Routines |
Prev: B53E | Up: Map | Next: B71B |
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 |