Yesterday at 09:12 AM1 day Hi everyone, I'm trying to extract texture files from two Dreamcast games—Kita e White Illumination and Kita e Photo Memories—and I'm stuck on two issues. First, for White Illumination, the .CB file (which I opened with a hex editor and found to contain .dds and .set files) was extracted using a script generated by DeepSeek, but the resulting .dds files won't open in any image viewer I've tried (see SSYF.zip). Second, for Photo Memories, the PVR files have GBIX and PVRT headers, but none of the usual tools—pvr2image, Noesis, sprt2png, or PVRTexTool—can convert or even open them (yuko_PVR.zip). I suspect the data might be compressed, encrypted, or using non‑standard headers. I know I can use the Flycast emulator to dump textures as the game runs, but that's pretty tedious. Has anyone successfully extracted these formats, or does anyone know of a working tool or script that can handle them? Any help would be greatly appreciated. yuko_PVR.zip SSYF.zip
17 hours ago17 hr What offset are you seeing a DDS subfile in SSFY.CB? Scrolling through it, there are very few regular block patterns, and changing the wrap width rapidly, you can see wavy patterns indicative of variable length compression. Does the exported DDS have a standard DDS header at least (e.g. this)? The "PVR" files are also wrapped in some variable length compression (not PVR standard blocks). Edited 17 hours ago17 hr by piken
14 hours ago14 hr 11 hours ago, Tefolium said:Hi everyone, I'm trying to extract texture files from two Dreamcast games—Kita e White Illumination and Kita e Photo Memories—and I'm stuck on two issues. First, for White Illumination, the .CB file (which I opened with a hex editor and found to contain .dds and .set files) was extracted using a script generated by DeepSeek, but the resulting .dds files won't open in any image viewer I've tried (see SSYF.zip). Second, for Photo Memories, the PVR files have GBIX and PVRT headers, but none of the usual tools—pvr2image, Noesis, sprt2png, or PVRTexTool—can convert or even open them (yuko_PVR.zip). I suspect the data might be compressed, encrypted, or using non‑standard headers. I know I can use the Flycast emulator to dump textures as the game runs, but that's pretty tedious. Has anyone successfully extracted these formats, or does anyone know of a working tool or script that can handle them? Any help would be greatly appreciated.yuko_PVR.zip SSYF.zipThe PVR files look to be LZSS0 compressed from offset 8, and one of the files I tested (IMG0088_A) is 512x512 BGRA5551 with DC swizzling. Something like this:
3 hours ago3 hr Author 13 hours ago, piken said:What offset are you seeing a DDS subfile in SSFY.CB? Scrolling through it, there are very few regular block patterns, and changing the wrap width rapidly, you can see wavy patterns indicative of variable length compression. Does the exported DDS have a standard DDS header at least (e.g. this)? The "PVR" files are also wrapped in some variable length compression (not PVR standard blocks).there are not standard DDS header. I don't know the offset, but the first 76 bytes of the extracted file header are:CLSS<bh:10><bh:00><bh:00><bh:00>CTRFImageBuffer<bh:00>IBUF<bh:81><bh:97><bh:00><bh:00><bh:00><bh:00><bh:00><bh:00><bh:00><bh:01><bh:00><bh:01><bh:00><bh:02><bh:01><bh:00><bh:00><bh:00><bh:10><bh:00><bh:00><bh:80><bh:00><bh:00><bh:00>|<bh:00><bh:00><bh:e0><bh:03><bh:00><bh:00><bh:1f><bh:00><bh:00><bh:00><bh:01><bh:05><bh:05><bh:05><bh:0f><bh:0e><bh:09><bh:04>LZSSThe DDS files(bag2.dds) not inside the .cb file (presumably icons from the game) have this header:CLSS<bh:10><bh:00><bh:00><bh:00>CTRFImageBuffer<bh:00>IBUF<bh:19><bh:05><bh:00><bh:00><bh:00><bh:00><bh:00><bh:00>@<bh:00>@<bh:00><bh:80><bh:00><bh:01><bh:00><bh:00><bh:00><bh:10><bh:00><bh:00><bh:80><bh:00><bh:00><bh:00>|<bh:00><bh:00><bh:e0><bh:03><bh:00><bh:00><bh:1f><bh:00><bh:00><bh:00><bh:01><bh:05><bh:05><bh:05><bh:0f><bh:0e><bh:09><bh:04>LZSS BAG2.DDS
3 hours ago3 hr Author 11 hours ago, DKDave said:The PVR files look to be LZSS0 compressed from offset 8, and one of the files I tested (IMG0088_A) is 512x512 BGRA5551 with DC swizzling. Something like this:LZSS0 compressed from offset 8, 512x512 BGRA5551, swizzle morton swap, then I got the picture... 7.py is the python script for test by DeepSeek:Decompresses the LZSS0 stream using the confirmed parameters.Takes the first width * height * 2 bytes (default 512×512 = 524288 bytes).Applies five different reverse‑swizzle algorithms:linear – no reorderingmorton_swap – the confirmed DC swizzle with swapped Morton coordinatesmorton_noswap – standard Morton coordinatesblock_4x4_morton – 4×4 tiles, Morton order inside each tileblock_8x8_morton – 8×8 tiles, Morton order inside each tileConverts the resulting BGRA5551 data to RGBA8888 and writes a PNG for each algorithm.7.py Edited 3 hours ago3 hr by Tefolium
2 hours ago2 hr Supporter But not sure how to decompress. The LZSS sign it's just coincidence I guess.//------------------------------------------------ //--- 010 Editor v14.0 Binary Template // // File: // Authors: // Version: // Purpose: // Category: // File Mask: // ID Bytes: // History: //------------------------------------------------ LittleEndian();OutputPaneClear(); local uint32 i,j,k,l,SignCheck; char CABSign[4]; uint32 FCBSize; FSeek(FCBSize + 8); struct { char STRSign[4]; uint32 STRSize; struct { uint32 StrCount; struct { FSkip(3); string ResourcePathName; }STRDefinition[StrCount]<optimize=false>; }STRDefinition; }ResourcePathDefinition; FSeek(startof(FCBSize) + sizeof(FCBSize)); struct { char FCBSign[4]; uint32 INFOSize; struct { char INFOSign[4]; uint32 TOCSize; struct { uint32 ResourceCount; struct { uint32 Unknown_0; uint32 Unknown_1; uint32 ResourceSize; uint32 ResourceOffset; uint32 ResourceNameId; }ResourceDefinition[ResourceCount]<optimize=false>; }TOCDefinition; char STRSign[4]; uint32 STRSize; struct { uint32 StrCount; struct { string ResourceName; }STRDefinition[StrCount]<optimize=false>; }STRDefinition; }INFODefinition; struct { for (i=0; i < INFODefinition.TOCDefinition.ResourceCount; i++) { FSeek(INFODefinition.TOCDefinition.ResourceDefinition[i].ResourceOffset); struct { char Sign[4]; if (Sign == "ENC2") { uint32 Size; byte ENC2Data[Size]; FSeek(startof(ResourcePathDefinition.STRDefinition.STRDefinition[INFODefinition.TOCDefinition.ResourceDefinition[i].ResourceNameId].ResourcePathName)); string ResourceName; } else if (Sign == "ENC0") { uint32 CLSSSize; struct { char CLSSSign[4]; uint32 StrLen; char CTRFSign[StrLen]; struct { char IBUFSign[4]; uint32 IBUFSize; uint32 Unknown_0; uint16 TextureWidth; uint16 TextureHeight; uint32 Unknown_1; uint32 Unknown_2; uint32 Unknown_3; uint32 Unknown_4; uint32 Unknown_5; uint32 Unknown_6; uint32 Unknown_7; uint32 Unknown_8; struct { do { struct { char LZSSSign[4]; uint32 Size; byte LZSSData[Size]; SignCheck=ReadUInt(FTell()); }LZSSDefinition; }while(SignCheck == 1397971532); }LZSSDefinition; }IBUFDefinition; }CLSSDefinition; FSeek(startof(ResourcePathDefinition.STRDefinition.STRDefinition[INFODefinition.TOCDefinition.ResourceDefinition[i].ResourceNameId].ResourcePathName)); string ResourceName; } }Resource; } }Resources; }FCBDefinition; Edited 2 hours ago2 hr by h3x3r
Create an account or sign in to comment