don't click here

How to port Sonic 2's level art loader to Sonic 1

Discussion in 'Engineering & Reverse Engineering' started by Clownacy, Apr 12, 2014.

  1. Clownacy

    Clownacy

    Tech Member
    1,158
    840
    93
    ...Huh?

    I expected the chunks to be hardcoded to the beginning of the RAM in some areas, but just changing the Variable worked fine for me. In sonic.asm, looking at the BlocksInROM checks, 16x16 isn't use by default, but 256x256+4 is, so I changed all instances of that to 16x16, and built, coming to the conclusion of my earlier post. After that, I just opened Variables.asm and changed 256x256 to
    Code (ASM):
    1. v_256x256:  = $FFFFB004
    It's working fine for me. Isn't 'Line 1111 Emulation' related to Floating Point? I don't know how that'd even be involved.
     
  2. RetroKoH

    RetroKoH

    Member
    1,734
    112
    43
    S1Fixed: A successor to ReadySonic
    Well I tried it on ReadySonic... works fine and dandy.

    Tried it on my hack... got the error. Would you like to grab a copy by chance and give it a run? I've no idea what's going on but its pissing me off.
     
  3. Clownacy

    Clownacy

    Tech Member
    1,158
    840
    93
    I guess, I'll head to PM.
     
  4. RetroKoH

    RetroKoH

    Member
    1,734
    112
    43
    S1Fixed: A successor to ReadySonic
    Scratch that I think I found the issue...


    Code (Text):
    1.  
    2. LoadZoneTiles:  ; REV C EDIT - FASTER LEVEL ART LOADING (CLOWNACY)
    3.                 moveq   #0,d0                   ; Clear d0
    4.                 move.b  (v_zone).w,d0           ; Load number of current zone to d0
    5.                 lsl.w   #4,d0                   ; Multiply by $10, converting the zone ID into an offset
    6.                 lea     (LevelHeaders).l,a2     ; Load LevelHeaders's address into a2
    7.                 lea     (a2,d0.w),a2            ; Offset LevelHeaders by the zone-offset, and load the resultant address to a2
    8.                 move.l  (a2)+,d0                ; Move the first longword of data that a2 points to to d0, this contains the zone's first PLC ID and its art's address. The auto increment is pointless as a2 is overwritten later, and nothing reads from a2 before then
    9.                 andi.l  #$FFFFFF,d0             ; Filter out the first byte, which contains the first PLC ID, leaving the address of the zone's art in d0
    10.                 movea.l d0,a0                   ; Load the address of the zone's art into a0 (source)
    11.                 lea     ($FF0000).l,a1        ; Load Chunk Table/StartOfRAM (in this context, an art buffer) into a1 (destination)
    12.                 bsr.w   KosDec                  ; Decompress a0 to a1 (Kosinski compression)
    The second to last line... that I copy/pasted from you was THIS
    Code (Text):
    1.  
    2.                 lea     (v_256x256).l,a1        ; Load Chunk Table/StartOfRAM (in this context, an art buffer) into a1 (destination)
    3.  


    I changed it to the hardcoded location and it fixed the problem. Basically changing the 256x256 was causing the problem. Your code above is supposed to read from the start of the RAM, as you pointed out... the line that I changed now reads as it should, in the event that one wants/needs to change the v_256x256 location.
     
  5. Clownacy

    Clownacy

    Tech Member
    1,158
    840
    93
    Oh man, I can't believe I missed that!

    I'll edit the code to read from startofRAM. Everywhere else in the disasm uses the hardcoded address instead of v_256x256 for the buffer. I must have picked up the opposite from the S2 disasm, where Chunk_Table is used.

    EDIT: Oh great, I've been using a vanilla ReadySonic this whole time...

    EDIT2: You were right, Blocks weren't the only problem. Leaving the Chunks where they were, Labyrinth Zone (Act 1) still had a minor glitch, moving v_256x526 fixed it.

    Let's hope this hack stays waterproof from now on, and save us the headaches.

    EDIT3: :specialed: I spent ages wondering if I should have included this in the annotated code, and I completely forgot about it! I may know why you got a calculation error.

    Remember this?:
    Code (ASM):
    1. move.w  a1,d3                   ; Move a word of a1 to d3, note that a1 doesn't exactly contain the address of v_256x256/StartOfRAM anymore, after KosDec, a1 now contains v_256x256/StartOfRAM offsetted by the size of the file decompressed to it, the result is that d3 now contains the length of the file that was decompressed
    2.  
    It uses a nice trick to obtain the decompressed art's size. You see, initially, a1 is $FF0000, after KosDec, it's $FF0000+SizeOfDecompressed file. So how is d3 JUST SizeOfDecompressed? It only moves a word! This cuts off the $FF, and, since the final word is $0000-based, nothing else needs to be done.

    So what if the address doesn't end with $0000? You get an inaccurate art size. I'd imagine that somewhere along thinking that the art is $B000 bytes bigger, the calculations begin using Floating Point logic, giving you the error, since there's no entry in the Vector Table to handle the logic, instead being an error trap.