Basic Questions and Answers Thread

Discussion in 'Discussion & Q&A' started by Malevolence, Jul 7, 2009.

  1. Devon

    Devon A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Member

    Joined:
    Aug 26, 2013
    Messages:
    1,377
    Location:
    your mom
    May I see the code used to implement it, so I can get an idea of why it's doing that? It's definitely not doing that because you somehow triggered some "undiscovered code" to do that, that's for sure, but I am still curious.
     
    DeltaWooloo likes this.
  2. Hame

    Hame Peepee Poopoo Member

    Joined:
    Jan 12, 2021
    Messages:
    57
    Location:
    Spain
    here is the disassembly (do what you want), check Sonic_panCamera.asm and Deformlayers, in movescreen I have changed sub#100 to sub #120 (I think). I have modified the code a bit so that you only have to spindash at the beginning of the level, if you do, go forward, wait for the camera to stabilize and go back
     

    Attached Files:

    • bug.rar
      File size:
      3.4 MB
      Views:
      55
  3. Devon

    Devon A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Member

    Joined:
    Aug 26, 2013
    Messages:
    1,377
    Location:
    your mom
    Okay, this is gonna be a doozy of an explanation, but it's an easy fix.

    This is actually exactly why it's broken. The problem is that when you spindash, the camera delay counter gets set to a multiple of $100. In MoveScreenHoriz, when it subtracts $120, it takes no precaution to check if it has gone under 0 (which CAN happen since you are subtracting a value that's not likely to be divisible with the camera delay counter value), and as a result when it does, it'll just keep subtracting and keep wrapping around until it somehow does go to 0. This is bad, because this value is used as an index for Sonic's recorded position table, which is how the lagging behind mechanism works. If it keeps rolling through that table, then it's possible that if you move far enough while it does so, it'll jump the camera back the distance you moved. The camera is only ever supposed to move at a maximum of 16px per frame.

    To fix this, just do this:
    Code:
    MoveScreenHoriz:
            move.w    ($FFFFC904).w,d1
            beq.s    @cont1
            sub.w    #$120,d1
            bpl.s    @nounderflow
            moveq    #0,d1
         
    @nounderflow:
    Now, there's a second bug (stemming from Sonic CD), and it's right here:
    Code:
    @cont2:
        sub.w    ($FFFFF700).w,d0
            sub.w    (v_camera_pan).w,d0    ; Horizontal camera pan value
            beq.s    SH_ProperlyFramed    ; if zero, branch
            bcs.s    SH_BehindMid    ; if less than, branch <--- HERE
            bra.s    SH_AheadOfMid    ; branch
    That "bcs" should be changed into a "bmi". For an explanation, see this. But basically, it can really mess with the camera positioning, and even make it underflow past 0, which the game was not programmed to handled, especially the object spawner. The object spawner checks the edges of a object layout via a dummy entry whose X position is set to -1 (or $FFFF when unsigned). When moving, if you cross a 128px boundary, it'll load in objects right up to where the camera is at + an certain offset depending on the direction of movement. That dummy entry helps stop object loading by utilizing a normally impossible position on either side (-1 or $FFFF), so loading will be halted once it's reached.

    When moving left, it continuously loads objects until it finds an entry that is less than the camera's position - 128px. Now, it'll attempt to stop loading new objects if you are on the leftmost 128px region of the stage by checking if the current 128px region the camera is in - 128px underflows past 0. However, it calculates which region you are in with a simple AND operation that masks out the lowest 7 bits of the value to get multiples of 128px. This is a problem, because if you somehow make the camera position itself underflow past 0, then it'll think you are at region $FF80, and the subtraction will just make it go to $FF00, which is technically not an underflow, so the check fails.

    From there, it'll perform the object loading. In this instance, it uses a signed check to perform at what point it should stop loading objects, and thus, the dummy entry's X position will be interpreted as -1, and if the camera value minus 128 with the AND masking ends up being $FF00, then it'll be -256. The dummy entry won't stop it, because -1 is GREATER than -256, and if it starts going through another stage's object layout, then it'll keep on loading new objects, since all their positions will be greater than -256. It'll keep spawning objects until object RAM is full or until it somehow finds a value < -256. If you are in Green Hill Zone Act 1, then there are no previous object layouts to go through, so it'll start interpreting data before GHZ1's object layout data, so you'll get corrupted data.

    Here's the code associated with this, annotated, which an optional fix highlighted:
    Code:
            move.w    (v_screenposx).w,d6        ; Get 128px region that we are in
            andi.w    #$FF80,d6
            cmp.w    (v_opl_screen).w,d6        ; Have we moved?
            beq.w    locret_DA3A            ; If not, exit
            bge.s    loc_D9F6            ; If we have moved right, branch
            move.w    d6,(v_opl_screen).w        ; Update current 128px region
         
            movea.l    (v_opl_data+4).w,a0        ; Get object layout left cursor
            subi.w    #$80,d6                ; Load objects up to the current region position - 128px
            blo.s    loc_D9D2            ; If we are at the leftmost side of the stage (region 0), branch
                                ; Note that if you are in a negative region (i.e. camera X position is < 0),
                                ; this check won't work Change to "bmi" to fix.
    
    loc_D9A6:
            cmp.w    -6(a0),d6            ; Is the next object entry past the current loading boundary?
            bge.s    loc_D9D2            ; If so, branch
            subq.w    #6,a0                ; Go to next object entry
         
            tst.b    4(a0)                ; (object respawn flag ID increment)
            bpl.s    loc_D9BC
            subq.b    #1,1(a2)
            move.b    1(a2),d2
    
    loc_D9BC:
            bsr.w    loc_DA3C            ; Spawn object
            bne.s    loc_D9C6            ; If it couldn't spawn it, branch
            subq.w    #6,a0                ; loc_DA3C advances a0 as the object is loaded, reverse it
            bra.s    loc_D9A6            ; Loop
    ; ===========================================================================
    
    loc_D9C6:
            tst.b    4(a0)                ; (object respawn flag ID rewind)
            bpl.s    loc_D9D0
            addq.b    #1,1(a2)
    
    loc_D9D0:
            addq.w    #6,a0                ; Rewind back to last object entry
    
    loc_D9D2:

    So yeah, it's a couple of bad cases that can cause the camera to be an invalid value, which can mess up the stage renderer and object spawner. It's not a scrapped feature that's been found, it's just a result of a bugged implementation breaking the engine. The Sonic engine was not designed to handle the camera position being negative, and this is the consequences of allowing that to happen.
     
    Last edited: Jun 19, 2023
    Hame and DeltaWooloo like this.
  4. Hame

    Hame Peepee Poopoo Member

    Joined:
    Jan 12, 2021
    Messages:
    57
    Location:
    Spain
    wow, thanks for telling me the solution, although interesting how it loads the data from the previous level.
     
  5. Devon

    Devon A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Member

    Joined:
    Aug 26, 2013
    Messages:
    1,377
    Location:
    your mom
    Well, like I said, it does that because the game just cannot really handle the camera being in a negative position. Allowing that will break checks such as the one I highlighted from the object spawner routine, and make it so that it keeps loading data past where it was supposed to stop.
     
    Hame likes this.
  6. Hame

    Hame Peepee Poopoo Member

    Joined:
    Jan 12, 2021
    Messages:
    57
    Location:
    Spain
    thanks for the information :)
     
  7. That-One-Mega-Man

    That-One-Mega-Man Doofus Maximus Member

    Joined:
    Jun 18, 2023
    Messages:
    35
    Location:
    Right behind you
    so, everyone's done stuff like porting the peelout and spindash, right
    why hasn't anyone ported the insta-shield to my knowledge? it's got some surprising uses if Cybernetic Outbreak is anything to consider
     
  8. Hame

    Hame Peepee Poopoo Member

    Joined:
    Jan 12, 2021
    Messages:
    57
    Location:
    Spain
    It could be for 2 things. 1: difficult to add 2: vram issues
     
    Last edited: Jun 19, 2023
  9. That-One-Mega-Man

    That-One-Mega-Man Doofus Maximus Member

    Joined:
    Jun 18, 2023
    Messages:
    35
    Location:
    Right behind you
    ah
    yeah that's probably it, from what i've heard sonic 3 assets are pretty damn difficult to backport to s1
     
  10. Devon

    Devon A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Member

    Joined:
    Aug 26, 2013
    Messages:
    1,377
    Location:
    your mom
    You can circumvent this by dynamically loading in the appropriate shield art within the same spot in VRAM when needed (insta shield art when no shield, shield art when shielded, etc.), which is what Sonic 3 does.
     
  11. Hame

    Hame Peepee Poopoo Member

    Joined:
    Jan 12, 2021
    Messages:
    57
    Location:
    Spain
    oh yeah i forgot i could do that
     
  12. MemeMaster9000

    MemeMaster9000 Newcomer Member

    Joined:
    Feb 12, 2023
    Messages:
    21
    Location:
    Ice Cap Zone
    I remember seeing a Sonic CD decompilation on github being worked on by Devon, but unfortunately it's not being developed anymore. Could someone point me towards a viable alternative?
     
  13. Devon

    Devon A̸ ̴S̴ ̵C̵ ̷E̶ ̸N̸ ̴D̶ ̵E̶ ̸D̶ Member

    Joined:
    Aug 26, 2013
    Messages:
    1,377
    Location:
    your mom
    My work is (I believe) the most anyone has ever done for Sonic CD (on Sega CD anyways). It's not being worked on by be anymore because I just don't have the time or energy to dedicate myself to it anymore. Now, anyone is free to continue working on it if they so want, so if anything like that pops up, then that will be your alternative.
     
  14. That-One-Mega-Man

    That-One-Mega-Man Doofus Maximus Member

    Joined:
    Jun 18, 2023
    Messages:
    35
    Location:
    Right behind you
    unsure if this qualifies as basic, but i'm curious.
    i mapped one of the small metal slug explosions to my sonic's palette and i've been wondering if it would be possible to port it.
    most likely not due to the frame amount, but still.
    [​IMG]
     
    Hame likes this.
  15. Hame

    Hame Peepee Poopoo Member

    Joined:
    Jan 12, 2021
    Messages:
    57
    Location:
    Spain
    I think not, there are some pixels that the palette of sonic does not have
     
  16. That-One-Mega-Man

    That-One-Mega-Man Doofus Maximus Member

    Joined:
    Jun 18, 2023
    Messages:
    35
    Location:
    Right behind you
    i applied sonic's palette to the sprites
    unless thats not what you mean
     
  17. Hame

    Hame Peepee Poopoo Member

    Joined:
    Jan 12, 2021
    Messages:
    57
    Location:
    Spain
    Nvm, I misunderstood. yes they look good
     
  18. That-One-Mega-Man

    That-One-Mega-Man Doofus Maximus Member

    Joined:
    Jun 18, 2023
    Messages:
    35
    Location:
    Right behind you
    i think the only possible issue COULD be space but that could possibly be circumvented by some shenanigans
     
  19. Hame

    Hame Peepee Poopoo Member

    Joined:
    Jan 12, 2021
    Messages:
    57
    Location:
    Spain
    It will definitely take up quite a bit of vram, so I recommend making art uncompressed and loading it into specific blocks, like Sonic.
     
    That-One-Mega-Man likes this.
  20. That-One-Mega-Man

    That-One-Mega-Man Doofus Maximus Member

    Joined:
    Jun 18, 2023
    Messages:
    35
    Location:
    Right behind you
    gotcha. might try that.
    =================
    anyways, i needed to compress these two posts into one, since i'm only a trialist and wanna conserve, but no matter what i do with the SMPS research pack, the wily boss themes from the wily wars won't convert properly no matter what. the .bin files show up but it sounds BAD in game.
    i tried s2, s3k, ors, nothin worked. help greatly appreciated.