![]() |
Routines |
| Prev: A53A | Up: Map | Next: A73C |
|
On a 1-in-4 frame, spawn a shot into a free laser slot when FIRE is held, then fly any live shots.
|
||||||||
| Handler_PlayerShot | A579 | LD A,($5E42) | Fetch GameTimer. | |||||
| A57C | AND %00000011 | Keep only bits 0-1. | ||||||
| A57E | RET NZ | Return if this is not a 4th frame. | ||||||
| A57F | CALL HandlerControls | Call HandlerControls. | ||||||
| A582 | BIT 4,A | Return if FIRE is not pressed. | ||||||
| A584 | RET NZ | |||||||
|
Look for a free laser slot.
|
||||||||
| A585 | LD HL,$6000 | HL=Laser_Parameter_1. | ||||||
| A588 | LD DE,$0018 | DE=0018. | ||||||
| A58B | LD B,$02 | Set a slot counter in B for 02 loops. | ||||||
| Handler_PlayerShot_Loop | A58D | LD A,(HL) | Jump to Handler_PlayerShot_Initialise if this slot is free. | |||||
| A58E | AND A | |||||||
| A58F | JR Z,Handler_PlayerShot_Initialise | |||||||
| A591 | ADD HL,DE | Move onto the next slot. | ||||||
| A592 | DJNZ Handler_PlayerShot_Loop | Decrease the slot counter by one and loop back to Handler_PlayerShot_Loop until both slots have been tried. | ||||||
| A594 | RET | Return. | ||||||
|
Initialise a new shot from the current actor.
|
||||||||
| Handler_PlayerShot_Initialise | A595 | PUSH HL | Stash the free slot on the stack. | |||||
| A596 | CALL Copy_Explosion_Template | Call Copy_Explosion_Template. | ||||||
| A599 | POP HL | Restore the free slot from the stack. | ||||||
| A59A | LD (HL),$58 | Write type 58. | ||||||
| A59C | INC HL | Move onto the new world X. | ||||||
| A59D | INC HL | |||||||
| A59E | EX DE,HL | Switch the destination into DE. | ||||||
|
Look up this actor's entry in the shot table at Handler_PlayerShot_Table.
|
||||||||
| A59F | LD A,(IX+$00) | Fetch the actor type. | ||||||
| A5A2 | RLCA | Rotate it left twice. | ||||||
| A5A3 | RLCA | |||||||
| A5A4 | AND %00111100 | Keep only bits 2-5. | ||||||
| A5A6 | LD C,A | Create an offset in BC. | ||||||
| A5A7 | LD B,$00 | |||||||
| A5A9 | LD HL,$A68B | HL=Handler_PlayerShot_Table. | ||||||
| A5AC | ADD HL,BC | Add the offset. | ||||||
|
Add the table X offset to the actor world X.
|
||||||||
| A5AD | LD A,(HL) | Fetch the X offset. | ||||||
| A5AE | LD B,$00 | Clear B. | ||||||
| A5B0 | AND A | Jump to Handler_PlayerShot_AddWorldX if the offset is positive. | ||||||
| A5B1 | JP P,Handler_PlayerShot_AddWorldX | |||||||
| A5B4 | DEC B | Sign-extend into B. | ||||||
| Handler_PlayerShot_AddWorldX | A5B5 | ADD A,(IX+$02) | Add the actor world X. | |||||
| A5B8 | INC HL | Move onto the next table byte. | ||||||
| A5B9 | LD (DE),A | Write the new world X. | ||||||
| A5BA | INC DE | Move onto the high byte. | ||||||
|
Work out the high byte of the new world X and the new Y.
|
||||||||
| A5BB | LD A,(IX+$03) | Fetch the actor world X high byte. | ||||||
| A5BE | ADC A,B | Add the sign. | ||||||
| A5BF | AND %00011111 | Keep only bits 0-4. | ||||||
| A5C1 | LD (DE),A | Write the high byte. | ||||||
| A5C2 | INC DE | Move onto the new Y. | ||||||
| A5C3 | LD A,(IX+$04) | Fetch the actor Y. | ||||||
| A5C6 | ADD A,(HL) | Add the table Y offset. | ||||||
| A5C7 | INC HL | Move onto the next table byte. | ||||||
|
Write the remaining shot fields and clear the rest of the slot.
|
||||||||
| Handler_PlayerShot_WriteFields | A5C8 | LD (DE),A | Write the new Y. | |||||
| A5C9 | INC DE | Move onto the speed. | ||||||
| A5CA | LD A,(HL) | Copy the next table byte. | ||||||
| A5CB | INC HL | |||||||
| A5CC | LD (DE),A | Write it and move on. | ||||||
| A5CD | INC DE | |||||||
| A5CE | LD A,(HL) | Copy the next table byte. | ||||||
| A5CF | INC HL | |||||||
| A5D0 | LD (DE),A | Write it and move on. | ||||||
| A5D1 | INC DE | |||||||
|
Pick the shot colour from the timer at RandomNumber.
|
||||||||
| A5D2 | LD A,($5E40) | Fetch RandomNumber. | ||||||
| A5D5 | AND %00000011 | Keep only bits 0-1. | ||||||
| A5D7 | LD BC,$A5EF | Point BC at the shot colour table at Handler_PlayerShot_Colours. | ||||||
| A5DA | ADD A,C | Add the colour index. | ||||||
| A5DB | LD C,A | Copy the low byte into C. | ||||||
| A5DC | LD A,B | Fetch the high byte. | ||||||
| A5DD | ADC A,$00 | Add the carry. | ||||||
| A5DF | LD B,A | Write it back to B. | ||||||
| A5E0 | LD A,(BC) | Fetch the colour. | ||||||
| A5E1 | LD (DE),A | Write it to the shot colour. | ||||||
| A5E2 | INC DE | Move onto the next field. | ||||||
| A5E3 | LD A,$20 | A=20. | ||||||
| A5E5 | LD (DE),A | Write it. | ||||||
| A5E6 | INC DE | Move on. | ||||||
|
Clear the remaining 0F bytes of the slot.
|
||||||||
| A5E7 | LD B,$0F | Set a byte counter in B for 0F loops. | ||||||
| A5E9 | XOR A | Clear A. | ||||||
| Handler_PlayerShot_ClearTail | A5EA | LD (DE),A | Write 00. | |||||
| A5EB | INC DE | Move onto the next byte. | ||||||
| A5EC | DJNZ Handler_PlayerShot_ClearTail | Decrease the byte counter by one and loop back to Handler_PlayerShot_ClearTail until the slot tail is clear. | ||||||
| A5EE | RET | Return. | ||||||
|
The four colours a player shot can be.
|
||||||||
| Handler_PlayerShot_Colours | A5EF | DEFB $44 | INK:GREEN, PAPER:BLACK (BRIGHT). | |||||
|
The four colours a player shot can be.
|
||||||||
| A5F0 | DEFB $45 | INK:CYAN, PAPER:BLACK (BRIGHT). | ||||||
|
The four colours a player shot can be.
|
||||||||
| A5F1 | DEFB $46 | INK:YELLOW, PAPER:BLACK (BRIGHT). | ||||||
|
The four colours a player shot can be.
|
||||||||
| A5F2 | DEFB $47 | INK:WHITE, PAPER:BLACK (BRIGHT). | ||||||
|
Advance the shot world X from the packed nibble at *IX+10.
|
||||||||
| Handler_PlayerShot_AdvanceX | A5F3 | ADD A,(IX+$10) | Add the X nibble. | |||||
| A5F6 | LD C,A | Stash the sum in C. | ||||||
| A5F7 | AND %00001111 | Keep only bits 0-3. | ||||||
| A5F9 | LD (IX+$10),A | Write it back as the X nibble. | ||||||
| A5FC | LD A,C | Copy the sum into A. | ||||||
| A5FD | RRCA | Rotate the high nibble down into bits 0-3. | ||||||
| A5FE | RRCA | |||||||
| A5FF | RRCA | |||||||
| A600 | RRCA | |||||||
| A601 | AND %00001111 | Keep only bits 0-3. | ||||||
| A603 | LD B,$00 | Clear B. | ||||||
| A605 | JR Handler_PlayerShot_WriteX | Jump to Handler_PlayerShot_WriteX. | ||||||
|
Advance the shot Y from the packed nibble at *IX+11.
|
||||||||
| Handler_PlayerShot_AdvanceY | A607 | ADD A,(IX+$11) | Add the Y nibble. | |||||
| A60A | LD C,A | Stash the sum in C. | ||||||
| A60B | AND %00001111 | Keep only bits 0-3. | ||||||
| A60D | LD (IX+$11),A | Write it back as the Y nibble. | ||||||
| A610 | LD A,C | Copy the sum into A. | ||||||
| A611 | RRCA | Rotate the high nibble down into bits 0-3. | ||||||
| A612 | RRCA | |||||||
| A613 | RRCA | |||||||
| A614 | RRCA | |||||||
| A615 | AND %00001111 | Keep only bits 0-3. | ||||||
| A617 | JR Handler_PlayerShot_WriteY | Jump to Handler_PlayerShot_WriteY. | ||||||
|
Count down the shot timer and work out the X step from the shot speed.
|
||||||||
| Handler_PlayerShot_Fly | A619 | DEC (IX+$08) | Decrease the shot timer by one. | |||||
| A61C | JP Z,StartSmallExplosion | Jump to StartSmallExplosion if it has expired. | ||||||
| A61F | LD A,(IX+$05) | Fetch the shot speed. | ||||||
| A622 | AND A | Jump to Handler_PlayerShot_AdvanceX if the speed is positive. | ||||||
| A623 | JP P,Handler_PlayerShot_AdvanceX | |||||||
|
Work out a negative X step when the speed is negative.
|
||||||||
| A626 | ADD A,(IX+$10) | Add the X nibble. | ||||||
| A629 | LD C,A | Stash the sum in C. | ||||||
| A62A | AND %00001111 | Keep only bits 0-3. | ||||||
| A62C | NEG | Negate it. | ||||||
| A62E | LD (IX+$10),A | Write it back as the X nibble. | ||||||
| A631 | LD A,C | Copy the sum into A. | ||||||
| A632 | NEG | Negate it. | ||||||
| A634 | RRCA | Rotate the high nibble down into bits 0-3. | ||||||
| A635 | RRCA | |||||||
| A636 | RRCA | |||||||
| A637 | RRCA | |||||||
| A638 | AND %00001111 | Keep only bits 0-3. | ||||||
| A63A | NEG | Negate it. | ||||||
| A63C | LD B,$FF | B=FF. | ||||||
|
Add the X step to the shot's world X.
|
||||||||
| Handler_PlayerShot_WriteX | A63E | ADD A,(IX+$02) | Add the step to the world X. | |||||
| A641 | LD (IX+$02),A | Write it back. | ||||||
| A644 | LD A,(IX+$03) | Fetch the high byte. | ||||||
| A647 | ADC A,B | Add the sign. | ||||||
| A648 | AND %00011111 | Keep only bits 0-4. | ||||||
| A64A | LD (IX+$03),A | Write the high byte back. | ||||||
|
Work out the Y step from the shot thrust.
|
||||||||
| A64D | LD A,(IX+$06) | Fetch the shot thrust. | ||||||
| A650 | AND A | Jump to Handler_PlayerShot_AdvanceY if the thrust is positive. | ||||||
| A651 | JP P,Handler_PlayerShot_AdvanceY | |||||||
|
Work out a negative Y step when the thrust is negative.
|
||||||||
| A654 | ADD A,(IX+$11) | Add the Y nibble. | ||||||
| A657 | LD C,A | Stash the sum in C. | ||||||
| A658 | AND %00001111 | Keep only bits 0-3. | ||||||
| A65A | NEG | Negate it. | ||||||
| A65C | LD (IX+$11),A | Write it back as the Y nibble. | ||||||
| A65F | LD A,C | Copy the sum into A. | ||||||
| A660 | NEG | Negate it. | ||||||
| A662 | RRCA | Rotate the high nibble down into bits 0-3. | ||||||
| A663 | RRCA | |||||||
| A664 | RRCA | |||||||
| A665 | RRCA | |||||||
| A666 | AND %00001111 | Keep only bits 0-3. | ||||||
| A668 | NEG | Negate it. | ||||||
| Handler_PlayerShot_WriteY | A66A | ADD A,(IX+$04) | Add the step to the shot Y. | |||||
|
Destroy the shot if it hits the ground or leaves the play area.
|
||||||||
| A66D | CP $AF | Compare it against AF. | ||||||
| A66F | JP NC,StartSmallExplosion | Jump to StartSmallExplosion if the shot is on the ground. | ||||||
| A672 | CP $30 | Compare it against 30. | ||||||
| A674 | JP C,StartSmallExplosion | Jump to StartSmallExplosion if the shot is above the play area. | ||||||
|
Store the new Y, flip the shot frame and draw the shot.
|
||||||||
| A677 | LD (IX+$04),A | Write the new Y. | ||||||
| A67A | LD A,(IX+$00) | Fetch the shot type. | ||||||
| A67D | XOR %00000001 | Flip bit 0. | ||||||
| A67F | LD (IX+$00),A | Write it back. | ||||||
| A682 | CALL DrawObjectSprite | Call DrawObjectSprite. | ||||||
| A685 | CALL ColouriseSprite | Call ColouriseSprite. | ||||||
| A688 | JP Handler_PlayerShot_TestSlots | Jump to Handler_PlayerShot_TestSlots. | ||||||
| Handler_PlayerShot_Table | A68B | DEFB $F8,$FC,$C0,$00,$F8,$F9,$C4,$FA | Shot table. Each 04-byte entry holds an X offset, a Y offset, a speed and a thrust. | |||||
| A693 | DEFB $F9,$F6,$C7,$E3,$F9,$F4,$CA,$DE | |||||||
| A69B | DEFB $FC,$F2,$D3,$D3,$FF,$F0,$DB,$CC | |||||||
| A6A3 | DEFB $01,$F0,$E3,$C7,$03,$EE,$EA,$C4 | |||||||
| A6AB | DEFB $10,$FC,$40,$00,$10,$F9,$3C,$FA | |||||||
| A6B3 | DEFB $10,$F5,$39,$E3,$0F,$F3,$36,$DE | |||||||
| A6BB | DEFB $0C,$F2,$2D,$D3,$09,$F0,$25,$CC | |||||||
| A6C3 | DEFB $08,$EF,$1D,$C7,$05,$ED,$16,$C4 | |||||||
|
Test the shot against the alien and object slots.
|
||||||||
| Handler_PlayerShot_TestSlots | A6CB | LD A,$18 | A=18. | |||||
| A6CD | LD ($A726),A | Write it over the hit-height compare at A726. | ||||||
| A6D0 | LD HL,$61B0 | HL=Alien_Slot_1. | ||||||
| A6D3 | LD DE,$0018 | DE=0018. | ||||||
| A6D6 | LD B,$06 | Set a slot counter in B for 06 loops. | ||||||
| A6D8 | CALL Handler_PlayerShot_ScanSlot | Call Handler_PlayerShot_ScanSlot. | ||||||
|
Test the object slot at Object_Slot_1 with a hit height of 0C.
|
||||||||
| A6DB | LD A,$0C | A=0C. | ||||||
| A6DD | LD ($A726),A | Write it over the hit-height compare at A726. | ||||||
| A6E0 | LD HL,$6108 | HL=Object_Slot_1. | ||||||
| A6E3 | LD B,$01 | Set a slot counter in B for 01 loop. | ||||||
| A6E5 | CALL Handler_PlayerShot_ScanSlot | Call Handler_PlayerShot_ScanSlot. | ||||||
|
Test the object slot at Object_Slot_3 with a hit height of 18.
|
||||||||
| A6E8 | LD A,$18 | A=18. | ||||||
| A6EA | LD ($A726),A | Write it over the hit-height compare at A726. | ||||||
| A6ED | LD HL,$6138 | HL=Object_Slot_3. | ||||||
| A6F0 | LD B,$01 | Set a slot counter in B for 01 loop. | ||||||
|
Test every slot in this group that is in use.
|
||||||||
| Handler_PlayerShot_ScanSlot | A6F2 | LD A,(HL) | Fetch the slot type. | |||||
| A6F3 | AND A | Test it. | ||||||
| A6F4 | PUSH BC | Stash BC, DE and HL on the stack. | ||||||
| A6F5 | PUSH DE | |||||||
| A6F6 | PUSH HL | |||||||
| A6F7 | CALL NZ,Handler_PlayerShot_CompareBox | Call Handler_PlayerShot_CompareBox if the slot is in use. | ||||||
| A6FA | POP HL | Restore HL, DE and BC from the stack. | ||||||
| A6FB | POP DE | |||||||
| A6FC | POP BC | |||||||
| A6FD | ADD HL,DE | Move onto the next slot. | ||||||
| A6FE | DJNZ Handler_PlayerShot_ScanSlot | Decrease the slot counter by one and loop back to Handler_PlayerShot_ScanSlot until every slot has been tested. | ||||||
| A700 | RET | Return. | ||||||
|
Compare this slot's box against the shot.
|
||||||||
| Handler_PlayerShot_CompareBox | A701 | INC HL | Move onto the slot world X. | |||||
| A702 | INC HL | |||||||
| A703 | EX DE,HL | Switch the slot pointer into DE. | ||||||
| A704 | LD A,(DE) | Fetch the world X. | ||||||
| A705 | INC DE | Move onto the high byte. | ||||||
| A706 | LD C,A | Copy the low byte into C. | ||||||
| A707 | LD A,(DE) | Fetch the high byte. | ||||||
| A708 | INC DE | Move onto the Y. | ||||||
| A709 | LD B,A | Copy the high byte into B. | ||||||
| A70A | LD HL,$0008 | HL=0008. | ||||||
| A70D | ADD HL,BC | Add the box offset. | ||||||
|
Check the shot is horizontally within reach of the slot.
|
||||||||
| A70E | LD C,(IX+$02) | Fetch the shot world X. | ||||||
| A711 | LD B,(IX+$03) | Fetch the shot world X high byte. | ||||||
| A714 | AND A | Clear the carry flag. | ||||||
| A715 | SBC HL,BC | Subtract the shot world X. | ||||||
| A717 | LD A,H | Fetch the high byte of the difference. | ||||||
| A718 | AND %00011111 | Keep only bits 0-4. | ||||||
| A71A | RET NZ | Return if they are on different screens. | ||||||
| A71B | LD A,L | Fetch the low byte. | ||||||
| A71C | CP $10 | Return if it is at least 10. | ||||||
| A71E | RET NC | |||||||
|
Check the shot is vertically within reach of the slot.
|
||||||||
| A71F | LD A,(DE) | Fetch the slot Y. | ||||||
| A720 | ADD A,$04 | Add 04. | ||||||
| A722 | SUB (IX+$04) | Subtract the shot Y. | ||||||
| A725 | CP $18 | Compare it against the current hit height. | ||||||
| A727 | RET NC | Return if the shot missed. | ||||||
|
Set the slot's explode flag, clear the shot and stop testing.
|
||||||||
| A728 | EX DE,HL | Switch the slot pointer into HL. | ||||||
| A729 | LD BC,$000C | Point HL at the explode flag. | ||||||
| A72C | ADD HL,BC | |||||||
| A72D | SET 0,(HL) | Set bit 0 of the explode flag. | ||||||
| A72F | CALL ClearMaskScratch | Call ClearMaskScratch. | ||||||
| A732 | LD (IX+$00),$00 | Write 00 to the shot type. | ||||||
| A736 | POP HL | Discard the stacked return addresses and saved registers. | ||||||
| A737 | POP HL | |||||||
| A738 | POP HL | |||||||
| A739 | POP HL | |||||||
| A73A | POP HL | |||||||
| A73B | RET | Return. | ||||||
| Prev: A53A | Up: Map | Next: A73C |