Sonic and Sega Retro Message Board: How to port Sonic 2's level art loader to Sonic 1 - Sonic and Sega Retro Message Board

Jump to content

Hey there, Guest!  (Log In · Register) Help
  • 2 Pages +
  • 1
  • 2
    Locked
    Locked Forum

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

#16 User is offline Super Egg 

Posted 22 April 2014 - 11:48 PM

  • Master of MS Paint.
  • Posts: 144
  • Joined: 01-July 10
  • Gender:Male
  • Location:Tomball, TEXAS
  • Project:Sonic 2 beta 3 hoax, SONIC X ABRIDGED BITCH!!!
  • Wiki edits:46
Odd. I've encountered no problems with this in Sonic 2 Beta. In fact...

https://www.dropbox....ep4/example.bin


Try this code instead, it may fix some of your issues. It is slightly modified and is from the Sonic 2 Rev 2 disasm. It's almost exactly the same as above.
Due note: I have never worked with the S1 HG disasm, so I'm only assuming this works. I've also taken the opportunity to make it AS friend, as this is from a non-AS disasm.

LoadZoneTiles: ; loc_5B98: 
        moveq   #$00,d0
        move.b  ($FFFFFE10).w,d0
        add.w   d0,d0
        add.w   d0,d0
        move.w  d0,d1
        add.w   d0,d0
        add.w   d1,d0
        lea     (TilesMainTable).l,a2    ; loc_3E390
        lea     (a2,d0.w),a2
        move.l  (a2)+,d0
        andi.l  #$FFFFFF,d0
        move.l  d0,a0
        lea     ($FFFF0000),a1
        bsr     KosinskiDec             ; loc_1E36
        move.w  a1,d3
        move.w  d3,d7
        andi.w  #$FFF,d3
        lsr.w   #$01,d3
        rol.w   #$04,d7
        andi.w  #$F,d7
loc_5BFA:                
        move.w  d7,d2
        lsl.w   #$07,d2
        lsl.w   #$05,d2
        move.l  #$FFFFFF,d1
        move.w  d2,d1
        jsr     (QueueDMATransfer).l
        move.w  d7,-(a7)
        move.b  #$C,(v_vbla_routine).w
        bsr.w   WaitForVBla
        bsr     RunPLC               ; loc_1B86
        move.w  (a7)+,d7
        move.w  #$800,d3
        dbra    d7, loc_5BFA
        rts



edit: fixed
This post has been edited by Super Egg: 23 April 2014 - 08:33 AM

#17 User is offline Clownacy 

Posted 23 April 2014 - 01:20 PM

  • Needs to make an avatar
  • Posts: 309
  • Joined: 06-July 13
  • Gender:Male
  • Location:Englandland
Looking at the code, if the only difference is the "add.w d0,d0"s at the top, then that's just the LevelHeaders/TilesMainTable offsetting, which I changed to match Sonic 1's.

Interestingly, in its native form, your code didn't work, I assume the offsetting was incompatible with Sonic 1, the result was that the art was never DMA'd, yet the bug appeared. Simply commenting out the bsr to the code, however, also caused the art to not be DMA'd, but the bug vanished.

EDIT: I'm no Kosinski wizard, but I'm getting closer to blaming KosDec for this: In the code, comment out the branch to QueueDMATransfer. Save and build. The art doesn't show up, yes, but the bug's there. Now comment out both that and the branch to KosDec. Save and build, bug vanishes. This is the case with the original KosDec.
This post has been edited by Clownacy: 23 April 2014 - 01:25 PM

#18 User is offline Super Egg 

Posted 23 April 2014 - 02:06 PM

  • Master of MS Paint.
  • Posts: 144
  • Joined: 01-July 10
  • Gender:Male
  • Location:Tomball, TEXAS
  • Project:Sonic 2 beta 3 hoax, SONIC X ABRIDGED BITCH!!!
  • Wiki edits:46
Odd. Ok then, I'll play around with the S1 HG disasm. Let me just prepare the full body wash for when I'm done....

#19 User is offline Clownacy 

Posted 31 May 2014 - 10:29 AM

  • Needs to make an avatar
  • Posts: 309
  • Joined: 06-July 13
  • Gender:Male
  • Location:Englandland
Allow me to say that this is really freaking weird.

Hello again, King. I've returned to looking into our problem, and I believe it to be related to ReadySonic's BlocksInROM. Looking at it a second time, it makes a whole lot more sense.

Where to begin... Well, in ReadySonic, ever try having RAM chunks and ROM blocks? It breaks everything. It's because RAM chunks use the 256x256 RAM space. RAM blocks use the 16x16 RAM space. When ReadySonic switches it to ROM, the RAM spaces are only used for addresses, the ROM addresses of the current chunks/blocks to use. For better organisation, these longwords aren't located at the first four bytes of 256x256 and 16x16, but the first eight bytes of 256x256, with the blocks' address sitting neatly behind the chunks'. If you have RAM chunks and ROM blocks, the blocks' address is overwritten with decompressed chunk data.

Now, what else if 256x256 used for? This hack's art buffer.

I might have been right on my earlier post, though I don't fully understand the Sonic Engine's psudo-multithread ability (wait for vblank), so I can't confirm it: It all works too fast. You see, for whatever reason, the game is busy reading the block address at 256x256+4 while level art is being written to it. Moving the address of where the block address is stored (for example, to 16x16) seemingly fixes the issue. I still don't understand why the game doesn't wait for the blocks' location to be set/data to be decompressed before it reads it.

I mean, the level art decompression routine is called before the block and chunk decompression routine. But the thing that actually reads the data is DrawBlocks, and I don't know where that code lies in terms of execution times.

tl;dr
Move the 'block/chunk ROM address' RAM addresses to somewhere that won't get overwritten by the level art.

If anyone else can chip in on why the game reads this data so early, please do.
This post has been edited by Clownacy: 31 May 2014 - 01:33 PM

#20 User is offline KingofHarts 

Posted 31 May 2014 - 09:10 PM

  • Call me back when people stop shitting in the punch bowl...
  • Posts: 1480
  • Joined: 07-August 10
  • Gender:Male
  • Wiki edits:1
Awesome feedback on this, I'll try this out and report back.

EDIT 2: I suffered from a case of stupidity from my previous post... lemme try this again:


So... I currently have them located at:
v_256x256:		=   $FF0000	; 256x256 tile mappings address (4 bytes)
v_16x16:		=   $FF0004	; 16x16 block mappings address (4 bytes)


The 16x16 is not at its original location noted below.
;v_16x16:		= $FFFFB000    ; 16x16 block mappings address (4 bytes)


Moving them back seems ok, and I think it fixes SOME of the issue.
Attempting to move the v_256x256 to that same general area... so as to have THIS:
v_256x256:		=   $FFFFB000	; 256x256 tile mappings address (4 bytes)
v_16x16:		=   $FFFFB004	; 16x16 block mappings address (4 bytes)


This causes errors. I get a screen that says the following:

Quote

"LINE 1111 EMULATOR $FAEAEBEA"


In fact.... moving that address to ANY other location causes issues.
IDK what the hell I've gone and done, but it seems to be stuck there in my hack
This post has been edited by KingofHarts: 01 June 2014 - 10:54 AM

#21 User is offline Clownacy 

Posted 01 June 2014 - 11:11 AM

  • Needs to make an avatar
  • Posts: 309
  • Joined: 06-July 13
  • Gender:Male
  • Location:Englandland
...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
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.

#22 User is offline KingofHarts 

Posted 01 June 2014 - 11:16 AM

  • Call me back when people stop shitting in the punch bowl...
  • Posts: 1480
  • Joined: 07-August 10
  • Gender:Male
  • Wiki edits:1
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.

#23 User is offline Clownacy 

Posted 01 June 2014 - 11:32 AM

  • Needs to make an avatar
  • Posts: 309
  • Joined: 06-July 13
  • Gender:Male
  • Location:Englandland
I guess, I'll head to PM.

#24 User is offline KingofHarts 

Posted 01 June 2014 - 11:35 AM

  • Call me back when people stop shitting in the punch bowl...
  • Posts: 1480
  • Joined: 07-August 10
  • Gender:Male
  • Wiki edits:1
Scratch that I think I found the issue...


LoadZoneTiles:  ; REV C EDIT - FASTER LEVEL ART LOADING (CLOWNACY)
                moveq   #0,d0                   ; Clear d0
                move.b  (v_zone).w,d0           ; Load number of current zone to d0
                lsl.w   #4,d0                   ; Multiply by $10, converting the zone ID into an offset
                lea     (LevelHeaders).l,a2     ; Load LevelHeaders's address into a2
                lea     (a2,d0.w),a2            ; Offset LevelHeaders by the zone-offset, and load the resultant address to a2
                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
                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
                movea.l d0,a0                   ; Load the address of the zone's art into a0 (source)
                lea     ($FF0000).l,a1        ; Load Chunk Table/StartOfRAM (in this context, an art buffer) into a1 (destination)
                bsr.w   KosDec                  ; Decompress a0 to a1 (Kosinski compression)


The second to last line... that I copy/pasted from you was THIS
                lea     (v_256x256).l,a1        ; Load Chunk Table/StartOfRAM (in this context, an art buffer) into a1 (destination)





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.

#25 User is offline Clownacy 

Posted 01 June 2014 - 11:39 AM

  • Needs to make an avatar
  • Posts: 309
  • Joined: 06-July 13
  • Gender:Male
  • Location:Englandland
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?:
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



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.
This post has been edited by Clownacy: 01 June 2014 - 12:06 PM

  • 2 Pages +
  • 1
  • 2
    Locked
    Locked Forum

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users