The new system allows defintion of tables.
Tables can be loaded and contain up to 3 objects.
-player_anim_header:
- anim_header 2, ANIM_HEAD_F_LOOP, 1, player_anim_table, NULL
-
player_anim_table:
- anim_ent 0x8C, 0x00, 0, 0
- anim_ent 0x8C, 0x00, 0, 0
+ anim_ent 0, 8, 0x8C, OAM_FXFLIP
+ anim_ent 0, 0, 0x8E, OAM_FXFLIP
+ anim_ent 0, 0, 0x00, 0
+ dw player_anim_table
+
+
+ ; translates tile to screen
+ ; inputs:
+ ; $1: Y/X offset
+ ; $2: register containing scroll
+ ; a: tile position
+#macro tile_to_scrn
+ mul16 a
+ add a, $1
+ sub a, $2
+#endmacro
+
+ ; performs no drawing
+unit_nop_draw:
+ ldnull bc
+ ret
; calls unit's draw function
ld a, 8
ret
- ; draws the unit's tile
- ; based on the set oam tile
- ; and the currently set offset
- ; each actor has 2 tiles drawn here
- ; tile 1 is the selected tile
- ; tile 2 is the tile next (+1) to the selected tile
+ ; 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:
- push de
- ld hl, act_oam_tile
- add hl, de ; hl = tile
- ld a, [hl+]
+ ; 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 = anim talbe entry
- ld b, a ; base tile
- ld a, [hl+]
- ld c, a ; flags
- ld a, [hl] ; a = tile offset
- add a, b ; base tile + offset
- ld b, a ; b = real tile
-
- ld a, c ; c = oam flags for offset call
- call get_left_tile_offset1
- push bc
- call unit_generic_draw
-
- ; draw same tile again
- pop bc
- pop de
- push de
- inc b
- inc b ; b+=2
- ld a, c ; a = flags
- call get_left_tile_offset2
- call unit_generic_draw
- pop de
-
- ldnull bc
+ call unit_draw_obj
+ call unit_draw_obj
+ call unit_draw_obj
+
+ ; load next anim table
+ ld hl, act_anim_table
+ ld a, [bc]
+ ld [hl+], a
+ inc bc
+ ld a, [bc]
+ ld [hl], a
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
; can be used for animations or other relevant timers
; state switching may change this value.
.de act_rt_timer, 1
-
- ; sub-tile drawing vars
- ; during this animation the actor is already technically in its new
- ; location. the real location offset can be calculated with
- ; the st_time in the actor if sub tile enable is set
- ; ab0de000: direction bits (a == 1 -> up; b == 1 -> down; d == 1 -> left; e == 1 -> right)
- ; 00c00000: c: sub tile enabled
-.de act_rt_sub_tile, 1
-
+
; stats1
.de act_level, 1
.de act_hp, stat_size
; returns:
; bc: null
.de act_draw, 2
-
- ; act_oam_tile + flags
- ; if using generic draw:
- ; 2 tiles are used
- ; tile 1 is the tile specified here
- ; tile 2 is the tile following tile 1
- ; flags are used for both tiles
- ; optional:
- ; tile + flags may be a pointer to a
- ; tile table. This can be implemented as needed
-.de act_oam_tile, 1
-.de act_oam_flags, 1
-
- ; offset from the currently selected tile
- ; animations work by applying this offset
- ; to the selected base tile
- ; this allows runtime configuration
- ; of the frames
- ; e.g. the offset could be switched to 0/2 based
- ; on the current frame count
- ; to make an idel animation
- ; note: the offset should always be an even number
- ; due to the use of 8x16 objects
-.de act_rt_oam_tile_offset, 1
-
+.de act_anim_table, 2
.de act_size, 0
; actor save game data
.se 0
.de action_st_action_ptr, 2
.de action_size, 0
-
-; animation header struct
-.se 0
- ; how many objects can an animation draw
- ; valid values are 1, 2, 3, 4
-.de anim_header_objs, 1
-.de anim_header_flags, 1
-.de anim_header_frames, 1
-.de anim_header_table, 1
-.de anim_header_next, 2 ; next animation if not looping
-
-; animation header flags
-.se 1
- ; loop the animation
- ; if set to 0 return to next animation
-.de ANIM_HEAD_F_LOOP, 1
-
; animation entry struct
+; an animation table is *always*
+; 3 entries followed by a next ptr
+; 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_x_offset, 1
-.de anim_ent_y_offset, 1
+.de anim_ent_size, 0
; special text commands
; defines actor meta data call for actor
; inputs:
; $1: draw call
- ; $2: default tiles
- ; $3: default oam flags
+ ; $2: animation header ptr
#macro act_def_meta
dw $1
- .db $2
- .db $3
- ; tile offset
- .db 0
+ dw $2
#endmacro
; define an actor without state
.db 0, 0, 0
; act_rt_collided_with
dw 0
- .db 0 ; act_rt_sub_tile
; act_rt_action_dat1/2
.db 0, 0
ld b, a
#endmacro
- ; animation header
- ; inputs:
- ; $1: obj count (1, 2, 3, 4)
- ; $2: flags
- ; $3: number of frames
- ; $4: animation table
- ; $5: next animation
-#macro anim_header
- .db $1
- .db $2
- .db $3
- dw $4
- dw $5
-#endmacro
-
; animation entry
; inputs:
- ; $1: tile
- ; $2: oam flags
- ; $3: x offset
- ; $4: y offset
+ ; $1: y offset
+ ; $2: x offset
+ ; $3: tile
+ ; $4: oam flags
#macro anim_ent
.db $1
.db $2
#include "map.s"
#include "math.s"
+#include "animation.s"
#include "roompatterns.s"
#include "mapgen.s"
#include "state.s"
#include "shoot.s"
#include "action_menu.s"
#include "select_menu.s"
-#include "animation.s"
; fill bank
.fill 0xFF, 0x4000 - $
cp a, 0
ret nz
- push de
- ld hl, act_oam_flags
- add hl, de
- ld a, [hl]
- or a, OAM_FXFLIP
- ld [hl], a
- pop de
-
; check if the player is currently
; on a convered tile or not
push de
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, 0x8C, OAM_FPRIO
+ act_def_meta player_draw, player_anim_table
st_unit_player_update:
st_def 0x00, unit_player_update, st_unit_player_update
jr nz, @loop REL
ret
-
- ; adjust an object's position
- ; based on sub-tile state
- ; inputs:
- ; de: actor
- ; hl: object in shadow oam
-unit_generic_draw_adjust_subtile:
- ; check if actor is in sub-tile mode
- push hl
- push de
-
- ld hl, act_rt_sub_tile
- add hl, de
- ld a, [hl] ; a = rt_sub_tile value
- pop de ; de = actor st_time
- pop hl ; hl = obj
- ld b, a ; b = rt_sub_tile value
- cp a, 0
- ; if this value is 0 we are not moving
- jp z, @done
-
- ld a, [de] ; load timer
- div8 a ; a = timer/8 giving us a pixel offset
- ld c, a ; c = timer/8
-
- ; test bit 7 for up
- bit 7, b
- jr z, @not_up REL
- ld a, [hl] ; a = obj y
- add a, c ; a += offset
- ld [hl], a
-@not_up:
-
- ; test bit 6 for down
- bit 6, b
- jr z, @not_down REL
- ld a, [hl]
- sub a, c ; a -= offset
- ld [hl], a
-@not_down:
-
- inc hl ; hl = x position
-
- ; test bit 4 for left
- bit 4, b
- jr z, @not_left REL
- ld a, [hl]
- add a, c ; a += offset
- ld [hl], a
-@not_left:
-
- ; test bit 3 for right
- bit 3, b
- jr z, @not_right REL
- ld a, [hl]
- sub a, c ; a += offset
- ld [hl], a
-@not_right:
-
-@done:
-
- ret
-
- ; translates tile to screen
- ; inputs:
- ; $1: Y/X offset
- ; $2: register containing scroll
- ; a: tile position
-#macro tile_to_scrn
- mul16 a
- add a, $1
- sub a, $2
-#endmacro
-
- ; performs no drawing
-unit_nop_draw:
- ldnull bc
- ret
-
- ; draws any unit
- ; inputs:
- ; de: actor
- ; a: x-offset for tiles
- ; b: tile1
- ; c: flags
-unit_generic_draw:
-#define TMP_OAMFLAG_PRIO scratch
-#define TMP_X_OFFSET scratch+1
- ld [TMP_X_OFFSET], a ; save for later
-
- push de ; save actor
-
- xor a, a
- ld [TMP_OAMFLAG_PRIO], a
-
- push bc
-
- ld hl, act_pos_y
- add hl, de ; hl = act_pos_y
- push hl
-
- call load_scroll
- call load_unit_obj
-
- pop de ; de = act_pos_y
-
- ; set y pos
- ld a, [de]
- tile_to_scrn OBJ_OFF_Y, b
- ld [hl+], a
-
- ; set x pos
- inc de
- ld a, [de]
- tile_to_scrn OBJ_OFF_X, c
- ld c, a
- ld a, [TMP_X_OFFSET]
- add a, c
- ld [hl+], a
-
- pop bc ; bc = inputs again
-
- ; set tile
- ld a, b
- ld [hl+], a
-
-
- ; set flags
- ld a, [TMP_OAMFLAG_PRIO]
- or a, c
- ld [hl], a
-
- dec hl
- dec hl
- dec hl ; object - 3 go back to start
- pop de
- call unit_generic_draw_adjust_subtile
-
- ldnull bc
- ret
-#undefine TMP_OAMFLAG_PRIO
-#undefine TMP_X_OFFSET
; sets player turn taken flag
unit_set_player_turn_taken:
ret
#undefine scratch_loop_i
- ; sets st_unit_delay_to_active speed to unit's move speed
- ; (STAT_MAX-stat_calc_speed)
- ; inputs:
- ; de: actor
- ; a: mask for rt_sub_tile
- ; rt_subtile |= a
-unit_set_delay_to_active_speed:
- push de
- ld hl, act_rt_sub_tile
- add hl, de ; hl = ptr to sub_tile
-
- ld b, a
- ld a, [hl]
- or a, b ; apply the mask
- ld [hl], a ; store new value
-
- ; get movement speed
- pop de
- call stat_calc_speed
- ld de, st_unit_delay_to_active ; de == st_time
- ; this overwrites the wait time
- ; by calculating the movement speed
- ; and subtracting it from STAT_MAX
- ld b, a ; b = current speed
- ld a, STAT_MAX
- ; a - b
- sub a, b
- ld [de], a ; delay timer is now speed
- ret
; moves a unit up
; moves are aborted
; actor initiative based on tile flags
; actor position
unit_try_move_up:
- ; enable subtile up
- ld a, 0b10100000
- push de
- call unit_set_delay_to_active_speed
- pop de
-
; y - 1
unit_test_collision dec b, CF_COLLISION
ret
unit_try_move_down:
- ; enable subtile down
- push de
- ld a, 0b01100000
- call unit_set_delay_to_active_speed
- pop de
-
; y + 1
unit_test_collision inc b, CF_COLLISION
ret
unit_try_move_left:
- ; enable subtile left
- push de
- ld a, 0b00110000
- call unit_set_delay_to_active_speed
- pop de
-
; x - 1
unit_test_collision dec c, CF_COLLISION
ret
unit_try_move_right:
- ; enable subtile right
- push de
- ld a, 0b00101000
- call unit_set_delay_to_active_speed
- pop de
-
; x + 1
unit_test_collision inc c, CF_COLLISION
; returns:
; bc: new state
unit_switch_to_active:
- push de
- ld hl, act_rt_sub_tile
- add hl, de
- xor a, a
- ld [hl], a ; clear sub_tile values
- pop de
-
ld hl, act_st_active
add hl, de ; hl = st_active ptr
ld a, [hl+]
+unit_demo_guard_anim_table:
+ anim_ent 0, 0, 0x88, 0
+ anim_ent 0, 8, 0x8A, 0
+ anim_ent 0, 0, 0x00, 0
+ dw unit_demo_guard_anim_table
+
+unit_demo_dog_anim_table:
+ anim_ent 0, 0, 0x90, 0
+ anim_ent 0, 8, 0x92, 0
+ anim_ent 0, 0, 0x00, 0
+ dw unit_demo_dog_anim_table
+
+unit_demo_hazmat_anim_table:
+ anim_ent 0, 0, 0x94, 0
+ anim_ent 0, 8, 0x96, 0
+ anim_ent 0, 0, 0x00, 0
+ dw unit_demo_hazmat_anim_table
unit_demo_1_init:
ldnull bc
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, 0x88, OAM_FPRIO
-
-unit_demo_agent:
- st_def 0x00, unit_demo_1_init, st_unit_demo_1_cpu_update
- act_def ACT_T_DEMO_1, 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, 0x8C, OAM_FPRIO
+ 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_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, 0x90, OAM_FPRIO
+ act_def_meta unit_draw, unit_demo_dog_anim_table
unit_demo_hazmat:
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, 0x94, OAM_FPRIO
+ act_def_meta unit_draw, unit_demo_hazmat_anim_table
st_unit_demo_1_cpu_update: