Prev: 42298 Up: Map Next: 42812
42361: Handler: Player Shot
On a 1-in-4 frame, spawn a shot into a free laser slot when FIRE is held, then fly any live shots.
Input
IX Actor slot
Handler_PlayerShot 42361 LD A,(24130) Fetch GameTimer.
42364 AND %00000011 Keep only bits 0-1.
42366 RET NZ Return if this is not a 4th frame.
42367 CALL HandlerControls Call HandlerControls.
42370 BIT 4,A Return if FIRE is not pressed.
42372 RET NZ
Look for a free laser slot.
42373 LD HL,24576 HL=Laser_Parameter_1.
42376 LD DE,24 DE=0024.
42379 LD B,2 Set a slot counter in B for 2 loops.
Handler_PlayerShot_Loop 42381 LD A,(HL) Jump to Handler_PlayerShot_Initialise if this slot is free.
42382 AND A
42383 JR Z,Handler_PlayerShot_Initialise
42385 ADD HL,DE Move onto the next slot.
42386 DJNZ Handler_PlayerShot_Loop Decrease the slot counter by one and loop back to Handler_PlayerShot_Loop until both slots have been tried.
42388 RET Return.
Initialise a new shot from the current actor.
Handler_PlayerShot_Initialise 42389 PUSH HL Stash the free slot on the stack.
42390 CALL Copy_Explosion_Template Call Copy_Explosion_Template.
42393 POP HL Restore the free slot from the stack.
42394 LD (HL),88 Write type 88.
42396 INC HL Move onto the new world X.
42397 INC HL
42398 EX DE,HL Switch the destination into DE.
Look up this actor's entry in the shot table at Handler_PlayerShot_Table.
42399 LD A,(IX+0) Fetch the actor type.
42402 RLCA Rotate it left twice.
42403 RLCA
42404 AND %00111100 Keep only bits 2-5.
42406 LD C,A Create an offset in BC.
42407 LD B,0
42409 LD HL,42635 HL=Handler_PlayerShot_Table.
42412 ADD HL,BC Add the offset.
Add the table X offset to the actor world X.
42413 LD A,(HL) Fetch the X offset.
42414 LD B,0 Clear B.
42416 AND A Jump to Handler_PlayerShot_AddWorldX if the offset is positive.
42417 JP P,Handler_PlayerShot_AddWorldX
42420 DEC B Sign-extend into B.
Handler_PlayerShot_AddWorldX 42421 ADD A,(IX+2) Add the actor world X.
42424 INC HL Move onto the next table byte.
42425 LD (DE),A Write the new world X.
42426 INC DE Move onto the high byte.
Work out the high byte of the new world X and the new Y.
42427 LD A,(IX+3) Fetch the actor world X high byte.
42430 ADC A,B Add the sign.
42431 AND %00011111 Keep only bits 0-4.
42433 LD (DE),A Write the high byte.
42434 INC DE Move onto the new Y.
42435 LD A,(IX+4) Fetch the actor Y.
42438 ADD A,(HL) Add the table Y offset.
42439 INC HL Move onto the next table byte.
Write the remaining shot fields and clear the rest of the slot.
Handler_PlayerShot_WriteFields 42440 LD (DE),A Write the new Y.
42441 INC DE Move onto the speed.
42442 LD A,(HL) Copy the next table byte.
42443 INC HL
42444 LD (DE),A Write it and move on.
42445 INC DE
42446 LD A,(HL) Copy the next table byte.
42447 INC HL
42448 LD (DE),A Write it and move on.
42449 INC DE
Pick the shot colour from the timer at RandomNumber.
42450 LD A,(24128) Fetch RandomNumber.
42453 AND %00000011 Keep only bits 0-1.
42455 LD BC,42479 Point BC at the shot colour table at Handler_PlayerShot_Colours.
42458 ADD A,C Add the colour index.
42459 LD C,A Copy the low byte into C.
42460 LD A,B Fetch the high byte.
42461 ADC A,0 Add the carry.
42463 LD B,A Write it back to B.
42464 LD A,(BC) Fetch the colour.
42465 LD (DE),A Write it to the shot colour.
42466 INC DE Move onto the next field.
42467 LD A,32 A=32.
42469 LD (DE),A Write it.
42470 INC DE Move on.
Clear the remaining 15 bytes of the slot.
42471 LD B,15 Set a byte counter in B for 15 loops.
42473 XOR A Clear A.
Handler_PlayerShot_ClearTail 42474 LD (DE),A Write 0.
42475 INC DE Move onto the next byte.
42476 DJNZ Handler_PlayerShot_ClearTail Decrease the byte counter by one and loop back to Handler_PlayerShot_ClearTail until the slot tail is clear.
42478 RET Return.
The four colours a player shot can be.
Handler_PlayerShot_Colours 42479 DEFB 68 INK:GREEN, PAPER:BLACK (BRIGHT).
The four colours a player shot can be.
42480 DEFB 69 INK:CYAN, PAPER:BLACK (BRIGHT).
The four colours a player shot can be.
42481 DEFB 70 INK:YELLOW, PAPER:BLACK (BRIGHT).
The four colours a player shot can be.
42482 DEFB 71 INK:WHITE, PAPER:BLACK (BRIGHT).
Advance the shot world X from the packed nibble at *IX+16.
Handler_PlayerShot_AdvanceX 42483 ADD A,(IX+16) Add the X nibble.
42486 LD C,A Stash the sum in C.
42487 AND %00001111 Keep only bits 0-3.
42489 LD (IX+16),A Write it back as the X nibble.
42492 LD A,C Copy the sum into A.
42493 RRCA Rotate the high nibble down into bits 0-3.
42494 RRCA
42495 RRCA
42496 RRCA
42497 AND %00001111 Keep only bits 0-3.
42499 LD B,0 Clear B.
42501 JR Handler_PlayerShot_WriteX Jump to Handler_PlayerShot_WriteX.
Advance the shot Y from the packed nibble at *IX+17.
Handler_PlayerShot_AdvanceY 42503 ADD A,(IX+17) Add the Y nibble.
42506 LD C,A Stash the sum in C.
42507 AND %00001111 Keep only bits 0-3.
42509 LD (IX+17),A Write it back as the Y nibble.
42512 LD A,C Copy the sum into A.
42513 RRCA Rotate the high nibble down into bits 0-3.
42514 RRCA
42515 RRCA
42516 RRCA
42517 AND %00001111 Keep only bits 0-3.
42519 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 42521 DEC (IX+8) Decrease the shot timer by one.
42524 JP Z,StartSmallExplosion Jump to StartSmallExplosion if it has expired.
42527 LD A,(IX+5) Fetch the shot speed.
42530 AND A Jump to Handler_PlayerShot_AdvanceX if the speed is positive.
42531 JP P,Handler_PlayerShot_AdvanceX
Work out a negative X step when the speed is negative.
42534 ADD A,(IX+16) Add the X nibble.
42537 LD C,A Stash the sum in C.
42538 AND %00001111 Keep only bits 0-3.
42540 NEG Negate it.
42542 LD (IX+16),A Write it back as the X nibble.
42545 LD A,C Copy the sum into A.
42546 NEG Negate it.
42548 RRCA Rotate the high nibble down into bits 0-3.
42549 RRCA
42550 RRCA
42551 RRCA
42552 AND %00001111 Keep only bits 0-3.
42554 NEG Negate it.
42556 LD B,255 B=255.
Add the X step to the shot's world X.
Handler_PlayerShot_WriteX 42558 ADD A,(IX+2) Add the step to the world X.
42561 LD (IX+2),A Write it back.
42564 LD A,(IX+3) Fetch the high byte.
42567 ADC A,B Add the sign.
42568 AND %00011111 Keep only bits 0-4.
42570 LD (IX+3),A Write the high byte back.
Work out the Y step from the shot thrust.
42573 LD A,(IX+6) Fetch the shot thrust.
42576 AND A Jump to Handler_PlayerShot_AdvanceY if the thrust is positive.
42577 JP P,Handler_PlayerShot_AdvanceY
Work out a negative Y step when the thrust is negative.
42580 ADD A,(IX+17) Add the Y nibble.
42583 LD C,A Stash the sum in C.
42584 AND %00001111 Keep only bits 0-3.
42586 NEG Negate it.
42588 LD (IX+17),A Write it back as the Y nibble.
42591 LD A,C Copy the sum into A.
42592 NEG Negate it.
42594 RRCA Rotate the high nibble down into bits 0-3.
42595 RRCA
42596 RRCA
42597 RRCA
42598 AND %00001111 Keep only bits 0-3.
42600 NEG Negate it.
Handler_PlayerShot_WriteY 42602 ADD A,(IX+4) Add the step to the shot Y.
Destroy the shot if it hits the ground or leaves the play area.
42605 CP 175 Compare it against 175.
42607 JP NC,StartSmallExplosion Jump to StartSmallExplosion if the shot is on the ground.
42610 CP 48 Compare it against 48.
42612 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.
42615 LD (IX+4),A Write the new Y.
42618 LD A,(IX+0) Fetch the shot type.
42621 XOR %00000001 Flip bit 0.
42623 LD (IX+0),A Write it back.
42626 CALL DrawObjectSprite Call DrawObjectSprite.
42629 CALL ColouriseSprite Call ColouriseSprite.
42632 JP Handler_PlayerShot_TestSlots Jump to Handler_PlayerShot_TestSlots.
Handler_PlayerShot_Table 42635 DEFB 248,252,192,0,248,249,196,250 Shot table. Each 4-byte entry holds an X offset, a Y offset, a speed and a thrust.
42643 DEFB 249,246,199,227,249,244,202,222
42651 DEFB 252,242,211,211,255,240,219,204
42659 DEFB 1,240,227,199,3,238,234,196
42667 DEFB 16,252,64,0,16,249,60,250
42675 DEFB 16,245,57,227,15,243,54,222
42683 DEFB 12,242,45,211,9,240,37,204
42691 DEFB 8,239,29,199,5,237,22,196
Test the shot against the alien and object slots.
Handler_PlayerShot_TestSlots 42699 LD A,24 A=24.
42701 LD (42790),A Write it over the hit-height compare at 42790.
42704 LD HL,25008 HL=Alien_Slot_1.
42707 LD DE,24 DE=0024.
42710 LD B,6 Set a slot counter in B for 6 loops.
42712 CALL Handler_PlayerShot_ScanSlot Call Handler_PlayerShot_ScanSlot.
Test the object slot at Object_Slot_1 with a hit height of 12.
42715 LD A,12 A=12.
42717 LD (42790),A Write it over the hit-height compare at 42790.
42720 LD HL,24840 HL=Object_Slot_1.
42723 LD B,1 Set a slot counter in B for 1 loop.
42725 CALL Handler_PlayerShot_ScanSlot Call Handler_PlayerShot_ScanSlot.
Test the object slot at Object_Slot_3 with a hit height of 24.
42728 LD A,24 A=24.
42730 LD (42790),A Write it over the hit-height compare at 42790.
42733 LD HL,24888 HL=Object_Slot_3.
42736 LD B,1 Set a slot counter in B for 1 loop.
Test every slot in this group that is in use.
Handler_PlayerShot_ScanSlot 42738 LD A,(HL) Fetch the slot type.
42739 AND A Test it.
42740 PUSH BC Stash BC, DE and HL on the stack.
42741 PUSH DE
42742 PUSH HL
42743 CALL NZ,Handler_PlayerShot_CompareBox Call Handler_PlayerShot_CompareBox if the slot is in use.
42746 POP HL Restore HL, DE and BC from the stack.
42747 POP DE
42748 POP BC
42749 ADD HL,DE Move onto the next slot.
42750 DJNZ Handler_PlayerShot_ScanSlot Decrease the slot counter by one and loop back to Handler_PlayerShot_ScanSlot until every slot has been tested.
42752 RET Return.
Compare this slot's box against the shot.
Handler_PlayerShot_CompareBox 42753 INC HL Move onto the slot world X.
42754 INC HL
42755 EX DE,HL Switch the slot pointer into DE.
42756 LD A,(DE) Fetch the world X.
42757 INC DE Move onto the high byte.
42758 LD C,A Copy the low byte into C.
42759 LD A,(DE) Fetch the high byte.
42760 INC DE Move onto the Y.
42761 LD B,A Copy the high byte into B.
42762 LD HL,8 HL=0008.
42765 ADD HL,BC Add the box offset.
Check the shot is horizontally within reach of the slot.
42766 LD C,(IX+2) Fetch the shot world X.
42769 LD B,(IX+3) Fetch the shot world X high byte.
42772 AND A Clear the carry flag.
42773 SBC HL,BC Subtract the shot world X.
42775 LD A,H Fetch the high byte of the difference.
42776 AND %00011111 Keep only bits 0-4.
42778 RET NZ Return if they are on different screens.
42779 LD A,L Fetch the low byte.
42780 CP 16 Return if it is at least 16.
42782 RET NC
Check the shot is vertically within reach of the slot.
42783 LD A,(DE) Fetch the slot Y.
42784 ADD A,4 Add 4.
42786 SUB (IX+4) Subtract the shot Y.
42789 CP 24 Compare it against the current hit height.
42791 RET NC Return if the shot missed.
Set the slot's explode flag, clear the shot and stop testing.
42792 EX DE,HL Switch the slot pointer into HL.
42793 LD BC,12 Point HL at the explode flag.
42796 ADD HL,BC
42797 SET 0,(HL) Set bit 0 of the explode flag.
42799 CALL ClearMaskScratch Call ClearMaskScratch.
42802 LD (IX+0),0 Write 0 to the shot type.
42806 POP HL Discard the stacked return addresses and saved registers.
42807 POP HL
42808 POP HL
42809 POP HL
42810 POP HL
42811 RET Return.
Prev: 42298 Up: Map Next: 42812