Prev: 9DC0 Up: Map Next: 9ECA
9E2C: Animate: Laser Beam
XOR the four beam pulses onto the screen and drop the slot when they have all expired.
Input
IX Actor slot
LaserBeam_Animate 9E2C CALL TestLaserHits Call TestLaserHits.
9E2F LD D,(IX+$01) Fetch the beam Y.
9E32 LD A,(IX+$02) Fetch pulse 01.
9E35 BIT 2,A Jump to LaserBeam_Animate_WalkPulses if bit 2 is reset.
9E37 JR Z,LaserBeam_Animate_WalkPulses
Move pulse 01 on and invert the screen byte there.
9E39 LD L,A Copy the pulse X into L.
9E3A LD A,$08 A=08.
9E3C BIT 0,L Jump to LaserBeam_Animate_StepX if bit 0 of the pulse X is reset.
9E3E JR Z,LaserBeam_Animate_StepX
9E40 NEG Negate the step.
Add the step to pulse 01 and find the screen byte there.
LaserBeam_Animate_StepX 9E42 ADD A,L Add the step to the pulse X.
9E43 LD E,A Copy the new X into E.
9E44 LD H,D Copy the beam Y into H.
9E45 PUSH HL Stash the beam position on the stack.
9E46 CALL ScreenAddress Call ScreenAddress.
9E49 LD (IX+$02),E Write the new X back as pulse 01.
Invert the screen byte, then find the attribute square.
9E4C LD A,$FF A=FF.
9E4E XOR (HL) Invert the screen byte.
9E4F LD (HL),A Write it back.
9E50 POP HL Restore the beam position from the stack.
9E51 CALL AttributeAddress Call AttributeAddress.
Colour the attribute square, then count the beam timer down.
9E54 LD A,(IX+$07) Fetch the beam colour.
9E57 LD (HL),A Write it to the attribute square.
9E58 LD A,(IX+$06) Fetch the beam timer.
9E5B SUB $08 Subtract 08.
9E5D LD (IX+$06),A Write it back.
9E60 AND %11111000 Keep only bits 3-7.
9E62 JR NZ,LaserBeam_Animate_WalkPulses Jump to LaserBeam_Animate_WalkPulses if any of those bits remain.
9E64 RES 2,(IX+$02) Reset bit 2 of pulse 01.
Set up the pixel masks in the shadow registers, then walk pulses 02-04.
LaserBeam_Animate_WalkPulses 9E68 EXX Switch to the shadow registers.
9E69 LD BC,$031C BC'=031C.
9E6C LD E,$E0 E'=E0.
9E6E EXX Switch back to the main registers.
9E6F LD E,$03 E=03.
9E71 PUSH IX Copy the slot pointer into BC (using the stack).
9E73 POP BC
9E74 INC BC Move BC onto pulse 02.
9E75 INC BC
9E76 INC BC
Walk the pulses, skipping any on pulse 01's character column.
LaserBeam_Animate_Loop 9E77 LD A,(BC) Fetch this pulse X.
9E78 XOR (IX+$02) Compare it against pulse 01.
9E7B AND %11111000 Keep only bits 3-7.
9E7D JR NZ,LaserBeam_Animate_TestBit Jump to LaserBeam_Animate_TestBit if the pulses are not on the same character column.
9E7F EXX Switch to the shadow registers.
9E80 LD A,B Rotate the mask bytes.
9E81 LD B,C
9E82 LD C,E
9E83 EXX Switch back to the main registers.
9E84 INC BC Move onto the next pulse.
9E85 DEC E Decrease the pulse counter by one.
9E86 JR NZ,LaserBeam_Animate_Loop Jump back to LaserBeam_Animate_Loop if any pulses remain.
Free the actor slot once every pulse has been skipped.
9E88 LD (IX+$00),$00 Write 00 to the slot type.
9E8C RET Return.
If this pulse is not moving yet, wait on the beam timer and then start it.
LaserBeam_Animate_TestBit 9E8D LD A,(BC) Fetch this pulse X.
9E8E BIT 2,A Jump to LaserBeam_Animate_DrawPulse if bit 2 is set.
9E90 JR NZ,LaserBeam_Animate_DrawPulse
Count the beam timer down and return until its low bits reach zero.
9E92 DEC (IX+$06) Decrease the beam timer by one.
9E95 LD A,(IX+$06) Fetch the beam timer.
9E98 AND %00000111 Keep only bits 0-2.
9E9A RET NZ Return if the timer is still running.
Fold bits 0-1 of RandomNumber into the beam timer and start this pulse moving.
9E9B LD A,($5E40) Fetch RandomNumber.
9E9E AND %00000011 Keep only bits 0-1.
9EA0 OR %00000100 Set bit 2.
9EA2 OR (IX+$06) Merge in the beam timer.
9EA5 LD (IX+$06),A Write it back.
9EA8 LD A,(BC) Fetch this pulse X.
9EA9 OR %00000100 Set bit 2.
9EAB LD (BC),A Write it back.
9EAC RET Return.
Move this pulse on and XOR its mask onto the screen.
LaserBeam_Animate_DrawPulse 9EAD LD A,(BC) Fetch this pulse X.
9EAE LD L,A Copy it into L.
9EAF LD A,$08 A=08.
9EB1 BIT 0,L Jump to LaserBeam_Animate_AdvancePulse if bit 0 of the pulse X is reset.
9EB3 JR Z,LaserBeam_Animate_AdvancePulse
9EB5 NEG Negate the step.
LaserBeam_Animate_AdvancePulse 9EB7 ADD A,L Add the step to the pulse X.
9EB8 LD (BC),A Write the new X back.
Draw this pulse by XORing its mask onto the screen byte.
9EB9 LD H,D Copy the beam Y into H.
9EBA CALL ScreenAddress Call ScreenAddress.
9EBD EXX Switch to the shadow registers.
9EBE LD A,B Rotate the mask bytes.
9EBF LD B,C
9EC0 LD C,E
9EC1 EXX Switch back to the main registers.
9EC2 XOR (HL) Flip the screen pixels that are set in the mask in A, so the pulse is drawn, or erased if it is already there.
9EC3 LD (HL),A Write it back.
9EC4 INC BC Move onto the next pulse.
9EC5 DEC E Decrease the pulse counter by one.
9EC6 JP NZ,LaserBeam_Animate_Loop Jump back to LaserBeam_Animate_Loop if any pulses remain.
9EC9 RET Return.
View the equivalent code in;
Prev: 9DC0 Up: Map Next: 9ECA