don't click here

S3K Sandopolis 2 Ghost Disasm Comments

Discussion in 'Engineering & Reverse Engineering' started by Cokie, Nov 19, 2021.

  1. Cokie

    Cokie

    C. Okie Member
    47
    6
    8
    I have been through the s3k disassembly https://github.com/sonicretro/skdisasm for code related to the ghosts in sandolopis zone act two and related subroutines . I want to share and wish to add one here . Welcome for any corrections and critiques .

    I have ;cokie tagged to just keep track of what I added


    Code (Text):
    1.  
    2.  
    3. ;COKIE THIS OBJECT WILL LOAD THE EGG CAPSULES RAW PLC FROM ROM WHEN TRIGGERED BY PLAYER BEING IN RANGE OF IT
    4. Obj_AB_2:
    5.         moveq    #0,d0
    6.         move.b    $2C(a0),d0 ;COKIE set offset to data containing boundary data
    7.                      
    8.         movea.l    off_8F3BE(pc,d0.w),a1               ;COKIE get the start address of data used to calculate the boundary of Obj_AB_2.
    9.                                ;COKIE we will check if player 1 / 2 are in range of this boundary.
    10.         jsr    (Check_PlayerInRange).l             ;COKIE check if player 1 and 2 are in range of bounary
    11.                                ;COKIE IF P2 IS IN range store its objet ram offset in upper word of d0
    12.                                ;COKIE IF P1 IS IN range store its objet ram offset in lower word of d0
    13.  
    14.         tst.l    d0                  
    15.         beq.w    locret_8F436           ;COKIE IF NEITHER P1 NOR P2 ARE IN RANGE BRANCH TO locret_8F436
    16.         tst.w    d0
    17.         beq.w    locret_8F436           ;COKIE IF NEITHER P1 NOR P2 ARE IN RANGE OR JUST TAILS IS IN RANGE , BRANCH TO locret_8F436  
    18.                                ;COKIE to put it another way , if p1 and also p2 are in range or just p1 is in range , DONT BRANCH          
    19.         moveq    #0,d0
    20.         move.b    $2C(a0),d0
    21.         movea.l    off_8F3C6(pc,d0.w),a1    ;COKIE set a1 to hold the addess of loc_8F3DE
    22.         jsr    (a1)                    ;COKIE go to loc_8F3DE
    23.         jmp    (Delete_Current_Sprite).l
    24. ; ---------------------------------------------------------------------------
    25. off_8F3BE:    dc.l word_8F3CE                ;COKIE OFFSET USED TO GO TO word_8F3CE and word_8F3D6 (see description below )
    26.         dc.l word_8F3D6
    27. off_8F3C6:    dc.l loc_8F3DE
    28.         dc.l loc_8F3F0
    29. word_8F3CE:    dc.w  $FFF0,   $20, $FFC0,   $80    ;COKIE data used for calculating Obj_AB_2 boundary area to check if player is in range of
    30. word_8F3D6:    dc.w  $FFF0,   $20, $FF80,  $100
    31. ; ---------------------------------------------------------------------------
    32.  
    33. loc_8F3DE:
    34.         lea    PLC_8F3E8(pc),a1            ;COKIE load the PLC data for the Egg Capsule
    35.  
    36.  
    Here is the subroutine that checks if just p1 or both player 1 and 2 are in range.
    Code (Text):
    1.  
    2.  
    3. ; =============== S U B R O U T I N E =======================================
    4.  
    5.  
    6. ;COKIE CHECKS IF PLAYER TWO AND IF PLAYER ONE IS IN RANGE OF BOUNDARY AREA AROUND THE OBJECTS STORED IN A0
    7. ;COKIE THE BOUNDARY AREA AROUND THE OBJECT IN A0 IS SPECIFIED IN 4 WORDS OF DATA THAT START ADDRESS IS IN A1
    8.  
    9. ;COKIE IF PLAYER TWO IS IN RANGE , PLAYER 2 OBJECT RAM START ADDRESS IS STORED IN THE HIGH WORD OF D0
    10. ;COKIE IF PLAYER ONE IS IN RANGE , PLAYER 1 OBJECT RAM START ADDRESS IS STORED IN THE LOW WORD OF D0
    11.  
    12. ;COKIE a2 contents is the address of Player 2 / Player 1 Object Ram start address
    13.  
    14. ;COKIE a0 is the start adress in object ram of the objet we are checking if player 1 / player 2 is in range of its boundary area
    15. ;COKIE a1 is the data that we add to the objects x and y to get bounary area of object to check if player 2 / 1 is within
    16.  
    17. ;COKIE Here is Effectively how the boundary areas are found:
    18. ;COKIE THE FIRST WORD OF DATA ADDED TO THE OBJECT X GETS THE OBJECTS X LEFT BOUND
    19. ;COKIE THE FIRST WORD OF DATA + SECOND WORD OF DATA ADDED TO THE OBJECT X GETS THE OBJECTS RIGHT BOUND
    20. ;COKIE THE THIRD WORD ADDED TO THE OBJECT Y GETS THE OBJECTS Y TOP BOUND
    21. ;COKIE THE THIRD WORD OF DATA + FOURTH WORD OF DATA ADDED TO THE OBJECT Y GETS THE OBJECTS BOTTOM BOUND
    22.  
    23.  
    24.  
    25.  
    26. Check_PlayerInRange:
    27.         moveq    #0,d0
    28.         lea    (Player_2).w,a2  ;COKIE store in a2 contents , the address of Player 2 Object Ram start address
    29.         move.w    $10(a2),d1 ;COKIE store player 2 x in d1
    30.         move.w    $14(a2),d2 ;COKIE store player 2 y in d2
    31.  
    32.      
    33.         ;COKIE we copy the x and y of this object into d3 and d4
    34.         move.w    $10(a0),d3 ;COKIE x of object we are checking if player is in range of into d3
    35.         move.w    $14(a0),d4 ;COKIE y of object we are checking if player is in range of into d4
    36.  
    37.  
    38.         ;COKIE the next 4 add.w statements calculate and store the left right top and bottom boundary range
    39.  
    40.         ;COKIE store the left boundary x for the oject we are checking if the player is in range of
    41.         ;COKIE by adding the first word of data to the object x and store it in d3
    42.         add.w    (a1)+,d3
    43.         move.w    d3,d5 ;COKIE copy that value to d5
    44.  
    45.      
    46.         ;COKIE store the right boundary x for the oject we are checking if the player is in range of
    47.         ;COKIE by adding the second word of data to the d5 and store it in d5 - effectively object x + first word + second word
    48.         add.w    (a1)+,d5
    49.  
    50.         ;COKIE store the top boundary y for the oject we are checking if the player is in range of
    51.         ;COKIE by adding the third word of data to the object y and store it in d4
    52.         add.w    (a1)+,d4
    53.  
    54.         move.w    d4,d6 ;COKIE copy that value to d6
    55.  
    56.  
    57.         ;COKIE store the bottom boundary y for the oject we are checking if the player is in range of
    58.         ;COKIE by adding the third and fourth word of data to the d6 and store it in d6 effectively object y + third word + second word
    59.         add.w    (a1)+,d6
    60.  
    61.         bsr.w    sub_8592C ;COKIE branch to subroutine that will check if player 2 / 1 in in range
    62.  
    63.         swap    d0    ;COKIE swap the high and low word. IF player 2 was in range, then we swap its contents in the low word of d0 to the high word of d0
    64.         lea    (Player_1).w,a2
    65.         move.w    $10(a2),d1
    66.         move.w    $14(a2),d2
    67. ; End of function Check_PlayerInRange
    68.  
    69.  
    70. ; =============== S U B R O U T I N E =======================================
    71.  
    72. ;COKIE actually check if player 1 / player 2 in in range
    73. ;COKIE we call sub_8592C TWICE , one for checking player 2 and one for checking for player 1
    74. ;COKIE the first time checking p2 returns to Check_PlayerInRange . The second time checking p2 returns to the subroutine that CALLED Check_PlayerInRange
    75. ;COKIE when checking the first time , if player 2 is in range , its object ram offset is put into the low word of d0
    76. ;COKIE when checking the second time , if player 1 is in range , d0 will have had its high / low word swapped so it will put p1 object ram
    77. ;COKIE offset into the low word of d0
    78.  
    79. sub_8592C:
    80.         ;COKIE CHECK THE LEFT BOUND OF OBJECT AND THE PLAYER 1/2 X
    81.         cmp.w    d3,d1
    82.         blo.s    locret_8593E ;COKIE branch if not in range
    83.  
    84.         ;COKIE CHECK THE RIGHT BOUND OF OBJECT AND THE PLAYER 1/2 X
    85.         cmp.w    d5,d1
    86.         bhs.s    locret_8593E ;COKIE branch if not in range
    87.  
    88.         ;COKIE CHECK THE TOP BOUND OF OBJECT AND THE PLAYER 1/2 Y
    89.         cmp.w    d4,d2
    90.         blo.s    locret_8593E ;COKIE branch if not in range
    91.  
    92.         ;COKIE CHECK THE BOTTOM BOUND OF OBJECT AND THE PLAYER 1/2 Y
    93.         cmp.w    d6,d2
    94.         bhs.s    locret_8593E ;COKIE branch if not in range
    95.  
    96.         ;COKIE if we are in range move player 1 / 2 object ram start adress to the low word of d0
    97.         move.w    a2,d0
    98.  
    99. locret_8593E:
    100.         rts ;COKIE either 1. player 1 or player 2 wasnt' in range when checking or 2. player 1 or 2 was in range when checking
    101.            ;COKIE IF we were checking if p2 was in range and he was, return and go on to eventually check if p1 was in range
    102.            ;COKIE IF we were checking if p1 was in range and he was, we return to the subroutine that called Check_PlayerInRange
    103. ; End of function sub_8592C
    104.  
    105.  
    106. ; =============== S U B R O U T I N E =======================================
    107.  
    108.         jmp    (Load_PLC_Raw).l            ;COKIE load the raw PLC from ram for the Egg Capsule
     
  2. Cokie

    Cokie

    C. Okie Member
    47
    6
    8
    Some questions.

    1. Is this information already commonly known regardin the above codes function.?

    2. Who should I contact , regarding contributing to the sonic 3k disassembly?

    Also , I am open input to ensure my accuracy of describing the codes function.
     
  3. PicklePower

    PicklePower

    Wiki Sysop
    624
    18
    18
  4. Cokie

    Cokie

    C. Okie Member
    47
    6
    8
    Fantastic thank you .
     
  5. Cokie

    Cokie

    C. Okie Member
    47
    6
    8
    So this s3k code works like this... Check_PlayerInRange will move
    player twos object ram offset into the high word of d0 if p2 is in range and will put p1 object ram offset into the lower word of d0 if p1 is in range. The code after that will not cause a break on either of the following two cases: 1. )if player 1 is in range or 2) . If Player 1 and player 2 is in range no other instance. So you can simplify it to it doesn’t break if sonic is in range...

    Code (Text):
    1.  
    2.  jsr    (Check_PlayerInRange
    3.  tst.l    d0              
    4.  beq.w    locret_8F436
    5.  tst.w    d0
    6.  beq.w    locret_8F436          
    7.  moveq    #0,d0
    8.  

    So what is the point of tst.l d0 when they could have only done


    Code (Text):
    1.  
    2.  jsr    (Check_PlayerInRange
    3.  tst.w    d0
    4.  beq.w    locret_8F436          
    5.  moveq    #0,d0
    6.  
    Maybe I am wrong about the cases of when it breaks but I checked it and seems to verify that it how it works . Don’t see need for tst.l D0.

    Hope hear back thanks !
     
  6. MainMemory

    MainMemory

    Kate the Wolf Tech Member
    4,626
    206
    43
    SonLVL
    Yes, the first tst and beq is completely superfluous.
     
    • Like Like x 1
    • Agree Agree x 1
    • List
  7. Cokie

    Cokie

    C. Okie Member
    47
    6
    8
    Thanks!