Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; ---------------------------------------------------------------------------
- ; Object 67 - disc that you run around (SBZ)
- ; ---------------------------------------------------------------------------
- RunningDisc:
- moveq #0,d0
- move.b routine(a0),d0
- move.w Disc_Index(pc,d0.w),d1
- jmp Disc_Index(pc,d1.w)
- ; ===========================================================================
- Disc_Index: dc.w Disc_Main-Disc_Index
- dc.w Disc_Action-Disc_Index
- disc_origX: equ $32 ; original x-axis position
- disc_origY: equ $30 ; original y-axis position
- ; ===========================================================================
- Disc_Main: ; Routine 0
- addq.b #2,routine(a0) ;set routine
- move.l #Map_Disc,mappings(a0) ;set mappings
- move.w #$C344,art_tile(a0) ;set arttile
- move.b #4,render_flags(a0) ;ensure object is visible as a level object
- move.b #4,priority(a0) ;set priority
- move.b #8,width_pixels(a0) ;set object width variable
- move.w x_pos(a0),disc_origX(a0) ;save our original x_pos
- move.w y_pos(a0),disc_origY(a0) ;save our original y_pos
- move.b #$18,$34(a0) ;save $18 into object ram $34 (only used for visual code)
- move.b #$48,$38(a0) ;save $48 into object ram $38. $38(a0) is likely our circle radius/diameter.
- move.b subtype(a0),d1 ; get object type
- andi.b #$F,d1 ; read only the 2nd digit
- beq.s RunningDisc_typeis0 ; branch if 0
- move.b #$10,$34(a0) ;set different values!!!
- move.b #$38,$38(a0) ;this code is entirely unused! Always uses subtype $40
- RunningDisc_typeis0:
- move.b subtype(a0),d1 ; get subtype
- andi.b #$F0,d1 ; read only the 1st digit. First digit appears to set the rolling direction...
- ext.w d1 ;extend subtype byte to a word (d1 might be uncleared, doecs this clear it?)
- asl.w #3,d1 ;bit shift left by 3 (for subtype $40, that's 0000 0000 0100 0000 to 0000 0010 0000 0000 or $200)
- move.w d1,$36(a0) ;save d1 (probably $200) into unused object ram at $36-$37. It's used as a quick check for our orientation.
- move.b status(a0),d0 ;copy object status bit table to d0
- ror.b #2,d0 ;roll bit table to the right twice (6,7,0,1,2,3,4,5)
- andi.b #$C0,d0 ;cut out the upper two bits (1100 0000), removing tails push/S1unused and Object specific flags
- move.b d0,angle(a0) ;copy remaining flags to our angle? (likely just repurposed scratch ram?)
- Disc_Action: ; Routine 2
- bsr.w Disc_MoveSonic ;likely run player movement code based on original position
- bsr.w Disc_MoveSpot ;visually move actual object position around and render
- bra.w Disc_ChkDel ;Sonic 1 version of MarkObjGone
- ; ===========================================================================
- Disc_MoveSonic:
- moveq #0,d2 ;clear d2
- move.b $38(a0),d2 ;move byte from object ram into d2 (this is $48 normally)
- move.w d2,d3 ;copy d2 to d3 as a word (upper word of d3 is dirty)
- add.w d3,d3 ;multiply d3 by 2 (so $90 normally)
- lea (MainCharacter).w,a1 ;load player ram address
- move.w x_pos(a1),d0 ;copy players x_pos to d0
- sub.w disc_origX(a0),d0 ;subtract our original x_pos from players x_pos (so get distance from)
- add.w d2,d0 ;add d2 ($90) to distance. $38(a0) is likely our circle radius/diameter.
- cmp.w d3,d0 ;is d0 (distance between player and our collision box?) d3 (size of our collision box?)
- bcc.s loc_155A8_RunningDisc ;if d3 is higher then or equal to d0, branch (so if player is not in our hitbox on x axis?)
- ;appears to be same as above, but for y axis
- move.w y_pos(a1),d1 ;copy player y pos into d1
- sub.w disc_origY(a0),d1 ;subtract our original y_pos from players y_pos (get distance from)
- add.w d2,d1 ;add circle size to distance
- cmp.w d3,d1 ;is circle diameter greater then or equal to distance + circle radius?
- bcc.s loc_155A8_RunningDisc ;if greater then or equal, branch
- btst #1,status(a1) ;check if player is in the air
- beq.s loc_155B8 ;if not in the air, branch
- clr.b $3A(a0) ;clear object ram byte $3A (idk what $3A is yet)
- rts ;return to main routine
- ; ===========================================================================
- ;appears to be a fail safe case for when the player isn't on our circle
- ;likely deactives disc run flag.
- loc_155A8_RunningDisc:
- tst.b $3A(a0) ;is $3A(a0) 0? (should be thus far, nothing has set it)
- beq.s locret_155B6 ;if it is 0, rts
- clr.b $38(a1) ;clear byte $38 in players code (flag that make player stick to surfaces!)
- clr.b $3A(a0) ;clear $3A(a0) (still not sure what sets this, or what it's for)
- locret_155B6:
- rts
- ; ===========================================================================
- loc_155B8:
- tst.b $3A(a0) ;is $3A(a0) 0?
- bne.s loc_155E2 ;if non-zero, branch
- ;this code appears to prevent rolling? Still not sure, but it only runs when $3A is set.
- move.b #1,$3A(a0) ;set $3A(a0)!
- btst #2,status(a1) ;check if player is jumping or rolling
- bne.s loc_155D0 ;if not, branch
- clr.b anim(a1) ;set players animation to 0 (walking. Can we not roll?)
- ;this appears to be where the cool stuff happens
- loc_155D0:
- bclr #5,status(a1) ;clear player pushing something flag
- move.b #1,next_anim(a1) ;set next animation to 1 (running)
- move.b #1,$38(a1) ;set $38 to 1 in player ram (sets the stick to surfaces flag!)
- ;This controls the players speed on the circle.
- ;functions exactly as intended, the weirdness is not down here.
- loc_155E2:
- move.w inertia(a1),d0 ;get players inertia
- tst.w $36(a0) ;is $36(a0) 0 (should be $200 initially)
- bpl.s loc_15608 ;if result is positive, branch (goes to a different set of speed checks)?
- ;this code is dependant on the value in $36(a0)
- ;this force the players inertia to be between -$400 and -$F00
- ;it works as intended, no problems here.
- cmpi.w #-$400,d0 ;is player inertia -$400? (minimum speed player can have on roller)
- ble.s loc_155FA ;if less then or equal, branch
- move.w #-$400,inertia(a1) ;set players inertia to -$400
- rts
- ; ===========================================================================
- loc_155FA:
- cmpi.w #-$F00,d0 ;is player inertia -$F00 (maximum speed player can have on roller)
- bge.s locret_15606 ;if -$F00 is greater or equal to player inertia rts
- move.w #-$F00,inertia(a1) ;set players speed to -$f00
- locret_15606:
- rts
- ; ===========================================================================
- ;this code is dependant on the value in $36(a0)
- ;should be what runs "first time"
- ;This is the same as the other speed checks, but for the other direction
- ;is $36 a flag for our roller direction!?
- loc_15608:
- cmpi.w #$400,d0 ;is player inertia positive $400?
- bge.s loc_15616
- move.w #$400,inertia(a1)
- rts
- ; ===========================================================================
- loc_15616:
- cmpi.w #$F00,d0
- ble.s locret_15622
- move.w #$F00,inertia(a1)
- locret_15622:
- rts
- ; ===========================================================================
- ;code to move actual visible spot I think
- ;likely not important for our cause, seems to work just fine.
- Disc_MoveSpot:
- move.w $36(a0),d0
- add.w d0,angle(a0)
- move.b angle(a0),d0
- jsr (CalcSine).l
- move.w disc_origY(a0),d2
- move.w disc_origX(a0),d3
- moveq #0,d4
- move.b $34(a0),d4
- lsl.w #8,d4
- move.l d4,d5
- muls.w d0,d4
- swap d4
- muls.w d1,d5
- swap d5
- add.w d2,d4
- add.w d3,d5
- move.w d4,y_pos(a0)
- move.w d5,x_pos(a0)
- rts
- ; ===========================================================================
- Disc_ChkDel:
- ;out_of_range.s RunningDisc_delete,disc_origX(a0)
- jsr MarkObjGone
- jmp (DisplaySprite).l
- RunningDisc_delete:
- jmp (DeleteObject).l
- Map_Disc: include "mappings\sprite\Running Disc.asm"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement