| Routines

ED8C: Determine the next move a character should make to reach his destination

Used by the routines at 72B1, 7996, 7A82 and F600. Returns with A holding a value that indicates the next move the character should make (if any) to reach his destination.
A | Meaning the character should...
--- | ---
0 | Do nothing (the character is already at his destination)
1 | Go right
2 | Go left
3 | Go up
4 | Go down
5 | Open a door from the inside
6 | Knock on a door or use a key
Input
H | Character number (0xD7-0xE6)
ED8C | CALL $7C40 | Deal with the case where the character will soon be entering or leaving the hotel; otherwise return here
ED8F | LD L,$0D | Initialise the location/destination indicator in byte 0x0D of the character's buffer to 0
ED91 | LD (HL),$00
ED93 | AND A | Is the character on the sidewalk or the road?
ED94 | JR NZ,$EDD3 | Jump if not
ED96 | DEC L | L=0x0C
ED97 | LD A,(HL) | A=destination location identifier (see ED36)
ED98 | AND A | Is the character's destination on the sidewalk or the road?
ED99 | JR NZ,$EDAA | Jump if not
The next section of code deals with the case where the character can reach his destination simply by continuing to move left or right. The routine at 7C40 re-enters here (from the opening CALL in this routine) if the character is on the front steps of the hotel, and his destination is on the first floor or the front steps of the hotel.
ED9B | LD L,$0A | Point HL at byte 0x0A of the character's buffer
ED9D | LD E,(HL) | E=destination x-coordinate
ED9E | LD A,E | Copy this to A
ED9F | LD L,$01 | Does the character's x-coordinate match the destination x-coordinate?
EDA1 | CP (HL)
EDA2 | LD A,$00 | Return with A=0 (do nothing) if so
EDA4 | RET Z
EDA5 | LD A,$01 | Return with A=1 (go right) if the character's x-coordinate is less than the destination x-coordinate
EDA7 | RET NC
EDA8 | INC A | A=2 (go left)
EDA9 | RET |
The character is on the sidewalk or the road, and his destination is somewhere other than the sidewalk or the road. Move the character left or right towards the building he's destined for, or make him go up a step if he's reached the front steps of the building.
EDAA | AND $F0 | Keep only the region identifier bits (bits 4-7) of the destination
EDAC | RRCA | Shift them into bits 1-4
EDAD | RRCA
EDAE | RRCA
EDAF | ADD A,$96 | A=0x98+2n (n=0x00-0x0B, 0x0D or 0x0E)
EDB1 | LD C,A | Point BC at the entry in the table of building entrance x-coordinates at FF98 that corresponds to the character's destination
EDB2 | LD B,$FF
EDB4 | LD L,$01 | Point HL at byte 0x01 of the character's buffer
EDB6 | LD A,(BC) | Pick up the lower x-coordinate of the building entrance
EDB7 | LD E,A | Copy it to E
EDB8 | CP (HL) | Compare it with the character's x-coordinate
EDB9 | LD A,L | A=1 (go right)
EDBA | JR NZ,$EDC1 | Jump unless the x-coordinates match
EDBC | DEC L | L=0x00
EDBD | BIT 7,(HL) | Is the character facing right?
EDBF | JR NZ,$EDCD | Jump if so
EDC1 | RET NC | Return with A=1 (go right)
EDC2 | INC C | Pick up the upper x-coordinate of the building entrance
EDC3 | LD A,(BC)
EDC4 | LD E,A | Copy it to E
EDC5 | CP (HL) | Compare it with the character's x-coordinate
EDC6 | LD A,$02 | A=2 (go left)
EDC8 | RET NZ | Return unless the x-coordinates match
EDC9 | DEC L | L=0x00
EDCA | BIT 7,(HL) | Is the character facing right?
EDCC | RET NZ | Return with A=2 (go left) if so
EDCD | LD L,$0D | Set byte 0x0D of the character's buffer to 1 (indicating that the character is no longer on the sidewalk or the road, and is in the same region as his destination)
EDCF | INC (HL)
EDD0 | LD A,$03 | A=3 (go up)
EDD2 | RET |
The character is on neither the sidewalk nor the road.
EDD3 | INC (HL) | Set byte 0x0D of the character's buffer to 1 (indicating that the character is on neither the sidewalk nor the road)
EDD4 | DEC L | L=0x0C
EDD5 | INC A | Is the character on the fire escape of the apartment building next to no. 19?
EDD6 | JR NZ,$EDFD | Jump if not
The character is on the fire escape of the apartment building next to no. 19.
EDD8 | LD A,(HL) | A=destination location identifier (see ED36)
EDD9 | INC A | Set the zero flag if the destination is on the fire escape
EDDA | SCF | Set the carry flag: the character will go back up the fire escape (if his destination is not on the fire escape)
EDDB | JR NZ,$EDE4 | Jump if the destination is not on the fire escape
EDDD | DEC L | L=0x0B
EDDE | LD A,(HL) | A=character's destination y-coordinate
EDDF | LD L,$02 | Point HL at byte 0x02 of the character's buffer
EDE1 | CP (HL) | Does the character's y-coordinate match that of his destination?
EDE2 | JR Z,$ED9B | If so, move the character left or right towards his destination
EDE4 | PUSH AF | Save the carry flag briefly
EDE5 | PUSH HL | Save the character number briefly
EDE6 | CALL $EB13 | Obtain descriptors for the character's current location
EDE9 | POP HL | Restore the character number to H
EDEA | POP AF | Restore the carry flag
EDEB | LD A,C | Copy the direction descriptor bits (see EB13) to A
EDEC | JR NC,$EDF5 | Jump if the character's y-coordinate is less than that of his destination
The character is on the fire escape of the apartment building next to no. 19, and his destination is either not on the fire escape, or somewhere further up the fire escape. In this case the character will go up the fire escape.
EDEE | AND $10 | Set the zero flag unless the character is next to a step going up to the right
EDF0 | LD A,$03 | A=3 (go up)
EDF2 | RET NZ | Return if the character is next to a step going up to the right
EDF3 | DEC A | A=2 (go left)
EDF4 | RET |
The character is on the fire escape of the apartment building next to no. 19, and his destination is somewhere further down the fire escape. In this case the character will go down the fire escape.
EDF5 | AND $08 | Set the zero flag unless the character is next to a step going down to the left
EDF7 | LD A,$04 | A=4 (go down)
EDF9 | RET NZ | Return if the character is next to a step going down to the left
EDFA | LD A,$01 | A=1 (go right)
EDFC | RET |
The character is on neither the sidewalk nor the road, nor on the fire escape of the apartment building next to no. 19.
EDFD | DEC A | A=identifier for the character's current location (see ED36)
EDFE | LD B,(HL) | B=destination location identifier (see ED36)
EDFF | INC B | Is the destination on the fire escape of the apartment building next to no. 19?
EE00 | JR NZ,$EE09 | Jump if not
EE02 | CP $FD | Is the character on the rim of the roof of the apartment building next to no. 19?
EE04 | JR NZ,$EE09 | Jump if not
EE06 | LD A,$04 | A=4 (go down)
EE08 | RET |
The character is on neither the sidewalk nor the road, nor on the fire escape of the apartment building next to no. 19; in addition, either his destination is not on the fire escape, or he is not on the rim of the roof of the apartment building next to no. 19.
EE09 | LD B,A | B=identifier for the character's current location (see ED36)
EE0A | AND $F0 | Keep only the region identifier bits (bits 4-7)
EE0C | LD C,A | Copy them to C
EE0D | LD A,(HL) | Collect the destination location identifier from byte 0x0C of the character's buffer
EE0E | AND $F0 | Keep only the region identifier bits (bits 4-7)
EE10 | CP C | Is the character in the same region as his destination?
EE11 | JP NZ,$EEAC | Jump if not
The character is in the same region as his destination.
EE14 | LD A,B | A=identifier for the character's current location (see ED36)
EE15 | CP (HL) | Compare it with the identifier for the character's destination
EE16 | JR NZ,$EE26 | Jump unless they match
The character is in the same region as his destination, and also on the same floor.
EE18 | LD L,$0B | A=character's destination y-coordinate
EE1A | LD A,(HL)
EE1B | LD L,$02 | Compare this with the character's current y-coordinate
EE1D | CP (HL)
EE1E | JP Z,$ED9B | If they match, move the character left or right towards his destination
EE21 | LD A,$03 | A=3 (go up)
EE23 | RET C | Return if the character's current y-coordinate is greater than that of his destination
EE24 | INC A | A=4 (go down)
EE25 | RET |
The character is in the same region as his destination, but either on a different floor, or outside the entrance to a shop or building when the destination is on the first floor inside (or vice versa).
EE26 | JR C,$EE6C | Jump if the character is below his destination
EE28 | AND $0F | Keep only bits 0-3 of the identifier for the character's current location
EE2A | CP $04 | Is the character in a shop or on the first floor of a building (inside)?
EE2C | JR NZ,$EE5E | Jump if not
EE2E | LD A,(HL) | A=destination location identifier
EE2F | AND $0F | Keep only bits 0-3
EE31 | CP $02 | Set the zero flag if the destination is outside the entrance
EE33 | LD L,$01 | Point HL at byte 0x01 of the character's buffer
EE35 | JR NZ,$EE49 | Jump unless the destination is outside the entrance
EE37 | LD A,(HL) | A=character's x-coordinate
EE38 | LD L,$0A | Does it match the destination x-coordinate?
EE3A | CP (HL)
EE3B | JR NZ,$EE47 | Jump if not
EE3D | PUSH DE | Save the staircase endpoint x-coordinates briefly
EE3E | PUSH HL | Save the character number briefly
EE3F | CALL $EB13 | Obtain descriptors for the character's current location
EE42 | POP HL | Restore the character number to H
EE43 | POP DE | Restore the staircase endpoint x-coordinates to DE
EE44 | SUB $03 | Is the character standing at the (open) entrance to a building?
EE46 | RET Z | Return with A=0 (do nothing) if so
EE47 | LD L,$01 | Point HL at byte 0x01 of the character's buffer
EE49 | LD A,(HL) | A=character's x-coordinate
EE4A | CP D | Is the character standing at the top of the steps down to the sidewalk or the floor below?
EE4B | JR NZ,$EE59 | If not, send the character towards the top of the steps
EE4D | PUSH HL | Save the character number briefly
EE4E | CALL $EB13 | Obtain descriptors for the character's current location
EE51 | POP HL | Restore the character number to H
EE52 | INC A | Is the character standing next to the open entrance to a building?
EE53 | CP $04
EE55 | RET Z | Return with A=4 (go down) if so
EE56 | LD A,$05 | A=5 (open the door)
EE58 | RET |
EE59 | LD A,$01 | A=1 (go right)
EE5B | RET C |
EE5C | INC A | A=2 (go left)
EE5D | RET |
Either the character is in the same region as his destination, but above it, and not in a shop or on the first floor of a building (inside); or the character is not in the same region as his destination, and is inside a building somewhere above the first floor.
EE5E | BIT 0,A | Set the zero flag unless the character is on a staircase between floors
EE60 | LD A,$04 | A=4 (go down)
EE62 | RET NZ | Return if the character is on a staircase between floors
EE63 | LD L,$01 | Point HL at byte 0x01 of the character's buffer
EE65 | LD A,(HL) | A=character's x-coordinate
EE66 | CP D | Compare it with the x-coordinate of the top of the staircase leading down to the floor below
EE67 | LD A,$04 | A=4 (go down)
EE69 | RET Z | Return if the character is standing at the top of the staircase leading down to the floor below
EE6A | JR $EE59 | Send the character towards the top of the staircase
The character is in the same region as his destination, but below it.
EE6C | CALL $7083 | Deal with the case where the character is on the roof of the police station or the apartment building next to no. 19 and is destined for the edge of that roof; otherwise return here
EE6F | NOP |
EE70 | JR NZ,$EE9C | Jump unless the character is standing outside the entrance to a shop or other building
EE72 | LD A,(HL) | A=destination location identifier (see ED36)
EE73 | AND $0F | Keep only bits 0-3
EE75 | CP $04 | Set the zero flag if the destination is inside the shop or on the first floor of the building outside the entrance to which the character is standing
EE77 | LD L,$01 | Point HL at byte 0x01 of the character's buffer
EE79 | JR NZ,$EE8B | Jump unless the destination is inside the shop or on the first floor of the building outside the entrance to which the character is standing
EE7B | LD A,(HL) | A=character's x-coordinate
EE7C | LD L,$0A | Compare this with the destination x-coordinate
EE7E | CP (HL)
EE7F | JR NZ,$EE8B | Jump unless they match
EE81 | PUSH DE | Save the staircase endpoint x-coordinates briefly
EE82 | PUSH HL | Save the character number briefly
EE83 | CALL $EB13 | Obtain descriptors for the character's current location
EE86 | POP HL | Restore the character number to H
EE87 | POP DE | Restore the staircase endpoint x-coordinates to DE
EE88 | SUB $03 | Is the entrance next to which the character is standing open?
EE8A | RET Z | Return with A=0 (do nothing) if so
EE8B | NOP |
The character is standing outside the entrance to a shop or other building, and his destination is somewhere inside that shop or building.
EE8C | CALL $F905 | Is the character standing at the right spot to enter the building or knock on the door?
EE8F | JR NZ,$EEA8 | Jump if not
EE91 | PUSH HL | Save the character number briefly
EE92 | CALL $EB13 | Obtain descriptors for the character's current location
EE95 | POP HL | Restore the character number to H
EE96 | CP $03 | Set the zero flag if the entrance is open
EE98 | JP $F91E | Check whether the character should enter the building or knock first
EE9B | NOP | This instruction is never executed
If we get here, then either the character is in the same region as his destination, but below it, and is not standing outside the entrance to a shop or other building; or the character is inside or on the roof of the police station and heading for no. 27 (or vice versa), and will be going via the roofs (instead of going down to the sidewalk).
EE9C | BIT 0,A | Bit 0 of A is set if the character is on a staircase
EE9E | LD A,$03 | A=3 (go up)
EEA0 | RET NZ | Return if the character is on a staircase
EEA1 | LD L,$01 | Point HL at byte 0x01 of the character's buffer
EEA3 | LD A,(HL) | A=character's x-coordinate
EEA4 | CP E | Compare this with the x-coordinate of the bottom of the staircase leading to the floor above
EEA5 | LD A,$03 | Return with A=3 (go up) if the character is at the bottom of the staircase leading to the floor above
EEA7 | RET Z
EEA8 | LD A,L | Return with A=1 (go right) if the character is to the left of either the bottom of the staircase leading to the floor above, or the correct spot at which to enter the building or knock on the door
EEA9 | RET C
EEAA | INC A | A=2 (go left)
EEAB | RET |
The character is not in the same region as his destination.
EEAC | INC L | Set byte 0x0D of the character's buffer to 2 (to indicate that the character is not on the sidewalk or the road, and is heading for some region other than the one he's in)
EEAD | INC (HL)
EEAE | DEC L | L=0x0C
EEAF | CP $60 | Is the character going to the police station?
EEB1 | JR Z,$EEBE | Jump if so
EEB3 | CP $70 | Is the character going to no. 27?
EEB5 | JR NZ,$EECA | Jump if not
The character is going to no. 27, and is not in the same region as that building.
EEB7 | LD A,C | A=region identifier for the character's current location
EEB8 | CP $60 | Is the character inside or on the roof of the police station?
EEBA | JR NZ,$EECA | Jump if not
EEBC | JR $EEC3 |
The character is going to the police station, and is not in the same region as that building.
EEBE | LD A,C | A=region identifier for the character's current location
EEBF | CP $70 | Is the character inside or on the roof of no. 27?
EEC1 | JR NZ,$EECA | Jump if not
The character is either inside or on the roof of no. 27 and heading for the police station, or inside or on the roof of the police station and heading for no. 27.
EEC3 | LD A,B | A=identifier for the character's current location (0x60-0x6D if it's the police station, or 0x70-0x7D if it's no. 27; see ED36)
EEC4 | ADD A,(HL) | Add the destination location identifier
EEC5 | CP $E1 | Reset the carry flag if it would be quicker to go via the roofs than back down to the sidewalk
EEC7 | LD A,B | A=identifier for the character's current location (see ED36)
EEC8 | JR NC,$EE9C | Jump if it would be quicker to go via the roofs than back down to the sidewalk
The character is not in the same region as his destination. Figure out his next move towards the destination via the sidewalk.
EECA | LD A,B | A=identifier for the character's current location (see ED36)
EECB | AND $0F | Keep only bits 0-3
EECD | CP $04 | Is the character inside a shop or on the first floor of a building (inside)?
EECF | JP Z,$EE47 | If so, send him towards the entrance
EED2 | CP $01 | Is the character on the front steps of a building below the first floor?
EED4 | JP NZ,$EE5E | If not, send the character towards the top of the staircase leading down to the floor below
The character is not in the same region as his destination, and is on the front steps of a building below the first floor. Figure out which direction to take down the steps towards the destination.
EED7 | PUSH HL | Save the character number briefly
EED8 | CALL $EB13 | Obtain descriptors for the character's current location
EEDB | POP HL | Restore the character number to H
EEDC | LD L,$01 | Point HL at byte 0x01 of the character's buffer
EEDE | LD A,(HL) | A=character's x-coordinate
EEDF | LD L,$0A | Compare this with the character's destination x-coordinate
EEE1 | CP (HL)
EEE2 | LD A,C | Copy the direction descriptor bits (see EB13) to A
EEE3 | JR NC,$EEF5 | Jump if the character's x-coordinate is greater than or equal to the destination x-coordinate
EEE5 | AND $04 | Is the character next to a step going down to the right?
EEE7 | JR NZ,$EEEC | Jump if not
EEE9 | LD A,$04 | A=4 (go down)
EEEB | RET |
EEEC | LD L,$00 | Point HL at byte 0x00 of the character's buffer
EEEE | BIT 7,(HL) | Is the character facing right?
EEF0 | JR NZ,$EEE9 | Jump if so to set A=4 (go down)
EEF2 | LD A,$01 | A=1 (go right)
EEF4 | RET |
EEF5 | AND $08 | Is the character standing next to a step going down to the left?
EEF7 | JR Z,$EEE9 | Jump if not to set A=4 (go down)
EEF9 | LD L,$00 | Point HL at byte 0x00 of the character's buffer
EEFB | BIT 7,(HL) | Is the character facing left?
EEFD | JR Z,$EEE9 | Jump if so to set A=4 (go down)
EEFF | LD A,$02 | A=2 (go left)
EF01 | RET |