Prev: 8965 Up: Map Next: 8A4D
8985: Draw a picture
Interprets the picture data at HL. Pictures are drawn with vector commands, not stored as bitmaps, which is how 22 full-width pictures fit into a few kilobytes. The first two bytes set the border colour and the colour of the picture area, which is cleared (8BE9); if Bilbo is in the dark the picture is not drawn at all.
The picture area is the top 128 pixel rows of the screen. The drawing position is kept in D (x, 0-255) and E (y, 0-127, measured upwards from the bottom); it starts in the middle, at (127,63). Then each command byte is one of:
Byte Command
$00 end of picture
$08 move: the next two bytes are the new x and y
%1dddssss, %sslllll line: bits 0-2 give the direction, bits 3-6 and the top two bits of the next byte give the slope, and the rest of that byte the length; drawn by 8B2F
%01000ccc, x, y flood fill from (x,y) with ink colour ccc (8A4F)
%00100ccc, address, runs... paint attribute cells with paper colour ccc: starting at the given attribute address, each following byte moves up, right, down or left (bits 0-1) a number of cells (bits 2-7, plus 1), painting as it goes; ended by $FF
Lines and fills also set the ink colour of every attribute cell they touch (8B93), so colour is applied as the picture is drawn. Anything else is ignored.
A picture normally ends with a 0. Two pictures (rooms 13 and 5) instead end with a move command whose coordinate bytes are the colour bytes of the next picture in memory, so they go on to draw that picture as well (see E02C and E142).
Input
HL Picture data
8985 PUSH IY Save the registers the caller uses
8987 PUSH HL
8988 PUSH HL IY = the picture data
8989 POP IY
898B PUSH DE
898C PUSH BC
898D CALL $8BE9 Set the border, clear and colour the picture area (or give up if Bilbo is in the dark)
8990 LD D,$7F Start the pen in the middle: x = 127...
8992 LD E,$3F ...y = 63
8994 LD B,$01
8996 LD C,$01
8998 LD L,$01
899A LD A,(IY+$00) NEXT COMMAND: fetch it
899D AND A Zero?
899E JP Z,$8A47 Yes: the end of the picture
89A1 INC IY
89A3 CP $08 $08: move the pen?
89A5 JR NZ,$89B3 No
89A7 LD D,(IY+$00) D = the new x
89AA INC IY
89AC LD E,(IY+$00) E = the new y
89AF INC IY
89B1 JR $899A Next command
89B3 BIT 7,A Bit 7 set: a line?
89B5 JR Z,$89D8 No
89B7 LD B,A
89B8 AND $07 C = the direction (bits 0-2)
89BA LD C,A
89BB LD A,B B = bits 3-6 of the first byte...
89BC RRCA
89BD AND $3C
89BF LD B,A
89C0 LD A,(IY+$00) L = the length (bottom six bits of the second byte, plus 1)
89C3 AND $3F
89C5 LD L,A
89C6 INC L
89C7 LD A,(IY+$00) ...combined with the top two bits of the second byte to give the slope
89CA INC IY
89CC RLCA
89CD RLCA
89CE AND $03
89D0 OR B
89D1 LD B,A
89D2 INC B (plus 1)
89D3 CALL $8B2F Draw the line
89D6 JR $899A Next command
89D8 BIT 6,A Bit 6 set: a flood fill?
89DA JR Z,$89F0 No
89DC AND $07 A = the colour
89DE PUSH DE Keep the pen position
89DF LD D,(IY+$00) D = x of the point to fill from
89E2 INC IY
89E4 LD E,(IY+$00) E = y
89E7 INC IY
89E9 CALL $8A4F Fill
89EC POP DE Restore the pen position
89ED JP $899A Next command
89F0 BIT 5,A Bit 5 set: paint character cells?
89F2 JP Z,$899A No: ignore the byte
89F5 AND $07 C = the colour, shifted into the paper bits
89F7 RLCA
89F8 RLCA
89F9 RLCA
89FA PUSH HL
89FB PUSH DE
89FC PUSH BC
89FD LD C,A
89FE LD H,(IY+$00) HL = the attribute address (high byte first)
8A01 INC IY
8A03 LD L,(IY+$00)
8A06 INC IY
8A08 LD A,(IY+$00) Next run byte
8A0B INC IY
8A0D CP $FF $FF ends the runs
8A0F JR Z,$8A41
8A11 LD B,A
8A12 AND $03 E = the direction (0 up, 1 right, 2 down, 3 left)
8A14 LD E,A
8A15 LD A,B B = the number of cells (bits 2-7, plus 1)
8A16 RRCA
8A17 RRCA
8A18 AND $3F
8A1A INC A
8A1B LD B,A
8A1C LD A,(HL) A = the cell's ink colour, shifted into the paper position
8A1D AND $07
8A1F RLCA
8A20 RLCA
8A21 RLCA
8A22 CP C Would the ink be the same as the new paper?
8A23 JR NZ,$8A27
8A25 XOR $38 Yes: use the complementary ink so the drawing stays visible
8A27 RRCA Shift the ink back down
8A28 RRCA
8A29 RRCA
8A2A OR C Combine with the new paper...
8A2B LD (HL),A ...and store the attribute
8A2C LD A,E Move one cell in the run's direction:
8A2D AND A
8A2E CALL Z,$8AD3 up,
8A31 DEC A
8A32 CALL Z,$8AFF right,
8A35 DEC A
8A36 CALL Z,$8AE4 down,
8A39 DEC A
8A3A CALL Z,$8AF5 or left
8A3D DJNZ $8A1C Next cell of the run
8A3F JR $8A08 Next run
8A41 POP BC
8A42 POP DE
8A43 POP HL
8A44 JP $899A Next command
This entry point is used by the routine at 8BE9.
8A47 POP BC Restore the registers
8A48 POP DE
8A49 POP HL
8A4A POP IY
8A4C RET
Prev: 8965 Up: Map Next: 8A4D