Prev: E9C8 Up: Map Next: EA80
E9D5: Update a character's animatory state and location and update the SRB
Used by the routines at 634C, 64BD, 6670, 71DD, 790D, 79E4, 7AF4, 7BB6, 7BE1, EBBB, EC5A, F338, F375, F731, F846, F9D2, FA83 and FAE3. Sets the new animatory state and location of a character, and updates the screen refresh buffer (SRB) accordingly.
Input
A New animatory state
D New y-coordinate
E New x-coordinate
H Character number (0xD7-0xE6)
E9D5 LD L,$02 Point HL at byte 0x02 of the character's buffer
E9D7 LD (HL),D Fill in the new y-coordinate
E9D8 DEC L L=0x01
E9D9 LD (HL),E Fill in the new x-coordinate
E9DA DEC L L=0x00
E9DB LD (HL),A Fill in the new animatory state
This entry point is used by the routine at E9C8.
E9DC LD BC,$0202 B=2, C=2
E9DF LD A,(HL) A=character's animatory state
E9E0 AND $7F Clear the 'direction' bit (bit 7)
E9E2 ADD A,$88 Is the animatory state >= 0x78?
E9E4 JR C,$E9F1 Jump if so
E9E6 LD BC,$0503 B=5, C=3
E9E9 INC A Is the animatory state equal to 7 mod 8?
E9EA AND $07
E9EC JR NZ,$E9F1 Jump if not
E9EE LD BC,$0305 B=3, C=5
Now B holds the height of the sprite in tiles, and C holds the width.
E9F1 LD A,($7FFF) A=Y, the y-coordinate of the topmost row of the play area on screen (2-20)
E9F4 SUB B A=Y-B
E9F5 JR C,$E9F9 Jump if B>Y
E9F7 CP D Is the character entirely above the portion of the play area currently on screen?
E9F8 RET NC Return if so
E9F9 ADD A,B A=Y
E9FA ADD A,$13 A=y-coordinate of the bottom row of the play area on screen (21-39)
E9FC SUB D Is the character entirely below the portion of the play area currently on screen?
E9FD RET C Return if so
E9FE CPL A=4*(D-Y+4)
E9FF ADD A,$18
EA01 ADD A,A
EA02 ADD A,A
EA03 LD D,A Copy this value (0, 4, 8, 12,...92) to D
EA04 LD A,($7FFE) A=X, the x-coordinate of the leftmost column of the play area on screen
EA07 SUB C A=X-C
EA08 JR C,$EA0C Jump if C>X
EA0A CP E Is the character entirely off-screen to the left?
EA0B RET NC Return if so
EA0C ADD A,C A=X
EA0D ADD A,$1F A=x-coordinate of the rightmost column of the play area on screen
EA0F SUB E Is the character entirely off-screen to the right?
EA10 RET C Return if so
If we get here, then the character's sprite (or at least a portion of it) is on-screen.
EA11 CPL A=E-X: the character's screen x-coordinate (-4 to 31)
EA12 ADD A,$20
EA14 PUSH AF Save this temporarily
EA15 LD A,(HL) A=character's animatory state
EA16 AND $07 Set the zero flag if the animatory state is 0 mod 8
EA18 LD A,(HL) A=character's animatory state
EA19 JR NZ,$EA1D Jump unless the animatory state is 0 mod 8
EA1B ADD A,$02 Add 2 if the animatory state is congruent to 0 mod 8
EA1D PUSH BC Push the sprite dimensions onto the stack
EA1E EXX
EA1F POP BC Retrieve the sprite dimensions in BC'
EA20 LD H,$D7 Page 0xD7 holds sprite tile references for the top-left tile (tile 0) in the left-facing sprites
EA22 LD D,B D'=sprite height (2, 3 or 5)
EA23 RLCA Set bit 7 of A, and set the carry flag if the character is facing right
EA24 SCF
EA25 RRA
EA26 LD L,A L'=character's animatory state (with bit 7 set)
EA27 JR NC,$EA34 Jump if the character is facing left
EA29 XOR A D'=-B' (negative sprite height)
EA2A SUB B
EA2B LD D,A
EA2C LD E,C E'=C'-1 (sprite width minus 1)
EA2D DEC E
EA2E LD A,H A=0xD7 (page containing references for sprite tile 0)
EA2F ADD A,B A=0xD7+B'*(C'-1)
EA30 DEC E
EA31 JR NZ,$EA2F
EA33 LD H,A Copy this value to H'
Now HL' points at the sprite tile reference for the top-left tile in the character's sprite.
EA34 POP AF Restore the character's screen x-coordinate to A
EA35 LD E,A Copy it to E'
EA36 JR C,$EA3F Jump if E'>=0 (meaning that the leftmost tiles in the character's sprite are on-screen)
EA38 LD A,H A=H'-D'*E' (sprite tile reference page number); C'=C'+E'
EA39 ADD A,D
EA3A DEC C
EA3B INC E
EA3C JR NZ,$EA39
EA3E LD H,A Copy the sprite tile reference page number to H'
Now HL' points at the sprite tile reference for the tile in the top row and the leftmost column of the character's sprite that is on-screen. C' holds the number of tile columns of the character's sprite that are to the right of the left edge of the screen.
EA3F LD A,E A=leftmost column of the screen occupied by the sprite (0-31)
EA40 EXX
EA41 LD E,A E=leftmost column of the screen occupied by the sprite
EA42 AND $07 Point BC at byte 0x15 of page 0xA0+(E%8)
EA44 ADD A,$A0
EA46 LD B,A
EA47 LD C,$15
EA49 LD A,(BC) Pick up the contents in A
EA4A LD C,A Copy them to C
Now C holds 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40 or 0x80. The bit set in C corresponds to the bit that needs to be set in the relevant byte of the screen refresh buffer (SRB).
EA4B LD A,E A=leftmost column of the screen occupied by the sprite (0-31)
EA4C RRCA Set A to the LSB of the first byte of the SRB that needs to be modified: D+INT(E/8)
EA4D RRCA
EA4E RRCA
EA4F AND $03
EA51 ADD A,D
EA52 LD B,A Copy this LSB to B
EA53 LD D,$7F The SRB is in page 0x7F
EA55 EXX
Here we enter a loop to set the appropriate bits in the SRB. At this point B' holds the number of tile rows in the sprite (2, 3, or 5) and C' holds the number of tile columns of the sprite that are to the right of the left edge of the screen.
EA56 PUSH BC Save the tile row and column counters temporarily
EA57 LD E,$00 Start at sprite tile row 0 (top row)
EA59 LD A,(HL) Pick up the sprite tile reference in A
EA5A AND A Is this the 'null' tile (blank square)?
EA5B JR Z,$EA67 Jump if so (no need to set a bit in the SRB)
EA5D LD A,E A=sprite tile row number (0-4)
EA5E EXX
EA5F ADD A,A Multiply by 4 (the number of bytes of the SRB that correspond to one row of the screen)
EA60 ADD A,A
EA61 ADD A,B Point DE at the relevant byte of the SRB
EA62 LD E,A
EA63 LD A,(DE) Pick up the SRB byte in A
EA64 OR C Make sure the appropriate bit is set
EA65 LD (DE),A Restore the SRB byte with the appropriate bit set
EA66 EXX
EA67 INC H Point HL' at the reference for the next tile in the sprite (one row down)
EA68 INC E Next row down in this column of the sprite
EA69 DJNZ $EA59 Jump back until we've set all the SRB bits for this tile column of the sprite
EA6B LD A,H Point HL' at the reference for the tile in the top row of the next column of the sprite
EA6C ADD A,D
EA6D POP BC
EA6E SUB B
EA6F LD H,A
EA70 EXX
EA71 RRC C Move the SRB marker bit in C one place to the right (possibly wrapping round to bit 7)
EA73 JR NC,$EA7A Jump if there are still bits to be set in the current SRB byte
EA75 INC B Otherwise move along to the next byte in the SRB
EA76 LD A,B A=LSB of the next SRB byte
EA77 AND $03 Does the next SRB byte correspond to a segment in the leftmost 8 columns of the screen (i.e. have we wrapped around from right to left)?
EA79 RET Z Return if so (any remaining sprite tile columns are off-screen to the right)
EA7A EXX
EA7B DEC C Next sprite tile column
EA7C JR NZ,$EA56 Jump back until the relevant SRB bits for every sprite tile column have been set
EA7E EXX
EA7F RET
Prev: E9C8 Up: Map Next: EA80