Prev: 6FDD Up: Map Next: 7159
7030: Handler: Player Bullets
Handler_PlayerBullets 7030 LD HL,$6695 HL=Bullet_RateLimiter.
7033 LD A,(HL) Jump to PlayerBullets_UpdateLimiter if *Bullet_RateLimiter is not equal to 03.
7034 CP $03
7036 JR NZ,PlayerBullets_UpdateLimiter
Reset Bullet_RateLimiter back to 00 (FF+01) to start the counter again.
7038 LD (HL),$FF Write FF to *Bullet_RateLimiter.
Increment the counter.
PlayerBullets_UpdateLimiter 703A INC (HL) Increment *Bullet_RateLimiter by one.
Start processing the bullets.
703B LD HL,$6697 HL=Table_BulletPosition.
Modified by the code at 741E.
703E LD B,$01 Set a counter in B for nn bullet(s).
PlayerBullets_Loop 7040 PUSH HL Stash the bullet data pointer and bullet counter on the stack.
7041 PUSH BC
7042 LD E,(HL) Load DE with the bullet position.
7043 INC HL
7044 LD D,(HL)
7045 LD A,D Jump to PlayerBullets_UpdateActive if the bullet is active.
7046 OR D
7047 JP NZ,PlayerBullets_UpdateActive
Check if the player can fire a new bullet.
704A LD A,($66A4) Jump to PlayerBullets_NextBullet if either *Flag_Collision or *Flag_Shield are active.
704D OR A
704E JP NZ,PlayerBullets_NextBullet
7051 LD A,($6693)
7054 OR A
7055 JP NZ,PlayerBullets_NextBullet
Load the previous fire button state into C (used for a debounce check at 708D).
7058 LD A,($6696) C=*Fire_ButtonState.
705B LD C,A
Check if the game is running in demo mode.
705C LD A,($66F3) Jump to PlayerBullets_ReadInput if *Flag_ActiveDemoMode is not active.
705F OR A
7060 JR Z,PlayerBullets_ReadInput
The game is in demo mode, so generate random firing action.
7062 CALL GenerateRandomNumber Generate a random number between 00-0F.
7065 AND %00001111
7067 JR PlayerBullets_ProcessInput Jump to PlayerBullets_ProcessInput.
The game is not in demo mode, so read the player fire button input.
PlayerBullets_ReadInput 7069 DI Disable interrupts.
Check if the control method is the Kempston joystick?
706A LD A,($66F6) Jump to PlayerBullets_AGF if *ControlMethod is not the Kempston joystick.
706D CP $02
706F JR NZ,PlayerBullets_AGF
The control method is Kempston joystick, so test the fire button.
7071 IN A,($1F) A=read from the Kempston joystick port.
7073 AND %00010000 Keep only bit 4 (the fire button input).
7075 JR PlayerBullets_StoreInput Jump to PlayerBullets_StoreInput.
Check if the control method is the AGF joystick?
PlayerBullets_AGF 7077 CP $01 Jump to PlayerBullets_Keyboard if *ControlMethod is not the AGF joystick.
7079 JR NZ,PlayerBullets_Keyboard
707B LD A,$EF
Port Number Bit
0 1 2 3 4
EF 0 9 8 7 6
707D JR PlayerBullets_ReadKeyboard Jump to PlayerBullets_ReadKeyboard.
Else, the only control option left is the keyboard.
PlayerBullets_Keyboard 707F LD A,$7F
Port Number Bit
0 1 2 3 4
7F SPACE FULL-STOP M N B
PlayerBullets_ReadKeyboard 7081 IN A,($FE) Read from the keyboard.
7083 AND %00000001 Keep only bit 0 (the fire button input).
PlayerBullets_ProcessInput 7085 LD A,$10 Set A to 10 (the fire button was pressed).
7087 JR Z,PlayerBullets_StoreInput Jump to PlayerBullets_StoreInput if the fire button was pressed.
7089 XOR A Set A to 00 (the fire button wasn't pressed).
PlayerBullets_StoreInput 708A LD ($6696),A Write the current fire button state to *Fire_ButtonState.
Is the fire button state unchanged since the last time this routine ran?
708D CP C Jump to PlayerBullets_NextBullet if the current fire button state matches the previous fire button state.
708E JP Z,PlayerBullets_NextBullet
7091 OR A Also jump to PlayerBullets_NextBullet if the fire button wasn't pressed.
7092 JP Z,PlayerBullets_NextBullet
Skip playing the firing sound if this is the demo mode.
7095 LD A,($66F3) Jump to PlayerBullets_CheckSpawn if *Flag_ActiveDemoMode is active.
7098 OR A
7099 JR NZ,PlayerBullets_CheckSpawn
709B PUSH DE Stash the bullet position on the stack.
709C LD B,$16 Set a counter in B for 16 sound iterations.
709E LD HL,$0052 Set the initial sound pitch to 0052.
PlayerBullets_SoundLoop 70A1 PUSH BC Stash the sound counter and pitch on the stack.
70A2 PUSH HL
70A3 LD A,$10 Enable the speaker (bit 4) and disable interrupts.
70A5 DI
70A6 OUT ($FE),A
70A8 LD DE,$0001 Set the sound duration to 0001.
70AB CALL $03B5 Call BEEPER.
70AE DI Disable interrupts.
70AF POP HL Restore the pitch value from the stack.
70B0 INC HL Increment the pitch by four.
70B1 INC HL
70B2 INC HL
70B3 INC HL
70B4 POP BC Restore the sound counter from the stack.
70B5 DJNZ PlayerBullets_SoundLoop Decrease the sound counter by one and loop back to PlayerBullets_SoundLoop until the counter is zero.
70B7 POP DE Restore the bullet position from the stack.
Check if the bullet spawning position is clear in the attribute buffer.
PlayerBullets_CheckSpawn 70B8 LD A,($66ED) Set L to *PlayerAttributeBufferPosition-1F to calculate the bullet spawn position.
70BB SUB $1F
70BD LD L,A
70BE LD H,$5A Set H to 5A as the bullets always spawn on the same row.
70C0 LD A,(HL) Jump to PlayerBullets_NextBullet if the attribute at this position isn't BLACK (i.e. it is occupied).
70C1 OR A
70C2 JP NZ,PlayerBullets_NextBullet
The bullet position isn't already occupied, so colour this attribute block.
70C5 LD (HL),$47 Write INK:WHITE, PAPER:BLACK (BRIGHT) to the bullet attribute buffer position.
70C7 CALL ConvertAttributeToScreenBufferAddress Call ConvertAttributeToScreenBufferAddress.
70CA SET 2,H Set bit 2 of H.
70CC PUSH HL Stash HL on the stack.
70CD LD A,($66A6) A=*MovementAnimationFrameCounter.
70D0 OR A Set the bits from A.
70D1 LD B,A B=A.
70D2 LD A,$01 A=01.
70D4 JR Z,PlayerBullets_Store Jump to PlayerBullets_Store if HL is equal to A.
PlayerBullets_FindSlot_Loop 70D6 SLA A Shift A left (with carry).
70D8 DJNZ PlayerBullets_FindSlot_Loop Decrease counter by one and loop back to PlayerBullets_FindSlot_Loop until counter is zero.
PlayerBullets_Store 70DA POP DE Restore DE and BC from the stack.
70DB POP BC
70DC PUSH BC Stash BC and DE on the stack.
70DD PUSH DE
70DE LD HL,$669E HL=Table_BulletData.
PlayerBullets_FindSlot 70E1 INC HL Increment HL by one.
70E2 DJNZ PlayerBullets_FindSlot Decrease counter by one and loop back to PlayerBullets_FindSlot until counter is zero.
70E4 LD (HL),A Write A to *HL.
70E5 JR PlayerBullets_DrawNew Jump to PlayerBullets_DrawNew.
Update active bullet position.
PlayerBullets_UpdateActive 70E7 LD HL,$669E HL=Table_BulletData.
70EA POP BC Restore the bullet counter from the stack.
70EB PUSH BC But also stash the bullet counter back on the stack.
LocateBulletData_Loop 70EC INC HL Advance to the next bullet data slot.
70ED DJNZ LocateBulletData_Loop Decrease the bullet counter by one and loop back to LocateBulletData_Loop until the current bullet slot is found.
70EF LD A,(HL) Load the bullet state into A.
70F0 PUSH AF Stash the bullet state and bullet position on the stack.
70F1 PUSH DE
70F2 CALL ConvertScreenToAttributeBufferAddress Call ConvertScreenToAttributeBufferAddress.
70F5 LD A,(DE) Fetch the current attribute applied to the bullet, check if it is: INK:WHITE, PAPER:BLACK (BRIGHT)?
70F6 CP $47
70F8 POP DE Restore the bullet position from the stack.
70F9 JR NZ,PlayerBullets_Collision Jump to PlayerBullets_Collision if the bullet has hit something, i.e. is no longer INK:WHITE, PAPER:BLACK (BRIGHT).
70FB BIT 2,D Jump to PlayerBullets_ClearOld if bit 2 of D is not set.
70FD JR Z,PlayerBullets_ClearOld
Clear the old bullet position and draw it at a new position.
70FF POP AF Restore AF from the stack.
7100 RES 2,D Reset bit 2 of D.
7102 PUSH DE Stash DE on the stack.
7103 LD B,$04 Set a counter in B for 04 pixel lines.
PlayerBullets_EraseLoop 7105 LD (DE),A Write A to *DE.
7106 INC D Move down one pixel line in the screen buffer.
7107 DJNZ PlayerBullets_EraseLoop Decrease the line counter by one and loop back to PlayerBullets_EraseLoop until all 04 lines of the bullet have been erased.
7109 XOR A Set A to 00 as we're clearing the bullet graphic.
710A JR PlayerBullets_DrawNew Jump to PlayerBullets_DrawNew.
Clear the old bullet from the screen.
PlayerBullets_ClearOld 710C LD B,$04 Set a counter in B for 04 pixel lines.
710E XOR A Set A to 00 as we're clearing the bullet graphic.
PlayerBullets_ClearLoop 710F LD (DE),A Write the empty data to the screen buffer.
7110 INC D Move down one pixel line in the screen buffer.
7111 DJNZ PlayerBullets_ClearLoop Decrease the line counter by one and loop back to PlayerBullets_ClearLoop until all 04 lines of the bullet have been erased.
7113 CALL ConvertScreenToAttributeBufferAddress Call ConvertScreenToAttributeBufferAddress.
7116 EX DE,HL Exchange the DE and HL registers.
7117 LD (HL),$00 Write 00 to *HL.
7119 LD A,H Jump to PlayerBullets_MoveUp if H is not equal to 58.
711A CP $58
711C JR NZ,PlayerBullets_MoveUp
711E LD A,L A=L.
711F AND %11100000 Keep only bits 5-7.
7121 CP $20 Jump to PlayerBullets_MoveUp if A is not equal to 20.
7123 JR NZ,PlayerBullets_MoveUp
7125 POP AF Restore the bullet state from the stack.
7126 LD DE,$0000 Set the bullet position to 0000 (inactive).
7129 JR PlayerBullets_NextBullet Jump to PlayerBullets_NextBullet.
Draw the bullet in the new position.
PlayerBullets_MoveUp 712B LD C,$20 Move up one row in the attribute buffer (subtract 20).
712D AND A
712E SBC HL,BC
7130 LD A,(HL) Jump to PlayerBullets_SetNewPosition if the new position is "clear" (i.e. the bullet hasn't hit anything/ there's no attribute applied at this attribute buffer location).
7131 OR A
7132 JR Z,PlayerBullets_SetNewPosition
The bullet has hit something so handle the collision.
PlayerBullets_Collision 7134 CALL Handler_BulletCollision Call Handler_BulletCollision.
7137 POP AF Restore the bullet state from the stack.
7138 LD DE,$0000 Set the bullet position to 0000 (inactive).
713B JR PlayerBullets_NextBullet Jump to PlayerBullets_NextBullet.
PlayerBullets_SetNewPosition 713D LD (HL),$47 Mark the new position with the attribute INK:WHITE, PAPER:BLACK (BRIGHT).
713F CALL ConvertAttributeToScreenBufferAddress Call ConvertAttributeToScreenBufferAddress.
7142 EX DE,HL Exchange the DE and HL registers.
7143 SET 2,D Set bit 2 of D.
7145 POP AF Restore the bullet state from the stack.
7146 PUSH DE Stash the new bullet position on the stack.
Draw the bullet graphic.
PlayerBullets_DrawNew 7147 LD B,$04 Set a counter in B for 04 pixel lines.
PlayerBullets_DrawLoop 7149 LD (DE),A Write A to *DE.
714A INC D Move down one pixel line in the screen buffer.
714B DJNZ PlayerBullets_DrawLoop Decrease the line counter by one and loop back to PlayerBullets_DrawLoop until all 04 lines of the bullet have been drawn.
714D POP DE Restore the original bullet position from the stack.
Housekeeping; move onto the next bullet.
PlayerBullets_NextBullet 714E POP BC Restore the bullet counter and bullet data pointer from the stack.
714F POP HL
7150 LD (HL),E Store the bullet position back to the data table.
7151 INC HL
7152 LD (HL),D
7153 INC HL
7154 DEC B Decrease the bullet counter by one.
7155 JP NZ,PlayerBullets_Loop Jump to PlayerBullets_Loop until all of the bullets have been processed.
7158 RET Return.
Prev: 6FDD Up: Map Next: 7159