OBJ file

From NeoGeo Development Wiki
Jump to: navigation, search

OBJ files contain the sprites graphics (equivalent to the C ROMs on cartridge systems). Data is compressed however using a simple RLE compression removing runs with a value of 0x00000000. Once decompressed the format is described here: sprite graphics format.

RLE compression

  • First long word value is the compressed data length (/4-1).
  • The system works by checking single long words at a time.
  • When a zero value is found it is stored and the next value is checked. A fill of zero is created to match the value read unless it is zero.



0x00000007, 0x11111111, 0x00000000, 0x00000003, 0x22222222, 0x00000000, 0x00000000, 0x33333333, 0x44444444


0x11111111, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x22222222, 0x00000000, 0x33333333, 0x44444444

This system will not compress data very well unless there are large areas of zero data within the decompressed sprite data. This is due to a single zero value being inflated by 100% to let the decompressor know it is not a run. To my current knowledge only Art of Fighting uses the OBJ format.

For reference below is a 68000 code snippet from bios TOP-SP1 that handles decompresses.

C0BC5A  203C 00E0 0000             MOVE.L   #0xE00000,D0
C0BC60  D0AD 7EF4                  ADD.L    (0x7EF4,A5),D0
C0BC64  2240                       MOVEA.L  D0,A1                      <---- Where to decompress data
C0BC66  206D 7EF8                  MOVEA.L  (0x7EF8,A5),A0
C0BC6A  7000                       MOVEQ    #0x0,D0
C0BC6C  2E18                       MOVE.L   (A0)+,D7                   <---- Get Length
C0BC6E  6738                       BEQ.S    *+0x3A [0xC0BCA8]
C0BC70  22D8                       MOVE.L   (A0)+,(A1)+                <---- Move single long word
C0BC72  6712                       BEQ.S    *+0x14 [0xC0BC86]          <---- Branch if zero.
C0BC74  51CF FFFA                  DBF      D7,*-0x4 [0xC0BC70]        <---- check data end
C0BC78  2009                       MOVE.L   A1,D0
C0BC7A  0480 00E0 0000             SUBI.L   #0xE00000,D0
C0BC80  2B40 7EF4                  MOVE.L   D0,(0x7EF4,A5)
C0BC84  4E75                       RTS

C0BC86  2C18                       MOVE.L   (A0)+,D6                   <---- Get next value
C0BC88  51CE 0014                  DBF      D6,*+0x12 [0xC0BC9E]       <---- Decompress if non zero
C0BC8C  51CF FFE2                  DBF      D7,*-0x1C [0xC0BC70]       <---- Check data end
C0BC90  2009                       MOVE.L   A1,D0
C0BC92  0480 00E0 0000             SUBI.L   #0xE00000,D0
C0BC98  2B40 7EF4                  MOVE.L   D0,(0x7EF4,A5)
C0BC9C  4E75                       RTS

C0BC9E  22C0                       MOVE.L   D0,(A1)+                   <---- Recreate zero run
C0BCA0  51CE FFFC                  DBF      D6,*-0x2 [0xC0BC9E]        <---- and Loop until complete
C0BCA4  51CF FFCA                  DBF      D7,*-0x34 [0xC0BC70]       <---- Check data end

C0BCA8  2009                       MOVE.L   A1,D0
C0BCAA  0480 00E0 0000             SUBI.L   #0xE00000,D0
C0BCB0  2B40 7EF4                  MOVE.L   D0,(0x7EF4,A5)
C0BCB4  4E75                       RTS