![]() |
Routines |
| Prev: 83EA | Up: Map | Next: 8566 |
|
The per-actor update. Actors drift in a direction until they hit the edge of the room, then reverse; the direction is re-rolled at intervals from the refresh register, which is the game's random number source.
Velocity lives in +$08 (x) and +$09 (y) and is nudged one step per call toward +2 or -2 rather than being set outright, so things accelerate and turn smoothly instead of snapping.
|
||||||||
| MOVE_ACTOR | 845F | CALL ACTOR_TO_WORKSPACE | An actor in another room is not drawn or moved... | |||||
| 8462 | LD A,($EA91) | |||||||
| 8465 | CP (IX+$01) | |||||||
| 8468 | JP NZ,ACTOR_TICK_TIMER | ...it only gets its timer ticked. | ||||||
| 846B | LD HL,$5E25 | Count of actors present in this room. | ||||||
| 846E | INC (HL) | |||||||
| 846F | CALL CHECK_SHOT_HIT | Two proximity tests: has the player shot this monster, and has this monster caught the player. | ||||||
| 8472 | DEC E | |||||||
| 8473 | JP Z,KILL_MONSTER | |||||||
| 8476 | CALL CHECK_HIT | |||||||
| 8479 | DEC E | |||||||
| 847A | JP Z,MONSTER_CAUGHT_PLAYER | |||||||
| 847D | LD DE,($5E1D) | The room's half-width and half-height -- how far from the centre an actor may stray. | ||||||
| 8481 | LD (IX+$0F),$00 | |||||||
| 8485 | LD (IX+$05),$46 | |||||||
| 8489 | LD A,(IX+$07) | |||||||
| 848C | AND $0F | |||||||
| 848E | JR NZ,MOVE_ACTOR_0 | |||||||
| 8490 | LD A,R | The refresh register as a source of randomness: whatever R happens to hold, masked to two direction bits. | ||||||
| 8492 | AND $03 | |||||||
| 8494 | LD (IX+$06),A | |||||||
| MOVE_ACTOR_0 | 8497 | BIT 0,(IX+$07) | ||||||
| 849B | JR NZ,MOVE_ACTOR_2 | |||||||
| 849D | BIT 0,(IX+$06) | |||||||
| 84A1 | JP Z,MOVE_ACTOR_8 | |||||||
| 84A4 | LD A,(IX+$08) | |||||||
| 84A7 | CP $02 | |||||||
| 84A9 | JR Z,MOVE_ACTOR_1 | |||||||
| 84AB | INC (IX+$08) | |||||||
| MOVE_ACTOR_1 | 84AE | BIT 1,(IX+$06) | ||||||
| 84B2 | JP Z,MOVE_ACTOR_9 | |||||||
| 84B5 | LD A,(IX+$09) | |||||||
| 84B8 | CP $02 | |||||||
| 84BA | JR Z,MOVE_ACTOR_2 | |||||||
| 84BC | INC (IX+$09) | |||||||
| MOVE_ACTOR_2 | 84BF | INC (IX+$07) | ||||||
| 84C2 | LD A,(IX+$07) | Flip the bottom bit of the sprite index every other tick, which is the walk animation. | ||||||
| 84C5 | AND $01 | |||||||
| 84C7 | XOR (IX+$00) | |||||||
| 84CA | LD (IX+$00),A | |||||||
|
This entry point is used by the routines at MOVE_BAT, MOVE_HOPPER, MOVE_FACE, MOVE_GHOST, MOVE_FRANKENSTEIN, MOVE_WITCH, MOVE_FACING_FLYER and MOVE_HUMPBACK.
|
||||||||
| STEP_ACTOR | 84CD | LD A,(IX+$03) | Provisional new x = x + x-velocity. | |||||
| 84D0 | ADD A,(IX+$08) | |||||||
| 84D3 | LD C,A | |||||||
| 84D4 | SUB $58 | Distance from the room's centre column ($58)... | ||||||
| 84D6 | JR C,MOVE_ACTOR_3 | |||||||
| 84D8 | CP E | |||||||
| 84D9 | JR C,MOVE_ACTOR_4 | |||||||
| 84DB | RES 0,(IX+$06) | ...and if that is outside the half-width, stay put and reverse. | ||||||
| 84DF | LD (IX+$08),$FE | |||||||
| 84E3 | LD C,(IX+$03) | |||||||
| 84E6 | JR MOVE_ACTOR_4 | |||||||
| MOVE_ACTOR_3 | 84E8 | NEG | ||||||
| 84EA | CP E | |||||||
| 84EB | JR C,MOVE_ACTOR_4 | |||||||
| 84ED | SET 0,(IX+$06) | |||||||
| 84F1 | LD C,(IX+$03) | |||||||
| 84F4 | LD (IX+$08),$02 | |||||||
| MOVE_ACTOR_4 | 84F8 | LD A,(IX+$04) | The same again for y, about centre row $68. | |||||
| 84FB | ADD A,(IX+$09) | |||||||
| 84FE | LD B,A | |||||||
| 84FF | SUB $68 | |||||||
| 8501 | JR C,MOVE_ACTOR_5 | |||||||
| 8503 | CP D | |||||||
| 8504 | JR C,MOVE_ACTOR_6 | |||||||
| 8506 | RES 1,(IX+$06) | |||||||
| 850A | LD (IX+$09),$FE | |||||||
| 850E | LD B,(IX+$04) | |||||||
| 8511 | JR MOVE_ACTOR_6 | |||||||
| MOVE_ACTOR_5 | 8513 | NEG | ||||||
| 8515 | CP D | |||||||
| 8516 | JR C,MOVE_ACTOR_6 | |||||||
| 8518 | SET 1,(IX+$06) | |||||||
| 851C | LD B,(IX+$04) | |||||||
| 851F | LD (IX+$09),$02 | |||||||
| MOVE_ACTOR_6 | 8523 | LD (IX+$03),C | Commit the new position. | |||||
| 8526 | LD (IX+$04),B | |||||||
| 8529 | LD A,($EA91) | |||||||
| 852C | CP (IX+$01) | |||||||
| 852F | RET NZ | |||||||
| 8530 | LD A,(IX+$00) | Two kinds are exempt from the test below: the humpback, whose codes are $9C-$9F, and the four big monsters at $70-$7F -- the mummy, Frankenstein's monster, the devil and Dracula, which come through STEP_ACTOR too. Masking with $FC and $F0 tests a whole run of codes in one compare, without caring which frame is showing. | ||||||
| 8533 | AND $FC | |||||||
| 8535 | CP $9C | |||||||
| 8537 | JR Z,MOVE_ACTOR_7 | |||||||
| 8539 | AND $F0 | |||||||
| 853B | CP $70 | |||||||
| 853D | JR Z,MOVE_ACTOR_7 | |||||||
| 853F | LD A,($EA90) | Everything else is destroyed, with the 155 points of KILL_MONSTER, whenever the player is not in play -- sinking or rising. So dying clears the room of small creatures (measured in the simulator, 2026-09-27). | ||||||
| 8542 | CP $31 | |||||||
| 8544 | JP NC,KILL_MONSTER | |||||||
| MOVE_ACTOR_7 | 8547 | JP REDRAW_ACTOR | ||||||
| MOVE_ACTOR_8 | 854A | LD A,(IX+$08) | ||||||
| 854D | CP $FE | |||||||
| 854F | JP Z,MOVE_ACTOR_1 | |||||||
| 8552 | DEC (IX+$08) | |||||||
| 8555 | JP MOVE_ACTOR_1 | |||||||
| MOVE_ACTOR_9 | 8558 | LD A,(IX+$09) | ||||||
| 855B | CP $FE | |||||||
| 855D | JP Z,MOVE_ACTOR_2 | |||||||
| 8560 | DEC (IX+$09) | |||||||
| 8563 | JP MOVE_ACTOR_2 | |||||||
|
Nothing in the disassembly jumps here, which is not because the routine is dead: it is entry $5C/$5D of the table at ACTOR_HANDLERS, and DISPATCH_ACTOR reaches it through a JP (HL). Breaking here does catch it, 16 times in 20, always with IX = $EE80 -- the monster whose sprite byte is currently $5C. Two earlier rounds of sampling reported zero hits and concluded it was unused; both were taken before the player had finished spawning, when no monster was in the room yet.
STEP_ACTOR is also entered directly by eight other routines, which is why the position update is written as a separate stretch: they supply their own velocity in +$08/+$09 and reuse the bounce logic. Verified against the running game -- ($5E1D) reads 56 by 56, and sampled actor positions stay inside $58 +/- 56 by $68 +/- 56.
|
||||||||
| Prev: 83EA | Up: Map | Next: 8566 |