Prev: 8FCA Up: Map Next: 90CC
900A: Check Obstacles
Used by the routine at ControlPlayer.
Checks whether an entity would hit one of the items in the room if it moved along each axis. This is the same as CheckRoomBounds, but for each of the items in the list for the room (see DrawRoom) whose attribute does not have bit 3 set. The position that the entity would move to is tested against a rectangle for the item. The byte at offset 06 of the item gives the left side in its top four bits (signed) and the width in its bottom four bits, and the byte at offset 07 gives the top and the height in the same way, all in units of four pixels. If the position is in the rectangle then the flag for the axis in offset 02 of the entity is set if the attribute of the item has bit 2 set, and cleared if it does not.
Input
DE The pixels to move (X in E and Y in D)
IX The entity
CheckObstacles 900A PUSH DE Stash the moves on the stack.
900B LD A,E Fetch the X move.
900C ADD A,(IX+$03) Add the X position of the entity.
900F LD E,A Keep the new X position in E.
9010 LD D,(IX+$04) Fetch the Y position of the entity.
9013 LD A,$10 A=10 (the flag for the X axis).
9015 EX AF,AF' Save the flag for the axis in AF'.
9016 CALL CheckObstacles_Position Call CheckObstacles_Position to test the position against the items for the room.
9019 POP DE Restore the moves from the stack.
901A PUSH DE Stash it on the stack again.
901B LD E,(IX+$03) Fetch the X position of the entity.
901E LD A,D Fetch the Y move.
901F ADD A,(IX+$04) Add the Y position of the entity.
9022 LD D,A Keep the new Y position in D.
9023 LD A,$20 A=20 (the flag for the Y axis).
9025 EX AF,AF' Save the flag for the axis in AF'.
9026 CALL CheckObstacles_Position Call CheckObstacles_Position to test the position against the items for the room.
9029 POP DE Restore the moves from the stack.
902A RET Return.
Test the position against the items for the room.
CheckObstacles_Position 902B LD C,(IX+$01) Fetch the room of the entity.
902E LD B,$00 Clear the high byte of the room number.
9030 LD HL,$757D HL=757D (the start of the lists of items for the rooms).
9033 SLA C Double BC, as there are two bytes for each room.
9035 RL B
9037 ADD HL,BC Find the entry for the room in the table of item lists.
9038 LD C,(HL) Fetch the low byte of the address of the list.
9039 INC HL Move HL on to the high byte.
903A LD B,(HL) Fetch the high byte of the address of the list.
CheckObstacles_Next 903B LD A,(BC) Fetch the low byte of the address of the item.
903C INC BC Move BC on to the next byte.
903D LD L,A Keep the low byte of the address of the item in L.
903E LD A,(BC) Fetch the high byte of the address of the item.
903F INC BC Move BC on to the next entry in the list.
9040 LD H,A Keep the high byte of the address of the item in H.
9041 OR L Return if the address of the item is zero, which is the end of the list.
9042 RET Z
9043 PUSH BC Stash the list pointer on the stack.
9044 LD BC,$757D BC=757D.
9047 AND A Subtract BC from HL to get the address of the live record.
9048 SBC HL,BC
904A INC HL Move HL on to the room of the item.
904B LD A,(HL) Fetch the room of the item.
904C CP (IX+$01) Compare it with the room of the entity.
904F JR Z,CheckObstacles_Item Jump to CheckObstacles_Item if they are the same.
9051 LD BC,$0008 BC=0008 (the size of half a record).
9054 ADD HL,BC Move HL on to the second half of the record.
CheckObstacles_Item 9055 INC HL Move HL on to offset 03 of the item.
9056 INC HL
9057 LD C,(HL) Fetch the X position of the item.
9058 INC HL Move HL on to the next byte.
9059 LD B,(HL) Fetch the Y position of the item.
905A INC HL Move HL on to the next byte.
905B LD A,(HL) Fetch the attribute of the item.
905C INC HL Move HL on to the next byte.
905D BIT 2,A Jump to CheckObstacles_Solid if bit 2 of the attribute is set.
905F JR NZ,CheckObstacles_Solid
9061 BIT 3,A Jump to CheckObstacles_Skip if bit 3 of the attribute is set.
9063 JR NZ,CheckObstacles_Skip
The item lets the entity through if the position is inside the rectangle, so clear the flag.
9065 LD A,(HL) A=offset 06 of the item (the left side and the width).
9066 SRA A Shift A right twice, keeping the sign.
9068 SRA A
906A AND %11111100 Keep only bits 2-7.
906C ADD A,C Add the X position of the item.
906D SUB E Subtract the new X position of the entity.
906E NEG Negate the result, to get the distance from the left side.
9070 LD C,A Keep the distance from the left in C.
9071 LD A,(HL) Fetch offset 06 of the item.
9072 RLCA Rotate A left twice.
9073 RLCA
9074 AND %00111100 Keep only bits 2-5 (the width).
9076 INC HL Move HL on to offset 07 of the item.
9077 CP C Jump to CheckObstacles_Skip if the position is not inside the item.
9078 JR C,CheckObstacles_Skip
907A LD A,(HL) A=offset 07 of the item (the top and the height).
907B SRA A Shift A right twice, keeping the sign.
907D SRA A
907F AND %11111100 Keep only bits 2-7.
9081 ADD A,B Add the Y position of the item.
9082 SUB D Subtract the new Y position of the entity.
9083 LD B,A Keep the distance from the top in B.
9084 LD A,(HL) Fetch offset 07 of the item.
9085 INC HL Move HL on to the next byte.
9086 RLCA Rotate A left twice.
9087 RLCA
9088 AND %00111100 Keep only bits 2-5 (the height).
908A CP B Jump to CheckObstacles_Skip if the position is not inside the item.
908B JR C,CheckObstacles_Skip
908D EX AF,AF' Swap AF and AF' to get the flag.
908E LD C,A Keep the flag for the axis in C.
908F EX AF,AF' Swap AF and AF' back again.
9090 LD A,C Fetch the flag for the axis.
9091 CPL Invert the flag, to make a mask.
9092 AND (IX+$02) Clear the flag in offset 02 of the entity.
CheckObstacles_SetFlags 9095 LD (IX+$02),A Write A to offset 02 of the entity.
CheckObstacles_Skip 9098 POP BC Restore the list pointer from the stack.
9099 JR CheckObstacles_Next Jump back to CheckObstacles_Next to look at the next item.
The item blocks the entity if the position is inside the rectangle, so set the flag.
CheckObstacles_Solid 909B LD A,(HL) A=offset 06 of the item (the left side and the width).
909C SRA A Shift A right twice, keeping the sign.
909E SRA A
90A0 AND %11111100 Keep only bits 2-7.
90A2 ADD A,C Add the X position of the item.
90A3 SUB E Subtract the new X position of the entity.
90A4 NEG Negate the result, to get the distance from the left side.
90A6 LD C,A Keep the distance from the left in C.
90A7 LD A,(HL) Fetch offset 06 of the item.
90A8 RLCA Rotate A left twice.
90A9 RLCA
90AA AND %00111100 Keep only bits 2-5 (the width).
90AC INC HL Move HL on to offset 07 of the item.
90AD CP C Jump to CheckObstacles_Skip if the position is not inside the item.
90AE JR C,CheckObstacles_Skip
90B0 LD A,(HL) A=offset 07 of the item (the top and the height).
90B1 SRA A Shift A right twice, keeping the sign.
90B3 SRA A
90B5 AND %11111100 Keep only bits 2-7.
90B7 ADD A,B Add the Y position of the item.
90B8 SUB D Subtract the new Y position of the entity.
90B9 LD B,A Keep the distance from the top in B.
90BA LD A,(HL) Fetch offset 07 of the item.
90BB INC HL Move HL on to the next byte.
90BC RLCA Rotate A left twice.
90BD RLCA
90BE AND %00111100 Keep only bits 2-5 (the height).
90C0 CP B Jump to CheckObstacles_Skip if the position is not inside the item.
90C1 JR C,CheckObstacles_Skip
90C3 EX AF,AF' Swap AF and AF' to get the flag.
90C4 LD C,A Keep the flag for the axis in C.
90C5 EX AF,AF' Swap AF and AF' back again.
90C6 LD A,C Fetch the flag for the axis.
90C7 OR (IX+$02) Set the flag in offset 02 of the entity.
90CA JR CheckObstacles_SetFlags Jump to CheckObstacles_SetFlags to set the flags of the entity.
Prev: 8FCA Up: Map Next: 90CC