Prev: E87D Up: Map Next: EACC
E89B: The room commands $C1-$E4: lines, mode bits, repeats, parts, the clean copy and $E4
Used by the routine at DO_ROOM_COMMAND.
Where the command interpreter (DO_ROOM_COMMAND) sends every code below $E6 that it has not dealt with itself -- it takes the points ($00-$BF), $C0, $CF, $D0 and $D6, and in object mode the objects. A cascade of comparisons; a code that none of them matches ($D1, $D3, $D4, $D7-$DF and $E3) does nothing and has no operand. The lengths of every code are laid out command by command in the rooms (ROOM1) and parts (PART1).
$D2 draws a line from the second point to the first, both ends included (DRAW_LINE; DO_ROOM_COMMAND also calls it after each point while mode bit 5 is on). It is Bresenham's: a step along the longer distance every pixel, and one along the shorter whenever the running error passes the longer. The first pixel goes through PLOT_LINE_START; the rest are plotted here with the same pen, stepping the screen address a line or a pixel at a time rather than working it out afresh.
$C1-$CE set and clear the mode bits (MODE), which the interpreter reads before every command. Bit 0 ($CB on, $CC off): lines clear pixels. Bit 1 ($CD on, $CE off): lines flip pixels. Bit 2 ($C3, $C4): after each point the second point is moved to it, so that with bit 5 the points make a joined line. Bit 3 ($C5, $C6): the second point moves along with the first. Bit 4 ($C1, $C2): points are relative -- their bytes are added to the point before, and those of $C0 and $E4 $05 to the second point and the origin. Bit 5 ($C7, $C8): a line from the second point to each new point. Bit 6 ($C9, $CA): the column bytes are negated or complemented, which mirrors the drawing left to right. Bit 7 is object mode, which $E4 $04 turns on. How the points use bits 2 to 6 is DO_ROOM_COMMAND's.
$D5 n repeats what follows, up to the $D6 that DO_ROOM_COMMAND handles, n times: the count goes in REPEATS and the place to go back to in REPEAT_FROM, so there is one repeat at a time. $E0 n and $E1 n draw part n (PART1) in the middle of the room's commands and come back to them; $E1 keeps the drawing's state as it was -- both points, the origin, the mode and the repeat, which it saves and restores -- and $E0 lets the part change it. Either way object mode ends with the part. $E2 copies the screen into the clean copy: from then on, what has been drawn so far bounds the fills.
$E4 has a second byte. $E4 $00 clears the clean copy and sends the lines into it, where they bound a fill without being seen; $E4 $01 sends them back to the screen. Room 2 uses the pair to lay a second texture over part of a wall that is already textured, inside an outline drawn only in the clean copy (measured: without them the fill finds its first point already set and does nothing); part 16 does the same. $E4 $04 turns object mode on, and $E4 $05 x y z sets the origin (ORIGIN, ORIGIN_Y, ORIGIN_Z) that is added to the place of each object a room's commands put down -- rooms 13 and 17 draw one part's objects several times over, moving the origin each time. Both first place the object table's things in the room (PLACE_ROOM_OBJECTS), once in each drawing of a room, whichever comes first -- so the table's things are always placed with the origin at 0, and their places are the room's own. Any other second byte does nothing.
Of these codes only $CE occurs in no room or part. Room 26 is the only one to turn flipping on, for its last line, which crosses a wall that is already textured; its drawing ends soon after, so nothing needs to turn it off (measured: with the line drawn in set pixels instead, 36 pixels of the room come out different).
MORE_ROOM_COMMANDS E89B CP $D2 not $D2: the other codes
E89D JP NZ,ROOM_MODE_CODES
This entry point is used by the routine at DO_ROOM_COMMAND.
DRAW_LINE E8A0 LD BC,(SECOND_POINT) the line starts at the second point
E8A4 CALL PLOT_LINE_START
E8A7 EXX rows: how far to the first point, and which way (D +1 down the screen, -1 up)
E8A8 LD A,(SECOND_POINT_ROW)
E8AB SUB (IY+POINT_ROW-V)
E8AE LD D,$01
E8B0 JR NC,MORE_ROOM_COMMANDS_0
E8B2 CPL
E8B3 INC A
E8B4 LD D,$FF
MORE_ROOM_COMMANDS_0 E8B6 LD B,A B = the rows
E8B7 LD A,(SECOND_POINT) columns: E +1 to go left, -1 right
E8BA SUB (IY+POINT-V)
E8BD LD E,$01
E8BF JR NC,MORE_ROOM_COMMANDS_1
E8C1 CPL
E8C2 INC A
E8C3 LD E,$FF
MORE_ROOM_COMMANDS_1 E8C5 LD C,A C = the columns
E8C6 CP B more rows than columns: every step moves a row, some a column too (the plain step has no column)
E8C7 JR NC,MORE_ROOM_COMMANDS_2
E8C9 LD L,C
E8CA PUSH DE
E8CB XOR A
E8CC LD E,A
E8CD JR MORE_ROOM_COMMANDS_3
MORE_ROOM_COMMANDS_2 E8CF OR C more columns: every step moves a column (the plain step has no row); nothing more to do if the points are the same
E8D0 RET Z
E8D1 LD L,B
E8D2 LD B,C
E8D3 PUSH DE
E8D4 LD D,$00
MORE_ROOM_COMMANDS_3 E8D6 LD H,B H = steps, the longer distance; the error starts at half of it
E8D7 LD A,B
E8D8 RRA
MORE_ROOM_COMMANDS_4 E8D9 ADD A,L add the shorter distance: past the longer?
E8DA JR C,MORE_ROOM_COMMANDS_5
E8DC CP H
E8DD JR C,MORE_ROOM_COMMANDS_6
MORE_ROOM_COMMANDS_5 E8DF SUB H yes: take the longer off, and step both ways (the step pushed first)
E8E0 LD C,A
E8E1 EXX
E8E2 POP BC
E8E3 PUSH BC
E8E4 JR MORE_ROOM_COMMANDS_7
MORE_ROOM_COMMANDS_6 E8E6 LD C,A no: the plain step
E8E7 PUSH DE
E8E8 EXX
E8E9 POP BC
MORE_ROOM_COMMANDS_7 E8EA LD A,B a row to move?
E8EB AND A
E8EC JR Z,MORE_ROOM_COMMANDS_9
E8EE ADD A,H down a line: into the next character row, and into the next third only if L carried
E8EF LD H,A
E8F0 AND $07
E8F2 JR NZ,MORE_ROOM_COMMANDS_8
E8F4 BIT 7,B
E8F6 JR NZ,MORE_ROOM_COMMANDS_9
E8F8 LD A,L
E8F9 ADD A,$20
E8FB LD L,A
E8FC JR C,MORE_ROOM_COMMANDS_9
E8FE LD A,H
E8FF SUB $08
E901 LD H,A
E902 JR MORE_ROOM_COMMANDS_9
MORE_ROOM_COMMANDS_8 E904 XOR $07 up a line: the same, the other way
E906 JR NZ,MORE_ROOM_COMMANDS_9
E908 BIT 7,B
E90A JR Z,MORE_ROOM_COMMANDS_9
E90C LD A,L
E90D SUB $20
E90F LD L,A
E910 JR C,MORE_ROOM_COMMANDS_9
E912 LD A,H
E913 ADD A,$08
E915 LD H,A
MORE_ROOM_COMMANDS_9 E916 LD A,C a column to move?
E917 AND A
E918 JR Z,MORE_ROOM_COMMANDS_11
E91A RLA left: the mask moves left, into the byte before when it wraps
E91B JR C,MORE_ROOM_COMMANDS_10
E91D LD A,D
E91E RLCA
E91F LD D,A
E920 JR NC,MORE_ROOM_COMMANDS_11
E922 DEC L
E923 JR MORE_ROOM_COMMANDS_11
MORE_ROOM_COMMANDS_10 E925 LD A,D right
E926 RRCA
E927 LD D,A
E928 JR NC,MORE_ROOM_COMMANDS_11
E92A INC L
MORE_ROOM_COMMANDS_11 E92B BIT 1,(IY+MODE-V) plot it with the pen, as PLOT_LINE_START does
E92F LD A,(HL)
E930 JR NZ,MORE_ROOM_COMMANDS_12
E932 OR D
E933 BIT 0,(IY+MODE-V)
E937 JR Z,MORE_ROOM_COMMANDS_13
MORE_ROOM_COMMANDS_12 E939 XOR D
MORE_ROOM_COMMANDS_13 E93A LD (HL),A
E93B EXX the error back in A; the next step
E93C LD A,C
E93D DJNZ MORE_ROOM_COMMANDS_4
E93F POP DE drop the step saved at the start
E940 RET
ROOM_MODE_CODES E941 CP $CB $CB: bit 0 on
E943 JR NZ,MORE_ROOM_COMMANDS_14
E945 LD C,$01
E947 JR MORE_ROOM_COMMANDS_16
MORE_ROOM_COMMANDS_14 E949 CP $CD $CD: bit 1 on
E94B JR NZ,MORE_ROOM_COMMANDS_15
E94D LD C,$02
E94F JR MORE_ROOM_COMMANDS_16
MORE_ROOM_COMMANDS_15 E951 CP $C3 $C3: bit 2 on
E953 JR NZ,MORE_ROOM_COMMANDS_17
E955 LD C,$04
MORE_ROOM_COMMANDS_16 E957 LD A,(MODE) set the bit in MODE
E95A OR C
E95B LD (MODE),A
E95E RET
MORE_ROOM_COMMANDS_17 E95F CP $C7 $C7: bit 5 on
E961 JR NZ,MORE_ROOM_COMMANDS_18
E963 LD C,$20
E965 JR MORE_ROOM_COMMANDS_16
MORE_ROOM_COMMANDS_18 E967 CP $C5 $C5: bit 3 on
E969 JR NZ,MORE_ROOM_COMMANDS_19
E96B LD C,$08
E96D JR MORE_ROOM_COMMANDS_16
MORE_ROOM_COMMANDS_19 E96F CP $C1 $C1: bit 4 on
E971 JR NZ,MORE_ROOM_COMMANDS_20
E973 LD C,$10
E975 JR MORE_ROOM_COMMANDS_16
MORE_ROOM_COMMANDS_20 E977 CP $C9 $C9: bit 6 on
E979 JR NZ,MORE_ROOM_COMMANDS_21
E97B LD C,$40
E97D JR MORE_ROOM_COMMANDS_16
MORE_ROOM_COMMANDS_21 E97F CP $CA $CA: bit 6 off
E981 JR NZ,MORE_ROOM_COMMANDS_22
E983 LD C,$BF
E985 JR MORE_ROOM_COMMANDS_28
MORE_ROOM_COMMANDS_22 E987 CP $C2 $C2: bit 4 off
E989 JR NZ,MORE_ROOM_COMMANDS_23
E98B LD C,$EF
E98D JR MORE_ROOM_COMMANDS_28
MORE_ROOM_COMMANDS_23 E98F CP $CE $CE: bit 1 off (no room or part has it)
E991 JR NZ,MORE_ROOM_COMMANDS_24
E993 LD C,$FD
E995 JR MORE_ROOM_COMMANDS_28
MORE_ROOM_COMMANDS_24 E997 CP $CC $CC: bit 0 off
E999 JR NZ,MORE_ROOM_COMMANDS_25
E99B LD C,$FE
E99D JR MORE_ROOM_COMMANDS_28
MORE_ROOM_COMMANDS_25 E99F CP $C8 $C8: bit 5 off
E9A1 JR NZ,MORE_ROOM_COMMANDS_26
E9A3 LD C,$DF
E9A5 JR MORE_ROOM_COMMANDS_28
MORE_ROOM_COMMANDS_26 E9A7 CP $C6 $C6: bit 3 off
E9A9 JR NZ,MORE_ROOM_COMMANDS_27
E9AB LD C,$F7
E9AD JR MORE_ROOM_COMMANDS_28
MORE_ROOM_COMMANDS_27 E9AF CP $C4 $C4: bit 2 off
E9B1 JR NZ,MORE_ROOM_COMMANDS_29
E9B3 LD C,$FB
MORE_ROOM_COMMANDS_28 E9B5 LD A,D clear the bit (D is MODE, as the interpreter read it)
E9B6 AND C
E9B7 LD (MODE),A
E9BA RET
MORE_ROOM_COMMANDS_29 E9BB CP $D5 $D5 n
E9BD JR NZ,MORE_ROOM_COMMANDS_30
E9BF INC IX the count, and where to go back to: the count's own place, which the interpreter steps past
E9C1 LD A,(IX+$00)
E9C4 LD (REPEATS),A
E9C7 LD (REPEAT_FROM),IX
E9CB RET
MORE_ROOM_COMMANDS_30 E9CC CP $E1 $E1 n
E9CE JR NZ,MORE_ROOM_COMMANDS_31
E9D0 LD HL,(POINT) keep the points, the mode, the repeat, the origin and the bytes between
E9D3 PUSH HL
E9D4 LD HL,(SECOND_POINT)
E9D7 PUSH HL
E9D8 LD E,(IY+WORK_SPRITE-V)
E9DB PUSH DE
E9DC LD HL,(REPEATS)
E9DF PUSH HL
E9E0 LD HL,(REPEAT_FROM)
E9E3 PUSH HL
E9E4 LD HL,(WORK_KIND)
E9E7 PUSH HL
E9E8 LD HL,(ORIGIN)
E9EB PUSH HL
E9EC LD HL,(ORIGIN_Z)
E9EF PUSH HL
E9F0 CALL DRAW_PART draw the part
E9F3 POP HL and put them all back
E9F4 LD (ORIGIN_Z),HL
E9F7 POP HL
E9F8 LD (ORIGIN),HL
E9FB POP HL
E9FC LD (WORK_KIND),HL
E9FF POP HL
EA00 LD (REPEAT_FROM),HL
EA03 POP HL
EA04 LD (REPEATS),HL
EA07 POP HL
EA08 LD A,L
EA09 LD (WORK_SPRITE),A
EA0C LD A,H
EA0D LD (MODE),A
EA10 POP HL
EA11 LD (SECOND_POINT),HL
EA14 POP HL
EA15 LD (POINT),HL
EA18 RET
MORE_ROOM_COMMANDS_31 EA19 CP $E0 $E0 n
EA1B JR NZ,MORE_ROOM_COMMANDS_34
DRAW_PART EA1D INC IX the part's number; the parts from PART1, the first numbered 1
EA1F LD B,(IX+$00)
EA22 LD HL,(PARTS_TABLE)
EA25 LD A,$01
EA27 LD C,A
MORE_ROOM_COMMANDS_32 EA28 LD A,C this one?
EA29 CP B
EA2A JR NZ,MORE_ROOM_COMMANDS_33
EA2C PUSH IX yes: run its commands to its $E5, after its length; object mode ends with it
EA2E INC HL
EA2F INC HL
EA30 PUSH HL
EA31 POP IX
EA33 CALL RUN_ROOM_COMMANDS
EA36 RES 7,(IY+MODE-V)
EA3A POP IX
EA3C RET
MORE_ROOM_COMMANDS_33 EA3D PUSH HL no: past it by its length
EA3E LD E,(HL)
EA3F INC HL
EA40 LD D,(HL)
EA41 POP HL
EA42 ADD HL,DE
EA43 INC C
EA44 JR MORE_ROOM_COMMANDS_32
MORE_ROOM_COMMANDS_34 EA46 CP $E2 $E2
EA48 JR NZ,MORE_ROOM_COMMANDS_36
EA4A LD HL,$4000 the screen...
EA4D LD E,$00
MORE_ROOM_COMMANDS_35 EA4F LD A,$40 ...into the clean copy, its 6144 bytes of pixels
EA51 ADD A,$80
EA53 LD D,A
EA54 LD BC,$1800
EA57 LDIR
EA59 RET
MORE_ROOM_COMMANDS_36 EA5A CP $E4 $E4, or nothing
EA5C RET NZ
EA5D INC IX the second byte
EA5F LD A,(IX+$00)
EA62 CP $00
EA64 JR NZ,MORE_ROOM_COMMANDS_37
EA66 LD HL,$BFFF 0: clear the clean copy (a zero at the end of the records area, RECORDS, copied along it) and send lines into it
EA69 LD (HL),$00
EA6B LD (IY+LINE_PAGE-V),$80
EA6F LD E,$00
EA71 JR MORE_ROOM_COMMANDS_35
MORE_ROOM_COMMANDS_37 EA73 CP $01 1: lines onto the screen again
EA75 JR NZ,MORE_ROOM_COMMANDS_38
EA77 LD (IY+LINE_PAGE-V),$00
EA7B RET
MORE_ROOM_COMMANDS_38 EA7C CP $04 4: object mode on
EA7E JR NZ,MORE_ROOM_COMMANDS_39
EA80 SET 7,(IY+MODE-V)
PLACE_OBJECTS_ONCE EA84 BIT 0,(IY+OBJECTS_PLACED-V) place the object table's things in the room, if this drawing has not yet
EA88 RET NZ
EA89 SET 0,(IY+OBJECTS_PLACED-V)
EA8D PUSH IX
EA8F CALL PLACE_ROOM_OBJECTS
EA92 POP IX
EA94 RET
MORE_ROOM_COMMANDS_39 EA95 CP $05 5: place them too
EA97 RET NZ
EA98 CALL PLACE_OBJECTS_ONCE
EA9B INC IX then the origin's three bytes, each added to the origin as it is while mode bit 4 is on
EA9D LD D,(IY+MODE-V)
EAA0 LD A,(IX+$00)
EAA3 BIT 4,D
EAA5 JR Z,MORE_ROOM_COMMANDS_40
EAA7 ADD A,(IY+ORIGIN-V)
MORE_ROOM_COMMANDS_40 EAAA LD (ORIGIN),A
EAAD INC IX
EAAF LD A,(IX+$00)
EAB2 BIT 4,D
EAB4 JR Z,MORE_ROOM_COMMANDS_41
EAB6 ADD A,(IY+ORIGIN_Y-V)
MORE_ROOM_COMMANDS_41 EAB9 LD (ORIGIN_Y),A
EABC INC IX
EABE LD A,(IX+$00)
EAC1 BIT 4,D
EAC3 JR Z,MORE_ROOM_COMMANDS_42
EAC5 ADD A,(IY+ORIGIN_Z-V)
MORE_ROOM_COMMANDS_42 EAC8 LD (ORIGIN_Z),A
EACB RET done
Prev: E87D Up: Map Next: EACC