[Reverse-engineering] [th03] Player structure

Completes P0071, funded by KirbyComment and -Tom-.
This commit is contained in:
nmlgc 2020-01-28 21:50:58 +01:00
parent 245fc55b63
commit 4bb04abb6f
9 changed files with 547 additions and 484 deletions

View File

@ -1,4 +1,4 @@
SPPoint8 struc
db ? ; x
db ? ; y
x8 db ?
y8 db ?
SPPoint8 ends

View File

@ -0,0 +1,30 @@
public GAUGE_AVAIL_ADD
gauge_avail_add proc near
@@charge = byte ptr 4
@@pid = byte ptr 6
push bp
mov bp, sp
push si
mov al, [bp+@@pid]
mov ah, 0
shl ax, 7
add ax, offset _players
mov si, ax
cmp [si+player_t.hyper_active], 0
jnz short @@ret
cmp [si+gauge_avail], GAUGE_MAX
jnb short @@ret
mov al, [bp+@@charge]
mov ah, 0
add [si+gauge_avail], ax
cmp [si+gauge_avail], GAUGE_MAX
jbe short @@ret
mov [si+gauge_avail], GAUGE_MAX
@@ret:
pop si
pop bp
retn 4
gauge_avail_add endp

View File

@ -1,14 +0,0 @@
#define PLAYER_COUNT 2
// Charge Shots
// ------------
typedef void (far pascal *near chargeshot_add_func_t)(
Subpixel center_x, Subpixel center_y
);
extern farfunc_t_near chargeshot_update[PLAYER_COUNT];
extern farfunc_t_near chargeshot_render[PLAYER_COUNT];
// ------------
extern unsigned char pid_current;
extern unsigned char pid_other;

98
th03/player/player.hpp Normal file
View File

@ -0,0 +1,98 @@
#define PLAYER_COUNT 2
#define HALFHEARTS_MAX 10
#define ROUND_START_INVINCIBILITY_FRAMES 50
#define MISS_INVINCIBILITY_FRAMES 110
#define MISS_DAMAGE_MAX 6
#define KNOCKBACK_FRAMES 64
#define SPELL_AUTOFIRE_FRAMES 128
#define CHARGE_AT_AVAIL_RING_SIZE 64
// Gauge
// -----
#define GAUGE_MAX (0xFF << 4)
typedef uint16_t gauge_t;
typedef uint8_t gauge_perbyte_t;
void pascal near gauge_avail_add(unsigned char pid, unsigned char charge);
// -----
// Charge Shots
// ------------
typedef void (far pascal *near chargeshot_add_func_t)(
Subpixel center_x, Subpixel center_y
);
extern farfunc_t_near chargeshot_update[PLAYER_COUNT];
extern farfunc_t_near chargeshot_render[PLAYER_COUNT];
// ------------
typedef struct {
SPPoint center;
bool is_hit;
uint8_t unused_1;
unsigned char invincibility_time;
char halfhearts;
// (<value from playchars_t> + 1) << 1 | <alternative palette flag>
unsigned char playchar_paletted;
speed_t speed;
shot_mode_t shot_mode;
unsigned char patnum_movement;
unsigned char patnum_glow;
unsigned char knockback_time;
unsigned char move_lock_time;
unsigned char knockback_angle;
unsigned char knockback_length;
bool knockback_active;
bool is_cpu;
unsigned char cpu_dodge_strategy; // unused
unsigned char gauge_charge_speed;
gauge_t gauge_charged;
gauge_t gauge_avail;
unsigned char cpu_charge_at_avail_ring_p;
unsigned char bombs;
// Set to [playchar_paletted] when active, for some reason...
unsigned char hyper_active;
unsigned char lose_anim_time;
input_t human_movement_last;
shot_active_t shot_active;
unsigned char spell_ready_frames;
// A CPU player will charge up a gauge attack once ([gauge_avail] >> 4)
// has reached the (random) value at [cpu_charge_at_avail_ring_p].
gauge_perbyte_t cpu_charge_at_avail_ring[CHARGE_AT_AVAIL_RING_SIZE];
nearfunc_t_near hyper; // Either hyper_standby() or [hyper_func].
nearfunc_t_near hyper_func;
chargeshot_add_func_t chargeshot_add;
unsigned char rounds_won;
uint8_t unused_2;
// A CPU player will focus on dodging bullets while [cpu_frame] remains
// smaller than this value.
unsigned int cpu_safety_frames;
unsigned int combo_bonus_max;
unsigned char combo_hits_max;
unsigned char miss_damage_next;
unsigned int cpu_frame;
unsigned char gauge_attacks_fired;
unsigned char boss_attacks_fired;
unsigned char boss_attacks_reversed;
unsigned char boss_panics_fired;
uint8_t padding[6];
} player_t;
extern unsigned char pid_current;
extern unsigned char pid_other;

View File

@ -0,0 +1,63 @@
HALFHEARTS_MAX = 10
ROUND_START_INVINCIBILITY_FRAMES = 50
MISS_INVINCIBILITY_FRAMES = 110
MISS_DAMAGE_MAX = 6
KNOCKBACK_FRAMES = 64
SPELL_AUTOFIRE_FRAMES = 128
CHARGE_AT_AVAIL_RING_SIZE = 64
GAUGE_MAX = (0FFh shl 4)
player_t struc
center Point ?
is_hit db ?
PLAYER_unused_1 db ?
invincibility_time db ?
halfhearts db ?
playchar_paletted db ?
speed speed_t <?>
shot_mode db ?
patnum_movement db ?
patnum_glow db ?
knockback_time db ?
move_lock_time db ?
knockback_angle db ?
knockback_length db ?
knockback_active db ?
is_cpu db ?
cpu_dodge_strategy db ?
gauge_charge_speed db ?
gauge_charged dw ?
gauge_avail dw ?
cpu_charge_at_avail_ring_p db ?
bombs db ?
hyper_active db ?
lose_anim_time db ?
human_movement_last dw ?
shot_active db ?
spell_ready_frames db ?
cpu_charge_at_avail_ring db CHARGE_AT_AVAIL_RING_SIZE dup(?)
hyper dw ?
hyper_func dw ?
chargeshot_add dd ?
rounds_won db ?
align 2
cpu_safety_frames dw ?
combo_bonus_max dw ?
combo_hits_max db ?
miss_damage_next db ?
cpu_frame dw ?
gauge_attacks_fired db ?
boss_attacks_fired db ?
boss_attacks_reversed db ?
boss_panics_fired db ?
align 16
player_t ends
public _p1, _p2, _players
_players label player_t
_p1 player_t <?>
_p2 player_t <?>

8
th03/player/win[bss].asm Normal file
View File

@ -0,0 +1,8 @@
public _win_combo_hits_max
public _win_gauge_attacks_fired, _win_boss_attacks_fired
public _win_boss_attacks_reversed, _win_boss_panics_fired
_win_combo_hits_max db ?
_win_gauge_attacks_fired db ?
_win_boss_attacks_fired db ?
_win_boss_attacks_reversed db ?
_win_boss_panics_fired db ?

View File

@ -2,12 +2,15 @@
#define PLAYFIELD_COUNT 2
#define PLAYFIELD_W 288
#define PLAYFIELD_H 368
// For both playfields, in every direction. (CSS style!)
// The clipped SPRITE16 display functions rely on this being at least 16!
#define PLAYFIELD_BORDER 16
#define PLAYFIELD_X PLAYFIELD_BORDER
#define PLAYFIELD_Y PLAYFIELD_BORDER
#define PLAYFIELD_VRAM_H (PLAYFIELD_H / 2)
#define PLAYFIELD_W_BORDERED (PLAYFIELD_BORDER + PLAYFIELD_W + PLAYFIELD_BORDER)
#define PLAYFIELD1_CLIP_LEFT 0
#define PLAYFIELD1_CLIP_RIGHT (PLAYFIELD1_CLIP_LEFT + PLAYFIELD_W_BORDERED - 1)

View File

@ -1,9 +1,12 @@
PLAYFIELD_COUNT = 2
PLAYFIELD_W = 288
PLAYFIELD_H = 368
PLAYFIELD_BORDER = 16
PLAYFIELD_X = PLAYFIELD_BORDER
PLAYFIELD_Y = PLAYFIELD_BORDER
PLAYFIELD_VRAM_H = (PLAYFIELD_H / 2)
PLAYFIELD_W_BORDERED = (PLAYFIELD_BORDER + PLAYFIELD_W + PLAYFIELD_BORDER)
PLAYFIELD1_CLIP_LEFT = 0
PLAYFIELD1_CLIP_RIGHT = (PLAYFIELD1_CLIP_LEFT + PLAYFIELD_W_BORDERED - 1)

File diff suppressed because it is too large Load Diff