![]() |
Routines |
| Prev: C47E | Up: Map | Next: C5D3 |
|
This adds a character to the visible character (vischar) list.
Used by the routine at spawn_characters.
|
||||||||
| spawn_character | C4E0 | BIT 6,(HL) | Is the character already on-screen? (test flag characterstruct_FLAG_ON_SCREEN) | |||||
| C4E2 | RET NZ | Return if so | ||||||
| C4E3 | PUSH HL | Preserve the character pointer | ||||||
|
Find an empty slot in the visible character list.
Iterate over non-player characters.
|
||||||||
| C4E4 | LD HL,$8020 | Point HL at the second visible character | ||||||
| C4E7 | LD DE,$0020 | Prepare the vischar stride | ||||||
| C4EA | LD A,$FF | Prepare vischar_CHARACTER_EMPTY_SLOT | ||||||
| C4EC | LD B,$07 | Set B for seven iterations (seven non-player vischars) | ||||||
|
Start loop
|
||||||||
| spawn_find_slot | C4EE | CP (HL) | Empty slot? | |||||
| C4EF | JR Z,spawn_found_empty_slot | Jump if so | ||||||
| C4F1 | ADD HL,DE | Advance to the next vischar | ||||||
| C4F2 | DJNZ spawn_find_slot | ...loop | ||||||
| spawn_no_spare_slot | C4F4 | POP HL | Restore the character pointer | |||||
| C4F5 | RET | Return (Z set) | ||||||
|
Found an empty slot.
|
||||||||
| spawn_found_empty_slot | C4F6 | POP DE | Restore the character pointer to DE | |||||
| C4F7 | PUSH HL | Point IY at the empty vischar slot | ||||||
| C4F8 | POP IY | |||||||
| C4FA | PUSH HL | Preserve the empty vischar slot pointer | ||||||
| C4FB | PUSH DE | Preserve the character pointer | ||||||
| C4FC | INC DE | Advance DE to point at charstr.room | ||||||
|
Scale coords dependent on which room the character is in.
|
||||||||
| C4FD | LD HL,$81A4 | Point HL at saved_pos_x | ||||||
| C500 | LD A,(DE) | Fetch charstr.room | ||||||
| C501 | INC DE | Advance DE to charstr.pos | ||||||
| C502 | AND A | Is it outside? | ||||||
| C503 | JR NZ,spawn_indoors | Jump if not | ||||||
|
Outdoors
|
||||||||
| C505 | LD A,$03 | Set A for three iterations (x,y,height) | ||||||
|
Start loop
|
||||||||
| spawn_outdoor_pos_loop | C507 | EX AF,AF' | Bank | |||||
| C508 | LD A,(DE) | Read an (8-bit) coord | ||||||
| C509 | CALL multiply_by_8 | Multiply it by 8 returning the result in BC | ||||||
| C50C | LD (HL),C | Store the result widened to 16-bit | ||||||
| C50D | INC HL | |||||||
| C50E | LD (HL),B | |||||||
| C50F | INC HL | |||||||
| C510 | INC DE | Advance to the next coord | ||||||
| C511 | EX AF,AF' | Unbank | ||||||
| C512 | DEC A | ...loop | ||||||
| C513 | JP NZ,spawn_outdoor_pos_loop | |||||||
| C516 | JR spawn_check_collide | (else) | ||||||
| spawn_indoors | C518 | LD B,$03 | Set B for three iterations | |||||
|
Start loop
|
||||||||
| spawn_indoor_pos_loop | C51A | LD A,(DE) | Read an (8-bit) coord | |||||
| C51B | LD (HL),A | Store the coord widened to 16-bit | ||||||
| C51C | INC DE | |||||||
| C51D | INC HL | |||||||
| C51E | LD (HL),$00 | |||||||
| C520 | INC HL | |||||||
| C521 | DJNZ spawn_indoor_pos_loop | ...loop | ||||||
| spawn_check_collide | C523 | CALL collision | Call collision | |||||
| C526 | CALL Z,bounds_check | If no collision, call bounds_check | ||||||
| C529 | POP DE | Restore the character pointer | ||||||
| C52A | POP HL | Restore the empty vischar slot pointer | ||||||
| C52B | RET NZ | Return if collision or bounds_check returned non-zero | ||||||
|
Transfer character struct to vischar.
|
||||||||
| C52C | LD A,(DE) | Set characterstruct_FLAG_ON_SCREEN in charstr.character_and_flags | ||||||
| C52D | OR $40 | |||||||
| C52F | LD (DE),A | |||||||
| C530 | AND $1F | Mask A against characterstruct_CHARACTER_MASK ($1F) and store that as vischar.character | ||||||
| C532 | LD (HL),A | |||||||
| C533 | INC L | |||||||
| C534 | LD (HL),$00 | Clear the vischar.flags | ||||||
| C536 | PUSH DE | Preserve the charstr.character_and_flags pointer | ||||||
| C537 | LD DE,$CD9A | Point DE at the character_meta_data for the commandant | ||||||
| C53A | AND A | Is it character_0_COMMANDANT? | ||||||
| C53B | JR Z,spawn_metadata_set | Jump if so | ||||||
| C53D | LD DE,$CD9E | Point DE at the character_meta_data for a guard | ||||||
| C540 | CP $10 | Is it character_1_GUARD_1 to character_15_GUARD_15? | ||||||
| C542 | JR C,spawn_metadata_set | Jump if so | ||||||
| C544 | LD DE,$CDA2 | Point DE at the character_meta_data for a dog | ||||||
| C547 | CP $14 | Is it character_16_GUARD_DOG_1 to character_19_GUARD_DOG_4? | ||||||
| C549 | JR C,spawn_metadata_set | Jump if so | ||||||
| C54B | LD DE,$CDA6 | Point DE at the character_meta_data for a prisoner | ||||||
| spawn_metadata_set | C54E | EX DE,HL | Swap vischar into DE, metadata into HL | |||||
| C54F | LD A,$07 | Point DE at vischar.animbase | ||||||
| C551 | ADD A,E | |||||||
| C552 | LD E,A | |||||||
| C553 | LDI | Copy metadata.animbase to vischar.animbase | ||||||
| C555 | LDI | |||||||
| C557 | LD A,$0B | Point DE at vischar.mi.sprite | ||||||
| C559 | ADD A,E | |||||||
| C55A | LD E,A | |||||||
| C55B | LDI | Copy metadata.sprite to vischar.mi.sprite | ||||||
| C55D | LDI | |||||||
| C55F | LD A,E | Rewind DE to vischar.mi.pos | ||||||
| C560 | SUB $08 | |||||||
| C562 | LD E,A | |||||||
| C563 | LD HL,$81A4 | Copy saved_pos to vischar.mi.pos | ||||||
| C566 | LD BC,$0006 | |||||||
| C569 | LDIR | |||||||
| C56B | POP HL | Restore the HL charstr.character_and_flags pointer | ||||||
| C56C | INC HL | Advance HL to charstr.route | ||||||
| C56D | INC HL | |||||||
| C56E | INC HL | |||||||
| C56F | INC HL | |||||||
| C570 | INC HL | |||||||
| C571 | LD A,$07 | Point DE at vischar.room | ||||||
| C573 | ADD A,E | |||||||
| C574 | LD E,A | |||||||
| C575 | LD A,($68A0) | Set vischar.room to the global current room index | ||||||
| C578 | LD (DE),A | |||||||
| C579 | AND A | Are we outside? | ||||||
| C57A | JR Z,spawn_entered | Jump if so | ||||||
| spawn_indoors_sound | C57C | LD BC,$2040 | Play the "character enters" sound effects | |||||
| C57F | CALL play_speaker | |||||||
| C582 | LD BC,$2030 | |||||||
| C585 | CALL play_speaker | |||||||
| spawn_entered | C588 | LD A,E | Rewind DE to vischar.route | |||||
| C589 | SUB $1A | |||||||
| C58B | LD E,A | |||||||
| C58C | LDI | vischar.route = charstr.route | ||||||
| C58E | LDI | |||||||
| C590 | DEC HL | Rewind HL to charstr.route | ||||||
| C591 | DEC HL | |||||||
|
This can get entered twice via C5B4. On the first entry HL points at charstr.route.index. On the second entry HL points at vischar.route.index.
|
||||||||
| spawn_again | C592 | LD A,(HL) | Load route.index | |||||
| C593 | AND A | Is this character stood still? (routeindex_0_HALT) | ||||||
| C594 | JR NZ,spawn_moving | Jump if not | ||||||
| C596 | LD A,$03 | Advance DE to vischar.counter_and_flags | ||||||
| C598 | ADD A,E | |||||||
| C599 | LD E,A | |||||||
| C59A | JR spawn_end | (else) | ||||||
| spawn_moving | C59C | XOR A | Clear the entered_move_a_character flag | |||||
| C59D | LD ($A13E),A | |||||||
| C5A0 | PUSH DE | Preserve the vischar.target pointer | ||||||
| C5A1 | CALL get_target | Get our next target: a location, a door or 'route ends'. The result is returned in A, target pointer returned in HL | ||||||
| C5A4 | CP $FF | Did get_target return get_target_ROUTE_ENDS? ($FF) | ||||||
| C5A6 | JR NZ,spawn_route_door_test | Jump if not | ||||||
| spawn_route_ends | C5A8 | POP HL | Restore the vischar.target pointer | |||||
| C5A9 | DEC L | Rewind HL to vischar.route | ||||||
| C5AA | DEC L | |||||||
| C5AB | PUSH HL | Preserve the vischar.route pointer | ||||||
| C5AC | CALL route_ended | Route ended | ||||||
| C5AF | POP HL | Restore the vischar.route pointer | ||||||
| C5B0 | LD D,H | Point DE at vischar.target | ||||||
| C5B1 | LD E,L | |||||||
| C5B2 | INC E | |||||||
| C5B3 | INC E | |||||||
| C5B4 | JR spawn_again | Jump back and try again... | ||||||
| spawn_route_door_test | C5B6 | CP $80 | Did get_target return get_target_DOOR? ($80) | |||||
| C5B8 | JR NZ,spawn_got_target | Jump if not (it must be get_target_LOCATION) | ||||||
| spawn_route_door | C5BA | SET 6,(IY+$01) | Set the vischar_FLAGS_TARGET_IS_DOOR flag | |||||
| spawn_got_target | C5BE | POP DE | Restore the vischar.target pointer | |||||
| C5BF | LD BC,$0003 | Copy the next target to vichar.target | ||||||
| C5C2 | LDIR | |||||||
| spawn_end | C5C4 | XOR A | Clear vischar.counter_and_flags | |||||
| C5C5 | LD (DE),A | |||||||
| C5C6 | LD A,E | Rewind DE back to vischar.character (first byte) | ||||||
| C5C7 | SUB $07 | |||||||
| C5C9 | LD E,A | |||||||
| C5CA | EX DE,HL | Swap vischar pointer into HL | ||||||
| C5CB | PUSH HL | Preserve vischar pointer | ||||||
| C5CC | CALL calc_vischar_iso_pos_from_vischar | Calculate screen position for the specified vischar | ||||||
| C5CF | POP HL | Restore vischar pointer | ||||||
| C5D0 | JP character_behaviour | Exit via character_behaviour | ||||||
| Prev: C47E | Up: Map | Next: C5D3 |