![]() |
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 |