Prev: C41C Up: Map Next: C4E0
C47E: Purge invisible characters
This iterates over all of the visible characters testing each one to see if it's off-screen. If so it can be purged.
This is the opposite of spawn_characters.
Used by the routine at main_loop.
purge_invisible_characters C47E LD HL,($81BB) Read the current map position into HL
Calculate clamped lower bound.
9 is the size, in UDGs, of a buffer zone around the visible screen in which visible characters will persist. (Compare to the spawning size of 8).
C481 LD A,L Get map_position.x
C482 SUB $09 Subtract 9
C484 JR NC,purge_invisible_characters_0 Jump if it was >= 9
C486 XOR A Otherwise zero it
purge_invisible_characters_0 C487 LD E,A E is the result: minx
C488 LD A,H Get map_position.y
C489 SUB $09 Subtract 9
C48B JR NC,purge_invisible_characters_1 Jump if it was >= 9
C48D XOR A Otherwise zero it
purge_invisible_characters_1 C48E LD D,A D is the result: miny
Iterate over non-player characters.
C48F LD B,$07 Set B for seven iterations
C491 LD HL,$8020 Point HL at the second visible character
Start loop
Ignore inactive characters.
pic_loop C494 LD A,(HL) Fetch the vischar's character index
C495 CP $FF Is it character_NONE?
C497 JP Z,pic_next Jump to the next vischar if so
C49A PUSH HL Preserve the vischar pointer
Reset this character if it's not in the current room.
C49B LD A,$1C Point HL at vischar.room
C49D ADD A,L
C49E LD L,A
C49F LD A,($68A0) Get the global current room index
C4A2 CP (HL) Is the vischar in the current room?
C4A3 JR NZ,pic_reset Jump to reset if not
Handle Y part
C4A5 DEC L Load vischar.iso_pos.y into (C,A)
C4A6 LD C,(HL)
C4A7 DEC L
C4A8 LD A,(HL)
C4A9 CALL divide_by_8_with_rounding Divide (C,A) by 8 with rounding. Result is in A
C4AC LD C,A Copy result C
C4AD LD A,D Copy miny to A
C4AE CP C Is miny >= result?
C4AF JR NC,pic_reset Jump to reset if so (out of bounds)
Commentary: 16 is used for screen height here, but 24 is used for width below - so that doesn't line up with the actual values which are 24x17.
C4B1 ADD A,$22 Add 16 + 2 * 9 (16 => screen height, 9 => buffer zone size)
C4B3 JR NC,purge_invisible_characters_2 Clamp to a maximum of 255
C4B5 LD A,$FF
purge_invisible_characters_2 C4B7 CP C Is result > (miny + buffer size, clamped to 255)?
C4B8 JR C,pic_reset Jump to reset if so (out of bounds)
Handle X part
C4BA DEC L Load vischar.iso_pos.x into (C,A)
C4BB LD C,(HL)
C4BC DEC L
C4BD LD A,(HL)
C4BE CALL divide_by_8 Divide (C,A) by 8 (with no rounding). Result is in A
C4C1 LD C,A Copy result C
C4C2 LD A,E Copy minx to A
C4C3 CP C Is minx >= result?
C4C4 JR NC,pic_reset Jump to reset if so (out of bounds)
C4C6 ADD A,$2A Add 24 + 2 * 9 (24 => screen width, 9 => buffer zone size)
C4C8 JR NC,purge_invisible_characters_3 Clamp to a maximum of 255
C4CA LD A,$FF
purge_invisible_characters_3 C4CC CP C Is result > (minx + buffer size, clamped to 255)?
C4CD JR NC,pic_pop_next Jump to reset if so (out of bounds)
pic_reset C4CF POP HL Restore the vischar pointer (reset_visible_character arg)
C4D0 PUSH HL Preserve the vischar pointer over the call
C4D1 PUSH DE Preserve minx/miny
C4D2 PUSH BC Preserve the loop counter
C4D3 CALL reset_visible_character Reset the visible character
C4D6 POP BC Restore the loop counter
C4D7 POP DE Restore minx/miny
pic_pop_next C4D8 POP HL Restore the vischar pointer
pic_next C4D9 LD A,$20 Advance to the next vischar
C4DB ADD A,L
C4DC LD L,A
C4DD DJNZ pic_loop ...loop
C4DF RET Return
Prev: C41C Up: Map Next: C4E0