2024-07-04 05:13:35 -04:00
|
|
|
import { BufferStream, SeekDir } from './buffer.js';
|
2024-07-03 06:00:16 -04:00
|
|
|
|
2024-07-04 05:13:35 -04:00
|
|
|
import { LOCATION } from './structs/core.js';
|
|
|
|
import { AcsCharacterInfo } from './structs/character.js';
|
|
|
|
import { AcsAnimationEntry } from './structs/animation.js';
|
2024-07-04 20:41:11 -04:00
|
|
|
import { AcsImageEntry } from './structs/image.js';
|
2024-07-09 19:47:10 -04:00
|
|
|
import { Agent } from './agent.js';
|
2024-07-03 06:00:16 -04:00
|
|
|
|
2024-07-04 05:13:35 -04:00
|
|
|
// Experiment for storing parsed data
|
2024-07-09 19:47:10 -04:00
|
|
|
export class AcsData {
|
2024-07-04 05:13:35 -04:00
|
|
|
characterInfo = new AcsCharacterInfo();
|
|
|
|
animInfo: AcsAnimationEntry[] = [];
|
2024-07-04 20:41:11 -04:00
|
|
|
images: AcsImageEntry[] = [];
|
2024-07-04 05:13:35 -04:00
|
|
|
}
|
2024-07-03 06:00:16 -04:00
|
|
|
|
2024-07-04 05:13:35 -04:00
|
|
|
function logOffset(o: number, name: string) {
|
|
|
|
let n = o >>> 0;
|
|
|
|
console.log(name, 'offset:', '0x' + n.toString(16));
|
|
|
|
}
|
2024-07-03 21:18:40 -04:00
|
|
|
|
2024-07-04 05:13:35 -04:00
|
|
|
function agentCharacterParseACS(buffer: BufferStream) {
|
|
|
|
// Make sure the magic is correct for the ACS file.
|
|
|
|
if (buffer.readU32LE() != 0xabcdabc3) {
|
|
|
|
throw new Error('The provided data buffer does not contain valid ACS data.');
|
|
|
|
}
|
|
|
|
|
|
|
|
let acsData = new AcsData();
|
|
|
|
|
|
|
|
// Read the rest of the header.
|
|
|
|
let characterInfoLocation = LOCATION.read(buffer);
|
|
|
|
let animationInfoLocation = LOCATION.read(buffer);
|
|
|
|
let imageInfoLocation = LOCATION.read(buffer);
|
|
|
|
let audioInfoLocation = LOCATION.read(buffer);
|
|
|
|
|
|
|
|
logOffset(characterInfoLocation.offset, 'character info');
|
|
|
|
logOffset(animationInfoLocation.offset, 'animation info');
|
|
|
|
logOffset(imageInfoLocation.offset, 'image info');
|
|
|
|
logOffset(audioInfoLocation.offset, 'audio info');
|
|
|
|
|
|
|
|
buffer.withOffset(characterInfoLocation.offset, () => {
|
|
|
|
acsData.characterInfo = AcsCharacterInfo.read(buffer);
|
|
|
|
});
|
|
|
|
|
|
|
|
buffer.withOffset(animationInfoLocation.offset, () => {
|
|
|
|
acsData.animInfo = buffer.readCountedList(() => {
|
|
|
|
return AcsAnimationEntry.read(buffer);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2024-07-04 20:41:11 -04:00
|
|
|
buffer.withOffset(imageInfoLocation.offset, () => {
|
|
|
|
acsData.images = buffer.readCountedList(() => {
|
|
|
|
return AcsImageEntry.read(buffer);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2024-07-04 05:13:35 -04:00
|
|
|
console.log(acsData);
|
2024-07-09 19:47:10 -04:00
|
|
|
return acsData;
|
2024-07-03 06:00:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// For the testbed code only, remove when that gets axed
|
|
|
|
// (or don't, I'm not your dad)
|
|
|
|
export function agentParseCharacterTestbed(buffer: Uint8Array) {
|
2024-07-09 19:47:10 -04:00
|
|
|
return new Agent(agentCharacterParseACS(new BufferStream(buffer)));
|
2024-07-03 06:00:16 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// TODO this will be the public API
|
|
|
|
// Dunno about maintaining canvases. We can pass a div into agentInit and add a characterInit() which recieves it
|
|
|
|
// (which we then mount characters and their wordballoons into?)
|
2024-07-04 05:13:35 -04:00
|
|
|
export function agentCreateCharacter(data: Uint8Array): Promise<void> {
|
|
|
|
throw new Error('Not implemented yet');
|
2024-07-03 06:00:16 -04:00
|
|
|
}
|