From 9eadf40d4ca6e26e7972970e727cff1724987954 Mon Sep 17 00:00:00 2001 From: modeco80 Date: Thu, 4 Jul 2024 20:41:11 -0400 Subject: [PATCH] read images (TODO) next is displaying them in the testbed --- msagent.js/src/character.ts | 8 ++++ msagent.js/src/structs/core.ts | 22 +++++++++ msagent.js/src/structs/image.ts | 81 +++++++++++++++++++++++++++++++++ 3 files changed, 111 insertions(+) create mode 100644 msagent.js/src/structs/image.ts diff --git a/msagent.js/src/character.ts b/msagent.js/src/character.ts index aeb4929..98aef75 100644 --- a/msagent.js/src/character.ts +++ b/msagent.js/src/character.ts @@ -3,11 +3,13 @@ import { BufferStream, SeekDir } from './buffer.js'; import { LOCATION } from './structs/core.js'; import { AcsCharacterInfo } from './structs/character.js'; import { AcsAnimationEntry } from './structs/animation.js'; +import { AcsImageEntry } from './structs/image.js'; // Experiment for storing parsed data class AcsData { characterInfo = new AcsCharacterInfo(); animInfo: AcsAnimationEntry[] = []; + images: AcsImageEntry[] = []; } function logOffset(o: number, name: string) { @@ -44,6 +46,12 @@ function agentCharacterParseACS(buffer: BufferStream) { }); }); + buffer.withOffset(imageInfoLocation.offset, () => { + acsData.images = buffer.readCountedList(() => { + return AcsImageEntry.read(buffer); + }); + }); + console.log(acsData); } diff --git a/msagent.js/src/structs/core.ts b/msagent.js/src/structs/core.ts index 13cc504..a2b4df2 100644 --- a/msagent.js/src/structs/core.ts +++ b/msagent.js/src/structs/core.ts @@ -1,4 +1,5 @@ import { BufferStream, SeekDir } from '../buffer.js'; +import { compressDecompress } from '../decompress.js'; // Win32 Rect export class RECT { @@ -114,3 +115,24 @@ export class RGBAColor { return RGBAColor.from_gdi_rgbquad(buffer.readU32LE()); } } + +export class COMPRESSED_DATABLOCK { + data: Uint8Array = new Uint8Array(); + + static read(buffer: BufferStream) { + let compressed = new COMPRESSED_DATABLOCK(); + + let compressedSize = buffer.readU32LE(); + let uncompressedSize = buffer.readU32LE(); + + if(compressedSize == 0) + compressed.data = buffer.subBuffer(uncompressedSize).raw(); + else { + let data = buffer.subBuffer(compressedSize).raw(); + compressed.data = new Uint8Array(uncompressedSize); + compressDecompress(data, compressed.data); + } + + return compressed; + } +} diff --git a/msagent.js/src/structs/image.ts b/msagent.js/src/structs/image.ts new file mode 100644 index 0000000..f19fc61 --- /dev/null +++ b/msagent.js/src/structs/image.ts @@ -0,0 +1,81 @@ +/* +struct AcsImageInfo { + u8 unkStart; + u16 width; + u16 height; + bool isCompressed; + + // This algorithm is the size used for allocating + // the decompression buffer. + // ((Width + 3) & 0xFC) * Height) + + // Data + DATABLOCK imageData; + + // The data here is a Win32 RGNDATA + COMPRESSED regionData; +}; + +struct AcsImageInfoPointer { + LOCATION imageInfoLocation; + u32 checksumMaybe; + + AcsImageInfo imageInfo @ imageInfoLocation.offset; +}; +*/ + +import { BufferStream } from '../buffer'; +import { compressDecompress } from '../decompress'; +import { COMPRESSED_DATABLOCK, LOCATION, RGNDATA } from './core'; + +export class AcsImage { + width = 0; + height = 0; + + data = new Uint8Array(); + regionData = new RGNDATA(); + + static read(buffer: BufferStream) { + let image = new AcsImage(); + + // This has unknown purpose + let eat = buffer.readU8(); + + image.width = buffer.readU16LE(); + image.height = buffer.readU16LE(); + + let isCompressed = buffer.readBool(); + + let data = buffer.readDataChunk(); + + if (isCompressed) { + image.data = new Uint8Array(((image.width + 3) & 0xfc) * image.height); + compressDecompress(data, image.data); + } else { + image.data = data; + } + + // this will be a rgndata (TODO) read this + //let temp = COMPRESSED_DATABLOCK.read(buffer); + + return image; + } +} + +export class AcsImageEntry { + image = new AcsImage(); + + static read(buffer: BufferStream) { + let image = new AcsImageEntry(); + + // We discard both after we're done. + let loc = LOCATION.read(buffer); + let checksum = buffer.readU32LE(); + + buffer.withOffset(loc.offset, () => { + image.image = AcsImage.read(buffer); + }); + + return image; + } +}