Prev: D014 Up: Map Next: D202
D037: Move Entity
Used by the routines at SettlePlayer, RunFrame and UpdateEntity.
Moves an entity for one frame, which is used for all of the types of entity that move. The entity is moved along its heading by the speed in fields 12-15 changed by its direction vector from GetDirectionVector, and the vertical speed in fields 12 and 13 is applied to the height. Purpose of the individual steps is not yet known.
Input
IX The entity
Return if the entity is not in use, and hand over to FollowPath if it is following a path.
MoveEntity D037 LD A,(IX+$00) Fetch the type of the entity.
D03A AND A Test it.
D03B RET Z Return if the entity is not in use.
D03C LD A,(IX+$24) Fetch the first byte of the path of the entity.
D03F OR (IX+$25) Combine it with the second byte.
D042 JP NZ,FollowPath Jump to FollowPath to follow the path if the entity has one.
Return if the sprite of the entity has not been set up, and note whether the entity is fast.
D045 LD A,(IX+$16) Fetch the width of the sprite.
D048 AND %11110000 Use bits 4-7.
D04A RET NZ Return if any of them are set.
D04B LD A,(IX+$17) Fetch the height of the sprite.
D04E AND %11000000 Use bits 6-7.
D050 RET NZ Return if any of them are set.
D051 LD A,(IX+$10) Fetch the speed of the entity.
D054 SUB $50 Subtract 50.
D056 JR NC,MoveEntity_Fast Jump to MoveEntity_Fast if the speed is at least 50.
D058 RES 7,(IX+$1E) Clear bit 7 of the flags of the entity.
D05C JR MoveEntity_Position Jump to MoveEntity_Position.
MoveEntity_Fast D05E SET 7,(IX+$1E) Set bit 7 of the flags of the entity.
Copy the position of the entity into the code that tests its collisions and the code at the end of this routine, which use it as the position that the entity started the frame at.
MoveEntity_Position D062 LD H,(IX+$02) Fetch the x coordinate of the entity.
D065 LD L,(IX+$03)
D068 LD ($D457),HL Store it in the collision code.
D06B LD H,(IX+$05) Fetch the y coordinate of the entity.
D06E LD L,(IX+$06)
D071 LD ($D466),HL Store it in the collision code.
D074 LD H,(IX+$08) Fetch the z coordinate of the entity.
D077 LD L,(IX+$09)
D07A LD ($D1F5),HL Store it in the instruction at D1F4, as the height that the entity started the frame at.
Change the speed of the entity. If the entity is not moving then the speed falls, and if it is moving then the speed rises, one step at a time, to the maximum.
D07D BIT 7,(IX+$11) Test bit 7 of the heading of the entity.
D081 LD A,(IX+$1A) Fetch the fraction of the speed.
D084 JR NZ,MoveEntity_Moving Jump to MoveEntity_Moving if the entity is moving.
D086 SUB (IX+$1B) Subtract the rate of change from the fraction.
D089 LD (IX+$1A),A Store the fraction.
D08C JP NC,MoveEntity_Speed Jump to MoveEntity_Speed if there was no step down.
D08F LD A,(IX+$10) Fetch the speed of the entity and keep it in B.
D092 LD B,A
D093 AND %11110000 Keep the maximum speed in bits 4-7.
D095 LD E,A Keep it in E.
D096 LD A,B Fetch the speed again.
D097 AND %00001111 Keep the current speed in bits 0-3.
D099 SUB $01 Take one away.
D09B JR C,MoveEntity_ZeroSpeed Jump to MoveEntity_ZeroSpeed if the speed was zero already.
D09D OR E Add the maximum speed.
D09E LD (IX+$10),A Store the new speed.
D0A1 JP MoveEntity_Speed Jump to MoveEntity_Speed.
MoveEntity_ZeroSpeed D0A4 LD (IX+$10),E Store the maximum speed as the speed, with the current speed zero.
D0A7 LD (IX+$1A),$00 Set the fraction of the speed to 00.
D0AB JP MoveEntity_Speed Jump to MoveEntity_Speed.
MoveEntity_Moving D0AE ADD A,(IX+$1B) Add the rate of change to the fraction.
D0B1 LD (IX+$1A),A Store the fraction.
D0B4 LD B,(IX+$10) Fetch the speed of the entity.
D0B7 JR C,MoveEntity_StepUp Jump to MoveEntity_StepUp if there was a step up.
D0B9 LD A,B Fetch the speed again.
D0BA RRCA Move the maximum speed down to bits 0-3.
D0BB RRCA
D0BC RRCA
D0BD RRCA
D0BE XOR B Compare it with the current speed.
D0BF AND %00001111 Use bits 0-3.
D0C1 JR NZ,MoveEntity_Speed Jump to MoveEntity_Speed if the current speed has not reached the maximum.
D0C3 LD (IX+$1A),A Set the fraction of the speed to zero.
D0C6 JR MoveEntity_Speed Jump to MoveEntity_Speed.
MoveEntity_StepUp D0C8 LD A,B Fetch the speed.
D0C9 AND %11110000 Keep the maximum speed in bits 4-7.
D0CB LD E,A Keep it in E.
D0CC RRCA Move the maximum speed down to bits 0-3...
D0CD RRCA
D0CE RRCA
D0CF RRCA
D0D0 LD C,A ...and keep it in C.
D0D1 LD A,B Fetch the speed again.
D0D2 AND %00001111 Keep the current speed in bits 0-3.
D0D4 INC A Add one.
D0D5 CP C Compare it with the maximum speed.
D0D6 JR C,MoveEntity_StoreSpeed Jump to MoveEntity_StoreSpeed if it is below the maximum.
D0D8 LD A,C Limit it to the maximum.
MoveEntity_StoreSpeed D0D9 OR E Add the maximum speed in bits 4-7.
D0DA LD (IX+$10),A Store the new speed.
Change the vertical speed of the entity by its acceleration, limit it, and move the entity up or down by it.
MoveEntity_Speed D0DD LD H,(IX+$12) Fetch the vertical speed of the entity.
D0E0 LD L,(IX+$13)
D0E3 LD D,(IX+$14) Fetch the acceleration of the entity.
D0E6 LD E,(IX+$15)
D0E9 LD A,H Combine the four bytes.
D0EA OR L
D0EB OR D
D0EC OR E
D0ED JP Z,MoveEntity_Heading Jump to MoveEntity_Heading if the entity is neither moving vertically nor accelerating.
D0F0 ADD HL,DE Add the acceleration to the vertical speed.
D0F1 BIT 7,H Jump to MoveEntity_Falling if the entity is moving down.
D0F3 JR NZ,MoveEntity_Falling
D0F5 LD A,(IX+$1C) Fetch the limit of the vertical speed from field 1C.
D0F8 AND %00001111 Use bits 0-3.
D0FA DEC A Take one away.
D0FB CP H Compare it with the high byte of the vertical speed.
D0FC JR NC,MoveEntity_Height Jump to MoveEntity_Height if the speed is within the limit.
D0FE INC A Add one back.
D0FF LD H,A Limit the vertical speed to the limit...
D100 LD L,$00 ...with no fraction.
D102 JR MoveEntity_Height Jump to MoveEntity_Height.
MoveEntity_Falling D104 LD A,(IX+$1C) Fetch the limit of the vertical speed from field 1C.
D107 AND %00001111 Use bits 0-3.
D109 CPL Make it negative, for moving down.
D10A CP H Compare it with the high byte of the vertical speed.
D10B JR C,MoveEntity_Height Jump to MoveEntity_Height if the speed is within the limit.
D10D INC A Add one back.
D10E LD H,A Limit the vertical speed to the limit...
D10F LD L,$00 ...with no fraction.
MoveEntity_Height D111 LD (IX+$12),H Store the vertical speed.
D114 LD (IX+$13),L
D117 LD D,(IX+$09) Fetch the z coordinate of the entity.
D11A LD E,(IX+$0A)
D11D LD C,(IX+$08)
D120 CALL AddDisplacement Add the vertical speed to the z coordinate.
D123 LD (IX+$09),H Store the new z coordinate.
D126 LD (IX+$0A),L
D129 LD (IX+$08),C
Set the entity going in the direction that it is heading. If the heading has changed, centre the entity within its cell on each axis.
MoveEntity_Heading D12C LD A,(IX+$22) Fetch the heading that the entity had.
D12F AND %00111111 Use bits 0-5.
D131 LD B,A Keep it in B.
D132 LD A,(IX+$11) Fetch the heading of the entity.
D135 AND %00111111 Use bits 0-5.
D137 CP B Compare it with the old heading.
D138 JR Z,MoveEntity_StoreHeading Jump to MoveEntity_StoreHeading if it has not changed.
D13A LD (IX+$04),$7F Set the fraction of the x coordinate to 7F.
D13E LD (IX+$07),$7F Set the fraction of the y coordinate to 7F.
MoveEntity_StoreHeading D142 LD B,A Keep the heading in B.
D143 LD A,(IX+$22) Fetch the old heading, with its flag.
D146 AND %01000000 Keep bit 6.
D148 OR B Combine it with the heading.
D149 LD (IX+$22),A Store it as the heading that the entity has.
Work out the distance to move, from the speed, and the amount of it along each axis from the direction vector of the heading.
D14C LD H,(IX+$10) Fetch the speed of the entity into H...
D14F LD L,(IX+$1A) ...and the fraction of the speed into L.
D152 ADD HL,HL Multiply the speed by sixteen.
D153 ADD HL,HL
D154 ADD HL,HL
D155 ADD HL,HL
D156 LD A,(IX+$00) Fetch the type of the entity.
D159 DEC A Take one away.
D15A CALL Z,LimitDisplacement Limit the distance if the entity is the player.
D15D LD ($5CEA),HL Store the distance.
D160 LD A,(IX+$11) Fetch the heading of the entity.
D163 CALL GetDirectionVector Get the direction vector of the heading.
D166 PUSH BC Keep the first part of the vector.
D167 EXX Switch to the alternate registers.
D168 POP BC Take the first part of the vector off the stack.
D169 CALL ScaleDisplacement Work out the displacement along the x axis.
D16C LD A,(IX+$00) Fetch the type of the entity.
D16F DEC A Take one away.
D170 JR NZ,MoveEntity_First Jump to MoveEntity_First unless the entity is the player.
D172 LD B,(IX+$10) Fetch the speed of the player.
D175 LD A,(IX+$1E) Fetch the flags of the player, which hold the change of the drift.
D178 CALL UpdateDrift Change the drift, and limit the displacement.
MoveEntity_First D17B LD D,(IX+$03) Fetch the x coordinate of the entity.
D17E LD E,(IX+$04)
D181 LD C,(IX+$02)
D184 CALL AddDisplacement Add the displacement to the x coordinate.
D187 LD (IX+$02),C Store the new x coordinate.
D18A LD (IX+$04),L
D18D LD (IX+$03),H
D190 EXX Switch to the alternate registers.
D191 PUSH HL Save the displacement along the y axis.
D192 EXX Switch to the alternate registers.
D193 POP BC Restore it into BC.
D194 CALL ScaleDisplacement Work out the displacement along the y axis.
D197 LD A,(IX+$00) Fetch the type of the entity.
D19A DEC A Take one away.
D19B JR NZ,MoveEntity_Second Jump to MoveEntity_Second unless the entity is the player.
D19D LD B,(IX+$10) Fetch the speed of the player.
D1A0 LD A,(IX+$1E) Fetch the flags of the player, which hold the change of the drift.
D1A3 RRA Shift the part that is for the y axis down to bits 0-2.
D1A4 RRA
D1A5 RRA
D1A6 INC IX Use the next field of the entity.
D1A8 CALL UpdateDrift Change the drift, and limit the displacement.
D1AB DEC IX Use the first field of the entity again.
MoveEntity_Second D1AD LD D,(IX+$06) Fetch the y coordinate of the entity.
D1B0 LD E,(IX+$07)
D1B3 LD C,(IX+$05)
D1B6 CALL AddDisplacement Add the displacement to the y coordinate.
D1B9 LD (IX+$05),C Store the new y coordinate.
D1BC LD (IX+$07),L
D1BF LD (IX+$06),H
Note that the entity has moved, and check what it has collided with.
D1C2 LD A,(IX+$1E) Fetch the flags of the entity.
D1C5 AND %11000000 Use bits 6-7.
D1C7 OR %01000000 Set bit 6, to show that it has moved.
D1C9 LD (IX+$1E),A Store the flags.
D1CC LD (IX+$1F),$FF Set field 1F of the entity to FF.
D1D0 BIT 6,(IX+$01) Test bit 6 of the frame of the entity.
D1D4 RET NZ Return if it is set.
D1D5 LD A,(IX+$00) Fetch the type of the entity.
D1D8 CP $09 Jump to MoveEntity_TestCollisions unless it is a shot.
D1DA JR NZ,MoveEntity_TestCollisions
D1DC XOR A Set the vertical speed of the shot to zero.
D1DD LD (IX+$12),A
MoveEntity_TestCollisions D1E0 CALL TestEntityCollisions Test the collisions of the entity.
D1E3 LD A,(IX+$00) Fetch the type of the entity.
D1E6 AND A Test it.
D1E7 RET Z Return if the entity has been removed.
D1E8 CP $05 Compare the type with 05.
D1EA LD A,$FF Set the height to test to FF.
D1EC JR Z,MoveEntity_TestCells Jump to MoveEntity_TestCells if the type is 05.
D1EE LD H,(IX+$08) Fetch the z coordinate of the entity.
D1F1 LD L,(IX+$09)
D1F4 LD DE,$0000 Set DE to the height that the entity started at, which is patched in.
D1F7 SBC HL,DE Subtract it to find how far the entity has risen.
D1F9 DEC HL Take one away.
D1FA LD A,L Keep the low byte.
MoveEntity_TestCells D1FB LD ($DAB2),A Store it in the code that tests the cells.
D1FE CALL TestEntityCells Test the cells that the entity is in.
D201 RET Return.
Prev: D014 Up: Map Next: D202