Prev: B53E Up: Map Next: B71B
B5CE: Animate
This animates all visible characters.
Used by the routines at setup_movable_items and main_loop.
animate B5CE LD B,$08 Set B for eight iterations
B5D0 LD IY,$8000 Point IY at the first vischar
Start loop
animate_loop B5D4 LD A,(IY+$01) Read the vischar's flags byte
B5D7 CP $FF Is it vischar_FLAGS_EMPTY_SLOT? ($FF)
B5D9 JP Z,animate_next Jump to the next iteration if so
B5DC PUSH BC Preserve the loop counter
B5DD SET 7,(IY+$01) Set flags byte to vischar_FLAGS_NO_COLLIDE ($80)
B5E1 BIT 7,(IY+$0D) Does the vischar's input field have flag input_KICK set? ($80)
B5E5 JP NZ,animate_kicked Jump if so
B5E8 LD H,(IY+$0B) Fetch vischar animation pointer into HL
B5EB LD L,(IY+$0A)
B5EE LD A,(IY+$0C) Fetch vischar animation index
B5F1 AND A Is vischar_ANIMINDEX_REVERSE set? ($80)
B5F2 JP P,animate_3 Jump if not
B5F5 AND $7F Otherwise mask off vischar_ANIMINDEX_REVERSE to get our frame number
Bug: This ought to check for $7F, not zero.
B5F7 JP Z,animate_init Jump to initialisation if the result is zero
B5FA INC A Calculate the animation frame pointer = (animation pointer) + (frame number + 1) * 4 - 1
B5FB ADD A,A
B5FC ADD A,A
B5FD LD C,A
B5FE LD B,$00
B600 ADD HL,BC
B601 DEC HL
B602 LD A,(HL) Fetch anim's sprite index
B603 EX AF,AF' Bank sprite index
B604 INC HL ...
animate_backwards B605 EX DE,HL Swap frame pointers
Apply frame deltas
saved_pos_x = vischar.mi.pos.x - frame->dx
B606 LD L,(IY+$0F) Fetch vischar.mi.pos.x into HL
B609 LD H,(IY+$10)
B60C LD A,(DE) Load animation frame's delta X
B60D LD C,A Sign extend into BC
B60E AND $80
B610 JR Z,animate_0
B612 LD A,$FF
animate_0 B614 LD B,A
B615 SBC HL,BC Subtract the delta
B617 LD ($81A4),HL Save it in saved_pos_x
saved_pos_y = vischar.mi.pos.y - frame->dy
B61A INC DE Advance to animation frame's delta Y
B61B LD L,(IY+$11) Fetch vischar.mi.pos.y into HL
B61E LD H,(IY+$12)
B621 LD A,(DE) Load animation frame's delta Y
B622 LD C,A Sign extend into BC
B623 AND $80
B625 JR Z,animate_1
B627 LD A,$FF
animate_1 B629 LD B,A
B62A SBC HL,BC Subtract the delta
B62C LD ($81A6),HL Save it in saved_pos_y
saved_height = vischar.mi.pos.height - frame->dh
B62F INC DE Advance to animation frame's delta height
B630 LD L,(IY+$13) Fetch vischar.mi.pos.height into HL
B633 LD H,(IY+$14)
B636 LD A,(DE) Load animation frame's delta height
B637 LD C,A Sign extend into BC
B638 AND $80
B63A JR Z,animate_2
B63C LD A,$FF
animate_2 B63E LD B,A
B63F SBC HL,BC Subtract the delta
B641 LD ($81A8),HL Save it in saved_height
B644 CALL touch Test for characters meeting obstacles like doors and map bounds
B647 JP NZ,animate_pop_next If outside bounds (collided with something), jump to animate_pop_next to halt any animation
B64A DEC (IY+$0C) Decrement animation index [DPT: Was there a bug around here?]
B64D JR animate_7 (else)
Have we reached the end of the animation?
animate_3 B64F CP (HL) Is the animation index equal to the number of frames in the animation?
B650 JP Z,animate_init Jump if so
B653 INC A Calculate the animation frame pointer = (animation pointer) + (frame number + 1) * 4
B654 ADD A,A
B655 ADD A,A
B656 LD C,A
B657 LD B,$00
B659 ADD HL,BC
animate_forwards B65A EX DE,HL Swap frame pointers
Apply frame deltas
saved_pos_x = vischar.mi.pos.x - frame->dx
B65B LD A,(DE) Load animation frame's delta X
B65C LD L,A Sign extend into HL
B65D AND $80
B65F JR Z,animate_4
B661 LD A,$FF
animate_4 B663 LD H,A
B664 LD C,(IY+$0F) Fetch vischar.mi.pos.x into BC
B667 LD B,(IY+$10)
B66A ADD HL,BC Add the delta
B66B LD ($81A4),HL Save it in saved_pos_x
saved_pos_y = vischar.mi.pos.y - frame->dy
B66E INC DE Advance to animation frame's delta Y
B66F LD A,(DE) Load animation frame's delta Y
B670 LD L,A Sign extend into HL
B671 AND $80
B673 JR Z,animate_5
B675 LD A,$FF
animate_5 B677 LD H,A
B678 LD C,(IY+$11) Fetch vischar.mi.pos.y into BC
B67B LD B,(IY+$12)
B67E ADD HL,BC Add the delta
B67F LD ($81A6),HL Save it in saved_pos_y
saved_height = vischar.mi.pos.height - frame->dh
B682 INC DE Advance to animation frame's delta height
B683 LD A,(DE) Load animation frame's delta height
B684 LD L,A Sign extend into HL
B685 AND $80
B687 JR Z,animate_6
B689 LD A,$FF
animate_6 B68B LD H,A
B68C LD C,(IY+$13) Fetch vischar.mi.pos.height into BC
B68F LD B,(IY+$14)
B692 ADD HL,BC Add the delta
B693 LD ($81A8),HL Save it in saved_height
B696 INC DE Advance to animation frame's sprite index
B697 LD A,(DE) Load animation frame's sprite index
B698 EX AF,AF' Bank A
B699 CALL touch Test for characters meeting obstacles like doors and map bounds
B69C JP NZ,animate_pop_next If outside bounds (collided with something), goto animate_pop_next to halt any animation
B69F INC (IY+$0C) Increment animation index
animate_7 B6A2 PUSH IY HL = IY
B6A4 POP HL
B6A5 CALL calc_vischar_iso_pos_from_state Calculate screen position for vischar from saved_pos
animate_pop_next B6A8 POP BC
B6A9 LD A,(IY+$01) Read the vischar's flags byte
B6AC CP $FF Is it vischar_FLAGS_EMPTY_SLOT? ($FF)
B6AE JR Z,animate_next Jump forward if so
B6B0 RES 7,(IY+$01) Otherwise clear the vischar_FLAGS_NO_COLLIDE flag ($80)
animate_next B6B4 LD DE,$0020 Set DE to the vischar stride (32)
B6B7 ADD IY,DE Advance IY to the next vischar
B6B9 DEC B ...loop
B6BA JP NZ,animate_loop
B6BD RET Return
animate_kicked B6BE RES 7,(IY+$0D) Clear the input_KICK flag
animate_init B6C2 LD A,(IY+$0E) Fetch vischar direction field
B6C5 LD D,A Multiply it by 9
B6C6 ADD A,A
B6C7 ADD A,A
B6C8 ADD A,A
B6C9 ADD A,D
B6CA ADD A,(IY+$0D) Add vischar input field to it
B6CD LD E,A Shuffle it into DE
B6CE LD D,$00
B6D0 LD HL,$CDAA Add it to the animindices base address
B6D3 ADD HL,DE
B6D4 LD A,(HL) Fetch the index pointed to
B6D5 LD C,A Stash in C for later
B6D6 LD L,(IY+$08) Fetch vischar.animbase (animbase is always &animations[0])
B6D9 LD H,(IY+$09)
B6DC ADD A,A Double A (and in doing so discard the top bit!)
B6DD LD E,A Set DE to A (we know D is zero from above)
B6DE ADD HL,DE Point at the A'th frame pointer
B6DF LD E,(HL) Load the frame pointer into DE and set vischar anim field to it
B6E0 INC HL
B6E1 LD (IY+$0A),E
B6E4 LD D,(HL)
B6E5 LD (IY+$0B),D
B6E8 BIT 7,C Was the reverse bit set on the index?
B6EA JR NZ,animate_8 Jump forward if so
B6EC LD (IY+$0C),$00 Zero the vischar animindex field
B6F0 INC DE Skip nframes and from fields. Advance DE to animB->to
B6F1 INC DE
B6F2 LD A,(DE) Set the vischar direction field to animB->to
B6F3 LD (IY+$0E),A
B6F6 INC DE Advance to animB->frames
B6F7 INC DE
B6F8 EX DE,HL Swap frame pointers
B6F9 JP animate_forwards Jump
else
animate_8 B6FC LD A,(DE) Fetch nframes
B6FD LD C,A Stash in C for later
Bug: C port uses (nframes - 1) here to fix something... (add detail)
B6FE OR $80 Set the vischar animindex field to (nframes | vischar_ANIMINDEX_REVERSE)
B700 LD (IY+$0C),A
B703 INC DE Advance to 'from'
B704 LD A,(DE) Set the vischar direction field to 'from'
B705 LD (IY+$0E),A
Bug: C port uses final frame here, not first... (add detail)
B708 INC DE Advance to animB->frame[0]
B709 INC DE
B70A INC DE
B70B PUSH DE Stack animB
B70C EX DE,HL Swap frame pointers
B70D LD A,C Point HL at anim[nframes - 1].spriteindex
B70E ADD A,A
B70F ADD A,A
B710 DEC A
B711 LD B,$00
B713 LD C,A
B714 ADD HL,BC
B715 LD A,(HL) Fetch the new sprite index
B716 EX AF,AF' Swap the sprite indices
B717 POP HL Pop and swap?
B718 JP animate_backwards Jump
Prev: B53E Up: Map Next: B71B