From: Lukas Krickl Date: Thu, 30 Oct 2025 05:13:37 +0000 (+0100) Subject: refactor: huge code cleanup X-Git-Url: https://git.krickl.dev/?a=commitdiff_plain;h=d4909c83c37439b11239d86d1ff789cececae16a;p=gbrg%2F.git refactor: huge code cleanup This change removes a lot of code for a faild map system :^) --- diff --git a/src/actor.s b/src/actor.s index 419d8d1..cc83bc4 100644 --- a/src/actor.s +++ b/src/actor.s @@ -1,476 +1 @@ - - ; same as actor_try_add - ; without inputs -actor_try_add_player_projectile: - ld hl, actors_player_projectiles - ld b, ACTS_PLAYER_PROJECTILES - jp actor_try_add - - ; same as actor_try_add - ; without inputs -actor_try_add_enemy: - ld hl, actors_enemy - ld b, ACTS_ENEMY - jp actor_try_add - - ; attempts to spawna a new actor - ; by searching for a free slot of type 0 - ; inputs: - ; hl: actor table - ; b: max - ; returns: - ; hl: free actor ptr - ; hl: NULL if no slot is available - ; note: memory is not cleared - ; the caller will have to initialize the actor -actor_try_add: - ld de, act_size -@loop: - ld a, [hl] ; check type - cp a, 0 - ret z ; if 0 type -> match! return now - ; go to next ptr - add hl, de - dec b - jr nz, @loop REL - - ; nothing found - ld hl, NULL - ret - - - ; draws a single object - ; for an actor accounting for scroll - ; inputs: - ; de: actor - ; hl: oam ptr - ; b: tile - ; c: oam flags - ; a: nnnn0000: y offset from actor pos; - ; 0000nnnn: x offset from actor pos - ; returns: - ; hl: next oam ptr (if reserved!) -actor_draw: - push hl - ld hl, act_pos_y - add hl, de - push hl - pop de ; de = pos y - pop hl - - ; hl = oam ptr again - - ; deal with y position - push bc - push af - - ; get y offset - and a, 0xF0 - swap a ; a = y offset - ld b, a - ld a, [de] - add a, OBJ_OFF_Y - add a, b ; a = y postion - - inc de ; de = x pos - - ld [hl+], a - - pop af - - ; deal with x position - - and a, 0xF ; a = x offset - ld b, a - ld a, [de] - add a, b ; b = x position - add a, OBJ_OFF_X - - ld [hl+], a - - pop bc - - ; tile - ld a, b - ld [hl+], a - - ; oam flags - ld a, c - ld [hl+], a - - - ret - - ; actor no-op call -act_nop: - ret - - ; tables for each actor type -actor_update_draw_table: - dw act_nop - dw player_update_and_draw - dw act_guard_update_and_draw - dw act_nop - dw act_nop - dw act_projectile_arrow_update_and_draw - - ; called when an actor is spawned - ; via a map object -actor_init_table: - dw act_nop - dw act_nop - dw act_guard_init - dw act_nop - dw act_nop - dw act_nop - -actor_collision_res_table: - dw act_nop - dw player_col_res - dw act_guard_col_res - dw act_nop - dw act_nop - dw act_projectile_arrow_col_res - - ; inits an actors - ; inputs: - ; de: actor -actor_init: - ld a, [de] - add a, a ; * 2 for offset - ld hl, actor_init_table - ld b, 0 - ld c, a - add hl, bc - - ld a, [hl+] - ld b, a - ld a, [hl] - ld h, a - ld l, b - call_hl - - ret - - ; calls update for all actors - ; and draws them -actor_update_all: - ld de, actors - ld b, ACTS_MAX - - ; updates a partial actor table - ; inputs: - ; de: actors - ; b: size -actor_update_table: -@loop: - ; look up rotuine from table - ld a, [de] ; a = type - add a, a ; * 2 for offset - - push_all - ld b, 0 - ld c, a ; bc = offset - ld hl, actor_update_draw_table - add hl, bc - ld a, [hl+] - ld b, a - ld a, [hl] - ld h, a - ld l, b - - call_hl - pop_all - - ; move to next actor - ld hl, act_size - add hl, de - push hl - pop de ; de = next act - - dec b ; counter-- - jr nz, @loop REL - ret - - ; despawns an actor - ; inputs: - ; de: actor ptr -actor_despawn: - xor a, a - ld [de], a - ret - - ; writes actor default collider - ; bsed on an input position - ; writes the collider to dst - ; e.g. use with actor's real rectangle - ; if real collision should be written - ; use with tmp_rect for collision tests before moving - ; inputs: - ; a: collision mask - ; b/c: y/x position of actor - ; hl: destination rectangle -actor_write_default_collider: - ld [hl+], a ; mask - ld a, b - add a, 14 - ld [hl+], a ; y pos - - ld a, c - add a, 2 - ld [hl+], a ; x pos - - ld a, 12 ; width/height - ld [hl+], a ; height - - ld a, 10 - ld [hl+], a ; width - ret - - ; performs a single test case - ; inputs: - ; tmp_rect: new target rect - ; de: ptr to 2 coordinates (y/x) e.g. tmp_rect_points - ; $1: rect_bl/tl/br/tr call - ; hl: rectangle to compare to - ; jumps to $1 on collision - ; returns: - ; de: de+=2 - ; preserves: hl -#macro actor_test_movement_corner - ld a, [de] - inc de - ld b, a - ld a, [de] - inc de - ld c, a - ; bc = point - - push hl - push de - call rect_point_test - pop de - pop hl - cp a, 1 - jp z, $1 -#endmacro - - ; tests movement against all collision rectangles - ; inputs: - ; hl: actor table start - ; c: actor table length - ; a: collision mask - ; b: direction - ; de: current actor (this actor is skipped) - ; tmp_rect: new collision rectangle - ; returns: - ; a == 0: no collision - ; a == 1: collision - ; hl: if collided with an actor points to the actor hit, otherwise NULL -actor_test_movement: - ; save actor table info - push hl - push bc - - ; save current actor - push de - ld [tmp_rect_mask], a - - ld a, b - ld [tmp_act_direction], a - ; a = direction - call actor_test_movement_write_points - - ; check all static rectangles - ld hl, rectangles - ld b, RECT_MAX - -@rect_test_loop: - push hl - push bc - call actor_test_rect - pop bc - pop hl - cp a, 0 - jp nz, @rect_collision -@skip_rect: - ld de, r_size - add hl, de ; next rect (de = r_size) - dec b - jp nz, @rect_test_loop - - pop de - - pop bc - ld b, c ; b = actor table lenth - - pop hl ; hl = actor table - -@actor_test_loop: - ld a, [hl] - cp a, 0 ; check if type is 0 - jp z, @skip_actor - - ; check if current actor is in de - ld a, d - cp a, h - jr nz, @test_actor REL - ld a, e - cp a, l - jr z, @skip_actor REL - -@test_actor: - push de - push hl - push bc - ld de, act_rect - add hl, de ; hl = rectangle for actor - - call actor_test_rect - cp a, 0 - pop bc - pop hl - pop de - jp nz, @actor_collision - -@skip_actor: - push bc - ld bc, act_size - add hl, bc ; next actor - pop bc - dec b - jp nz, @actor_test_loop - -@no_collision: - ld hl, NULL - xor a, a ; no collision - ret -@rect_collision: - ; need to pop 3 values that were pushed - ; before rect loop - pop de - pop hl - pop bc - ld hl, NULL - ld a, 1 - ret -@actor_collision: - ; hl = actor already - ld a, 1 - ret - - ; writes a point to a rectangle - ; inputs: - ; hl: rectangle - ; bc: tmp_rect_points ptr - ; $1 rect_tr,bl,br,tl -#macro act_test_movement_write_point_at - push hl - push bc - call $1 - pop bc - pop hl - - ld a, d - ld [bc], a - inc bc - ld a, e - ld [bc], a - inc bc -#endmacro - - ; writes tmp rect points to - ; tmp_rect_points. only writes 2 points - ; based on the chosen direction - ; inputs: - ; a: direction - ; tmp_rect: the rectangle -actor_test_movement_write_points: - ld hl, tmp_rect - ld bc, tmp_rect_points - - cp a, DIRDOWN - jp z, @down - cp a, DIRLEFT - jp z, @left - cp a, DIRRIGHT - jp z, @right - - ; default case: up -@up: - act_test_movement_write_point_at rect_tl - act_test_movement_write_point_at rect_tr - ret -@down: - act_test_movement_write_point_at rect_bl - act_test_movement_write_point_at rect_br - ret -@right: - act_test_movement_write_point_at rect_br - act_test_movement_write_point_at rect_tr - ret -@left: - act_test_movement_write_point_at rect_bl - act_test_movement_write_point_at rect_tl - ret - - ; tests a single rectangle against an actor - ; based on the current direction only 2 points are tested - ; inputs: - ; tmp_act_direction: direction - ; tmp_rect: new collision rectangle - ; tmp_rect_mask: mask to test agains - ; tmp_rect_points: 2 rectangle points base don tmp_rect and the - ; chosen direction - ; hl: rectangle to test - ; returns: - ; a: 1 collision - ; a: 0 no collision -actor_test_rect: - - ; pre-filter rectangle mask - ld a, [tmp_rect_mask] - call rect_test_mask - jp z, @no_collision - - ; test the first 2 points in tmp_rect_points - ld de, tmp_rect_points - actor_test_movement_corner @rect_collision - actor_test_movement_corner @rect_collision - -@no_collision: - xor a, a - ret -@rect_collision: - ld a, 1 - ret - - ; calls collision resolution - ; inputs: - ; de: event origin actor - ; hl: actor collided with -actor_col_res: - ld a, h - or a, l - cp a, 0 - ret z ; do nothing if 0 - - ld a, [hl] - add a, a ; type * 2 as offset into table - - push hl - - ld hl, actor_collision_res_table - ld b, 0 - ld c, a - add hl, bc ; hl = routine ptr - - ld a, [hl+] - ld b, a - ld a, [hl] - ld h, a - ld l, b - - pop bc ; the rotuine wants collider in bc - call_hl - ret + ; common routines for both player and enemy diff --git a/src/debug.s b/src/debug.s index c0ba348..e69de29 100644 --- a/src/debug.s +++ b/src/debug.s @@ -1,239 +0,0 @@ -#define DBG_MARKER_TILE 0x80 - -debug_routines: - dw dbg_nop - dw dbg_rect_draw -debug_routines_end: - -dbg_nop: - ret - - ; inits the debug interface -dbg_init: - ; set first rectangle to display - ld a, rectangles LO - ld [dbg_rect], a - ld a, rectangles HI - ld [dbg_rect+1], a - - ret - - ; updates debug options - ; keys: - ; down + select: cycle next debug function -dbg_update: - ld a, [dbg_delay] - cp a, 0 - jp nz, @debug_delay - - ; check if dbg swap to next function is needed - ld b, BTNDOWN | BTNSELECT - input_held - cp a, BTNDOWN | BTNSELECT - jr nz, @no_switch REL - ; set a timer - ld a, 16 - ld [dbg_delay], a - - ; next function - ld a, [dbg_fn] - inc a - - ; loop around if > max functions - cp a, (debug_routines_end - debug_routines) / 2 - jr nz, @no_reset REL - xor a, a -@no_reset: - ld [dbg_fn], a -@no_switch: - - ld a, [dbg_fn] - add a, a ; * 2 for table offset - - ld hl, debug_routines - 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 hl -@debug_delay: - - dec a - ld [dbg_delay], a - ret - - ; gets rectangle point and loads it into de - ; preserves all other registers - ; inputs: - ; $1: rect_br/bl/tr/tl - ; de: rectangle ptr -#macro dbg_rect_draw_get - push hl - push de - - push de - pop hl ; hl = rectangle - call $1 - push de - pop bc ; bc = point - - pop de - pop hl -#endmacro - - ; draws a marker obj at - ; the edge of a rectangle - ; keys: - ; up + select: cycle to next debug rectangle -dbg_rect_draw: - ld b, BTNUP | BTNSELECT - input_held - cp a, BTNUP | BTNSELECT - jp z, @rect_draw_cycle - - ; draw each corner of the rectangle if it is not 0 - ld a, [dbg_rect] - ld e, a - ld a, [dbg_rect+1] - ld d, a - - call dbg_rect_draw_ptr - - ; always draw player rectangle - ld de, actors+act_rect - call dbg_rect_draw_ptr - - ret - -@rect_draw_cycle: - ld a, [dbg_rect] - ld l, a - ld a, [dbg_rect+1] - ld h, a - ld de, r_size - add hl, de - - ; next rectangle - ld a, l - ld [dbg_rect], a - ld a, h - ld [dbg_rect+1], a - - ld a, 16 - ld [dbg_delay], a - ret - - ; draws a rectangle from ptr - ; inputs: - ; de: rectangle -dbg_rect_draw_ptr: - - ; de = rectangle ptr - - ; if flags are 0 we exit - ld a, [de] - cp a, 0 - jp z, @rect_not_alloced - push de - ld a, 4 - call oamalloc - pop de - - ; hl = oam - dbg_rect_draw_get rect_tl - ; bc = top left - - ; write top left y - ld a, b - add a, OBJ_OFF_Y - ld [hl+], a - - ; write top left x - ld a, c - add a, OBJ_OFF_X - ld [hl+], a - - ; write tile - ld a, DBG_MARKER_TILE - ld [hl+], a - - ; write flags - xor a, a - ld [hl+], a - - - ; bottom left - dbg_rect_draw_get rect_bl - - ; write bottom left y - ld a, b - add a, OBJ_OFF_Y - ld [hl+], a - - ; write bottom left x - ld a, c - add a, OBJ_OFF_X - ld [hl+], a - - ; write tile - ld a, DBG_MARKER_TILE - ld [hl+], a - - ; write flags - xor a, a - ld [hl+], a - - - - ; bottom right - dbg_rect_draw_get rect_br - - ; write bottom right y - ld a, b - add a, OBJ_OFF_Y - ld [hl+], a - - ; write bottomt right x - ld a, c - add a, OBJ_OFF_X - ld [hl+], a - - ; write tile - ld a, DBG_MARKER_TILE - ld [hl+], a - - ; write flags - xor a, a - ld [hl+], a - - - ; top right - dbg_rect_draw_get rect_tr - - ld a, b - add a, OBJ_OFF_Y - ld [hl+], a - - ; write top left x - ld a, c - add a, OBJ_OFF_X - ld [hl+], a - - ; write tile - ld a, DBG_MARKER_TILE - ld [hl+], a - - ; write flags - xor a, a - ld [hl+], a - - - ret -@rect_not_alloced: - ret diff --git a/src/defs.s b/src/defs.s index 7ab83f4..efbd193 100644 --- a/src/defs.s +++ b/src/defs.s @@ -9,22 +9,8 @@ #define WRAM 0xC000 #define WRAMLEN 0xFFF -#define GAME_SPEED_DEFAULT GAME_SPEED_NORMAL - #define NULL 0 -#define ACTS_PLAYER_PROJECTILES 6 -#define ACTS_ENEMY 4 -#define ACTS_ENEMY_PROJECTILES 6 -#define ACTS_MAX (ACTS_PLAYER_PROJECTILES + ACTS_ENEMY + ACTS_ENEMY_PROJECTILES) - -#define HP_MAX 20 - -#define MAP_OBJ_MAX 32 -#define RECT_MAX 6 - -#define MAP_ROW_H 16 ; pixels per row - #define STACK_BEGIN 0xDFFF ; seed for the rng @@ -38,66 +24,32 @@ #define UI_TILE_WIDTH 32 #define UI_TILE_HEIGHT 4 - - ; rectangle collision flags -.se 1 - ; collides with player -.de RF_PLAYER, 1 - ; is a generic wall -.de RF_WALL, 2 - ; collides with enemy -.de RF_ENEMY, 4 - - ; rectangle struct -.se 0 - ; if flags == 0 the rectangle is free -.de r_flags, 1 -.de r_pos_y, 1 -.de r_pos_x, 1 -.de r_h, 1 -.de r_w, 1 -.de r_size, 0 - +#define MAP_W 16 +#define MAP_H 16 ; actor type enum .se 0 .de ACT_T_NULL, 1 -.de ACT_T_PLAYER, 1 -.de ACT_T_GUARD, 1 -.de ACT_T_DOG, 1 -.de ACT_T_HAZMAT, 1 -.de ACT_T_ARROW_BULLET, 1 ; actor struct ; act_def .se 0 .de act_type, 1 .de act_flags, 1 - .de act_pos_y, 1 ; y/x position .de act_pos_x, 1 - ; custom parameter .de act_p0, 1 - ; state parameter .de act_state, 1 - - ; stats -.de act_hp, 1 -.de act_ac, 1 - - ; every actor has a collision rectangle -.de act_rect, r_size .de act_size, 0 ; map header struct .se 0 .de map_flags, 1 -.de map_init_pat, 2 - ; ptr to map objects list -.de map_objs_ptr, 2 + ; ptr to map routine +.de map_routine, 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 @@ -108,8 +60,7 @@ .de map_tile_bank3_ptr, 2 .de map_header_size, 0 -#define DISTANCE_BGTA 1 -#define DISTANCE_AGTB 0 + ; the map header is followed by MAP_W * MAP_H bytes ; alias for directions .def int DIRUP = BTNUP @@ -117,41 +68,6 @@ .def int DIRLEFT = BTNLEFT .def int DIRRIGHT = BTNRIGHT - - ; row pattern struct -.se 0 -.de pat_tilemap, 10 -.de pat_size, 0 - - ; map object types -.se 0 -.de MOT_NOP, 1 -.de MOT_SET_PAT, 1 -.de MOT_DISABLE_SCROLL, 1 -.de MOT_ENABLE_SCROLL, 1 -.de MOT_RECT, 1 -.de MOT_ACTOR_SPAWNER, 1 -.de MOT_SET_MAP_ROUTINE, 1 -.de MOT_RECT_CLEAR, 1 - - ; map object struct -.se 0 -.de mo_type, 1 -.de mo_flags, 1 -.de mo_row, 1 -.de mo_dat, 2 -.de mo_size, 0 - - ; gameplay control flags .se 1 -.de GPF_NO_SCROLL, 1 - ; scroll a row up next vblank -.de GPF_SCROLL, 2 - ; player max hp is set to 1 -.de GPF_HARD_MODE, 4 - ; weapon type for player -.se 0 -.de WT_ARROW, 1 -.de WT_RIFLE, 1 diff --git a/src/enemy.s b/src/enemy.s index 373dc95..a14c34c 100644 --- a/src/enemy.s +++ b/src/enemy.s @@ -1,197 +1,8 @@ -#define GUARD_SPRITE_IDLE1 0x88 - -act_enemy_guard: - actdef ACT_T_GUARD, 0, 0, 10, 0 - -#define ACT_GUARD_WALK_RIGHT 0 -#define ACT_GUARD_SHOOT 1 -#define ACT_GUARD_WALK_LEFT 2 - -#define ACT_GUARD_MOVE_FRAMES 40 - -act_guard_state_table: - dw act_guard_walk_right - dw act_guard_shoot - dw act_guard_walk_left - - ; updates the guard enemy - ; inputs: - ; de: actor ptr -act_guard_update: - ; load position - ld hl, act_pos_y - add hl, de - ld a, [hl+] - ld b, a - ld a, [hl+] - ld c, a - - ; check if dead - ld hl, act_hp - add hl, de - ld a, [hl] - cp a, 0 - jp z, @despawn - - ; write collision shape - ld hl, act_rect - add hl, de - ld a, RF_ENEMY - call actor_write_default_collider - - ; call states - ld hl, act_state - add hl, de - ld a, [hl] - ld hl, act_guard_state_table - jp call_tbl - - ret -@despawn: - call actor_despawn - ret - - ; guard shoot state - ; inputs: - ; de: actor -act_guard_shoot: - ; TODO - ld hl, act_state - add hl, de - ld a, ACT_GUARD_WALK_LEFT - ld [hl], a - ret - - ; actor walk left state - ; inputs: - ; de: actor ptr - ; uses: - ; p0 as timer -act_guard_walk_left: - ; walk - ld hl, act_pos_x - add hl, de - ld a, [hl] - dec a - ld [hl], a - - ; process timer - ld hl, act_p0 - add hl, de - ld a, [hl] - inc a - ld [hl], a - cp a, ACT_GUARD_MOVE_FRAMES - jr nz, @not_done REL - ; clear p0 and transition - xor a, a - ld [hl], a - - ld hl, act_state - add hl, de - ld a, ACT_GUARD_WALK_RIGHT - ld [hl], a -@not_done: - ret - - ; walk right state - ; inputs: - ; de: actor ptr - ; uses: - ; p0 as timer -act_guard_walk_right: - ; walk - ld hl, act_pos_x - add hl, de - ld a, [hl] - inc a - ld [hl], a - - ; process timer - ld hl, act_p0 - add hl, de - ld a, [hl] - inc a - ld [hl], a - cp a, ACT_GUARD_MOVE_FRAMES ; how many frames do we walk? - jr nz, @not_done REL - ; clear p0 and transition - xor a, a - ld [hl], a - - ld hl, act_state - add hl, de - ld a, ACT_GUARD_SHOOT - ld [hl], a - -@not_done: + ; inits enemy +enemy_init: ret - ; draws the guard enemy - ; inputs: - ; de: actor ptr -act_guard_draw: - push de - ld a, 2 - call oamalloc - pop de - - push de - ld b, GUARD_SPRITE_IDLE1 - ld c, 0 - ld a, 0 - call actor_draw - pop de - - ld b, GUARD_SPRITE_IDLE1+2 - ld c, 0 - ld a, 8 - call actor_draw - ret - - ; combination of update and draw call -act_guard_update_and_draw: - push de - call act_guard_draw - pop de - jp act_guard_update - - ; collision resolution between guard and another actor - ; inputs: - ; de: event origin actor - ; bc: guard -act_guard_col_res: - ld a, [de] - cp a, ACT_T_ARROW_BULLET - jr z, @arrow_bullet REL - - ret -@arrow_bullet: - ld hl, act_hp - add hl, bc - - ld a, [hl] - dec a - ld [hl], a - ret - - ; inits a guard - ; inputs: - ; de: actor -act_guard_init: - ld hl, act_hp - add hl, de - ld a, 4 - ld [hl], a - - xor a, a - ld hl, act_state - add hl, de - ld [hl], a - - ld hl, act_p0 - add hl, de - ld [hl], a - + ; updates enemy AI +enemy_update: ret diff --git a/src/levels.s b/src/levels.s index c888523..473e4e2 100644 --- a/src/levels.s +++ b/src/levels.s @@ -23,3 +23,4 @@ level_def_to_tile: ; followed by a 16x16 tilemap l1: + mapdef 0, map_r_nop, bank8000, bank8800, bank8C00, bank9000 diff --git a/src/macros.inc b/src/macros.inc index 01ab53f..962d1ef 100644 --- a/src/macros.inc +++ b/src/macros.inc @@ -153,12 +153,11 @@ $1: ; defines a map header ; inputs: ; $1: flags - ; $2: initial pattern - ; $3: objs ptr - ; $4: tile bank 0 - ; $5: tile bank 1 - ; $6: tile bank 2 - ; $7: tile bank 3 + ; $2: map routine + ; $3: tile bank 0 + ; $4: tile bank 1 + ; $5: tile bank 2 + ; $6: tile bank 3 #macro mapdef .db $1 dw $2 @@ -166,7 +165,6 @@ $1: dw $4 dw $5 dw $6 - dw $7 #endmacro ; defines a new actor @@ -196,26 +194,6 @@ $1: .db 0, 0, 0, 0, 0 #endmacro - ; defines a map object - ; inputs: - ; $1: type - ; $2: flags - ; $3: row - ; $4: dat1/dat2 (word) -#macro modef - .db $1, $2, $3 - dw $4 -#endmacro - - ; same as modef - ; but - ; $4: dat1 - ; $5: dat2 -#macro modef2 - .db $1, $2, $3, $4, $5 -#endmacro - - ; defines a rectangle ; inputs: ; $1: collision flags diff --git a/src/main.s b/src/main.s index f3fa6de..f63d46f 100644 --- a/src/main.s +++ b/src/main.s @@ -61,13 +61,9 @@ main: #include "ui.s" #include "audio.s" #include "map.s" -#include "mapobj.s" -#include "rowpatterns.s" #include "math.s" #include "game.s" #include "actor.s" -#include "rectangle.s" -#include "projectile.s" #include "mainmenu.s" #include "tiles.s" #include "levels.s" @@ -82,4 +78,3 @@ main: ; fill bank .fill 0xFF, 0x7FFF - $ - diff --git a/src/mainmenu.s b/src/mainmenu.s index 9919e9b..139597f 100644 --- a/src/mainmenu.s +++ b/src/mainmenu.s @@ -1,36 +1,2 @@ - - ; map routine that loads l1 -map_r_load_l1: - - ld a, [player+act_pos_y] - cp a, 5 - ret nc - - ; if the player is on the right side of the map - ; load hard mode - ld a, [player+act_pos_x] - cp a, 0x5F - jr c, @no_hard REL - ld a, [game_flags] - or a, GPF_HARD_MODE - ld [game_flags], a -@no_hard: - - call player_init - - ld de, l1_map - call map_load - ret - -l_main_menu: - mapdef 0, pat_empty, l_main_menu_objs, bank8000, bank8800, bank8C00, bank9000 - -l_main_menu_objs: - modef MOT_SET_MAP_ROUTINE, 0, 0, map_r_load_l1 - modef MOT_DISABLE_SCROLL, 0, 0, 0 - - modef MOT_SET_PAT, 0, 5, pat_easy_hard_mode - modef MOT_SET_PAT, 0, 6, pat_center_wall - modef MOT_NOP, 0, 0xFF, 0 diff --git a/src/map.s b/src/map.s index bdfb420..5d9be9f 100644 --- a/src/map.s +++ b/src/map.s @@ -1,12 +1,4 @@ #define SCRN0_END 0x9BF3 - - ; clears the map routine to nop -map_clear_routine: - ld a, map_r_nop LO - ld [map_routine], a - ld a, map_r_nop HI - ld [map_routine+1], a - ret ; loads a map ; including the required tileset @@ -16,16 +8,6 @@ map_clear_routine: ; inputs: ; de: map ptr map_load: - ; clear row - xor a, a - ld [map_curr_row], a - - ; enable scroll - call mo_enable_scroll - - ; clear map routine - call map_clear_routine - call disableinterrupts call next_vblank_wait call lcd_off @@ -39,35 +21,12 @@ map_load: call map_tile_banks_load pop de - ; load initial pattern - ld hl, map_init_pat - add hl, de - ld a, [hl+] - ld [map_curr_pat], a - ld a, [hl] - ld [map_curr_pat+1], a - - ; reset bg ptr - ld a, SCRN0_END LO - ld [map_scrn_ptr], a - ld a, SCRN0_END HI - ld [map_scrn_ptr+1], a - - ; load mo ptr - ld hl, map_objs_ptr - add hl, de - ld a, [hl+] - ld [map_curr_obj], a - ld a, [hl+] - ld [map_curr_obj+1], a - - call lcd_on call vblank_wait call enableinterrupts - call map_page_full_draw + call map_full_draw call player_init call ui_init @@ -140,264 +99,18 @@ map_tile_banks_load: ld [de], a dec de #endmacro - - ; draws the current row pattern of 16x16 tiles - ; only call during blank - ; also triggers objects -map_advance_row: - ld a, [map_scrn_ptr] - ld e, a - ld a, [map_scrn_ptr+1] - ld d, a - - ld a, [map_curr_pat] - ld l, a - ld a, [map_curr_pat+1] - ld h, a - - push hl - - ; first row of tiles - - map_advance_row_draw_bot - map_advance_row_draw_bot - map_advance_row_draw_bot - map_advance_row_draw_bot - map_advance_row_draw_bot - map_advance_row_draw_bot - map_advance_row_draw_bot - map_advance_row_draw_bot - map_advance_row_draw_bot - map_advance_row_draw_bot - - ; move to next row - ld hl, -12 & 0xFFFF - add hl, de - push hl - pop de ; de = next row - - pop hl - ; second row of tiles - map_advance_row_draw_top - map_advance_row_draw_top - map_advance_row_draw_top - map_advance_row_draw_top - map_advance_row_draw_top - map_advance_row_draw_top - map_advance_row_draw_top - map_advance_row_draw_top - map_advance_row_draw_top - map_advance_row_draw_top - - ; write new scrn ptr - ld hl, -12 & 0xFFFF - add hl, de - ; hl = new scrn ptr - ld a, l - ld [map_scrn_ptr], a - ld a, h - ld [map_scrn_ptr+1], a - - ; check if we reached the last row of scrn0 - cp a, 0x97 - jr nz, @not_end_of_scrn0 REL - ; end of scrn0 - wrap around back to first row - ld a, SCRN0_END LO - ld [map_scrn_ptr], a - ld a, SCRN0_END HI - ld [map_scrn_ptr+1], a -@not_end_of_scrn0: - - ; move to next row - ld a, [map_curr_row] - inc a - ld [map_curr_row], a - - ret ; draws a full page of the currently selected map ; waits for blank between each row ; inputs: ; [map] -map_page_full_draw: - call mo_exec - call next_vblank_wait - call map_advance_row - - call mo_exec - call next_vblank_wait - call map_advance_row - - call mo_exec - call next_vblank_wait - call map_advance_row - - call mo_exec - call next_vblank_wait - call map_advance_row - - call mo_exec - call next_vblank_wait - call map_advance_row - - call mo_exec - call next_vblank_wait - call map_advance_row - - call mo_exec - call next_vblank_wait - call map_advance_row - - ; last row will be out of visible scroll - call mo_exec - call next_vblank_wait - call map_advance_row +map_full_draw: ret ; nop map rotuine map_r_nop: ret - ; checks if all enemies are defeated - ; and re-enables scroll -map_r_enable_scroll_all_enemies_defeated: - ; don't run check loop if the anmation is already going - ld a, [map_anim_timer] - cp a, 0 - jr nz, @no_check_loop REL - - ; check if all enemies are NULL actors - ld hl, actors_enemy - ld de, act_size - ld b, ACTS_ENEMY - - xor a, a -@check_loop: - ; or type into a - or a, [hl] - ret nz ; one type is not 0 - add hl, de ; next actor - dec b - jr nz, @check_loop REL - -@no_check_loop: - - ld a, [map_anim_timer] - cp a, 0 - jp z, @no_animation - call map_arrow_indicator - - ld a, [map_anim_timer] - cp a, 0 - ret nz ; if timer is not 0 do not set scroll - - ; re-enable scroll - ld a, [game_flags] - and a, ~GPF_NO_SCROLL & 0xFF - ld [game_flags], a - call map_clear_routine - ret - -@no_animation: - ; set animation - ld a, 120 - ld [map_anim_timer], a - - xor a, a - ld [map_anim_state], a - - ld a, 80 ; x position - ld [map_anim_p0], a - ret - -#define MAP_TILE_ARROW 0x84 - - ; plays an arrow indicator animation - ; flashng it every 32 frames - ; uses timer for duration - ; map anim state for state counter - ; anim p0 for x position -map_arrow_indicator: - ld a, [map_anim_timer] - dec a - ld [map_anim_timer], a - jp z, @end_anim - - ; check state - ld a, [map_anim_state] - inc a - cp a, 32 - jr nz, @no_x_swap REL - ld a, [map_anim_p0] - xor a, 80 - ld [map_anim_p0], a - xor a, a ; clear state -@no_x_swap: - ld [map_anim_state], a - - ld a, 1 - call oamalloc - - ld a, 16 - ; y - ld [hl+], a - - ; x - ld a, [map_anim_p0] - ld [hl+], a - - ; tile - ld a, MAP_TILE_ARROW - ld [hl+], a - - ; flags - xor a, a - ld [hl+], a - - ret -@end_anim: - call map_clear_routine - ret - -l1_map: - mapdef 0, pat_empty, l1_objs, bank8000, bank8800, bank8C00, bank9000 - -l1_objs: - ; show GO arrow at the start - modef MOT_SET_MAP_ROUTINE, 0, 0, map_r_enable_scroll_all_enemies_defeated - - modef MOT_SET_PAT, 0, 8, pat_center_empty_wall - modef2 MOT_ACTOR_SPAWNER, 0, 8, ACT_T_GUARD, 0x40 - ; rectangle at y/x 0/0 with height 32 width 64 - modef MOT_RECT, 0, 8, 0x0703 - - - ; rectangle at y/x 0/0 with height 32 width 48 - modef MOT_RECT, 0, 8, 0xE503 - - modef MOT_SET_PAT, 0, 10, pat_center_grass - modef2 MOT_ACTOR_SPAWNER, 0, 11, ACT_T_GUARD, 0x80 - modef MOT_SET_PAT, 0, 18, pat_left_wall - - modef MOT_RECT_CLEAR, 0, 18, 0 - modef2 MOT_RECT, 0, 18, 0x0F, 0x07 - modef2 MOT_ACTOR_SPAWNER, 0, 18, ACT_T_GUARD, 0x40 - - modef MOT_SET_PAT, 0, 0x1A, pat_empty - modef2 MOT_ACTOR_SPAWNER, 0, 0x1F, ACT_T_GUARD, 0x40 - modef MOT_DISABLE_SCROLL, 0, 0x20, 0 - modef MOT_SET_MAP_ROUTINE, 0, 0x20, map_r_enable_scroll_all_enemies_defeated - - modef MOT_RECT_CLEAR, 0, 0x21, 0 - modef2 MOT_RECT, 0, 0x21, 0x0F, 0xE7 - modef MOT_SET_PAT, 0, 0x21, pat_right_wall - - modef2 MOT_RECT, 0, 0x29, 0x09, 0x07 - modef MOT_SET_PAT, 0, 0x29, pat_left_wall - - modef MOT_SET_PAT, 0, 0x2E, pat_empty - modef MOT_DISABLE_SCROLL, 0, 0x30, 0 - modef MOT_NOP, 0, 0xFF, 0 diff --git a/src/mapobj.s b/src/mapobj.s deleted file mode 100644 index 0135256..0000000 --- a/src/mapobj.s +++ /dev/null @@ -1,251 +0,0 @@ -; map objects are a list of objects -; a map has a static list of loadable objects -; when a row is being drawn the next object -; is checked -; if the row matches it is loaded into ram and executed -; when an object is off-screen it is unloded - -mo_routines: - dw mo_nop - dw mo_set_pat - dw mo_disable_scroll - dw mo_enable_scroll - dw mo_rect - dw mo_actor_spawner - dw mo_set_map_routine - dw mo_rect_clear - -mo_nop: - ret - - ; executes all map objects in the map object list - ; until the mo's row != current row - ; advances mo ptr -mo_exec: - ld a, [map_curr_obj] - ld e, a - ld a, [map_curr_obj+1] - ld d, a - - ld a, [map_curr_row] - ld b, a ; b = current row -@loop: - ; execute map object by type - ld hl, mo_row - add hl, de - ld a, [hl] - ; if rows do not match exit - cp a, b - jr nz, @done REL - - ; otherwise call object routine - push_all - ld a, [de] ; type - add a, a ; * 2 for offset - ld hl, mo_routines - ld b, 0 - ld c, a - add hl, bc - - ; hl = rotuine ptr - ld a, [hl+] - ld b, a - ld a, [hl+] - ld h, a - ld l, b - - ; call routine - call_hl - - - pop_all - ; go to next object - ld hl, mo_size - add hl, de - push hl - pop de ; de = next obj - jr @loop REL - -@done: - - ; write back next ptr - ld a, e - ld [map_curr_obj], a - ld a, d - ld [map_curr_obj+1], a - - ret - - ; sets the next draw pattern - ; inputs: - ; de: map object ptr -mo_set_pat: - ; new pattern is in dat1 and dat2 - ld hl, mo_dat - add hl, de - - ld a, [hl+] - ld [map_curr_pat], a - ld a, [hl] - ld [map_curr_pat+1], a - ret - - ; disables map scrolling - ; inputs: - ; de: map object ptr -mo_disable_scroll: - ld a, [game_flags] - or a, GPF_NO_SCROLL - ld [game_flags], a - ret - - ; enables map scrolling - ; inputs: - ; de: map object ptr -mo_enable_scroll: - ld a, [game_flags] - and a, ~GPF_NO_SCROLL & 0xFF - ld [game_flags], a - ret - - ; spawns a collision rectangle - ; the origin of a rectangle is the bottom left - ; dat1: nnnn0000: y offset from row in 8 pixel increments - ; 0000nnnn: height in 8 pixel increments (+1 height is implicitly added) - ; dat2: nnnn0000: x offset from row in 8 pixel increments - ; 0000nnnn: width in 8 pixel increments (+1 widt is implicitly added) - ; inputs: - ; de: map object ptr -mo_rect: - ld hl, mo_dat - add hl, de - ; hl = dat1 - - ; current row always has y-position 0 - ; (actually -16 so the next adjust will not move the rectanglet to the wrong spot) - ; for the bottom left corner - - ; calculate y position - ld a, [hl] - and a, 0xF0 - swap a - mul8 a - ; a = y offset - ld b, -16 & 0xFF - add a, b - ld b, a ; b = y position - - ; calculate height - ld a, [hl+] ; hl = dat2 - and a, 0x0F - inc a - mul8 a - ; d = height - ld d, a - - ; calculate x position - ld a, [hl] - and a, 0xF0 - swap a - mul8 a - ; c = x offset - ld c, a - - ; calculate width - ld a, [hl] - and a, 0x0F - inc a - mul8 a - ; e = width - ld e, a - - ; flag hard-coded to WALL - ld a, RF_WALL - - call rect_try_add - - ret - - ; spawns an actor spawner - ; dat1: actor type - ; dat2 nnnn0000: x offset to spawn at / 8 - ; inputs: - ; de: map object ptr -mo_actor_spawner: - ld hl, mo_dat - add hl, de - - push hl - call actor_try_add_enemy - pop de - ld a, h - or a, l - ret z ; bail if hl is NULL - - ; we have a ptr! - ld a, [de] - inc de ; go to dat2 - - push hl - ; set type - ld [hl+], a - - ; clear flags - xor a, a - ld [hl+], a - - ; y position is always the same - ld a, -16 & 0xFF - ld [hl+], a - - ; TODO: - ; x position is based on dat2 - ld a, [de] - and a, 0xF0 - swap a - add a, a ; * 2 - add a, a ; * 4 - add a, a ; * 8 - ld [hl+], a - - ; clear p0 and state - xor a, a - ld [hl+], a - ld [hl+], a - - ; TODO: run some init code based on type - pop de - ; de = actor base - call actor_init - - ret - - ; sets the current map routine - ; dat1/2: map routine ptw - ; inputs: - ; de: map object ptr -mo_set_map_routine: - ld hl, mo_dat - add hl, de - ld a, [hl+] - ld [map_routine], a - ld a, [hl+] - ld [map_routine+1], a - ret - - ; clears all map rectangles - ; use this to despawn current collision - ; shapes -mo_rect_clear: - ld hl, rectangles - ld de, r_size - ld b, RECT_MAX - xor a, a -@loop: - ld [hl], a - add hl, de - dec b - jr nz, @loop REL - - - ret diff --git a/src/math.s b/src/math.s index 4d90eec..e69de29 100644 --- a/src/math.s +++ b/src/math.s @@ -1,27 +0,0 @@ - - ; calculates the distance between 2 - ; numbers: - ; inputs: - ; a: n1 - ; b: n2 - ; returns: - ; a: absolute distance between a and b - ; c: 1 if b > a - ; c: 0 otherwise -distance: - cp a, b - ; if b > a jp - jr c, @b_gt_a REL - - ; otherwise a simple sub will do - sub a, b - ld c, DISTANCE_AGTB - ret -@b_gt_a: - ; exchange a and b and sub - ld c, a - ld a, b - ld b, c - sub a, b - ld c, DISTANCE_BGTA - ret diff --git a/src/mem.s b/src/mem.s index 07c063e..60da28e 100644 --- a/src/mem.s +++ b/src/mem.s @@ -29,8 +29,6 @@ mem_init: ld hl, new_game call game_set_state - call dbg_init - ret ; copies memory from one location to another diff --git a/src/player.s b/src/player.s index 52a41e2..fdee32e 100644 --- a/src/player.s +++ b/src/player.s @@ -1,352 +1,12 @@ -#define PLAYER_SPEED 0xE0 -#define ARROW_TILE 0x86 -#define PLAYER_WALKING_TILE 0x8E - - ; inits hard mode -player_init_hard_mode: - ld a, 1 - ld [player_hp_max], a - ret ; sets up the player actor player_init: - ; initial position - ld a, 0x60 - ld [player+act_pos_y], a - ld a, 0x40 - ld [player+act_pos_x], a - - ld a, 0x30 ; initial next scroll - ld [player_next_scroll_y], a - - ld a, [player_hp_max] - ld [player+act_hp], a - - - ld a, [game_flags] - and a, GPF_HARD_MODE - call nz, player_init_hard_mode ret ; updates the special player actor player_update: - - ld b, BTNUP - input_held - jr z, @not_up REL - ld b, PLAYER_SPEED - ld c, 0 - call player_stage_move_n - - ld a, DIRUP - call player_try_move - - ; only scroll if player actually moved - cp a, 0 - jr nz, @not_up REL - call player_try_scroll_up -@not_up: - - ld b, BTNDOWN - input_held - jr z, @not_down REL - ld b, PLAYER_SPEED - ld c, 0 - call player_stage_move_p - - ld a, DIRDOWN - call player_try_move - -@not_down: - -@left_right: - - ld b, BTNLEFT - input_held - jr z, @not_left REL - ld b, 0 - ld c, PLAYER_SPEED - call player_stage_move_n - - ld a, DIRLEFT - call player_try_move -@not_left: - - ld b, BTNRIGHT - input_held - jr z, @not_right REL - - ld b, 0 - ld c, PLAYER_SPEED - call player_stage_move_p - - ld a, DIRRIGHT - call player_try_move -@not_right: - - ld b, BTNA - input_held - jr z, @not_a REL - call player_shoot -@not_a: - -@direction_done: - ; write collider for this frame - ld a, [player+act_pos_y] - ld b, a - ld a, [player+act_pos_x] - ld c, a - ld a, RF_PLAYER - ld hl, player+act_rect - call actor_write_default_collider - - - ret - -#define PLAYER_SPRITE_IDLE1 0x8D - - ; sets scroll unless scroll is diabled -player_set_scroll: - ; scroll can still be allowed to complete the next tile - ; even if the scroll disable object is loaded - ld a, [scroll_timer] - cp a, MAP_ROW_H-1 - jr z, @scroll_anyway REL - - ld a, [game_flags] - and a, GPF_NO_SCROLL - ret nz - -@scroll_anyway: - ld a, [game_flags] - or a, GPF_SCROLL - ld [game_flags], a - ret - - ; if the player's real y position is over - ; a certain value we should scroll the map - ; if scrolling is allowed -player_try_scroll_up: - ld a, [player_next_scroll_y] - ld b, a - ld a, [player+act_pos_y] - cp a, b - jp nc, @no_scroll - - call player_set_scroll - - ; run next objects - ; so they are loaded before a move is attempted - call mo_exec - - -@no_scroll: - ret - - ; stages a move in a positive directon - ; inputs: - ; b/c: y/x movement - ; returns: - ; b/c: new y/x position -player_stage_move_p: - ld a, [player_sub_pixel_y] - add a, b - ld [player_sub_pixel_y], a - ld a, [player+act_pos_y] - adc a, 0 - - jr nc, @no_overflow_y REL - ld a, 0xFF -@no_overflow_y: - - ; bottom of screen - cp a, 0x60 - jr c, @no_edge_y REL - ld a, 0x60 -@no_edge_y: - - ld b, a - - ld a, [player_sub_pixel_x] - add a, c - ld [player_sub_pixel_x], a - ld a, [player+act_pos_x] - adc a, 0 - -jr nc, @no_overflow_x REL - ld a, 0xFF -@no_overflow_x: - - ; right side of screen - cp a, 0x90 - jr c, @no_edge_x REL - ld a, 0x90 -@no_edge_x: - - ld c, a - - ret - - ; stages a move in a negative directon - ; inputs: - ; b/c: y/x movement - ; returns: - ; b/c: new y/x position -player_stage_move_n: - ld a, [player_sub_pixel_y] - sub a, b - ld [player_sub_pixel_y], a - ld a, [player+act_pos_y] - sbc a, 0 - - jr nc, @no_underflow_y REL - xor a, a -@no_underflow_y: - - ld b, a - - ld a, [player_sub_pixel_x] - sub a, c - ld [player_sub_pixel_x], a - ld a, [player+act_pos_x] - sbc a, 0 - - jr nc, @no_underflow_x REL - xor a, a -@no_underflow_x: - - ld c, a - ret - ; moves the player - ; performs a collision check - ; moves scroll and performs map loads if needed - ; inputs: - ; a: direction - ; b/c: new y/x position - ; returns: - ; a: 1 == collision - ; a: 0 no collision -player_try_move: - ; store direction for now - ld [tmp_act_direction], a - - ; write temporary collider - push bc - ld a, RF_PLAYER - ld hl, tmp_rect - call actor_write_default_collider - - ; test collision agains walls and enemies - ld a, [tmp_act_direction] - ld b, a ; b = direction - ld a, RF_WALL | RF_ENEMY - ld de, player - ld hl, actors_enemy - ld c, ACTS_ENEMY - call actor_test_movement - pop bc - - ; hl should be NULL or an actor ptr - push af - call actor_col_res - pop af - - cp a, 0 - ret nz - - ld a, b - ld [player+act_pos_y], a - - ld a, c - ld [player+act_pos_x], a - - xor a, a - ret - - ; draws the special player actor + ; draws player at current location player_draw: - ld a, 2 - call oamalloc - - ; was any direction pressed this frame? - ld a, [curr_inputs] - and a, BTNUP | BTNDOWN | BTNLEFT | BTNRIGHT - jp nz, @walking - - ; idle sprite - ld de, player - ld b, PLAYER_SPRITE_IDLE1 - ld c, 0 - ld a, 3 - call actor_draw - - jp @weapon -@walking: - - ld de, player - ld b, PLAYER_WALKING_TILE - - ld a, [animation_frame] - cp a, 1 - jr z, @flip REL - - ld c, 0 - ld a, 3 - jr @no_flip REL - -@flip: - ld c, OAM_FXFLIP - ld a, 4 -@no_flip: - - call actor_draw - -@weapon: - ; TODO: draw based on player weapon type - ld de, player - ld b, ARROW_TILE - ld c, 0 - ld a, 0x46 - call actor_draw - ret - - -#define PLAYER_SHOOT_DELAY 32 - ; shoots the player's current weapon -player_shoot: - ld a, [player_shoot_delay] - cp a, 0 - jp nz, @tick - - ; TODO: check player curr weapon - - call actor_try_add_player_projectile - ld a, h - or a, l - ret z - - call act_spawn_projectile_arrow_player - - ld a, PLAYER_SHOOT_DELAY - ld [player_shoot_delay], a - - ret -@tick: - dec a - ld [player_shoot_delay], a - ret - - ; combination of update and draw call -player_update_and_draw: - call player_draw - jp player_update - - ; collision resolution between player - ; and other actor - ; inputs: - ; de: origin actor - ; bc: player -player_col_res: ret diff --git a/src/projectile.s b/src/projectile.s deleted file mode 100644 index f09054c..0000000 --- a/src/projectile.s +++ /dev/null @@ -1,154 +0,0 @@ - -#define ARROW_SPRITE 0x82 - -; projectile flags -.se 1 -.de PROJECTILE_F_PLAYER, 1 - - ; spawns a arrow projectile for player - ; inputs: - ; hl: actor ptr -act_spawn_projectile_arrow_player: - ld a, ACT_T_ARROW_BULLET - ld [hl], a ; write type - - push hl - ld de, act_pos_y - add hl, de - ; hl = new pos y - - - ld a, [player+act_pos_y] - ld [hl+], a - - ld a, [player+act_pos_x] - add a, 4 - ld [hl+], a - pop hl - - ; set to player type - ld de, act_p0 - add hl, de - ld a, PROJECTILE_F_PLAYER - ld [hl], a - - call play_attack_noise - - ret - - ; updates a simple arrow projectile - ; inputs: - ; de: actor ptr -act_projectile_arrow_update: - ; is this a player actor? - ld hl, act_p0 - add hl, de - ld a, [hl] ; load projectile p0 flags - and a, PROJECTILE_F_PLAYER - jp nz, @player - - ; TODO: - ; enemy projectile logic - - ret -@player: - ld hl, act_pos_y - add hl, de - - ld a, [hl] - dec a - cp a, 0xFF - jp z, @despawn - ld [hl+], a - - ; a = y pos - ld b, a - ld a, [hl] - ld c, a ; c = x pos - - push de - - ld a, RF_PLAYER - ld hl, tmp_rect - call actor_projectile_write_default_collider - - ; check enemy collision - pop de - push de - - ld b, DIRUP - ld a, RF_ENEMY | RF_WALL - ld hl, actors_enemy - ld c, ACTS_ENEMY - call actor_test_movement - - pop de - cp a, 1 - jr z, @collided REL - - ret - -@collided: - push de - call actor_col_res - pop de - call play_hit_noise -@despawn: - jp actor_despawn - - - ; draws a arrow projectile - ; inputs: - ; de: actor -act_projectile_arrow_draw: - push de - ld a, 1 - call oamalloc - pop de - - ld b, ARROW_SPRITE - ld c, 0 - ld a, 0 - jp actor_draw - - ; updates and draws projectile - ; for pistosl -act_projectile_arrow_update_and_draw: - push de - call act_projectile_arrow_update - pop de - jp act_projectile_arrow_draw - - ; collision resolution for arrow projectile - ; inputs: - ; de: event origin actor - ; bc: projectile -act_projectile_arrow_col_res: - ret - - - ; writes actor default projectile collider - ; based on an input position - ; writes the collider to dst - ; e.g. use with actor's real rectangle - ; if real collision should be written - ; use with tmp_rect for collision tests before moving - ; inputs: - ; a: collision mask - ; b/c: y/x position of actor - ; hl: destination rectangle -actor_projectile_write_default_collider: - ld [hl+], a ; mask - ld a, b - add a, 4 - ld [hl+], a ; y pos - - ld a, c - add a, 2 - ld [hl+], a ; x pos - - ld a, 4 ; width/height - ld [hl+], a ; height - - ld [hl+], a ; width - ret diff --git a/src/rectangle.s b/src/rectangle.s deleted file mode 100644 index 058474a..0000000 --- a/src/rectangle.s +++ /dev/null @@ -1,253 +0,0 @@ - ; limitations: - ; positions can never wrap around a page - ; in this engine - ; all positions are 8-bit only - ; great care must be taken to avoid - ; collisions from overlapping a page swap! - - - ; attempts to add a rectangle - ; to the rectangle buffer - ; if no slots are availabel it will simply be skipped - ; this function always sets y_hi to 0 - ; inputs: - ; a: flags - ; b/c: y/x position - ; d/e: h/w -rect_try_add: - push af - push bc - push de - call rect_find_slot - ld a, h - or a, l - cp a, 0 - ; if hl == 00 exit - jp z, @exit - - pop de - pop bc - pop af - - ; write flags - ld [hl+], a - - ; write y - ld a, b - ld [hl+], a - - ; wirte x - ld a, c - ld [hl+], a - - ; write h - ld a, d - ld [hl+], a - - ; write w - ld a, e - ld [hl], a - - ret -@exit: - pop de - pop bc - pop af - ret - - ; attempts to find a rectangle slot where - ; flags == 0 (unused) - ; returns: - ; hl: 0000 -> no slot - ; hl: ptr -> slot -rect_find_slot: - ld hl, rectangles - ld de, r_size - ld b, RECT_MAX - -@loop: - ; hl = flags - ld a, [hl] - ; if flags is 0 we ret - cp a, 0 - ret z - - add hl, de - dec b - jr nz, @loop REL - - ; if nothing was found ld NULL - ld hl, 0 - ret - - - ; gets top left of a rectangle - ; inputs: - ; hl: rectangle - ; returns: - ; de: y/x -rect_tl: - inc hl ; skip mask - ld a, [hl+] - ld d, a ; d = y - ld a, [hl+] - ld e, a ; e = x - - ld a, [hl] - ld l, a - ld a, d - sub a, l ; y-height - capunderflow - ld d, a ; d = top left y - ret - - ; same as rect_tl - ; bototm left -rect_bl: - inc hl ; skip mask - ld a, [hl+] - ld d, a ; d = y - ld a, [hl] - ld e, a ; e = x - ret - - ; same as rect_tl - ; top right -rect_tr: - inc hl ; skip mask - ld a, [hl+] - ld d, a ; d = y - ld a, [hl+] - ld e, a ; e = x - inc hl ; skip height - - ld a, [hl] - add a, e ; e = x + width - capoverflow - ld e, a - - dec hl ; go back to height - ld a, [hl] - ld l, a - ld a, d - sub a, l ; y-height - capunderflow - ld d, a ; d = top right y - ret - - ; same as rect_tl - ; bottom right -rect_br: - inc hl ; skip mask - ld a, [hl+] - ld d, a ; d = y - ld a, [hl+] - ld e, a ; e = x - inc hl ; skip height - - ld a, [hl] - add a, e ; e = x + width - capoverflow - ld e, a - ret - - ; tests if a point is inside r1 - ; does not perform collision mask test - ; bc: y/x point - ; hl: rectangle - ; returns: - ; a == 1: inside - ; a == 0: not inside - ; hl: byte after original rectangle -rect_point_test: - inc hl ; skip mask - - ; bottom left - - ; load bottom left point - ld a, [hl+] - ld d, a ; d = y - ld a, [hl+] - ld e, a ; e = x - - ld a, b ; compare y - cp a, d - jr nc, @no_collision REL - ld a, c ; compare x - cp a, e - jr c, @no_collision REL - - - ; top left - - ; get top left y point - ld a, [hl+] - push hl - ld l, a ; TODO: remove use of l to avoid push - ld a, d - sub a, l ; y-height - capunderflow - ld d, a ; d = top left y - pop hl - - ; x was already tested in bottom left - - ld a, b ; compare y points - cp a, d - jr c, @no_collision REL - - - ; top right - - ; get top right x - ld a, [hl+] - add a, e ; e = x + width - capoverflow - ld e, a - - ; top right has unique x and y positions - - ld a, b ; compare y - cp a, d - jr c, @no_collision REL - ld a, c ; compare x position - cp a, e - jr nc, @no_collision REL - - - ; bottom right - - ; original y position was already tested in bottom left - ; x positions was already tested in top right - - ; all other missing x/y checks have - ; already been performed in previous points - ; e.g. original y is tested in bottom left - -@collision: - ld a, 1 - ret -@no_collision: - xor a, a ; no collision - ret - - ; tests rectangle mask - ; inputs: - ; a: mask - ; hl: rectangle - ; returns: - ; z-flag: != 0 if mask is ok - ; uses: a, c -rect_test_mask: - ld c, a - ld a, [hl] - and a, c - ret - - ; removes a rectangle - ; inputs: - ; de: rectangle -rect_despawn: - xor a, a - ld [de], a - ret diff --git a/src/rowpatterns.s b/src/rowpatterns.s deleted file mode 100644 index bad115c..0000000 --- a/src/rowpatterns.s +++ /dev/null @@ -1,37 +0,0 @@ - - ; tile space -.def int TS = 0x20 - - ; tile grass -.def int GS = 0x62 - - ; generic wall -.def int WG = 0x40 - - ; tile HARD MODE / Skull -.def int SK = 0x0A - -pat_empty: -.db TS, TS, TS, TS, TS, TS, TS, TS, TS, TS - -pat_center_grass: -.db TS, TS, TS, GS, GS, GS, TS, TS, TS, TS - -pat_center_empty_wall: -.db WG, WG, WG, TS, TS, TS, WG, WG, WG, WG - -pat_right_wall: -.db WG, WG, WG, TS, TS, TS, TS, TS, TS, TS - -pat_left_wall: -.db TS, TS, TS, TS, TS, TS, WG, WG, WG, WG - -pat_easy_hard_mode: -.db TS, SK, TS, TS, WG, WG, TS, TS, TS, TS - -pat_center_wall: -.db TS, TS, TS, TS, WG, WG, TS, TS, TS, TS - - ; enf of level row pattern -pat_eol: -.db 0xFF diff --git a/src/ui.s b/src/ui.s index 3aee756..79ed476 100644 --- a/src/ui.s +++ b/src/ui.s @@ -26,81 +26,4 @@ ui_init: ; draws the entire UI ; only call during blank ui_draw_all: - call ui_clear_player_hp - call ui_draw_player_hp - call ui_draw_enemy_hp - ret - - ; clears player hp -ui_clear_player_hp: - ld hl, UI_PLAYER_HP+7 - ld a, UI_WINDOW_BACKGROUND - -.rep i, 8, 1, ld [hl+], a - - ret - - ; draws player hp -ui_draw_player_hp: - ld de, UI_PLAYER_HP - ld hl, str_player - call puts - - ld hl, UI_PLAYER_HP+7 - ld a, [player+act_hp] - ld b, a - jp ui_draw_hp - - ; draws generic hp - ; inputs: - ; hl: address to draw to - ; b: current hp -ui_draw_hp: - -@full_loop: - ld a, b - cp a, 4 - jr c, @skip_full REL - - ld a, UI_TILE_HP_4 - ld [hl+], a - - ld a, b - sub a, 4 - ld b, a - jp z, @done - jp c, @done ; no more hp to draw - jr @full_loop REL - -@skip_full: - - ld a, UI_TILE_HP_1+1 - sub a, b - ld [hl+], a - -@done: - - ; clear the next index - ld a, UI_WINDOW_BACKGROUND - ld [hl+], a - - ret - - ; draws boss hp -ui_draw_enemy_hp: - ld de, UI_ENEMY_HP - ld hl, str_enemy - call puts - - ld hl, UI_ENEMY_HP+7 - ld a, HP_MAX ; TODO: load real hp - ld b, a - jp ui_draw_hp - - ; draws current score -ui_draw_score: - ret - - ; draws continues -ui_draw_continues: ret diff --git a/src/update.s b/src/update.s index 01044c7..800bc85 100644 --- a/src/update.s +++ b/src/update.s @@ -5,48 +5,23 @@ update_game: ; tick rng every frame call rand - call video_map_adjust_scroll + ; clear oam + ; TODO: only clear used OAM + call shadow_oam_clear - call player_draw call player_update + call player_draw - call actor_update_all + call enemy_update - ; clear oam - call shadow_oam_clear_rest - ; update map - ld a, [map_routine] - ld l, a - ld a, [map_routine+1] - ld h, a - call_hl - - call update_anim_timer + ; TODO: update map routine ret - ; updates the global animation timer - ; and the animation frame -update_anim_timer: - ld a, [animation_timer] - inc a - and a, 0x1F ; max timer - ld [animation_timer], a - ; bail if no overflow - ret nz - -@tick_frame: - ld a, [animation_frame] - xor a, 1 - ld [animation_frame], a - ret new_game: - ld a, HP_MAX - ld [player_hp_max], a - - ld de, l_main_menu + ld de, l1 call map_load ld hl, update_game @@ -71,8 +46,6 @@ update: ld a, [game_state+1] ld h, a call_hl - - call dbg_update ret diff --git a/src/video.s b/src/video.s index f226a18..1900c0d 100644 --- a/src/video.s +++ b/src/video.s @@ -19,8 +19,6 @@ vblank: ; get inputs call poll_inputs - - call video_map_perform_scroll ; dma previous frame's oam call OAMDMAFN @@ -33,146 +31,17 @@ vblank: @skip_rest: pop_all ret - - ; scrolls if the flag is set - ; loads a new map row and sets the scroll - ; timer -video_map_perform_scroll: - ld a, [scroll_timer] - cp a, MAP_ROW_H-1 - ret nz - - xor a, a - ld [scroll_timer], a - - call map_advance_row - - ret - - ; adjusts the scroll slowly 1 pixel each frame - ; until the timer reaches 0 -video_map_adjust_scroll: - ld a, [game_flags] - and a, GPF_SCROLL - ret z - - ; unset flag - ld a, [game_flags] - and a, ~GPF_SCROLL & 0xFF - ld [game_flags], a - - ld a, [scroll_timer] - inc a - ld [scroll_timer], a - - ld a, [scroll_y] - sub a, SCROLL_ADJUST_STEP - ld [scroll_y], a - - call scroll_up_adjust - ret - - ; adjusts all actors and rectangles positions - ; when a scroll occurs -scroll_up_adjust: - ; only adjust enemies - ; do not adjust projectiles or player here - ld b, ACTS_ENEMY - ld hl, actors_enemy - -@act_loop: - push hl - - ld de, act_pos_y - add hl, de - ld a, [hl] - add a, SCROLL_ADJUST_STEP - ld [hl+], a ; hl = page y pos hi - - ; check if off-screen - ; do not despawn if -16 - cp a, -16 & 0xFF - jr nc, @no_act_despawn REL - - pop de - push de - push af - cp a, 0x70 - call nc, actor_despawn - pop af - -@no_act_despawn: - pop hl - push hl - - ; adjust actor rectangle position - ld de, act_rect+r_pos_y - add hl, de - ld a, [hl] - add a, SCROLL_ADJUST_STEP - ld [hl], a - - pop hl - - dec b - ld de, act_size - add hl, de - jr nz, @act_loop REL - - - ; adjust player - - ld a, [player+act_pos_y] - add a, SCROLL_ADJUST_STEP - ld [player+act_pos_y], a - - ld a, [player+act_rect+r_pos_y] - add a, SCROLL_ADJUST_STEP - ld [player+act_rect+r_pos_y], a - - ; adjust rectangles - ld b, RECT_MAX - ld hl, rectangles - -@rect_loop: - push hl - - ld de, r_pos_y - add hl, de - - ld a, [hl] - add a, SCROLL_ADJUST_STEP - ld [hl+], a - ; hl = r_pos_x - - ; rectangles never despawn - ; unless cleared with mo_rect_clear -@no_rect_despawn: - - pop hl - dec b - ld de, r_size - add hl, de - jr nz, @rect_loop REL - - ; adjust tmp rect - ; (just in case we missed a vblank) - ld a, [tmp_rect+r_pos_y] - add a, SCROLL_ADJUST_STEP - ld [tmp_rect+r_pos_y], a - - ret ; writes scroll to scroll registers - ; only call during blank + ; only call during blank scroll_write: - ld a, [scroll_y] - ld [RSCY], a + ld a, [scroll_y] + ld [RSCY], a - ld a, [scroll_x] - ld [RSCX], a + ld a, [scroll_x] + ld [RSCX], a + ret - ret ; swaps the current tilebank by setting/unsetting ; LCDC_TILE_BANK @@ -287,85 +156,6 @@ video_wait_n_frames: or a, c jr nz, video_wait_n_frames REL ret - - ; sets BGP | $1 - ; and then waits - ; inputs: - ; $1: BGP -#macro video_fade_set_bgp - ld a, [RBGP] - and a, $1 - ld [RBGP], a - - ; wait for 5 frames - ld bc, 0x4 - call video_wait_n_frames -#endmacro - - ; fades out the background - ; interrupts must be enabled - ; preserved all registers - ; disables window - ; fades away from current RBGP -video_fade_out: - push_all - - ; disable winodw - ld a, [RLCD] - and a, ~LCDF_WINDOWON & 0xFF - ld [RLCD], a - - video_fade_set_bgp 0b11111111 - video_fade_set_bgp 0b11111100 - video_fade_set_bgp 0b11110000 - video_fade_set_bgp 0b11000000 - video_fade_set_bgp 0b00000000 - - call disableinterrutpts - pop_all - ret - - - - ; fades the background in - ; sets RBGP to BGP - ; interrupts must be enabled - ; preserved all registers - ; enables window - ; inputs: - ; a: new palette -video_fade_in: - push_all - - call enableinterrupts - - ; disable winodw - ld a, [RLCD] - and a, ~LCDF_WINDOWON & 0xFF - ld [RLCD], a - - ; wait a few frames - call next_vblank_wait - call next_vblank_wait - call next_vblank_wait - call next_vblank_wait - call next_vblank_wait - call next_vblank_wait - call next_vblank_wait - - ; re-enable window - ld a, [RLCD] - or a, LCDF_WINDOWON - ld [RLCD], a - - - pop_all - ; push all saved new palette value - ; so we can use it here - ld [RBGP], a - ret -#undefine video_fade_set_bgp - ; loads tilesets diff --git a/src/wram.s b/src/wram.s index aa3f9ef..d767394 100644 --- a/src/wram.s +++ b/src/wram.s @@ -65,78 +65,12 @@ animation_frame: .adv 1 ; seed must never be 0 srand: .adv 2 - ; if player y < next_scroll - ; advance if possible -player_next_scroll_y: .adv 1 - -player_hp_max: .adv 1 -player_shoot_delay: .adv 1 - -; y/x sub pixel movement for player -player_sub_pixel_y: .adv 1 -player_sub_pixel_x: .adv 1 - - ; current player weapon -player_curr_weapon: .adv 1 player: .adv act_size -; actor table should follow player! -actors: -actors_enemy: .adv act_size * ACTS_ENEMY -actors_enemy_projectiles: .adv act_size * ACTS_ENEMY_PROJECTILES -actors_player_projectiles: .adv act_size * ACTS_PLAYER_PROJECTILES - -map_objs: .adv mo_size * MAP_OBJ_MAX - -rectangles: .adv r_size * RECT_MAX - - ; temporary rectangle used for collision checks - ; during movement -tmp_rect: .adv r_size -tmp_rect_mask: .adv 1 - - ; temporary points - ; has enough space for 4 points - ; store pre-calculated points here for collision checking -tmp_rect_points: .adv 8 - - ; temporary actor direction mask -tmp_act_direction: .adv 1 - - ; current row that is being drawn -map_curr_row: .adv 1 - ; current pattern to be drawn -map_curr_pat: .adv 2 +enemy: .adv act_size ; current map ptr map: .adv 2 - ; ptr to the next map object - ; that may be loaded -map_curr_obj: .adv 2 - - ; current bg pointer to write to -map_scrn_ptr: .adv 2 - - ; map update routine - ; can be set by map object -map_routine: .adv 2 - - ; map animation timer - ; use for e.g. arrow indicating scroll is enabled again -map_anim_timer: .adv 1 - ; state data for map anim -map_anim_state: .adv 1 - ; custom data for map anim -map_anim_p0: .adv 1 - - ; current debug function -dbg_fn: .adv 1 - - ; selected debug rect -dbg_rect: .adv 2 - -dbg_delay: .adv 1 -