don't click here

Random freezing (ROM build glitch)

Discussion in 'Engineering & Reverse Engineering' started by redhotsonic, Feb 16, 2012.

  1. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber
    Apologies if this is in the wrong forum.

    Here I am again, another problem, probably the weirdest one yet, but it gets rid of a lot of bugs! Any help would be most grateful!



    You can skip this story (spoiler) if you like and get on with the real problem.



    I have put Sonic 3 sprites in my game, so as you could imagine, the Sonic running across the SEGA logo went wrong. I couldn't be bothered to fix it. But later on, I put RHS in the game, and he uses the traditional Sonic 2 sprites. So, I thought I would fix Sonic at the SEGA logo. I made it load RHS's art, his running DPLC's and mappings, but no matter what I tried, it never worked.



    Here are some codes that I've done, can you see where I went wrong?



    You might want to read about the problem I have first before looking into depth about this code

    Code (Text):
    1. ; ===========================================================================
    2. ; ----------------------------------------------------------------------------
    3. ; Object B0 - SEGA screen? (Unknown)
    4. ; ----------------------------------------------------------------------------
    5.  
    6.  
    7. ; Sprite_3A1DC:
    8. ObjB0:
    9.  moveq #0,d0
    10.  move.b routine(a0),d0
    11.  move.w off_3A1EA(pc,d0.w),d1
    12.  jmp off_3A1EA(pc,d1.w)
    13.  
    14.  
    15.  
    16. ; ===========================================================================
    17.  
    18.  
    19.  
    20. off_3A1EA:
    21.  dc.w loc_3A1F6-off_3A1EA
    22.  dc.w loc_3A2F4-off_3A1EA; 1
    23.  dc.w loc_3A32C-off_3A1EA; 2
    24.  dc.w loc_3A396-off_3A1EA; 3
    25.  dc.w loc_3A3CC-off_3A1EA; 4
    26.  dc.w return_3A3F6-off_3A1EA; 5
    27.  
    28.  
    29. ; ===========================================================================
    30.  
    31.  
    32.  
    33. loc_3A1F6:
    34.  bsr.w LoadSubObject
    35.  move.w #$1E8,x_pos(a0)
    36.  move.w #$F0,objoff_A(a0)
    37.  move.w #$B,objoff_2A(a0)
    38.  move.w #2,($FFFFF662).w
    39.  bset #0,render_flags(a0)
    40.  bset #0,status(a0)
    41.  lea ($FFFFE138).w,a1
    42.  lea byte_3A76C(pc),a2
    43.  moveq #0,d0
    44.  moveq #$22,d6
    45.  
    46.  
    47.  
    48. loc_3A22A:
    49.  move.b (a2)+,d0
    50.  add.w d0,(a1)
    51.  addq.w #8,a1
    52.  dbf d6,loc_3A22A
    53.  lea off_3A294(pc),a1
    54. ; lea (ArtUnc_Sonic).l,a3
    55.   lea (ArtUnc_S2sonicart).l,a3
    56.  
    57. conloc_3A22A:
    58.  lea (Metablock_Table).l,a5
    59.  moveq #3,d5
    60.  
    61.  
    62.  
    63. ; etc, etc


    Code (Text):
    1. ; ===========================================================================
    2.  ; These next four things are pointers to Sonic's dereferenced
    3.  ; DPLC entries of his "running animation" frames for the SEGA screen.
    4.  ; I want that DPLC data split into a binary file for use with editors,
    5.  ; but unfortunately there's no way to refer to BINCLUDE'd bytes
    6.  ; from within AS, so I put an educated guess (default) here and
    7.  ; run an external program (fixpointer.exe) to fix it later.
    8. ; WARNING: the build script needs editing if you rename this label
    9.  
    10.  
    11. ;off_3A294:
    12. ; dc.l (MapRUnc_Sonic+$33A) ;dc.l word_7181A
    13. ; dc.l (MapRUnc_Sonic+$340) ;dc.l word_71820
    14. ; dc.l (MapRUnc_Sonic+$346) ;dc.l word_71826
    15. ;  dc.l (MapRUnc_Sonic+$34C) ;dc.l word_7182C
    16.  
    17.  
    18. off_3A294: dc.l MapRUnc_RHS_2DE  ; 0 ; DATA XREF: h+232C0t h+23324o ...
    19.   dc.l MapRUnc_RHS_2E4  ; 1
    20.   dc.l MapRUnc_RHS_2EA  ; 2
    21.   dc.l MapRUnc_RHS_2F0  ; 3
    22. ; The above is RHS's running DPLC's, I've trippled checked
    23.  
    24.  
    25. word_3A2A4:
    26.  dc.w $FFFF,    0,$FFFF, $B00, $201
    27.  dc.w $FFFF,  $C0,$FFFF, $E00, $303; 5
    28.  dc.w $FFFF, $2C0,$FFFF,$1600, $201; 10
    29.  dc.w $FFFF, $380,$FFFF,$1900, $303; 15
    30.  dc.w $FFFF, $580,$FFFF,$2100, $201; 20
    31.  dc.w $FFFF, $640,$FFFF,$2400, $303; 25
    32.  dc.w $FFFF, $840,$FFFF,$2C00, $201; 30
    33.  dc.w $FFFF, $900,$FFFF,$2F00, $303; 35


    Code (Text):
    1. ; ------------------------------------------------------------------------------
    2. ; sprite mappings
    3. ; Gigantic Sonic (2x size) mappings for the SEGA screen
    4. ; ------------------------------------------------------------------------------
    5. ;ObjB1_MapUnc_3A5A6: BINCLUDE "S3Sonic/mapsega.bin"
    6. ;ObjB1_MapUnc_3A5A6:
    7. ; BINCLUDE "mappings/sprite/objB1.bin" ;try thisArtUnc_3A5A6
    8. ArtUnc_3A5A6:    ; DATA XREF: h+23616o h+23620o ...
    9.   dc.w word_3A5B0-ArtUnc_3A5A6; 0
    10.   dc.w word_3A5E2-ArtUnc_3A5A6; 1
    11.   dc.w word_3A614-ArtUnc_3A5A6; 2
    12.   dc.w word_3A646-ArtUnc_3A5A6; 3
    13.   dc.w word_3A678-ArtUnc_3A5A6; 4
    14. word_3A5B0: dc.w 6   ; DATA XREF: h+23632o
    15.   dc.w $D80F,    0,    0,$FFF0; 0
    16.   dc.w $D807,  $10,    8,  $10; 4
    17.   dc.w $F80F,  $18,   $C,$FFE0; 8
    18.   dc.w $180F,  $28,  $14,$FFE0; 12
    19.   dc.w $F80F,  $38,  $1C,    0; 16
    20.   dc.w $180F,  $48,  $24,    0; 20
    21. word_3A5E2: dc.w 6   ; DATA XREF: h+23632o
    22.   dc.w $D80F,  $58,  $2C,$FFF0; 0
    23.   dc.w $D807,  $68,  $34,  $10; 4
    24.   dc.w $F80F,  $70,  $38,$FFE0; 8
    25.   dc.w $180F,  $80,  $40,$FFE0; 12
    26.   dc.w $F80F,  $90,  $48,    0; 16
    27.   dc.w $180F,  $A0,  $50,    0; 20
    28. word_3A614: dc.w 6   ; DATA XREF: h+23632o
    29.   dc.w $D80F,  $B0,  $58,$FFF0; 0
    30.   dc.w $D807,  $C0,  $60,  $10; 4
    31.   dc.w $F80F,  $C8,  $64,$FFE0; 8
    32.   dc.w $180F,  $D8,  $6C,$FFE0; 12
    33.   dc.w $F80F,  $E8,  $74,    0; 16
    34.   dc.w $180F,  $F8,  $7C,    0; 20
    35. word_3A646: dc.w 6   ; DATA XREF: h+23632o
    36.   dc.w $D80F, $108,  $84,$FFF0; 0
    37.   dc.w $D807, $118,  $8C,  $10; 4
    38.   dc.w $F80F, $120,  $90,$FFE0; 8
    39.   dc.w $180F, $130,  $98,$FFE0; 12
    40.   dc.w $F80F, $140,  $A0,    0; 16
    41.   dc.w $180F, $150,  $A8,    0; 20
    42. word_3A678: dc.w 2   ; DATA XREF: h+23632o
    43.   dc.w $FC00,    0,    0,$FFF8; 0
    44.   dc.w $FC00,    0,    0,    0; 4
    45.   even







    Anyway, I was doing some work on something to my hack, completely unrelated to the SEGA screen. I was getting frustrated at what I was doing, and kept asking REGEN to open my ROM when it was in the middle of building, and as you can imagine:



    "This file does not exist" (because it's in the middle of building).



    Anyway, just before it finished building, the ROM opened, and there he was! Sonic running across the SEGA screen! WTF? I was so happy he was there.



    Then, when I next built the ROM, he was gone again? I haven't touched it, what happened? Then I tried building it again and tried re-opening the ROM over and over, and Sonic loaded again.





    It seems if I open the ROM just before it finishes building, Sonic is there. If I reload the same ROM later, because it finished building ages ago, Sonic has gone again.





    Funnily enough, if I load the ROM before it finished building and Sonic is there, all my previous bugs are gone. No more random freezes, no more sprite glitching (well I played through my whole ROM twice this way and never came across it, even by going to the places it normally happens, it was fine).





    Here is a video demonstrating what I am trying to say. As you can see, after if finally opens the ROM, Sonic is there. Resetting the ROM still shows Sonic (as you can see) But when I close the ROM then reload the same ROM, Sonic has gone again. Resetting the ROM stills shows no Sonic.



    Sorry for the crap sound and video quality, the video freezes at the 0:13 point for a second for some reason





    Has anyone else ever encountered this bug and no how to fix it? I'd greatly appreciate it.



    P.S I do have this



    Code (Text):
    1. ;---------------------------------------------------------------------------------------
    2. ;Uncompressed art
    3. ;
    4. ;Patterns for Sonic 2
    5. ;---------------------------------------------------------------------------------------
    6.  align $20000
    7. ArtUnc_S2sonicart:     BINCLUDE "art\uncompressed\RHSart.bin"


    With the alignment, Sonic isn't there. Without the alignment, there's garbled "Knuckles" sprites.



    [​IMG]

    Loading the ROM quickly with $20000 alignment



    [​IMG]

    Loading the ROM anytime with $20000 alignment



    [​IMG]

    Loading the ROM quickly without alignment



    [​IMG]

    Loading the ROM anytime without alignment





    Cheers,

    redhotsonic


    EDIT: Forgot to mention, I'm using Xenowhirl's 2007 disassembly
     
  2. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,161
    65
    28
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    Try doing this first: find label loc_3A246 and locate the following block of code:
    Code (Text):
    1.     andi.w  #$FFF,d0
    2.     lsl.w   #5,d0
    3.     lea (a3,d0.w),a4 ; source ROM address of tiles to copy
    Replace it by this:
    Code (Text):
    1.     andi.l  #$FFF,d0
    2.     lsl.l   #5,d0
    3.     lea (a3,d0.l),a4 ; source ROM address of tiles to copy
    Build and see if it works.
     
  3. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber
    It did something, but it didn't work. With your new instructions, with or without the alignment:


    [​IMG]

    Loading up the ROM just before building finishes.


    [​IMG]
    [​IMG]
    [​IMG]
    [​IMG]

    Loading up the ROM anytime after


    So, even when loading up the ROM quickly, he no longer works.
     
  4. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,161
    65
    28
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    That was to fix the issue of needing the alignment, as well as a few other problems that could crop up; but it clearly wasn't enough. Now lets go to part 2: open build.bat and edit it; you want to find 'MapRUnc_Sonic' and replace by the mappings file name in question. The 3 numbers after it ('$2D 0 4') are the mappings frame of the first running frame to use ($2D for Sonic in vanilla S2), the destination offset (the '0'; leave it alone) and the number of frames of running (the '4' -- vanilla S2 Sonic runs with 4 frames).
     
  5. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber
    Code (Text):
    1. off_3A294 MapRUnc_Sonic $2D 0 4
    Sonic's running maps do start at $2D, so no point changing that. So I tried this:

    Code (Text):
    1. off_3A294 MapRUnc_RHS $2D 0 4

    Now when I build, at the end of the building process, it says:

    but

    When I now load the game, at any time, Sonic is there. So this has worked!

    But if it can't find it, how did it work? =P
     
  6. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,161
    65
    28
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    At the end of s2.asm, add MapRUnc_RHS to the 'shared' line you find there. The reason it is working anyway is because you made sure to have the correct locations in 'off_3A294'; that line in build.bat fixes several locations in ROM to point to what they should point to.
     
  7. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber
    Cheers mate, it worked a treat.

    EDIT:

    I'm sorry, I do not understand.

    Code (Text):
    1. ;---------------------------------------------------------------------------------------
    2. ;Uncompressed art
    3. ;
    4. ;Patterns for Sonic 2
    5. ;---------------------------------------------------------------------------------------
    6.     align $20000
    7. ArtUnc_S2sonicart:     BINCLUDE "art\uncompressed\RHSart.bin"
    8.  
    9. Nem_LevSel:     binclude    "LS_BG/GFX2.bin"
    10.             even
    11.  
    12. Eni_LevSel:     binclude    "LS_BG/Map2.bin"
    13.             even
    14.  
    15. Pal_LevSel:     binclude    "LS_BG/Pal2.bin"
    16.             even
    17.  
    18. EndOfRom:
    19.     END
    Where would I put it to?



    Also, I have another question that is off-topic to this one but saves me making a new topic.

    Is there a way to display a message in the hack when the game freezes (similar to Sonic 1)? Every now and then, my hack suddenly freezes for no reason whatsoever. Normally it happens when you're about to get hurt like in this video. (iignore the flash at the 6 second mark, that was the video, no the hack itself)




    But then again, it freezes for no reason at all:

    [​IMG]

    Sonic is just running here, but it's actually frozen at this point. Because I have no leads to why it's going wrong, can I make it display something on where it went wrong? Regen only displays this when frozen:

    Code (Text):
    1. ErrorTrap:
    2.     nop
    3.     nop
    4.     bra.s   ErrorTrap
    I will say, I have recently ported the S3K object manager in, and it never froze half as bad 'til then, so maybe I've gone wrong there. But who knows...
     
  8. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,161
    65
    28
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    Just before EndOfRom, add the line
    Code (Text):
    1.     shared EndOfRom
    Indeed porting the S3K object manager is fraught with peril, and any misstep can cause problems. As for the freezes: you may want to try my address error debugger (which I will be updating as soon as I get a mod to unlock the thread). If it is an address error, it will help a great deal.
     
  9. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber
    Haha, Sonic at the SEGA logo has gone wrong again =P

    I think I will just put up with the error message, at least Sonic loads up right that way =P


    Cheers, I will test this out and get back to see what the results are

    EDIT:
    Can't go about trying it.
     
  10. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,161
    65
    28
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    Oops, sorry; that was meant to be
    Code (Text):
    1.     shared MapRUnc_RHS
    I don't know why I pasted it wrong, but I failed to notice it.

    For what is worth, I will be updating it tomorrow (Aquaslash has graciously unlocked the thread for me), as soon as I finish up a couple of things.
     
  11. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber
    That's what I did. Sonic is all garbled again. If I don't put it in, I get the error message, but he's fine =P

    Okay, mate. Will check by tomorrow




    EDIT: Okay, my game froze again. Sonic has disapeared. It's near enough the same place as the last shot.

    [​IMG]


    But this time, REGEN chucked this at me, something different from the normal errortrap:

    [​IMG]

    No idea what it means though.



    To me, I'm thinking it's something that I've done with respawn_index:

    Code (Text):
    1. ; conventions followed by most objects:
    2. x_vel =         $10 ; and $11 ; horizontal velocity
    3. y_vel =         $12 ; and $13 ; vertical velocity
    4. y_radius =      $16 ; collision width / 2
    5. x_radius =      $17 ; collision height / 2
    6. anim_frame =        $1B
    7. anim =          $1C
    8. next_anim =     $1D
    9. respawn_index =     $1E ; and $1F, it's now a word ; was just 23.
    10. anim_frame_duration =   $23 ; was $1E and $1F.  Changed them all to bytes and made neccessary changes
    11. status =        $22 ; note: exact meaning depends on the object... for sonic/tails: bit 0: leftfacing. bit 1: inair. bit 2: spinning. bit 3: onobject. bit 4: rolljumping. bit 5: pushing. bit 6: underwater.
    12. routine =       $24 ; used to be 24
    13. routine_secondary = $25 ; used to be 25
    14. angle =         $26 ; angle about the z=0 axis (360 degrees = 256)
    15. ; ---------------------------------------------------------------------------
    16. ; conventions followed by many objects but NOT sonic/tails:
    17. collision_flags =   $20
    18. collision_property =    $21
    19. ; $23 is free
    20. subtype =       $28

    You see, respawn_index HAS to be a word, so needed to find space somewhere. I know "anim_frame_duration" used to be a word, but I made the changes to make it work as a byte. For example, here is GameOver:

    Code (Text):
    1. loc_13FE2:
    2.     move.b  #$F0,anim_frame_duration(a0) ; anim_frame_duration - change from .w to .b
    3. ; the above was .w $2D0, now .b $F0
    4.     addq.b  #2,routine(a0)
    5.     rts
    6. ; ===========================================================================
    7.  
    8. loc_13FEE:
    9.     btst    #0,mapping_frame(a0)
    10.     bne.w   BranchTo17_DisplaySprite
    11.         ;tst.w  (Game_paused).w ; is game already paused?
    12.     ;beq.w  loc_1407E       ; if yes, branch
    13.     move.b  (Ctrl_1_Press).w,d0
    14.     or.b    (Ctrl_2_Press).w,d0
    15.     andi.b  #$70,d0
    16.     bne.s   loc_14014
    17.     tst.b   anim_frame_duration(a0) ; anim_frame_duration - change from .w to .b
    18.     beq.s   loc_14014
    19. ; -----------------------------------------------------------------------------------
    20.   move.b  ($FFFFFE05).w,d0 ; Move Game Frame timer to d0
    21.   andi.b  #3,d0 ; andi by 3
    22.   bne.s + ; if d0 does NOT equal 0, skip subtracting 1 byte from anim_frame_duration
    23. ; otherwise, subtract 1 byte from anim_frame_duration
    24. ; -----------------------------------------------------------------------------------
    25.     subq.b  #1,anim_frame_duration(a0) ; anim_frame_duration - change from .w to .b
    26. + ; new label, so the above can skip the subtraction of anim_frame_duration correctly
    27.     bra.w   DisplaySprite
    Instead of anim_frame_duration counting down every frame, it counts down every 4 frames. I tested it and it worked perfectly fine.

    This is my only guess for the random freezes, 'cause it's only started to happen since the port of the S3K object manager.


    EDIT: I KNOW WHAT'S CAUSING THE FREEZING. It's definately the respawn_index. Most freezing happens when I'm about to touch something that used to be there before (destroyed or not).

    Check this video. Notice that I jump over the crab badnik, but when I go back to him, he's not there. Run into his location, and ta-da! Froze.

    [​IMG]