4 hours ago4 hr Captain Tsubasa J - Get in the Tomorrow (PS1) — Texture/Asset Container Format AnalysisGame: Captain Tsubasa J: Get in the Tomorrow (PSX) Engine: Based on Konami's Winning Eleven 2002 / ISS Pro Evolution engine Goal: Extract and re-inject player sprites, team logos, and menu/background graphics.I've done manual hex analysis and light MIPS disassembly (no Ghidra/IDA available on my end) and found a consistent, custom, engine-wide container format used across multiple asset files. Posting my findings here in hopes someone with proper tooling can finish cracking the pixel/compression format.1. File map (extracted from strings in the main executable, CAPTIN.EXE)BRDATA\BR.TEX BRDATA\T00.BIN ... T2A.BIN (many sequential files) DATA\BG0.BIN ... BG6.BIN DATA\BOX.BIN DATA\HUMAN.TEX DATA\MATER.BIN SOUND\GAMESE.BIN, M00-M05.BIN, MBR.BIN STR0\A_DEMO.BIN, A_SWAZA.BIN TEAMD0\TEAM00.BIN ... TEAM09.BIN HUMAN.TEX = player character sprites. TEAM0X.BIN = per-team data (likely includes logos). BG*.BIN = background/menu screens. BR.TEX = border/UI graphics.2. Top-level container format (confirmed in HUMAN.TEX, TEAM00.BIN, BR.TEX)All three files begin with an offset table:u32 count u32 offset[count] // absolute file offsets, ABSOLUTE from file start The first offset value always equals 4 + count*4 (i.e., points exactly to the end of the table), confirming this parsing is correct. Some offset values repeat (multiple table entries point to the same sub-block — shared/reused assets, e.g. duplicate frames).Example (HUMAN.TEX): count = 162, 119 unique blocks after dedup. Example (BR.TEX): count = 0x23 (35).Note: BG0.BIN uses a slightly different variant:u32 unknown (always 0) u32 count u32 offset[count] // RELATIVE to the count field's position (add 4 to get absolute) 3. Second-level "chunk" header (found inside sub-blocks of HUMAN.TEX/TEAM00.BIN)Each top-level sub-block in HUMAN.TEX / TEAM00.BIN starts with its own nested table:u32 sub_count (e.g. 8 in HUMAN.TEX block 0) u32 sub_offset[sub_count] // relative to start of this sub-block Followed by a fixed 6-byte marker: 00 00 03 BF 01 FF (HUMAN.TEX) or 00 00 03 3F variant (TEAM00.BIN) — only differs by one bit (0xBF vs 0x3F), likely a flag (bpp mode / has-alpha / etc).After this marker, data strongly resembles a 16-color CLUT (palette) in native PS1 BGR555 16-bit format — confirmed by extracting plausible skin-tone/hair colors when interpreted this way. However, interpreting the remaining bytes as raw packed 4bpp pixel indices produces visual noise, not a coherent sprite — meaning the pixel data itself is compressed with an unknown RLE-like scheme (not raw packed nibbles).Repeating byte patterns of the form [byte][byte] where one side is frequently 0x00 suggest a (count,value) or (value,count) RLE pair scheme, but I could not confirm the exact bit order/escape logic through data inspection alone.4. Different container type found in BG0.BIN / BR.TEXUnlike HUMAN.TEX, the sub-blocks in BG0.BIN and BR.TEX start with a different, distinct chunk header:u32 magic // 0x00000041 ('A') u32 zero u32 type // observed: 1 (BG0.BIN) and 2 (BR.TEX) u32 size Type 1 blocks (BG0.BIN) appear to contain raw PS1 GPU primitive packets — repeating 16-byte records matching the structure of GP0 command 0x30 (flat-shaded opaque triangle: color word + 3 vertices). This suggests some backgrounds are drawn live using solid-color polygons rather than stored as bitmaps.Type 2 blocks (BR.TEX) contain further nested numeric tables (possibly frame/sprite descriptor tables with width/height-like fields), not yet decoded.5. Executable analysis (CAPTIN.EXE)Standard PS-EXE header, confirmed valid:Entry point (PC0): 0x800781fcLoad address (T_ADDR): 0x80012000Code size: 0x000a3000 (matches file size exactly)Relevant debug strings found:"clut: (%d,%d)" at VA 0x800147e8"DATA\HUMAN.TEX" at VA 0x80012138Found and disassembled (by hand — MIPS) the function referencing the clut debug string at 0x800784ac–0x8007857c. This turned out to be a standard debug-print helper that decodes a packed 16-bit CLUT id into (X,Y) VRAM coordinates and calls a function-pointer (likely a printf-style TTY function from a table at 0x800bd054). This confirms the game uses real PSY-Q libgpu CLUT conventions, but is not the custom pixel-decompression routine itself. I was not able to further pinpoint the actual decompression function via manual byte-pattern scanning (searching for the 0x03BF/0x033F-style magic as immediate loads produced no reliable hits — too many false positives without proper xref/decompiler tooling).A disassembler with jump table / call graph analysis (e.g. Ghidra with a PS1/MIPS loader, or an existing PSX ISO project in IDA) would very likely find the actual decompression loop quickly by tracing what function is called right after the top-level offset table lookup for HUMAN.TEX/TEAM0X.BIN.6. Files attachedHUMAN.TEX (raw, extracted top-level + level-2 sub-blocks included)TEAM00.BINBG0.BINBR.TEXCAPTIN.EXE (main executable, for disassembly)7. What I'm looking forConfirmation/correction of the nested offset-table structure aboveThe actual pixel decompression algorithm for the 00 00 03 BF 01 FF-style chunks (HUMAN.TEX/TEAM0X.BIN)Whether BR.TEX's type-2 chunks are compressed the same way or differentlyAny existing tools/scripts for Winning Eleven 2002-family PS1 titles that might already handle this container format, since this engine is shared across several Konami PS1 sports titles from the same era.Thanks in advance to anyone who can take this further! Captain Tsubasa J - Get in the Tomorrow (Japan)77.zip
1 hour ago1 hr Supporter 3 hours ago, CRUYFFORD said:Captain Tsubasa J - Get in the Tomorrow (PS1) — Texture/Asset Container Format AnalysisGame: Captain Tsubasa J: Get in the Tomorrow (PSX) Engine: Based on Konami's Winning Eleven 2002 / ISS Pro Evolution engine Goal: Extract and re-inject player sprites, team logos, and menu/background graphics.I've done manual hex analysis and light MIPS disassembly (no Ghidra/IDA available on my end) and found a consistent, custom, engine-wide container format used across multiple asset files. Posting my findings here in hopes someone with proper tooling can finish cracking the pixel/compression format.1. File map (extracted from strings in the main executable, CAPTIN.EXE)BRDATA\BR.TEX BRDATA\T00.BIN ... T2A.BIN (many sequential files) DATA\BG0.BIN ... BG6.BIN DATA\BOX.BIN DATA\HUMAN.TEX DATA\MATER.BIN SOUND\GAMESE.BIN, M00-M05.BIN, MBR.BIN STR0\A_DEMO.BIN, A_SWAZA.BIN TEAMD0\TEAM00.BIN ... TEAM09.BIN HUMAN.TEX = player character sprites. TEAM0X.BIN = per-team data (likely includes logos). BG*.BIN = background/menu screens. BR.TEX = border/UI graphics.2. Top-level container format (confirmed in HUMAN.TEX, TEAM00.BIN, BR.TEX)All three files begin with an offset table:u32 count u32 offset[count] // absolute file offsets, ABSOLUTE from file start The first offset value always equals 4 + count*4 (i.e., points exactly to the end of the table), confirming this parsing is correct. Some offset values repeat (multiple table entries point to the same sub-block — shared/reused assets, e.g. duplicate frames).Example (HUMAN.TEX): count = 162, 119 unique blocks after dedup. Example (BR.TEX): count = 0x23 (35).Note: BG0.BIN uses a slightly different variant:u32 unknown (always 0) u32 count u32 offset[count] // RELATIVE to the count field's position (add 4 to get absolute) 3. Second-level "chunk" header (found inside sub-blocks of HUMAN.TEX/TEAM00.BIN)Each top-level sub-block in HUMAN.TEX / TEAM00.BIN starts with its own nested table:u32 sub_count (e.g. 8 in HUMAN.TEX block 0) u32 sub_offset[sub_count] // relative to start of this sub-block Followed by a fixed 6-byte marker: 00 00 03 BF 01 FF (HUMAN.TEX) or 00 00 03 3F variant (TEAM00.BIN) — only differs by one bit (0xBF vs 0x3F), likely a flag (bpp mode / has-alpha / etc).After this marker, data strongly resembles a 16-color CLUT (palette) in native PS1 BGR555 16-bit format — confirmed by extracting plausible skin-tone/hair colors when interpreted this way. However, interpreting the remaining bytes as raw packed 4bpp pixel indices produces visual noise, not a coherent sprite — meaning the pixel data itself is compressed with an unknown RLE-like scheme (not raw packed nibbles).Repeating byte patterns of the form [byte][byte] where one side is frequently 0x00 suggest a (count,value) or (value,count) RLE pair scheme, but I could not confirm the exact bit order/escape logic through data inspection alone.4. Different container type found in BG0.BIN / BR.TEXUnlike HUMAN.TEX, the sub-blocks in BG0.BIN and BR.TEX start with a different, distinct chunk header:u32 magic // 0x00000041 ('A') u32 zero u32 type // observed: 1 (BG0.BIN) and 2 (BR.TEX) u32 size Type 1 blocks (BG0.BIN) appear to contain raw PS1 GPU primitive packets — repeating 16-byte records matching the structure of GP0 command 0x30 (flat-shaded opaque triangle: color word + 3 vertices). This suggests some backgrounds are drawn live using solid-color polygons rather than stored as bitmaps.Type 2 blocks (BR.TEX) contain further nested numeric tables (possibly frame/sprite descriptor tables with width/height-like fields), not yet decoded.5. Executable analysis (CAPTIN.EXE)Standard PS-EXE header, confirmed valid:Entry point (PC0): 0x800781fcLoad address (T_ADDR): 0x80012000Code size: 0x000a3000 (matches file size exactly)Relevant debug strings found:"clut: (%d,%d)" at VA 0x800147e8"DATA\HUMAN.TEX" at VA 0x80012138Found and disassembled (by hand — MIPS) the function referencing the clut debug string at 0x800784ac–0x8007857c. This turned out to be a standard debug-print helper that decodes a packed 16-bit CLUT id into (X,Y) VRAM coordinates and calls a function-pointer (likely a printf-style TTY function from a table at 0x800bd054). This confirms the game uses real PSY-Q libgpu CLUT conventions, but is not the custom pixel-decompression routine itself. I was not able to further pinpoint the actual decompression function via manual byte-pattern scanning (searching for the 0x03BF/0x033F-style magic as immediate loads produced no reliable hits — too many false positives without proper xref/decompiler tooling).A disassembler with jump table / call graph analysis (e.g. Ghidra with a PS1/MIPS loader, or an existing PSX ISO project in IDA) would very likely find the actual decompression loop quickly by tracing what function is called right after the top-level offset table lookup for HUMAN.TEX/TEAM0X.BIN.6. Files attachedHUMAN.TEX (raw, extracted top-level + level-2 sub-blocks included)TEAM00.BINBG0.BINBR.TEXCAPTIN.EXE (main executable, for disassembly)7. What I'm looking forConfirmation/correction of the nested offset-table structure aboveThe actual pixel decompression algorithm for the 00 00 03 BF 01 FF-style chunks (HUMAN.TEX/TEAM0X.BIN)Whether BR.TEX's type-2 chunks are compressed the same way or differentlyAny existing tools/scripts for Winning Eleven 2002-family PS1 titles that might already handle this container format, since this engine is shared across several Konami PS1 sports titles from the same era.Thanks in advance to anyone who can take this further!Captain Tsubasa J - Get in the Tomorrow (Japan)77.zipThe game uses a simple LZSS: flag byte bit by bit, 1 = literal, 0 = offset/length copy.These files use the same decompression routine, but not the same "container".Human.tex belowLoad screen Edited 1 hour ago1 hr by Rabatini
Create an account or sign in to comment