From: Lukas Krickl Date: Fri, 19 Sep 2025 07:32:56 +0000 (+0200) Subject: rework: Removed existing map setup and actor code X-Git-Url: https://git.krickl.dev/?a=commitdiff_plain;h=b17c9cd51d1accb2e99442237821cd4e1700fe6f;p=gbrg%2F.git rework: Removed existing map setup and actor code --- diff --git a/src/action.s b/src/action.s deleted file mode 100644 index 9c55d2a..0000000 --- a/src/action.s +++ /dev/null @@ -1,154 +0,0 @@ -#define ACTION_ATTACK_SPRITE1 0xA0 -#define UNIT_ACTION_ATTACK_ANIM_LEN 16 - - ; sets up default actions for a new game - ; for button A and button B -actions_new_game_init: - ; write default action ptrs - ld hl, action_btna - - ; default A button action - ld a, st_action_attack_init HI - ld [hl+], a - ld a, st_action_attack_init LO - ld [hl+], a - - ; default B button action - ld a, st_action_attack_init HI - ld [hl+], a - ld a, st_action_attack_init LO - ld [hl+], a - - ret - - ; handles an assinged action - ; a player can assign any in-game action to either A or B - ; inputs: - ; hl: action ptr (usually action btna or action btnb) - ; returns: - ; bc: next state -unit_handle_assigned_action: - ; load state ptr for action - ld a, [hl+] - ld b, a - ld a, [hl] - ld c, a - ret - - ; generic direction picker - ; press B to abort - ; press keyopad to pick direction - ; inputs: - ; de: unit - ; bc: next success state - ; returns: - ; bc: null if no press - ; bc: unit_switch_to_active -> B pressed - ; bc: bc input -> direction pressed - ; act_rt_action_dat1: writes pressed bit BTNUP, BTNDOWN, BTNLEFT, BTNRIGHT - ; act_rt_action_dat2: set to 0 -unit_action_pick_direction: - ld hl, act_rt_action_dat1 - add hl, de ; hl = act_rt_action - - ; save next state - push bc - - ; b to abort - ld b, BTNB - input_just - pop bc ; need to pop in case of jp - jp nz, unit_switch_to_active - - push bc ; save again.. - - - ld b, BTNUP - input_just - jr nz, @direction_pressed REL - - ld b, BTNDOWN - input_just - jr nz, @direction_pressed REL - - ld b, BTNLEFT - input_just - jr nz, @direction_pressed REL - - ld b, BTNRIGHT - input_just - jr nz, @direction_pressed REL - - pop bc ; remove from stack - - ldnull bc - ret -@direction_pressed: - ld a, b - ld [hl+], a ; write pressed button to action dat - xor a, a - ; clear dat2 - ld [hl], a - - call ui_status_line_clear - - ; should contain next state - pop bc - ret - - - ; get the attack location - ; input: - ; de: actor - ; returns: - ; bc: tile position -unit_attack_get_attack_tile: - ; get location - call unit_get_pos - - ld hl, act_rt_action_dat1 - add hl, de ; hl = dat1 - - ; determine where to draw animation - ld a, [hl] ; a = direction pressed - cp a, DIRUP - jr nz, @not_up REL - dec b ; y-- -@not_up: - - cp a, DIRDOWN - jr nz, @not_down REL - inc b ; y++ -@not_down: - - cp a, DIRLEFT - jr nz, @not_left REL - dec c ; x-- -@not_left: - - cp a, DIRRIGHT - jr nz, @not_right REL - inc c ; x++ -@not_right: - ret - - ; rests for a turn healing the unit - ; and skipping the turn - ; inputs: - ; de: actor -unit_action_rest: - ld a, 1 - call stat_heal_by - push af - call ui_redraw_player - call ui_request_redraw - - ld hl, STR_HEALDED_FOR - pop af - call ui_draw_status_stat - ldnull bc - ret - - ; rest action skips a turn -st_action_rest: - st_def 0x00, unit_action_rest, st_unit_delay_to_active_template diff --git a/src/action_menu.s b/src/action_menu.s deleted file mode 100644 index e4d7966..0000000 --- a/src/action_menu.s +++ /dev/null @@ -1,123 +0,0 @@ -str_am_attack: -.str "attack" -.db 0 - -str_am_shoot: -.str "shoot" -.db 0 - -str_am_rest: -.str "rest" -.db 0 - -str_am_pick_up: -.str "pick up" -.db 0 - - ; label -action_menu_str_table: - dw str_am_attack - dw str_am_pick_up - dw str_am_shoot - dw str_am_rest -action_menu_str_table_end: - - ; map to actions -action_menu_action_table: - dw st_action_attack_init - dw st_action_attack_init - dw st_action_shoot_init - dw st_action_rest -action_menu_action_table_end: - -#define ACTION_MENU_STR_TABLE_LEN (action_menu_str_table_end - action_menu_str_table) / 2 - - ; game state for action menu selector - ; the action menu allows the player to select - ; any action the character can perform - ; it also allows binding an action to the B button - ; by pressing select - ; inputs: - ; de: state - ; returns: - ; bc: next state -update_action_menu: - ; exit menu on b button press - ld b, BTNB - input_just - jr z, @notb REL - ld bc, st_update_game - ret -@notb: - - ; on up enter debug mode - ld b, BTNUP - input_just - jr z, @notup REL - ; load debug menu - call debug_menu_init - ldnull bc - ret -@notup: - - ; update menu - ld a, [action_menu_cursor] - ld hl, action_menu_str_table - ld b, ACTION_MENU_STR_TABLE_LEN - call select_menu_update - ld [action_menu_cursor], a - - ; did the player select an action? - ld a, b - cp a, BTNA - jr nz, @no_action_selected REL - ; if selection was made - ; return to game state - ; and run action for player - - ; load action into player - ld a, [action_menu_cursor] - add a, a - ld d, 0 - ld e, a - ld hl, action_menu_action_table - add hl, de ; hl = action selected - - ld a, [hl+] - ld e, a - ld a, [hl] - ld d, a - - ; de = action state ptr - ld hl, player_unit - ld bc, st_size - call memcpy - - ld bc, st_update_game - ret -@no_action_selected: - - - ldnull bc - ret - - ; transitions from the current state - ; to action menu -action_menu_init: - ld hl, game_mode - ld de, st_next - add hl, de - ; write st_update_action_menu to st_next - ld a, st_update_action_menu LO - ld [hl+], a - ld a, st_update_action_menu HI - ld [hl], a - - ; draw the initial status line - ld a, [action_menu_cursor] - ld b, ACTION_MENU_STR_TABLE_LEN - ld hl, action_menu_str_table - call select_menu_draw_status - - ret - diff --git a/src/actortables.s b/src/actortables.s deleted file mode 100644 index 3c70e14..0000000 --- a/src/actortables.s +++ /dev/null @@ -1,35 +0,0 @@ -#include "unit_demo.s" - -; actor table: -; an actor table is a list of actors -; that can either be loaded into the active table directly -; or it can be used as a template for placing new actors -; that are valid for this map. -; to use as a template use the actors but move the position -; as needed and setting act_loot_table_dat. - -floor_1_actor_table: -map_c_actor_table: -.db 7 ; size -dw unit_demo_guard -dw unit_demo_guard -dw unit_demo_guard -dw unit_demo_hazmat -dw unit_demo_hazmat -dw unit_demo_dog -dw unit_demo_dog -dw unit_demo_dog -dw unit_demo_dog -dw unit_demo_guard -dw unit_demo_guard -dw unit_demo_guard -dw unit_demo_guard -dw unit_demo_guard -dw unit_demo_guard -dw unit_demo_guard -dw unit_demo_guard -dw unit_demo_guard - -; actor tables for each floor -floor_actor_tables: -dw floor_1_actor_table diff --git a/src/actsave.s b/src/actsave.s deleted file mode 100644 index e9a90f0..0000000 --- a/src/actsave.s +++ /dev/null @@ -1,230 +0,0 @@ - ; init the actor saves - ; sets everything to 0xFF -act_save_init: - ld hl, act_sg - ld bc, act_sg_end - act_sg - ld d, ACT_SG_DEFAULT_VALUE - call memset - ret - - ; loads current start of save game slot - ; based on the current map seed index - ; inputs: - ; a: map cursor - ; returns: - ; bc: act save game slot -act_sg_load_current_slot: - ld hl, act_sg - ; no need to loop if a is 0 - cp a, 0 - jr z, @done REL - ld de, act_sg_size * UNITS_MAX - - ; add sg size for every index offset -@loop: - add hl, de - dec a - jr nz, @loop REL -@done: - push hl - pop bc ; we want return value in bc - - ret - - ; stores actor save game - ; based on the current map's seed offset - ; skipped if [map_header] is NULL -act_sg_store: - ; check if map header is NULL - ld a, [map_header] - ld b, a - ld a, [map_header+1] - or a, b - ret z - - ld a, [player_map_cursor_prev] - call act_sg_load_current_slot - - ld hl, p0_units -.rep i, UNITS_MAX, 1, call act_sg_store_single - - ret - - ; stores data from a single actor into - ; the save slot - ; inputs: - ; bc: act save game slot - ; hl: actor - ; returns: - ; hl: next actor - ; bc: next slot -act_sg_store_single: - ; store type - push hl - ld de, act_type - add hl, de - ld a, [hl] - ld [bc], a - inc bc - pop hl - - push hl - ; store flags - ld de, act_flags - add hl, de - ld a, [hl] - ld [bc], a - inc bc - pop hl - - push hl - - ; store y pos - ld de, act_pos_y - add hl, de - ld a, [hl+] - ld [bc], a - inc bc - - ; store x pos - ld a, [hl] - ld [bc], a - inc bc - - pop hl - - ; store p0 - push hl - ld de, act_p0 - add hl, de - ld a, [hl] - ld [bc], a - inc bc - pop hl - - ; store hp - push hl - ld de, act_hp - add hl, de - - ld a, [hl] - ld [bc], a - inc bc - pop hl - - ; sotre mp - push hl - ld de, act_mp - add hl, de - - ld a, [hl] - ld [bc], a - inc bc - pop hl - - ; advance to next actor - ld de, act_size - add hl, de - - ret - - ; restores actor save game based on - ; current map's seed offset -act_sg_restore: - ld a, [player_map_cursor] - call act_sg_load_current_slot - ; skip over player -.rep i, act_sg_size, 1, inc bc - ld hl, p0_units+act_size -.rep i, UNITS_MAX-1, 1, call act_sg_restore_single - ret - - ; restores a single entry of actor data - ; skips restore if pos y is 0xFF - ; inputs: - ; bc: act save game slot - ; hl: actor - ; returns: - ; hl: next actor - ; bc: next slot -act_sg_restore_single: - inc bc ; bc = position y - ld a, [bc] - dec bc - cp a, 0xFF - jp z, @skip ; skip if 0xFF - - ; load type - push hl - ld de, act_type - add hl, de - ld a, [bc] - ld [hl], a - inc bc - pop hl - - push hl - ; load flags - ld de, act_flags - add hl, de - ld a, [bc] - ld [hl], a - inc bc - pop hl - - push hl - ; load positions - ld de, act_pos_y - add hl, de - ld a, [bc] - ld [hl+], a - inc bc - - ld a, [bc] - ld [hl], a - inc bc - - pop hl - - push hl - ; load p0 - ld de, act_p0 - add hl, de - - ld a, [bc] - ld [hl], a - inc bc - - pop hl - - ; load hp - push hl - ld de, act_hp - add hl, de - - ld a, [bc] - ld [hl], a - inc bc - - pop hl - - ; load mp - push hl - ld de, act_mp - add hl, de - - ld a, [bc] - ld [hl], a - inc bc - pop hl - - ld de, act_size - add hl, de ; next actor - ret - -@skip: - ; move to next item and ret -.rep i, act_sg_size, 1, inc bc - ld de, act_size - add hl, de - ret diff --git a/src/animation.s b/src/animation.s deleted file mode 100644 index 78a4cc5..0000000 --- a/src/animation.s +++ /dev/null @@ -1,379 +0,0 @@ -#define ATTACK_ANIM_LEN 32 - -player_anim_table: - anim_header 32, player_anim_table_f2 - anim_ent 0, 8, 0x8C, OAM_FXFLIP - anim_ent 0, 0, 0x8E, OAM_FXFLIP - anim_ent 0, 0, 0x00, 0 - -player_anim_table_f2: - anim_header 32, player_anim_table - anim_ent 1, 8, 0x8C, OAM_FXFLIP - anim_ent 1, 0, 0x8E, OAM_FXFLIP - anim_ent 0, 0, 0x00, 0 - -player_anim_table_attack_up: - anim_header ATTACK_ANIM_LEN, player_anim_table - anim_ent 1, 8, 0x8C, OAM_FXFLIP - anim_ent 1, 0, 0x8E, OAM_FXFLIP - anim_ent -12, 0, ACTION_ATTACK_SPRITE1, 0 - -player_anim_table_attack_down: - anim_header ATTACK_ANIM_LEN, player_anim_table - anim_ent 1, 8, 0x8C, OAM_FXFLIP - anim_ent 1, 0, 0x8E, OAM_FXFLIP - anim_ent 12, 0, ACTION_ATTACK_SPRITE1, 0 - -player_anim_table_attack_left: - anim_header ATTACK_ANIM_LEN, player_anim_table - anim_ent 1, 8, 0x8C, OAM_FXFLIP - anim_ent 1, 0, 0x8E, OAM_FXFLIP - anim_ent 0, -12, ACTION_ATTACK_SPRITE1, 0 - -player_anim_table_attack_right: - anim_header ATTACK_ANIM_LEN, player_anim_table - anim_ent 1, 8, 0x8C, OAM_FXFLIP - anim_ent 1, 0, 0x8E, OAM_FXFLIP - anim_ent 0, 12, ACTION_ATTACK_SPRITE1, 0 - - ; table that maps actor type to - ; a list of animations -anim_actor_table: - dw NULL - dw anim_list_player - dw anim_list_guard - dw anim_list_dog - dw anim_list_hazmat - - -anim_list_player: - ; IDLE_NEUTRAL - dw player_anim_table - ; ATTACK LEFT - dw player_anim_table_attack_left - ; ATTACK RIGHT - dw player_anim_table_attack_right - ; ATTACK_UP - dw player_anim_table_attack_up - ; ATTACK_DOWN - dw player_anim_table_attack_down - -anim_list_guard: - ; IDLE NEUTRAL - dw unit_demo_guard_anim_table - ; ATTACK LEFT - dw unit_demo_guard_attack_left - ; ATTACK RIGHT - dw unit_demo_guard_attack_right - ; ATTACK UP - dw unit_demo_guard_attack_up - ; ATTACK DOWN - dw unit_demo_guard_attack_down - -anim_list_dog: - ; idle neutral - dw unit_demo_dog_anim_table - ; attack left - dw unit_demo_dog_attack_left - ; attack right - dw unit_demo_dog_attack_right - ; attack up - dw unit_demo_dog_attack_up - ; attack down - dw unit_demo_dog_attack_down - -anim_list_hazmat: - ; idle - dw unit_demo_hazmat_anim_table - ; attack left - dw unit_demo_hazmat_attack_left - ; attack right - dw unit_demo_hazmat_attack_right - ; attack up - dw unit_demo_hazmat_attack_up - ; attack down - dw unit_demo_hazmat_attack_down - - - ; translates tile to screen - ; inputs: - ; $1: Y/X offset - ; $2: register containing scroll - ; a: tile position -#macro tile_to_scrn - add a, $1 - sub a, $2 -#endmacro - - ; loads an animation for the current acotr - ; based on its type - ; and the requested animation entry - ; inputs: - ; de: actor - ; b: the animation - ; writes: - ; new animation into selected actor -anim_load_type: - push de ; save actor - - ; 1) load animation list based on type - ld hl, act_type - add hl, de - ld a, [hl] ; a = actor type - sla a ; * 2 to use as ptr offset - ld d, 0 - ld e, a - ld hl, anim_actor_table - add hl, de - - ld a, [hl+] - ld d, a - ld a, [hl+] - ld h, a - ld l, d - - ; 2) load animation table based on requested animation - - sla b ; * 2 to get offset - ld d, 0 - ld e, b - add hl, de ; get animation ptr - - ld a, [hl+] - ld c, a - ld a, [hl+] - ld b, a - - ; bc = animation ptr - - ; 3) write animation to animation entry - pop de ; restore actor - - ; write anim table - ld hl, act_anim_table - add hl, de - ld a, c - ld [hl+], a - ld a, b - ld [hl], a - ret - - ; performs no drawing -unit_nop_draw: - ldnull bc - ret - - - ; calls unit's draw function - ; inputs: - ; hl: actor ptr -unit_update_draw: - push hl - ld de, act_draw - add hl, de - ; hl = draw ptr - ld a, [hl+] - ld e, a - ld a, [hl] - ld d, a - ; de = draw function - push de - pop hl ; hl = draw function - pop de ; de = actor - call_hl - ret - - ; gets the left tile offset - ; for object 1 - ; based on the y flip of oam - ; inputs: - ; a: oam flags - ; returns: - ; a: x-offset -get_left_tile_offset1: - and a, OAM_FXFLIP - jr z, @not_set REL - ld a, 8 - ret -@not_set: - xor a, a - ret - - ; gets the left tile offset - ; for object 2 - ; based on the y flip of oam - ; inputs: - ; a: oam flags - ; returns: - ; a: x-offset -get_left_tile_offset2: - and a, OAM_FXFLIP - jr z, @not_set REL - xor a, a - ret -@not_set: - ld a, 8 - ret - - ; draws a unit's animation table - ; draws all 3 tables based on animation timer - ; and animation max value (first item in table) - ; inputs - ; de: actor -unit_draw: - ; load anim entries - ld hl, act_anim_table - add hl, de ; hl = entry 1 - ld a, [hl+] - push af - ld a, [hl] - ld h, a - pop af - ld l, a - push hl - pop bc - - ; bc = animation header - push bc ; save header for later - inc bc - inc bc - inc bc ; go past header - - ; bc = anim talbe entry - call unit_draw_obj - call unit_draw_obj - call unit_draw_obj - - ; process header - pop bc - - ld hl, act_rt_anim_timer - add hl, de ; hl = animation timer - ld a, [hl] - inc a - ld [hl], a ; timer++ - - push de - ld d, a ; d = current timer - ld a, [bc] ; a = expected timer - cp a, d ; next frame? - pop de - jr nc, @no_new_frame REL - - ; if new frame: clear timer - xor a, a - ld [hl], a ; clear timer - - inc bc ; bc = next animation ptr - ; load next table - ld hl, act_anim_table - add hl, de - ld a, [bc] - ld [hl+], a - inc bc - ld a, [bc] - ld [hl], a -@no_new_frame: - ret - - ; draws a single object - ; in the current animation table - ; inputs: - ; de: actor - ; bc: anim table entry - ; returns: - ; bc: next entry -unit_draw_obj: -#define TMP_SCROLL_Y scratch -#define TMP_SCROLL_X scratch+1 -#define TMP_A scratch+2 - ; skip if tile is 0x00 - inc bc - inc bc - ld a, [bc] - dec bc - dec bc - cp a, 0 - jp z, @skip_ent - - push de - - ; hl = pos y - ld hl, act_pos_y - add hl, de - push hl - pop de ; de = pos y - - push bc - push de - - call load_scroll - ld a, b - ld [TMP_SCROLL_Y], a - ld a, c - ld [TMP_SCROLL_X], a - - call load_unit_obj - - pop de - - ; set y position - ld a, [TMP_SCROLL_Y] - ld b, a ; b = y scroll - ld a, [de] - tile_to_scrn OBJ_OFF_Y, b ; scroll offset - ld [TMP_A], a - - ; apply anim entry y offset - pop bc - ld a, [bc] - push bc - ld b, a - ld a, [TMP_A] - add a, b ; a += y offset - ; write result to obj - ld [hl+], a - - - ; set x position - inc de - ld a, [TMP_SCROLL_X] - ld c, a ; c = scroll x - ld a, [de] - tile_to_scrn OBJ_OFF_X, c - ld [TMP_A], a - - ; apply anim entry x offset - pop bc - inc bc ; next entry - ld a, [bc] - push bc - ld b, a - ld a, [TMP_A] - add a, b ; a += x offset - ; write result to obj - ld [hl+], a - - pop bc - inc bc ; bc = tile index - ; write tile from table - ld a, [bc] - ld [hl+], a - - ; write flags - inc bc - ld a, [bc] - ld [hl+], a - inc bc - - pop de - ret -@skip_ent: - inc bc - inc bc - inc bc - inc bc - ret -#undefine TMP_SCROLL_Y -#undefine TMP_SCROLL_X -#undefine TMP_A diff --git a/src/attack.s b/src/attack.s deleted file mode 100644 index 8955dd4..0000000 --- a/src/attack.s +++ /dev/null @@ -1,140 +0,0 @@ -; melee attack action - - - ; picks a direction for an attack - ; inputs: - ; de: unit - ; returns: - ; bc: next action -unit_action_attack_pick_direction_init: - ; draw question to status line - ld hl, STR_ATTACK_DIRECTION - ld de, UI_STATUS_LINE - call puts - - call ui_request_redraw - - ldnull bc - ret - - ; reads player direction inputs to pick a direction - ; inputs: - ; de: unit - ; returns: - ; bc: next action -unit_action_attack_pick_direction: - ld bc, st_action_attack_damage_actor - jp unit_action_pick_direction - - ; decides which animation to load - ; based on units action dat 1 direction - ; inputs: - ; de: actor -unit_action_attack_decide_animation: - ld hl, act_rt_action_dat1 - add hl, de - - ld a, [hl] - cp a, DIRUP - jr nz, @notup REL - ld b, ANIM_T_ATTACK_UP - call anim_load_type - ret -@notup: - - cp a, DIRDOWN - jr nz, @notdown REL - ld b, ANIM_T_ATTACK_DOWN - call anim_load_type - ret -@notdown: - - cp a, DIRLEFT - jr nz, @notleft REL - ld b, ANIM_T_ATTACK_LEFT - call anim_load_type - ret -@notleft: - - cp a, DIRRIGHT - jr nz, @notright REL - ld b, ANIM_T_ATTACK_RIGHT - call anim_load_type -@notright: - ret - - ; performs an attack - ; based on the units rt_action tmp value - ; inputs: - ; de: unit - ; returns: - ; bc: next action -unit_action_attack_finish: - - ; unset flag - ld a, [gpf_attack_ongoing] - dec a - ld [gpf_attack_ongoing], a - - ldnull bc - ret - - ; performs damage calculations based on the attacked location - ; inputs: - ; de: unit - ; returns: - ; bc: new state -unit_action_attack_damage_calc: - ; play animation - push de - call unit_action_attack_decide_animation - call play_attack_noise - pop de - - ; set flag - ld a, [gpf_attack_ongoing] - inc a - ld [gpf_attack_ongoing], a - - ; calculate damage - push de - call unit_attack_get_attack_tile - call unit_find_at - - ld a, h - or a, l - pop de - jp z, @miss ; no unit found - - - push hl - pop bc - ; de = attacker - ; bc = attacked unit - push hl - call stat_calc_physical_damage_vs - pop hl - - ld hl, STR_HIT_FOR - call ui_draw_status_stat - call ui_redraw_player - - ldnull bc - ret -@miss: - ld hl, STR_MISS - ld de, UI_STATUS_LINE - call puts - call ui_request_redraw - ldnull bc - ret - - ; default attack state -st_action_attack_init: - st_def 0x00, unit_action_attack_pick_direction_init, st_action_attack_pick_direction -st_action_attack_pick_direction: - st_def 0x00, unit_action_attack_pick_direction, st_action_attack_pick_direction -st_action_attack_direction_picked: - st_def ATTACK_ANIM_LEN, unit_action_attack_finish, st_unit_delay_to_active_fast -st_action_attack_damage_actor: - st_def 0x00, unit_action_attack_damage_calc, st_action_attack_direction_picked diff --git a/src/battle.s b/src/battle.s deleted file mode 100644 index 4725d95..0000000 --- a/src/battle.s +++ /dev/null @@ -1,7 +0,0 @@ - ; inputs: - ; de: source actor - ; bc: target coordinates -battle_attack: - call unit_find_at - ret - diff --git a/src/debug.s b/src/debug.s index 4ada5bb..e69de29 100644 --- a/src/debug.s +++ b/src/debug.s @@ -1,107 +0,0 @@ -; this is a helper file for a debug menu - -strz str_dbg_new_game, "RELOAD" - -str_dbg_clear_actors: -.str "CLEAR ACTORS" -.db 0 - -debug_menu_str_table: - dw str_dbg_new_game - dw str_dbg_clear_actors -debug_menu_str_table_end: - -#define DEBUG_MENU_STR_TABLE_LEN (debug_menu_str_table_end - debug_menu_str_table) / 2 - -; debug routines: -; get jumped to directly -; return: -; bc: new game state -debug_menu_action_table: - dw debug_fn_new_game - dw debug_fn_clear_actors -debug_menu_action_table_end: - - ; updates the debug menu - ; inputs: - ; de: state - ; returns: - ; bc: next state -update_debug_menu: - ; exit debug menu on b press - ld b, BTNB - input_just - jr z, @notb REL - ld bc, st_update_game - ret -@notb: - - ; update menu - ld a, [debug_menu_cursor] - ld hl, debug_menu_str_table - ld b, DEBUG_MENU_STR_TABLE_LEN - call select_menu_update - ld [debug_menu_cursor], a - - ; did the player select an action? - ld a, b - cp a, BTNA - jr nz, @no_action_selected REL - - ; load ptr from action table - ; into hl and call it - ld a, [debug_menu_cursor] - add a, a ; * 2 for offset - ld hl, debug_menu_action_table - ld d, 0 - ld e, a - add hl, de - - ld a, [hl+] - ld d, a - ld a, [hl] - ld h, a - ld l, d - - ; jp to selected routine - jp hl -@no_action_selected: - - ldnull bc - ret - -debug_menu_init: - ld hl, game_mode - ld de, st_next - add hl, de - ; write st_update_debug_menu to std_Next - ld a, st_update_debug_menu LO - ld [hl+], a - ld a, st_update_debug_menu HI - ld [hl], a - - ; draw initial status line - ld a, [debug_menu_cursor] - ld b, DEBUG_MENU_STR_TABLE_LEN - ld hl, debug_menu_str_table - call select_menu_draw_status - ret - - ; debug new game routine - ; but load with a known hard-coded seed - ; returns: - ; bc: new state -debug_fn_new_game: - ; ld a, 15 - ; ld [srand], a - ; ld [srand+1], a - - call new_game_init - ld bc, st_update_game - ret - -debug_fn_clear_actors: - ld bc, st_update_game - ret - - diff --git a/src/defs.s b/src/defs.s index 43bce5f..76868ed 100644 --- a/src/defs.s +++ b/src/defs.s @@ -3,42 +3,20 @@ .section defs -#define FLOOR_W 4 -#define FLOOR_H 4 -#define FLOOR_MAP_COUNT (FLOOR_W * FLOOR_H) - #define UI_STATUS_LINE shadow_ui+1 .def int OAMDMAFN = 0xFF80 #define WRAM 0xC000 #define WRAMLEN 0xFFF -#define STAT_MAX 255 - -; game speed defs -#define GAME_SPEED_SLOW 128 -#define GAME_SPEED_NORMAL 235 -#define GAME_SPEED_FAST 255 - #define GAME_SPEED_DEFAULT GAME_SPEED_NORMAL #define NULL 0 -#define UNITS_MAX 20 -#define UNITS_SPAWN_MIN 2 -#define UNITS_SPAWN_MASK 3 +#define ACTS_MAX 32 #define STACK_BEGIN 0xDFFF -#define TILE_SIZE 8 -#define MAP_W 16 -.def int MAP_W_DEF = MAP_W -#define MAP_H 16 -#define MAP_SIZE (MAP_W * MAP_H) - -#define VIEW_PORT_TILES_W 6 -#define VIEW_PORT_TILES_H 6 - ; seed for the rng ; 8 bit signed int #define RAND_MAGIC 0x1B @@ -50,98 +28,6 @@ #define UI_TILE_WIDTH 32 #define UI_TILE_HEIGHT 4 -#define BG_WIDTH 32 -#define BG_SHADOW_HEIGHT 4 - - ; defines end of scroll location -#define CURSOR_MIN_X 0 -#define CURSOR_MAX_X 0xF8 -#define CURSOR_MIN_Y 0 -#define CURSOR_MAX_Y 0xB8 - -#define REDRAW_TILES_PER_FRAME 4 - - - - ; draw flags -.se 1 - ; if set to 1, return - ; an invalid object from soam - ; when units want to draw -.de DRAWF_SKIP_UNIT_OBJS, 1 - - - ; gameplay flags -.se 1 - ; if this is set units do not update - ; but draw calls still happen - ; this is useful when waiting for an animation -.de GPF_PAUSE_UPDATE, 1 - ; set if the player has taken their turn - ; this will allow all other units to - ; perform their update -.de GPF_PLAYER_TURN_TAKEN, 2 - - ; cell flags -.se 1 -.de CF_COLLISION, 1 - ; exit flag - ; flags this tile as a valid exit - ; must be at the edge of the map - ; TODO: maybe add a special exit as a default -.de CF_EXIT, 2 -.de CF_DOOR, 4 - ; if this flag is set do not - ; set object priority bit - ; so that objects are behind the tile -.de CF_COVERED, 8 - - ; player special flags - ; set if player is currently on a covered tile. - ; this can be used for drawing units that - ; are inside -.def int PLAYERSF_CF_COVERED = CF_COVERED - - ; cells struct -.se 0 -.de c_tile, 1 -.de c_flags, 1 -.de c_size, 0 - - ; state struct - ; states are intended to - ; be used as part of a larger - ; struct - ; e.g. player state -.se 0 - ; time until next state -.de st_time, 1 - ; state routine (LE) - ; it can return 0000 in hl - ; or a new state address in hl (LE) - ; if bc is not 0000 after - ; the calling state's address - ; will be set to bc immediatly - ; inputs for all state routines: - ; de: state pointer -.de st_routine, 2 - ; next state (LE) -.de st_next, 2 -.de st_size, 0 - - - ; stats struct - ; this tracks the current value. most real values - ; are calculated - ; e.g. stat_calc_str with actor as input -#define stat_size 1 - - ; status effect -.se 0 -.de effect_type, 1 -.de effect_dat, 1 -.de effect_size, 0 - ; actor type enum .se 0 @@ -150,127 +36,34 @@ .de ACT_T_GUARD, 1 .de ACT_T_DOG, 1 .de ACT_T_HAZMAT, 1 - - ; actor struct (unit's are instances of actors) - ; actor structs are basically just states - ; to define an actor the following macros must be used in order - ; st_def + + ; actor struct ; act_def - ; act_stat_def1 - ; act_stat_def2 - ; act_st_def - ; act_def_meta .se 0 - ; copy of current state -.de act_state, st_size .de act_type, 1 .de act_flags, 1 -.de act_pos_y, 1 ; y/x tile position +.de act_pos_y, 1 ; y/x position .de act_pos_x, 1 ; custom parameter .de act_p0, 1 - ; actor runtime values - - ; last collision tile position -.de act_rt_collision_pos_y, 1 -.de act_rt_collision_pos_x, 1 - ; last collision flags -.de act_rt_collision_cf, 1 - ; last collision with actor - ; set during unit_collision_woth_any_other -.de act_rt_collided_with, 2 - - ; temporary buffer for any action picked -.de act_rt_action_dat1, 1 -.de act_rt_action_dat2, 1 - - ; generic timer - ; can be used for animations or other relevant timers - ; state switching may change this value. -.de act_rt_timer, 1 - - ; animation frame timer -.de act_rt_anim_timer, 1 - - ; stats1 -.de act_level, 1 -.de act_hp, stat_size -.de act_mp, stat_size -.de act_ac, stat_size - - ; stats2 - -.de act_str, stat_size -.de act_int, stat_size -.de act_dex, stat_size -.de act_vit, stat_size - - ; actor states - ; used for state switching - ; set to 0000 to disable the state -.de act_st_active, 2 -.de act_st_idle, 2 - - ; ptr to function for drawing the actor - ; called after state update - ; replace in state code if drawing needs to be - ; changed at runtime - ; inputs: - ; de: actor - ; returns: - ; bc: null -.de act_draw, 2 -.de act_anim_table, 2 + ; stats +.de act_hp, 1 +.de act_ac, 1 .de act_size, 0 - ; actor save game data - ; if pos y and x is 0xFF - ; it is not restored -.se 0 -.de act_sg_type, 1 -.de act_sg_flags, 1 -.de act_sg_pos_y, 1 -.de act_sg_pos_x, 1 -.de act_sg_p0, 1 -.de act_sg_hp, 1 -.de act_sg_mana, 1 -.de act_sg_size, 0 - -#define ACT_SG_DEFAULT_VALUE 0xFF - -#define MAP_BG_TILE_OFFSET 0 -#define MAP_BG_FLAGS_OFFSET 1 - -#define MAP_NAME_LEN 8 - - ; map flags1 -.se 1 - ; disables random generation -.de MAPF1_NO_RAND, 1 ; map header struct .se 0 -.de map_flags_1, 1 -.de map_flags_2, 1 -.de map_flags_3, 1 -.de map_flags_4, 1 +.de map_flags, 1 ; 8 bytes reserved for map names ; map_name in map properties -.de map_name, MAP_NAME_LEN .de map_bg_ptr, 2 -.de map_tile_flags_ptr, 2 - ; ptr to mape state to be loaded - ; maps to map property state_ptr -.de map_state_ptr, 2 - ; ptr to actor table - ; an actor table is a single byte for number of actors - ; followed by a list of pointers to actor - ; templates - ; maps to map property actor_table_ptr -.de map_actor_table_ptr, 2 + + ; ptr to map objects list +.de map_objs_ptr, 2 ; pointers to tile banks to be loaded ; maps to map property tile_bank0, tile_bank1, tile_bank2, tile_bank3 ; note that tile_bank1 and tile_bank2 are 128 bytes each @@ -281,82 +74,6 @@ .de map_tile_bank3_ptr, 2 .de map_header_size, 0 - ; map actor table struct -.se 0 -.de map_actor_table_len, 1 - ; list of be pointers to actors -.de map_actor_table_act_ptrs, 0 - - - ; map exit table entry struct -.se 0 -.de exit_flags, 1 - ; if this is != 0 - ; the exit will only trigger - ; if the input specified is pressed -.de exit_required_input, 1 -.de exit_goto_y, 1 -.de exit_goto_x, 1 - ; pointer to new map struct -.de exit_to, 2 -.de exit_size, 0 - - ; object animation struct - ; simple call in update code - ; with a single state - ; intended for use with short-term map animations - ; e.g. door opening -.se 0 -.de obja_st, st_size -.de obja_flags, 1 -.de obja_pos_y, 1 -.de obja_pos_x, 1 -.de obja_dat, 1 - ; time in frames -.de obja_timer, 1 -.de obja_size, 0 - - - ; action struct -.se 0 -.de action_st_action_ptr, 2 -.de action_size, 0 - - ; animation header -.se 0 -.de anim_header_frame_time, 1 -.de anim_header_next, 2 - -; animation entry struct -; start with a header -; an animation table *always* has -; 3 entries -; if the tile is 0x00 the entry is not rendered -.se 0 -.de anim_ent_y_offset, 1 -.de anim_ent_x_offset, 1 -.de anim_ent_oam_tile, 1 -.de anim_ent_oam_flags, 1 -.de anim_ent_size, 0 - -; animation types -.se 0 -.de ANIM_T_IDLE_NEUTRAL, 1 -.de ANIM_T_ATTACK_LEFT, 1 -.de ANIM_T_ATTACK_RIGHT, 1 -.de ANIM_T_ATTACK_UP, 1 -.de ANIM_T_ATTACK_DOWN, 1 - - -; special text commands - -; consumes the command -; and interprets the next -; byte as a number -#define TEXT_NUMBER 0x80 - - ; constants - #define DISTANCE_BGTA 1 #define DISTANCE_AGTB 0 diff --git a/src/effect.s b/src/effect.s deleted file mode 100644 index 1e7d96d..0000000 --- a/src/effect.s +++ /dev/null @@ -1,22 +0,0 @@ - ; updates a unit's status effects - ; inputs: - ; de: unit -effects_unit_update: - ret - - ; adds a new effect to a unit - ; if no effect slot is available - ; the new effect is dropped - ; inputs: - ; de: unit - ; a: effect type - ; b: effect dat -effect_add: - ret - - ; updates a single status effect - ; inputs: - ; de: unit - ; hl: effect -effect_update: - ret diff --git a/src/exittables.s b/src/exittables.s deleted file mode 100644 index e69de29..0000000 diff --git a/src/game.s b/src/game.s new file mode 100644 index 0000000..a4e275c --- /dev/null +++ b/src/game.s @@ -0,0 +1,9 @@ + ; sets the state routine + ; inputs: + ; hl: new state +game_set_state: + ld a, l + ld [game_state], a + ld a, h + ld [game_state+1], a + ret diff --git a/src/macros.inc b/src/macros.inc index 96ae48e..45f7654 100644 --- a/src/macros.inc +++ b/src/macros.inc @@ -115,144 +115,6 @@ .endscope #endmacro - - ; adjust player scroll - ; inputs: - ; $1: add/sub - ; $2: scroll_move_y/x - ; uses: a - ; skipped if z flag is 1 -#macro cursor_adjust_scroll -.beginscope - ld a, [$2] - $1 a, 1 - ld [$2], a -.endscope -#endmacro - - ; move cursor - ; inputs: - ; $1: cursor_move_y/x -> move - ; $2: cursor_move_y/x -> clear - ; $2: NEGATE/1 -#macro cursor_move_direction - xor a, a - ld [$2], a - ld a, CURSOR_MOVE_SPEED * $3 - ld [$1], a -#endmacro - - ; defines a state - ; to be used by actors - ; inputs: - ; $1 timer - ; $2 routine - ; $3 next -#macro st_def - .db $1 - dw $2 - dw $3 -#endmacro - - ; defines actor meta data call for actor - ; inputs: - ; $1: draw call - ; $2: animation header ptr -#macro act_def_meta - dw $1 - dw $2 -#endmacro - - ; define an actor without state - ; to define an actor call - ; st_def and act_def - ; inputs: - ; $1 type - ; $2 flags - ; $3 y pos - ; $4 x pos - ; $5 custom p0 value -#macro act_def - .db $1 ; type - .db $2 ; flags - .db $3 ; y pos - .db $4 ; x pos - .db $5 ; p0 - - ; act rt pos y, pos x, collision cf - .db 0, 0, 0 - ; act_rt_collided_with - dw 0 - ; act_rt_action_dat1/2 - .db 0, 0 - - ; rt timer - .db 0 - ; rt animation timer - .db 0 -#endmacro - - ; defines an actor's stats (1/2) - ; $1 level - ; $2 health points - ; $3 mana points - ; $5 armor -#macro act_stat_def1 - .db $1 ; level - .db $2 ; hp hp max - .db $3 ; mp mp max - .db $4 ; ac -#endmacro - - ; $1 str - ; $2 int - ; $3 dex - ; $4 vit -#macro act_stat_def2 - .db $1 ; str - .db $2 ; int - .db $3 ; dex - .db $4 ; vit -#endmacro - - ; defines actor state callbacks - ; inputs: - ; $1: st_active - ; $2: st_idle -#macro act_st_def - dw $1 - dw $2 -#endmacro - - ; defines an exit table entry - ; inputs: - ; $1: flags - ; $2: required input/0 - ; $3: goto y - ; $4: goto x - ; $5: map header pointer -#macro exit_def - .db $1 - .db $2 - .db $3 - .db $4 - dw $5 -#endmacro - - ; loads NULL into a 16 bit register - ; inputs: - ; $1: register -#macro ldnull - ld $1, 0 -#endmacro - - ; creates a NUL terminated string - ; inputs: - ; $1: string -#macro strt - .str $1 - .db 0 -#endmacro ; calls rst 0x08 #macro call_hl @@ -278,28 +140,6 @@ ld b, a #endmacro - ; animation header - ; inputs: - ; $1: frame time - ; $2: next frame ptr -#macro anim_header - .db $1 - dw $2 -#endmacro - - ; animation entry - ; inputs: - ; $1: y offset - ; $2: x offset - ; $3: tile - ; $4: oam flags -#macro anim_ent - .db $1 - .db $2 - .db $3 - .db $4 -#endmacro - ; defines a 0-terminated stirng ; inpputs: ; $1: label name diff --git a/src/main.s b/src/main.s index 0587cf8..24402c5 100644 --- a/src/main.s +++ b/src/main.s @@ -56,34 +56,16 @@ main: #include "sys.s" #include "input.s" #include "player.s" -#include "unit_cpu.s" #include "update.s" #include "ui.s" #include "audio.s" #include "map.s" #include "math.s" +#include "game.s" -#include "animation.s" -#include "roompatterns.s" -#include "mapgen.s" -#include "state.s" #include "tiles.inc" -#include "unit.s" -#include "effect.s" #include "text.s" -#include "stats.s" -#include "actortables.s" -#include "exittables.s" #include "demos.s" -#include "mainmenu.s" -#include "actsave.s" -#include "objanim.s" -#include "battle.s" -#include "action.s" -#include "attack.s" -#include "shoot.s" -#include "action_menu.s" -#include "select_menu.s" #include "debug.s" ; fill bank diff --git a/src/mainmenu.s b/src/mainmenu.s deleted file mode 100644 index 43da733..0000000 --- a/src/mainmenu.s +++ /dev/null @@ -1,150 +0,0 @@ -#define MAIN_MENU_FILE_1_OFFSET 128+2 - -#define MENU_CURSOR_TILE 0xF5 -#define MENU_CURSOR_TILE_REVERSE 0xF5+3 - - - ; location table for cursor - ; y positon -main_menu_cursor_locations_y: -.db 40, 48, 56, 72 - -#define MAIN_MENU_CURSOR_MAX 3 - - ; fixed x position -#define main_menu_cursor_x 16 - - ; update main menu state - ; handles cursor sprite drawing - ; handles file/new game selection -main_menu_update: - call rand - - ; clear oam - call shadow_oam_clear - - ; ensure the cursor is capped to MAX - ld a, [menu_cursor_index] - and a, MAIN_MENU_CURSOR_MAX - ld [menu_cursor_index], a - - ; draw cursor as sprite - ld d, 0 - ld a, [menu_cursor_index] - ld e, a ; de = cursor location offset - ld hl, main_menu_cursor_locations_y - add hl, de - ld a, [hl] ; a = y position - - ld hl, shadow_oam - ld [hl+], a ; write y - - ld a, main_menu_cursor_x - ld [hl+], a ; write x - - ; write tile - ld a, MENU_CURSOR_TILE - ld [hl+], a - - xor a, a - ld [hl], a ; write flags - - - ld b, BTNSTART | BTNA ; b = button mask - input_just - jr z, @no_new_game REL - ld bc, st_init_new_game - ret -@no_new_game: - - ld b, BTNDOWN - input_held - jr z, @not_down REL - - ; cursor++ - ld a, [menu_cursor_index] - inc a - ld [menu_cursor_index], a - ld bc, st_main_menu_delay - ret -@not_down: - - - ld b, BTNUP - input_held - jr z, @not_up REL - - ; cursor-- - ld a, [menu_cursor_index] - dec a - ld [menu_cursor_index], a - ld bc, st_main_menu_delay - ret -@not_up: - - ldnull bc - ret - - ; inits main menu - ; draws the menu screen to SCRN0 - ; disables lcd and interrupts while it is - ; loading -main_menu_init: - call next_vblank_wait - call lcd_off - - ; set up palettes - ; for main menu - ld a, 0b11000000 - ld [RBGP], a - - ld a, 0b11000000 - ld [ROBP0], a - - ld a, 0b11000000 - ld [ROBP1], a - - call unit_load_default_player - - ; load tile banks of default map - ld hl, map_c_header - call map_tile_banks_load - - - ld hl, STR_FILE1 - ld de, SCRN0+MAIN_MENU_FILE_1_OFFSET - call puts - - ld hl, STR_FILE2 - ld de, SCRN0+MAIN_MENU_FILE_1_OFFSET+32 - call puts - - ld hl, STR_FILE3 - ld de, SCRN0+MAIN_MENU_FILE_1_OFFSET+64 - call puts - - ld hl, STR_DELETE - ld de, SCRN0+MAIN_MENU_FILE_1_OFFSET+128 - call puts - - ; hide window - ld a, 144 - ld [RWY], a - ld [RWX], a - - ; set cursor index to 0 - xor a, a - ld [menu_cursor_index], a - - call lcd_on - ldnull bc - ret - -st_main_menu_update: - st_def 0x00, main_menu_update, st_main_menu_update - -st_main_menu_delay: - st_def 16, st_null_fn, st_main_menu_update - -st_main_menu_init: - st_def 0x00, main_menu_init, st_main_menu_update diff --git a/src/map.s b/src/map.s index adb8314..e69de29 100644 --- a/src/map.s +++ b/src/map.s @@ -1,571 +0,0 @@ - - ; disables the lcd - ; call before map_load -map_load_start: - ; disable interruts - ; wait for next blank - ; disable lcd - call disableinterrutpts - call next_vblank_wait - call lcd_off - - xor a, a - ld [gpf_attack_ongoing], a - ret - - ; draws the map - ; enables the lcd - ; call after map_load -map_load_end: - call map_draw_all - - ; restore lcd and interrupts - call lcd_on - call vblank_wait - call enableinterrupts - ret - - ; loads a new map - ; inputs: - ; hl: map ptr - ; disables and enables interrupts - ; and lcd - ; TODO: do not touch lcd or interrupts if - ; they were not enabled! -map_load: - ; backup the map header - ld a, l - ld [map_header], a - ld a, h - ld [map_header+1], a - - - push hl - call map_draw_area_title - pop hl - - push hl - call map_tiles_load - - pop hl - push hl - call map_state_load - pop hl - - push hl - call map_actors_load - pop hl - - push hl - call map_tile_banks_load - pop hl - - ret - - ; draws map title to UI - ; inputs: - ; hl: map_ptr -map_draw_area_title: - ld de, map_name - add hl, de ; hl = map_name ptr - - ld b, MAP_NAME_LEN - ld de, shadow_ui+1 -@loop: - ld a, [hl+] - add a, FONT_OFFSET - ld [de], a - inc de - dec b - jr nz, @loop REL - - ; draw player map cursor number - ld a, [player_map_cursor] - add a, FONT_OFFSET+1 - ld [de], a - - call ui_request_redraw - - ret - - ; same as map_get_tile - ; but also divides the b/c input by 16 -map_get_tile_div16: - div16 b - div16 c - - ; gets the tile at a y/x position - ; inputs: - ; b/c: y/x tile position - ; returns: - ; a: flags - ; b: tile index - ; hl: ptr to tile index -map_get_tile: - ; current map - ld hl, map - ld d, 0 - ld e, MAP_W * c_size - - ld a, b - cp a, 0 - jr z, @skip_y REL - - ; calculate y offset -@y_loop: - add hl, de - dec b - jr nz, @y_loop REL -@skip_y: - - ; add x offset - ld e, c - ; add x offset c_size times -.rep i, c_size, 1, add hl, de - ; hl should now be the correct tile - - - ; load values - ld a, [hl+] ; tile index - ld b, a - ld a, [hl] ; tile flags - - dec hl - - ret - - ; loads map tiles - ; inputs: - ; hl: map header -map_tiles_load: - ; first clear - push_all - - ld hl, map - ld bc, map_end - map - ld d, 0 - call memset - - pop_all - - ; load bg ptr - push hl - ld de, map_bg_ptr - add hl, de ; hl = bg_ptr - ld a, [hl+] - ld d, a - ld a, [hl+] - ld h, a - ld l, d - ; hl = bg ptr - - ld de, MAP_BG_TILE_OFFSET ; 0 offset for bg - call tile_map_compressed_load - pop hl - - ; load tile flags ptr - ld de, map_tile_flags_ptr - add hl, de ; hl = bg_ptr - ld a, [hl+] - ld d, a - ld a, [hl+] - ld h, a - ld l, d - ; hl = bg ptr - - ld de, MAP_BG_FLAGS_OFFSET - call tile_map_compressed_load - ret - - ; loads compressed data into the map buffer - ; this can either be tiles or flags - ; based on its offset and the compressed ptr - ; - ; map compression: - ; maps are using a simple RLE - ; 1 byte of length, 1 byte of data - ; the data is terminated with a 0x00 length byte - ; inputs: - ; hl: compressed map data - ; de: target offset (usually 0/1) -tile_map_compressed_load: - push hl - pop bc ; bc = map ptr - - ld hl, map - add hl, de ; + offset - ; bc = destination - ; hl = rle encoded data - -@decompress_loop: - ; load run length - ld a, [bc] - cp a, 0 - ret z ; if run length == 0 exit - ld d, a ; d = copy coutner - - inc bc - ld a, [bc] ; load data - inc bc - -@copy_loop: - ld [hl+], a - inc hl ; hl++ to skip over unneeded byte - - dec d - jr nz, @copy_loop REL - - ; again - jr @decompress_loop REL - - ; loads a map's state - ; inputs: - ; hl: map ptr -map_state_load: - ld de, map_state_ptr - add hl, de ; hl = state ptr ptr - - ld a, [hl+] - ld e, a - ld a, [hl] - ld d, a - ; de = state ptr - ld hl, map_st - ld bc, st_size - call memcpy - - ret - - ; loads a map's actor table - ; starting at p0_actors+1 (0 is reserved for player) - ; inputs: - ; hl: map ptr -map_actors_load: - ; first clear actor table except player - push hl - ld hl, p0_units + act_size - ld bc, act_size * (UNITS_MAX - 1) - ld d, 0 - call memset - pop hl - - ld de, map_actor_table_ptr - add hl, de ; hl = actor table ptr - - ld a, [hl+] - ld e, a - ld a, [hl] - ld d, a - ; de = actor table - - ; load actor count - ld a, [de] - cp a, 0 - jp z, @skip ; do not load if ptr is 0 - inc de ; de = first actor ptr - - ; load starting at slot 1 - ; hl = dst - ld hl, p0_units + act_size - @loop: - ; load next actor - push af - push hl - - ; load ptr - ld a, [de] - ld b, a - inc de - ld a, [de] - inc de - ; save de for now - ; de = next ptr - push de - - ; set src ptr - ld e, b - ld d, a - ; de = str ptr - ; hl = dst already - ld bc, act_size - call memcpy - - - ; copy - - pop de - pop hl - push de - ; move to next actor destination - ld de, act_size - add hl, de - pop de - - pop af - ; i-- - dec a - jr nz, @loop REL - -@skip: - ; hand over control to a unit - ld de, player_unit - call unit_wake_up - ret - - ; loads map tilesets - ; inputs: - ; hl: map ptr -map_tile_banks_load: - ld de, map_tile_bank0_ptr - add hl, de ; hl = bank0 ptr - - ; load ptr - ld a, [hl+] - ld e, a - ld a, [hl+] - ld d, a - push hl - call tiles_load_bank8000 - - pop hl - ld a, [hl+] - ld e, a - ld a, [hl+] - ld d, a - push hl - call tiles_load_bank8800 - - pop hl - ld a, [hl+] - ld e, a - ld a, [hl+] - ld d, a - push hl - call tiles_load_bank8C00 - - pop hl - ld a, [hl+] - ld e, a - ld a, [hl+] - ld d, a - call tiles_load_bank9000 - - ret - - ; draws all cells currently loaded to the screen - ; only call during blank! -map_draw_all: -#define TMP_TILE_COUNT scratch -#define TMP_TILE_OFFSET scratch+1 - - ; de = loop counter - ld de, MAP_SIZE - ld bc, SCRN0 - - ; clear tile count - xor a, a - ld [TMP_TILE_COUNT], a - ; set a tile offset - ld [TMP_TILE_OFFSET], a - - ld hl, map - ; hl = c_tile - - ; load row 1 - call map_draw_rows - - ld de, MAP_SIZE - ld bc, SCRN0+32 - ; clear tile count - xor a, a - ld [TMP_TILE_COUNT], a - ; set a tile offset - ld a, 16 - ld [TMP_TILE_OFFSET], a - ld hl, map - call map_draw_rows - - ret - - ; draws 2 2x2 rows of tiles to shadow_bg - ; map size is equal to 2 rows - ; inputs: - ; a: row offset -map_draw_shadow2: - ld hl, map - ld de, MAP_W * c_size - - ; calculate what row to draw -@offset_loop: - cp a, 0 - jr z, @offset_done REL - ; go down a row - add hl, de - dec a - jr @offset_loop REL -@offset_done: - - push hl ; save map ptr - - ; row 1 - ld de, MAP_W * 2 - ld bc, shadow_bg - xor a, a - ld [TMP_TILE_COUNT], a - ld [TMP_TILE_OFFSET], a - - call map_draw_rows - - ; row 2 - pop hl ; resotre map ptr - - ld de, MAP_W * 2 - ld bc, shadow_bg+32 - xor a, a - ld [TMP_TILE_COUNT], a - ld a, 16 - ld [TMP_TILE_OFFSET], a - - call map_draw_rows - - ret - - - ; requests a full map redraw - ; always draws to SCRN0 - ; redraws one set of shadow tiles to SCRN0 + a * MAP_W - ; inputs: - ; a: row to begin drawing at -map_request_redraw_at: - push af ; save y for after - call map_draw_shadow2 - pop af - - ld hl, SCRN0 - ; a = y position - call map_request_redraw2 - ret - - ; requests a map redraw - ; this will set up redraw_bg - ; redraw_shadow and redraw steps for 4 rows of tiles - ; inputs: - ; hl: bg target ptr - ; a: row offset (a*2*32 + hl) -map_request_redraw2: - ; adjust screen target position by row offset - ld de, 32 - add a, a -@row_offset_calc: - cp a, 0 - jr z, @row_offset_done REL - add hl, de - dec a - jr @row_offset_calc REL -@row_offset_done: - - ; write bg target - ld a, h - ld [redraw_bg], a - ld a, l - ld [redraw_bg+1], a - - ; load tiles to write - ld de, shadow_bg - ld a, d - ld [redraw_shadow], a - ld a, e - ld [redraw_shadow+1], a - - ; steps of 5 * 16 - ld a, BG_WIDTH * BG_SHADOW_HEIGHT / REDRAW_TILES_PER_FRAME - ld [redraw_steps], a - ret - - - ; draws a map rows - ; either top or bottom rows of a 2x2 tile - ; inputs: - ; hl: map ptr - ; bc: SCRN start - ; de: MAP_SIZE - ; [TMP_TILE_COUNT]: 0 - ; [TMP_TILE_OFFSET]: 0 or 16 -map_draw_rows: -@loop: - push de - ; load row 1 - ld a, [hl] ; load tile - ld d, a - ld a, [TMP_TILE_OFFSET] - add a, d ; tile + tile offset - - ld [bc], a ; draw - inc bc ; bc++ - inc a ; move one tile over - ld [bc], a ; draw - inc bc ; bc++ - - ; count tiles drawn - ld a, [TMP_TILE_COUNT] - inc a - cp a, MAP_W ; map size - ; bc + 32 to go to next row if edge is reached - jr nz, @no_advance REL - - push hl - ld hl, 32 - add hl, bc - push hl - pop bc ; bc = next row - - pop hl - - ; clear map tile counter - xor a, a -@no_advance: - ld [TMP_TILE_COUNT], a - - ld de, c_size - add hl, de ; next cell - pop de - - dec de ; de-- - - ; check if de is 0 - ld a, d - or a, e - cp a, 0 - jr nz, @loop REL - - ret -#undefine TMP_TILE_COUNT -#undefine TMP_TILE_OFFSET - - ; empty actor table -map_actor_table_null: -.db 0 - -st_map_null: - st_def 0, map_null_state, st_map_null - - ; null state -map_null_state: - ldnull bc - ret - -; template maps -; maps can be loaded directly - -#include "map_c.s" -#include "map_ce.s" -#include "map_cw.s" - -#include "map_te.s" -#include "map_tc.s" -#include "map_tw.s" - -#include "map_be.s" -#include "map_bc.s" -#include "map_bw.s" - diff --git a/src/mapgen.s b/src/mapgen.s deleted file mode 100644 index 56db1e2..0000000 --- a/src/mapgen.s +++ /dev/null @@ -1,667 +0,0 @@ - - ; initial map setup - ; seeds the floor - ; loads a random map from the map table - ; clears act_save - ; also places initial door locations -mapgen_init: - ; disable act sg - ld a, [mapgen_flags] - or a, MAPGEN_F_NO_ACT_SG - ld [mapgen_flags], a - - call act_save_init - call mapgen_seed - call mapgen_make_doors - call mapgen_select_player_spawn - - ; re-enable act sg - xor a, a - ld [mapgen_flags], a - ret - - ; selects a room pattern table - ; returns: - ; hl: pattern table - ; a: size -mapgen_select_pattern_table: - ; TODO: select different tables based on floor - ld hl, room_patterns_floor1 - ld a, ((room_patterns_floor1_end - room_patterns_floor1) / 2) - 1 - ret - - ; selects a map from the tables based on the current floor - ; and the current cursor seed - ; returns: - ; hl: map pointer -mapgen_select_map: - call mapgen_select_pattern_table - push hl - - ld b, a - call rand - and a, b ; cap rand to table size - - pop hl - - add a, a ; * 2 because its a 2-byte table - - ld b, 0 - ld c, a - add hl, bc - - ; load table ptr - ld a, [hl+] - ld c, a - ld a, [hl] - ld b, a - - ld l, c - ld h, b - - - ret - - - ; generates a new set of seeds - ; and places them into map_seeds -mapgen_seed: - ld hl, map_seeds - ; 2 bytes per seed - ld b, FLOOR_MAP_COUNT*2 - -@loop: - push hl - call rand - pop hl - ld [hl+], a - dec b - jr nz, @loop REL - - - ret - - ; loads the current seed based on player map cursor - ; returns: - ; de: the seed -mapgen_load_seed: - ld a, [player_map_cursor] - add a, a ; * 2 because it is a 2-byte table - ld d, 0 - ld e, a - ld hl, map_seeds - add hl, de - ; hl = seeds+offset - ld a, [hl+] - ld d, a - ld a, [hl] - ld e, a ; de = seed - ret - - ; places a rectangular room - ; into the currently loaded map - ; 1) selects a random map to draw - ; 2) places doors - ; 3) places actors - ; 4) reloads actor sg - ; 5) draws map - ; preserves: - ; srand -mapgen: - call map_load_start - - ld a, [mapgen_flags] - and a, MAPGEN_F_NO_ACT_SG - call z, act_sg_store - - ; load seed - ; and back it up - ld a, [srand] - ld b, a - ld a, [srand+1] - ld c, a - push bc - - - call mapgen_load_seed - - ; load seed param - ld a, e - ld [srand+1], a - ld a, d - ld [srand], a - - call mapgen_select_map - call map_load - ld hl, map - - call mapgen_draw_doors - - call mapgen_place_actors - - - ; restore seed - pop bc - ld a, c - ld [srand+1], a - ld b, a - ld [srand], a - - ld a, [mapgen_flags] - and a, MAPGEN_F_NO_ACT_SG - call z, act_sg_restore - - call map_load_end - - ret - - ; generates door locations for each map - ; starts at location 3/3 and moves one door at a time - ; avoids placing doors at the edge. - ; stops after plaving at least N doors -mapgen_make_doors: - ld b, 0 - ld c, 0 ; bc = y/x position - ; start current ptr at 1/1 as well - ld hl, map_doors_location - - ; set map cursor - ld a, 0 - ld [player_map_cursor], a - - ; select how many doors we want - push bc - push hl - call rand - add a, 24 ; at least N doors - and a, (FLOOR_MAP_COUNT * 2) - 1 - - pop hl - pop bc - -@loop: - push af - push hl - push bc - - ; select a random location - - call rand - and a, 3 - - pop bc - pop hl - - call make_door - call make_opp_door - - pop af - dec a - jr nz, @loop REL - ret - - ; creates the counterpart to - ; a recently created door - ; inputs: - ; a: 1 = UP, 2 = DOWN, 3 = LEFT, 0 = RIGHT - ; [hl]: current door ptr - ; returns: - ; [hl]: ord new door -make_opp_door: - cp a, 0 - jp z, @right - cp a, 1 - jp z, @up - cp a, 2 - jp z, @down - cp a, 3 - jp z, @left - -@right: - ld a, [hl] - or a, DIRLEFT - ld [hl], a - ret -@up: - ld a, [hl] - or a, DIRDOWN - ld [hl], a - ret -@down: - ld a, [hl] - or a, DIRUP - ld [hl], a - ret -@left: - ld a, [hl] - or a, DIRRIGHT - ld [hl], a - ret - - ; creates a single door - ; based on the random selection - ; inputs: - ; a: 1 = UP, 2 = DOWN, 3 = LEFT, 0 = RIGHT - ; bc: current coordinate - ; hl: current ptr - ; returns: - ; a: door direction -> door placed - ; [hl]: ors new door bit - ; bc: if door placed moves coordinates - ; hl: if door placed moves ptr -make_door: - push af - cp a, 0 - jp z, @right - - cp a, 1 - jp z, @up - - cp a, 2 - jp z, @down - - cp a, 3 - jp z, @left - -@try_again: - pop af - inc a - and a, 3 - jp make_door -@left: - - ; can we even place it? - ld a, c - cp a, 0 - jp z, @try_again - - ; is this door already set? - ; ld a, [hl] - ; and a, DIRLEFT - ; jp nz, @try_again - - ; we can! - ld a, [hl] - or a, DIRLEFT - ld [hl], a - - dec c ; x-- - dec hl ; hl-- - - pop af - ret -@right: - ld a, c - cp a, FLOOR_W-1 - jp z, @try_again - - ; ld a, [hl] - ; and a, DIRRIGHT - ; jp nz, @try_again - - ld a, [hl] - or a, DIRRIGHT - ld [hl], a - - inc c ; x++ - inc hl ; hl++ - - pop af - ret -@up: - - ld a, b - cp a, 0 - jp z, @try_again - - ; ld a, [hl] - ; and a, DIRUP - ; jp nz, @try_again - - ld a, [hl] - or a, DIRUP - ld [hl], a - - dec b ; y-- - - ; move hl up one row -.rep i, FLOOR_W, 1, dec hl - - pop af - ret -@down: - - ld a, b - cp a, FLOOR_H-1 - jp z, @try_again - - ; ld a, [hl] - ; and a, DIRDOWN - ; jp nz, @try_again - - ld a, [hl] - or a, DIRDOWN - ld [hl], a - - inc b ; y++ - - ; move hl one row down -.rep i, FLOOR_W, 1, inc hl - - pop af - ret - - ; loads the current player map cursor - ; and draws the required doors - ; inputs: - ; hl: [map] - ; preserves: hl -mapgen_draw_doors: - push hl - ld hl, map_doors_location - ld a, [player_map_cursor] - ld e, a - ld d, 0 - add hl, de ; hl = door entry - - ld a, [hl] ; a = door pattern - pop hl ; hl = map - ld b, a ; b = door pattern backup - - and a, DIRUP - jr z, @no_door_up REL - push hl - ld de, 7*c_size ; move over 7 tiles - add hl, de - ld a, DOOR_TILE_TOP - ld [hl+], a - ld a, CF_DOOR | CF_COLLISION | CF_EXIT - ld [hl], a - pop hl -@no_door_up: - - ld a, b - and a, DIRDOWN - jr z, @no_door_down REL - push hl - ld de, 7*c_size + MAP_W * (MAP_H - 1) * c_size - add hl, de - ld a, DOOR_TILE_BOTTOM - ld [hl+], a - ld a, CF_DOOR | CF_COLLISION | CF_EXIT - ld [hl], a - pop hl -@no_door_down: - - ld a, b - and a, DIRLEFT - jr z, @no_door_left REL - push hl - ld de, 7 * MAP_W * c_size - add hl, de - ld a, DOOR_TILE_LEFT - ld [hl+], a - ld a, CF_DOOR | CF_COLLISION | CF_EXIT - ld [hl], a - pop hl -@no_door_left: - - ld a, b - and a, DIRRIGHT - jr z, @no_door_right REL - push hl - ld de, 7 * MAP_W * c_size + (MAP_W - 1) * c_size - add hl, de - ld a, DOOR_TILE_RIGHT - ld [hl+], a - ld a, CF_DOOR | CF_COLLISION | CF_EXIT - ld [hl], a - pop hl -@no_door_right: - - ; check if player is on top of a door - ; if so remove it and mark as an exit instead - ld de, player_unit - call unit_get_pos - call map_get_tile - - ld a, b - cp a, DOOR_TILE_LEFT - jr z, @door_tile REL - cp a, DOOR_TILE_RIGHT - jr z, @door_tile REL - cp a, DOOR_TILE_TOP - jr z, @door_tile REL - cp a, DOOR_TILE_BOTTOM - jr z, @door_tile REL - - ret - -@door_tile: - xor a, a - ld [hl+], a ; clear tile - - ld a, [hl] ; clear collision and door flags - and a, CF_EXIT - ld [hl], a - ret - - ; places actors from a valid actor table - ; from the current floor value. This will overwrite the - ; header loaded by map_load. Preserves player entry. - ; the length of the actor table must be maskable - ; inputs: - ; a loaded map -mapgen_place_actors: - ; clear everything past player - ld hl, p0_units + act_size - ld bc, (UNITS_MAX - 1) * act_size - ld d, 0 - call memset - - - ; load floor actor tables - ld hl, floor_actor_tables - ld d, 0 - ld a, [floor] - ld e, a - add hl, de - ; hl = floor actor table ptr - - ; load actor table ptr - ld a, [hl+] - ld b, a - ld a, [hl+] - ; hl = map header actor table ptr - ld h, a - ld l, b - - ld a, [hl+] - ld c, a - cp a, 0 - ret z ; if length is 0 we bail - ; c = actor table length - ; hl = actor entries - - ; load actor table starting after plater - ld de, p0_units + act_size - ; de = actor table - - ; b = loop counter - ld b, UNITS_MAX - 1 - push hl - call rand - and a, UNITS_SPAWN_MASK - add a, UNITS_SPAWN_MIN - ld b, a - ; b = units to spawn, at least 4 but might be more - pop hl -@spawn_another: - push bc - push de - push hl - call rand - pop hl - pop de - pop bc - - ; mask the rand result - and a, c - - ; now we know which actor to pick - add a, a ; * 2 because the table is a ptr table - - push hl - push bc - push de - - ld d, 0 - ld e, a - add hl, de - ; hl = actor picked ptr - ld a, [hl+] - ld e, a - ld a, [hl+] - ld d, a - ; de = actor picked = src - - - pop hl ; hl = actor table dst - push hl ; re-push for pop de later - ld bc, act_size - call memcpy - - pop de - pop bc - pop hl - - ; move to next actor table entry - push hl - call mapgen_unit_randomize_position - ld hl, act_size - add hl, de - push hl - pop de ; de = next entry - pop hl - - dec b - jp nz, @spawn_another - - ret - - ; randomizes (or reloads from sram) - ; an actors position - ; inputs: - ; de: actor table entry - ; preserves all registers -mapgen_unit_randomize_position: - push_all - ld hl, act_pos_y - add hl, de ; hl = y pos -@retry: - - ; select position - push hl - call rand - and a, MAP_H - 1 - ld b, a - call rand - and a, MAP_W - 1 - ld c, a - ; bc = y/x - - ; check if tile is OK to spawn on - push bc - call map_get_tile - cp a, 0x00 ; check flags - pop bc - pop hl - ; if collision flag is set try again - jr nz, @retry REL - - push bc - push hl - ; check if this tile already had an actor - call unit_find_at - ld a, h - or a, l - pop hl - pop bc - cp a, 0 - jr nz, @retry REL - - ; write y and x positions - ld a, b - mul16 a - ld [hl+], a - - ld a, c - mul16 a - ld [hl], a - - pop_all - ret - - ; selects player spawn room - ; selects a random room that has an exit and - ; sets the map cursor - ; then places the player on a tile without flags - ; calls mapgen after player is placed to make the map -mapgen_select_player_spawn: - call rand - and a, FLOOR_MAP_COUNT-1 - ld hl, map_doors_location - ld d, 0 - ld e, a - add hl, de - ; check if the selected room has doors (is not 0) - - ld a, [hl] - cp a, 0 - jr z, mapgen_select_player_spawn REL - - ; write selected room - ld a, e - ld [player_map_cursor], a - - call mapgen - -@try_placement_again: - call rand - and a, MAP_H-1 - ld b, a ; y pos - call rand - and a, MAP_W-1 - ld c, a ; x pos - - ; get tile data - push bc - call map_get_tile - cp a, 0x00 ; we want no flags here - pop bc - jr nz, @try_placement_again REL - - push bc - ; test if a unit is here - call unit_find_at - ld a, h - or a, l - pop bc - - jp nz, @try_placement_again - ; otherwise write position - ld hl, player_unit - ld de, act_pos_y - add hl, de - ld a, b - mul16 a - ld [hl+], a ; write y - - ld a, c - mul16 a - ld [hl], a ; write x - - ld de, player_unit - call unit_scroll_center - - ret diff --git a/src/mem.s b/src/mem.s index 7ffb0e1..4d803d0 100644 --- a/src/mem.s +++ b/src/mem.s @@ -21,28 +21,14 @@ mem_init: ; set up mbc1 call mbc1_init - ; load initial game state - ld de, st_main_menu_init - ld hl, game_mode - ld bc, st_size - call memcpy - - ; copy delay to active template to wram - ld de, st_unit_delay_to_active_template - ld hl, st_unit_delay_to_active - ld bc, st_size - call memcpy - - call objanim_init - - ; set up default game speed - ld a, GAME_SPEED_DEFAULT - ld [game_speed], a - ; load a demo ; ld hl, demo_inputs1 ; call load_demo_ptr + ; set initial game state ptr + ld hl, update_game + call game_set_state + ret ; copies memory from one location to another diff --git a/src/objanim.s b/src/objanim.s deleted file mode 100644 index 459a875..0000000 --- a/src/objanim.s +++ /dev/null @@ -1,353 +0,0 @@ -#define DOOR_SPRITE_TILE 0x80 - - ; sets up object animation state -objanim_init: - ld de, st_null - ld hl, objanim - ld bc, st_size - call memcpy - - ret - - ; sets objanim to display a door - ; opening animation. - ; decides which animation to play based on the tile inex - ; supplied. - ; inputs: - ; a: tile flags - ; b: tile index - ; de: actor -objanim_door_open: - push de - push bc - - ; set up the correct state based on tile index - ld a, b ; a = tile index - cp a, DOOR_TILE_TOP - jr nz, @not_top REL - - ld de, st_objanim_door_open_up - ld hl, objanim - ld bc, st_size - call memcpy - jp @done -@not_top: - - cp a, DOOR_TILE_LEFT - jr nz, @not_left REL - - ld de, st_objanim_door_open_left - ld hl, objanim - ld bc, st_size - call memcpy - jp @done -@not_left: - - cp a, DOOR_TILE_RIGHT - jr nz, @not_right REL - ld de, st_objanim_door_open_right - ld hl, objanim - ld bc, st_size - call memcpy - jp @done -@not_right: - - ; default to down - ld de, st_objanim_door_open_down - ld hl, objanim - ld bc, st_size - call memcpy - -@done: - - pop bc - pop de - - ld hl, act_rt_collision_pos_y - add hl, de ; hl = col pos y - - ; clear flags - ld de, objanim+obja_flags - xor a, a - ld [de], a - inc de ; de = y pos - - ld a, [hl+] - ld [de], a - inc de ; de = x pos - - ld a, [hl] - ld [de], a - inc de ; de = dat - - ; dat = tile index - ld a, b - ld [de], a - inc de ; de = timer - - ; clear frame counter - xor a, a - ld [de], a - - ; set gameplay flag to pause object updates - ld a, [gameplay_flags] - or a, GPF_PAUSE_UPDATE - ld [gameplay_flags], a - - ret - - ; down animation -objanim_door_open_down_fn: - ld a, [objanim+obja_timer] ; read timer before calling handler - push af - call objanim_door_open_generic_fn - - pop af - push bc ; save next state - ; hl = oam ptr - inc hl ; skip obj1 y - - ; adjust x position based on timer - ; offset position by counter - sra a - ld b, a - ld a, [hl] - sub a, b - ; wirte adjusted obj1 x - ld [hl+], a ; hl = obj1 tile - - inc hl ; skip obj1 tile - inc hl ; skip obj1 flags - inc hl ; skip obj2 y - - ; hl = obj2 x - ld a, [hl] - add a, b - ; write adjusted obj2 x - ld [hl+], a - - pop bc ; restore next state - ret - -objanim_door_open_up_fn: - ld a, [objanim+obja_timer] ; read timer before calling handler - push af - call objanim_door_open_generic_fn - - pop af - push bc ; save next state - ; hl = oam ptr - inc hl ; skip obj1 y - - ; adjust x position based on timer - ; offset position by counter - sra a - ld b, a - ld a, [hl] - sub a, b - ; wirte adjusted obj1 x - ld [hl+], a ; hl = obj1 tile - - inc hl ; skip obj1 tile - ld a, OAM_FYFLIP - ld [hl+], a ; write obj1 flag and ++ - inc hl ; skip obj2 y - - ; hl = obj2 x - ld a, [hl] - add a, b - ; write adjusted obj2 x - ld [hl+], a - - inc hl ; skip obj2 tile - ld a, OAM_FYFLIP ; write obj2 flag - ld [hl], a - - pop bc ; restore next state - - ret - -objanim_door_open_left_fn: - ld a, [objanim+obja_timer] ; read timer before calling handler - push af - call objanim_door_open_generic_fn - - pop af - push bc ; save next state - ; hl = oam ptr - - ; adjust x position based on timer - ; offset position by counter - ld b, a - ld a, [hl] - sub a, b - ; wirte adjusted obj1 y - ld [hl+], a ; hl = obj1 tile - inc hl ; skip obj1 x - - ; adjust tile by 4 (next tile) and ++ - ld a, DOOR_SPRITE_TILE + 4 - ld [hl+], a - - xor a, a - ld [hl+], a ; write obj1 flag and ++ - - ; hl = obj2 y - ld a, [hl] - sub a, b - ; write adjusted obj2 y - ld [hl+], a - inc hl ; skip obj2 x - - ; adjust tile by 4 (next tile) and ++ - ld a, DOOR_SPRITE_TILE + 6 - ld [hl+], a - - xor a, a - ld [hl], a - - pop bc ; restore next state - ret - -objanim_door_open_right_fn: - ld a, [objanim+obja_timer] ; read timer before calling handler - push af - call objanim_door_open_generic_fn - - pop af - push bc ; save next state - ; hl = oam ptr - - ; adjust x position based on timer - ; offset position by counter - ld b, a - ld a, [hl] - sub a, b - ; wirte adjusted obj1 y - ld [hl+], a ; hl = obj1 tile - inc hl ; skip obj1 x - - ; adjust tile by 4 (next tile) and ++ - ld a, DOOR_SPRITE_TILE + 6 - ld [hl+], a - - ld a, OAM_FXFLIP - ld [hl+], a ; write obj1 flag and ++ - - ; hl = obj2 y - ld a, [hl] - sub a, b - ; write adjusted obj2 y - ld [hl+], a - inc hl ; skip obj2 x - - ; adjust tile by 4 (next tile) and ++ - ld a, DOOR_SPRITE_TILE + 4 - ld [hl+], a - - ld a, OAM_FXFLIP - ld [hl], a - - pop bc ; restore next state - ret - - ; state function for door opening animation - ; is called by more specific functions that take this base setup - ; and set the right tiles and animations after - ; inputs: - ; de: objanim - ; returns: - ; hl: first object used - ; the objects are guaranteed to be consecutive - ; and 2 objects will have been reserved - ; bc: next state -objanim_door_open_generic_fn: -#define TMP_Y, scratch -#define TMP_X, scratch+1 - - call load_unit_obj - push hl - ld de, objanim+st_size - call load_scroll - - ; hl = oam ptr - ; de = anim flags - - ; set first object - inc de ; skip flags - ld a, [de] ; a = y position - inc de ; de = x postion - tile_to_scrn OBJ_OFF_Y, b - ld [hl+], a - ld [TMP_Y], a - - ld a, [de] ; a = x position - tile_to_scrn OBJ_OFF_X, c - ld [TMP_X], a - ld [hl+], a - - - ; door tile - ld a, DOOR_SPRITE_TILE - ld [hl+], a - - xor a, a - ld [hl+], a ; no flags - - - ; set up second object - call load_unit_obj - - ; set y pos - ld a, [TMP_Y] - ld [hl+], a - - ; set x pos - ld a, [TMP_X] - add a, 8 ; move over a tile - ld [hl+], a - - ; tile - ld a, DOOR_SPRITE_TILE+2 - ld [hl+], a - - ; flags - xor a, a - ld [hl], a - - pop hl ; restore object ptr used == return value - ; check if we are done - ld a, [objanim+obja_timer] - inc a - ld [objanim+obja_timer], a ; frame counter++ - cp a, 0x10 ; end frame? - jr z, @timer_done REL - - ldnull bc - ret -@timer_done: - call door_open_done -#undefine TMP_X -#undefine TMP_Y - - ; completes the door opening animation -door_open_done: - ; unset pause object update - ld a, [gameplay_flags] - and a, ~GPF_PAUSE_UPDATE & 0xFF - ld [gameplay_flags], a - - ld bc, st_null - ret - -st_objanim_door_open_down: - st_def 0x00, objanim_door_open_down_fn, st_objanim_door_open_down - -st_objanim_door_open_up: - st_def 0x00, objanim_door_open_up_fn, st_objanim_door_open_up - -st_objanim_door_open_left: - st_def 0x00, objanim_door_open_left_fn, st_objanim_door_open_left - -st_objanim_door_open_right: - st_def 0x00, objanim_door_open_right_fn, st_objanim_door_open_right diff --git a/src/player.s b/src/player.s index 314363f..e69de29 100644 --- a/src/player.s +++ b/src/player.s @@ -1,342 +0,0 @@ -.def int CURSOR_TILE = 0x04 - - ; loads the default player unit - ; and hands over control -unit_load_default_player: - ld de, unit_player - ld hl, p0_units - ld bc, act_size - call memcpy - - ret - -unit_player_init: - ldnull bc - ret - - ; inputs - ; de: actor -unit_player_update: - ; check if player flag is set - ; if so return early - ldnull bc - ld a, [gameplay_flags] - and a, GPF_PLAYER_TURN_TAKEN - ret nz - - ; check if an attack is ongoing - ld a, [gpf_attack_ongoing] - cp a, 0 - ret nz - - ; check if the player is currently - ; on a convered tile or not - push de - - ; first read the current tile - call unit_get_pos - call map_get_tile_div16 - push af ; store for later use - - ; a = tile flags - and a, CF_COVERED - ld b, a - ld a, [player_rt_special_flags] - ld c, a ; remove door might needs this in c - and a, (~CF_COVERED) & 0xFF - or a, b - ld [player_rt_special_flags], a - pop af ; get back a for next check - pop de - - ; hl should still be tile ptr here - - ; check for exit flags - push de - call unit_check_exit_hit - pop de - - push de - call unit_scroll_center - pop de - - push de - call unit_handle_inputs - pop de - - push de - push bc - ; test last collision flags - push de - ld hl, act_rt_collision_cf - add hl, de - ld a, [hl] - pop de - and a, CF_DOOR - call nz, unit_player_remove_door - pop bc - pop de - - ret - - ; removes the door tile the player is currently - ; standing on - ; inputs: - ; de: actor -unit_player_remove_door: - ; get tile of last collision - push de - ld hl, act_rt_collision_pos_y - add hl, de - ld a, [hl+] ; load y - ld b, a - ld a, [hl+] ; load x - ld c, a - xor a, a - ld [hl], a ; clear cf - call map_get_tile_div16 - pop de - - ; schedule animation - push_all - call objanim_door_open - call play_door_open_noise - pop_all - - ; remove door tile, door flag - ; and redraw map - ld a, 0x00 ; floor tile - ; clear map - ld [hl+], a - - ; clear all flags but exit - ld a, [hl] - and a, CF_EXIT - ld [hl], a - - ld hl, act_rt_collision_pos_y - add hl, de - ld a, [hl] ; load y offset - div16 a - - ; if y is at bottom of map go back up a tile... - cp a, MAP_H-1 ; - jr nz, @not_end_of_map REL - dec a -@not_end_of_map: - call map_request_redraw_at - - ret - - ; checks the current tile - ; and checks for exit flags - ; if an exit flag is set, checks if - ; the player is in position y == 0 - ; y == MAP_H-1, x == 0 or x == MAP_W-1 - ; to determine where to take the player - ; the direction moving the player oob must be pressed to move the player - ; inputs: - ; de: actor -unit_check_exit_hit: - push de - ld hl, act_pos_y - add hl, de ; hl = actor_y - - ld a, [hl+] - ld b, a ; b = y pos - ld a, [hl] ; hl = x pos - ld c, a ; c = x pos - - call map_get_tile_div16 - ; a = flags - ld b, a ; b = flags for later use - and a, CF_EXIT - pop de - ret z ; if not we bail - - ; now it's time to look up - ; the exit's position - ; de = actor - ld hl, act_pos_y - add hl, de - ; hl = act_pos_y - - ld a, [hl] - div16 a - cp a, 0 ; top - jp z, unit_exit_top - - ld a, [hl+] - div16 a - cp a, MAP_H-1 - jp z, unit_exit_bottom - - ld a, [hl] ; hl = x pos - div16 a - cp a, 0 - jp z, unit_exit_left - - ld a, [hl] - div16 a - cp a, MAP_W-1 - jp z, unit_exit_right - - - ; performs the map load -unit_map_load: - ; fade out - call video_fade_out - - - ; generate new map - call mapgen - - ; hl = player - ld hl, player_unit - ld de, act_pos_y - add hl, de ; hl = y pos - - - ; scroll to player's position - ld de, player_unit - call unit_scroll_center - call next_vblank_wait - call scroll_write - - ; fade back in - ld a, [shadow_bpg] - call video_fade_in - - ret - - ; performs a top exit - ; adjusts player cursor - ; and units position - ; checks if input is held, -> calls unit_load_map - ; inputs: - ; de: unit - ; preserves: - ; hl, de -unit_exit_top: - ld b, BTNUP - input_held - ret z - - ld hl, act_pos_y - add hl, de - - ; move player down - ld a, MAP_H-2 - mul16 a - ld [hl], a - - ld a, [player_map_cursor] - ; cursor needs to go 1 row up - sub a, FLOOR_W - ld [player_map_cursor], a - - call unit_map_load - ret - - ; performs bottom exit - ; same as exit top - ; inputs: - ; de; unit - ; preserves: - ; hl, de -unit_exit_bottom: - ld b, BTNDOWN - input_held - ret z - - ld hl, act_pos_y - add hl, de - - ; move player up - ld a, 1 - mul16 a - ld [hl], a - - ld a, [player_map_cursor] - ; go down a row - add a, FLOOR_W - ld [player_map_cursor], a - - call unit_map_load - ret - - ; performs a right exit - ; same as exit top - ; inputs: - ; de: unit -unit_exit_right: - ld b, BTNRIGHT - input_held - ret z - - ld hl, act_pos_x - add hl, de - - ; move player left - ld a, 1 - mul16 a - ld [hl], a - - ld a, [player_map_cursor] - ; go right one row - inc a - ld [player_map_cursor], a - - call unit_map_load - ret - - ; performs a left exit - ; same as exit top - ; inputs: - ; de: unit -unit_exit_left: - ld b, BTNLEFT - input_held - ret z - - ld hl, act_pos_x - add hl, de - - ; move player right - ld a, MAP_W-2 - mul16 a - ld [hl], a - - ld a, [player_map_cursor] - ; go left one row - dec a - ld [player_map_cursor], a - - call unit_map_load - ret - - - ; player attack state - ; inputs: - ; de: actor - ; returns: - ; bc: next state -unit_player_attack: - ldnull bc - ret - -#define player_draw unit_draw - -unit_player: - st_def 0x00, unit_player_init, st_unit_idle - act_def ACT_T_PLAYER, 0, 2, 2, 0 - act_stat_def1 1, 3, 1, 1 - act_stat_def2 1, 1, 90, 1 - act_st_def st_unit_player_update, st_unit_idle - act_def_meta player_draw, player_anim_table - -st_unit_player_update: - st_def 0x00, unit_player_update, st_unit_player_update - -st_unit_player_attack: - st_def 0x00, unit_player_attack, st_unit_player_attack diff --git a/src/rand.s b/src/rand.s index 1fb95f1..8414b11 100644 --- a/src/rand.s +++ b/src/rand.s @@ -74,21 +74,3 @@ rand: ld a, [srand] ret - - ; rolls a d16 - ; returns a number between - ; 0 and 15 - ; returns: - ; [d16]: last roll - ; a: d16 roll - ; preserves registers other than af -roll_d16: - push hl - - call rand - and a, 0x0F - ld [d16], a - - pop hl - ret - diff --git a/src/roompatterns.s b/src/roompatterns.s deleted file mode 100644 index a259df0..0000000 --- a/src/roompatterns.s +++ /dev/null @@ -1,20 +0,0 @@ -#define DOOR_TILE_TOP 0x2E -#define DOOR_TILE_BOTTOM 0x0E -#define DOOR_TILE_LEFT 0x0C -#define DOOR_TILE_RIGHT 0x2C - - ; table of possible maps - ; must be divisible by 2 in size - -room_patterns_floor1: - dw map_c_header - dw map_ce_header - dw map_cw_header - dw map_be_header - dw map_bc_header - dw map_bw_header - dw map_te_header - dw map_tc_header -room_patterns_floor1_end: - - diff --git a/src/select_menu.s b/src/select_menu.s deleted file mode 100644 index 06ccfc2..0000000 --- a/src/select_menu.s +++ /dev/null @@ -1,145 +0,0 @@ -#define SELECT_MENU_DELAY_FRAMES 10 - - ; a select menu is any menu that allows the player to select - ; a range of values - ; writes current string to status line and requests an update - ; if the direction keys are pressed - ; inputs: - ; hl: string ptr table - ; b: table length - ; a: current slection value - ; returns: - ; a: selection value - ; b: button pressed -select_menu_update: - push af - - ; check if delay timer is active - ld a, [select_menu_delay] - cp a, 0 - jr z, @not_delay REL - dec a - ld [select_menu_delay], a - jp @no_select -@not_delay: - - ; save table length - pop af - push af - push bc - - cp a, 0 - jr z, @notleft REL - - ld b, BTNLEFT - input_held - jr z, @notleft REL - ld a, SELECT_MENU_DELAY_FRAMES - ld [select_menu_delay], a - pop bc - pop af - dec a - call select_menu_draw_status - ld b, BTNLEFT - ret -@notleft: - - pop bc ; get back table length - ld c, b ; store table length in c - pop af - push af - dec b ; length - 1 - cp a, b - jr z, @notright REL ; is a > b - - ld b, BTNRIGHT - input_held - jr z, @notright REL - ld a, SELECT_MENU_DELAY_FRAMES - ld [select_menu_delay], a - pop af - inc a - ld b, c ; table length = c - call select_menu_draw_status - ld b, BTNRIGHT - ret -@notright: - -@no_select: - - ; A button to select action - ld b, BTNA - input_just - jr z, @nota REL - pop af - ld b, BTNA - ret -@nota: - - ; TODO: SELECT to assign to B - pop af ; pop original input for a - ld b, 0 ; clear b return value - ret - - ; draws a status text for the current selection - ; inputs: - ; hl: string ptr table - ; a: selection - ; b: string table length - ; preserves: - ; af -select_menu_draw_status: - push af - push bc - - push hl - push af - call ui_clear_status_line - - pop af - push af - ; check if left arrow needs to be drawn (a != 0) - cp a, 0 - jr z, @no_left_arrow REL - ; write cursor tile - ld de, UI_STATUS_LINE - ld a, MENU_CURSOR_TILE_REVERSE - ld [de], a -@no_left_arrow: - - pop af - pop hl - - add a, a ; * 2 for table offset - ld d, 0 - ld e, a - add hl, de ; hl = string ptr - - ld a, [hl+] - ld d, a - ld a, [hl] - ; hl = the string - ld h, a - ld l, d - - ld de, UI_STATUS_LINE+1 - call puts - push de - call ui_request_redraw - pop de - ; de = tile after string - - pop bc - pop af - - push af - ; check if right arrow needs to be drawn (a != b-1) - dec b - cp a, b - jr z, @no_right_arrow REL - ; write cursor tile - ld a, MENU_CURSOR_TILE - ld [de], a -@no_right_arrow: - pop af - ret diff --git a/src/shoot.s b/src/shoot.s deleted file mode 100644 index fd35b00..0000000 --- a/src/shoot.s +++ /dev/null @@ -1,21 +0,0 @@ -; shoot (ranged attack) actions -; cast a ray in direction -; hit first actor found -; and attacking actor plays a small shoot animation - -unit_action_shoot_pick_direction_init: - ld hl, STR_ATTACK_DIRECTION - ld de, UI_STATUS_LINE - call puts - call ui_request_redraw - ldnull bc - ret - -unit_action_shoot_pick_direction: - ld bc, st_unit_delay_to_active_template - jp unit_action_pick_direction - -st_action_shoot_init: - st_def 0x00, unit_action_shoot_pick_direction_init, st_action_shoot_pick_direction -st_action_shoot_pick_direction: - st_def 0x00, unit_action_shoot_pick_direction, st_action_shoot_pick_direction diff --git a/src/state.s b/src/state.s deleted file mode 100644 index 98a687c..0000000 --- a/src/state.s +++ /dev/null @@ -1,84 +0,0 @@ - ; updates the state of an actor - ; inputs: - ; de: actor -st_update: - push de - - inc de - ld a, [de] - ld l, a - inc de - ld a, [de] - ld h, a - ; hl = function ptr - - dec de - dec de ; de = timer - ld a, [de] ; a = timer - cp a, 0 - ; if timer is 0 update state - jr z, @update REL - - ; otherwise timer-- - dec a - ld [de], a - - pop de - ret -@update: - ; de = actor ptr - pop de - push de - call_hl - - pop hl ; hl = original actor ptr = dst - - ; if routine returns - ; a new ptr in bc - ; set state to this pointer - ; otherwise use state's next - ld a, b - or a, c - cp a, 0 - jr z, @set_next_state_default REL - - ; hl = actor ptr - - ; set returned state - push bc - pop de ; de = src - - ld bc, st_size - call memcpy - ret -@set_next_state_default: - - ; set default state - ; hl = actor ptr - push hl - - inc hl - inc hl - inc hl - ; hl = st_next - ld a, [hl+] - ld e, a - ld a, [hl] - ld d, a ; de = next state ptr - - pop hl - - ld bc, st_size - call memcpy - ret - - ; null state - ; do nothing and return -st_null_fn: - ldnull bc - ret - -st_null: - st_def 0xFF, st_null_fn, st_null - - diff --git a/src/stats.s b/src/stats.s deleted file mode 100644 index 4909cf8..0000000 --- a/src/stats.s +++ /dev/null @@ -1,202 +0,0 @@ - ; main stats: - ; str: increases heavy weapon damage - ; increases heavy weapon speed - ; int: increases mana and spell damage - ; increases spell speed - ; dex: increases ranged/short weapon damage - ; increases ranged/short weapon speed - ; decreses time between moves and attack speed - ; vit: increases health - ; increases hit chance - - ; calculated stats based on gear/other stats: - ; hit: increases chance to hit - ; resistances: decrease how long a dot lasts and how much damage - ; is taken. - ; fire, lightning, poison resistance and magic resitance - ; health - ; mana - ; ac: armor value - - ; calculates the real strength stat - ; inputs: - ; de: actor - ; returns: - ; a: str value -stat_calc_str: - ld hl, act_str - add hl, de - ld a, [hl] - ret - - ; calculates hp - ; inputs: - ; de: actor - ; returns: - ; a: hp -stat_calc_hp: - ld hl, act_hp - add hl, de - ld a, [hl] - ret - - ; calculates mp - ; inputs: - ; de: actor - ; returns: - ; a: mp -stat_calc_mp: - ld hl, act_mp - add hl, de - ld a, [hl] - ret - - ; calculates weapon damage - ; inputs: - ; de actor - ; returns: - ; a: raw weapon damage -stat_calc_weapon_damage: - ; TODO: 1 is fist stat... - ld a, 1 - ret - - ; calculates ac - ; inputs: - ; de: actor - ; returns: - ; a: ac -stat_calc_ac: - ld hl, act_ac - add hl, de - ld a, [hl] - ret - - ; calculates max hp based - ; inputs: - ; deL actor - ; returns: - ; a: max hp -stat_calc_hp_max: - ld hl, act_vit - add hl, de - ld a, [hl] - add a, 2 ; base health - ret - - ; calculates mp max - ; inputs: - ; de: actor - ; returns: - ; a: mp max -stat_calc_mp_max: - ; TODO calculate properly - ld a, 255 - ret - - ; calculates physical damage of - ; one actor agains another - ; formula: - ; physical damage = (weapon damage a1 + strength a1 / 8) - (ac a2 / 2) - ; inputs: - ; de: actor1 - ; bc: actor2 - ; returns: - ; sub damage from actor2 - ; a: damage -stat_calc_physical_damage_vs: - ; actor 1 - push bc - - call stat_calc_weapon_damage - ; a = damage - ld b, a ; b = weapon damage - - ; weapon damage + strenth / 8 - call stat_calc_str - sra a ; / 2 - sra a ; / 4 - sra a ; / 8 - add a, b - ld b, a ; b = real damage - - ; actor 2 - - pop de ; de = actor2 now - ; damage - ac/2 - call stat_calc_ac - sra a - sub_ba - jp c, @no_damage - - ; b = damage to apply - - ; apply damage - - ld hl, act_hp - add hl, de - ; hl = act2 hp - ld a, [hl] - sub a, b - jp c, @dead - - ; write new hp - ld [hl], a - - ; a = damage dealt - ld a, b - - ret -@no_damage: - xor a, a - ret -@dead: - xor a, a - ld [hl], a ; write 0 hp - ld a, b ; a = damage dealt - ret - - ; heals the actor by N - ; does not overheal - ; inputs: - ; de: actor - ; a: amount - ; returns: - ; a: actual heal amount -stat_heal_by: - push af ; push original a value - ld b, a ; b = amount to heal by - ld hl, act_hp - add hl, de - ld a, [hl] ; a = current hp - add a, b ; a = new hp - - push hl - push af - call stat_calc_hp_max - ld b, a ; b = max hp - pop af - pop hl - - cp a, b - ; a > b? (max > new value) - jr nc, @overheal REL - ld [hl], a ; write new value - pop af ; return input value - ret -@overheal: - ; set to max - ld a, b - ld [hl], a ; write max into hp - pop af - xor a, a ; no healing was done - ret - - ; calculates the real speed state - ; inputs: - ; de: actor - ; returns: - ; a: speed stat -stat_calc_speed: - ld a, [game_speed] - ret diff --git a/src/sys.s b/src/sys.s index 3d1972d..3c6e58f 100644 --- a/src/sys.s +++ b/src/sys.s @@ -70,12 +70,8 @@ load_scroll: ; increments unit sprite ; returns; ; hl: current unit sprite -load_unit_obj: - ld a, [draw_flags] - and a, DRAWF_SKIP_UNIT_OBJS - jr nz, @load_unit_empty REL - - ld a, [unit_sprite] +load_oam_obj: + ld a, [current_oam_obj] ld d, 0 @@ -86,17 +82,14 @@ load_unit_obj: ; next object add a, oamsize - ld [unit_sprite], a + ld [current_oam_obj], a ret -@load_unit_empty: - ld hl, empty_oam - ret ; resets unit obj -reset_unit_obj: +reset_oam_obj: xor a, a - ld [unit_sprite], a + ld [current_oam_obj], a ret ; writes default vblank jmp vector @@ -117,3 +110,4 @@ setup_vblank_jp_smc: ld a, 0xD9 ; reti ld [hl], a ret + diff --git a/src/ui.s b/src/ui.s index f62ad26..b053cbe 100644 --- a/src/ui.s +++ b/src/ui.s @@ -12,127 +12,5 @@ ui_str_clear: ; inits UI ui_init: - ; fill shadow UI with default tile - ld hl, shadow_ui - ld bc, UI_TILE_WIDTH * UI_TILE_HEIGHT - ld d, UI_WINDOW_BACKGROUND - call memset - call ui_redraw_hp - call ui_redraw_mp - - call ui_request_redraw - ret - - ; redraws player stats - ; preserves all -ui_redraw_player: - push_all - call ui_redraw_hp - pop_all - ret - - ; updates HP UI -ui_redraw_hp: - ld hl, STR_HP - ld de, UI_STATUS_LINE+32 - call puts - - push de - ld de, player_unit - call stat_calc_hp - pop de - - call putn - - ; print / - ld hl, STR_SLASH - call puts - - ; print max hp - push de - ld de, player_unit - call stat_calc_hp_max - pop de - - call putn - - ret - - ; updates MP UI -ui_redraw_mp: - ld hl, STR_MP - ld de, UI_STATUS_LINE+64 - call puts - - push de - ld de, player_unit - call stat_calc_mp - pop de - - call putn - - ; print / - ld hl, STR_SLASH - call puts - - ; print max mp - push de - ld de, player_unit - call stat_calc_mp_max - pop de - call putn - ret - - ; clears the status line - ; and requests a UI redraw -ui_status_line_clear: - ld hl, STR_STATUS_CLEAR - ld de, UI_STATUS_LINE - call puts - jp ui_request_redraw - - ; requests a redraw - ; this will set up redraw_bg - ; redraw_shadow and redraw_steps -ui_request_redraw: - ld hl, SCRN1 - ld a, h - ld [redraw_bg], a - ld a, l - ld [redraw_bg+1], a - - ld de, shadow_ui - ld a, d - ld [redraw_shadow], a - ld a, e - ld [redraw_shadow+1], a - - ; steps of 5 * 16 - ld a, UI_TILE_WIDTH * UI_TILE_HEIGHT / REDRAW_TILES_PER_FRAME - ld [redraw_steps], a ret - - - ; draw a string and a number - ; as a status line - ; inputs: - ; hl: text ptr - ; a: value to display -ui_draw_status_stat: - push af - ld de, UI_STATUS_LINE - call puts - pop af - - call putn - call ui_request_redraw - - ret - - ; clears the UI status line -ui_clear_status_line: - ld de, UI_STATUS_LINE - ld hl, ui_str_clear - jp puts - diff --git a/src/unit.s b/src/unit.s deleted file mode 100644 index ac1f0dd..0000000 --- a/src/unit.s +++ /dev/null @@ -1,650 +0,0 @@ - ; runs state for each unit - ; does not update if actor is ACT_T_NULL - ; inputs: - ; hl: unit table (p0/p1) -units_update: - - ; loop counter - ld a, UNITS_MAX - -@loop: - push af ; store loop counter - - push hl - ld de, act_type - add hl, de ; hl = act_type - - ; a = type - ld a, [hl] - pop hl ; restore hl - cp a, ACT_T_NULL ; do not update type NULL - jr z, @skip REL - - ; save hl again - ; hl = act_state state machine - push hl - push hl - pop de ; need hl in de for parameter - ld a, [gameplay_flags] - and a, GPF_PAUSE_UPDATE - call z, st_update - - pop hl - - push hl - call unit_update_draw - pop hl -@skip: - ; next actor - ld de, act_size - add hl, de - - ; a-- - pop af - dec a - jr nz, @loop REL - - ret - - ; sets player turn taken flag -unit_set_player_turn_taken: - ld a, [gameplay_flags] - or a, GPF_PLAYER_TURN_TAKEN - ld [gameplay_flags], a - ret - - ; clears player turn taken flag -unit_clear_player_turn_taken: - ld a, [gameplay_flags] - and a, ~GPF_PLAYER_TURN_TAKEN & 0xFF - ld [gameplay_flags], a - ret - - ; generic unit input handler - ; inputs: - ; de: actor - ; hl: action table - ; a: remaining moves - ; returns: - ; bc: next state -unit_handle_inputs: - ; push next state to the stack for now - ld bc, NULL - push bc - - - ld b, BTNA - input_just - ld hl, action_btna - jr z, @nota REL - pop bc - call unit_handle_assigned_action - push bc ; bc = next state -@nota: - - ld b, BTNSELECT - input_just - jr z, @notselect REL - call action_menu_init -@notselect: - - ld b, BTNUP - input_held - jr z, @notup REL - - push de - push hl - call unit_try_move_up - pop hl - pop de - - call unit_set_player_turn_taken - pop bc - ld bc, st_unit_delay_to_active - push bc -@notup: - - ld b, BTNDOWN - input_held - jr z, @notdown REL - - push de - push hl - call unit_try_move_down - pop hl - pop de - - call unit_set_player_turn_taken - pop bc - ld bc, st_unit_delay_to_active - push bc -@notdown: - - ld b, BTNLEFT - input_held - jr z, @notleft REL - - push de - push hl - call unit_try_move_left - pop hl - pop de - - call unit_set_player_turn_taken - pop bc - ld bc, st_unit_delay_to_active - push bc -@notleft: - - ld b, BTNRIGHT - input_held - jr z, @notright REL - - call unit_try_move_right - - call unit_set_player_turn_taken - pop bc - ld bc, st_unit_delay_to_active - push bc -@notright: - - pop bc - ret - - ; performs a generic collision test - ; before a move is attempted - ; ret on nz - ; inputs: - ; $1: register containing coordinate - ; $2: change in register (e.g. +16/-16) - ; $3: collision mask for tile - ; de: actor - ; returns: - ; unit_test_collision_cf_flags: 0 if not collided with a tile - ; FLAGS if collided - ; _pox_y/x: set to input acot y and x -#macro unit_test_collision - ; perform tile collision check - push de - call unit_get_pos - - ld a, $1 - add a, ($2 & 0xFF) - ld $1, a - - ; write y and x pos - ld hl, act_rt_collision_pos_y - add hl, de ; de = collision vars y pos - ld a, b - ld [hl+], a ; write y - ld a, c - ld [hl+], a ; write x - - push bc - push hl ; save hl = rt cf value - call map_get_tile_div16 - ; set flags result - pop hl - ld [hl], a ; store last cf - and a, $3 - pop bc - pop de - ret nz - - push de - call unit_collides_with_any_other - ; TODO: write collided unit here as well - and a, $2 - pop de - ret nz -#endmacro - - ; tests a tile position for collision with - ; any other actor. Skips actors of type 0 - ; inputs: - ; b/c: y/x tile positon to test - ; de : current actor - ; returns: - ; a = CF_COLLISION if collision occured - ; sets act_rt_collided_with -unit_collides_with_any_other: -#define scratch_loop_i scratch - ld hl, p0_units - ld a, UNITS_MAX ; loop counter - -@loop: - ld [scratch_loop_i], a - push de ; save current actor on stack - push bc - - ; skip act type == 0 - push de - push hl - ld de, act_type - add hl, de ; hl = actor type - ; skip if type is 0 - ld a, [hl] - cp a, 0 - pop hl - pop de - jr z, @skip REL - - ; check if actor is current actor - ld a, h - cp a, e - jr nz, @no_skip REL - ld a, l - cp a, d - jr z, @skip REL -@no_skip: - - push hl - ld de, act_pos_y - add hl, de ; hl = pos_y of current actor - - ld a, [hl+] ; a = y - cp a, b - ; a != b -> no collision - jr nz, @no_collision REL - - ld a, [hl] ; a = x - cp a, c - ; a != c -> no collision - jr z, @collision REL -@no_collision: - pop hl - -@skip: - ld de, act_size - add hl, de ; move to next actor - - ld a, [scratch_loop_i] - dec a - - pop bc - pop de - jp nz, @loop - - ; if we get here - ; no collision occured - ld a, 0 - ret -@collision: - pop hl - pop bc - pop de - ; set de to hl's current collider actor - ld bc, act_rt_collided_with - add hl, bc - ld a, e - ld [hl+], a - ld a, d - ld [hl], a - - ; if we get here clean up the stack - ; and set the CF_COLLISION flag - ld a, CF_COLLISION - ret -#undefine scratch_loop_i - - - ; moves a unit up - ; moves are aborted - ; if no more initiative is left - ; a wall is hit, another unit is hit - ; or the edge of the map is hit - ; inputs: - ; de: actor - ; updates: - ; actor initiative based on tile flags - ; actor position -unit_try_move_up: - ; y - 1 - unit_test_collision b, -16 & 0xFF, CF_COLLISION - - push de - ld hl, act_pos_y - add hl, de - ; hl = actor y - ld a, [hl] - cp a, 0 ; upper bound - - pop de - ret z - - sub a, 16 - ld [hl], a - - call play_walk_noise - - ret - -unit_try_move_down: - ; y + 1 - unit_test_collision b, 16, CF_COLLISION - - ld hl, act_pos_y - add hl, de - ; hl = actor y - ld a, [hl] - cp a, MAP_H - 1 ; lower bound - ret z - - add a, 16 - ld [hl], a - - call play_walk_noise - - ret - -unit_try_move_left: - ; x - 1 - unit_test_collision c, -16 & 0xFF, CF_COLLISION - - ld hl, act_pos_x - add hl, de - ; hl = actor x - ld a, [hl] - cp a, 0 ; left bound - ret z - - sub a, 16 - ld [hl], a - - call play_walk_noise - - ret - -unit_try_move_right: - ; x + 1 - unit_test_collision c, 16, CF_COLLISION - - ld hl, act_pos_x - add hl, de - ; hl = actor x - ld a, [hl] - cp a, MAP_W - 1 ; right bound - ret z - - add a, 16 - ld [hl], a - - call play_walk_noise - - ret - - - ; centers the current scroll on the selected unit - ; snaps to corners of the map - ; inputs: - ; de: actor -unit_scroll_center: - ld hl, act_pos_y - add hl, de - ; hl = pos y - - ; y position scroll - ld a, [hl+] - div16 a - - ; max y - cp a, 0x0E - jr c, @not_max_y REL - ld a, 0x0E -@not_max_y: - - ; min y - cp a, 0x05 - jr nc, @not_min_y REL - ld a, 0x05 -@not_min_y: - ; adjust scroll - sub a, (MAP_H - VIEW_PORT_TILES_H) / 2 - mul16 a - ld [scroll_y], a - - ; x position scroll - ld a, [hl] - div16 a - - ; max x - cp a, 0x0B - jr c, @not_max_x REL - ld a, 0x0B -@not_max_x: - - ; min x - cp a, 0x05 - jr nc, @not_min_x REL - ld a, 0x05 -@not_min_x: - - sub a, (MAP_W - VIEW_PORT_TILES_W) / 2 - - mul16 a - ld [scroll_x], a - - - ret - - ; switches a unit to active state - ; inputs: - ; de: unit - ; returns: - ; bc: new state -unit_switch_to_active: - ld hl, act_st_active - add hl, de ; hl = st_active ptr - ld a, [hl+] - ld c, a - ld a, [hl] - ld b, a - ; bc = next active state - - ret - - ; forces a unit into an active state - ; inputs: - ; de: unit -unit_wake_up: - push de - call unit_switch_to_active - ; bc = active state - push bc - pop de ; de = new state - pop hl ; unit ptr - ld bc, st_size - call memcpy - ret - - ; switches the current unit to idle - ; sets moves to 0 - ; inputs: - ; de: unit - ; returns: - ; bc: new state -unit_switch_to_idle: - ld hl, act_st_idle - add hl, de ; hl = st_idle ptr - ld a, [hl+] - ld c, a - ld a, [hl] - ld b, a - ret - - ; forces a unit to go into idle state - ; inputs: - ; de: unit -unit_sleep: - push de - call unit_switch_to_idle - ; bc = active state - push bc - pop de ; de = new state - pop hl ; unit ptr - ld bc, st_size - call memcpy - ret - - ; called before switching to active - ; this call also checks if the unit may need to - ; hand over control to a new unit - ; this is done when moves are 0 - ; if the player unit is here we set the turn as finished - ; inputs: - ; de: unit -unit_delay_to_active: - ; check if de is player - ; if so set turn as finished - ld a, player_unit LO - cp a, e - jr nz, @not_player REL - ld a, player_unit HI - cp a, d - jr nz, @not_player REL - - call unit_set_player_turn_taken - -@not_player: - ; do not proceed if an attack animation is ongoing - ld a, [gpf_attack_ongoing] - cp a, 0 - jr nz, @delay_again REL - - ldnull bc - ret -@delay_again: - ld bc, st_unit_delay_to_active_fast - ret - - ; inputs - ; de: actor -unit_idle: - ldnull bc - ret - - ; pauses object redraws - ; until unpause is called -unit_pause_objs: - ld a, [draw_flags] - or a, DRAWF_SKIP_UNIT_OBJS - ld [draw_flags], a - ret - - ; resumes obj updates -unit_resume_objs: - ld a, [draw_flags] - and a, ~DRAWF_SKIP_UNIT_OBJS & 0xFF - ld [draw_flags], a - ret - - - ; gets the tile value at the current unit's position - ; inputs: - ; de: unit - ; returns: - ; bc: y/x -unit_get_pos: - ld hl, act_pos_y - add hl, de ; hl = pos y - ld a, [hl+] - ld b, a ; b = y - ld a, [hl] - ld c, a ; c = x - ret - - ; TODO: - ; returns: - ; hl: inventory ptr - ; a: inventory length -unit_get_inventory: - ret - - ; TODO: - ; returns: - ; hl: equipment ptr - ; a: equipment length -unit_get_equipment: - ret - - ; sets a draw routine for a unit - ; inputs: - ; de: unit - ; bc: draw routine -unit_set_draw: - ld hl, act_draw - add hl, de - ; hl = draw ptr - ld a, c - ld [hl+], a - ld a, b - ld [hl], a - ret - - ; finds a unit at a specific location - ; inputs: - ; bc: y/x - ; returns: - ; hl: unit ptr or NULL if not found -unit_find_at: - ld hl, p0_units - - ; a = loop counter - ld a, UNITS_MAX - -@loop: - push af - push hl - - push hl - ; do not find type null - ld de, act_type - add hl, de - ld a, [hl] - pop hl - cp a, 0 - jr z, @no_match REL - - ld de, act_pos_y - add hl, de - ; hl = y pos - - ; check if positions match - ld a, [hl+] - cp a, b ; does y match? - jr nz, @no_match REL - - ld a, [hl] - cp a, c ; does x match? - jp z, @found - -@no_match: - pop hl ; back to start - pop af ; restore loop counter - ; next unit - ld de, act_size - add hl, de - dec a - jp nz, @loop - - ldnull hl - ret - -@found: - pop hl ; hl = start of found act - pop af ; af was also saved so we need to pop - ret - -st_unit_idle: - st_def 0x00, unit_idle, st_unit_idle - - ; template for st_unit_delay_to_active - ; in wram -st_unit_delay_to_active_template: - st_def 8, unit_delay_to_active, st_unit_switch_to_active - -st_unit_delay_to_active_fast: - st_def 0, unit_delay_to_active, st_unit_switch_to_active - -st_unit_switch_to_active: - st_def 0, unit_switch_to_active, st_unit_switch_to_active diff --git a/src/unit_cpu.s b/src/unit_cpu.s deleted file mode 100644 index 7a3ff94..0000000 --- a/src/unit_cpu.s +++ /dev/null @@ -1,309 +0,0 @@ -#define UNIT_SCAN_RANGE_Y MAP_H/4 -#define UNIT_SCAN_RANGE_X MAP_W/4 - - ; checks if the unit is dead - ; if so sets type to 0 - ; inputs: - ; de: actor - ; returns: - ; z-flag if dead -unit_cpu_check_dead: - ld hl, act_hp - add hl, de - ld a, [hl] - cp a, 0 - ret nz ; not dead - push af - - ld a, ACT_T_NULL - ld hl, act_type - add hl, de - ld [hl], a ; set type to NULL - - pop af - ret - - ; handles cpu inputs - ; chaser CPU script - ; inputs: - ; de: actor - ; returns: - ; bc: next state -unit_handle_cpu_inputs: -#define MOVE_MADE scratch - - ; check if dead - ; if so set type to 0 - call unit_cpu_check_dead - ldnull bc - ret z - - ; check if player has taken turn - ; if not exit - ldnull bc - ld a, [gameplay_flags] - and a, GPF_PLAYER_TURN_TAKEN - ret z - - ; if rand is > 127 we do not - ; attack no matter what - call rand - cp a, 127 - jr c, @skip_attack REL - - ; attempt an attack - ; and jump to move made if attack was performed - call unit_cpu_attack_player - cp a, 0 - jp nz, @attack_started - -@skip_attack: - ; clear move made buffer - xor a, a - ld [MOVE_MADE], a - - ; there's a change the - ; unit will just move randomly anyway - call rand - and a, 0x2 - cp a, 0 - jp z, @random_move - - ; otherwise follow player - - ; check y position - ; and follow player in y direction if player is in range - ld hl, player_unit+act_pos_y - ld a, [hl] - ld b, a ; b = player y pos - push de - ld hl, act_pos_y - add hl, de - ld a, [hl] ; a = act y pos - call distance - pop de - - ; are we in scan range? - cp a, UNIT_SCAN_RANGE_Y - jr nc, @not_in_y_range REL - cp a, 0 - jr z, @not_in_y_range REL - - ; which direction? - ld a, c - cp a, DISTANCE_BGTA - push af - call nz, unit_try_move_up - pop af - call z, unit_try_move_down - ld a, 1 - ld [MOVE_MADE], a -@not_in_y_range: - - ; check x position - ; and follow player in x direction if player is in range - ld hl, player_unit+act_pos_x - ld a, [hl] - ld b, a ; b = player x pos - push de - ld hl, act_pos_x - add hl, de - ld a, [hl] ; a = act x pos - call distance - pop de - - ; are we in scan range? - cp a, UNIT_SCAN_RANGE_X - jr nc, @not_in_x_range REL - cp a, 0 - jr z, @not_in_x_range REL - - ; which direction? - ld a, c - cp a, DISTANCE_BGTA - push af - call nz, unit_try_move_left - pop af - call z, unit_try_move_right - ld a, 1 - ld [MOVE_MADE], a -@not_in_x_range: -@random_move: - - ; call random move if move was not made - ld a, [MOVE_MADE] - cp a, 0 - call z, unit_cpu_random_move - -@move_made: - ld bc, st_unit_delay_to_active - ret -@attack_started: - ld bc, st_action_attack_damage_actor - ret -#undefine MOVE_MADE - - ; loads attack runtime ptr and clears values - ; inputs - ; de: actor - ; returns: - ; hl: act_rt_action_dat1 - ; preserves: af -unit_cpu_load_and_clear_attack_rt_dat: - ; hl = rt action dat 1 - ld hl, act_rt_action_dat1 - add hl, de - - push af - inc hl ; rt action dat 2 - ; clear attack frame timer - xor a, a - ld [hl], a - dec hl ; back to dat 1 - pop af - ret - - ; performs an attack - ; in the direction of the player - ; checks if player is on tile next to current unit - ; inputs: - ; de: actors - ; returns: - ; a: 1 attack performed - ; a: 0 no attack -unit_cpu_attack_player: - ; first check if x == x player - ld hl, act_pos_x - add hl, de - ld a, [hl] - ld b, a ; b = act x - - ld hl, player_unit+act_pos_x - ld a, [hl] - - ; they need to be equal to be in range - cp a, b - jr nz, @not_in_y_range REL - - ; now check y position distance - ld hl, act_pos_y - add hl, de - - ld a, [hl] ; a = current unit y - ld b, a ; move to b - - ld hl, player_unit+act_pos_y - ld a, [hl] ; a = player y - - call unit_cpu_load_and_clear_attack_rt_dat - - - ; check y distance - call distance - cp a, 1 - jr nz, @not_in_y_range REL - ld a, c ; find out which direction - cp a, DISTANCE_AGTB - ; jump up or down - jp nz, @attack_up - jp @attack_down - -@not_in_y_range: - - ; check x distance - ; first check if y == y player - ld hl, act_pos_y - add hl, de - ld a, [hl] - ld b, a ; b = act y - - ld hl, player_unit+act_pos_y - ld a, [hl] - - cp a, b - jr nz, @not_in_x_range REL - - ; now check x position distance - ld hl, act_pos_x - add hl, de - ld a, [hl] ; a = current unit x - ld b, a ; move to b - - ld hl, player_unit+act_pos_x - ld a, [hl] ; a = player_x - - call unit_cpu_load_and_clear_attack_rt_dat - - ; check x distance - call distance - cp a, 1 - jr nz, @not_in_x_range REL - ld a, c ; find out which direction - cp a, DISTANCE_AGTB - ; jump left or right - jp nz, @attack_left - jp @attack_right -@not_in_x_range: - - ld a, 0 ; no attack - ret - -@attack_up: - ; write direction values - ld a, DIRUP - ld [hl], a - ld a, 1 ; attack - ret - -@attack_down: - ld a, DIRDOWN - ld [hl], a - ld a, 1 ; attack - ret - -@attack_left: - ld a, DIRLEFT - ld [hl], a - ld a, 1 ; attack - ret - -@attack_right: - ld a, DIRRIGHT - ld [hl], a - ld a, 1 ; attack - ret - - - ; moves actor into a random direction - ; inputs: - ; de: actor -unit_cpu_random_move: - ; pick where to go - call roll_d16 - and a, 3 ; 0-3 - ; 0 == left - cp a, 0 - call z, unit_try_move_left - - ; 1 == right - cp a, 1 - call z, unit_try_move_right - - ; 2 == up - cp a, 2 - call z, unit_try_move_up - - ; 3 == down - cp a, 3 - call z, unit_try_move_down - - ret - - ; attack state for demo units - ; inputs: - ; de: actor ptr - ; returns: - ; bc: next state -unit_demo_1_cpu_update_attack: - ldnull bc - ret diff --git a/src/unit_demo.s b/src/unit_demo.s deleted file mode 100644 index 593a96d..0000000 --- a/src/unit_demo.s +++ /dev/null @@ -1,140 +0,0 @@ -unit_demo_guard_anim_table: - anim_header 0, unit_demo_guard_anim_table - anim_ent 0, 0, 0x88, 0 - anim_ent 0, 8, 0x8A, 0 - anim_ent 0, 0, 0x00, 0 - -unit_demo_guard_attack_up: - anim_header ATTACK_ANIM_LEN, unit_demo_guard_anim_table - anim_ent 0, 0, 0x88, 0 - anim_ent 0, 8, 0x8A, 0 - anim_ent -12, 0, ACTION_ATTACK_SPRITE1, 0 - -unit_demo_guard_attack_down: - anim_header ATTACK_ANIM_LEN, unit_demo_guard_anim_table - anim_ent 0, 0, 0x88, 0 - anim_ent 0, 8, 0x8A, 0 - anim_ent 12, 0, ACTION_ATTACK_SPRITE1, 0 - -unit_demo_guard_attack_left: - anim_header ATTACK_ANIM_LEN, unit_demo_guard_anim_table - anim_ent 0, 0, 0x88, 0 - anim_ent 0, 8, 0x8A, 0 - anim_ent 0, -12, ACTION_ATTACK_SPRITE1, 0 - - -unit_demo_guard_attack_right: - anim_header ATTACK_ANIM_LEN, unit_demo_guard_anim_table - anim_ent 0, 0, 0x88, 0 - anim_ent 0, 8, 0x8A, 0 - anim_ent 0, 12, ACTION_ATTACK_SPRITE1, 0 - -unit_demo_dog_anim_table: - anim_header 0, unit_demo_dog_anim_table - anim_ent 0, 0, 0x90, 0 - anim_ent 0, 8, 0x92, 0 - anim_ent 0, 0, 0x00, 0 - -unit_demo_dog_attack_up: - anim_header ATTACK_ANIM_LEN, unit_demo_dog_anim_table - anim_ent 0, 0, 0x90, 0 - anim_ent 0, 8, 0x92, 0 - anim_ent -12, 0, ACTION_ATTACK_SPRITE1, 0 - -unit_demo_dog_attack_down: - anim_header ATTACK_ANIM_LEN, unit_demo_dog_anim_table - anim_ent 0, 0, 0x90, 0 - anim_ent 0, 8, 0x92, 0 - anim_ent 12, 0, ACTION_ATTACK_SPRITE1, 0 - -unit_demo_dog_attack_left: - anim_header ATTACK_ANIM_LEN, unit_demo_dog_anim_table - anim_ent 0, 0, 0x90, 0 - anim_ent 0, 8, 0x92, 0 - anim_ent 0, -12, ACTION_ATTACK_SPRITE1, 0 - - -unit_demo_dog_attack_right: - anim_header ATTACK_ANIM_LEN, unit_demo_dog_anim_table - anim_ent 0, 0, 0x90, 0 - anim_ent 0, 8, 0x92, 0 - anim_ent 0, 12, ACTION_ATTACK_SPRITE1, 0 - -unit_demo_hazmat_anim_table: - anim_header 0, unit_demo_hazmat_anim_table - anim_ent 0, 0, 0x94, 0 - anim_ent 0, 8, 0x96, 0 - anim_ent 0, 0, 0x00, 0 - -unit_demo_hazmat_attack_up: - anim_header ATTACK_ANIM_LEN, unit_demo_hazmat_anim_table - anim_ent 0, 0, 0x94, 0 - anim_ent 0, 8, 0x96, 0 - anim_ent -12, 0, ACTION_ATTACK_SPRITE1, 0 - -unit_demo_hazmat_attack_down: - anim_header ATTACK_ANIM_LEN, unit_demo_hazmat_anim_table - anim_ent 0, 0, 0x94, 0 - anim_ent 0, 8, 0x96, 0 - anim_ent 12, 0, ACTION_ATTACK_SPRITE1, 0 - -unit_demo_hazmat_attack_left: - anim_header ATTACK_ANIM_LEN, unit_demo_hazmat_anim_table - anim_ent 0, 0, 0x94, 0 - anim_ent 0, 8, 0x96, 0 - anim_ent 0, -12, ACTION_ATTACK_SPRITE1, 0 - -unit_demo_hazmat_attack_right: - anim_header ATTACK_ANIM_LEN, unit_demo_hazmat_anim_table - anim_ent 0, 0, 0x94, 0 - anim_ent 0, 8, 0x96, 0 - anim_ent 0, 12, ACTION_ATTACK_SPRITE1, 0 - -unit_demo_1_init: - ldnull bc - ret - - ; cpu controllerd unit update -unit_demo_1_cpu_update: - push de - call unit_handle_cpu_inputs - pop de - - ret - -unit_demo_1_cpu_update_idle: - ldnull bc - ret - -unit_demo_guard: - st_def 0x00, unit_demo_1_init, st_unit_demo_1_cpu_update - act_def ACT_T_GUARD, 0, 9, 9, 0 - act_stat_def1 1, 3, 1, 1 - act_stat_def2 1, 1, 32, 1 - act_st_def st_unit_demo_1_cpu_update, st_unit_idle - act_def_meta unit_draw, unit_demo_guard_anim_table - -unit_demo_dog: - st_def 0x00, unit_demo_1_init, st_unit_demo_1_cpu_update - act_def ACT_T_DOG, 0, 9, 9, 0 - act_stat_def1 1, 2, 1, 1 - act_stat_def2 1, 1, 32, 1 - act_st_def st_unit_demo_1_cpu_update, st_unit_idle - act_def_meta unit_draw, unit_demo_dog_anim_table - - -unit_demo_hazmat: - st_def 0x00, unit_demo_1_init, st_unit_demo_1_cpu_update - act_def ACT_T_HAZMAT, 0, 9, 9, 0 - act_stat_def1 1, 1, 1, 1 - act_stat_def2 1, 1, 32, 1 - act_st_def st_unit_demo_1_cpu_update, st_unit_idle - act_def_meta unit_draw, unit_demo_hazmat_anim_table - - -st_unit_demo_1_cpu_update: - st_def 0x00, unit_demo_1_cpu_update, st_unit_demo_1_cpu_update - -st_unit_demo_1_cpu_update_idle: - st_def 0x00, unit_demo_1_cpu_update_idle, st_unit_demo_1_cpu_update_idle - diff --git a/src/update.s b/src/update.s index 8971f4f..a160c8d 100644 --- a/src/update.s +++ b/src/update.s @@ -1,36 +1,13 @@ update_game_over: - ldnull bc ret update_game: ; tick rng every frame call rand - ; clear turn taken flag - call unit_clear_player_turn_taken - ; clear oam call shadow_oam_clear - - ; update map state - ld de, map_st - call st_update - - ld hl, p0_units - call units_update - - ; play obj animation - ld de, objanim - call st_update - - ld a, [player_map_cursor] - ld [player_map_cursor_prev], a - - ldnull bc - ret - -update_pause: - ldnull bc + ret ; called after vblank @@ -40,76 +17,13 @@ update: ld [frame_count], a ; reset objects - call reset_unit_obj - - ld de, game_mode - jp st_update - - ; sets up a new game - ; loads default player - ; fades out the screen - ; loads default map -new_game_init: - call video_fade_out - - call shadow_oam_clear - - call ui_init - - call unit_load_default_player - call actions_new_game_init - - ; init initial map + call reset_oam_obj + + ; load current sate routine + ld a, [game_state] + ld l, a + ld a, [game_state+1] + ld h, a + jp hl - call mapgen_init - - call game_init - - ld a, BGP - ld [shadow_bpg], a - call video_fade_in ret - - ; geric game init call - ; sets up window - ; inits UI -game_init: - ; set up UI - ld a, WINDOW_Y - ld [RWY], a - ld a, WINDOW_X - ld [RWX], a - - ; set up palettes for - ; gameplay - ld a, BGP - ld [RBGP], a - ld [shadow_bpg], a - - ld a, 0b11100100 - ld [ROBP0], a - ld [shadow_robp0], a - - ld a, 0b11011000 - ld [ROBP1], a - ld [shadow_robp1], a - - ldnull bc - ret - - -st_init_new_game: - st_def 0x00, new_game_init, st_update_game - -st_update_game: - st_def 0x00, update_game, st_update_game -st_update_pause: - st_def 0x00, update_pause, st_update_pause -st_update_game_over: - st_def 0x00, update_game_over, st_update_game_over - -st_update_action_menu: - st_def 0x00, update_action_menu, st_update_action_menu - -st_update_debug_menu: - st_def 0x00, update_debug_menu, st_update_debug_menu diff --git a/src/video.s b/src/video.s index 5c0cc13..82a8cda 100644 --- a/src/video.s +++ b/src/video.s @@ -11,9 +11,6 @@ vblank: or a, LCDCF_OBJON ld [RLCD], a - ; check ui update - call redraw_vblank - ; dma previous frame's oam call OAMDMAFN @@ -22,8 +19,6 @@ vblank: ; get inputs call poll_inputs - call video_swap_tile_bank_player_indoors - ld a, 1 ld [frame_ready], a pop_all @@ -41,29 +36,6 @@ scroll_write: ret - ; swaps tilebank if the player is currently - ; inside a room - ; sets LCDC_TILE_BANK if player is inside - ; unsets it otherwise -video_swap_tile_bank_player_indoors: - ld a, [player_rt_special_flags] - and a, CF_COVERED - jr nz, @not_covered REL - - ld a, [RLCD] - ; set bit - or a, LCDCF_TILE_BANK - ld [RLCD], a - - ret -@not_covered: - ld a, [RLCD] - ; unset bit - and a, (~LCDCF_TILE_BANK) & 0xFF - ld [RLCD], a - - ret - ; swaps the current tilebank by setting/unsetting ; LCDC_TILE_BANK video_swap_tile_bank: @@ -257,58 +229,6 @@ video_fade_in: #undefine video_fade_set_bgp -#macro redraw_vblank_write - ld a, [de] - inc de - ld [hl+], a -#endmacro - ; redraws a BG step in vblank -redraw_vblank: - ld a, [redraw_steps] - ; no more steps we bail - cp a, 0 - ret z - - ; steps-- - dec a - ld [redraw_steps], a - - ; load bg ptr - ld a, [redraw_bg] - ld h, a - ld a, [redraw_bg+1] - ld l, a - - ; load source address - ld a, [redraw_shadow] - ld d, a - ld a, [redraw_shadow+1] - ld e, a - - ; write data - ; in an unrolled loop - redraw_vblank_write - redraw_vblank_write - redraw_vblank_write - redraw_vblank_write - - ; lastly store current ptr state again - - - ld a, d - ld [redraw_shadow], a - ld a, e - ld [redraw_shadow+1], a - - ld a, h - ld [redraw_bg], a - ld a, l - ld [redraw_bg+1], a - - ret -#undefine redraw_vblank_write - - ; loads tilesets ; inputs: diff --git a/src/wram.s b/src/wram.s index 0dcc1d4..5e2f38c 100644 --- a/src/wram.s +++ b/src/wram.s @@ -5,23 +5,15 @@ shadow_oam: .adv OBJSMAX * oamsize shadow_oam_end: - ; temporary variables - ; that can be used by any routine - ; as storage -scratch: .adv 16 - frame_ready: .adv 1 frame_count: .adv 1 - ; current sprite -unit_sprite: .adv 1 +current_oam_obj: .adv 1 ; current frame's inputs curr_inputs: .adv 1 ; previous frame's inputs prev_inputs: .adv 1 - -game_mode: .adv st_size ; used by video fade out and fade in shadow_bpg: .adv 1 @@ -30,6 +22,9 @@ shadow_robp1: .adv 1 ; shadow version of IE shadow_ie: .adv 1 + + ; game state routine ptr +game_state: .adv 2 ; self modifying code ; the vblank interrupt jumps here @@ -45,166 +40,26 @@ vblank_jp: .adv 4 ; if set to NULL do not read from this address demo_inputs: .adv 2 - ; menu cursor can be used by any in-game menu -menu_cursor_index: .adv 1 - -draw_flags: .adv 1 -gameplay_flags: .adv 1 - - ; special flags that are set by the player unit -player_rt_special_flags: .adv 1 - - ; shadow UI is a buffer for drawing the UI - ; this UI is then re-drawn on request in vblank -shadow_ui: .adv UI_TILE_WIDTH * UI_TILE_HEIGHT - - ; shadow bg - ; 4 rows of tiles that can be updated - ; the same way shadow_ui can be redrawn - ; draw new tiles here - ; and queue up a redraw for the desired amount of rows - ; at the desired location -shadow_bg: .adv BG_WIDTH * BG_SHADOW_HEIGHT - -; redraw BG address -redraw_bg: .adv 2 -; redraw shadow address -redraw_shadow: .adv 2 -; remaining redraw steps -redraw_steps: .adv 1 - -action_menu_cursor: .adv 1 -debug_menu_cursor: .adv 1 - - ; simple menu delay timer -select_menu_delay: .adv 1 - ; dummy oam ; same memory as empty_unit empty_oam: .adv oamsize - ; > 0 if an actor has an ongoing attack - ; used to delay other actors during the animation -gpf_attack_ongoing: .adv 1 - - ; mapgen flags -mapgen_flags: .adv 1 - - - ; can be used for custom state transtions - ; simple write state info to this location - ; and return st_custom -st_custom: .adv st_size - ; it is common for delay to active to have a custom - ; timer to simulate movement speed - ; this is a valid delay state and should only be written to - ; to change its timer -st_unit_delay_to_active: .adv st_size ; scroll location scroll_y: .adv 1 scroll_x: .adv 1 - - ; +/-1 for each time the cursor moves - ; allows us to move scroll when needed -scroll_move_y: .adv 1 -scroll_move_x: .adv 1 - ; state for object animation -objanim: .adv obja_size - - ; game state - ; this region holds the entire game state - ; everything thats needed for a savme game should be - ; contained here -state: ; 16 bit srand seed ; seed must never be 0 srand: .adv 2 - ; game speed variable - ; this controls how fast the - ; game runs -game_speed: .adv 1 - - ; last d16 result -d16: .adv 1 - - - ; the current floor -floor: .adv 1 - - - - ; player speciifc data - - ; player inventory data -player_inventory: - ; TODO: add data here - - ; player equipment - ; pointers to items - ; stores all items equiped - ; for player actors there are 6 eqipment slots - ; for all other actors there is no equipment -player_equipment: -player_eq_head: .adv 2 -player_eq_body: .adv 2 -player_eq_hand1: .adv 2 -player_eq_hand2: .adv 2 -player_eq_ring: .adv 2 -player_eq_amulet: .adv 2 ; units ; player_unit (unit 0) is reserved player_unit: .adv 0 -p0_units: .adv act_size * UNITS_MAX - - ; - ; floor data - ; - - ; cursor into the floor's map tables (e.g. seeds) - ; go up: dec by FLOOR_W - ; go down: inc by FLOOR_W - ; go left: dec - ; go right: inc -player_map_cursor: .adv 1 - ; the previous frame's map cursor -player_map_cursor_prev: .adv 1 - - ; one byte per map - ; indicating where doors should be placed - ; DIRUP, DIRDOWN, DIRLEFT, DIRRIGHT bits - ; this links all maps in a floor -map_doors_location: .adv FLOOR_MAP_COUNT - - ; list of seeds used - ; for the current maps - ; fill using mapgen_seed - ; the seeds will be accessed via the map's - ; seed index -map_seeds: .adv FLOOR_MAP_COUNT * 2 +actors: .adv act_size * ACTS_MAX - ; map tiles and collision data -map: .adv c_size * MAP_SIZE -map_end: - - ; mape state machine -map_st: .adv st_size - ; ptr to the last map header used -map_header: .adv 2 +map_current_page: .adv 1 - ; actor savegame data; - ; store actor data here on map load - ; and re-load on map restore - ; if pos y and pos x are both 0xFF do not restore -act_sg: .adv act_sg_size * UNITS_MAX * FLOOR_MAP_COUNT -act_sg_end: - -; buttton-assigned actions -action_btna: .adv action_size -action_btnb: .adv action_size - state_end: