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): ;COKIE THIS OBJECT WILL LOAD THE EGG CAPSULES RAW PLC FROM ROM WHEN TRIGGERED BY PLAYER BEING IN RANGE OF IT Obj_AB_2: moveq #0,d0 move.b $2C(a0),d0 ;COKIE set offset to data containing boundary data movea.l off_8F3BE(pc,d0.w),a1 ;COKIE get the start address of data used to calculate the boundary of Obj_AB_2. ;COKIE we will check if player 1 / 2 are in range of this boundary. jsr (Check_PlayerInRange).l ;COKIE check if player 1 and 2 are in range of bounary ;COKIE IF P2 IS IN range store its objet ram offset in upper word of d0 ;COKIE IF P1 IS IN range store its objet ram offset in lower word of d0 tst.l d0 beq.w locret_8F436 ;COKIE IF NEITHER P1 NOR P2 ARE IN RANGE BRANCH TO locret_8F436 tst.w d0 beq.w locret_8F436 ;COKIE IF NEITHER P1 NOR P2 ARE IN RANGE OR JUST TAILS IS IN RANGE , BRANCH TO locret_8F436 ;COKIE to put it another way , if p1 and also p2 are in range or just p1 is in range , DONT BRANCH moveq #0,d0 move.b $2C(a0),d0 movea.l off_8F3C6(pc,d0.w),a1 ;COKIE set a1 to hold the addess of loc_8F3DE jsr (a1) ;COKIE go to loc_8F3DE jmp (Delete_Current_Sprite).l ; --------------------------------------------------------------------------- off_8F3BE: dc.l word_8F3CE ;COKIE OFFSET USED TO GO TO word_8F3CE and word_8F3D6 (see description below ) dc.l word_8F3D6 off_8F3C6: dc.l loc_8F3DE dc.l loc_8F3F0 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 word_8F3D6: dc.w $FFF0, $20, $FF80, $100 ; --------------------------------------------------------------------------- loc_8F3DE: lea PLC_8F3E8(pc),a1 ;COKIE load the PLC data for the Egg Capsule Here is the subroutine that checks if just p1 or both player 1 and 2 are in range. Code (Text): ; =============== S U B R O U T I N E ======================================= ;COKIE CHECKS IF PLAYER TWO AND IF PLAYER ONE IS IN RANGE OF BOUNDARY AREA AROUND THE OBJECTS STORED IN A0 ;COKIE THE BOUNDARY AREA AROUND THE OBJECT IN A0 IS SPECIFIED IN 4 WORDS OF DATA THAT START ADDRESS IS IN A1 ;COKIE IF PLAYER TWO IS IN RANGE , PLAYER 2 OBJECT RAM START ADDRESS IS STORED IN THE HIGH WORD OF D0 ;COKIE IF PLAYER ONE IS IN RANGE , PLAYER 1 OBJECT RAM START ADDRESS IS STORED IN THE LOW WORD OF D0 ;COKIE a2 contents is the address of Player 2 / Player 1 Object Ram start address ;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 ;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 ;COKIE Here is Effectively how the boundary areas are found: ;COKIE THE FIRST WORD OF DATA ADDED TO THE OBJECT X GETS THE OBJECTS X LEFT BOUND ;COKIE THE FIRST WORD OF DATA + SECOND WORD OF DATA ADDED TO THE OBJECT X GETS THE OBJECTS RIGHT BOUND ;COKIE THE THIRD WORD ADDED TO THE OBJECT Y GETS THE OBJECTS Y TOP BOUND ;COKIE THE THIRD WORD OF DATA + FOURTH WORD OF DATA ADDED TO THE OBJECT Y GETS THE OBJECTS BOTTOM BOUND Check_PlayerInRange: moveq #0,d0 lea (Player_2).w,a2 ;COKIE store in a2 contents , the address of Player 2 Object Ram start address move.w $10(a2),d1 ;COKIE store player 2 x in d1 move.w $14(a2),d2 ;COKIE store player 2 y in d2 ;COKIE we copy the x and y of this object into d3 and d4 move.w $10(a0),d3 ;COKIE x of object we are checking if player is in range of into d3 move.w $14(a0),d4 ;COKIE y of object we are checking if player is in range of into d4 ;COKIE the next 4 add.w statements calculate and store the left right top and bottom boundary range ;COKIE store the left boundary x for the oject we are checking if the player is in range of ;COKIE by adding the first word of data to the object x and store it in d3 add.w (a1)+,d3 move.w d3,d5 ;COKIE copy that value to d5 ;COKIE store the right boundary x for the oject we are checking if the player is in range of ;COKIE by adding the second word of data to the d5 and store it in d5 - effectively object x + first word + second word add.w (a1)+,d5 ;COKIE store the top boundary y for the oject we are checking if the player is in range of ;COKIE by adding the third word of data to the object y and store it in d4 add.w (a1)+,d4 move.w d4,d6 ;COKIE copy that value to d6 ;COKIE store the bottom boundary y for the oject we are checking if the player is in range of ;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 add.w (a1)+,d6 bsr.w sub_8592C ;COKIE branch to subroutine that will check if player 2 / 1 in in range 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 lea (Player_1).w,a2 move.w $10(a2),d1 move.w $14(a2),d2 ; End of function Check_PlayerInRange ; =============== S U B R O U T I N E ======================================= ;COKIE actually check if player 1 / player 2 in in range ;COKIE we call sub_8592C TWICE , one for checking player 2 and one for checking for player 1 ;COKIE the first time checking p2 returns to Check_PlayerInRange . The second time checking p2 returns to the subroutine that CALLED Check_PlayerInRange ;COKIE when checking the first time , if player 2 is in range , its object ram offset is put into the low word of d0 ;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 ;COKIE offset into the low word of d0 sub_8592C: ;COKIE CHECK THE LEFT BOUND OF OBJECT AND THE PLAYER 1/2 X cmp.w d3,d1 blo.s locret_8593E ;COKIE branch if not in range ;COKIE CHECK THE RIGHT BOUND OF OBJECT AND THE PLAYER 1/2 X cmp.w d5,d1 bhs.s locret_8593E ;COKIE branch if not in range ;COKIE CHECK THE TOP BOUND OF OBJECT AND THE PLAYER 1/2 Y cmp.w d4,d2 blo.s locret_8593E ;COKIE branch if not in range ;COKIE CHECK THE BOTTOM BOUND OF OBJECT AND THE PLAYER 1/2 Y cmp.w d6,d2 bhs.s locret_8593E ;COKIE branch if not in range ;COKIE if we are in range move player 1 / 2 object ram start adress to the low word of d0 move.w a2,d0 locret_8593E: 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 ;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 ;COKIE IF we were checking if p1 was in range and he was, we return to the subroutine that called Check_PlayerInRange ; End of function sub_8592C ; =============== S U B R O U T I N E ======================================= jmp (Load_PLC_Raw).l ;COKIE load the raw PLC from ram for the Egg Capsule
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.
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): jsr (Check_PlayerInRange tst.l d0 beq.w locret_8F436 tst.w d0 beq.w locret_8F436 moveq #0,d0 So what is the point of tst.l d0 when they could have only done Code (Text): jsr (Check_PlayerInRange tst.w d0 beq.w locret_8F436 moveq #0,d0 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 !