Prev: BAF7 Up: Map Next: BCAA
BB98: Restore tiles
This paints any tiles occupied by visible characters with tiles from tile_buf.
Used by the routine at main_loop.
restore_tiles BB98 LD B,$08 Set B for eight iterations
BB9A LD IY,$8000 Point IY at the first vischar
Start loop (once per vischar)
rt_loop BB9E PUSH BC Preserve the loop counter
BB9F LD A,(IY+$01) Read the vischar's flags byte
BBA2 CP $FF Is it vischar_FLAGS_EMPTY_SLOT? ($FF)
BBA4 JP Z,rt_next_vischar Jump to the next iteration if so
Get the visible character's position in screen space.
Compute iso_pos_y = vischar.iso_pos.y / 8.
BBA7 LD H,(IY+$1B) Read vischar.iso_pos.y
BBAA LD A,(IY+$1A)
BBAD SRL H Shift it right by three bits
BBAF RRA
BBB0 SRL H
BBB2 RRA
BBB3 SRL H
BBB5 RRA
BBB6 LD ($81B6),A Store low byte
Compute iso_pos_x = vischar.iso_pos.x / 8.
BBB9 LD H,(IY+$19) Read vischar.iso_pos.x
BBBC LD A,(IY+$18)
BBBF SRL H Shift it right by three bits
BBC1 RRA
BBC2 SRL H
BBC4 RRA
BBC5 SRL H
BBC7 RRA
BBC8 LD ($81B5),A Store low byte
Clip.
BBCB CALL vischar_visible Clip the vischar's dimensions to the game window
BBCE CP $FF Jump to next iteration if not visible ($FF)
BBD0 JP Z,rt_next_vischar
Compute scaled clipped height = (clipped height / 8) + 2
BBD3 LD A,E Copy clipped height
BBD4 RRA Shift it right by three bits
BBD5 RRA
BBD6 RRA
BBD7 AND $1F Mask away the rotated-out bits
BBD9 ADD A,$02 Add two
BBDB PUSH AF Save the computed height
Commentary: It seems that the following sequence (from $BBDC to $BC01) duplicates the work done by vischar_visible. I can't see any benefit to it.
Compute bottom = height + iso_pos_y - map_position_y. This is the distance of the (clipped) bottom edge of the vischar from the top of the window.
BBDC LD HL,$81B6 Point HL at iso_pos_y
BBDF ADD A,(HL) Add iso_pos_y to height
BBE0 LD HL,$81BC Point HL at map_position_y
BBE3 SUB (HL) Subtract map_position_y from the total
BBE4 JR C,rt_visible Jump if bottom is < 0 (the bottom edge is beyond the top edge of screen)
Bottom edge is on-screen, or off the bottom of the screen.
BBE6 SUB $11 Now reduce bottom by the height of the game window
BBE8 JR Z,rt_visible Jump over if <= 17 (bottom edge off top of screen)
BBEA JR C,rt_visible
Bottom edge is now definitely visible.
BBEC LD E,A Save new bottom
BBED POP AF Get computed height back
BBEE SUB E Calculate visible height = computed height - bottom
BBEF JP C,rt_next_vischar If invisible (height < 0) goto next
BBF2 JR NZ,rt_clamp_height Jump if visible (height > 0)
BBF4 JP rt_next_vischar If invisible (height == 0) goto next
rt_visible BBF7 POP AF Restore computed height
Clamp the height to a maximum of five.
rt_clamp_height BBF8 CP $05 Compare height to 5
BBFA JP Z,restore_tiles_0 Jump over if equal to 5
BBFD JP C,restore_tiles_0 Jump over if less than 5
BC00 LD A,$05 Otherwise set it to 5
Self modify the loops' control instructions.
restore_tiles_0 BC02 LD ($BC5F),A Self modify the outer loop counter (= height)
BC05 LD A,C Copy (clipped) width to A
BC06 LD ($BC61),A Self modify the inner loop counter (= width)
BC09 LD ($BC89),A Self modify the "reset x" instruction (= width)
BC0C LD A,$18 Compute tilebuf_skip = 24 - width (24 is window columns)
BC0E SUB C
BC0F LD ($BC8E),A Self modify the "tilebuf row-to-row skip" instruction
BC12 ADD A,$A8 Compute windowbuf_skip = (8 * 24) - width
BC14 LD ($BC95),A Self modify the "windowbuf row-to-row skip" instruction
Work out x,y offsets into the tile buffer.
X part
BC17 LD HL,$81BB Point HL at map_position.x
BC1A LD A,B Copy the lefthand skip into A
BC1B AND A Is it zero?
BC1C LD A,$00 Set x to zero (interleaved)
BC1E JR NZ,restore_tiles_1 Jump if not
BC20 LD A,($81B5) Compute x = iso_pos_x - map_position.x
BC23 SUB (HL)
restore_tiles_1 BC24 LD B,A
Y part
BC25 LD A,D Copy top skip into A
BC26 AND A Is it zero?
BC27 LD A,$00 Set Y to zero (interleaved)
BC29 JR NZ,restore_tiles_2 Jump if not
BC2B INC HL Advance HL to map_position.y
BC2C LD A,($81B6) Compute y = iso_pos_y - map_position.y
BC2F SUB (HL)
restore_tiles_2 BC30 LD C,A
Calculate the offset into the window buffer.
BC31 LD H,C DE = y << 7 (== y * 128)
BC32 XOR A
BC33 SRL H
BC35 RRA
BC36 LD E,A
BC37 LD D,H
BC38 SRL H HL = y << 6 (== y * 64)
BC3A RRA
BC3B LD L,A
BC3C ADD HL,DE Sum DE and HL = y * 192 (== y * 24 * 8)
BC3D LD E,B HL += x
BC3E LD D,$00
BC40 ADD HL,DE
BC41 LD DE,$F290 Point DE at the window buffer's start address (windowbuf)
BC44 ADD HL,DE Add
BC45 EX DE,HL Swap the buffer offset into DE. HL is about to be overwritten
Calculate the offset into the tile buffer.
Compute pointer = C * 24 + A + $F0F8
BC46 PUSH BC Stack the x and y values
BC47 EXX Bank
BC48 POP HL Restore into HL
BC49 EXX Unbank
BC4A LD A,B Copy x into A
BC4B LD L,C HL = y
BC4C LD H,$00
BC4E ADD HL,HL Multiply it by 8
BC4F ADD HL,HL
BC50 ADD HL,HL
BC51 LD C,L Copy result to BC
BC52 LD B,H
BC53 ADD HL,HL Double result
BC54 ADD HL,BC = y * 8 + y * 16
BC55 LD C,A Copy x into BC
BC56 LD B,$00
BC58 ADD HL,BC = y * 24 + x
BC59 LD BC,$F0F8 Point DE at the visible tiles array (tilebuf)
BC5C ADD HL,BC = $F0F8 + y * 24 + x
BC5D EX DE,HL Move tilebuf pointer into DE
Loops start here.
BC5E LD C,$05 Set C for <self modified by $BC5F> rows
Start loop
rt_copy_row BC60 LD B,$04 Set B for <self modified by $BC61> columns
Start loop
rt_copy_column BC62 PUSH HL Save windowbuf pointer
BC63 LD A,(DE) Read a tile from tilebuf
BC64 EXX Bank
BC65 POP DE Restore windowbuf pointer
BC66 PUSH HL Save x,y
BC67 CALL select_tile_set Turn a map ref into a tile set pointer (in BC)
Copy the tile into the window buffer.
Compute the tile row pointer. (This is similar to 6B4F onwards).
BC6A LD L,A Widen the tile index into HL
BC6B LD H,$00
BC6D ADD HL,HL Multiply by 8
BC6E ADD HL,HL
BC6F ADD HL,HL
BC70 ADD HL,BC Add to tileset base address
BC71 LD BC,$0818 Simultaneously set B for eight iterations and C for a 24 byte stride
Start loop
rt_copy_tile BC74 LD A,(HL) Transfer a byte (a row) of tile across
BC75 LD (DE),A
BC76 LD A,C Advance the screen buffer pointer by the stride
BC77 ADD A,E
BC78 JR NC,rt_copy_tile_nocarry
BC7A INC D
rt_copy_tile_nocarry BC7B LD E,A
BC7C INC L
BC7D DJNZ rt_copy_tile ...loop for each byte of the tile
Move to next column.
BC7F POP HL Restore x,y
BC80 INC H Increment x
BC81 EXX Unbank
BC82 INC DE Advance the tilebuf pointer
BC83 INC HL Advance the windowbuf pointer
BC84 DJNZ rt_copy_column ...loop (width counter)
Reset x offset. Advance to next row.
BC86 EXX Bank
BC87 LD A,H Get x
BC88 SUB $00 Reset x to initial value <self modified by $BC89>
BC8A LD H,A Save x
BC8B INC L Increment y
BC8C EXX Unbank
BC8D LD A,$14 Get tilebuf row-to-row skip <self modified by $BC8E>
BC8F ADD A,E Increment tilebuf pointer DE
BC90 JR NC,rt_tilebuf_nocarry
BC92 INC D
rt_tilebuf_nocarry BC93 LD E,A
BC94 LD A,$BC Get windowbuf row-to-row skip <self modified by $BC95>
BC96 ADD A,L Increment windowbuf pointer HL
BC97 JR NC,rt_windowbuf_nocarry
BC99 INC H
rt_windowbuf_nocarry BC9A LD L,A
BC9B DEC C ...loop
BC9C JP NZ,rt_copy_row
rt_next_vischar BC9F POP BC Restore loop counter
BCA0 LD DE,$0020 Set DE to the vischar stride (32)
BCA3 ADD IY,DE Advance IY to the next vischar
BCA5 DEC B ...loop
BCA6 JP NZ,rt_loop
BCA9 RET Return
Prev: BAF7 Up: Map Next: BCAA