From 5f2738872e72a2341cd4fd2478b0b2e6b24a236c Mon Sep 17 00:00:00 2001 From: LolHacksRule Date: Sun, 21 Apr 2024 03:32:26 -0700 Subject: [PATCH] patterns: Added XGSPak and XGSTexture patterns (#237) * Add XGSPak and XGSTexture patterns * Whoops forgot proper pointers * Fix typo * Whoops * Proper start * Update xgstexture.hexpat --- README.md | 4 +- patterns/xci.hexpat | 2 +- patterns/xgspak.hexpat | 157 +++++++++++++++++++++++++++++++++++++ patterns/xgstexture.hexpat | 113 ++++++++++++++++++++++++++ 4 files changed, 274 insertions(+), 2 deletions(-) create mode 100644 patterns/xgspak.hexpat create mode 100644 patterns/xgstexture.hexpat diff --git a/README.md b/README.md index 95fc594..d5588d8 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | NRO | | [`patterns/nro.hexpat`](patterns/nro.hexpat) | Nintendo Switch NRO files | | NTAG | | [`patterns/ntag.hexpat`](patterns/ntag.hexpat) | NTAG213/NTAG215/NTAG216, NFC Forum Type 2 Tag compliant IC | | OGG | `audio/ogg` | [`patterns/ogg.hexpat`](patterns/ogg.hexpat) | OGG Audio format | +| PAK | | [`patterns/xgspak.hexpat`](patterns/xgspak.hexpat) | Exient XGS Engine Pak files | | PCAP | `application/vnd.tcpdump.pcap` | [`patterns/pcap.hexpat`](patterns/pcap.hexpat) | pcap header and packets | | PCX | `application/x-pcx` | [`patterns/pcx.hexpat`](patterns/pcx.hexpat) | PCX Image format | | PE | `application/x-dosexec` `application/x-msdownload` | [`patterns/pe.hexpat`](patterns/pe.hexpat) | PE header, COFF header, Standard COFF fields and Windows Specific fields | @@ -119,7 +120,8 @@ Everything will immediately show up in ImHex's Content Store and gets bundled wi | 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 | +| XCI | | [`patterns/xci.hexpat`](patterns/xci.hexpat) | Nintendo Switch XCI cartridge ROM | +| XGT | | [`patterns/xgt.hexpat`](patterns/xgstexture.hexpat) | Exient XGS Engine Texture | | Xilinx BIT | | [`patterns/xilinx_bit.hexpat`](patterns/xilinx_bit.hexpat) | Xilinx FPGA Bitstreams | | Xilinx Bootgen | | [`patterns/xilinx_bootgen.hexpat`](patterns/xilinx_bootgen.hexpat) | Xilinx ZynqMP Boot Images | | ZIP | `application/zip` | [`patterns/zip.hexpat`](patterns/zip.hexpat) | End of Central Directory Header, Central Directory File Headers | diff --git a/patterns/xci.hexpat b/patterns/xci.hexpat index f806fd6..80d4d8c 100644 --- a/patterns/xci.hexpat +++ b/patterns/xci.hexpat @@ -1,5 +1,5 @@ #pragma author WerWolv -#pragma description Nintendo Switch XCI cardridge ROM +#pragma description Nintendo Switch XCI cartridge ROM import std.core; diff --git a/patterns/xgspak.hexpat b/patterns/xgspak.hexpat new file mode 100644 index 0000000..414358d --- /dev/null +++ b/patterns/xgspak.hexpat @@ -0,0 +1,157 @@ +import std.mem; +import std.core; +import type.time; +import type.magic; + +//By LolHacksRule + +/* +XGSPAK VX only works with games using XGS Engine VX (I think First Touch Games use multiple?), using different versions with them is likely a bad idea as devs can only use one of the three. +XGSPAKV1 can be used with ZLib or Raw content. +Works nearly perfectly on PAKs WITH and WITHOUT folders. +*/ + +/* +TODO: +Double check XGSPAKV0 from NFS Wii, it's probably similar? +Fix FTG V1 PAK if possible, uses V0 layout +*/ + +/* +Format info I used: +https://aluigi.altervista.org/bms/angry_birds_go.bms +https://aluigi.altervista.org/bms/angry_birds_starwars.bms +https://aluigi.altervista.org/bms/xpk2.bms +https://aluigi.altervista.org/bms/dls20.bms +*/ + +enum PakVersion : u8 +{ + Version0, //NFS Wii/Trilogy 3DS/DLS + Version1, //ABGO V1/ABTF, AB Console Ports + Version2 //ABGO V2+ +}; + +enum CompressionType : u32 +{ + Raw, //NFS Wii/Trilogy 3DS/DLS + Zlib, //ABGO V1/ABTF, AB Console Ports + LZ4 //ABGO V2+ +}; + +struct XGSPakHeader +{ + if (std::mem::read_unsigned($, 1) > 2) //Assume BE + { + std::core::set_endian(std::mem::Endian::Big); + char magic[3]; + PakVersion ver; + } + else + { + PakVersion ver; + char magic[3]; + } + u32 folders; + u32 files; //-1 bcz init folder + u32 fileContentTableSize; + if (ver == PakVersion::Version2) + { + CompressionType compressionType; + } +}; + +struct XGSPakFolderBase +{ + if (Head.ver == PakVersion::Version0) + { + char *name[] : u32[[pointer_base("offToStringTable")]]; + u32 filesInFolder; + u32 subfolders; + u32 filesPos; + u32 foldersPos; + } + else + { + if (Head.magic == "XPK") + { + u32 dummy; + char *name[] : u32 [[pointer_base("offToStringTable")]]; + u32 dummy2; + u32 filesPos; + u32 dummy3; + u32 foldersPos; + u32 filesInFolder; + u32 subfolders; + } + else + { + //u64 name; + char *name[] : u64 [[pointer_base("offToStringTable")]]; + u64 filesPos; + u64 foldersPos; + u32 filesInFolder; + u32 subfolders; + } + } +}; + +struct XGSPakContentMeta +{ + if (Head.ver == PakVersion::Version0) + { + char *name[] : u32 [[pointer_base("offToStringTable")]]; + u32 decompFileSize; + u32 fileOff; + u32 compressed; + type::time32_t timestamp; + u32 compFileSize; + } + else + { + if (Head.magic == "XPK") + { + u32 dummy; + char *name[] : u32 [[pointer_base("offToStringTable")]]; + u32 decompFileSize; + u32 fileOff; + u32 compressed; + type::time32_t timestamp; + u32 compFileSize; + u32 dummy2; + } + else + { + //u64 name; + char *name[] : u64 [[pointer_base("offToStringTable")]]; + u32 decompFileSize; + u32 fileOff; + u32 compressed; + type::time32_t timestamp; + u64 compFileSize; + } + } + if (compressed) + { + u8 compressedFile[compFileSize] @ fileOff; + } + else + { + u8 file[decompFileSize] @ fileOff; + } +}; + + +XGSPakHeader Head @ $; +//u32 offToStringTable_old = ((0x20*Head.folders)+(0x20*Head.files))+sizeof (Head); //Finicky but it works + +fn offToStringTable(u128 offset) { + match (Head.ver) + { + (PakVersion::Version0): return ((0x14*Head.folders)+(0x18*Head.files))+sizeof (Head); + (PakVersion::Version1 | PakVersion::Version2): return ((0x20*Head.folders)+(0x20*Head.files))+sizeof (Head); + } +}; + +XGSPakFolderBase FolderBase[Head.folders] @ $; +XGSPakContentMeta ContentMeta[Head.files] @ $; \ No newline at end of file diff --git a/patterns/xgstexture.hexpat b/patterns/xgstexture.hexpat new file mode 100644 index 0000000..b950d81 --- /dev/null +++ b/patterns/xgstexture.hexpat @@ -0,0 +1,113 @@ +import type.magic; +//By LolHacksRule + +enum XGSPlatform : u8 +{ + WIN32_OR_ANDROID, //Android sure but Win32 p much was only used in EOP (Edge of Perception)? + PS3, //PlayStation 3, + iOS_OR_PSP, //iPhone/iPad or PSP (confusion, I think PSP was renamed to iOS but idk) + REVOLUTION, //Nintendo Wii + XENON, //Xbox 360 + iOS_IPHONE_LEGACY, //Legacy iPhone/iPad since ABGO V1 + CTR, //Nintendo 3DS + PSP2, //PlayStation Vita + OSX, //Mac OS X + ANDROID_LEGACY, //Definitely Android since ABGO V1 + METRO_OR_WINSTORE, //WP7? + CAFE, //Wii U + BLACKBERRY, + OGL, //? + ORBIS, //PlayStation 4 + DURANGO, //Xbox One + WINPHONE, //PCOGL + WINPHONE_LEGACY, //WP8 + APPLE_TV, //Apple TV +}; + +enum XGSTextureFormat : u16 +{ + RGB565_SWIZZLED, //AB SW Console, Vita/PS3 uses no swizzle + RGB565, //ABTF but supported in GO + RGBA4444, //On PS3 this is BGRA8888/ARGB8888? + RGBA4444_2_OR_RGBA8888_OR_LA88, //On PS4/X360/XENON this is ARGB8888, on Win this is RGBA8888, on current Android this is RGBA4444 OR RGBA8888 (ABTF2017 Chi?), on caFe/Wii U or legacy iOS this is RGBA8888, on current iOS it's both, on Orbis/PS4 it's BGRA8888, on Wii it's linear indexed 32BPP LA88 with BC swizzle, on legacy Android or ABGO v101 crashes + RGBA8888, //On GO v101, nothing is read + PALLETIZED_RGBA5A3, //Palletized RGB5A3, AB SW Wii, doesn't crash in EOP or ABGO v101 (Android) but doesn't return any data + //6, //crash on EOP and PS3 but not ABGO v101 but doesn't return any data + //7, //crash on EOP and PS3 but not ABGO v101 but doesn't return any data + AL88_OR_DXT1_OR_RGB565 = 8, //On Xbox 360/PS3 this is usually DXT, on Wii U, RGBA8888, on Android, this is usually AL88 unless the format is DXT, on 3DS, swizzled RGB565, on EOP, crash, on ABGO v101, nothing + UNKNOWN_DXT, //DXT3? no XGS games so far use this one, crashes on EOP, on ABGO v101, nothing + DXT5_SWIZZLED, //ABSW PS3/WinPhone/Legacy Android only? on ABGO v101, nothing + PVR_UNK, //2BPP no alpha? Crashes in ABGO v101 + RGB888, //Greyscale? unused, crashes in EOP but works in ABGO v101 + AL88, + //14, //8BPP something? Crash on EOP and PS3, on ABGO v101, nothing + PVRTC_2BPP_RGBA = 15, //Crash on PS3, on ABGO v101, nothing + PVRTC_4BPP_RGBA, //Crash on PS3 or is this 2bppRGBA, on ABGO v101, nothing + PVRTC_4BPP_RGBA_2, //May need to swap these two, crash on PS3, on ABGO v101, nothing + PVRTC_4BPP_RGBA_3, //Crashes on EOP and PS3, on ABGO v101, nothing + //19, //Crash on PS3 and EOP, on ABGO v101, nothing + //20, //Crash on PS3 and EOP, on ABGO v101, nothing + //21, //Crash on PS3 and EOP, on ABGO v101, nothing + RG88_OR_GR88 = 22, //Unused. On PS3, it's unswizzled GR88, crashes on EOP, on ABGO v101, nothing + L4, //Unused, crashes on EOP, on ABGO v101, nothing + DXT1_OR_ETC1, //On Android this is usually DXT1, old Android has this DXT1 swizzled, null on PS3, crash on EOP, on ABGO v101, nothing + LA44, //Crash on EOP, on ABGO v101, nothing + DXT5, //Crash on EOP, on ABGO v101, nothing + //?, //Crash on EOP, on ABGO v101, nothing, note starting here PS3 crashes + //?, //Crash on EOP, on ABGO v101, nothing + PVRTC_2BPP_RGBA_2 = 29, //on ABGO v101, nothing + PVRTC_4BPP_RGBA_V2, //on ABGO v101, nothing + PVRTC_4BPP_RGB_V3, //on ABGO v101, nothing + //? //on ABGO v101, nothing + //? //on ABGO v101, nothing + //? //on ABGO v101, nothing + ETC2_RGB = 35, //on ABGO v101, nothing + //? //on ABGO v101, nothing + ATC = 37, //BC Swizzled, on ABGO v101, nothing + //ATC_RGBA_Exp, //? on ABGO v101, nothing + ATCA_Interpolated = 39, //BC Swizzled, on ABGO v101, nothing + //? //on ABGO v101, nothing + RGBA5A3 = 250, //on ABGO v101, nothing + CMPR, //CMPR/DXT1 with different blocks, nothing on ABGO v101 + ETC2_RGB_2_OR_ETC1, //On CTR, ETC1 Z-Order 1, works on ABGO v101 (ETC1) + ETC1_RGB_SPLITALPHA, //CTR only, nothing on ABGO v101 + ATC_RGB, //Confirm, nothing on ABGO v101 + ATC_RGBA_EXPLICIT, //Prob nothing on ABGO v101 + ATC_RGBA_INTERPOLATED, //Prob nothing on ABGO v101 + XGSTEXFMT_257, //Defined in ABGO v101 but idk what it is + //258-263 are unknown + DXT1_EXT = 264, //DXT1 EXT (?) + DXT3_EXT, //DXT3 EXT (?) + DXT5_EXT, //DXT1 EXT (?) +}; + +bitfield XGSTextureFlags +{ + Mips : 2; Twiddle : 2; Normal : 2; Border : 2; CubeMap : 2; MipMapDebugColoring : 2; Volume3D : 2; AlphaChannelPresent : 2; VFlip : 2; + //Idk how this works +}; + +struct XGSTextureHeader +{ + type::Magic"XGST"> magic; + u8 dataOffset; + XGSPlatform compilationPlatform; //Definitely platform, this has no harm when modifying (except in Edge of Perception) but does help with knowing platform specific compressions, usually + u16 headerSize; //? + //byte dmy; + u8 numMips; + //? start + XGSTextureFlags flags; + //? end + //char format[4]; + XGSTextureFormat format; + u16 numColors; //Modifying this seems to have no known effect but idk + u16 width; + u16 height; + u16 width2; //No use modifying + u16 height2; //No use modifying + u32 paletteSize; //Modifying this affects the game badly, take care + u32 dataSize; +}; + +XGSTextureHeader Head @ $; +u8 Texture[Head.dataSize] @ $; \ No newline at end of file