Prev: C11D Up: Map Next: C1BD
C126: Fire Projectile
Used by the routine at HandlePlayerLegs.
Fires a projectile in the direction that the player is facing, if the fire key is pressed and it was not already being held down from before. There are two object records that are used for projectiles, so nothing is done if both are in use.
The projectile is a copy of the player that is changed into a projectile and moved on by twice its speed along the way that the player is facing. It is thrown away at once if it starts outside the room.
Input
IX Record of the object of the legs of the player
FireProjectile C126 LD HL,$A7AF Start at the first of the two projectile object records, ObjectsTable_Projectiles.
C129 LD A,($A737) Fetch the controls from ControlsPressed.
C12C AND %01000000 Keep only the fire bit.
C12E JR NZ,FireProjectile_Pressed Jump to FireProjectile_Pressed if the fire key is being pressed.
C130 XOR A Clear the flag in FireKeyHeldFlag, to say that the key has been released.
C131 LD ($A743),A
C134 RET Return.
FireProjectile_Pressed C135 LD A,($A743) Fetch the flag from FireKeyHeldFlag.
C138 AND A Return if the key was already being held down.
C139 RET NZ
C13A INC A Set the flag in FireKeyHeldFlag, to say that the key is being held down.
C13B LD ($A743),A
C13E LD BC,$0020 Set the size of an object record in BC.
C141 LD A,(HL) Jump to FireProjectile_Create if the first record is free.
C142 AND A
C143 JR Z,FireProjectile_Create
C145 ADD HL,BC Move on to the second record.
C146 LD A,(HL) Return if that is not free either.
C147 AND A
C148 RET NZ
Copy the player to the free record, then change the copy into a projectile.
FireProjectile_Create C149 EX DE,HL Move the address of the free record to DE.
C14A PUSH DE Take the free record, using the stack.
C14B POP IY
C14D PUSH IX Take the player, using the stack.
C14F POP HL
C150 LDIR Copy the player to the projectile.
C152 LD (IY+$00),$96 Set the type of the projectile to 96, which is the first of its sprites.
C156 CALL GetFacingDirection Call GetFacingDirection to find out which way the player is facing.
C159 LD L,A Set HL to the number of the direction.
C15A LD H,$00
C15C LD DE,$C1BD Take the table of speeds of projectiles, ProjectileSpeeds.
C15F ADD HL,HL Find the entry for the direction, which is two bytes for each direction.
C160 ADD HL,DE
C161 LD A,(HL) Fetch the speed along x, and set it as the x speed of the projectile.
C162 LD (IY+$14),A
C165 ADD A,A Double it, and stash it in E.
C166 LD E,A
C167 INC HL Move on to the speed along y.
C168 LD A,(HL) Fetch the speed along y, and set it as the y speed of the projectile.
C169 LD (IY+$15),A
C16C ADD A,A Double it.
C16D ADD A,(IY+$02) Add it to the y position of the projectile.
C170 LD (IY+$02),A
C173 LD A,E Add the doubled speed along x to the x position of the projectile.
C174 ADD A,(IY+$01)
C177 LD (IY+$01),A
C17A LD A,(IY+$03) Raise the projectile by 04.
C17D ADD A,$04
C17F LD (IY+$03),A
C182 LD (IY+$07),$14 Set the flags of the projectile, which make it pushable and mark it to be drawn.
C186 LD (IY+$0C),$00 Clear the collision flags of the projectile.
C18A LD (IY+$06),$08 Set the size of the projectile along z to 08.
Make sure that the projectile is inside the room.
C18E LD HL,($A71D) Fetch the limits of the room from RoomSizeX.
C191 LD A,L Take away the half size along x from the limit along x.
C192 SUB (IY+$04)
C195 LD L,A
C196 LD A,H Take away the half size along y from the limit along y.
C197 SUB (IY+$05)
C19A LD H,A
C19B LD A,(IY+$01) Fetch the x position of the projectile.
C19E SUB $80 Take away the middle of the room, 80, and jump to FireProjectile_TestX if the distance from the middle is not negative.
C1A0 JP P,FireProjectile_TestX
C1A3 NEG Make the distance positive.
FireProjectile_TestX C1A5 CP L Jump to FireProjectile_Cancel to give up if the distance is not less than the limit along x.
C1A6 JR NC,FireProjectile_Cancel
C1A8 LD A,(IY+$02) Fetch the y position of the projectile.
C1AB SUB $80 Take away the middle of the room, 80, and jump to FireProjectile_TestY if the distance from the middle is not negative.
C1AD JP P,FireProjectile_TestY
C1B0 NEG Make the distance positive.
FireProjectile_TestY C1B2 CP H Jump to FireProjectile_Cancel to give up if the distance is not less than the limit along y.
C1B3 JR NC,FireProjectile_Cancel
C1B5 JP PlayProjectileSound Jump to PlayProjectileSound.
FireProjectile_Cancel C1B8 LD (IY+$00),$00 Free the record, as the projectile would be outside the room.
C1BC RET Return.
Prev: C11D Up: Map Next: C1BD