From edd0aa9a2fe61187ddb1144b60a1794e17699539 Mon Sep 17 00:00:00 2001 From: DmitriLeon2000 Date: Tue, 24 Oct 2023 14:35:38 +0900 Subject: [PATCH] patterns: Add .fas and .was pattern files (Oska DeskMates) (#176) * Add .fas and .was pattern files (Oska DeskMates) * Update .was pattern file * Update .was/.wa3 pattern file * Update README.md * Update README.md * Update .fas & .was pattern files * Update README.md * Update fas_oskasoftware_old.hexpat * Added WAS test file * Update WAS test file * Update was_oskasoftware.hexpat --- README.md | 2 + patterns/fas_oskasoftware.hexpat | 111 ++++++++++++++++++ patterns/fas_oskasoftware_old.hexpat | 87 ++++++++++++++ patterns/was_oskasoftware.hexpat | 24 ++++ .../test_data/was_oskasoftware.hexpat.was | Bin 0 -> 32046 bytes 5 files changed, 224 insertions(+) create mode 100644 patterns/fas_oskasoftware.hexpat create mode 100644 patterns/fas_oskasoftware_old.hexpat create mode 100644 patterns/was_oskasoftware.hexpat create mode 100644 tests/patterns/test_data/was_oskasoftware.hexpat.was diff --git a/README.md b/README.md index 21cd1a5..caebdf2 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | DTA | | [`patterns/max_v104.hexpat`](patterns/max_v104.hexpat) | Mechanized Assault and Exploration v1.04 (strategy game) save file format | | ELF | `application/x-executable` | [`patterns/elf.hexpat`](patterns/elf.hexpat) | ELF header in elf binaries | | EVTX | | [`patterns/evtx.hexpat`](patterns/evtx.hexpat) | MS Windows Vista Event Log | +| FAS | | [`patterns/fas_oskasoftware.hexpat`](patterns/fas_oskasoftware.hexpat) [`patterns/fas_oskasoftware_old.hexpat`](patterns/fas_oskasoftware_old.hexpat) (Old versions of Oska DeskMate) | Oska Software DeskMates FAS (Frames and Sequences) file | | FDT | | [`patterns/fdt.hexpat`](patterns/fdt.hexpat) | Flat Linux Device Tree blob | | File System | | [`patterns/fs.hexpat`](patterns/fs.hexpat) | Drive File System | | FLAC | `audio/flac` | [`patterns/flac.hexpat`](patterns/flac.hexpat) | Free Lossless Audio Codec, FLAC Audio Format | @@ -104,6 +105,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | VDF | | [`patterns/vdf.hexpat`](patterns/vdf.hexpat) | Binary Value Data Format (.vdf) files | | VHDX | | [`patterns/vhdx.hexpat`](patterns/vhdx.hexpat) | Microsoft Hyper-V Virtual Hard Disk format | | WAV | `audio/x-wav` | [`patterns/wav.hexpat`](patterns/wav.hexpat) | RIFF header, WAVE header, PCM header | +| WAS | | [`patterns\was_oskasoftware.hexpat`](patterns\was_oskasoftware.hexpat) | Oska Software DeskMates WAS/WA3 (WAVE/MP3 Set) file | WAD | | [`patterns/wad.hexpat`](patterns/wad.hexpat) | DOOM WAD Archive | | XBEH | `audio/x-xbox-executable` | [`patterns/xbeh.hexpat`](patterns/xbeh.hexpat) | Xbox executable | | XCI | | [`patterns/xci.hexpat`](patterns/xci.hexpat) | Nintendo Switch XCI cardridge ROM | diff --git a/patterns/fas_oskasoftware.hexpat b/patterns/fas_oskasoftware.hexpat new file mode 100644 index 0000000..617ba4b --- /dev/null +++ b/patterns/fas_oskasoftware.hexpat @@ -0,0 +1,111 @@ +#pragma author DmitriLeon2000 +#pragma description Oska Software DeskMates FAS (Frames and Sequences) file +#pragma endian little + +enum Compression : u32 { + BI_RGB, + BI_RLE8, + BI_RLE4, + BI_BITFIELDS, + BI_JPEG, + BI_PNG, + BI_ALPHABITFIELDS, + BI_CMYK, + BI_CMYKRLE8, + BI_CMYKRLE4, +}; + +struct Colors { + u8 blue; + u8 green; + u8 red; + u8 reserved; +}; + +struct FASHeader { + char name[50]; // name of the pack, may include garbage data + u16 version; // Format version number + s16 frameIDFirst; // assigned ID of the first frame + s16 frameIDLast; // assigned ID of the last frame + s32 width; // width of the animation (in pixels) + s32 height; // height of the animation (in pixels) + u16 frameSize; // size of the animation ((frameWidth * BPP + 31) // 32 * 4 * frameHeight) + u16 DblHeaderCount; // amount of BitmapInfoHeader pairs (one for color, one for masking) +}; + +struct BitmapInfoHeader { // bog-standard BitmapInfoHeaderV1 + u32 biSize; + s32 biWidth; + s32 biHeight; + u16 biPlanes; + u16 biBitCount; + Compression compression; + u32 biSizeImage; + s32 biXPelsPerMeter; + s32 biYPelsPerMeter; + u32 biClrUsed; + u32 biClrImportant; +}; + +struct BitmapInfo { + BitmapInfoHeader header; + Colors colorMap[header.biClrUsed == 0 ? + 1 << header.biBitCount : header.biClrUsed]; +}; + +struct ExtraSprite { + char name[]; +}; + +struct AnimSequence { + char name[]; + char sequence[]; +}; + +struct SeqHeader { + le u32 size; + le u32 count; + le u32 strPointers[count*2]; +}; + +struct Bitmap { + u8 byte[fas.fasHeader.version >= 3 ? fas.fasHeader.frameSize + (fas.frameSizeHigh << 16) : fas.fasHeader.frameSize]; +}; + +struct FramesHeader { + le u32 count; + le s16 frameID[count]; + u8 frameDblHdrID[count]; +}; + +struct FAS { + FASHeader fasHeader; + BitmapInfo dibHeaders[fasHeader.DblHeaderCount * 2]; + if (fasHeader.version >= 1) + u8 charID; + if (fasHeader.version >= 2) + { + u32 extraEndOffset; + u16 extraSpritesCount; + if (extraSpritesCount) + // char extraSpriteList[touchOffset - 6]; + ExtraSprite extraSprites[extraSpritesCount]; + } + if (fasHeader.version >= 3) + le u16 frameSizeHigh; + le u16 touchColors; + if (touchColors) + { + u32 touchColorMap[touchColors]; + u16 touchWidth; + u8 touchBitmap[this.touchWidth * fasHeader.height]; + } + SeqHeader seqHeader; + if (fasHeader.version >= 1) + u8 filenameChecksum; // a checksum for a filename in ASCII + AnimSequence sequences[seqHeader.count]; + FramesHeader framesHeader; +}; + +FAS fas @ 0x00; +Bitmap framesBitmap[fas.framesHeader.count] @ $; \ No newline at end of file diff --git a/patterns/fas_oskasoftware_old.hexpat b/patterns/fas_oskasoftware_old.hexpat new file mode 100644 index 0000000..9c7e790 --- /dev/null +++ b/patterns/fas_oskasoftware_old.hexpat @@ -0,0 +1,87 @@ +#pragma author DmitriLeon2000 +#pragma description Oska Software DeskMates FAS (Frames and Sequences) file (Oska DeskMate versions 1.3 and 2.06) +#pragma endian little + +enum Compression : u32 { + BI_RGB, + BI_RLE8, + BI_RLE4, + BI_BITFIELDS, + BI_JPEG, + BI_PNG, + BI_ALPHABITFIELDS, + BI_CMYK, + BI_CMYKRLE8, + BI_CMYKRLE4, +}; + +struct Colors { + u8 blue; + u8 green; + u8 red; + u8 reserved; +}; + +struct FASHeader { + s32 width; // width of the animation (in pixels) + s32 height; // height of the animation (in pixels) + u16 reserved1; + u16 reserved2; + u16 frameSizeCombined; // a sum of frameSizeColor and frameSizeMask + u16 frameSizeColor; // size of the animation ((frameWidth * 4 + 31) // 32 * 4 * frameHeight) + u16 frameSizeMask; // size of the animation's mask ((frameWidth * 1 + 31) // 32 * 4 * frameHeight) + u16 headerCount; // amount of DIB headers +}; + +struct BitmapInfoHeader { // bog-standard BitmapInfoHeaderV1 + u32 biSize; + s32 biWidth; + s32 biHeight; + u16 biPlanes; + u16 biBitCount; + Compression compression; + u32 biSizeImage; + s32 biXPelsPerMeter; + s32 biYPelsPerMeter; + u32 biClrUsed; + u32 biClrImportant; +}; + +struct BitmapInfo { + BitmapInfoHeader header; + le u32 colorMap[header.biClrUsed == 0 ? + 1 << header.biBitCount : header.biClrUsed]; +}; + +struct AnimSequence { + char name[]; + char sequence[]; +}; + +struct SeqHeader { + le u32 size; + le u32 count; + le u32 strPointers[count*2]; +}; + +struct Frame { + u8 colorBitmap[fas.fasHeader.frameSizeColor]; + u8 maskBitmap[fas.fasHeader.frameSizeMask]; +}; + +struct FramesHeader { + le u32 count; + le s16 frameID[count]; +}; + +struct FAS { + FASHeader fasHeader; + BitmapInfo dibHeaders[fasHeader.headerCount]; + SeqHeader seqHeader; + AnimSequence sequences[seqHeader.count]; + FramesHeader framesHeader; +}; + + +FAS fas @ 0x00; +Frame frames[fas.framesHeader.count] @ $; diff --git a/patterns/was_oskasoftware.hexpat b/patterns/was_oskasoftware.hexpat new file mode 100644 index 0000000..976adce --- /dev/null +++ b/patterns/was_oskasoftware.hexpat @@ -0,0 +1,24 @@ +#pragma author DmitriLeon2000 +#pragma description Oska Software DeskMates WAS/WA3 (WAVE/MP3 Set) file +#pragma endian little + +#include + +struct Sound { + char name[]; + u32 length; + u8 data[length]; +}; + +struct Header { + type::Size size; + u32 count; + u32 pointers[count * 2]; +}; + +struct WAS { + Header header; + Sound sounds[header.count]; +}; + +WAS was @ 0x00; \ No newline at end of file diff --git a/tests/patterns/test_data/was_oskasoftware.hexpat.was b/tests/patterns/test_data/was_oskasoftware.hexpat.was new file mode 100644 index 0000000000000000000000000000000000000000..66d9332ad766fc04746ec43142f5b4a9adc0161a GIT binary patch literal 32046 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 Bw2c4& literal 0 HcmV?d00001