![]() |
Routines |
| Prev: 5FE7 | Up: Map | Next: 6280 |
|
Used by the routine at Game_Initialise.
Main game loop handler. Reads player input (either from Kempston joystick or keyboard), moves Percy, checks for collisions with the room scenery, handles room transitions, item collection and updates Percy's animation frame.
|
||||||||||||||||||||||
| MainGameLoop | 5FE9 | LD A,($5FA7) | If *FallingState is unset, call Initialise_Lives. | |||||||||||||||||||
| 5FEC | OR A | |||||||||||||||||||||
| 5FED | CALL Z,UpdateEnergyBar | |||||||||||||||||||||
|
Seed the chick animation states and introduce a short random delay using the Memory Refresh Register.
|
||||||||||||||||||||||
| 5FF0 | LD A,R | L=the contents of the Memory Refresh Register. | ||||||||||||||||||||
| 5FF2 | LD L,A | |||||||||||||||||||||
| 5FF3 | LD H,$00 | Set the low byte in H to 00 so only low memory is accessed. | ||||||||||||||||||||
| 5FF5 | LD A,(HL) | Fetch a byte from low memory and write it to *ChickAnimationStates. | ||||||||||||||||||||
| 5FF6 | LD ($5FB4),A | |||||||||||||||||||||
| 5FF9 | AND %00000111 | Keep only bits 0-2. | ||||||||||||||||||||
| 5FFB | LD B,A | Set the same byte value as a delay counter in B. | ||||||||||||||||||||
| MainGameLoop_RandomDelay | 5FFC | NOP | No operation. | |||||||||||||||||||
| 5FFD | DJNZ MainGameLoop_RandomDelay | Decrease the delay counter by one and loop back to MainGameLoop_RandomDelay until done. | ||||||||||||||||||||
|
Read the Kempston joystick port to check for input.
|
||||||||||||||||||||||
| MainGameLoop_ReadInput | 5FFF | LD BC,$EFFE | BC=EFFE. | |||||||||||||||||||
| 6002 | LD IX,$DAC0 | IX=Percy_X_Position. | ||||||||||||||||||||
| 6006 | LD A,$1F | Write 1F to *InputState (default: no direction pressed). | ||||||||||||||||||||
| 6008 | LD ($5FA2),A | |||||||||||||||||||||
| 600B | IN A,(C) | Read from the Kempston joystick port. | ||||||||||||||||||||
| 600D | AND %00011111 | Keep only bits 0-4. | ||||||||||||||||||||
| 600F | CP $1F | Jump to MainGameLoop_JoystickInput if any joystick direction was detected. | ||||||||||||||||||||
| 6011 | JR NZ,MainGameLoop_JoystickInput | |||||||||||||||||||||
| 6013 | JR MainGameLoop_CheckInputMode | Jump to MainGameLoop_CheckInputMode. | ||||||||||||||||||||
| MainGameLoop_JoystickInput | 6015 | LD ($5FA2),A | Write A to *InputState. | |||||||||||||||||||
| 6018 | JP MainGameLoop_HandleEggDrop | Jump to MainGameLoop_HandleEggDrop. | ||||||||||||||||||||
|
Check whether to read from Kempston joystick or keyboard. Bit 7 of *InputMode indicates keyboard mode.
|
||||||||||||||||||||||
| MainGameLoop_CheckInputMode | 601B | LD A,($5FA6) | A=*InputMode. | |||||||||||||||||||
| 601E | BIT 7,A | Jump to MainGameLoop_ReadKeyboard if keyboard mode is active (bit 7 is set). | ||||||||||||||||||||
| 6020 | JR NZ,MainGameLoop_ReadKeyboard | |||||||||||||||||||||
| 6022 | LD BC,$001F | BC=001F. | ||||||||||||||||||||
| 6025 | OR A | Jump to MainGameLoop_ReadJoystick if A is non-zero. | ||||||||||||||||||||
| 6026 | JR NZ,MainGameLoop_ReadJoystick | |||||||||||||||||||||
|
Auto-detect input method. Poll the joystick port repeatedly and if any input is detected, switch to joystick mode; otherwise switch to keyboard.
|
||||||||||||||||||||||
| 6028 | LD E,$F0 | E=F0 (poll retry counter). | ||||||||||||||||||||
| MainGameLoop_AutoDetect_Loop | 602A | IN A,(C) | Read from the joystick port. | |||||||||||||||||||
| 602C | AND %00011111 | Keep only bits 0-4. | ||||||||||||||||||||
| 602E | CP $1F | Jump to MainGameLoop_SetKeyboardMode if no joystick was input detected. | ||||||||||||||||||||
| 6030 | JR Z,MainGameLoop_SetKeyboardMode | |||||||||||||||||||||
| 6032 | DEC E | Decrease the retry counter. | ||||||||||||||||||||
| 6033 | JR NZ,MainGameLoop_AutoDetect_Loop | Jump to MainGameLoop_AutoDetect_Loop until all the retries have been used. | ||||||||||||||||||||
|
Joystick input was detected so set joystick mode.
|
||||||||||||||||||||||
| 6035 | LD A,$1F | Write 1F to *InputMode (joystick mode). | ||||||||||||||||||||
| 6037 | LD ($5FA6),A | |||||||||||||||||||||
| 603A | JR MainGameLoop_ReadJoystick | Jump to MainGameLoop_ReadJoystick. | ||||||||||||||||||||
|
No joystick was detected so set keyboard mode.
|
||||||||||||||||||||||
| MainGameLoop_SetKeyboardMode | 603C | LD A,$80 | Write 80 to *InputMode (keyboard mode). | |||||||||||||||||||
| 603E | LD ($5FA6),A | |||||||||||||||||||||
| 6041 | JR MainGameLoop_ReadKeyboard | Jump to MainGameLoop_ReadKeyboard. | ||||||||||||||||||||
|
Read the Kempston joystick and remap the direction bits into the game's internal input format stored in *InputState.
|
||||||||||||||||||||||
| MainGameLoop_ReadJoystick | 6043 | IN A,(C) | Read from the joystick port. | |||||||||||||||||||
| 6045 | LD E,$1F | E=1F (all directions inactive). | ||||||||||||||||||||
| MainGameLoop_Joystick_TestFire | 6047 | BIT 4,A | Jump to MainGameLoop_Joystick_TestRight if fire is not being pressed. | |||||||||||||||||||
| 6049 | JR Z,MainGameLoop_Joystick_TestRight | |||||||||||||||||||||
| 604B | RES 0,E | Reset bit 0 of E (fire active). | ||||||||||||||||||||
| MainGameLoop_Joystick_TestRight | 604D | BIT 0,A | Jump to MainGameLoop_Joystick_TestLeft if right is not being pressed. | |||||||||||||||||||
| 604F | JR Z,MainGameLoop_Joystick_TestLeft | |||||||||||||||||||||
| 6051 | RES 3,E | Reset bit 3 of E (right active). | ||||||||||||||||||||
| MainGameLoop_Joystick_TestLeft | 6053 | BIT 1,A | Jump to MainGameLoop_Joystick_TestDown if left is not being pressed. | |||||||||||||||||||
| 6055 | JR Z,MainGameLoop_Joystick_TestDown | |||||||||||||||||||||
| 6057 | RES 4,E | Reset bit 4 of E (left active). | ||||||||||||||||||||
| MainGameLoop_Joystick_TestDown | 6059 | BIT 2,A | Jump to MainGameLoop_Joystick_TestUp if down is not being pressed. | |||||||||||||||||||
| 605B | JR Z,MainGameLoop_Joystick_TestUp | |||||||||||||||||||||
| 605D | RES 2,E | Reset bit 2 of E (down active). | ||||||||||||||||||||
| MainGameLoop_Joystick_TestUp | 605F | BIT 3,A | Jump to MainGameLoop_Joystick_Store if up is not being pressed. | |||||||||||||||||||
| 6061 | JR Z,MainGameLoop_Joystick_Store | |||||||||||||||||||||
| 6063 | RES 1,E | Reset bit 1 of E (up active). | ||||||||||||||||||||
| MainGameLoop_Joystick_Store | 6065 | LD A,E | Write E to *InputState. | |||||||||||||||||||
| 6066 | LD ($5FA2),A | |||||||||||||||||||||
| 6069 | JR MainGameLoop_HandleEggDrop | Jump to MainGameLoop_HandleEggDrop. | ||||||||||||||||||||
|
Read keyboard input. Scans multiple keyboard half-rows and maps them into the same internal input format.
|
||||||||||||||||||||||
| MainGameLoop_ReadKeyboard | 606B | LD BC,$7FFE | BC=7FFE. | |||||||||||||||||||
| 606E | LD E,$1F | E=1F (all directions inactive). | ||||||||||||||||||||
|
Read SPACE-B row for fire.
|
||||||||||||||||||||||
| 6070 | IN A,(C) | Read from the keyboard port. | ||||||||||||||||||||
| 6072 | AND %00011111 | Keep only bits 0-4. | ||||||||||||||||||||
| 6074 | CP $1F | Jump to MainGameLoop_Keyboard_TestDown if no key was being pressed. | ||||||||||||||||||||
| 6076 | JR Z,MainGameLoop_Keyboard_TestDown | |||||||||||||||||||||
| 6078 | RES 0,E | Reset bit 0 of E (fire active). | ||||||||||||||||||||
|
Read ENTER-H row for down.
|
||||||||||||||||||||||
| MainGameLoop_Keyboard_TestDown | 607A | LD B,$BF | B=BF. | |||||||||||||||||||
| 607C | IN A,(C) | Read from the keyboard port. | ||||||||||||||||||||
| 607E | AND %00011111 | Jump to MainGameLoop_Keyboard_TestUp if no key was being pressed. | ||||||||||||||||||||
| 6080 | CP $1F | |||||||||||||||||||||
| 6082 | JR Z,MainGameLoop_Keyboard_TestUp | |||||||||||||||||||||
| 6084 | RES 2,E | Reset bit 2 of E (down active). | ||||||||||||||||||||
|
Read P-Y row for up.
|
||||||||||||||||||||||
| MainGameLoop_Keyboard_TestUp | 6086 | LD B,$DF | B=DF. | |||||||||||||||||||
| 6088 | IN A,(C) | Read from the keyboard port. | ||||||||||||||||||||
| 608A | AND %00011111 | Jump to MainGameLoop_Keyboard_TestLeftRight if no key was being pressed. | ||||||||||||||||||||
| 608C | CP $1F | |||||||||||||||||||||
| 608E | JR Z,MainGameLoop_Keyboard_TestLeftRight | |||||||||||||||||||||
| 6090 | RES 1,E | Reset bit 1 of E (up active). | ||||||||||||||||||||
|
Read Q-T row for left (Q, bit 0) and right (W, bit 1).
|
||||||||||||||||||||||
| MainGameLoop_Keyboard_TestLeftRight | 6092 | LD B,$FB | B=FB. | |||||||||||||||||||
| 6094 | IN A,(C) | Read from the keyboard port. | ||||||||||||||||||||
| 6096 | AND %00000001 | Jump to MainGameLoop_Keyboard_TestRight if Q is not being pressed. | ||||||||||||||||||||
| 6098 | JR NZ,MainGameLoop_Keyboard_TestRight | |||||||||||||||||||||
| 609A | RES 4,E | Reset bit 4 of E (left active). | ||||||||||||||||||||
| MainGameLoop_Keyboard_TestRight | 609C | IN A,(C) | Read from the keyboard port again. | |||||||||||||||||||
| 609E | AND %00000010 | Jump to MainGameLoop_Keyboard_Store if W is not being pressed. | ||||||||||||||||||||
| 60A0 | JR NZ,MainGameLoop_Keyboard_Store | |||||||||||||||||||||
| 60A2 | RES 3,E | Reset bit 3 of E (right active). | ||||||||||||||||||||
| MainGameLoop_Keyboard_Store | 60A4 | LD A,E | Write E to *InputState. | |||||||||||||||||||
| 60A5 | LD ($5FA2),A | |||||||||||||||||||||
|
Handle Percy's egg drop state. If *EggDropFlag is set, Percy has dropped an egg and it is currently in flight.
|
||||||||||||||||||||||
| MainGameLoop_HandleEggDrop | 60A8 | LD A,($5FA9) | Jump to MainGameLoop_TestFirePressed if *EggDropFlag is unset (no egg active). | |||||||||||||||||||
| 60AB | OR A | |||||||||||||||||||||
| 60AC | JR Z,MainGameLoop_TestFirePressed | |||||||||||||||||||||
|
Egg is in flight so advance its Y position.
|
||||||||||||||||||||||
| 60AE | LD A,(IX+$21) | A=*IX+21 (Egg_Y_Position). | ||||||||||||||||||||
| 60B1 | ADD A,$04 | A+=04. | ||||||||||||||||||||
| 60B3 | CP $A8 | Has the egg reached Y position A8? | ||||||||||||||||||||
| 60B5 | JR C,MainGameLoop_UpdateEggY | Jump to MainGameLoop_UpdateEggY if not yet reached. | ||||||||||||||||||||
|
Egg has reached its target so end the egg drop state.
|
||||||||||||||||||||||
| 60B7 | LD (IX+$23),$00 | Write 00 to *IX+23 (Egg_Frame_ID). | ||||||||||||||||||||
| 60BB | XOR A | Write 00 to *EggDropFlag (egg drop complete). | ||||||||||||||||||||
| 60BC | LD ($5FA9),A | |||||||||||||||||||||
| MainGameLoop_UpdateEggY | 60BF | LD (IX+$21),A | Write A to *IX+21 (Egg_Y_Position). | |||||||||||||||||||
|
Play a rising sound effect while the egg is in flight.
|
||||||||||||||||||||||
| 60C2 | PUSH IX | Stash IX on the stack. | ||||||||||||||||||||
| 60C4 | LD HL,($5FB7) | HL=*BeepPitch. | ||||||||||||||||||||
| 60C7 | LD BC,$0010 | HL+=10. | ||||||||||||||||||||
| 60CA | ADD HL,BC | |||||||||||||||||||||
| 60CB | LD ($5FB7),HL | Write HL to *BeepPitch. | ||||||||||||||||||||
| 60CE | LD DE,$0004 | DE=0004. | ||||||||||||||||||||
| 60D1 | CALL $03B5 | Call BEEP. | ||||||||||||||||||||
| 60D4 | DI | Disable interrupts. | ||||||||||||||||||||
| 60D5 | POP IX | Restore IX from the stack. | ||||||||||||||||||||
| 60D7 | JR MainGameLoop_ApplyMovement | Jump to MainGameLoop_ApplyMovement. | ||||||||||||||||||||
|
Check if fire is pressed and conditions are met to drop an egg.
|
||||||||||||||||||||||
| MainGameLoop_TestFirePressed | 60D9 | LD A,($5FA2) | Jump to MainGameLoop_ApplyMovement if *InputState states that fire has not been pressed. | |||||||||||||||||||
| 60DC | BIT 0,A | |||||||||||||||||||||
| 60DE | JR NZ,MainGameLoop_ApplyMovement | |||||||||||||||||||||
| 60E0 | LD A,($5FAD) | Jump to MainGameLoop_ApplyMovement if *LandedOnPlatformFlag is set. | ||||||||||||||||||||
| 60E3 | OR A | |||||||||||||||||||||
| 60E4 | JR NZ,MainGameLoop_ApplyMovement | |||||||||||||||||||||
|
Percy must be below Y position 84 to drop an egg.
|
||||||||||||||||||||||
| 60E6 | LD A,(IX+$01) | Jump to MainGameLoop_ApplyMovement if Percy's Y position (*IX+01) is greater than or equal to 84 (too high to drop an egg). | ||||||||||||||||||||
| 60E9 | CP $84 | |||||||||||||||||||||
| 60EB | JR NC,MainGameLoop_ApplyMovement | |||||||||||||||||||||
|
Start the egg drop sequence and set the egg's target position/ activate the egg state.
|
||||||||||||||||||||||
| 60ED | ADD A,$10 | A+=10. | ||||||||||||||||||||
| 60EF | PUSH AF | Stash AF on the stack. | ||||||||||||||||||||
| 60F0 | CALL DropWorm | Call DropWorm. | ||||||||||||||||||||
| 60F3 | POP AF | Restore AF from the stack. | ||||||||||||||||||||
| 60F4 | LD (IX+$21),A | Write A to *IX+21 (egg target Y). | ||||||||||||||||||||
| 60F7 | LD (IX+$23),$0F | Write 0F to *IX+23 (Egg_Frame_ID). | ||||||||||||||||||||
| 60FB | LD A,(IX+$00) | A=*IX+00 (Percy's X position). | ||||||||||||||||||||
| 60FE | ADD A,$05 | A+=05. | ||||||||||||||||||||
| 6100 | LD (IX+$20),A | Write A to *IX+20 (egg target X). | ||||||||||||||||||||
| 6103 | OR %11111111 | Write FF to *EggDropFlag (egg drop in progress). | ||||||||||||||||||||
| 6105 | LD ($5FA9),A | |||||||||||||||||||||
| 6108 | LD HL,$0064 | Write 0064 to *BeepPitch (initial beep pitch). | ||||||||||||||||||||
| 610B | LD ($5FB7),HL | |||||||||||||||||||||
|
Apply the direction input to Percy's movement. First ensure fire is flagged as released, then dispatch to the appropriate movement handler for each direction.
|
||||||||||||||||||||||
| MainGameLoop_ApplyMovement | 610E | LD A,($5FA2) | Set bit 0 of *InputState (mark fire as handled). | |||||||||||||||||||
| 6111 | SET 0,A | |||||||||||||||||||||
| 6113 | LD ($5FA2),A | |||||||||||||||||||||
|
If Percy is falling (*FallingState is non-zero), handle the falling state.
|
||||||||||||||||||||||
| 6116 | LD A,($5FA7) | Jump to MainGameLoop_MovePercy if *FallingState is unset. | ||||||||||||||||||||
| 6119 | OR A | |||||||||||||||||||||
| 611A | JR Z,MainGameLoop_MovePercy | |||||||||||||||||||||
| 611C | CP $FE | Jump to MainGameLoop_Falling if A is FE. | ||||||||||||||||||||
| 611E | JR Z,MainGameLoop_Falling | |||||||||||||||||||||
|
Start falling and set the fall state and initial beep pitch.
|
||||||||||||||||||||||
| 6120 | LD A,$FE | Write FE to *FallingState. | ||||||||||||||||||||
| 6122 | LD ($5FA7),A | |||||||||||||||||||||
| 6125 | LD HL,$0082 | Write 82 to *BeepPitch. | ||||||||||||||||||||
| 6128 | LD ($5FB7),HL | |||||||||||||||||||||
|
Percy is falling so play a descending beep and move downward.
|
||||||||||||||||||||||
| MainGameLoop_Falling | 612B | LD BC,$0010 | Write *BeepPitch + 0010 back to *BeepPitch. | |||||||||||||||||||
| 612E | LD HL,($5FB7) | |||||||||||||||||||||
| 6131 | ADD HL,BC | |||||||||||||||||||||
| 6132 | LD ($5FB7),HL | |||||||||||||||||||||
| 6135 | LD DE,$0004 | DE=0004. | ||||||||||||||||||||
| 6138 | PUSH IX | Stash IX on the stack. | ||||||||||||||||||||
| 613A | CALL $03B5 | Call BEEP. | ||||||||||||||||||||
| 613D | POP IX | Restore IX from the stack. | ||||||||||||||||||||
| 613F | LD (IX+$02),$FF | Write FF to *IX+02. | ||||||||||||||||||||
|
Override input and force all directions inactive and only allow down.
|
||||||||||||||||||||||
| 6143 | LD HL,$5FA2 | Write 1F to *InputState. | ||||||||||||||||||||
| 6146 | LD (HL),$1F | |||||||||||||||||||||
|
If Percy has fallen below Y position 8D lose a life.
|
||||||||||||||||||||||
| 6148 | LD A,(IX+$01) | A=*IX+01 (Percy's Y position). | ||||||||||||||||||||
| 614B | CP $8D | Jump to Handle_Level_Complete if Percy has fallen off the screen (Percy's Y position is greater than 8D). | ||||||||||||||||||||
| 614D | JP NC,Lose_Life | |||||||||||||||||||||
| 6150 | RES 2,(HL) | Reset bit 2 of *HL (force downward movement). | ||||||||||||||||||||
|
Apply directional movement. Each handler moves Percy in the corresponding direction, checking screen boundaries.
|
||||||||||||||||||||||
| MainGameLoop_MovePercy | 6152 | LD C,(IX+$00) | C=*IX+00 (Percy's X position). | |||||||||||||||||||
| 6155 | LD B,(IX+$01) | B=*IX+01 (Percy's Y position). | ||||||||||||||||||||
| 6158 | PUSH BC | Stash Percy's position on the stack. | ||||||||||||||||||||
| 6159 | LD A,($5FA2) | E=*InputState. | ||||||||||||||||||||
| 615C | LD E,A | |||||||||||||||||||||
|
If no direction is pressed, decelerate.
|
||||||||||||||||||||||
| 615D | CP $1F | Call UpdateMovementSpeed_Decelerate if no direction has been pressed. | ||||||||||||||||||||
| 615F | CALL Z,UpdateMovementSpeed_Decelerate | |||||||||||||||||||||
| 6162 | LD A,($5FAE) | D=*MovementSpeed. | ||||||||||||||||||||
| 6165 | LD D,A | |||||||||||||||||||||
|
Dispatch to each direction handler if active.
|
||||||||||||||||||||||
| 6166 | BIT 4,E | Call MovePercyLeft if left is active. | ||||||||||||||||||||
| 6168 | CALL Z,MovePercyLeft | |||||||||||||||||||||
| 616B | BIT 3,E | Call MovePercyRight if right is active. | ||||||||||||||||||||
| 616D | CALL Z,MovePercyRight | |||||||||||||||||||||
| 6170 | BIT 1,E | Call MovePercyUp if up is active. | ||||||||||||||||||||
| 6172 | CALL Z,MovePercyUp | |||||||||||||||||||||
| 6175 | BIT 2,E | Call MovePercyDown if down is active. | ||||||||||||||||||||
| 6177 | CALL Z,MovePercyDown | |||||||||||||||||||||
|
Update the movement speed.
|
||||||||||||||||||||||
| 617A | CALL UpdateMovementSpeed | Call UpdateMovementSpeed. | ||||||||||||||||||||
|
If any direction was pressed, store it for animation purposes.
|
||||||||||||||||||||||
| 617D | LD A,($5FA2) | A=*InputState. | ||||||||||||||||||||
| 6180 | CP $1F | Jump to MainGameLoop_CollisionDetection if there was no input. | ||||||||||||||||||||
| 6182 | JR Z,MainGameLoop_CollisionDetection | |||||||||||||||||||||
| 6184 | LD ($5FA4),A | Write A to *PreviousInputState. | ||||||||||||||||||||
|
Collision detection with room scenery. Converts Percy's position to a room attribute buffer address and checks if Percy overlaps any solid tiles.
|
||||||||||||||||||||||
| MainGameLoop_CollisionDetection | 6187 | LD D,$00 | D=00. | |||||||||||||||||||
| 6189 | LD A,$00 | Write 00 to *CollisionFlag. | ||||||||||||||||||||
| 618B | LD ($5FA8),A | |||||||||||||||||||||
| 618E | LD E,$07 | E=07. | ||||||||||||||||||||
|
Load Percy's current position.
|
||||||||||||||||||||||
| 6190 | LD C,(IX+$00) | C=*IX+00 (Percy's X position). | ||||||||||||||||||||
| 6193 | LD B,(IX+$01) | B=*IX+01 (Percy's Y position). | ||||||||||||||||||||
|
Check if Percy's X position is on a pixel boundary.
|
||||||||||||||||||||||
| 6196 | LD A,C | A=C. | ||||||||||||||||||||
| 6197 | AND %00000111 | Keep only bits 0-2 (sub-character X offset). | ||||||||||||||||||||
| 6199 | OR A | Jump to MainGameLoop_CalcAttributeAddress if A is zero (aligned to character). | ||||||||||||||||||||
| 619A | JR Z,MainGameLoop_CalcAttributeAddress | |||||||||||||||||||||
| 619C | SET 0,D | Set bit 0 of D (not X-aligned). | ||||||||||||||||||||
|
Calculate the room attribute buffer address from Percy's position.
|
||||||||||||||||||||||
| MainGameLoop_CalcAttributeAddress | 619E | LD A,C | A=C. | |||||||||||||||||||
| 619F | RRCA | Rotate right three positions (divide X by 08). | ||||||||||||||||||||
| 61A0 | RRCA | |||||||||||||||||||||
| 61A1 | RRCA | |||||||||||||||||||||
| 61A2 | AND %00011111 | Keep only bits 0-4 (character column). | ||||||||||||||||||||
| 61A4 | LD L,A | L=A. | ||||||||||||||||||||
| 61A5 | LD A,B | A=B. | ||||||||||||||||||||
| 61A6 | AND %00000111 | Keep only bits 0-2 (sub-character Y offset). | ||||||||||||||||||||
| 61A8 | OR A | Jump to MainGameLoop_CalcAttributeAddress_2 if A is zero (aligned to character row). | ||||||||||||||||||||
| 61A9 | JR Z,MainGameLoop_CalcAttributeAddress_2 | |||||||||||||||||||||
| 61AB | SET 1,D | Set bit 1 of D (not Y-aligned). | ||||||||||||||||||||
| MainGameLoop_CalcAttributeAddress_2 | 61AD | LD A,B | A=B. | |||||||||||||||||||
| 61AE | RLCA | Rotate left two positions. | ||||||||||||||||||||
| 61AF | RLCA | |||||||||||||||||||||
| 61B0 | AND %11100000 | Keep only bits 5-7. | ||||||||||||||||||||
| 61B2 | OR L | Merge in the column from L. | ||||||||||||||||||||
| 61B3 | LD L,A | L=A. | ||||||||||||||||||||
| 61B4 | LD A,B | A=B. | ||||||||||||||||||||
| 61B5 | RLCA | Rotate left two positions. | ||||||||||||||||||||
| 61B6 | RLCA | |||||||||||||||||||||
| 61B7 | AND %00000011 | Keep only bits 0-1. | ||||||||||||||||||||
| 61B9 | OR %11011000 | Set bits 3-4 and 6-7 for room attribute buffer at RoomAttributeBuffer. | ||||||||||||||||||||
| 61BB | LD H,A | H=A. | ||||||||||||||||||||
|
Check a vertical strip of attribute cells for solid tiles. The height of the strip depends on whether Percy is Y-aligned.
|
||||||||||||||||||||||
| 61BC | LD B,$02 | B=02 (rows to check). | ||||||||||||||||||||
| 61BE | BIT 1,D | Jump to MainGameLoop_CollisionCheck_Loop if Y-aligned. | ||||||||||||||||||||
| 61C0 | JR Z,MainGameLoop_CollisionCheck_Loop | |||||||||||||||||||||
| 61C2 | INC B | Check an extra row if not Y-aligned. | ||||||||||||||||||||
| MainGameLoop_CollisionCheck_Loop | 61C3 | PUSH BC | Stash the row counter on the stack. | |||||||||||||||||||
|
Check the current attribute cell and the one to its right.
|
||||||||||||||||||||||
| 61C4 | LD A,(HL) | A=*HL. | ||||||||||||||||||||
| 61C5 | AND E | Mask with E. | ||||||||||||||||||||
| 61C6 | CP E | Jump to MainGameLoop_CollisionDetected if a collision was detected (not all bits set). | ||||||||||||||||||||
| 61C7 | JR NZ,MainGameLoop_CollisionDetected | |||||||||||||||||||||
| 61C9 | INC HL | Move to the next column. | ||||||||||||||||||||
| 61CA | LD A,(HL) | A=*HL. | ||||||||||||||||||||
| 61CB | AND E | Mask with E. | ||||||||||||||||||||
| 61CC | CP E | Jump to MainGameLoop_CollisionDetected if a collision was detected. | ||||||||||||||||||||
| 61CD | JR NZ,MainGameLoop_CollisionDetected | |||||||||||||||||||||
| 61CF | DEC HL | Move back to the original column. | ||||||||||||||||||||
|
If Percy is not X-aligned, also check the cell two columns right.
|
||||||||||||||||||||||
| 61D0 | BIT 0,D | Jump to MainGameLoop_CollisionCheck_NextRow if X-aligned. | ||||||||||||||||||||
| 61D2 | JR Z,MainGameLoop_CollisionCheck_NextRow | |||||||||||||||||||||
| 61D4 | INC HL | Move two columns right. | ||||||||||||||||||||
| 61D5 | INC HL | |||||||||||||||||||||
| 61D6 | LD A,(HL) | A=*HL. | ||||||||||||||||||||
| 61D7 | AND E | Mask with E. | ||||||||||||||||||||
| 61D8 | CP E | Jump to MainGameLoop_CollisionDetected if a collision was detected. | ||||||||||||||||||||
| 61D9 | JR NZ,MainGameLoop_CollisionDetected | |||||||||||||||||||||
| 61DB | DEC HL | Move back two columns. | ||||||||||||||||||||
| 61DC | DEC HL | |||||||||||||||||||||
|
Move down one row in the attribute buffer and continue.
|
||||||||||||||||||||||
| MainGameLoop_CollisionCheck_NextRow | 61DD | LD BC,$0020 | HL+=0020. | |||||||||||||||||||
| 61E0 | ADD HL,BC | |||||||||||||||||||||
| 61E1 | POP BC | Restore the row counter from the stack. | ||||||||||||||||||||
| 61E2 | DJNZ MainGameLoop_CollisionCheck_Loop | Decrease the row counter by one and loop back to MainGameLoop_CollisionCheck_Loop until all rows are checked. | ||||||||||||||||||||
|
No collision detected so Percy can move freely. Restore the position from the stack and update the sprite frame.
|
||||||||||||||||||||||
| MainGameLoop_NoCollision | 61E4 | POP BC | Restore Percy's previous position from the stack. | |||||||||||||||||||
| 61E5 | LD (IX+$02),$07 | Write 07 to *IX+02. | ||||||||||||||||||||
|
If Percy is not falling, check for ground beneath.
|
||||||||||||||||||||||
| 61E9 | LD A,($5FA7) | Jump to MainGameLoop_ClearLandedFlag if Percy is falling (*FallingState is set). | ||||||||||||||||||||
| 61EC | OR A | |||||||||||||||||||||
| 61ED | JR NZ,MainGameLoop_ClearLandedFlag | |||||||||||||||||||||
|
Check if there is ground below Percy's feet. Calculate the attribute address one character row below Percy's position.
|
||||||||||||||||||||||
| MainGameLoop_CheckGround | 61EF | LD C,(IX+$00) | C=*IX+00 (Percy's X position). | |||||||||||||||||||
| 61F2 | LD B,(IX+$01) | B=*IX+01 (Percy's Y position).. | ||||||||||||||||||||
| 61F5 | LD A,C | A=C. | ||||||||||||||||||||
| 61F6 | AND %00000111 | Keep only bits 0-2 (sub-character X offset). | ||||||||||||||||||||
| 61F8 | PUSH AF | Stash the X offset on the stack. | ||||||||||||||||||||
| 61F9 | LD A,C | A=C. | ||||||||||||||||||||
| 61FA | RRCA | Rotate right three positions (divide X by 08). | ||||||||||||||||||||
| 61FB | RRCA | |||||||||||||||||||||
| 61FC | RRCA | |||||||||||||||||||||
| 61FD | AND %00011111 | Keep only bits 0-4 (character column). | ||||||||||||||||||||
| 61FF | LD L,A | L=A. | ||||||||||||||||||||
|
Add 10 pixels to the Y position to check below Percy's feet.
|
||||||||||||||||||||||
| 6200 | LD A,B | A=B. | ||||||||||||||||||||
| 6201 | ADD A,$10 | B=A + 10. | ||||||||||||||||||||
| 6203 | LD B,A | |||||||||||||||||||||
| 6204 | RLCA | Rotate left two positions. | ||||||||||||||||||||
| 6205 | RLCA | |||||||||||||||||||||
| 6206 | AND %11100000 | Keep only bits 5-7. | ||||||||||||||||||||
| 6208 | OR L | Merge in the column. | ||||||||||||||||||||
| 6209 | LD L,A | L=A. | ||||||||||||||||||||
| 620A | LD A,B | A=B. | ||||||||||||||||||||
| 620B | AND %11000000 | Keep only bits 6-7. | ||||||||||||||||||||
| 620D | RRCA | Rotate right three positions. | ||||||||||||||||||||
| 620E | RRCA | |||||||||||||||||||||
| 620F | RRCA | |||||||||||||||||||||
| 6210 | OR %11000000 | Set bits 6-7 for the room attribute buffer at RoomBuffer. | ||||||||||||||||||||
| 6212 | LD H,A | H=A. | ||||||||||||||||||||
| 6213 | POP AF | Restore the X offset from the stack. | ||||||||||||||||||||
|
If Percy is X-aligned, skip the extra column check.
|
||||||||||||||||||||||
| 6214 | OR A | Jump to MainGameLoop_CheckGround_ExtraCol if the X offset is non-zero. | ||||||||||||||||||||
| 6215 | JR NZ,MainGameLoop_CheckGround_ExtraCol | |||||||||||||||||||||
| 6217 | LD A,($5FA5) | Jump to MainGameLoop_CheckGround_Test if *PercyFacingDirection is zero (Percy is facing right). | ||||||||||||||||||||
| 621A | OR A | |||||||||||||||||||||
| 621B | JR Z,MainGameLoop_CheckGround_Test | |||||||||||||||||||||
| MainGameLoop_CheckGround_ExtraCol | 621D | INC L | Move one column right. | |||||||||||||||||||
|
Check if the tile below is a platform (attribute AA).
|
||||||||||||||||||||||
| MainGameLoop_CheckGround_Test | 621E | LD A,(HL) | Jump to MainGameLoop_ClearLandedFlag if there's no platform below Percy (by checking if the attribute is AA/ INK:RED, PAPER:CYAN (FLASH: ON)). | |||||||||||||||||||
| 621F | CP $AA | |||||||||||||||||||||
| 6221 | JR NZ,MainGameLoop_ClearLandedFlag | |||||||||||||||||||||
|
Platform detected so check if Percy should land.
|
||||||||||||||||||||||
| 6223 | LD A,($5FA2) | Jump to MainGameLoop_CheckGround_TestUp if *InputState states that down is not being pressed. | ||||||||||||||||||||
| 6226 | BIT 2,A | |||||||||||||||||||||
| 6228 | JR NZ,MainGameLoop_CheckGround_TestUp | |||||||||||||||||||||
|
Down is pressed while on a platform so snap Percy's Y to the platform.
|
||||||||||||||||||||||
| 622A | LD A,(IX+$01) | A=*IX+01. | ||||||||||||||||||||
| 622D | AND %11111000 | Keep only bits 3-7 (snap to character row). | ||||||||||||||||||||
| 622F | LD (IX+$01),A | Write A to *IX+01. | ||||||||||||||||||||
| 6232 | OR %11111111 | Write FF to *LandedOnPlatformFlag (landed on platform flag). | ||||||||||||||||||||
| 6234 | LD ($5FAD),A | |||||||||||||||||||||
| 6237 | JR MainGameLoop_UpdateAnimation | Jump to MainGameLoop_UpdateAnimation. | ||||||||||||||||||||
|
Check if up is pressed while on a platform.
|
||||||||||||||||||||||
| MainGameLoop_CheckGround_TestUp | 6239 | BIT 1,A | Jump to MainGameLoop_UpdateAnimation if up is not pressed. | |||||||||||||||||||
| 623B | JR NZ,MainGameLoop_UpdateAnimation | |||||||||||||||||||||
|
No platform below so clear the landed flag.
|
||||||||||||||||||||||
| MainGameLoop_ClearLandedFlag | 623D | XOR A | Write 00 to clear *LandedOnPlatformFlag. | |||||||||||||||||||
| 623E | LD ($5FAD),A | |||||||||||||||||||||
| MainGameLoop_UpdateAnimation | 6241 | JP UpdatePercyAnimation | Jump to UpdatePercyAnimation. | |||||||||||||||||||
|
Collision with solid scenery detected so reject the move and restore Percy's previous position.
|
||||||||||||||||||||||
| MainGameLoop_CollisionDetected | 6244 | POP BC | Restore the row counter and overwrite it with Percy's previous position from the stack. | |||||||||||||||||||
| 6245 | POP BC | |||||||||||||||||||||
|
If Percy is falling, handle the impact.
|
||||||||||||||||||||||
| 6246 | LD A,($5FA7) | Jump to MainGameLoop_FallImpact if Percy is falling (*FallingState is set). | ||||||||||||||||||||
| 6249 | OR A | |||||||||||||||||||||
| 624A | JR NZ,MainGameLoop_FallImpact | |||||||||||||||||||||
|
Check if Percy has hit the bottom of the screen.
|
||||||||||||||||||||||
| 624C | LD A,(IX+$01) | Jump to MainGameLoop_SnapPosition if Percy's Y position (*IX+01) is greater than or equal to 91 and Percy is at the bottom of the screen. | ||||||||||||||||||||
| 624F | CP $91 | |||||||||||||||||||||
| 6251 | JR NC,MainGameLoop_SnapPosition | |||||||||||||||||||||
|
Special case; if in room 06 treat collision differently.
|
||||||||||||||||||||||
| 6253 | LD A,($5FC5) | Jump to MainGameLoop_SnapPosition if *CurrentRoom is room 06. | ||||||||||||||||||||
| 6256 | CP $06 | |||||||||||||||||||||
| 6258 | JR Z,MainGameLoop_SnapPosition | |||||||||||||||||||||
|
Check if the collision cell is empty.
|
||||||||||||||||||||||
| 625A | LD A,(HL) | A=*HL. | ||||||||||||||||||||
| 625B | AND E | Mask with E. | ||||||||||||||||||||
| 625C | OR A | Jump to MainGameLoop_SnapPosition if the cell is empty. | ||||||||||||||||||||
| 625D | JR Z,MainGameLoop_SnapPosition | |||||||||||||||||||||
|
Handle Percy falling and hitting something.
|
||||||||||||||||||||||
| MainGameLoop_FallImpact | 625F | CP $FE | Jump to MainGameLoop_FallImpact_Done if A is FE. | |||||||||||||||||||
| 6261 | JR Z,MainGameLoop_FallImpact_Done | |||||||||||||||||||||
| 6263 | OR %11111111 | Write FF to *FallingState. | ||||||||||||||||||||
| 6265 | LD ($5FA7),A | |||||||||||||||||||||
| 6268 | LD (IX+$02),$FF | Write FF to *IX+02. | ||||||||||||||||||||
| MainGameLoop_FallImpact_Done | 626C | JP UpdatePercyAnimation | Jump to UpdatePercyAnimation. | |||||||||||||||||||
|
Percy has moved past a screen boundary so trigger a room transition. The direction determines which room to move to.
|
||||||||||||||||||||||
| MainGameLoop_SnapPosition | 626F | LD A,$01 | Write 01 to; | |||||||||||||||||||
| 6271 | LD ($5FAE),A | |||||||||||||||||||||
| 6274 | LD ($5FA8),A | |||||||||||||||||||||
|
Restore Percy's position from before the rejected move.
|
||||||||||||||||||||||
| 6277 | LD (IX+$00),C | Write C to *IX+00 (Percy's X position). | ||||||||||||||||||||
| 627A | LD (IX+$01),B | Write B to *IX+01 (Percy's Y position). | ||||||||||||||||||||
| 627D | JP UpdatePercyAnimation | Jump to UpdatePercyAnimation. | ||||||||||||||||||||
| Prev: 5FE7 | Up: Map | Next: 6280 |