Prev: BADC Up: Map Next: BB98
BAF7: Vischar visible
This clips the given vischar's dimensions to the game window.
Used by the routines at restore_tiles and setup_vischar_plotting.
Input
IY Pointer to visible character
Output
A 0/255 => vischar visible/not visible
B Lefthand skip (bytes
C Clipped width (bytes).
D Top skip (rows)
E Clipped height (rows)
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