Basic Questions & Answers thread

Discussion in 'Engineering & Reverse Engineering' started by Tweaker, May 29, 2008.

  1. FraGag

    FraGag

    Tech Member
    OK. Now, does frame 6 exist in the mappings?

    Code (ASM):
    1.  
    2.         move.b  #6,mapping_frame(a0)
    3.  
    When I first read the code, I thought it was always overwritten, but I read the code again and now I see that the frame is indeed used when the object appears initially. If the mappings have less than 6 frames (which is the case with the original obj7E mappings), frame 6 will be garbage. By moving the object offscreen initially, the bug is avoided; since frame 6 is only used once, when the object initially appears, it doesn't occur when you scroll the camera to make the object visible after it's been loaded for a while.
     
  2. Ralakimus

    Ralakimus

    pretty much a dead account Tech Member
    557
    170
    43
    Alright, I found the problem and is fixed. Apparently, it WAS an issue with the sprite table and the palettes. All I had to do is move the palette line RAM addresses away from the sprite table RAM and I just extended the sprite table.
     
  3. FraGag

    FraGag

    Tech Member
    Now you just have more garbage in your sprite table. The size of the sprite table is more than enough for the Genesis's limit of 80 sprites on screen. BuildSprites just doesn't check for overflow. It's not normal that you would need to enlarge the sprite table.
     
  4. Ralakimus

    Ralakimus

    pretty much a dead account Tech Member
    557
    170
    43
    Alright, since the invincibility stars and the hyper stars aren't going to appear at the same time, so I had the hyper stars and invincibility stars use uncompressed art and DPLCs, and use the same VRAM location, so now I no longer need to extend the sprite table. When I reset the sprite table back to normal size and put the palette RAM addresses where they originally were, it worked just fine.
     
  5. RetroKoH

    RetroKoH

    Member
    1,661
    17
    18
    Project Sonic 8x16
    Yea... golden rule, and I follow it with my Sonic 1 hack... anything shield or star related... just have it in the same location. For example, in my hack, I've got invincibility stars, 4 shields, bonus stage entry effect, and super stars ALL in the exact same place. Try to find other instances where you can do that. IIRC the skid dust, spindash dust and splash art do the same thing in their location.
     
  6. Hitaxas

    Hitaxas

    Retro 80's themed Twich streamer Member
    I'm curious and want a technical explanation for this.

    In Sonic 3, there is a code that resets player position data.

    Code (ASM):
    1. Reset_Player_Position_Array:
    2.         cmpa.w  #Player_1,a0            ; is object player 1?
    3.         bne.s   Reset_Player_Position_ArrayP2   ; if not, branc
    4. ; Reset_Player_Position_ArrayP1:
    5.         lea (Pos_table).w,a1
    6.         lea (Stat_table).w,a2
    7.         move.w  #$3F,d0
    8. ; loc_10DEC:
    9. -       move.w  x_pos(a0),(a1)+         ; write location to pos_table
    10.         move.w  y_pos(a0),(a1)+
    11.         move.l  #0,(a2)+
    12.         dbf d0,-
    13.  
    14.         move.w  #0,(Pos_table_index).w
    15. ; loc_10E04:
    16. Reset_Player_Position_ArrayP2:
    17.         tst.w   (Competition_mode).w    ; are we in Competition mode?
    18.         beq.s   locret_10E24        ; if not, branch
    19.         lea (Stat_table).w,a1
    20.         move.w  #$3F,d0
    21. ; loc_10E12:
    22. -       move.w  x_pos(a0),(a1)+
    23.         move.w  y_pos(a0),(a1)+
    24.         dbf d0,-
    25.         move.w  #0,(Pos_table_index_P2).w
    26.  
    27. locret_10E24:
    28.         rts
    29. ; End of function Reset_Player_Position_Array
    Now this is self explainable. But It got me thinking, how is something like this handled in Sonic 2?

    Well, I looked in S3 for codes that called for Reset_Player_Position_Array, and then searched S2 for similar code. Here's where I found that S3K calls for it during character init codes.
    Looking at how S2 does it, I noticed the routine is much smaller.

    Code (ASM):
    1.     move.w  #$3F,d2
    2. -   bsr.w   Sonic_RecordPos
    3.     subq.w  #4,a1
    4.     move.l  #0,(a1)
    5.     dbf d2,-
    In my test, this pretty much does the same thing as Reset_Player_Position_Array...

    Is the code S3K uses faster in any way? Or would using the second code be a better way to go?
     
  7. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,551
    145
    43
    SonLVL
    The code used in S3K is definitely faster than the code used in S2 when you factor in the contents of the Sonic_RecordPos function:
    Code (ASM):
    1. Sonic_RecordPos:
    2.     move.w  (Sonic_Pos_Record_Index).w,d0
    3.     lea (Sonic_Pos_Record_Buf).w,a1
    4.     lea (a1,d0.w),a1
    5.     move.w  x_pos(a0),(a1)+
    6.     move.w  y_pos(a0),(a1)+
    7.     addq.b  #4,(Sonic_Pos_Record_Index+1).w
    8.  
    9.     lea (Sonic_Stat_Record_Buf).w,a1
    10.     lea (a1,d0.w),a1
    11.     move.w  (Ctrl_1_Logical).w,(a1)+
    12.     move.w  status(a0),(a1)+
    13.  
    14.     rts
    15. ; End of subroutine Sonic_RecordPos
    Sonic 2's code ends up repeatedly writing the index variable, then reading it, using it to get an offset into the tables, writing the position values, writing the status value, then moving back one element in the status table and overwriting what it just wrote with 0.
     
  8. Hitaxas

    Hitaxas

    Retro 80's themed Twich streamer Member
    Thank you for the explanation. :)
     
  9. RetroKoH

    RetroKoH

    Member
    1,661
    17
    18
    Project Sonic 8x16
    Copied from SSRG
    I'm actually trying to get Knuckles' break wall ability in Sonic 1.... but what's happening, is that while the wall works properly for ALL other characters, when I play as Knuckles, the wall breaks whenever Knuckles' x-position is close enough to the wall, seemingly regardless of Y position. Mind you, close enough being about 5-6 feet away from the damn thing. I'm sure I'm missing something VERY BASIC and EASY to fix... I've tried adapting the S1 code t suit the S3K code... but something is not right... I think it has to do with how far I'm skipping ahead with Knuckles... but IDK because I don't feel like I'm doing this any differently from S3K... Here is my code:
    Code (Text):
    1.  
    2.  
    3. Smash_Solid:    ; Routine 2
    4.         move.w  (v_player+x_vel).w,speed(a0) ; load character's horizontal speed
    5.         move.w  #$1B,d1
    6.         move.w  #$20,d2
    7.         move.w  #$20,d3
    8.         move.w  x_pos(a0),d4
    9.         bsr.w   SolidObject
    10.         cmpi.b  #id_KnuxPlayer,id(a1)   ; is the current character Knuckles
    11.         beq.s   @continue       ; if yes, continue
    12.                 btst    #5,status(a0)       ; is character pushing against the wall?
    13.         beq.s   @donothing      ; if yes, branch
    14.  
    15.     @chkroll:
    16.         cmpi.b  #id_Roll,anim(a1)   ; is character rolling?
    17.         bne.s   @donothing      ; if not, branch
    18.         move.w  speed(a0),d0
    19.         bpl.s   @chkspeed
    20.         neg.w   d0
    21.  
    22.     @chkspeed:
    23.         cmpi.w  #$480,d0        ; is character's speed $480 or higher?
    24.         bcs.s   @donothing      ; if not, branch
    25.         bclr    #5,status(a0)
    26.  
    27.     @continue:
    28.         move.w  speed(a0),x_vel(a1)
    29.         addq.w  #4,x_pos(a1)
    30.         lea (Smash_FragSpd1).l,a4 ; use fragments that move right
    31.         move.w  x_pos(a0),d0
    32.         cmp.w   x_pos(a1),d0    ; is player to the right of the block?
    33.         bcs.s   @smash      ; if yes, branch
    34.         subq.w  #8,x_pos(a1)
    35.         lea (Smash_FragSpd2).l,a4 ; use fragments that move left
    36.        
    37.     @smash:
    38.         move.w  x_vel(a1),g_vel(a1)
    39.         bclr    #5,status(a1)
    40.         moveq   #7,d1       ; load 8 fragments
    41.         move.w  #$70,d2
    42.         bsr.s   SmashObject
    43.  
    44.     @donothing:
    45.         rts
    46.  
    47. Smash_FragMove: ; Routine 4
    48.         bsr.w   SpeedToPos
    49.         addi.w  #$70,y_vel(a0)  ; make fragment fall faster
    50.         bsr.w   DisplaySprite
    51.         tst.b   render_flags(a0)
    52.         bpl.w   DeleteObject
    53.         rts
    54.  
     
  10. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,551
    145
    43
    SonLVL
    You probably shouldn't be skipping the btst that checks whether the character is actually touching the object when playing as Knuckles.
     
  11. RetroKoH

    RetroKoH

    Member
    1,661
    17
    18
    Project Sonic 8x16
    Spoiler tags contain my code issue due to page break.

    Code (Text):
    1.  
    2.  
    3. Smash_Solid:    ; Routine 2
    4.         move.w  (v_player+x_vel).w,speed(a0) ; load character's horizontal speed
    5.         move.w  #$1B,d1
    6.         move.w  #$20,d2
    7.         move.w  #$20,d3
    8.         move.w  x_pos(a0),d4
    9.         bsr.w   SolidObject
    10.         cmpi.b  #id_KnuxPlayer,id(a1)   ; is the current character Knuckles
    11.         beq.s   @continue       ; if yes, continue
    12.                 btst    #5,status(a0)       ; is character pushing against the wall?
    13.         beq.s   @donothing      ; if yes, branch
    14.  
    15.     @chkroll:
    16.         cmpi.b  #id_Roll,anim(a1)   ; is character rolling?
    17.         bne.s   @donothing      ; if not, branch
    18.         move.w  speed(a0),d0
    19.         bpl.s   @chkspeed
    20.         neg.w   d0
    21.  
    22.     @chkspeed:
    23.         cmpi.w  #$480,d0        ; is character's speed $480 or higher?
    24.         bcs.s   @donothing      ; if not, branch
    25.         bclr    #5,status(a0)
    26.  
    27.     @continue:
    28.         move.w  speed(a0),x_vel(a1)
    29.         addq.w  #4,x_pos(a1)
    30.         lea (Smash_FragSpd1).l,a4 ; use fragments that move right
    31.         move.w  x_pos(a0),d0
    32.         cmp.w   x_pos(a1),d0    ; is player to the right of the block?
    33.         bcs.s   @smash      ; if yes, branch
    34.         subq.w  #8,x_pos(a1)
    35.         lea (Smash_FragSpd2).l,a4 ; use fragments that move left
    36.        
    37.     @smash:
    38.         move.w  x_vel(a1),g_vel(a1)
    39.         bclr    #5,status(a1)
    40.         moveq   #7,d1       ; load 8 fragments
    41.         move.w  #$70,d2
    42.         bsr.s   SmashObject
    43.  
    44.     @donothing:
    45.         rts
    46.  
    47. Smash_FragMove: ; Routine 4
    48.         bsr.w   SpeedToPos
    49.         addi.w  #$70,y_vel(a0)  ; make fragment fall faster
    50.         bsr.w   DisplaySprite
    51.         tst.b   render_flags(a0)
    52.         bpl.w   DeleteObject
    53.         rts
    54.  

    Unless I'm missing another btst, I believe that the one you are referring to is the object's push flag to detect if the character is pushing the object, IIRC. I took your advice and I moved it before the character check... and it brought me back to the first issue I was having, where Knuckles can run through the wall, but if he is in the air, it will not work at all. That shouldn't be the case.

    In S3K this is skipped when the character is super or the character is Knuckles... in which case it goes on to the breaking code. OR it's also skipped when the player has a flame shield, in that case it skips slightly less ahead to seeing if the character is in his rolling animation. (Blasting through the wall using Sonic's ability)... so I don't think this is the issue.
     
  12. E-122-Psi

    E-122-Psi

    Member
    2,130
    327
    63
    Okay progress on the Final Zone query, I've (or more someone more competent) managed to get the boss to take hits properly using a branch, however the result is that the collision is gone for Eggman when getting away (which seems to be based on the normal boss object but is in obj85). Is there any sort of flag or data that recognises the difference between the two to use for the branch?

    EDIT: Never mind. Fixed.
     
  13. RetroKoH

    RetroKoH

    Member
    1,661
    17
    18
    Project Sonic 8x16
    Quick update, I fixed my bug. Knuckles works perfectly now. After a more careful search through the code, this is what was needed:

    Code (Text):
    1.  
    2.  
    3. Smash_Solid:    ; Routine 2
    4.         move.w  (v_player+x_vel).w,speed(a0) ; load Sonic's horizontal speed
    5.         move.w  #$1B,d1
    6.         move.w  #$20,d2
    7.         move.w  #$20,d3
    8.         move.w  x_pos(a0),d4
    9.         bsr.w   SolidObject
    10.  
    11.         beq.s   @donothing ; THIS LINE FIXES THE BUG AND MAKES IT ALL WORK CORRECTLY
    12.  
    13.         cmpi.b  #id_KnuxPlayer,id(a1)   ; is the current character Knuckles
    14.         beq.s   @continue       ; if yes, continue
    15.                 btst    #5,status(a0)       ; is character pushing against the wall?
    16.         beq.s   @donothing      ; if yes, branch
    17.  

    Basically the SolidObject subroutine will give a return, determining whether or not the player collided with the object or not. Without this, it will disregard that completely... in vanilla Sonic 1, it doesn't check this because Sonic cannot break the wall simply by touching it. He breaks the wall by rolling along the ground into it, which is why the push bit of obStatus(a0) (#5) is checked. Here, we want to branch away if the character is not touching the object at all, because the character COULD be knuckles.... who walks through the wall. Otherwise, you'd get the bug I got because it's not checking for collision. The S3K equivalent is seen here:

    Code (Text):
    1.  
    2.  
    3.         jsr (SolidObjectFull).l
    4.         tst.b   subtype(a0)
    5.         bpl.s   loc_215A4
    6.         tst.b   (Level_trigger_array).w
    7.         beq.s   loc_215AC
    8.         jmp (Delete_Current_Sprite).l
    9. ; ---------------------------------------------------------------------------
    10.  
    11. loc_215A4:
    12.         swap    d6
    13.         andi.w  #3,d6
    14.         bne.s   loc_215B2 ; EQUIVALENT
    15.  
    16. BreakWall_DoNothing: ;loc_215AC:
    17.         jmp (Sprite_OnScreen_Test).l
    18.  
    Though not quite exact, here... because there are a couple of other things the engine needs to check in S3K as well, but that line I marked is the equivalent.

    Moving the btst to before the character check as MainMemory suggested, didn't work properly because it wasn't necessarily checking for a collision, moreso it was checking whether or not the character was actually pushing against the object along the ground, hence why Knuckles couldn't break it in the air like he's supposed to in S3K.

    I hope this helps future Knuckles hacks to understand this.
     
  14. Truner

    Truner

    Member
    I pretty much know nothing about the Sega Saturn (besides the fact that it's a pita to emulate), so excuse my slightly noobish question here:
    Since Sonic 3D uses Redbook audio on the Saturn, does that mean that it could be replaced with the Mega Drive soundtrack, if converted and looped properly? If so, are there any guide for this kind of thing?
    EDIT:oh hey, it turns out I should learn to Google better, such a thing already exists. Sweet.
     
  15. E-122-Psi

    E-122-Psi

    Member
    2,130
    327
    63
    * Does the coding in S1 to recognise collecting rings (I take it's Obj25_Collect) have anyway of recognising if it's touched by Sonic and only Sonic? Right now I have a glitch that leads to another object being able to collect rings and add them to the counter.

    * This one is more complex. Does anyone know what command makes the green cylinders in Marble Zone move up and down? I want to add a branch to make them stop and start (I've done it with other objects in the game, but for some reason this one won't budge from it's routine).
     
  16. Clownacy

    Clownacy

    Tech Member
    837
    79
    28
    Why can't you check? I just did, and it's obvious that it doesn't. At least, by default, not explicitly.

    Look, Ring_Collect is triggered by the ring object having an obRoutine of 4. Nothing in the obj25 object does that, however. This is done by ReactToItem, who has a special way of handing obj25's obColType, $47 (and similar ones). It works by increasing the object's routine counter by 2 when touched by whatever object branches to ReactToItem. So, in order for a ring to be collected, it must have an obColType of $47, and be touched by an object that routinely branches to ReactToItem. Usually, only Sonic does that. There's your problem.

    Above Touch_Monitor (React_Monitor), above the addq.b, add these instructions:

    Code (ASM):
    1.     cmpa.w #BulletRAMSlot,a0    ; is the colliding object a bullet?
    2.     beq.s   locret_1AEF2        ; if so don't collect ring
     
  17. E-122-Psi

    E-122-Psi

    Member
    2,130
    327
    63
    Doesn't seem to work. I should note this is a very particular glitch. The object only collects a ring just as it's routine ends and it deletes, otherwise it has no problems.

    EDIT: Whoop, hold on. I tweaked the branch to this and it seemed to do it. Thanx very much. :D

    Code (ASM):
    1.     cmp.b #$10,(a0) ; is the colliding object a bullet?
     
  18. Caverns 4

    Caverns 4

    Member
    342
    0
    16
    Sanik Quest: Journey To The Right
    Does anyone know how to remove the heat wave/ripple efect from Angel Island Zone? I've been looking through the disassembly, but I'm not really clear on where it is...

    All I've been able to really figure out is that it has something to do with AIZ2_BackgroundEvent, but I've yet to figure out how it works.
     
  19. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    9
    18
    United Kingdom
    YouTuber
    I haven't tried it, but there is a label called "ApplyFGandBGDeformation". Maybe try skipping that will help?
     
  20. Caverns 4

    Caverns 4

    Member
    342
    0
    16
    Sanik Quest: Journey To The Right
    Sorry, I've tried that and nothing..
    I get the feeling that there's an unequated RAM constant somewhere that's set to make the rippling happens, bur I have no idea what it could be. I'll keep looking into it too.

    EDIT: I figured something out that seems to work.

    Under loc_50260, I put this line:
    Code (Text):
    1.         jmp (AIZ1_ApplyDeformWater).l
    Before this:
    Code (Text):
    1.         jsr (AIZ2_ApplyDeform).l
    2.         jmp ShakeScreen_Setup(pc)