Prev: C460 Up: Map Next: C571
C501: Set up room foreground scenery objects - part 1
examples of foreground scenery objects
There are 16 foreground scenery objects, whose graphics addresses are held from 9897.
  • 'Brick' levels have an assortment of the first 8 (from 9897)
  • 'Cavern' levels have an assortment of the second 8 (from 98A7)
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