![]() |
Routines |
| Prev: 69A7 | Up: Map | Next: 6AF6 |
|
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 00 terminators for each room.
|
||||
| Handler_RedBird | 69F7 | LD A,($5FBB) | Jump to HandleRedBird_Update if *RespawnFlag is not set. | |
| 69FA | OR A | |||
| 69FB | JR Z,HandleRedBird_Update | |||
|
Initialise the red bird for the current room. Scan through the flight path data at Table_RedBirdFlightPath_01, skipping past 00 terminators until the entry for the current room is found.
|
||||
| 69FD | LD HL,$BE00 | Point HL at Table_RedBirdFlightPath_01. | ||
| 6A00 | LD A,($5FC5) | Load A and E with *CurrentRoom. | ||
| 6A03 | LD E,A | |||
| 6A04 | LD B,$01 | Set a room counter in B starting at 01. | ||
| 6A06 | CP B | Jump to HandleRedBird_InitPath if this is room 01 (data starts here). | ||
| 6A07 | JR Z,HandleRedBird_InitPath | |||
|
Scan through the flightpath data to find the current room.
|
||||
| HandleRedBird_ScanLoop | 6A09 | LD A,(HL) | A=*HL. | |
| 6A0A | INC HL | Advance the data pointer. | ||
| 6A0B | OR A | Jump back to HandleRedBird_ScanLoop if this byte isn't the terminator (00). | ||
| 6A0C | JP NZ,HandleRedBird_ScanLoop | |||
|
Found a 00 terminator so move to the data for the next room.
|
||||
| 6A0F | INC B | Increment the room counter. | ||
| 6A10 | LD A,E | Jump back to HandleRedBird_ScanLoop if this isn't at the target room yet. | ||
| 6A11 | CP B | |||
| 6A12 | JR NZ,HandleRedBird_ScanLoop | |||
|
Found the correct room's data so store the flight path pointer.
|
||||
| HandleRedBird_InitPath | 6A14 | LD ($6CBB),HL | Write HL to *Pointer_RedBirdFlightpathData (current flight path pointer). | |
|
Seed the random animation state from the Memory Refresh Register.
|
||||
| HandleRedBird_SetAnimationSeed | 6A17 | LD A,R | Write the contents of the Memory Refresh Register to *RedBirdAnimationSeed. | |
| 6A19 | LD ($6CB7),A | |||
|
Update the red bird's position and check for collisions.
|
||||
| HandleRedBird_Update | 6A1C | CALL UpdateRedBirdMovement | Call UpdateRedBirdMovement. | |
|
Check if the red bird has stolen Percy's worm.
|
||||
| 6A1F | LD A,($6CB4) | Jump to HandleRedBird_CheckEgg if *RedBirdStunTimer is set so the red bird is already stunned/ caught. | ||
| 6A22 | OR A | |||
| 6A23 | JR NZ,HandleRedBird_CheckEgg | |||
| 6A25 | LD A,($5FAA) | Jump to HandleRedBird_CheckEgg if *CarryingWormFlag is unset. | ||
| 6A28 | OR A | |||
| 6A29 | JR Z,HandleRedBird_CheckEgg | |||
|
Check collision between Percy and the red bird.
|
||||
| 6A2B | LD IX,$DAC0 | IX=Percy_X_Position (Percy's sprite data). | ||
| 6A2F | LD IY,$DAC4 | IY=Sprite01_3Wide_X_Position (red bird sprite data). | ||
| 6A33 | CALL CheckSpriteCollision | Call CheckSpriteCollision. | ||
| 6A36 | JR C,HandleRedBird_CheckEgg | Jump to HandleRedBird_CheckEgg if no collision. | ||
|
Check the red bird has a valid frame (is visible).
|
||||
| 6A38 | LD A,(IY+$03) | Jump to HandleRedBird_CheckEgg if *IY+03 is unset, so the red bird frame is 00 (i.e. not visible). | ||
| 6A3B | OR A | |||
| 6A3C | JR Z,HandleRedBird_CheckEgg | |||
|
Red bird stole Percy's worm so return the worm to the room and play a sound.
|
||||
| 6A3E | CALL DropWorm | Call DropWorm. | ||
| 6A41 | LD DE,$0003 | DE=0003. | ||
| 6A44 | LD HL,$00C8 | HL=00C8 (initial beep pitch). | ||
| 6A47 | LD B,$0A | Set a sound step counter in B of 0A steps. | ||
| HandleRedBird_StolenSound | 6A49 | PUSH BC | Stash the step counter, pitch and duration on the stack. | |
| 6A4A | PUSH HL | |||
| 6A4B | PUSH DE | |||
| 6A4C | LD IY,$5C3D | IY=ERR_SP. | ||
| 6A50 | CALL $03B5 | Call BEEP. | ||
| 6A53 | DI | Disable interrupts. | ||
| 6A54 | POP DE | Restore the duration and pitch from the stack. | ||
| 6A55 | POP HL | |||
| 6A56 | LD BC,$0012 | HL=0012 (raise the pitch for the next step). | ||
| 6A59 | ADD HL,BC | |||
| 6A5A | POP BC | Restore the step counter from the stack. | ||
| 6A5B | DJNZ HandleRedBird_StolenSound | Decrease the step counter by one and loop back to HandleRedBird_StolenSound until the sound is complete. | ||
| 6A5D | NOP | No operation. | ||
| 6A5E | NOP | |||
| 6A5F | NOP | |||
|
Check if Percy's egg has hit the red bird.
|
||||
| HandleRedBird_CheckEgg | 6A60 | LD A,($5FA9) | Jump to HandleRedBird_Done if *EggDropFlag is unset/ no egg is active. | |
| 6A63 | OR A | |||
| 6A64 | JR Z,HandleRedBird_Done | |||
| 6A66 | LD IY,$DAE0 | IY=Egg_X_Position. | ||
| 6A6A | LD IX,$DAC4 | IX=Sprite01_3Wide_X_Position. | ||
|
Only check collision if the red bird is in the same room as the egg.
|
||||
| 6A6E | LD A,($6CB6) | B=*RedBirdCurrentRoom. | ||
| 6A71 | LD B,A | |||
| 6A72 | LD A,($5FC5) | A=*CurrentRoom. | ||
| 6A75 | CP B | Jump to HandleRedBird_Done if the red bird is not in the current room. | ||
| 6A76 | JR NZ,HandleRedBird_Done | |||
|
The red bird is in the current room.
|
||||
| 6A78 | CALL CheckEggCollision | Call CheckEggCollision. | ||
| 6A7B | JR C,HandleRedBird_Done | Jump to HandleRedBird_Done if no collision. | ||
|
Egg hit the red bird so check if already stunned.
|
||||
| 6A7D | LD A,($6CB4) | Jump to HandleRedBird_CancelEgg if *RedBirdStunTimer is set so the red bird is already stunned. | ||
| 6A80 | OR A | |||
| 6A81 | JR NZ,HandleRedBird_CancelEgg | |||
|
Stun the red bird so set a random stun timer and award points.
|
||||
| 6A83 | CALL GenerateRandomNumber | Call GenerateRandomNumber. | ||
| 6A86 | OR %01000000 | Set bit 6 (ensure a minimum stun duration). | ||
| 6A88 | LD ($6CB4),A | Write A to *RedBirdStunTimer. | ||
| 6A8B | LD ($6CB5),A | Write A to *RedBirdStunTimerCopy. | ||
| 6A8E | LD (IX+$02),$01 | Write 01 to *IX+02 (stunned colour: BLUE). | ||
| 6A92 | LD A,$14 | Call AddToScore to add 14 points to the score. | ||
| 6A94 | CALL AddToScore | |||
| 6A97 | CALL PlayHitSound | Call PlayHitSound. | ||
|
Cancel the egg.
|
||||
| HandleRedBird_CancelEgg | 6A9A | CALL CancelEggDrop | Call CancelEggDrop. | |
| HandleRedBird_Done | 6A9D | CALL Handle_Butterfly | Call Handle_Butterfly. | |
| 6AA0 | 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 | 6AA1 | LD A,($5FC5) | B=*CurrentRoom. | |
| 6AA4 | LD B,A | |||
| 6AA5 | LD A,($6CB6) | A=*RedBirdCurrentRoom. | ||
|
Check if the combined value wraps past room 0B.
|
||||
| 6AA8 | ADD A,B | A+=B. | ||
| 6AA9 | CP $0C | Jump to HandleRedBird_LookupSpeed if the combined value doesn't wrap past room 0B. | ||
| 6AAB | JR NZ,HandleRedBird_LookupSpeed | |||
|
Wrap point reached so flip the red bird's flight direction.
|
||||
| 6AAD | LD A,($6CB3) | A=*RedBirdTraversalDirection. | ||
| 6AB0 | XOR %00000001 | Toggle bit 0 (flip direction). | ||
| 6AB2 | LD ($6CB3),A | Write A to *RedBirdTraversalDirection. | ||
|
Look up the flight speed for the current level from the table at RedBirdSpeedTable.
|
||||
| HandleRedBird_LookupSpeed | 6AB5 | LD HL,$6CBE | HL=RedBirdSpeedTable. | |
| 6AB8 | LD A,($5FB1) | A=*CurrentLevel. | ||
| 6ABB | DEC A | Decrement to make zero-indexed. | ||
| 6ABC | LD E,A | E=A. | ||
| 6ABD | LD D,$00 | D=00. | ||
| 6ABF | ADD HL,DE | HL+=DE. | ||
| 6AC0 | LD A,(HL) | A=*HL (flight speed for this level). | ||
| 6AC1 | LD ($6CB9),A | Write A to *RedBirdFlightSpeed. | ||
|
Set up the starting position based on the flight direction.
|
||||
| 6AC4 | LD A,($6CB3) | A=*RedBirdTraversalDirection. | ||
| 6AC7 | LD C,$E6 | C=E6 (starting X for rightward flight). | ||
| 6AC9 | LD B,$06 | B=06 (starting Y). | ||
| 6ACB | OR A | Jump to HandleRedBird_FindPosition if flying right (direction is non-zero). | ||
| 6ACC | JR NZ,HandleRedBird_FindPosition | |||
| 6ACE | LD C,$06 | C=06 (starting X for leftward flight). | ||
|
Search for a valid Y position that doesn't collide with scenery.
|
||||
| HandleRedBird_FindPosition | 6AD0 | CALL Validate_Position | Call Validate_Position. | |
| 6AD3 | RET NC | Return if no collision (valid position found). | ||
|
Position blocked so try the next row down.
|
||||
| 6AD4 | INC B | Increment B by 04. | ||
| 6AD5 | INC B | |||
| 6AD6 | INC B | |||
| 6AD7 | INC B | |||
| 6AD8 | LD A,B | A=B. | ||
| 6AD9 | CP $50 | Jump back to HandleRedBird_FindPosition until the bottom of search area is reached. | ||
| 6ADB | JR C,HandleRedBird_FindPosition | |||
|
Reached the bottom so wrap back to the top and shift X inward.
|
||||
| 6ADD | LD B,$04 | B=04 (reset Y to the top). | ||
| 6ADF | LD A,($6CB3) | A=*RedBirdTraversalDirection (flight direction). | ||
| 6AE2 | OR A | Jump to HandleRedBird_ShiftLeft if flying right. | ||
| 6AE3 | JR NZ,HandleRedBird_ShiftLeft | |||
|
Flying left so shift the starting X position rightward.
|
||||
| 6AE5 | INC C | Increment C by 06. | ||
| 6AE6 | INC C | |||
| 6AE7 | INC C | |||
| 6AE8 | INC C | |||
| 6AE9 | INC C | |||
| 6AEA | INC C | |||
| 6AEB | JR HandleRedBird_FindPosition | Jump to HandleRedBird_FindPosition to try again. | ||
|
Flying right so shift the starting X position leftward.
|
||||
| HandleRedBird_ShiftLeft | 6AED | DEC C | Decrement C by 06. | |
| 6AEE | DEC C | |||
| 6AEF | DEC C | |||
| 6AF0 | DEC C | |||
| 6AF1 | DEC C | |||
| 6AF2 | DEC C | |||
| 6AF3 | JR HandleRedBird_FindPosition | Jump to HandleRedBird_FindPosition to try again. | ||
| 6AF5 | RET | Return. | ||
| Prev: 69A7 | Up: Map | Next: 6AF6 |