don't click here

Projectile reflecting shield

Discussion in 'Engineering & Reverse Engineering' started by Hitaxas, Mar 30, 2008.

Thread Status:
Not open for further replies.
  1. Hitaxas

    Hitaxas

    Retro 80's themed Twitch streamer ( on hiatus) Member
    I am porting over the projectile reflecting shield from S3 to S2, and I believe I have everything converted correctly, but it still won't work.

    Here's the code

    Code (ASM):
    1. ; loc_3F862:
    2. Touch_ChkHurt:              ; XREF: Touch_ChkValue
    3.         tst.b   ($FFFFFE2D).w   ; is Sonic invincible?
    4.         beq Touch_Hurt  ; if not, branch
    5.  
    6. loc_1AFE6:              ; XREF: Touch_Hurt
    7.         moveq   #-1,d0
    8.         rts
    9.  
    10. Touch_ChkHurt2:
    11.     btst    #1,$2B(a1)
    12.     bne.s   Touch_ChkHurt_Bounce_Projectile ;return_15AC4
    13.     tst.w   $30(a1)
    14.     bne.s   return_15AC4
    15.     cmpi.b  #4,$24(a1)
    16.     bcc.s   return_15AC4
    17.     move.l  $C(a1),d3
    18.     move.w  $12(a1),d0
    19.     ext.l   d0
    20.     asl.l   #8,d0
    21.     sub.l   d0,d3
    22.     move.l  d3,$C(a1)
    23.     movea.l a0,a2
    24.     movea.l a1,a0
    25.     jsr (HurtSonic).l
    26.     movea.l a2,a0
    27.  
    28. return_15AC4:
    29.     rts
    30.    
    31. Touch_ChkHurt_NoPowerUp:        ; CODE XREF: sub_FE6E+3B8j
    32.         cmpi.b  #1,$21(a0)
    33.         bne Touch_ChkHurt2
    34.  
    35. Touch_ChkHurt_HaveShield:       ; CODE XREF: sub_FE6E+3C6j
    36.         move.b  $2B(a1),d0
    37.         andi.b  #8,d0
    38.         beq Touch_ChkHurt2
    39.  
    40. Touch_ChkHurt_Bounce_Projectile:    ; reflects bee's energy bullet
    41.         move.w  $10(a0),d1
    42.         move.w  $12(a0),d2
    43.         sub.w   $10(a1),d1
    44.         sub.w   $12(a1),d2
    45.         jsr (CalcAngle).l ;GetArcTan
    46.         jsr (CalcSine).l
    47.         muls.w  #-$800,d1
    48.         asr.l   #8,d1
    49.         move.w  d1,$18(a1)
    50.         muls.w  #-$800,d0
    51.         asr.l   #8,d0
    52.         move.w  d0,$1A(a1)
    53.         clr.b   $28(a1)
    54.         bra return_15AC4
     
  2. JoseTB

    JoseTB

    Tech Member
    716
    59
    28
    Shouldn't that be a0? Unless I'm missing something else, I don't know if you want everything to bounce.
     
  3. Dracula

    Dracula

    Oldbie
    605
    0
    16
    I'm watching you!
    Converting NES Mappers to MMC5
    Try this:

    Code (Text):
    1. Touch_ChkHurt:          ; CODE XREF: sub_FE6E+17Cj
    2.                 ; sub_FE6E+27Ej ...
    3.     move.b  $2B(a0),d0
    4.     andi.b  #$73,d0; 's'
    5.     beq.s   Touch_ChkHurt_NoPowerUp
    6.     and.b   status_secondary(a1),d0
    7.     bne.s   Touch_NoHurt
    8.     btst    #0,status_secondary(a0)
    9.     bne.s   Touch_ChkHurt_HaveShield
    10.        
    11. ; ===========================================================================      
    12.  
    13. ; loc_3F862:
    14. Touch_ChkHurt3:
    15.     btst    #1,status_secondary(a0); is Sonic invincible?
    16.     beq.s   Touch_Hurt  ; if not, branch
    17. ; loc_3F86A:
    18. Touch_NoHurt:
    19.     moveq   #-1,d0
    20.     rts
    21. ; ===========================================================================  
    22.    
    23. Touch_ChkHurt_NoPowerUp:    ; CODE XREF: sub_FE6E+3B8j
    24.     cmpi.b  #1,double_jump(a0)
    25.     bne.s   Touch_ChkHurt3
    26.  
    27. Touch_ChkHurt_HaveShield:   ; CODE XREF: sub_FE6E+3C6j
    28.     move.b  status_secondary(a1),d0
    29.     andi.b  #8,d0
    30.     beq.s   Touch_ChkHurt3
    31.  
    32. Touch_ChkHurt_Bounce_Projectile:; CODE XREF: sub_1050C+8Aj
    33.     move.w  $10(a0),d1
    34.     move.w  $14(a0),d2
    35.     sub.w   $10(a1),d1
    36.     sub.w   $14(a1),d2
    37.     jsr (CalcAngle).l
    38.     jsr (CalcSine).l
    39.     muls.w  #-$800,d1
    40.     asr.l   #8,d1
    41.     move.w  d1,x_vel(a1)
    42.     muls.w  #-$800,d0
    43.     asr.l   #8,d0
    44.     move.w  d0,y_vel(a1)
    45.     clr.b   $28(a1)
    46.     bra.s   Touch_NoHurt








    Change "bne.s Touch_ChkHurt_Bounce_Projectile" into "jsr Touch_ChkHurt_Bounce_Projectile"
     
  4. Hitaxas

    Hitaxas

    Retro 80's themed Twitch streamer ( on hiatus) Member
    Dracula, that didn't work either.


    Is there something I have to do to calcangle and calcsine?
     
  5. If you're calling the bouncing routine from Touch_ChkHurt2, it expects the character to be at a1 and the projectile at a0. Also, some conversions seem to be incorrect when compared to Sonic 3k's code. This should work:

    Code (ASM):
    1. Touch_ChkHurt_Bounce_Projectile:    ; reflects bee's energy bullet
    2.         move.w  x_pos(a1),d1
    3.         move.w  y_pos(a1),d2
    4.         sub.w   x_pos(a0),d1
    5.         sub.w   y_pos(a0),d2
    6.         jsr (CalcAngle).l ;GetArcTan
    7.         jsr (CalcSine).l
    8.         muls.w  #-$800,d1
    9.         asr.l   #8,d1
    10.         move.w  d1,x_vel(a0)
    11.         muls.w  #-$800,d0
    12.         asr.l   #8,d0
    13.         move.w  d0,y_vel(a0)
    14.         clr.b   collision_flags(a0)
    15.         bra return_15AC4
    Also,

    Code (ASM):
    1.         btst    #1,$2B(a1)
    2.         bne.s   Touch_ChkHurt_Bounce_Projectile ;return_15AC4
    is wrong, that checks for invincibility and not a shield.
     
  6. Hitaxas

    Hitaxas

    Retro 80's themed Twitch streamer ( on hiatus) Member
    Still fails to work, which is strange.

    Code (ASM):
    1. ; loc_3F862:
    2. Touch_ChkHurt:            ; CODE XREF: sub_FE6E+17Cj
    3.                 ; sub_FE6E+27Ej ...
    4.     move.b    $2B(a0),d0
    5.     andi.b    #$73,d0; 's'
    6.     beq.s    Touch_ChkHurt_NoPowerUp
    7.     and.b    status_secondary(a1),d0
    8.     bne.s    Touch_NoHurt
    9.     btst    #0,status_secondary(a0)
    10.     bne.s    Touch_ChkHurt_HaveShield
    11.  
    12. ; ===========================================================================        
    13. Touch_ChkHurt2:
    14.     btst    #1,$2B(a1)
    15.     bne.s   return_15AC4
    16.  
    17.     tst.w   $30(a1)
    18.     bne.s   return_15AC4
    19.     cmpi.b  #4,$24(a1)
    20.     bcc.s   return_15AC4
    21.     move.l  $C(a1),d3
    22.     move.w  $12(a1),d0
    23.     ext.l   d0
    24.     asl.l   #8,d0
    25.     sub.l   d0,d3
    26.     move.l  d3,$C(a1)
    27.     movea.l a0,a2
    28.     movea.l a1,a0
    29.     jsr (HurtSonic).l
    30.     movea.l a2,a0
    31.  
    32. return_15AC4:
    33.     rts
    34.  
    35. ; loc_3F862:
    36. Touch_ChkHurt3:
    37.     btst    #1,status_secondary(a0); is Sonic invincible?
    38.     beq.s    Touch_Hurt    ; if not, branch
    39. ; loc_3F86A:
    40. Touch_NoHurt:
    41.     moveq    #-1,d0
    42.     rts
    43. ; ===========================================================================    
    44.    
    45. Touch_ChkHurt_NoPowerUp:    ; CODE XREF: sub_FE6E+3B8j
    46.     cmpi.b    #1,$21(a0)
    47.     bne.s    Touch_ChkHurt3
    48.  
    49. Touch_ChkHurt_HaveShield:    ; CODE XREF: sub_FE6E+3C6j
    50.     cmpi.b  #$4B,0(a1)
    51.     bne      Touch_ChkHurt_Bounce_Projectile
    52.     move.b    status_secondary(a1),d0
    53.     andi.b    #8,d0
    54.     beq.s    Touch_ChkHurt3
    55.  
    56. Touch_ChkHurt_Bounce_Projectile:    ; reflects bee's energy bullet
    57.         move.w  x_pos(a1),d1
    58.         move.w  y_pos(a1),d2
    59.         sub.w   x_pos(a0),d1
    60.         sub.w   y_pos(a0),d2
    61.         jsr (CalcAngle).l ;GetArcTan
    62.         jsr (CalcSine).l
    63.         muls.w  #-$800,d1
    64.         asr.l   #8,d1
    65.         move.w  d1,x_vel(a0)
    66.         muls.w  #-$800,d0
    67.         asr.l   #8,d0
    68.         move.w  d0,y_vel(a0)
    69.         clr.b   collision_flags(a0)
    70.         bra return_15AC4
    71. ; ---------------------------------------------------------------------------
    72. ; loc_3F86E:
    73. Touch_Hurt:
    74.     nop
    75.     tst.w   invulnerable_time(a0)
    76.     bne.s   Touch_NoHurt
    77.     movea.l a1,a2
    78. ; End of function TouchResponse
    79. ; continue straight to HurtSonic
     
  7. That would be because you're calling it from Touch_ChkHurt now, so the player is in a0 and the projectile in a1. In Touch_ChkHurt_Bounce_Projectile, swap a1 and a0 around. That should work.
     
  8. Hitaxas

    Hitaxas

    Retro 80's themed Twitch streamer ( on hiatus) Member
    That still doesn't work... I have no clue why either.
     
  9. You have remembered to set the secondary status bitfield of whichever object you want to bounce to #8 right? That's the only reason I can think of for it not working.
     
  10. Hitaxas

    Hitaxas

    Retro 80's themed Twitch streamer ( on hiatus) Member
    Now THAT might be why it doesn't work. =X

    I will check right now.


    EDIT:
    Code (Text):
    1. error: invalid bit position
    2. > > >   bset    #8,status_secondary(a1)
    ...what?
     
  11. Aurochs

    Aurochs

    Единый, могучий Советский Союз! Tech Member
    2,343
    0
    0
    Whatever catches my fancy
    You want to set bit 7, not 8.
     
  12. Nope, he needs to set bit 3, since he's ANDing by 8
     
  13. Hitaxas

    Hitaxas

    Retro 80's themed Twitch streamer ( on hiatus) Member
    Alright, so I set the bit for 3, it compiles. I go to test it and... it still won't work. It seems I have the best of luck with S3. :(
     
  14. Where have you placed the bset? Why does it use a1?
     
  15. Hitaxas

    Hitaxas

    Retro 80's themed Twitch streamer ( on hiatus) Member
    I tried a number of places, but the places I put it were all part of the buzz bomber object. Also, I notice it was a1 and changed to a0.

    EDIT: Keep in mind, this is meant to work with the normal shield and the others as well.
     
  16. Go to loc_2D24E and after
    Code (ASM):
    1.     move.b  #6,routine(a1)
    add
    Code (ASM):
    1.     move.b  #8,status_secondary(a1)
    That should work.
     
  17. Hitaxas

    Hitaxas

    Retro 80's themed Twitch streamer ( on hiatus) Member
    You mean

    Code (ASM):
    1. move.b  #3,status_secondary(a1)

    right? since #8 is invalid in S2.
     
  18. Uh no I don't, a MOVE of #8 is perfectly valid. A bit operation on bit #8 on a non-register operand is invalid.
     
  19. Hitaxas

    Hitaxas

    Retro 80's themed Twitch streamer ( on hiatus) Member
    Ah, I see. I didn't notice that.

    Also. The bullet will now pass through Sonic if he has a shield, rather than bouncing off... any ideas why?
     
  20. All right, since I finally have my computer back (motherboard failure, ugh), I tested this out and got it working properly. There are actually two projectile response routines, one which was labeled by Stealth (the one you ported) and the other at $1041E, which isn't. Anyway, the code which works for me:

    Code (ASM):
    1. Touch_ChkHurt:
    2.     move.b  status_secondary(a0),d0
    3.     and.b   #$73,d0
    4.     beq.s   Touch_ChkHurt_NoPowerUp
    5.     cmp.b   #$98,(a1)   ; miscellaneous projectiles which use $2B of the SST for something else
    6.     beq.s   Touch_ChkHurt_BounceProjectile
    7.     and.b   status_secondary(a1),d0
    8.     bne.s   Touch_NoHurt
    9.     btst    #0,status_secondary(a0)
    10.     bne.s   Touch_ChkHurt_HaveShield
    11.    
    12. Touch_ChkHurt3:
    13.     btst    #1,status_secondary(a0) ; is Sonic invincible?
    14.     beq.s   Touch_Hurt      ; if not, branch
    15. ; loc_3F86A:
    16. Touch_NoHurt:
    17.     moveq   #-1,d0
    18.     rts
    19. ; ---------------------------------------------------------------------------
    20.  
    21. Touch_ChkHurt_NoPowerUp:
    22.     cmp.b   #1,double_jump_flag(a0)
    23.     bne.s   Touch_ChkHurt3
    24.    
    25. Touch_ChkHurt_HaveShield:
    26.     move.b  status_secondary(a1),d0
    27.     and.b   #8,d0
    28.     beq.s   Touch_ChkHurt3
    29.    
    30. Touch_ChkHurt_BounceProjectile:
    31.     move.w  x_pos(a0),d1
    32.     move.w  y_pos(a0),d2
    33.     sub.w   x_pos(a1),d1
    34.     sub.w   y_pos(a1),d2
    35.     jsr (CalcAngle).l
    36.     jsr (CalcSine).l
    37.     muls.w  #-$800,d1
    38.     asr.l   #8,d1
    39.     move.w  d1,x_vel(a1)
    40.     muls.w  #-$800,d0
    41.     asr.l   #8,d0
    42.     move.w  d0,y_vel(a1)
    43.     clr.b   collision_flags(a1)
    44.     bra.s   Touch_NoHurt
    45. ; ---------------------------------------------------------------------------
    46. ; loc_3F86E:
    47. Touch_Hurt:
    48.     ...
    This was the second routine. The first one is basically the same, but instead of using the player's width, it uses the shield's width. It isn't necessary to have this, but if you don't, it'll look like projectiles are bouncing off the player rather than bouncing off the shield.

    Code (ASM):
    1. ; ---------------------------------------------------------------------------
    2. ; Projectile touch response subroutine - $20(a0) in the object RAM
    3. ; collides Sonic with projectiles in the level
    4. ; ---------------------------------------------------------------------------
    5.  
    6. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
    7.  
    8.  
    9. ProjectileResponse:
    10.     move.b  status_secondary(a0),d0
    11.     andi.b  #$71,d0
    12.     beq.s   ProjectileResponse_Done
    13.     move.w  x_pos(a0),d2
    14.     move.w  y_pos(a0),d3
    15.     subi.w  #$18,d2
    16.     subi.w  #$18,d3
    17.     move.w  #$30,d4
    18.     move.w  #$30,d5
    19.     lea (Object_RAM+$400).w,a1
    20.     move.w  #$6F,d6
    21.  
    22. Projectile_Loop:
    23.     move.b  collision_flags(a1),d0
    24.     andi.b  #$C0,d0
    25.     cmpi.b  #$80,d0
    26.     beq.s   Projectile_Height
    27.  
    28. Projectile_Next:
    29.     lea next_object(a1),a1 ; load obj address ; goto next object
    30.     dbf d6,Projectile_Loop ; repeat 6F more times
    31.  
    32. ProjectileResponse_Done:
    33.     rts
    34. ; ---------------------------------------------------------------------------
    35.  
    36. Projectile_Height:
    37.     move.b  collision_flags(a1),d0
    38.     andi.w  #$3F,d0
    39.     beq.s   Projectile_Next
    40.     add.w   d0,d0
    41.     lea (Touch_Sizes).l,a2
    42.     lea (a2,d0.w),a2
    43.     moveq   #0,d1
    44.     move.b  (a2)+,d1
    45.     move.w  x_pos(a1),d0
    46.     sub.w   d1,d0
    47.     sub.w   d2,d0
    48.     bcc.s   Projectile_CheckHeight
    49.     add.w   d1,d1
    50.     add.w   d1,d0
    51.     bcs.s   Projectile_Width
    52.     bra.s   Projectile_Next
    53. ; ---------------------------------------------------------------------------
    54.  
    55. Projectile_CheckHeight:
    56.     cmp.w   d4,d0
    57.     bhi.s   Projectile_Next
    58.  
    59. Projectile_Width:
    60.     moveq   #0,d1
    61.     move.b  (a2)+,d1
    62.     move.w  y_pos(a1),d0
    63.     sub.w   d1,d0
    64.     sub.w   d3,d0
    65.     bcc.s   Projectile_CheckWidth
    66.     add.w   d1,d1
    67.     add.w   d1,d0
    68.     bcs.w   Projectile_Bounce
    69.     bra.s   Projectile_Next
    70. ; ---------------------------------------------------------------------------
    71.  
    72. Projectile_CheckWidth:
    73.     cmp.w   d5,d0
    74.     bhi.s   Projectile_Next
    75.  
    76. Projectile_Bounce:
    77.     cmpi.b  #$98,(a1)   ; miscellaneous projectiles which use $2B of the SST for something else
    78.     beq.s   +
    79.     move.b  status_secondary(a1),d0
    80.     andi.b  #8,d0
    81.     beq.s   Projectile_Next
    82. +
    83.     move.w  x_pos(a0),d1
    84.     move.w  y_pos(a0),d2
    85.     sub.w   x_pos(a1),d1
    86.     sub.w   y_pos(a1),d2
    87.     jsr (CalcAngle).l
    88.     jsr (CalcSine).l
    89.     muls.w  #-$800,d1
    90.     asr.l   #8,d1
    91.     move.w  d1,x_vel(a1)
    92.     muls.w  #-$800,d0
    93.     asr.l   #8,d0
    94.     move.w  d0,y_vel(a1)
    95.     clr.b   collision_flags(a1)
    96.     rts
    97. ; End of function ProjectileResponse
    You can place this anywhere you want, but I recommend putting it right above TouchResponse so that no branches go out of range. To call this, in TouchResponse, after
    Code (ASM):
    1.     bsr.w   JmpTo_loc_170BA
    add
    Code (ASM):
    1.     bsr.w   ProjectileResponse
     
Thread Status:
Not open for further replies.