![]() |
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 |