Prev: 28637 Up: Map Next: 29017
28720: Handler: Player Bullets
Handler_PlayerBullets 28720 LD HL,26261 HL=Bullet_RateLimiter.
28723 LD A,(HL) Jump to PlayerBullets_UpdateLimiter if *Bullet_RateLimiter is not equal to 3.
28724 CP 3
28726 JR NZ,PlayerBullets_UpdateLimiter
Reset Bullet_RateLimiter back to 0 (255+1) to start the counter again.
28728 LD (HL),255 Write 255 to *Bullet_RateLimiter.
Increment the counter.
PlayerBullets_UpdateLimiter 28730 INC (HL) Increment *Bullet_RateLimiter by one.
Start processing the bullets.
28731 LD HL,26263 HL=Table_BulletPosition.
Modified by the code at 29726.
28734 LD B,1 Set a counter in B for nn bullet(s).
PlayerBullets_Loop 28736 PUSH HL Stash the bullet data pointer and bullet counter on the stack.
28737 PUSH BC
28738 LD E,(HL) Load DE with the bullet position.
28739 INC HL
28740 LD D,(HL)
28741 LD A,D Jump to PlayerBullets_UpdateActive if the bullet is active.
28742 OR D
28743 JP NZ,PlayerBullets_UpdateActive
Check if the player can fire a new bullet.
28746 LD A,(26276) Jump to PlayerBullets_NextBullet if either *Flag_Collision or *Flag_Shield are active.
28749 OR A
28750 JP NZ,PlayerBullets_NextBullet
28753 LD A,(26259)
28756 OR A
28757 JP NZ,PlayerBullets_NextBullet
Load the previous fire button state into C (used for a debounce check at 28813).
28760 LD A,(26262) C=*Fire_ButtonState.
28763 LD C,A
Check if the game is running in demo mode.
28764 LD A,(26355) Jump to PlayerBullets_ReadInput if *Flag_ActiveDemoMode is not active.
28767 OR A
28768 JR Z,PlayerBullets_ReadInput
The game is in demo mode, so generate random firing action.
28770 CALL GenerateRandomNumber Generate a random number between 0-15.
28773 AND %00001111
28775 JR PlayerBullets_ProcessInput Jump to PlayerBullets_ProcessInput.
The game is not in demo mode, so read the player fire button input.
PlayerBullets_ReadInput 28777 DI Disable interrupts.
Check if the control method is the Kempston joystick?
28778 LD A,(26358) Jump to PlayerBullets_AGF if *ControlMethod is not the Kempston joystick.
28781 CP 2
28783 JR NZ,PlayerBullets_AGF
The control method is Kempston joystick, so test the fire button.
28785 IN A,(31) A=read from the Kempston joystick port.
28787 AND %00010000 Keep only bit 4 (the fire button input).
28789 JR PlayerBullets_StoreInput Jump to PlayerBullets_StoreInput.
Check if the control method is the AGF joystick?
PlayerBullets_AGF 28791 CP 1 Jump to PlayerBullets_Keyboard if *ControlMethod is not the AGF joystick.
28793 JR NZ,PlayerBullets_Keyboard
28795 LD A,239
Port Number Bit
0 1 2 3 4
239 0 9 8 7 6
28797 JR PlayerBullets_ReadKeyboard Jump to PlayerBullets_ReadKeyboard.
Else, the only control option left is the keyboard.
PlayerBullets_Keyboard 28799 LD A,127
Port Number Bit
0 1 2 3 4
127 SPACE FULL-STOP M N B
PlayerBullets_ReadKeyboard 28801 IN A,(254) Read from the keyboard.
28803 AND %00000001 Keep only bit 0 (the fire button input).
PlayerBullets_ProcessInput 28805 LD A,16 Set A to 16 (the fire button was pressed).
28807 JR Z,PlayerBullets_StoreInput Jump to PlayerBullets_StoreInput if the fire button was pressed.
28809 XOR A Set A to 0 (the fire button wasn't pressed).
PlayerBullets_StoreInput 28810 LD (26262),A Write the current fire button state to *Fire_ButtonState.
Is the fire button state unchanged since the last time this routine ran?
28813 CP C Jump to PlayerBullets_NextBullet if the current fire button state matches the previous fire button state.
28814 JP Z,PlayerBullets_NextBullet
28817 OR A Also jump to PlayerBullets_NextBullet if the fire button wasn't pressed.
28818 JP Z,PlayerBullets_NextBullet
Skip playing the firing sound if this is the demo mode.
28821 LD A,(26355) Jump to PlayerBullets_CheckSpawn if *Flag_ActiveDemoMode is active.
28824 OR A
28825 JR NZ,PlayerBullets_CheckSpawn
28827 PUSH DE Stash the bullet position on the stack.
28828 LD B,22 Set a counter in B for 22 sound iterations.
28830 LD HL,82 Set the initial sound pitch to 0082.
PlayerBullets_SoundLoop 28833 PUSH BC Stash the sound counter and pitch on the stack.
28834 PUSH HL
28835 LD A,16 Enable the speaker (bit 4) and disable interrupts.
28837 DI
28838 OUT (254),A
28840 LD DE,1 Set the sound duration to 0001.
28843 CALL 949 Call BEEPER.
28846 DI Disable interrupts.
28847 POP HL Restore the pitch value from the stack.
28848 INC HL Increment the pitch by four.
28849 INC HL
28850 INC HL
28851 INC HL
28852 POP BC Restore the sound counter from the stack.
28853 DJNZ PlayerBullets_SoundLoop Decrease the sound counter by one and loop back to PlayerBullets_SoundLoop until the counter is zero.
28855 POP DE Restore the bullet position from the stack.
Check if the bullet spawning position is clear in the attribute buffer.
PlayerBullets_CheckSpawn 28856 LD A,(26349) Set L to *PlayerAttributeBufferPosition-31 to calculate the bullet spawn position.
28859 SUB 31
28861 LD L,A
28862 LD H,90 Set H to 90 as the bullets always spawn on the same row.
28864 LD A,(HL) Jump to PlayerBullets_NextBullet if the attribute at this position isn't BLACK (i.e. it is occupied).
28865 OR A
28866 JP NZ,PlayerBullets_NextBullet
The bullet position isn't already occupied, so colour this attribute block.
28869 LD (HL),71 Write INK:WHITE, PAPER:BLACK (BRIGHT) to the bullet attribute buffer position.
28871 CALL ConvertAttributeToScreenBufferAddress Call ConvertAttributeToScreenBufferAddress.
28874 SET 2,H Set bit 2 of H.
28876 PUSH HL Stash HL on the stack.
28877 LD A,(26278) A=*MovementAnimationFrameCounter.
28880 OR A Set the bits from A.
28881 LD B,A B=A.
28882 LD A,1 A=1.
28884 JR Z,PlayerBullets_Store Jump to PlayerBullets_Store if HL is equal to A.
PlayerBullets_FindSlot_Loop 28886 SLA A Shift A left (with carry).
28888 DJNZ PlayerBullets_FindSlot_Loop Decrease counter by one and loop back to PlayerBullets_FindSlot_Loop until counter is zero.
PlayerBullets_Store 28890 POP DE Restore DE and BC from the stack.
28891 POP BC
28892 PUSH BC Stash BC and DE on the stack.
28893 PUSH DE
28894 LD HL,26270 HL=Table_BulletData.
PlayerBullets_FindSlot 28897 INC HL Increment HL by one.
28898 DJNZ PlayerBullets_FindSlot Decrease counter by one and loop back to PlayerBullets_FindSlot until counter is zero.
28900 LD (HL),A Write A to *HL.
28901 JR PlayerBullets_DrawNew Jump to PlayerBullets_DrawNew.
Update active bullet position.
PlayerBullets_UpdateActive 28903 LD HL,26270 HL=Table_BulletData.
28906 POP BC Restore the bullet counter from the stack.
28907 PUSH BC But also stash the bullet counter back on the stack.
LocateBulletData_Loop 28908 INC HL Advance to the next bullet data slot.
28909 DJNZ LocateBulletData_Loop Decrease the bullet counter by one and loop back to LocateBulletData_Loop until the current bullet slot is found.
28911 LD A,(HL) Load the bullet state into A.
28912 PUSH AF Stash the bullet state and bullet position on the stack.
28913 PUSH DE
28914 CALL ConvertScreenToAttributeBufferAddress Call ConvertScreenToAttributeBufferAddress.
28917 LD A,(DE) Fetch the current attribute applied to the bullet, check if it is: INK:WHITE, PAPER:BLACK (BRIGHT)?
28918 CP 71
28920 POP DE Restore the bullet position from the stack.
28921 JR NZ,PlayerBullets_Collision Jump to PlayerBullets_Collision if the bullet has hit something, i.e. is no longer INK:WHITE, PAPER:BLACK (BRIGHT).
28923 BIT 2,D Jump to PlayerBullets_ClearOld if bit 2 of D is not set.
28925 JR Z,PlayerBullets_ClearOld
Clear the old bullet position and draw it at a new position.
28927 POP AF Restore AF from the stack.
28928 RES 2,D Reset bit 2 of D.
28930 PUSH DE Stash DE on the stack.
28931 LD B,4 Set a counter in B for 4 pixel lines.
PlayerBullets_EraseLoop 28933 LD (DE),A Write A to *DE.
28934 INC D Move down one pixel line in the screen buffer.
28935 DJNZ PlayerBullets_EraseLoop Decrease the line counter by one and loop back to PlayerBullets_EraseLoop until all 4 lines of the bullet have been erased.
28937 XOR A Set A to 0 as we're clearing the bullet graphic.
28938 JR PlayerBullets_DrawNew Jump to PlayerBullets_DrawNew.
Clear the old bullet from the screen.
PlayerBullets_ClearOld 28940 LD B,4 Set a counter in B for 4 pixel lines.
28942 XOR A Set A to 0 as we're clearing the bullet graphic.
PlayerBullets_ClearLoop 28943 LD (DE),A Write the empty data to the screen buffer.
28944 INC D Move down one pixel line in the screen buffer.
28945 DJNZ PlayerBullets_ClearLoop Decrease the line counter by one and loop back to PlayerBullets_ClearLoop until all 4 lines of the bullet have been erased.
28947 CALL ConvertScreenToAttributeBufferAddress Call ConvertScreenToAttributeBufferAddress.
28950 EX DE,HL Exchange the DE and HL registers.
28951 LD (HL),0 Write 0 to *HL.
28953 LD A,H Jump to PlayerBullets_MoveUp if H is not equal to 88.
28954 CP 88
28956 JR NZ,PlayerBullets_MoveUp
28958 LD A,L A=L.
28959 AND %11100000 Keep only bits 5-7.
28961 CP 32 Jump to PlayerBullets_MoveUp if A is not equal to 32.
28963 JR NZ,PlayerBullets_MoveUp
28965 POP AF Restore the bullet state from the stack.
28966 LD DE,0 Set the bullet position to 0000 (inactive).
28969 JR PlayerBullets_NextBullet Jump to PlayerBullets_NextBullet.
Draw the bullet in the new position.
PlayerBullets_MoveUp 28971 LD C,32 Move up one row in the attribute buffer (subtract 32).
28973 AND A
28974 SBC HL,BC
28976 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).
28977 OR A
28978 JR Z,PlayerBullets_SetNewPosition
The bullet has hit something so handle the collision.
PlayerBullets_Collision 28980 CALL Handler_BulletCollision Call Handler_BulletCollision.
28983 POP AF Restore the bullet state from the stack.
28984 LD DE,0 Set the bullet position to 0000 (inactive).
28987 JR PlayerBullets_NextBullet Jump to PlayerBullets_NextBullet.
PlayerBullets_SetNewPosition 28989 LD (HL),71 Mark the new position with the attribute INK:WHITE, PAPER:BLACK (BRIGHT).
28991 CALL ConvertAttributeToScreenBufferAddress Call ConvertAttributeToScreenBufferAddress.
28994 EX DE,HL Exchange the DE and HL registers.
28995 SET 2,D Set bit 2 of D.
28997 POP AF Restore the bullet state from the stack.
28998 PUSH DE Stash the new bullet position on the stack.
Draw the bullet graphic.
PlayerBullets_DrawNew 28999 LD B,4 Set a counter in B for 4 pixel lines.
PlayerBullets_DrawLoop 29001 LD (DE),A Write A to *DE.
29002 INC D Move down one pixel line in the screen buffer.
29003 DJNZ PlayerBullets_DrawLoop Decrease the line counter by one and loop back to PlayerBullets_DrawLoop until all 4 lines of the bullet have been drawn.
29005 POP DE Restore the original bullet position from the stack.
Housekeeping; move onto the next bullet.
PlayerBullets_NextBullet 29006 POP BC Restore the bullet counter and bullet data pointer from the stack.
29007 POP HL
29008 LD (HL),E Store the bullet position back to the data table.
29009 INC HL
29010 LD (HL),D
29011 INC HL
29012 DEC B Decrease the bullet counter by one.
29013 JP NZ,PlayerBullets_Loop Jump to PlayerBullets_Loop until all of the bullets have been processed.
29016 RET Return.
Prev: 28637 Up: Map Next: 29017