![]() |
Routines |
| Prev: 27047 | Up: Map | Next: 27382 |
|
Used by the routine at Run_Main_Loop_Body.
Handles the red bird who is a thief that steals worms Percy is carrying.
Percy can stun the red bird by hitting it with an egg. The red bird's flight path data is stored at Table_RedBirdFlightPath_01 with entries separated by 0 terminators for each room.
|
||||
| Handler_RedBird | 27127 | LD A,(24507) | Jump to HandleRedBird_Update if *RespawnFlag is not set. | |
| 27130 | OR A | |||
| 27131 | JR Z,HandleRedBird_Update | |||
|
Initialise the red bird for the current room. Scan through the flight path data at Table_RedBirdFlightPath_01, skipping past 0 terminators until the entry for the current room is found.
|
||||
| 27133 | LD HL,48640 | Point HL at Table_RedBirdFlightPath_01. | ||
| 27136 | LD A,(24517) | Load A and E with *CurrentRoom. | ||
| 27139 | LD E,A | |||
| 27140 | LD B,1 | Set a room counter in B starting at 1. | ||
| 27142 | CP B | Jump to HandleRedBird_InitPath if this is room 1 (data starts here). | ||
| 27143 | JR Z,HandleRedBird_InitPath | |||
|
Scan through the flightpath data to find the current room.
|
||||
| HandleRedBird_ScanLoop | 27145 | LD A,(HL) | A=*HL. | |
| 27146 | INC HL | Advance the data pointer. | ||
| 27147 | OR A | Jump back to HandleRedBird_ScanLoop if this byte isn't the terminator (0). | ||
| 27148 | JP NZ,HandleRedBird_ScanLoop | |||
|
Found a 0 terminator so move to the data for the next room.
|
||||
| 27151 | INC B | Increment the room counter. | ||
| 27152 | LD A,E | Jump back to HandleRedBird_ScanLoop if this isn't at the target room yet. | ||
| 27153 | CP B | |||
| 27154 | JR NZ,HandleRedBird_ScanLoop | |||
|
Found the correct room's data so store the flight path pointer.
|
||||
| HandleRedBird_InitPath | 27156 | LD (27835),HL | Write HL to *Pointer_RedBirdFlightpathData (current flight path pointer). | |
|
Seed the random animation state from the Memory Refresh Register.
|
||||
| HandleRedBird_SetAnimationSeed | 27159 | LD A,R | Write the contents of the Memory Refresh Register to *RedBirdAnimationSeed. | |
| 27161 | LD (27831),A | |||
|
Update the red bird's position and check for collisions.
|
||||
| HandleRedBird_Update | 27164 | CALL UpdateRedBirdMovement | Call UpdateRedBirdMovement. | |
|
Check if the red bird has stolen Percy's worm.
|
||||
| 27167 | LD A,(27828) | Jump to HandleRedBird_CheckEgg if *RedBirdStunTimer is set so the red bird is already stunned/ caught. | ||
| 27170 | OR A | |||
| 27171 | JR NZ,HandleRedBird_CheckEgg | |||
| 27173 | LD A,(24490) | Jump to HandleRedBird_CheckEgg if *CarryingWormFlag is unset. | ||
| 27176 | OR A | |||
| 27177 | JR Z,HandleRedBird_CheckEgg | |||
|
Check collision between Percy and the red bird.
|
||||
| 27179 | LD IX,56000 | IX=Percy_X_Position (Percy's sprite data). | ||
| 27183 | LD IY,56004 | IY=Sprite01_3Wide_X_Position (red bird sprite data). | ||
| 27187 | CALL CheckSpriteCollision | Call CheckSpriteCollision. | ||
| 27190 | JR C,HandleRedBird_CheckEgg | Jump to HandleRedBird_CheckEgg if no collision. | ||
|
Check the red bird has a valid frame (is visible).
|
||||
| 27192 | LD A,(IY+3) | Jump to HandleRedBird_CheckEgg if *IY+3 is unset, so the red bird frame is 0 (i.e. not visible). | ||
| 27195 | OR A | |||
| 27196 | JR Z,HandleRedBird_CheckEgg | |||
|
Red bird stole Percy's worm so return the worm to the room and play a sound.
|
||||
| 27198 | CALL DropWorm | Call DropWorm. | ||
| 27201 | LD DE,3 | DE=0003. | ||
| 27204 | LD HL,200 | HL=0200 (initial beep pitch). | ||
| 27207 | LD B,10 | Set a sound step counter in B of 10 steps. | ||
| HandleRedBird_StolenSound | 27209 | PUSH BC | Stash the step counter, pitch and duration on the stack. | |
| 27210 | PUSH HL | |||
| 27211 | PUSH DE | |||
| 27212 | LD IY,23613 | IY=ERR_SP. | ||
| 27216 | CALL 949 | Call BEEP. | ||
| 27219 | DI | Disable interrupts. | ||
| 27220 | POP DE | Restore the duration and pitch from the stack. | ||
| 27221 | POP HL | |||
| 27222 | LD BC,18 | HL=0018 (raise the pitch for the next step). | ||
| 27225 | ADD HL,BC | |||
| 27226 | POP BC | Restore the step counter from the stack. | ||
| 27227 | DJNZ HandleRedBird_StolenSound | Decrease the step counter by one and loop back to HandleRedBird_StolenSound until the sound is complete. | ||
| 27229 | NOP | No operation. | ||
| 27230 | NOP | |||
| 27231 | NOP | |||
|
Check if Percy's egg has hit the red bird.
|
||||
| HandleRedBird_CheckEgg | 27232 | LD A,(24489) | Jump to HandleRedBird_Done if *EggDropFlag is unset/ no egg is active. | |
| 27235 | OR A | |||
| 27236 | JR Z,HandleRedBird_Done | |||
| 27238 | LD IY,56032 | IY=Egg_X_Position. | ||
| 27242 | LD IX,56004 | IX=Sprite01_3Wide_X_Position. | ||
|
Only check collision if the red bird is in the same room as the egg.
|
||||
| 27246 | LD A,(27830) | B=*RedBirdCurrentRoom. | ||
| 27249 | LD B,A | |||
| 27250 | LD A,(24517) | A=*CurrentRoom. | ||
| 27253 | CP B | Jump to HandleRedBird_Done if the red bird is not in the current room. | ||
| 27254 | JR NZ,HandleRedBird_Done | |||
|
The red bird is in the current room.
|
||||
| 27256 | CALL CheckEggCollision | Call CheckEggCollision. | ||
| 27259 | JR C,HandleRedBird_Done | Jump to HandleRedBird_Done if no collision. | ||
|
Egg hit the red bird so check if already stunned.
|
||||
| 27261 | LD A,(27828) | Jump to HandleRedBird_CancelEgg if *RedBirdStunTimer is set so the red bird is already stunned. | ||
| 27264 | OR A | |||
| 27265 | JR NZ,HandleRedBird_CancelEgg | |||
|
Stun the red bird so set a random stun timer and award points.
|
||||
| 27267 | CALL GenerateRandomNumber | Call GenerateRandomNumber. | ||
| 27270 | OR %01000000 | Set bit 6 (ensure a minimum stun duration). | ||
| 27272 | LD (27828),A | Write A to *RedBirdStunTimer. | ||
| 27275 | LD (27829),A | Write A to *RedBirdStunTimerCopy. | ||
| 27278 | LD (IX+2),1 | Write 1 to *IX+2 (stunned colour: BLUE). | ||
| 27282 | LD A,20 | Call AddToScore to add 20 points to the score. | ||
| 27284 | CALL AddToScore | |||
| 27287 | CALL PlayHitSound | Call PlayHitSound. | ||
|
Cancel the egg.
|
||||
| HandleRedBird_CancelEgg | 27290 | CALL CancelEggDrop | Call CancelEggDrop. | |
| HandleRedBird_Done | 27293 | CALL Handle_Butterfly | Call Handle_Butterfly. | |
| 27296 | RET | Return. | ||
|
This entry point is used by the routine at UpdateRedBirdMovement.
Calculates the red bird's next room and flight direction when it crosses a room boundary. Also looks up the flight speed for the current level and finds a valid starting position.
|
||||
| HandleRedBird_SetupFlight | 27297 | LD A,(24517) | B=*CurrentRoom. | |
| 27300 | LD B,A | |||
| 27301 | LD A,(27830) | A=*RedBirdCurrentRoom. | ||
|
Check if the combined value wraps past room 11.
|
||||
| 27304 | ADD A,B | A+=B. | ||
| 27305 | CP 12 | Jump to HandleRedBird_LookupSpeed if the combined value doesn't wrap past room 11. | ||
| 27307 | JR NZ,HandleRedBird_LookupSpeed | |||
|
Wrap point reached so flip the red bird's flight direction.
|
||||
| 27309 | LD A,(27827) | A=*RedBirdTraversalDirection. | ||
| 27312 | XOR %00000001 | Toggle bit 0 (flip direction). | ||
| 27314 | LD (27827),A | Write A to *RedBirdTraversalDirection. | ||
|
Look up the flight speed for the current level from the table at RedBirdSpeedTable.
|
||||
| HandleRedBird_LookupSpeed | 27317 | LD HL,27838 | HL=RedBirdSpeedTable. | |
| 27320 | LD A,(24497) | A=*CurrentLevel. | ||
| 27323 | DEC A | Decrement to make zero-indexed. | ||
| 27324 | LD E,A | E=A. | ||
| 27325 | LD D,0 | D=0. | ||
| 27327 | ADD HL,DE | HL+=DE. | ||
| 27328 | LD A,(HL) | A=*HL (flight speed for this level). | ||
| 27329 | LD (27833),A | Write A to *RedBirdFlightSpeed. | ||
|
Set up the starting position based on the flight direction.
|
||||
| 27332 | LD A,(27827) | A=*RedBirdTraversalDirection. | ||
| 27335 | LD C,230 | C=230 (starting X for rightward flight). | ||
| 27337 | LD B,6 | B=6 (starting Y). | ||
| 27339 | OR A | Jump to HandleRedBird_FindPosition if flying right (direction is non-zero). | ||
| 27340 | JR NZ,HandleRedBird_FindPosition | |||
| 27342 | LD C,6 | C=6 (starting X for leftward flight). | ||
|
Search for a valid Y position that doesn't collide with scenery.
|
||||
| HandleRedBird_FindPosition | 27344 | CALL Validate_Position | Call Validate_Position. | |
| 27347 | RET NC | Return if no collision (valid position found). | ||
|
Position blocked so try the next row down.
|
||||
| 27348 | INC B | Increment B by 4. | ||
| 27349 | INC B | |||
| 27350 | INC B | |||
| 27351 | INC B | |||
| 27352 | LD A,B | A=B. | ||
| 27353 | CP 80 | Jump back to HandleRedBird_FindPosition until the bottom of search area is reached. | ||
| 27355 | JR C,HandleRedBird_FindPosition | |||
|
Reached the bottom so wrap back to the top and shift X inward.
|
||||
| 27357 | LD B,4 | B=4 (reset Y to the top). | ||
| 27359 | LD A,(27827) | A=*RedBirdTraversalDirection (flight direction). | ||
| 27362 | OR A | Jump to HandleRedBird_ShiftLeft if flying right. | ||
| 27363 | JR NZ,HandleRedBird_ShiftLeft | |||
|
Flying left so shift the starting X position rightward.
|
||||
| 27365 | INC C | Increment C by 6. | ||
| 27366 | INC C | |||
| 27367 | INC C | |||
| 27368 | INC C | |||
| 27369 | INC C | |||
| 27370 | INC C | |||
| 27371 | JR HandleRedBird_FindPosition | Jump to HandleRedBird_FindPosition to try again. | ||
|
Flying right so shift the starting X position leftward.
|
||||
| HandleRedBird_ShiftLeft | 27373 | DEC C | Decrement C by 6. | |
| 27374 | DEC C | |||
| 27375 | DEC C | |||
| 27376 | DEC C | |||
| 27377 | DEC C | |||
| 27378 | DEC C | |||
| 27379 | JR HandleRedBird_FindPosition | Jump to HandleRedBird_FindPosition to try again. | ||
| 27381 | RET | Return. | ||
| Prev: 27047 | Up: Map | Next: 27382 |