Fix problem on real HW where the player will start the next level shooting if they died while shooting, regardless of the state of the mouse. It now ignores the first poll of the mouse at the start of a level to avoid stale poll information. Add some debug in the code for jumping to the head and body segment draw routines to confirm that the table offsets are sane. I have seen a crash which indicates that sometimes the offset is incorrect.

This commit is contained in:
Jeremy Rand 2020-12-16 12:51:37 -05:00
parent d201f80c3b
commit 763ce0626e
3 changed files with 62 additions and 5 deletions

10
BUGS.md
View File

@ -4,11 +4,12 @@ BUGS
This is a list of the software bugs (as opposed to the bugs in the game that you shoot) that still need attention:
* On the latest build (0136579125034f41f8415b496d5ba706e86d65d9) on real HW, on startup I head the spider loop once and then I can play a game and finish that game. But when I try to start a second game, I crash. The stack looks corrupted and execution is way off in the weeds somewhere. This isn't happening on either emulator.
* I am thinking this is the same crash as the one which follows. I tried to reproduce this on real HW again with that debug in place but could not.
* I reproduced a crash on GSPlus after dying and starting a new game. From the stack, it was clear it was trying to draw a body segment but the jump instruction was set to garbage. I am hoping this is the same crash as the one saw on real HW.
* I have added some debug code to detect this. I am validating that the offset into the draw table for head and body segments is "sane" and if not brk.
* A spider moving left to right went off screen and left garbage on the RHS as it exited. I have only seen this once. I think it coincided with the player dying.
* Sometimes when the player dies, the "you can shoot" indicator is left behind as garbage on-screen.
* If you die holding the mouse button down, your next game will start shooting without pressing the mouse button.
* I was reproducing this reliably on real HW but I don't see it from either emulator. Need to try to reproduce it again on real HW.
* I also don't see how this happens given how the code is structured.
@ -24,3 +25,6 @@ FIXED
* Caused by both gamePlayer.s and level.s calling start level when the last segment is the one which kills the player. The player code now defers to the level code to handle starting the level after the player dies that way.
* Sometimes centipede segments seem to be stacked one on top of another. You think there is just one left but you shoot it and there is one underneath it. This should not happen.
* Caused by the lack of head segment collision detection in the slow segment code paths. I had thought that slow head segments would never collide. But once you split a slow centipede into two separate segments, you now have slow heads that can collide.
* If you die holding the mouse button down, your next game will start shooting without pressing the mouse button.
* I was reproducing this reliably on real HW but I don't see it from either emulator. Need to try to reproduce it again on real HW.
* The problem is that the game should ignore the first poll from the mouse when starting a new level. The mouse HW/ADB has put some info in about the state of the mouse and we don't poll it for quite some time. Even if the mouse changes state, the last state is still there and becomes stale. The solution I implemented was to throw away the first mouse poll at the start of every level.

View File

@ -22,6 +22,7 @@ PLAYER_RESTART_LEVEL_FRAME_COUNT equ 20
initPlayer entry
ldy #STARTING_NUM_LIVES
sty numLives
stz playerIgnoreFirstPoll
ldx #P1_LIVES_OFFSET
initPlayer_loop anop
lda #TILE_PLAYER
@ -37,6 +38,7 @@ initPlayer_loop anop
playerLevelStart entry
stz playerIgnoreFirstPoll
lda #PLAYER_STATE_ONSCREEN
sta playerState
lda #STARTING_MOUSE_X
@ -194,7 +196,11 @@ updatePlayer_mouseYOnly anop
updatePlayer_doneMousePoll anop
plb
long i,m
bra updatePlayer_handleDeltas
lda playerIgnoreFirstPoll
bne updatePlayer_handleDeltas
lda #1
sta playerIgnoreFirstPoll
jmp updatePlayer_skipDeltas
updatePlayer_noMousePoll anop
plb
@ -528,6 +534,7 @@ updatePlayer_done anop
playerFrameCount dc i2'0'
playerExplosionOffset dc i2'0'
playerIgnoreFirstPoll dc i2'0'
mouseDown dc i2'0'
mouseTemp dc i2'0'

View File

@ -131,6 +131,18 @@ segmentHeadJump entry
beq segmentHeadJump_noShift
tay
; DEBUG - Validate the offset into the table and crash if not valid
and #3
beq segmentHeadJump_isMultipleOf4
brk $5
segmentHeadJump_isMultipleOf4 anop
cpy #157
blt segmentHeadJump_isInsideTable
brk $6
segmentHeadJump_isInsideTable anop
; DEBUG - End of validation
lda headShiftJumpTable,y
sta segmentHeadJump_jumpInst+1
lda headShiftJumpTable+2,y
@ -141,6 +153,18 @@ segmentHeadJump entry
segmentHeadJump_noShift anop
tay
; DEBUG - Validate the offset into the table and crash if not valid
and #3
beq segmentHeadJumpShift_isMultipleOf4
brk $7
segmentHeadJumpShift_isMultipleOf4 anop
cpy #157
blt segmentHeadJumpShift_isInsideTable
brk $8
segmentHeadJumpShift_isInsideTable anop
; DEBUG - End of validation
lda headJumpTable,y
sta segmentHeadJump_jumpInst+1
lda headJumpTable+2,y
@ -168,6 +192,17 @@ segmentBodyJump entry
beq segmentBodyJump_noShift
tay
; DEBUG - Validate the offset into the table and crash if not valid
and #3
beq segmentBodyJump_isMultipleOf4
brk $1
segmentBodyJump_isMultipleOf4 anop
cpy #157
blt segmentBodyJump_isInsideTable
brk $2
segmentBodyJump_isInsideTable anop
; DEBUG - End of validation
lda bodyShiftJumpTable,y
sta segmentBodyJump_jumpInst+1
lda bodyShiftJumpTable+2,y
@ -178,7 +213,18 @@ segmentBodyJump entry
segmentBodyJump_noShift anop
tay
lda bodyJumpTable,y
; DEBUG - Validate the offset into the table and crash if not valid
and #3
beq segmentBodyJumpShift_isMultipleOf4
brk $3
segmentBodyJumpShift_isMultipleOf4 anop
cpy #157
blt segmentBodyJumpShift_isInsideTable
brk $4
segmentBodyJumpShift_isInsideTable anop
; DEBUG - End of validation
lda bodyJumpTable,y
sta segmentBodyJump_jumpInst+1
lda bodyJumpTable+2,y
sta segmentBodyJump_jumpInst+3