Skip to content

Commit

Permalink
Fix collision physics for reverse gravity
Browse files Browse the repository at this point in the history
  • Loading branch information
mdsteele committed Jul 1, 2024
1 parent dfa3084 commit e9577b2
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 25 deletions.
29 changes: 22 additions & 7 deletions src/avatar.asm
Original file line number Diff line number Diff line change
Expand Up @@ -263,13 +263,30 @@ _SetPoseInWater:
sta Zp_AvatarPose_eAvatar
rts
_SetPoseOnGround:
;; TODO: Invert Up and Down buttons if gravity is reversed.
;; If gravity is normal, use Down to kneel and Up to look; if gravity is
;; reversed, use Down to look and Up to kneel.
lda Zp_P1ButtonsHeld_bJoypad
and #bJoypad::Down
tax ; joypad down bit
lda Zp_P1ButtonsHeld_bJoypad
and #bJoypad::Up
bit Zp_AvatarFlags_bObj
.assert bObj::FlipV = bProc::Negative, error
bpl @normalGravity
@reverseGravity:
stx T1 ; joypad look bit
sta T0 ; joypad kneel bit
bmi @setPose ; unconditional
@normalGravity:
sta T1 ; joypad look bit
stx T0 ; joypad kneel bit
@setPose:
;; Set the avatar's pose based on its state and the joypad.
lda Zp_AvatarState_bAvatar
and #bAvatar::LandMask
beq @standOrRun ; landing timer is zero
@landing:
lda Zp_P1ButtonsHeld_bJoypad
and #bJoypad::Down
lda T0 ; joypad kneel bit
bne @kneeling
lda #eAvatar::Landing
bne @setAvatarPose ; unconditional
Expand All @@ -288,11 +305,9 @@ _SetPoseOnGround:
@standing:
lda Zp_AvatarHarmTimer_u8
bne @kneeling
lda Zp_P1ButtonsHeld_bJoypad
and #bJoypad::Down
lda T0 ; joypad kneel bit
bne @kneeling
lda Zp_P1ButtonsHeld_bJoypad
and #bJoypad::Up
lda T1 ; joypad look bit
bne @looking
lda #eAvatar::Standing
bne @setAvatarPose ; unconditional
Expand Down
42 changes: 29 additions & 13 deletions src/platform.asm
Original file line number Diff line number Diff line change
Expand Up @@ -714,11 +714,20 @@ _MovingUp:
blt _Return
@topEdgeHit:
;; Check bottom edge of platform.
lda Ram_PlatformBottom_i16_0_arr, x
add #kAvatarBoundingBoxUp ; TODO: handle reverse gravity
bit Zp_AvatarFlags_bObj
.assert bObj::FlipV = bProc::Negative, error
bpl @normalGravity
@reverseGravity:
lda #kAvatarBoundingBoxDown + 1
.assert kAvatarBoundingBoxDown > 0, error
bne @doneBoundingBox ; unconditional
@normalGravity:
lda #kAvatarBoundingBoxUp
@doneBoundingBox:
add Ram_PlatformBottom_i16_0_arr, x
sta T0 ; platform bottom edge + bbox (lo)
lda Ram_PlatformBottom_i16_1_arr, x
adc #0
lda #0
adc Ram_PlatformBottom_i16_1_arr, x
sta T1 ; platform bottom edge + bbox (hi)
cmp Zp_AvatarPosY_i16 + 1
blt _Return
Expand All @@ -733,8 +742,17 @@ _MovingUp:
sta Zp_AvatarPosY_i16 + 0
lda T1 ; platform bottom edge + bbox (hi)
sta Zp_AvatarPosY_i16 + 1
;; TODO: if reverse gravity, set Zp_AvatarPlatformIndex_u8
jmp _Collided
;; If gravity is reversed, the avatar is now riding this platform.
bit Zp_AvatarFlags_bObj
.assert bObj::FlipV = bProc::Negative, error
bpl _Collided ; gravity is normal, so avatar isn't riding platform above
_RidingPlatform:
stx Zp_AvatarPlatformIndex_u8
_Collided:
lda Ram_PlatformType_ePlatform_arr, x
sta Zp_AvatarCollided_ePlatform
_Return:
rts
_MovingDown:
;; Check bottom edge of platform.
lda Ram_PlatformBottom_i16_1_arr, x
Expand Down Expand Up @@ -766,13 +784,11 @@ _MovingDown:
sta Zp_AvatarPosY_i16 + 0
lda T1 ; platform top edge - bbox (hi)
sta Zp_AvatarPosY_i16 + 1
;; Record that the avatar is now riding this platform.
stx Zp_AvatarPlatformIndex_u8 ; TODO: only for normal gravity
_Collided:
lda Ram_PlatformType_ePlatform_arr, x
sta Zp_AvatarCollided_ePlatform
_Return:
rts
;; If gravity is normal, the avatar is now riding this platform.
bit Zp_AvatarFlags_bObj
.assert bObj::FlipV = bProc::Negative, error
bpl _RidingPlatform
bmi _Collided ; unconditional
.ENDPROC

;;; Determines whether both (1) the bottom of the avatar is below the top of
Expand Down
23 changes: 18 additions & 5 deletions src/push.asm
Original file line number Diff line number Diff line change
Expand Up @@ -398,10 +398,22 @@ _NoHitPassage:
.assert bObj::FlipV = bProc::Negative, error
bpl _MovingDown ; normal gravity; treat no vertical movement as "down"
_MovingUp:
bit Zp_AvatarFlags_bObj
.assert bObj::FlipV = bProc::Negative, error
bpl @normalGravity
@reverseGravity:
lda #kAvatarBoundingBoxDown
clc ; subtract an extra 1 below
bcc @setBoundingBox ; unconditional
@normalGravity:
lda #kAvatarBoundingBoxUp
sec ; perform normal subtraction below
@setBoundingBox:
sta T3 ; bounding box up
;; Calculate the room block row index just above the avatar's head, and
;; store it in T2.
lda Zp_AvatarPosY_i16 + 0
sub #kAvatarBoundingBoxUp ; TODO: handle reverse gravity
sbc T3 ; bounding box up
sta T2
lda Zp_AvatarPosY_i16 + 1
sbc #0
Expand All @@ -420,16 +432,17 @@ _MovingUp:
@solid:
;; We've hit the ceiling, so set vertical position to just below the
;; ceiling we hit.
inc T2 ; increment room block row to just below the ceiling
lda #0
.repeat 4
asl T2 ; room block row index (top of avatar)
asl T2 ; room block row index (middle of avatar)
rol a
.endrepeat
tax
lda T2
add #kBlockHeightPx + kAvatarBoundingBoxUp ; TODO: handle reverse gravity
lda T2 ; bottom of ceiling (lo)
adc T3 ; bounding box up (carry is clear from ROL above)
sta Zp_AvatarPosY_i16 + 0
txa
txa ; bottom of ceiling (hi)
adc #0
sta Zp_AvatarPosY_i16 + 1
;; Indicate that we hit solid terrain.
Expand Down

0 comments on commit e9577b2

Please sign in to comment.