Prev: 9F6A Up: Map Next: A002
9F70: Handler: Pickups
Keep the collectible objects in the world. When the pickup slots are empty, refill them, choose a world X away from Jetman and the rover, place the pickups from it and then advance the level.
Refill Object_Slot_1 from Pickup_Defaults when those slots are empty.
Handler_Pickups 9F70 CALL ScanObjectSlots_Test Call ScanObjectSlots_Test.
9F73 RET NZ Return if any pickup slot is still in use.
9F74 LD HL,$A068 Copy the 90 bytes of pickup templates from Pickup_Defaults into the pickup slots at Object_Slot_1.
9F77 LD DE,$6108
9F7A LD BC,$0090
9F7D LDIR
Seed the candidate world X in HL from GameTimer and RandomNumber.
9F7F LD A,($5E42) Fetch GameTimer.
9F82 LD H,A Stash it in H.
9F83 LD A,($5E40) Fetch RandomNumber.
9F86 LD L,A Stash it in L.
Keep the new world X at least 10 away from Jetman_Position and Rover_Position.
Handler_Pickups_AwayFromJetman 9F87 LD A,($607B) Fetch the high byte of Jetman_Position.
9F8A ADD A,A Multiply it by 08.
9F8B ADD A,A
9F8C ADD A,A
9F8D SUB H Subtract the candidate high byte.
9F8E JP P,Handler_Pickups_TestJetmanX Jump to Handler_Pickups_TestJetmanX if the result is positive.
9F91 NEG Negate the difference.
Handler_Pickups_TestJetmanX 9F93 CP $10 Compare it against 10.
9F95 JR C,StepPickupCandidate Jump to StepPickupCandidate if it is closer than that.
Retry unless the candidate is also at least 10 from Rover_Position.
9F97 LD A,($6093) Fetch the high byte of Rover_Position.
9F9A ADD A,A Multiply it by 08.
9F9B ADD A,A
9F9C ADD A,A
9F9D SUB H Subtract the candidate high byte.
9F9E JP P,Handler_Pickups_TestRoverX Jump to Handler_Pickups_TestRoverX if the result is positive.
9FA1 NEG Negate the difference.
Handler_Pickups_TestRoverX 9FA3 CP $10 Compare it against 10.
9FA5 JR C,StepPickupCandidate Jump to StepPickupCandidate if it is closer than that.
Write the new pickup positions into the pickup slots.
9FA7 SRL H Divide the candidate high byte by 08.
9FA9 SRL H
9FAB SRL H
9FAD LD ($610A),HL Write it to 610A.
Derive the other pickup world X values by adding offsets and wrapping. MaskWorldX hands the wrapped result back in HL, so each offset is added to the world X written just before it.
9FB0 LD BC,$0040 Set the offset in BC to 0040 to place the next pickup that far on from the first.
9FB3 CALL MaskWorldX Call MaskWorldX to add the offset and wrap the world X.
9FB6 LD ($616A),HL Write it to 616A.
Place the next pickup a smaller step further on.
9FB9 LD BC,$0008 Set the offset in BC to 0008.
9FBC CALL MaskWorldX Call MaskWorldX to add the offset and wrap the world X.
9FBF LD ($6182),HL Write it to AlienBase_WorldX.
Finally step on by 40 again for the last pickup.
9FC2 LD BC,$0040 Set the offset in BC to 0040.
9FC5 CALL MaskWorldX Call MaskWorldX to add the offset and wrap the world X.
9FC8 LD ($613A),HL Write it to Object_Slot_3_Position.
Advance the level, and award an extra life every fourth level.
9FCB LD A,($5EA0) Fetch ActivePlayer_Level.
9FCE CP $63 Jump to Handler_Pickups_WriteLevel if it is already 63.
9FD0 JR Z,Handler_Pickups_WriteLevel
9FD2 INC A Increase the level by one.
Handler_Pickups_WriteLevel 9FD3 LD ($5EA0),A Write it back to ActivePlayer_Level.
9FD6 AND A Jump to Handler_Pickups_TestLevel10 if the new level is zero.
9FD7 JR Z,Handler_Pickups_TestLevel10
9FD9 AND %00000011 Keep only bits 0-1.
9FDB JR NZ,Handler_Pickups_TestLevel10 Jump to Handler_Pickups_TestLevel10 if this is not a fourth level.
Award an extra life and queue a jingle, then redraw the lives.
9FDD LD HL,$5EA1 HL=ActivePlayer_Lives.
9FE0 INC (HL) Increase ActivePlayer_Lives by one.
9FE1 LD DE,$BAB4 Point DE at the tune at Tune_Extra_2.
9FE4 CALL QueueTune Call QueueTune.
9FE7 CALL DisplayPlayerLives Call DisplayPlayerLives.
Turn the level into the missile launcher countdown at Missile_Launcher_Countdown (the higher the level, the shorter it is), then jump to PrintPlayerLevels. Rotating left twice multiplies the level by 04. Inverting and masking that to bits 2-5 gives 3C minus 04 for each level, so adding 51 leaves a countdown that falls by 04 per level, from 8D to 51.
Level Rotate x2 Invert Keep bits 2-5 Add 51
00 00 FF 3C 8D
01 04 FB 38 89
02 08 F7 34 85
07 1C E3 20 71
0F 3C C3 00 51
10 and up FF 00 00 51
Handler_Pickups_TestLevel10 9FEA LD A,($5EA0) Fetch ActivePlayer_Level.
9FED CP $10 Compare it against 10.
9FEF CALL NC,Handler_Pickups_ForceMaximumLevel Call Handler_Pickups_ForceMaximumLevel if the level is at least 10.
9FF2 RLCA Rotate the level left twice.
9FF3 RLCA
9FF4 CPL Invert the bits.
9FF5 AND %00111100 Keep only bits 2-5.
9FF7 ADD A,$51 Add 51.
9FF9 LD ($617F),A Write it to Missile_Launcher_Countdown.
9FFC JP PrintPlayerLevels Jump to PrintPlayerLevels.
Levels of 10 and above use FF in place of the level, so they all get the shortest countdown (51). The rotate would otherwise wrap the high bits of the level round into the result.
Handler_Pickups_ForceMaximumLevel 9FFF LD A,$FF A=FF.
A001 RET Return.
Prev: 9F6A Up: Map Next: A002