; ; gamePlayer.s ; BuGS ; ; Created by Jeremy Rand on 2020-10-28. ;Copyright © 2020 Jeremy Rand. All rights reserved. ; case on mcopy gamePlayer.macros keep gamePlayer gamePlayer start using globalData using tileData using screenData PLAYER_EXPLOSION_FRAME_COUNT equ 3 PLAYER_RESTART_LEVEL_FRAME_COUNT equ 20 initPlayer entry ldy #STARTING_NUM_LIVES sty numLives stz playerIgnoreFirstPoll stz playerNum ldx #P1_LIVES_OFFSET initPlayer_loop1 anop lda #TILE_PLAYER sta tileType,x phy _dirtyNonGameTile ply dex dex dey bne initPlayer_loop1 lda isSinglePlayer beq initPlayer_done ldy #STARTING_NUM_LIVES sty numLives+2 ldx #P2_LIVES_OFFSET initPlayer_loop2 anop lda #TILE_PLAYER sta tileType,x phy _dirtyNonGameTile ply dex dex dey bne initPlayer_loop2 initPlayer_done anop jmp scoreSwitchPlayer playerLevelStart entry stz playerIgnoreFirstPoll lda #PLAYER_STATE_ONSCREEN sta playerState lda #STARTING_MOUSE_X sta mouseX lda #STARTING_MOUSE_Y sta mouseY asl a tay lda mouseX lsr a adc mouseYAddress,y sta mouseAddress lda #1 sta mouseDown ldx playerNum dec numLives,x cpx #PLAYER_ONE beq playerLevelStart_playerOne lda #P2_LIVES_OFFSET bra playerLevelStart_cont playerLevelStart_playerOne anop lda #P1_LIVES_OFFSET playerLevelStart_cont anop sec sbc numLives,x sec sbc numLives,x tax lda #TILE_EMPTY sta tileType,x _dirtyNonGameTile rtl playerAddLife entry ldx playerNum cpx #PLAYER_ONE beq playerAddLife_playerOne lda #P2_LIVES_OFFSET bra playerAddLife_cont playerAddLife_playerOne anop lda #P1_LIVES_OFFSET playerAddLife_cont anop sec sbc numLives,x sec sbc numLives,x inc numLives,x tax lda #TILE_PLAYER sta tileType,x _dirtyNonGameTile jmp playExtraLifeSound updatePlayer entry lda gameState bne updatePlayer_gameRunning rtl updatePlayer_gameRunning anop lda playerState cmp #PLAYER_STATE_NONE bne updatePlayer_notNone rtl updatePlayer_notNone anop cmp #PLAYER_STATE_EXPLODING beq updatePlayer_exploding jmp updatePlayer_onScreen updatePlayer_exploding anop lda playerFrameCount beq updatePlayer_nextExplosion dec a sta playerFrameCount bra updatePlayer_drawExplosion updatePlayer_nextExplosion anop lda playerExplosionOffset beq updatePlayer_doneExplosion sec sbc #4 sta playerExplosionOffset lda #PLAYER_EXPLOSION_FRAME_COUNT sta playerFrameCount bra updatePlayer_drawExplosion updatePlayer_doneExplosion anop lda #PLAYER_STATE_NONE sta playerState rtl updatePlayer_drawExplosion anop lda mouseAddress sec sbc #SCREEN_ADDRESS and #$fffc tax lda >screenToTileOffset,x tax lda #TILE_STATE_DIRTY sta tileDirty,x ldy tileBelow,x cpy #INVALID_TILE_NUM beq updatePlayer_drawExplosionSkipBelow1 sta tileDirty,y updatePlayer_drawExplosionSkipBelow1 anop ldy tileRight,x sta tileDirty,y ldx tileBelow,y cpx #INVALID_TILE_NUM beq updatePlayer_drawExplosionSkipBelow2 sta tileDirty,x updatePlayer_drawExplosionSkipBelow2 anop ldx tileRight,y cpx #RHS_FIRST_TILE_OFFSET bge updatePlayer_drawExplosionSkipBelow3 sta tileDirty,x ldy tileBelow,x cpy #INVALID_TILE_NUM beq updatePlayer_drawExplosionSkipBelow3 sta tileDirty,y updatePlayer_drawExplosionSkipBelow3 anop ldy mouseAddress ldx playerExplosionOffset lda shipExplosionJumpTable,x sta jumpInst+1 lda shipExplosionJumpTable+2,x sta jumpInst+3 jumpInst anop jmp >shipExplosion1 nop updatePlayer_onScreen anop ldx #0 ldy #0 ; This code for reading the mouse data is based on some code which John Brooks helpfully provided, although I did things ; quite differently because I have different needs. But this is about as low cost as can be made for reading the position ; of the mouse. short i,m phb lda #$e0 pha plb lda MOUSE_STATUS bpl updatePlayer_noMousePoll and #2 bne updatePlayer_mouseYOnly ldx MOUSE_DATA_REG updatePlayer_mouseYOnly anop ldy MOUSE_DATA_REG updatePlayer_doneMousePoll anop plb long i,m lda playerIgnoreFirstPoll bne updatePlayer_handleDeltas lda #1 sta playerIgnoreFirstPoll jmp updatePlayer_skipDeltas updatePlayer_noMousePoll anop plb long i,m jmp updatePlayer_skipDeltas updatePlayer_handleDeltas anop ; The X and Y register also has a bit in each which indicates whether a ; mouse button is down or not. txa and #$0080 beq updatePlayer_mouseDown tya and #$0080 beq updatePlayer_mouseDown lda #1 sta mouseDown bra updatePlayer_doY updatePlayer_mouseDown anop stz mouseDown updatePlayer_doY anop ; The Y register has the deltaY tya bit #$40 bne updatePlayer_negY and #$3f inc a lsr a bne updatePlayer_hasPosY jmp updatePlayer_doX updatePlayer_hasPosY anop cmp #9 blt updatePlayer_posYNoClamp lda #8 updatePlayer_posYNoClamp anop clc adc mouseY cmp #MOUSE_MAX_Y blt updatePlayer_checkBelow lda #MOUSE_MAX_Y-1 updatePlayer_checkBelow anop sta mouseY asl a tay lda mouseYTileBelow,y sta mouseTemp lda mouseX asl a tay lda mouseXTileLeft,y clc adc mouseTemp phx tax lda tileType,x bne updatePlayer_blockedBelow lda mouseXTileRight,y clc adc mouseTemp tax lda tileType,x bne updatePlayer_blockedBelow plx bra updatePlayer_doX updatePlayer_blockedBelow anop plx lda mouseY dec a and #$fff8 sta mouseY bra updatePlayer_doX updatePlayer_negY anop ora #$ffc0 dec a lsr a ora #$8000 cmp #$fff8 bge updatePlayer_negYNoClamp lda #$fff8 updatePlayer_negYNoClamp anop clc adc mouseY bpl updatePlayer_checkAbove lda #0 updatePlayer_checkAbove anop sta mouseY asl a tay lda mouseYTileAbove,y sta mouseTemp lda mouseX asl a tay lda mouseXTileLeft,y clc adc mouseTemp phx tax lda tileType,x bne updatePlayer_blockedAbove lda mouseXTileRight,y clc adc mouseTemp tax lda tileType,x bne updatePlayer_blockedAbove plx bra updatePlayer_doX updatePlayer_blockedAbove anop plx lda mouseY clc adc #TILE_PIXEL_HEIGHT and #$fff8 sta mouseY updatePlayer_doX anop ; The X register has the deltaX txa bit #$40 bne updatePlayer_negX and #$3f inc a lsr a bne updatePlayer_hasPosX jmp updatePlayer_skipDeltas updatePlayer_hasPosX anop cmp #9 blt updatePlayer_posXNoClamp lda #8 updatePlayer_posXNoClamp anop clc adc mouseX cmp #MOUSE_MAX_X blt updatePlayer_checkRight lda #MOUSE_MAX_X-1 updatePlayer_checkRight anop sta mouseX asl a tay lda mouseXTileRight,y sta mouseTemp lda mouseY asl a tay lda mouseYTileAbove,y clc adc mouseTemp tax lda tileType,x bne updatePlayer_blockedRight lda mouseYTileBelow,y clc adc mouseTemp tax lda tileType,x beq updatePlayer_skipDeltas updatePlayer_blockedRight anop lda mouseX dec a and #$fff8 sta mouseX bra updatePlayer_skipDeltas updatePlayer_negX anop ora #$ffc0 dec a lsr a ora #$8000 cmp #$fff8 bge updatePlayer_negXNoClamp lda #$fff8 updatePlayer_negXNoClamp anop clc adc mouseX bpl updatePlayer_checkLeft lda #0 updatePlayer_checkLeft anop sta mouseX asl a tay lda mouseXTileLeft,y sta mouseTemp lda mouseY asl a tay lda mouseYTileAbove,y clc adc mouseTemp tax lda tileType,x bne updatePlayer_blockedLeft lda mouseYTileBelow,y clc adc mouseTemp tax lda tileType,x beq updatePlayer_skipDeltas updatePlayer_blockedLeft anop lda mouseX clc adc #TILE_PIXEL_WIDTH and #$fff8 sta mouseX updatePlayer_skipDeltas anop lda mouseDown bne updatePlayer_notShooting jsl maybeShoot updatePlayer_notShooting anop lda mouseY asl a tay lda mouseX lsr a bcs updatePlayer_shift adc mouseYAddress,y sta mouseAddress tay jsl drawShip bra updatePlayer_dirty updatePlayer_shift anop adc mouseYAddress,y dec a sta mouseAddress tay jsl drawShipShift updatePlayer_dirty anop bne updatePlayer_collision jmp updatePlayer_noCollision updatePlayer_collision anop lda #PLAYER_STATE_EXPLODING sta playerState ; Figure out which kind of bug collided with the player and cause it to ; explode. txa sec sbc #SCREEN_ADDRESS and #$fffc tax lda >screenToTileOffset,x jsl isSpiderCollision bcc updatePlayer_notSpiderCollision jsl explodeSpider bra updatePlayer_explode updatePlayer_notSpiderCollision anop jsl isFleaCollision bcc updatePlayer_notFleaCollision jsl explodeFlea bra updatePlayer_explode updatePlayer_notFleaCollision anop jsl isSegmentCollision bcc updatePlayer_explode jsl explodeSegment updatePlayer_explode anop lda mouseAddress sec sbc #TILE_BYTE_WIDTH/2 sta mouseAddress sec sbc #SCREEN_ADDRESS and #$fffc tax lda >screenToTileOffset,x cmp #RHS_FIRST_TILE_OFFSET bge updatePlayer_explosionOffLeft tay ldx tileRight,y ldy tileRight,x cpy #RHS_FIRST_TILE_OFFSET blt updatePlayer_contCollision lda mouseAddress dec a and #$fffc sta mouseAddress bra updatePlayer_contCollision updatePlayer_explosionOffLeft anop lda mouseAddress clc adc #TILE_BYTE_WIDTH and #$fffc sta mouseAddress updatePlayer_contCollision anop lda #PLAYER_EXPLOSION_FRAME_COUNT sta playerFrameCount lda #SHIP_EXPLOSION_LAST_OFFSET sta playerExplosionOffset jsl playDeathSound jmp updatePlayer_exploding updatePlayer_noCollision anop lda mouseAddress sec sbc #SCREEN_ADDRESS and #$fffc tax lda >screenToTileOffset,x tax lda #TILE_STATE_DIRTY cpx #RHS_FIRST_TILE_OFFSET bge updatePlayer_tileOffscreen1 sta tileDirty,x updatePlayer_tileOffscreen1 anop ldy tileRight,x cpy #RHS_FIRST_TILE_OFFSET bge updatePlayer_tileOffscreen2 sta tileDirty,y updatePlayer_tileOffscreen2 anop ldy tileBelow,x cpy #INVALID_TILE_NUM beq updatePlayer_done sta tileDirty,y ldx tileRight,y cpx #RHS_FIRST_TILE_OFFSET bge updatePlayer_done sta tileDirty,x updatePlayer_done anop rtl playerFrameCount dc i2'0' playerExplosionOffset dc i2'0' playerIgnoreFirstPoll dc i2'0' mouseDown dc i2'0' mouseTemp dc i2'0' SHIP_EXPLOSION_LAST_OFFSET equ 7*4 shipExplosionJumpTable anop dc i4'shipExplosion8' dc i4'shipExplosion7' dc i4'shipExplosion6' dc i4'shipExplosion5' dc i4'shipExplosion4' dc i4'shipExplosion3' dc i4'shipExplosion2' dc i4'shipExplosion1' end