Prev: DFBC Up: Map Next: E039
DFCD: Check for events/collisions
Used by the routines at CA8E, CB96, CC27, CC72, CD21, CD66, CD88, D04B, D116, D1D2, D479 and D49D.
Input
C Collision/event type, e.g.:
0 = Collision with Maroc, e.g.:
creature missile hitting Maroc (D11D) or Maroc moving through an open doorway (CA19)
1 = Door opening/closing (CA8E)
3 = Check for creature being destroyed (e.g. by missile/sword)
5 = Servant picking up an object (CD66)
15 = Item being collected by Maroc (checked at CC72)
136 = Check for Maroc entering portal door in room 81 D49D
137 = Maroc has destroyed Avelach with Caliburn (CC2E)
253 = Check if Maroc is touching a (stationary) energy-restoring object - from D48F
254 = Check if Maroc is touching a (stationary) energy-draining object - from D481
D Horizontal (X) position (in pixels) for graphic, e.g. servant, door
E Vertical (Y) position (in pixels), e.g. servant, door
Check for a variety of collisions, or 'instances of items touching other items':
  • Servant picks up an object
  • Servant uses an object on another object/creature
  • Servant gives an item to a warlock
  • Servant touches an open door handle
  • Maroc's missile/bolt collides with a creature
  • Maroc touches an object that restores/drains energy
  • Creature missile hits Maroc
  • Creature closes a door (touches the handle of an open door)
example of an event - using an item to open a chest
The routine returns the A register containing 0 (no collision) or 1 (collision has taken place):
DFCD LD A,($EAD3) Graphic's horizontal position, in pixels, starting from screen pixel column 8 (halfway into left decorative border)
DFD0 LD D,A
DFD1 LD A,($EAD2) Graphic's vertical position, in pixels, from top of playing area
DFD4 LD E,A
Horizontal (D) and vertical (E) pixel co-ordinates either identified in the previous 4 instructions, or pre-loaded prior to a CALL directly here (e.g. D83B for servant checks)
DFD5 LD A,($EAD4) This byte indicates whether the item is in the current view horizontally (0), off-screen to the right (1), or offscreen to the left (255)
DFD8 CP $00 If it's NOT zero, it's off-screen so no collision action needs checking. Jump to the end of this routine (setting no collision/energy drain flag to zero)
DFDA JR NZ,$E036
DFDC LD A,C Retrieve the value from the C register from the previous routine - this is the collision/event check value to test
DFDD CP $00 0 tests for a collision with Maroc - e.g. the servant and Maroc's backpack (placing/retrieving items)
DFDF JR Z,$DFE7
DFE1 CP $01 Collision value 1 = Opening/closing doors interactions
DFE3 JR Z,$DFE7
DFE5 JR $DFFC All other sorts of event/collision
CHECK FOR COLLISIONS WITH MAROC'S SPRITE.
This could be the servant (for object manipulation) or Maroc opening a door.
DFE7 LD A,$78 120 (in pixels) is roughly 1 character/8 pixels to the right of the centre of the screen - Maroc's horizontal central point
DFE9 SUB D Subtract the graphic's horizontal (X) position
DFEA CP $10 If the difference is <= 16 pixels, the other room item is (horizontally) close enough to Maroc
DFEC JR NC,$DFFC Collision NOT within horizontal 'hit box'. Skip next few instructions
DFEE LD A,($EAC1) Collision IS within horizontal 'hit box'. Get Maroc's vertical (Y-axis) screen position
DFF1 ADD A,$08 Maroc's central point/backpack is on the lower part of his graphic, so move down 8 pixels...
DFF3 SUB E Subtract the graphic's vertical (Y) position
DFF4 CP $10 If the difference is <=16 pixels, Maroc is (vertically) close enough
DFF6 JR NC,$DFFC Collision NOT within horizontal 'hit box'. Skip next couple of instructions
Positive collision with Maroc confirmed
DFF8 LD A,$01 Positive collision - set flag (A register) to 1
DFFA JR $E038 Jump straight to RET
CHECK FOR OTHER COLLISIONS/EVENTS
Jump from DFE5 if the collision type in the C register is NOT 0 ir 1 (all other event matches/collisions).
This might be checking for collision with energy restoring (253) or draining (254) objects, or for an item acting on another (matching) item, such as a key and a chest.
DFFC LD A,C Retrieve the type-of-collision value to test/check
DFFD CP $00 Is it 0?
DFFF JR Z,$E036 If so, that check's done, so can skip to the end (setting collision flag to zero)
E001 LD B,$FD 253 = value to test for energy-replenishing objects
However, this test won't match because of the AND 3 in a few instructions at E018.
Explicit event checks for both energy-draining (C=254) and energy-restoring (C=253) objects are CALLed in the routine at D479
E003 LD HL,($EB6C) Pointer to room item event table at 7FB3.
E006 CP $04 Check if type-of-collision value >= 4
E008 JR NC,$E00D
E00A LD B,C If < 4, store the type-of-collision value in B register
E00B LD C,$00 ...and set C register to 0
E00D LD A,(HL) Get first byte from data table (at 7FB3)
E00E INC HL (...and move the pointer along)
E00F CP $FF Is there data to check in this set (255 = end-of-data)?
E011 JR Z,$E036 If not, skip to the end of this routine, setting collision/energy drain flag to zero
E013 LD A,(HL) Get the (second) byte in the set
E014 INC HL (...and move the pointer along)
E015 CP C Check collision test value vs object/item collision type (second byte in set at 7FB3) to see if it matches
E016 JR Z,$E01D If so, jump to check Maroc's 'hit boxes' for a collision
Check door-, spell- or creature-related interactions. For example:
  • goblins have a creature event value - for items acting on them - of 3
  • missiles 2-7 in the table at 6CDC have bits 0 & 1 of their event byte set (value = 3)
  • similarly Caliburn (78BB) and the animated sabre (7A63) have bits 0-1 of their event byte set (value = 3)
By just filtering these two bits, we can set/determine which items or spells will cause a positive event/collision on goblins.
E018 AND $03 This filters bits 0-1 (values 1-3)
E01A CP B If no match for this, continue to check the event table at 7FB3
E01B JR NZ,$E032
Check X/Y co-ordinates for collision
First, an X (horizontal) co-ordinate check:
E01D LD A,(HL) Get item's horizontal pixel co-ordinate (byte 3 of item set at 7FB3)
E01E INC HL (...and move the pointer along)
E01F ADD A,$08 The collision check is a 16-pixel horizontal collision area, so adding 8 is an offset which gives it an 8-pixel-each-side collision box
E021 SUB D Subtract the horizontal pixel co-ordinate of the 'acting item'
E022 CP $10 Is the difference within the 16 pixel 'hit box' threshold (8 pixels left/right of target co-ordinates)?
E024 JR NC,$E033 If not, no need to check vertical co-ordinates
Y (vertical) co-ordinate check:
E026 LD A,(HL) Get item's vertical pixel co-ordinate (byte 4 of item set at 7FB3)
E027 ADD A,$08 The collision check is a 16-pixel vertical collision area, so adding 8 is an offset which gives it an 8-pixel-each-side collision box
E029 SUB E Subtract the vertical pixel co-ordinate of the 'acting item' (e.g. servant)
E02A CP $10 Is the difference within the 16 pixel 'hit box' threshold (8 pixels left/right of target co-ordinates)
E02C JR NC,$E033 If not, jump to set negative collision flag (0) in A register
POSITIVE COLLISION
E02E LD A,$01 Set collision flag (A register) to 1 - collision has taken place with this item.
E030 JR $E038 Jump straight to RET and deal with it
No positive collision found for this object - move to next item and continue checks:
E032 INC HL Jumps from E01B...
E033 INC HL ...and from E033, that advance the address pointer to the next data set (at 7FB3).
E034 JR $E00D
NEGATIVE COLLISION - Set collision flag (A register) to 0 - no collision has taken place with any on-screen objects.
E036 LD A,$00
Routine returns with A register either set to 1 (collision) or 0 (no collision)
E038 RET
Prev: DFBC Up: Map Next: E039