![]() |
Routines |
| Prev: D7E4 | Up: Map | Next: DC3F |
|
Used by the routine at TestEntityCells.
Finds the group of objects at a cell of the level with FindGroup and then tests the entity against each of the objects, which are three bytes each. The low five bits of the group header are the number of objects. Objects of type 84 86 and 06 are skipped. A solid block stops the entity. Type 81 is a bottle and is collected with CollectBottle. Type 85 sets bit 1 of ExitMessageFlag, the exit-closed message, while BottlesLeft is not zero. A type 83 and a type 85 once no bottles are left, is solid: the entity is pushed back to the edge and FindPathAtPosition looks for a path there. Other objects are matched with TestObjectMatch. The smaller gap is kept in field 1F and bit 6 of the flags is cleared. Purpose of that gap is not yet known.
|
||||||||||
| TestGroupObjects | D8E4 | LD ($5CB9),HL | Remember the cell position. | |||||||
| D8E7 | CALL FindGroup | Find the group of objects. | ||||||||
| D8EA | RET C | Return if this cell has no group. | ||||||||
| D8EB | LD ($5CDC),DE | Remember the cell offset. | ||||||||
| D8EF | INC D | Advance the high byte of the cell offset. | ||||||||
| D8F0 | LD A,(IY+$00) | Read the group header. | ||||||||
| D8F3 | AND %00011111 | Keep the object count. | ||||||||
| D8F5 | LD B,A | Keep the object count aside. | ||||||||
| D8F6 | INC IY | Step on to the first object. | ||||||||
| D8F8 | INC IY | |||||||||
| D8FA | AND %00010000 | Test bit 4, which the count mask has already cleared. | ||||||||
| D8FC | JR Z,TestGroupObjects_Loop | Skip the extra step. This jump is always taken. | ||||||||
| D8FE | INC IY | Step on another byte. This is not reached. | ||||||||
| TestGroupObjects_Loop | D900 | INC IY | Advance to the type byte of the object. | |||||||
| D902 | PUSH BC | Remember the object count. | ||||||||
| D903 | LD A,(IY+$01) | Read the type byte. | ||||||||
| D906 | AND %10001111 | Keep the type bits. | ||||||||
| D908 | CP $84 | Skip an object of type 84. | ||||||||
| D90A | JP Z,TestGroupObjects_Next | |||||||||
| D90D | CP $86 | Skip an object of type 86. | ||||||||
| D90F | JP Z,TestGroupObjects_Next | |||||||||
| D912 | CP $06 | Skip an object of type 06. | ||||||||
| D914 | JP Z,TestGroupObjects_Next | |||||||||
| D917 | RLA | Move bit 7 of the type into the carry flag. | ||||||||
| D918 | JR NC,TestGroupObjects_Player | Test the object when that bit is clear. | ||||||||
| D91A | AND %00011110 | Keep the shifted type bits. | ||||||||
| D91C | CP $1E | Skip an object whose shifted type is 1E. | ||||||||
| D91E | JP Z,TestGroupObjects_Next | |||||||||
| TestGroupObjects_Player | D921 | LD A,(IX+$00) | On any other frame, or for any entity but the player, test the block below. | |||||||
| D924 | DEC A | |||||||||
| D925 | JP NZ,TestGroupObjects_Block | |||||||||
| D928 | LD A,($A2DD) | Read the frame counter. | ||||||||
| D92B | AND %00000111 | Act on every eighth frame. | ||||||||
| D92D | JP NZ,TestGroupObjects_Block | Leave this path on the other frames. | ||||||||
| D930 | LD A,(IY+$01) | Read the type byte again. | ||||||||
| D933 | ADD A,$03 | Add three to the type. | ||||||||
| D935 | AND %10000100 | Use bits 2 and 7 of the adjusted type. | ||||||||
| D937 | CP $84 | Match the object when the result is 84. | ||||||||
| D939 | CALL Z,TestObjectMatch | |||||||||
|
Build the object's x range from its first and third bytes, then test it against the x coordinate. A type of 82 uses a fixed size of 08.
|
||||||||||
| TestGroupObjects_Block | D93C | LD HL,($5CB8) | Fetch the word at TitleAnimationFrame. | |||||||
| D93F | LD A,(IY+$00) | Read the first byte of the object. | ||||||||
| D942 | AND %11110000 | Keep the high nibble as the low byte of the range. | ||||||||
| D944 | LD L,A | Keep that nibble as the low byte of the range. | ||||||||
| D945 | LD A,(IY+$02) | Read the third byte of the object. | ||||||||
| D948 | ADD A,A | Shift that byte up by four bits. | ||||||||
| D949 | ADD A,A | |||||||||
| D94A | ADD A,A | |||||||||
| D94B | ADD A,A | |||||||||
| D94C | AND %01110000 | Use bits 4-6 as the size. | ||||||||
| D94E | ADD A,$10 | Add the base size of 10. | ||||||||
| D950 | LD C,A | Keep the size. | ||||||||
| D951 | LD D,(IX+$02) | Fetch the x coordinate. | ||||||||
| D954 | LD E,(IX+$03) | |||||||||
| D957 | LD A,(IY+$01) | Read the type byte. | ||||||||
| D95A | INC A | Advance the type. | ||||||||
| D95B | AND %10000110 | Use bits 1, 2 and 7. | ||||||||
| D95D | CP $82 | Keep this size unless the type is 82. | ||||||||
| D95F | JR NZ,TestGroupObjects_XRange | |||||||||
| D961 | SET 2,L | Mark the fixed-size object. | ||||||||
| D963 | LD C,$08 | Use a size of 08. | ||||||||
| TestGroupObjects_XRange | D965 | LD ($D6E7),DE | Pass the x coordinate to the overlap test. | |||||||
| D969 | LD ($D6E4),HL | Pass the object's x range to the overlap test. | ||||||||
| D96C | LD B,(IX+$0B) | Fetch the x extent. | ||||||||
| D96F | CALL TestRangeOverlap | Test the two x ranges. | ||||||||
| D972 | JP NC,TestGroupObjects_Next | Skip the object when the x ranges do not overlap. | ||||||||
| D975 | LD ($DDCF),HL | Remember the x overlap. | ||||||||
| D978 | INC IX | Point the entity one byte on, so the y fields line up. | ||||||||
|
Build the object's y range in the same way, and test it against the y coordinate. IX still addresses the byte after the type, so a displacement reads the following field.
|
||||||||||
| D97A | LD HL,($5CB9) | Fetch the cell position again. | ||||||||
| D97D | LD A,(IY+$00) | Read the first byte of the object. | ||||||||
| D980 | ADD A,A | Shift it up by four bits. | ||||||||
| D981 | ADD A,A | |||||||||
| D982 | ADD A,A | |||||||||
| D983 | ADD A,A | |||||||||
| D984 | LD L,A | Keep it as the low byte of the range. | ||||||||
| D985 | LD A,(IY+$02) | Read the third byte of the object. | ||||||||
| D988 | ADD A,A | Double it. | ||||||||
| D989 | AND %01110000 | Use bits 4-6 as the size. | ||||||||
| D98B | ADD A,$10 | Add the base size of 10. | ||||||||
| D98D | LD C,A | Keep the size. | ||||||||
| D98E | LD D,(IX+$04) | Fetch the y coordinate. | ||||||||
| D991 | LD E,(IX+$05) | |||||||||
| D994 | LD B,(IX+$0B) | Fetch the y extent. | ||||||||
| D997 | LD A,(IY+$01) | Read the type byte. | ||||||||
| D99A | INC A | Advance the type. | ||||||||
| D99B | AND %10000110 | Use bits 1, 2 and 7. | ||||||||
| D99D | CP $82 | Keep this size unless the type is 82. | ||||||||
| D99F | JR NZ,TestGroupObjects_YRange | |||||||||
| D9A1 | SET 2,L | Mark the fixed-size object. | ||||||||
| D9A3 | LD C,$08 | Use a size of 08. | ||||||||
| TestGroupObjects_YRange | D9A5 | LD ($D6F8),DE | Pass the y coordinate to the overlap test. | |||||||
| D9A9 | LD ($D6F5),HL | Pass the object's y range to the overlap test. | ||||||||
| D9AC | CALL TestRangeOverlap | Test the two y ranges. | ||||||||
| D9AF | DEC IX | Restore the entity address. | ||||||||
| D9B1 | JP NC,TestGroupObjects_Next | Skip the object when the y ranges do not overlap. | ||||||||
| D9B4 | LD ($DDD1),HL | Remember the y overlap. | ||||||||
|
Compare the z coordinate with the object, and remember the smaller gap in field 1F.
|
||||||||||
| D9B7 | LD H,(IX+$08) | Fetch the z coordinate. | ||||||||
| D9BA | LD L,(IX+$09) | |||||||||
| D9BD | LD ($D6D6),HL | Pass the z coordinate to the edge test. | ||||||||
| D9C0 | LD A,(IY+$01) | Read the object's type. | ||||||||
| D9C3 | LD C,A | Keep the type aside. | ||||||||
| D9C4 | AND %00001111 | Use the low nibble of the type. | ||||||||
| D9C6 | LD L,A | Keep it as the low byte of the index. | ||||||||
| D9C7 | LD A,C | Bring bit 4 of the type down beside it. | ||||||||
| D9C8 | RRA | |||||||||
| D9C9 | RRA | |||||||||
| D9CA | RRA | |||||||||
| D9CB | AND %00010000 | Use that bit. | ||||||||
| D9CD | OR L | Combine it with the low nibble. | ||||||||
| D9CE | LD E,A | |||||||||
| D9CF | LD HL,$D7B3 | Look this kind up in the object flags. | ||||||||
| D9D2 | CALL AddToAddress | |||||||||
| D9D5 | LD A,(HL) | Read the flag byte. | ||||||||
| D9D6 | LD ($5CD8),A | Remember the object's flags. | ||||||||
| D9D9 | LD HL,($5CDC) | Fetch the cell offset. | ||||||||
| D9DC | INC H | Advance its high byte. | ||||||||
| D9DD | LD A,C | Take the type again. | ||||||||
| D9DE | AND %01110000 | Use bits 4-6 as a row within the group. | ||||||||
| D9E0 | ADD A,L | Add that row to the cell offset. | ||||||||
| D9E1 | LD L,A | |||||||||
| D9E2 | LD ($D6CF),HL | Pass the address to the edge test. | ||||||||
| TestGroupObjects_Heights | D9E5 | LD C,$00 | Start with no extra height. | |||||||
| D9E7 | LD A,E | A kind of 02 has no extra height. | ||||||||
| D9E8 | CP $02 | |||||||||
| D9EA | JR Z,TestGroupObjects_Overlap | |||||||||
| D9EC | LD A,(IY+$02) | Read the third byte of the object. | ||||||||
| D9EF | RRA | Shift it down by two. | ||||||||
| D9F0 | RRA | |||||||||
| D9F1 | AND %00110000 | Use bits 4-5 of that byte. | ||||||||
| D9F3 | JR NZ,TestGroupObjects_AddHeight | Use the looked-up height when those bits are set. | ||||||||
| D9F5 | BIT 7,(IY+$01) | Jump to TestGroupObjects_AddHeight to use the looked-up height when the top bit is clear. | ||||||||
| D9F9 | JR Z,TestGroupObjects_AddHeight | |||||||||
| D9FB | PUSH HL | Look up a height for this kind. | ||||||||
| D9FC | LD HL,$D7D4 | |||||||||
| D9FF | LD A,E | |||||||||
| DA00 | AND %00001111 | Use the low nibble of the kind. | ||||||||
| DA02 | CALL AddToAddress | Look the height up. | ||||||||
| DA05 | LD A,(HL) | Read the height. | ||||||||
| DA06 | POP HL | Restore the address and use that height. | ||||||||
| DA07 | JR TestGroupObjects_Height | |||||||||
| TestGroupObjects_AddHeight | DA09 | ADD A,$10 | Add 10 to the height. | |||||||
| TestGroupObjects_Height | DA0B | LD C,A | Keep the height. | |||||||
|
The entity is only touching the block when half of either extent, less two, still covers the overlap. A deeper overlap on both axes means the entity is inside the block.
|
||||||||||
| TestGroupObjects_Overlap | DA0C | LD A,$04 | Mark the entity as only touching the block. | |||||||
| DA0E | LD ($DD4C),A | |||||||||
| DA11 | LD A,($DDCF) | Fetch the x overlap. | ||||||||
| DA14 | LD B,A | Keep it. | ||||||||
| DA15 | LD A,(IX+$0B) | Compare half the x extent, less two, with the overlap. | ||||||||
| DA18 | SRL A | |||||||||
| DA1A | SUB $02 | |||||||||
| DA1C | CP B | |||||||||
| DA1D | JP NC,TestGroupObjects_ZRange | |||||||||
| DA20 | LD A,($DDD1) | Compare half the y extent, less two, with the overlap. | ||||||||
| DA23 | LD B,A | |||||||||
| DA24 | LD A,(IX+$0C) | |||||||||
| DA27 | SRL A | |||||||||
| DA29 | SUB $02 | |||||||||
| DA2B | CP B | |||||||||
| DA2C | JP NC,TestGroupObjects_ZRange | |||||||||
| DA2F | XOR A | The entity is inside the block, so clear the touching flag. | ||||||||
| DA30 | LD ($DD4C),A | |||||||||
| DA33 | PUSH HL | Remember the edge address. | ||||||||
| DA34 | LD A,($5CD8) | Read the object's flags. | ||||||||
| DA37 | RLA | Compare the z coordinate directly when the top flag is clear. | ||||||||
| DA38 | JR C,TestGroupObjects_Raised | |||||||||
| DA3A | LD B,$00 | Add the overlap to the edge address. | ||||||||
| DA3C | ADD HL,BC | |||||||||
| DA3D | EX DE,HL | |||||||||
| DA3E | LD H,(IX+$08) | Fetch the z coordinate. | ||||||||
| DA41 | LD L,(IX+$09) | |||||||||
| DA44 | XOR A | Subtract the edge. | ||||||||
| DA45 | SBC HL,DE | |||||||||
| DA47 | JR C,TestGroupObjects_Vertical | Leave this object if the entity is below the edge. | ||||||||
| DA49 | OR H | Leave this object unless the result is within one page. | ||||||||
| DA4A | JR NZ,TestGroupObjects_Vertical | |||||||||
| DA4C | LD E,L | The low byte is the gap. | ||||||||
| DA4D | JR TestGroupObjects_SaveGap | |||||||||
| TestGroupObjects_Raised | DA4F | EX DE,HL | Compare the z coordinate with the z extent instead. | |||||||
| DA50 | LD H,(IX+$08) | |||||||||
| DA53 | LD L,(IX+$09) | |||||||||
| DA56 | PUSH BC | |||||||||
| DA57 | LD B,$00 | |||||||||
| DA59 | LD A,(IX+$0D) | |||||||||
| DA5C | ADD A,$06 | |||||||||
| DA5E | LD C,A | |||||||||
| DA5F | ADD HL,BC | |||||||||
| DA60 | SBC HL,DE | |||||||||
| DA62 | POP BC | |||||||||
| DA63 | JR C,TestGroupObjects_Vertical | |||||||||
| DA65 | CALL TestWideOverlap | Test a wide block. | ||||||||
| DA68 | LD A,($5CD8) | Read the object's flags. | ||||||||
| DA6B | AND %01100000 | Use the layout in bits 5-6. | ||||||||
| DA6D | JR Z,TestGroupObjects_Gap | No further height test when the layout is clear. | ||||||||
| DA6F | CP $40 | A layout of 40 ends the height test. | ||||||||
| DA71 | JR NZ,TestGroupObjects_SaveGap | |||||||||
| TestGroupObjects_Gap | DA73 | LD A,E | Reduce the gap by four, and ignore a gap below four. | |||||||
| DA74 | SUB $04 | |||||||||
| DA76 | LD E,$00 | |||||||||
| DA78 | JR C,TestGroupObjects_SaveGap | |||||||||
| DA7A | LD E,A | Keep the reduced gap. | ||||||||
| DA7B | POP HL | Keep the smaller of the gap and the room above the entity. | ||||||||
| DA7C | PUSH HL | |||||||||
| DA7D | PUSH DE | |||||||||
| DA7E | LD B,$00 | |||||||||
| DA80 | ADD HL,BC | |||||||||
| DA81 | EX DE,HL | |||||||||
| DA82 | XOR A | |||||||||
| DA83 | LD H,(IX+$08) | |||||||||
| DA86 | LD L,(IX+$09) | |||||||||
| DA89 | SBC HL,DE | |||||||||
| DA8B | POP DE | |||||||||
| DA8C | JR C,TestGroupObjects_SaveGap | |||||||||
| DA8E | LD A,L | |||||||||
| DA8F | CP E | |||||||||
| DA90 | JR C,TestGroupObjects_SaveGap | |||||||||
| DA92 | LD E,L | |||||||||
| TestGroupObjects_SaveGap | DA93 | LD A,(IX+$1F) | Fetch the gap already stored for this entity. | |||||||
| DA96 | CP E | Keep the stored gap when it is the smaller one. | ||||||||
| DA97 | JR C,TestGroupObjects_Vertical | |||||||||
| DA99 | LD (IX+$1F),E | Remember this smaller gap. | ||||||||
| DA9C | RES 6,(IX+$1E) | Clear bit 6 of the flags. | ||||||||
|
Test the z range. The vertical speed is put back afterwards, and a stand-in value of 18 is used for the test.
|
||||||||||
| TestGroupObjects_Vertical | DAA0 | POP HL | Restore the edge address. | |||||||
| TestGroupObjects_ZRange | DAA1 | LD B,(IX+$12) | Fetch the vertical speed. | |||||||
| DAA4 | PUSH BC | Remember it. | ||||||||
| DAA5 | LD B,(IX+$0D) | Fetch the z extent. | ||||||||
| DAA8 | PUSH IX | Remember the entity. | ||||||||
| DAAA | LD DE,$FFFA | Move back to the byte the test reads. | ||||||||
| DAAD | ADD IX,DE | |||||||||
| DAAF | LD (IX+$18),$00 | Plant 18 for the test. | ||||||||
| DAB3 | LD DE,($D6D6) | Fetch the z coordinate passed to the test. | ||||||||
| DAB7 | CALL TestRangeOverlap | Test the z range. | ||||||||
| DABA | POP IX | Restore the entity. | ||||||||
| DABC | POP BC | Bring the vertical speed back. | ||||||||
| DABD | LD (IX+$12),B | Restore the vertical speed. | ||||||||
| DAC0 | JP NC,TestGroupObjects_Next | Leave this object when the z ranges do not overlap. | ||||||||
| DAC3 | BIT 7,(IX+$1E) | Test whether the entity is moving fast. | ||||||||
| DAC7 | JR Z,TestGroupObjects_Positive | The overlap is ordinary when the entity is not fast. | ||||||||
| DAC9 | BIT 7,H | Test the sign of the result. | ||||||||
| DACB | JR NZ,TestGroupObjects_ZOverlap | A negative result keeps the low byte. | ||||||||
| DACD | LD L,$FF | Force the low byte to FF. | ||||||||
| DACF | JR TestGroupObjects_ZOverlap | Join the stored overlap. | ||||||||
| TestGroupObjects_Positive | DAD1 | BIT 7,H | Test the sign of the result. | |||||||
| DAD3 | JR NZ,TestGroupObjects_ZOverlap | A negative result is stored as it is. | ||||||||
| DAD5 | INC L | Raise a positive overlap by two. | ||||||||
| DAD6 | INC L | |||||||||
| TestGroupObjects_ZOverlap | DAD7 | DEC L | Reduce the overlap by one. | |||||||
| DAD8 | LD ($DDD3),HL | Remember the z overlap. | ||||||||
| DADB | LD A,(IY+$01) | Read the object's type. | ||||||||
| DADE | AND %10001111 | Use the type bits that select a solid block. | ||||||||
| DAE0 | CP $83 | A type 83 is solid. | ||||||||
| DAE2 | JP Z,TestGroupObjects_Solid | |||||||||
| DAE5 | CP $85 | A type other than 85 is handled below. | ||||||||
| DAE7 | JR NZ,TestGroupObjects_Handle | |||||||||
| DAE9 | LD A,($DEE0) | Read how many bottles are left. | ||||||||
| DAEC | AND A | A type 85 is solid once no bottles are left. | ||||||||
| DAED | JP Z,TestGroupObjects_Solid | |||||||||
| TestGroupObjects_Handle | DAF0 | LD A,($5CD8) | Read the object's flags. | |||||||
| DAF3 | RLA | Test the edge when the top flag is set. | ||||||||
| DAF4 | CALL C,TestEdgeOverlap | |||||||||
| DAF7 | XOR A | Clear the handled flag. | ||||||||
| DAF8 | LD ($D5A4),A | |||||||||
| DAFB | LD A,($5CD8) | Read the flags again. | ||||||||
| DAFE | INC A | Handle the overlap unless the flags were FF. | ||||||||
| DAFF | CALL NZ,HandleOverlap | |||||||||
| DB02 | LD A,(IX+$00) | Only the player is placed against the block. | ||||||||
| DB05 | DEC A | |||||||||
| DB06 | JP NZ,TestGroupObjects_Special | |||||||||
| DB09 | LD A,($A2DD) | Read the frame counter. | ||||||||
| DB0C | AND $07 | Only on every eighth frame. | ||||||||
| DB0E | JP NZ,TestGroupObjects_Special | |||||||||
| DB11 | LD A,(IY+$01) | Read the object's type. | ||||||||
| DB14 | AND %10001110 | Use bits 1, 2, 3 and 7 of the type. | ||||||||
| DB16 | CP $02 | Only a type whose remaining bits are 02 places the player. | ||||||||
| DB18 | JP NZ,TestGroupObjects_Special | |||||||||
| DB1B | LD A,($D5A4) | Read the handled flag. | ||||||||
| DB1E | AND A | Leave the placement when the flag is clear. | ||||||||
| DB1F | JP Z,TestGroupObjects_Special | |||||||||
| DB22 | LD A,(IX+$1F) | Read the stored gap. | ||||||||
| DB25 | AND A | Leave the placement when a gap is already stored. | ||||||||
| DB26 | JP NZ,TestGroupObjects_Special | |||||||||
| DB29 | LD DE,($D6E7) | Fetch the x edge passed to the overlap test. | ||||||||
| DB2D | DEC DE | Step that edge back by two. | ||||||||
| DB2E | DEC DE | |||||||||
| DB2F | LD HL,($D6E4) | Fetch the other x edge. | ||||||||
| DB32 | AND A | Keep the first edge when it is the nearer. | ||||||||
| DB33 | SBC HL,DE | |||||||||
| DB35 | JR C,TestGroupObjects_XEdge | |||||||||
| DB37 | LD DE,($D6E4) | Otherwise use the other edge. | ||||||||
| TestGroupObjects_XEdge | DB3B | LD A,E | Keep the column of that edge. | |||||||
| DB3C | AND $F0 | |||||||||
| DB3E | LD E,A | |||||||||
| DB3F | LD ($E4C6),DE | Remember it as the position to match. | ||||||||
| DB43 | LD DE,($D6F8) | Fetch the y edge passed to the overlap test. | ||||||||
| DB47 | DEC DE | Step that edge back by two. | ||||||||
| DB48 | DEC DE | |||||||||
| DB49 | LD HL,($D6F5) | Fetch the other y edge. | ||||||||
| DB4C | AND A | Keep the first edge when it is the nearer. | ||||||||
| DB4D | SBC HL,DE | |||||||||
| DB4F | JR C,TestGroupObjects_YEdge | |||||||||
| DB51 | LD DE,($D6F5) | Otherwise use the other edge. | ||||||||
| TestGroupObjects_YEdge | DB55 | LD A,E | Keep the column of that edge. | |||||||
| DB56 | AND $F0 | |||||||||
| DB58 | LD E,A | |||||||||
| DB59 | LD ($E4C8),DE | Remember it as the other position to match. | ||||||||
| DB5D | LD DE,($B548) | Remember the player's height for the match. | ||||||||
| DB61 | LD ($E4CA),DE | |||||||||
| DB65 | JP TestGroupObjects_Special | Go on to the bottle and the exit. | ||||||||
|
A solid block matches the object, raises the entity by one, and pushes it back to the edge. If it is still inside, the position is set from both edges and FindPathAtPosition looks for a path there.
|
||||||||||
| TestGroupObjects_Solid | DB68 | CALL TestObjectMatch | Match the object. | |||||||
| DB6B | LD H,(IX+$08) | Fetch the z coordinate. | ||||||||
| DB6E | LD L,(IX+$09) | |||||||||
| DB71 | INC HL | Raise the entity by one. | ||||||||
| DB72 | LD (IX+$08),H | |||||||||
| DB75 | LD (IX+$09),L | |||||||||
| DB78 | LD A,($DD4C) | Read the touching flag. | ||||||||
| DB7B | AND A | Leave this object when the entity was only touching. | ||||||||
| DB7C | JR NZ,TestGroupObjects_Special | |||||||||
| DB7E | LD DE,($D6E4) | Fetch an x edge. | ||||||||
| DB82 | INC E | Step that edge on by three. | ||||||||
| DB83 | INC E | |||||||||
| DB84 | INC E | |||||||||
| DB85 | LD HL,($D6E7) | Fetch the other x edge. | ||||||||
| DB88 | PUSH HL | Turn that edge into a coordinate. | ||||||||
| DB89 | POP BC | |||||||||
| DB8A | AND A | Subtract the stepped edge. | ||||||||
| DB8B | SBC HL,DE | |||||||||
| DB8D | BIT 7,H | Jump to TestGroupObjects_PushX to push the entity the other way when the difference is negative. | ||||||||
| DB8F | JR NZ,TestGroupObjects_PushX | |||||||||
| DB91 | DEC BC | Step the edge back. | ||||||||
| DB92 | LD (IX+$02),B | Move the x coordinate back to that edge. | ||||||||
| DB95 | LD (IX+$03),C | |||||||||
| DB98 | LD BC,$0005 | Step the difference back by five. | ||||||||
| DB9B | SBC HL,BC | |||||||||
| DB9D | JR TestGroupObjects_TryY | |||||||||
| TestGroupObjects_PushX | DB9F | INC BC | Step the edge on. | |||||||
| DBA0 | LD (IX+$02),B | Move the x coordinate on to that edge. | ||||||||
| DBA3 | LD (IX+$03),C | |||||||||
| DBA6 | LD BC,$0004 | Step the difference on by four. | ||||||||
| DBA9 | ADD HL,BC | |||||||||
| TestGroupObjects_TryY | DBAA | JR NC,TestGroupObjects_Special | Leave this object when the x push was enough. | |||||||
| DBAC | PUSH DE | Remember the y edge. | ||||||||
| DBAD | LD DE,($D6F5) | Fetch a y edge. | ||||||||
| DBB1 | INC E | Step that edge on by three. | ||||||||
| DBB2 | INC E | |||||||||
| DBB3 | INC E | |||||||||
| DBB4 | LD HL,($D6F8) | Fetch the other y edge. | ||||||||
| DBB7 | PUSH HL | Turn that edge into a coordinate. | ||||||||
| DBB8 | POP BC | |||||||||
| DBB9 | AND A | Subtract the stepped edge. | ||||||||
| DBBA | SBC HL,DE | |||||||||
| DBBC | BIT 7,H | Jump to TestGroupObjects_PushY to push the entity the other way when the difference is negative. | ||||||||
| DBBE | JR NZ,TestGroupObjects_PushY | |||||||||
| DBC0 | DEC BC | Step the edge back. | ||||||||
| DBC1 | LD (IX+$05),B | Move the y coordinate back to that edge. | ||||||||
| DBC4 | LD (IX+$06),C | |||||||||
| DBC7 | LD BC,$0005 | Step the difference back by five. | ||||||||
| DBCA | SBC HL,BC | |||||||||
| DBCC | JR TestGroupObjects_Place | |||||||||
| TestGroupObjects_PushY | DBCE | INC BC | Step the edge on. | |||||||
| DBCF | LD (IX+$05),B | Move the y coordinate on to that edge. | ||||||||
| DBD2 | LD (IX+$06),C | |||||||||
| DBD5 | LD BC,$0004 | Step the difference on by four. | ||||||||
| DBD8 | ADD HL,BC | |||||||||
| TestGroupObjects_Place | DBD9 | POP BC | Restore the saved edge. | |||||||
| DBDA | JR NC,TestGroupObjects_Special | Leave this object when the y push was enough. | ||||||||
| DBDC | LD (IX+$02),B | Place the entity on both saved edges. | ||||||||
| DBDF | LD (IX+$03),C | |||||||||
| DBE2 | LD (IX+$05),D | |||||||||
| DBE5 | LD (IX+$06),E | |||||||||
| DBE8 | PUSH IY | Remember the object. | ||||||||
| DBEA | CALL FindPathAtPosition | Find the path at this position. | ||||||||
| DBED | POP IY | Restore the object. | ||||||||
|
A type 85 object shows the exit-closed message for the player while bottles remain. A type 81 object is a bottle.
|
||||||||||
| TestGroupObjects_Special | DBEF | LD A,(IY+$01) | Read the type byte. | |||||||
| DBF2 | AND %10001111 | Keep the type bits. | ||||||||
| DBF4 | CP $85 | Try a bottle unless the type is 85. | ||||||||
| DBF6 | JR NZ,TestGroupObjects_Bottle | |||||||||
| DBF8 | LD A,($DEE0) | Read how many bottles are left. | ||||||||
| DBFB | AND A | Leave the message alone when no bottles are left. | ||||||||
| DBFC | JR Z,TestGroupObjects_Next | |||||||||
| DBFE | LD A,(IX+$00) | Show the message for the player only. | ||||||||
| DC01 | DEC A | |||||||||
| DC02 | JP NZ,TestGroupObjects_Next | |||||||||
| DC05 | LD A,($CE59) | Read the exit message flag. | ||||||||
| DC08 | OR %00000010 | Set the exit-closed bit. | ||||||||
| DC0A | LD ($CE59),A | Update the exit message flag. | ||||||||
| DC0D | JP TestGroupObjects_Next | Go on to the next object. | ||||||||
| TestGroupObjects_Bottle | DC10 | CP $81 | Leave any object that is not a bottle. | |||||||
| DC12 | JR NZ,TestGroupObjects_Next | |||||||||
| DC14 | LD A,(IX+$00) | Collect a bottle for the player only. | ||||||||
| DC17 | DEC A | |||||||||
| DC18 | JR NZ,TestGroupObjects_Next | |||||||||
| DC1A | LD A,($DD4C) | Leave the bottle if the flag at DD4C is clear. | ||||||||
| DC1D | AND A | |||||||||
| DC1E | JR NZ,TestGroupObjects_Next | |||||||||
| DC20 | LD A,($D5A4) | Leave the bottle if the flag at D5A4 is set. | ||||||||
| DC23 | AND A | |||||||||
| DC24 | JR Z,TestGroupObjects_Next | |||||||||
| DC26 | PUSH IX | Collect the bottle, keeping the entity and the object. | ||||||||
| DC28 | PUSH IY | |||||||||
| DC2A | PUSH IY | |||||||||
| DC2C | POP IX | |||||||||
| DC2E | CALL CollectBottle | |||||||||
| DC31 | POP IY | |||||||||
| DC33 | POP IX | |||||||||
| TestGroupObjects_Next | DC35 | INC IY | Advance to the next object. | |||||||
| DC37 | INC IY | |||||||||
| DC39 | POP BC | Restore the object count. | ||||||||
| DC3A | DEC B | Take the next object until every object has been tested. | ||||||||
| DC3B | JP NZ,TestGroupObjects_Loop | |||||||||
| DC3E | RET | Return. | ||||||||
| Prev: D7E4 | Up: Map | Next: DC3F |