Routines |
Prev: BAF7 | Up: Map | Next: BCAA |
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 |