Prev: CC96 Up: Map Next: CE06
CCA7: Build a room's object records from the room directory
Used by the routine at ENTER_ROOM.
Finds the robot's room in ROOM02, stepping from record to record by the count at +1, and takes its ink (ROOM_INK), the address of its colour byte (ROOM_COLOUR_AT), and its half-sizes and floor from ROOM_SIZES. Then it fills the records from record 4 (ROOM_OBJECTS) up, backgrounds first, then objects, and clears every record after the last it filled. A room that is not in the directory gets no records at all. Called by ENTER_ROOM on entering a room; the first four records -- the robot's two and the two for the places -- are not touched.
Backgrounds: a byte each, up to an $FF. A background (BACKGROUND_TABLE) is a list of eight-byte pieces -- graphic, U, V, Z, the half-sizes, the height, flags -- ended by a zero, each piece its own record, with this room as its +8.
Objects: groups, each a header byte (bits 0-2 how many less one, bits 3-7 the template) and a position byte for each. A template (OBJECT_TABLE) is a list of five-byte pieces -- graphic, the half-sizes, the height, flags -- ended by a zero, each piece its own record at the same place: U = 72 + 16 times bits 0-2 of the position, V = 72 + 16 times bits 3-5, and Z = the floor + 12 times bits 6-7.
Two templates are not templates. Template 31 moves TEMPLATES_AT on 64 bytes, to the second page, and the byte after it is skipped (twelve times in the rooms). Template 0 makes the byte after it the placement nudge (PLACE_NUDGE) for the groups that follow: its bit 0 adds 8 to U, bit 1 adds 8 to V, and the rest is added to Z. The rooms use it 42 times, 41 of them with $30, which raises the objects that follow by 48 -- four levels -- and once with 0. Pentagram's builder has the same code for the nudge but no jump reaches it; in Alien 8 it is live.
The count at +1 of the room's record, of the bytes from there to the end, is what stops the build, not the data: the backgrounds can use it up, or a group be cut short. Nothing checks that the 52 records are enough; if a room overran them the clearing loop, which stops only when it reaches the end of the records exactly, would not stop. None does: every room was built in the build's sessions.
Input
IX the robot's legs, whose +8 is the room
BUILD_ROOM CCA7 LD HL,OBJECT_TABLE The first page of object templates, no nudge; LIFT_TOP cleared
CCAA LD (TEMPLATES_AT),HL
CCAD XOR A
CCAE LD (PLACE_NUDGE),A
CCB1 LD (LIFT_TOP),A
CCB4 LD DE,ROOM_OBJECTS DE = the first record to fill; BC = the end of the directory; HL = its first room
CCB7 LD BC,OBJECT_TABLE
CCBA LD HL,ROOM02
BUILD_ROOM_0 CCBD LD A,(HL) This room?
CCBE INC HL
CCBF CP (IX+$08)
CCC2 JR Z,BUILD_ROOM_1
CCC4 LD A,(HL) No: on by the count, until the end of the directory
CCC5 CALL ADD_HL_A
CCC8 AND A
CCC9 SBC HL,BC
CCCB JR NC,BUILD_CLEAR_REST
CCCD ADD HL,BC
CCCE JR BUILD_ROOM_0
BUILD_CLEAR_REST CCD0 LD HL,BELOW_BLOCK Clear the records from DE to the last; every way out of the builder ends here
CCD3 AND A
CCD4 SBC HL,DE
CCD6 RET Z
CCD7 LD B,$20
CCD9 CALL ZERO_DE
CCDC JR BUILD_CLEAR_REST
BUILD_ROOM_1 CCDE LD B,(HL) B = the count
CCDF INC HL
CCE0 LD A,(HL) The room's ink, and where its colour byte is
CCE1 AND $07
CCE3 LD (ROOM_INK),A
CCE6 LD (ROOM_COLOUR_AT),HL
CCE9 PUSH DE Bits 6-7 of the colour byte: which of the three sizes, times three
CCEA EX DE,HL
CCEB LD A,(DE)
CCEC INC DE
CCED RLCA
CCEE RLCA
CCEF AND $03
CCF1 LD C,A
CCF2 ADD A,A
CCF3 ADD A,C
CCF4 LD HL,ROOM_SIZES The half-sizes in U and V, and the floor
CCF7 CALL ADD_HL_A
CCFA LD A,(HL)
CCFB INC HL
CCFC LD (ROOM_HALF_U),A
CCFF LD A,(HL)
CD00 INC HL
CD01 LD (ROOM_HALF_V),A
CD04 LD A,(HL)
CD05 LD (FLOOR),A
CD08 DEC B Two of the count used; HL on the backgrounds, DE the record
CD09 DEC B
CD0A EX DE,HL
CD0B POP DE
BUILD_NEXT_BACKGROUND CD0C LD A,(HL) The backgrounds end at an $FF
CD0D INC HL
CD0E CP $FF
CD10 JR Z,BUILD_OBJECTS
CD12 PUSH BC HL = the background, the place in the room's record kept
CD13 PUSH HL
CD14 LD L,A
CD15 LD H,$00
CD17 ADD HL,HL
CD18 LD BC,BACKGROUND_TABLE
CD1B ADD HL,BC
CD1C LD A,(HL)
CD1D INC HL
CD1E LD H,(HL)
CD1F LD L,A
BUILD_BACKGROUND_PIECE CD20 LD BC,$0008 A piece: graphic, U, V, Z, half-sizes, height, flags into +0 to +7
CD23 LDIR
CD25 LD A,(IX+$08) +8: this room
CD28 LD (DE),A
CD29 INC DE
CD2A LD B,$17 +9 to +31 cleared; DE on the next record
CD2C CALL ZERO_DE
CD2F LD A,(HL) Another piece?
CD30 AND A
CD31 JR NZ,BUILD_BACKGROUND_PIECE
CD33 POP HL The next background, while the count lasts
CD34 POP BC
CD35 DJNZ BUILD_NEXT_BACKGROUND
CD37 JP BUILD_CLEAR_REST The count ran out
BUILD_OBJECTS CD3A DEC B The $FF counted
CD3B PUSH IY IY = the next record; the caller's IY kept
CD3D PUSH DE
CD3E POP IY
BUILD_NEXT_GROUP CD40 LD A,(HL) C = how many in this group
CD41 AND $07
CD43 INC A
CD44 LD C,A
CD45 LD A,(HL) The header counted; D = the first position; the place kept
CD46 INC HL
CD47 DEC B
CD48 LD D,(HL)
CD49 INC HL
CD4A PUSH HL
CD4B RRCA The template number doubled; template 0 sets the nudge
CD4C RRCA
CD4D AND $3E
CD4F JP Z,BUILD_SET_NUDGE
CD52 CP $3E Template 31 moves to the second page
CD54 JP Z,BUILD_TEMPLATE_PAGE
CD57 LD HL,(TEMPLATES_AT) HL = the template, from the page in TEMPLATES_AT
CD5A CALL ADD_HL_A
CD5D LD A,(HL)
CD5E INC HL
CD5F LD H,(HL)
CD60 LD L,A
BUILD_NEXT_OBJECT CD61 PUSH HL Kept for the next object of the group
BUILD_OBJECT_PIECE CD62 LD A,(HL) A piece: graphic into +0, half-sizes and height into +4 to +6, flags into +7
CD63 INC HL
CD64 LD (IY+$00),A
CD67 LD A,(HL)
CD68 INC HL
CD69 LD (IY+$04),A
CD6C LD A,(HL)
CD6D INC HL
CD6E LD (IY+$05),A
CD71 LD A,(HL)
CD72 INC HL
CD73 LD (IY+$06),A
CD76 LD A,(HL)
CD77 INC HL
CD78 LD (IY+$07),A
CD7B LD A,(IX+$08) +8: this room
CD7E LD (IY+$08),A
CD81 LD A,(PLACE_NUDGE) U from bits 0-2 of the position, and 8 more for bit 0 of the nudge
CD84 RLCA
CD85 RLCA
CD86 RLCA
CD87 AND $08
CD89 LD E,A
CD8A LD A,D
CD8B RLCA
CD8C RLCA
CD8D RLCA
CD8E RLCA
CD8F AND $70
CD91 ADD A,E
CD92 ADD A,$48
CD94 LD (IY+$01),A
CD97 LD A,(PLACE_NUDGE) V from bits 3-5, and 8 more for bit 1 of the nudge
CD9A RLCA
CD9B RLCA
CD9C AND $08
CD9E LD E,A
CD9F LD A,D
CDA0 RLCA
CDA1 AND $70
CDA3 ADD A,E
CDA4 ADD A,$48
CDA6 LD (IY+$02),A
CDA9 LD A,D Z from bits 6-7, 12 a level, plus the nudge less its bits 0-1, on the floor
CDAA RLCA
CDAB RLCA
CDAC AND $03
CDAE ADD A,A
CDAF ADD A,A
CDB0 LD E,A
CDB1 ADD A,A
CDB2 ADD A,E
CDB3 LD E,A
CDB4 LD A,(PLACE_NUDGE)
CDB7 ADD A,E
CDB8 AND $FC
CDBA LD E,A
CDBB LD A,(FLOOR)
CDBE ADD A,E
CDBF LD (IY+$03),A
CDC2 PUSH BC +9 to +31 cleared; IY on the next record
CDC3 LD BC,$0009
CDC6 ADD IY,BC
CDC8 LD B,$17
BUILD_ROOM_2 CDCA LD (IY+$00),$00
CDCE INC IY
CDD0 DJNZ BUILD_ROOM_2
CDD2 POP BC
CDD3 LD A,(HL) Another piece?
CDD4 AND A
CDD5 JR NZ,BUILD_OBJECT_PIECE
CDD7 POP DE DE = the template, HL = the place in the room's record
CDD8 POP HL
CDD9 DEC B The position counted; the end of the count ends the room
CDDA JR Z,BUILD_OBJECTS_DONE
CDDC DEC C The end of the group: the next header
CDDD JP Z,BUILD_NEXT_GROUP
CDE0 LD A,(HL) The next position, the same template
CDE1 INC HL
CDE2 PUSH HL
CDE3 EX DE,HL
CDE4 LD D,A
CDE5 JP BUILD_NEXT_OBJECT
BUILD_OBJECTS_DONE CDE8 PUSH IY DE = the next free record; the caller's IY back; clear the rest
CDEA POP DE
CDEB POP IY
CDED JP BUILD_CLEAR_REST
BUILD_TEMPLATE_PAGE CDF0 LD HL,(TEMPLATES_AT) Template 31: the next page of templates
CDF3 LD A,$40
CDF5 CALL ADD_HL_A
CDF8 LD (TEMPLATES_AT),HL
BUILD_ROOM_3 CDFB DEC B The byte after the header counted and skipped; the next group
CDFC POP HL
CDFD JP BUILD_NEXT_GROUP
BUILD_SET_NUDGE CE00 LD A,D Template 0: the byte after it is the nudge
CE01 LD (PLACE_NUDGE),A
CE04 JR BUILD_ROOM_3
Prev: CC96 Up: Map Next: CE06