Routines |
Prev: BADC | Up: Map | Next: BB98 |
This clips the given vischar's dimensions to the game window.
Used by the routines at restore_tiles and setup_vischar_plotting.
|
||||||||||||||||||||
To determine visibility and sort out clipping there are five cases to consider per axis: (A) the vischar is completely off the left/top of window, (B) the vischar is clipped on its left/top, (C) the vischar is entirely visible, (D) the vischar is clipped on its right/bottom, and (E) the vischar is completely off the right/bottom of window.
Note that no vischar will ever be wider than the window so we never need to consider if clipping will occur on both sides.
First handle the horizontal cases.
|
||||||||||||||||||||
vischar_visible | BAF7 | LD HL,$81B5 | Point HL at iso_pos_x (vischar left edge) | |||||||||||||||||
Calculate the right edge of the window in map space.
|
||||||||||||||||||||
BAFA | LD A,($81BB) | Load map X position | ||||||||||||||||||
BAFD | ADD A,$18 | Add 24 (number of window columns) | ||||||||||||||||||
Subtract iso_pos_x giving the distance between the right edge of the window and the current vischar's left edge (in bytes).
|
||||||||||||||||||||
BAFF | SUB (HL) | available_right = (map_position.x + 24) - vischar_left_edge | ||||||||||||||||||
Check for case (E): Vischar left edge beyond the window's right edge.
|
||||||||||||||||||||
BB00 | JP Z,vv_not_visible | Jump to exit if zero (vischar left edge at right edge) | ||||||||||||||||||
BB03 | JP C,vv_not_visible | Jump to exit if negative (vischar left edge beyond right edge) | ||||||||||||||||||
Check for case (D): Vischar extends outside the window.
|
||||||||||||||||||||
BB06 | CP (IY+$1E) | Compare result to (sprite width bytes + 1) | ||||||||||||||||||
BB09 | JP NC,vv_not_clipped_on_right_edge | Jump if it fits | ||||||||||||||||||
Vischar's right edge is outside the window: clip its width.
|
||||||||||||||||||||
BB0C | LD B,$00 | No lefthand skip | ||||||||||||||||||
BB0E | LD C,A | Clipped width = available_right | ||||||||||||||||||
BB0F | JR vv_height | Jump to height part | ||||||||||||||||||
Calculate the right edge of the vischar.
|
||||||||||||||||||||
vv_not_clipped_on_right_edge | BB11 | LD A,(HL) | Load iso_pos_x (vischar left edge) | |||||||||||||||||
BB12 | ADD A,(IY+$1E) | vischar_right_edge = iso_pos_x + (sprite width bytes + 1) | ||||||||||||||||||
Subtract the map position's X giving the distance between the current vischar's right edge and the left edge of the window (in bytes).
|
||||||||||||||||||||
BB15 | LD HL,$81BB | Load map X position | ||||||||||||||||||
BB18 | SUB (HL) | available_left = vischar_right_edge - map_position.x | ||||||||||||||||||
Check for case (A): Vischar's right edge is beyond the window's left edge.
|
||||||||||||||||||||
BB19 | JP Z,vv_not_visible | Jump to exit if zero (vischar right edge at left edge) | ||||||||||||||||||
BB1C | JP C,vv_not_visible | Jump to exit if negative (vischar right edge beyond left edge) | ||||||||||||||||||
Check for case (B): Vischar's left edge is outside the window and its right edge is inside the window.
|
||||||||||||||||||||
BB1F | CP (IY+$1E) | Compare result to (sprite width bytes + 1) | ||||||||||||||||||
BB22 | JP NC,vv_not_clipped | Jump if it fits | ||||||||||||||||||
Vischar's left edge is outside the window: move the lefthand skip into B and the clipped width into C.
|
||||||||||||||||||||
BB25 | LD C,A | Clipped width = available_left | ||||||||||||||||||
BB26 | NEG | Lefthand skip = (sprite width bytes + 1) - available_left | ||||||||||||||||||
BB28 | ADD A,(IY+$1E) | |||||||||||||||||||
BB2B | LD B,A | |||||||||||||||||||
BB2C | JR vv_height | (else) | ||||||||||||||||||
Case (C): No clipping required.
|
||||||||||||||||||||
vv_not_clipped | BB2E | LD B,$00 | No lefthand skip | |||||||||||||||||
BB30 | LD C,(IY+$1E) | Clipped width = (sprite width bytes + 1) | ||||||||||||||||||
Handle vertical cases.
Note: This uses vischar.iso_pos, not state.iso_pos as above.
Calculate the bottom edge of the window in map space.
|
||||||||||||||||||||
vv_height | BB33 | LD A,($81BC) | Load the map position's Y and add 17 (number of window rows) | |||||||||||||||||
BB36 | ADD A,$11 | |||||||||||||||||||
BB38 | LD L,A | Multiply it by 8 | ||||||||||||||||||
BB39 | LD H,$00 | |||||||||||||||||||
BB3B | ADD HL,HL | |||||||||||||||||||
BB3C | ADD HL,HL | |||||||||||||||||||
BB3D | ADD HL,HL | |||||||||||||||||||
Subtract vischar's Y giving the distance between the bottom edge of the window and the current vischar's top (in rows).
|
||||||||||||||||||||
BB3E | LD E,(IY+$1A) | Load vischar.iso_pos.y (vischar top edge) | ||||||||||||||||||
BB41 | LD D,(IY+$1B) | |||||||||||||||||||
BB44 | AND A | Clear carry flag | ||||||||||||||||||
BB45 | SBC HL,DE | available_bottom = window_bottom_edge * 8 - vischar->iso_pos.y | ||||||||||||||||||
Check for case (E): Vischar top edge beyond the window's bottom edge.
|
||||||||||||||||||||
BB47 | JP Z,vv_not_visible | Jump to exit if zero (vischar top edge at bottom edge) | ||||||||||||||||||
BB4A | JP C,vv_not_visible | Jump to exit if negative (vischar top edge beyond bottom edge) | ||||||||||||||||||
BB4D | LD A,H | Jump to exit if >= 256 (way out of range) | ||||||||||||||||||
BB4E | AND A | |||||||||||||||||||
BB4F | JP NZ,vv_not_visible | |||||||||||||||||||
Check for case (D): Vischar extends outside the window.
|
||||||||||||||||||||
BB52 | LD A,L | A = available_bottom | ||||||||||||||||||
BB53 | CP (IY+$1F) | Compare result to vischar.height | ||||||||||||||||||
BB56 | JP NC,vv_not_clipped_on_top_edge | Jump if it fits (available_top >= vischar.height) | ||||||||||||||||||
Vischar's bottom edge is outside the window: clip its height.
|
||||||||||||||||||||
BB59 | LD E,A | Clipped height = available_bottom | ||||||||||||||||||
BB5A | LD D,$00 | No top skip | ||||||||||||||||||
BB5C | JR vv_visible | Jump to exit | ||||||||||||||||||
Calculate the bottom edge of the vischar.
|
||||||||||||||||||||
vv_not_clipped_on_top_edge | BB5E | LD L,(IY+$1F) | Load sprite height and widen | |||||||||||||||||
BB61 | LD H,$00 | |||||||||||||||||||
BB63 | ADD HL,DE | vischar_bottom_edge = vischar.iso_pos.y + (sprite height) | ||||||||||||||||||
Subtract map position's Y (scaled) giving the distance between the current vischar's bottom edge and the top edge of the window (in rows).
|
||||||||||||||||||||
BB64 | EX DE,HL | Bank | ||||||||||||||||||
BB65 | LD A,($81BC) | Load the map position's Y and widen | ||||||||||||||||||
BB68 | LD L,A | |||||||||||||||||||
BB69 | LD H,$00 | |||||||||||||||||||
BB6B | ADD HL,HL | Multiply by 8 | ||||||||||||||||||
BB6C | ADD HL,HL | |||||||||||||||||||
BB6D | ADD HL,HL | |||||||||||||||||||
BB6E | EX DE,HL | Unbank | ||||||||||||||||||
BB6F | AND A | Clear the carry flag | ||||||||||||||||||
BB70 | SBC HL,DE | available_top = vischar_bottom_edge - map_pos_y * 8 | ||||||||||||||||||
Check for case (A): Vischar's bottom edge is beyond the window's top edge.
|
||||||||||||||||||||
BB72 | JP C,vv_not_visible | Jump to exit if negative (vischar bottom edge beyond top edge) | ||||||||||||||||||
BB75 | JP Z,vv_not_visible | Jump to exit if zero (vischar bottom edge at top edge) | ||||||||||||||||||
BB78 | LD A,H | Jump to exit if >= 256 (way out of range) | ||||||||||||||||||
BB79 | AND A | |||||||||||||||||||
BB7A | JP NZ,vv_not_visible | |||||||||||||||||||
Check for case (B): Vischar's top edge is outside the window and its bottom edge is inside the window.
|
||||||||||||||||||||
BB7D | LD A,L | A = available_top | ||||||||||||||||||
BB7E | CP (IY+$1F) | Compare result to vischar.height | ||||||||||||||||||
BB81 | JP NC,vischar_visible_0 | Jump if it fits (available_top >= vischar.height) | ||||||||||||||||||
Vischar's top edge is outside the window: move the top skip into D and the clipped height into E.
|
||||||||||||||||||||
BB84 | LD E,A | Clipped height = available_top | ||||||||||||||||||
BB85 | NEG | Top skip = vischar.height - available_top | ||||||||||||||||||
BB87 | ADD A,(IY+$1F) | |||||||||||||||||||
BB8A | LD D,A | |||||||||||||||||||
BB8B | JR vv_visible | (else) | ||||||||||||||||||
Case (C): No clipping required.
|
||||||||||||||||||||
vischar_visible_0 | BB8D | LD D,$00 | No top skip | |||||||||||||||||
BB8F | LD E,(IY+$1F) | Clipped height = vischar.height | ||||||||||||||||||
vv_visible | BB92 | XOR A | Set Z (vischar is visible) | |||||||||||||||||
BB93 | RET | Return | ||||||||||||||||||
vv_not_visible | BB94 | LD A,$FF | Signal invisible | |||||||||||||||||
BB96 | AND A | Clear Z (vischar is not visible) | ||||||||||||||||||
BB97 | RET | Return |
Prev: BADC | Up: Map | Next: BB98 |