Routines |
Prev: C460 | Up: Map | Next: C571 |
|
||||
There are 16 foreground scenery objects, whose graphics addresses are held from 9897.
This routine calculates the number, types, and X/Y co-ordinates of scenery objects in the room, and stashes the data for each one into a 7-byte data set in a table at 7F01.
The following instructions identifies the level type. If it's a cavern-style level, sets the offset for the graphic address pointer to 8.
|
||||
C501 | LD A,($EAB7) | Get room number | ||
C504 | LD L,A | Store in L register | ||
C505 | CP $52 | If room number is 1-81 it's a 'brick style level'. For other scenery types it's actually rooms 1-82 (C178). This means the first room in the High Temple of Chaos (room 82) is a hybrid room, with brickwork walls but cavern foreground scenery. |
||
C507 | LD A,$00 | ...So set graphics offset EB77 to 0... | ||
C509 | JR C,$C50D | |||
C50B | LD A,$08 | ...Otherwise it's a 'cavern' style level, so set the offset to 8. | ||
C50D | LD ($EB77),A | Store the offset | ||
Bytes in the ROM, picked using the room number, are used to generate a varied but repeatable selection of foreground object types.
|
||||
C510 | LD H,$00 | Multiply room number by 8 | ||
C512 | ADD HL,HL | |||
C513 | ADD HL,HL | |||
C514 | ADD HL,HL | |||
C515 | EX DE,HL | ...Store result in DE register to be used for the ROM address | ||
C516 | LD HL,($EB70) | Get address pointer to the foreground object data table at 7F01 | ||
CALCULATE NUMBER OF FOREGROUND SCENERY OBJECTS
The first of the room data bytes at 61A9 reflects the size of the room.
The number of foreground objects in a room is this room size byte divided by two (rounded down).
|
||||
C519 | LD A,($EB7C) | Get (first) room data byte from banks at 61A9, which indicates the size of the room | ||
C51C | LD C,A | Temp store in C register | ||
C51D | RRA | Divide by 2 | ||
C51E | AND $7F | Filter out any carry bits caused by the RRA | ||
C520 | LD B,A | ...and store in B register as a counter for number-of-objects | ||
SET LEFTMOST OBJECT POSITION
The next bit calculates the first (leftmost) item's horizontal position (in 4-pixel/half-character steps) within the room, based on room size.
|
||||
C521 | LD A,C | Retrieve (first) room data byte from C register | ||
C522 | RLA | x 2 | ||
C523 | NEG | Make the value negative as the first object will be to the left of (or near) the leftmost screen wall | ||
C525 | ADD A,$08 | Add 8 to the value as a small offset, to move it over to the right slightly | ||
C527 | LD ($EB48),A | |||
IDENTIFY SCENERY OBJECT TYPE AND GRAPHIC ADDRESS POINTER
DE is currently pointing at a ROM address based on room number (x 8, so room 1 = memory address location 00008).
A combination of the room number and bytes from addresses in ROM are used to create a repeatable, but varied pattern of foreground scenery objects for each room.
|
||||
C52A | LD A,(DE) | Get byte from ROM | ||
C52B | INC DE | ...and move pointer along to next ROM address | ||
C52C | ADD A,B | Add byte from B register (which contains the first room data byte divided by 2) to added variation | ||
C52D | AND $07 | There are only 8 types of foreground object for each level type, so we only need bits 0-2 (values 0-7) | ||
C52F | ADD A,$6A | Add to the graphic address pointer table at 97C3. An offset of 106 puts the address pointer at the scenery objects at 9897. | ||
C531 | LD C,A | |||
C532 | LD A,($EB77) | Add the offset calculated earlier (either 0 or 8 depending on the level type). Offset should now be between 106 and 121 | ||
C535 | ADD A,C | |||
C536 | LD ($EABE),HL | Store address pointer to the foreground object data set at 7F01 | ||
C539 | LD ($EB7A),DE | Store ROM address pointer | ||
C53D | LD D,$00 | Double the offset value to create an address pointer offset in DE | ||
C53F | RLA | |||
C540 | RL D | Filter out bit 0 to ensure it's an even number | ||
C542 | AND $FE | |||
C544 | LD E,A | |||
C545 | LD HL,($EB6A) | Get the base graphics address pointer | ||
C548 | ADD HL,DE | Add the offset | ||
C549 | LD E,(HL) | Get the scenery graphics address in the DE register, e.g. AA5B for the skeleton | ||
C54A | INC HL | |||
C54B | LD D,(HL) | |||
COPY FOREGROUND SCENERY DATA VARIABLES INTO DATA SETS
Foreground scenery object data is stored in the data tables at 7F01.
|
||||
C54C | LD HL,($EABE) | Retrieve address pointer to foreground object data sets at 7F01 | ||
C54F | LD (HL),$00 | First byte default value = 0 (item not on screen) | ||
C551 | INC HL | |||
C552 | LD (HL),$00 | Horizontal position precision/fraction byte = 0 (item starting position will be a multiple of 8 pixels) | ||
C554 | INC HL | |||
C555 | LD A,($EB48) | Horizontal position in room. This is in 1-character/8-pixel steps (foreground scenery moves in larger distance increments than other scenery) | ||
C558 | LD (HL),A | |||
C559 | INC HL | |||
C55A | ADD A,$10 | Add 16 to the horizontal position and re-store. The value of 16 puts a gap of 16 character squares between foreground objects. | ||
C55C | LD ($EB48),A | |||
C55F | LD (HL),$00 | Vertical position precision/fraction byte (not needed here) | ||
C561 | INC HL | |||
C562 | LD (HL),$68 | Vertical position from top of playing area, in pixels - default position = 104 | ||
C564 | INC HL | |||
C565 | LD (HL),E | Address pointer to the scenery graphic to draw, e.g. AA5B | ||
C566 | INC HL | |||
C567 | LD (HL),D | |||
C568 | INC HL | |||
C569 | LD DE,($EB7A) | Retrieve ROM address pointer | ||
C56D | DJNZ $C52A | Continue to store object details in the 7 byte scenery data banks at 7F01. B register = count of objects that need storing. | ||
C56F | LD (HL),$FF | Set end-of-data byte to indicate the end of room foreground scenery object sets |
Prev: C460 | Up: Map | Next: C571 |