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 |