Prev: 36810 Up: Map Next: 37068
36874: 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 6 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 7 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 2 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 36874 PUSH DE Stash the moves on the stack.
36875 LD A,E Fetch the X move.
36876 ADD A,(IX+3) Add the X position of the entity.
36879 LD E,A Keep the new X position in E.
36880 LD D,(IX+4) Fetch the Y position of the entity.
36883 LD A,16 A=16 (the flag for the X axis).
36885 EX AF,AF' Save the flag for the axis in AF'.
36886 CALL CheckObstacles_Position Call CheckObstacles_Position to test the position against the items for the room.
36889 POP DE Restore the moves from the stack.
36890 PUSH DE Stash it on the stack again.
36891 LD E,(IX+3) Fetch the X position of the entity.
36894 LD A,D Fetch the Y move.
36895 ADD A,(IX+4) Add the Y position of the entity.
36898 LD D,A Keep the new Y position in D.
36899 LD A,32 A=32 (the flag for the Y axis).
36901 EX AF,AF' Save the flag for the axis in AF'.
36902 CALL CheckObstacles_Position Call CheckObstacles_Position to test the position against the items for the room.
36905 POP DE Restore the moves from the stack.
36906 RET Return.
Test the position against the items for the room.
CheckObstacles_Position 36907 LD C,(IX+1) Fetch the room of the entity.
36910 LD B,0 Clear the high byte of the room number.
36912 LD HL,30077 HL=30077 (the start of the lists of items for the rooms).
36915 SLA C Double BC, as there are two bytes for each room.
36917 RL B
36919 ADD HL,BC Find the entry for the room in the table of item lists.
36920 LD C,(HL) Fetch the low byte of the address of the list.
36921 INC HL Move HL on to the high byte.
36922 LD B,(HL) Fetch the high byte of the address of the list.
CheckObstacles_Next 36923 LD A,(BC) Fetch the low byte of the address of the item.
36924 INC BC Move BC on to the next byte.
36925 LD L,A Keep the low byte of the address of the item in L.
36926 LD A,(BC) Fetch the high byte of the address of the item.
36927 INC BC Move BC on to the next entry in the list.
36928 LD H,A Keep the high byte of the address of the item in H.
36929 OR L Return if the address of the item is zero, which is the end of the list.
36930 RET Z
36931 PUSH BC Stash the list pointer on the stack.
36932 LD BC,30077 BC=30077.
36935 AND A Subtract BC from HL to get the address of the live record.
36936 SBC HL,BC
36938 INC HL Move HL on to the room of the item.
36939 LD A,(HL) Fetch the room of the item.
36940 CP (IX+1) Compare it with the room of the entity.
36943 JR Z,CheckObstacles_Item Jump to CheckObstacles_Item if they are the same.
36945 LD BC,8 BC=0008 (the size of half a record).
36948 ADD HL,BC Move HL on to the second half of the record.
CheckObstacles_Item 36949 INC HL Move HL on to offset 3 of the item.
36950 INC HL
36951 LD C,(HL) Fetch the X position of the item.
36952 INC HL Move HL on to the next byte.
36953 LD B,(HL) Fetch the Y position of the item.
36954 INC HL Move HL on to the next byte.
36955 LD A,(HL) Fetch the attribute of the item.
36956 INC HL Move HL on to the next byte.
36957 BIT 2,A Jump to CheckObstacles_Solid if bit 2 of the attribute is set.
36959 JR NZ,CheckObstacles_Solid
36961 BIT 3,A Jump to CheckObstacles_Skip if bit 3 of the attribute is set.
36963 JR NZ,CheckObstacles_Skip
The item lets the entity through if the position is inside the rectangle, so clear the flag.
36965 LD A,(HL) A=offset 6 of the item (the left side and the width).
36966 SRA A Shift A right twice, keeping the sign.
36968 SRA A
36970 AND %11111100 Keep only bits 2-7.
36972 ADD A,C Add the X position of the item.
36973 SUB E Subtract the new X position of the entity.
36974 NEG Negate the result, to get the distance from the left side.
36976 LD C,A Keep the distance from the left in C.
36977 LD A,(HL) Fetch offset 6 of the item.
36978 RLCA Rotate A left twice.
36979 RLCA
36980 AND %00111100 Keep only bits 2-5 (the width).
36982 INC HL Move HL on to offset 7 of the item.
36983 CP C Jump to CheckObstacles_Skip if the position is not inside the item.
36984 JR C,CheckObstacles_Skip
36986 LD A,(HL) A=offset 7 of the item (the top and the height).
36987 SRA A Shift A right twice, keeping the sign.
36989 SRA A
36991 AND %11111100 Keep only bits 2-7.
36993 ADD A,B Add the Y position of the item.
36994 SUB D Subtract the new Y position of the entity.
36995 LD B,A Keep the distance from the top in B.
36996 LD A,(HL) Fetch offset 7 of the item.
36997 INC HL Move HL on to the next byte.
36998 RLCA Rotate A left twice.
36999 RLCA
37000 AND %00111100 Keep only bits 2-5 (the height).
37002 CP B Jump to CheckObstacles_Skip if the position is not inside the item.
37003 JR C,CheckObstacles_Skip
37005 EX AF,AF' Swap AF and AF' to get the flag.
37006 LD C,A Keep the flag for the axis in C.
37007 EX AF,AF' Swap AF and AF' back again.
37008 LD A,C Fetch the flag for the axis.
37009 CPL Invert the flag, to make a mask.
37010 AND (IX+2) Clear the flag in offset 2 of the entity.
CheckObstacles_SetFlags 37013 LD (IX+2),A Write A to offset 2 of the entity.
CheckObstacles_Skip 37016 POP BC Restore the list pointer from the stack.
37017 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 37019 LD A,(HL) A=offset 6 of the item (the left side and the width).
37020 SRA A Shift A right twice, keeping the sign.
37022 SRA A
37024 AND %11111100 Keep only bits 2-7.
37026 ADD A,C Add the X position of the item.
37027 SUB E Subtract the new X position of the entity.
37028 NEG Negate the result, to get the distance from the left side.
37030 LD C,A Keep the distance from the left in C.
37031 LD A,(HL) Fetch offset 6 of the item.
37032 RLCA Rotate A left twice.
37033 RLCA
37034 AND %00111100 Keep only bits 2-5 (the width).
37036 INC HL Move HL on to offset 7 of the item.
37037 CP C Jump to CheckObstacles_Skip if the position is not inside the item.
37038 JR C,CheckObstacles_Skip
37040 LD A,(HL) A=offset 7 of the item (the top and the height).
37041 SRA A Shift A right twice, keeping the sign.
37043 SRA A
37045 AND %11111100 Keep only bits 2-7.
37047 ADD A,B Add the Y position of the item.
37048 SUB D Subtract the new Y position of the entity.
37049 LD B,A Keep the distance from the top in B.
37050 LD A,(HL) Fetch offset 7 of the item.
37051 INC HL Move HL on to the next byte.
37052 RLCA Rotate A left twice.
37053 RLCA
37054 AND %00111100 Keep only bits 2-5 (the height).
37056 CP B Jump to CheckObstacles_Skip if the position is not inside the item.
37057 JR C,CheckObstacles_Skip
37059 EX AF,AF' Swap AF and AF' to get the flag.
37060 LD C,A Keep the flag for the axis in C.
37061 EX AF,AF' Swap AF and AF' back again.
37062 LD A,C Fetch the flag for the axis.
37063 OR (IX+2) Set the flag in offset 2 of the entity.
37066 JR CheckObstacles_SetFlags Jump to CheckObstacles_SetFlags to set the flags of the entity.
Prev: 36810 Up: Map Next: 37068