| Routines

26075: Move and draw the bullets

Used by the routine at 61568. For each bullet currently in flight, calculates the bullet's next location and draws it there (unless it has hit Sam).
26075 | LD HL,32743 | 32743 holds the bullet timer
26078 | DEC (HL) | Is it time to move and redraw the bullets?
26079 | RET NZ | Return if not
26080 | LD A,(32671) | Collect the MSB of Sam's cash supply
26083 | LD C,3 | Keep only bits 0 and 1 of the MSB
26085 | AND C
26086 | XOR C | A=6-A
26087 | ADD A,C
26088 | LD (HL),A | Reinitialise the bullet timer at 32743 to 3, 4, 5 or 6
26089 | LD L,192 | HL=32704 (first byte of bullet buffer 1)
The following loop checks each bullet to see whether it is in flight or has flown off the screen.
26091 | LD DE,(32766) | Collect the x- and y-coordinates of the top-left tile of the play area on screen in E and D
26095 | LD A,(HL) | A=x-coordinate of the leftmost column of the play area that was on screen the last time the bullet was drawn
26096 | LD (HL),E | Replace that x-coordinate with the current value
26097 | SUB E | A=bullet's current screen x-coordinate
26098 | INC HL
26099 | ADD A,(HL)
26100 | LD E,A | Copy this to E
26101 | LD (HL),A | Also store it in the bullet buffer
26102 | INC HL | Point HL at the third byte of the bullet buffer
26103 | CP 32 | Has the bullet flown off screen to the right?
26105 | JR NC,26111 | Jump if so
26107 | LD A,(HL) | A=bullet's current screen y-coordinate (or 0 if the bullet is not in flight)
26108 | AND A | Is the bullet in flight at the moment?
26109 | JR NZ,26120 | Jump if so
26111 | LD (HL),0 | Set the third byte of the bullet's buffer to 0, indicating that it is not in flight
26113 | INC L | Point HL at the last byte of the bullet buffer
26114 | INC L | Point HL at the first byte of the next bullet buffer
26115 | BIT 3,L | Have we dealt with both bullets yet?
26117 | JR Z,26091 | Jump back if not
26119 | RET |
This bullet is currently in flight.
26120 | LD A,D | A=y-coordinate of the topmost row of the play area on screen
26121 | CP 20 | Is the sidewalk on screen at the moment?
26123 | JR NZ,26111 | Terminate the bullet if not
26125 | LD D,(HL) | D=bullet's current screen y-coordinate
26126 | PUSH HL | Save the pointer to the bullet buffer
26127 | EX DE,HL | Transfer the bullet's screen x- and y-coordinates to L and H
26128 | CALL 59148 | Print the play area tile at these coordinates, thus erasing the bullet
26131 | POP HL | Restore the bullet buffer pointer to HL
26132 | INC HL | Point HL at the fourth byte of the bullet buffer
26133 | LD A,32 | Flip bit 5 of this byte
26135 | XOR (HL)
26136 | LD (HL),A
26137 | DEC HL | Point HL at the second byte of the bullet buffer (which holds the bullet's screen x-coordinate)
26138 | DEC HL
26139 | DEC (HL) | Decrement the bullet's screen x-coordinate
26140 | ADD A,A | Is the bullet flying leftwards?
26141 | JR NC,26145 | Jump if so
26143 | INC (HL) | Otherwise increment the bullet's x-coordinate
26144 | INC (HL)
26145 | LD E,(HL) | E=bullet's next screen x-coordinate
26146 | INC HL | Point HL at the third byte of the bullet buffer
26147 | BIT 5,E | Would the bullet now be off-screen to the left or right?
26149 | JR NZ,26111 | Terminate the bullet if so
26151 | ADD A,A | Is the bullet flying perfectly horizontally?
26152 | JR NC,26188 | Jump if so
The bullet is flying at an angle towards the ground or the sky.
26154 | ADD A,A | Push what was bit 5 of the fourth byte of the bullet buffer into the carry flag (and ignore it)
26155 | NOP |
26156 | NOP |
26157 | ADD A,A | Set the carry flag if the bullet is flying towards the sky
26158 | INC HL | Point HL at the fourth byte of the bullet buffer
26159 | JR C,26178 | Jump if the bullet is flying towards the sky
The bullet is flying at an angle towards the ground.
26161 | RES 3,(HL) | Reset bit 3 to prevent overflow (which would affect bits 4-7)
26163 | INC (HL) | Increment the pixel row counter in bits 0-2
26164 | LD A,(HL) | Pick up the fourth byte of the bullet buffer
26165 | AND 7 | Keep only bits 0-2 (the pixel row counter)
26167 | DEC HL | Point HL at the third byte of the bullet buffer
26168 | JR NZ,26188 | Jump unless the pixel row counter rolled over from 7 to 0
26170 | INC (HL) | Increment the bullet's screen y-coordinate
26171 | LD A,(HL) | A=bullet's next screen y-coordinate
26172 | CP 20 | Has the bullet flown off the bottom of the screen?
26174 | JR Z,26111 | Terminate it if so
26176 | JR 26188 |
The bullet is flying at an angle towards the sky.
26178 | SET 3,(HL) | Set bit 3 to prevent underflow (which would affect bits 4-7)
26180 | LD A,(HL) | Pick up the fourth byte of the bullet buffer
26181 | DEC (HL) | Decrement the pixel row counter in bits 0-2
26182 | AND 7 | A=previous value of the pixel row counter (0-7)
26184 | DEC HL | Point HL at the third byte of the bullet buffer
26185 | JR NZ,26188 | Jump unless the pixel row counter rolled over from 0 to 7
26187 | DEC (HL) | Decrement the bullet's screen y-coordinate
26188 | LD D,(HL) | D=bullet's next screen y-coordinate
Having calculated where the bullet is going next, we check whether it would hit Sam.
26189 | CALL 26002 | Would the bullet hit Sam?
26192 | JR C,26111 | Terminate the bullet if so
The bullet has not flown off the screen or hit Sam, so now we draw it.
26194 | LD A,D | A=bullet's next screen y-coordinate
26195 | AND 7 | Point DE at the top pixel row of the screen cell in which the bullet will be drawn
26197 | RRCA
26198 | RRCA
26199 | RRCA
26200 | ADD A,E
26201 | LD E,A
26202 | LD A,D
26203 | AND 24
26205 | ADD A,64
26207 | LD D,A
26208 | INC HL | Point HL at the fourth byte of the bullet buffer
26209 | LD A,(HL) | Point DE at the exact pixel row of the screen cell in which the bullet will be drawn
26210 | AND 7
26212 | ADD A,D
26213 | LD D,A
26214 | LD A,(DE) | Pick up the current pixel row from the display file
26215 | OR 60 | Set bits 2-5
26217 | AND 189 | Reset bits 6 and 1
26219 | LD (DE),A | Draw the bullet
26220 | JR 26114 | Jump back to deal with the next bullet