[Decompilation] [th01] Kikuri: Move all data to C land

5th PC-98 Touhou boss completely decompiled, 26 to go!

Part of P0200, funded by Yanga.
This commit is contained in:
nmlgc 2022-06-10 21:36:01 +02:00
parent dfd52513de
commit 0724d972de
3 changed files with 40 additions and 131 deletions

View File

@ -100,11 +100,17 @@ enum kikuri_hp_t {
PHASE_6_END_HP = 0,
};
// Global boss state that is defined here for some reason
// ------------------------------------------------------
Palette4 boss_palette;
// ------------------------------------------------------
// State that's suddenly no longer shared with other bosses
// --------------------------------------------------------
#define boss_phase kikuri_phase
extern int8_t boss_phase;
int8_t boss_phase;
// --------------------------------------------------------
// Entities
@ -115,14 +121,13 @@ static const int SOUL_CELS = 3;
static const int TEAR_COUNT = 10;
#define tear_anim_frame kikuri_tear_anim_frame
#define souls kikuri_souls
#define tears kikuri_tears
// Nonzero values are also used to indicate whether a given tear is alive.
extern int8_t tear_anim_frame[TEAR_COUNT];
int8_t tear_anim_frame[TEAR_COUNT];
extern CBossEntitySized<SOUL_W, SOUL_H> souls[SOUL_COUNT + 3];
extern CBossEntity tears[10];
CBossEntity souls_raw[SOUL_COUNT + 3];
CBossEntity tears[10];
#define souls reinterpret_cast<CBossEntitySized<SOUL_W, SOUL_H> *>(souls_raw)
#define kikuri_ent_load(tmp_i) { \
souls[0].load("tamasii.bos", 0); \
@ -175,8 +180,7 @@ enum kikuri_phase_4_subphase_t {
_kikuri_phase_4_subphase_t_FORCE_INT16 = 0x7FFF
};
#define pattern_state kikuri_pattern_state
extern union {
union {
int interval;
int speed_multiplied_by_8;
} pattern_state;
@ -513,13 +517,9 @@ inline void entrance_symmetric_line_1_to_0(
void near pattern_symmetric_spiral_from_disc(void)
{
#define angle pattern0_angle
#define drift pattern0_drift
#define distance pattern0_distance
extern unsigned char angle;
extern unsigned char drift;
extern pixel_t distance;
static unsigned char angle;
static unsigned char drift;
static pixel_t distance;
screen_x_t left;
screen_y_t top;
@ -549,10 +549,6 @@ void near pattern_symmetric_spiral_from_disc(void)
angle -= 0x08;
drift++;
}
#undef distance
#undef drift
#undef angle
}
void near pattern_spinning_aimed_rings(void)
@ -740,9 +736,7 @@ void near pattern_souls_single_aimed_pellet_and_move_diagonally(void)
int near pattern_4_spiral_along_disc(void)
{
#define angle pattern6_angle
extern unsigned char angle;
static unsigned char angle;
if(boss_phase_frame < 100) {
return 0;
@ -780,8 +774,6 @@ int near pattern_4_spiral_along_disc(void)
}
}
return 0;
#undef angle
}
int near pattern_single_lasers_from_left_eye(void)
@ -895,9 +887,7 @@ int near pattern_vertical_lasers_from_top(void)
// [shootout_lasers] would be indexed out of bounds otherwise.
static_assert(LASER_COUNT <= SHOOTOUT_LASER_COUNT);
#define random_range_x_half pattern9_random_range_x_half
extern pixel_t random_range_x_half;
static pixel_t random_range_x_half;
if(boss_phase_frame < KEYFRAME_START) {
return 3;
@ -935,28 +925,20 @@ int near pattern_vertical_lasers_from_top(void)
return 0;
}
return 3;
#undef random_range_x_half
}
void kikuri_main(void)
{
#define hit kikuri_hit
#define entrance_ring_radius_base kikuri_entrance_ring_radius_base
#define initial_hp_rendered kikuri_initial_hp_rendered
struct hack { unsigned char col[4]; }; // XXX
extern struct {
static struct {
bool16 invincible;
int invincibility_frame;
void update_and_render(const struct hack &flash_colors) {
void update_and_render(const unsigned char (&flash_colors)[4]) {
boss_hit_update_and_render(
invincibility_frame,
invincible,
boss_hp,
flash_colors.col,
flash_colors,
sizeof(flash_colors),
7000,
boss_nop,
@ -964,9 +946,9 @@ void kikuri_main(void)
);
}
} hit;
extern pixel_t entrance_ring_radius_base;
extern bool initial_hp_rendered;
extern struct {
static pixel_t entrance_ring_radius_base;
static bool initial_hp_rendered;
static struct {
union {
kikuri_phase_4_subphase_t subphase_4;
int phase_6_pattern;
@ -977,11 +959,10 @@ void kikuri_main(void)
boss_phase_frame++;
hit.invincibility_frame++;
}
} phase;
extern struct hack kikuri_invincibility_flash_colors;
} phase = { P4_SOUL_ACTIVATION, 0 };
int i;
struct hack flash_colors = kikuri_invincibility_flash_colors;
const unsigned char flash_colors[] = { 6, 11, 8, 2 };
// Entrance animation
if(boss_phase == 0) {

View File

@ -33,6 +33,8 @@ public:
char zero_3;
unsigned char bos_slot;
CBossEntity();
// Even Turbo C++ 4.0J implements copy constructors for trivially
// constructible types via an equivalent of memcpy() by default. This
// constructor downgrades that to dumb single-member assignment, and is
@ -296,10 +298,14 @@ public:
// Despite CBossEntity's own width and height fields, ZUN still likes to
// statically hardcode the intended sprite sizes when calculating offsets
// within a .BOS sprite. Since bosses either declare their own instances or
// #define more readable names for each instance of [boss_entities], we might
// as well use the opportunity to lift up these static sizes into the type
// system, and avoid the need for per-boss boilerplate coordinate functions.
// within a .BOS sprite. Since bosses #define more readable names for each
// instance of [boss_entities], we might as well use the opportunity to lift up
// these static sizes into the type system, and avoid the need for per-boss
// boilerplate coordinate functions.
//
// (Due to CBossEntity unfortunately having a non-inlined default constructor,
// we can't ever directly declare instance of this template without emitting
// another constructor for this class.)
template <pixel_t W, pixel_t H> struct CBossEntitySized : public CBossEntity {
screen_x_t cur_center_x(void) const {
return (cur_left + (W / 2));

View File

@ -67,7 +67,6 @@ main_29 group main_29_TEXT, main_29__TEXT
main_31 group main_31_TEXT, main_31__TEXT
main_32 group main_32_TEXT, main_32__TEXT
main_33 group main_33_TEXT, main_33__TEXT
main_34 group main_34_TEXT, main_34__TEXT
; ===========================================================================
@ -5086,7 +5085,7 @@ sub_17041 proc far
CBossEntity__ctor boss_entity_3
CBossEntity__ctor boss_entity_4
push seg main_21
push offset sub_17096
push offset @CBossEntity@$bctr$qv
push 5
pushd 5
push size CBossEntity
@ -5102,8 +5101,8 @@ sub_17041 endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_17096 proc far
public @CBossEntity@$bctr$qv
@CBossEntity@$bctr$qv proc far
arg_0 = dword ptr 6
@ -5131,7 +5130,7 @@ loc_170C3:
mov ax, word ptr [bp+arg_0]
pop bp
retf
sub_17096 endp
@CBossEntity@$bctr$qv endp
main_21__TEXT ends
@ -14707,41 +14706,6 @@ main_34_TEXT segment byte public 'CODE' use16
extern @kikuri_main$qv:proc
main_34_TEXT ends
main_34__TEXT segment byte public 'CODE' use16
assume cs:main_34
;org 4
assume es:nothing, ss:nothing, ds:_DATA, fs:nothing, gs:nothing
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_24DFF proc far
push bp
mov bp, sp
push seg main_21
push offset sub_17096
push 5
pushd 5
push size CBossEntity
push ds
push offset _kikuri_souls
call @_vector_new_$qnvuiuluie ; _vector_new_(void *,uint,ulong,uint,...)
push seg main_21
push offset sub_17096
push 5
pushd KIKURI_TEAR_COUNT
push size CBossEntity
push ds
push offset _kikuri_tears
call @_vector_new_$qnvuiuluie ; _vector_new_(void *,uint,ulong,uint,...)
add sp, 20h
pop bp
retf
sub_24DFF endp
main_34__TEXT ends
; ===========================================================================
; Segment type: Pure code
@ -15321,12 +15285,6 @@ aBoss1_bos db 'boss1.bos',0
aBoss1_2_bos db 'boss1_2.bos',0
aBoss1_3_bos db 'boss1_3.bos',0
aBoss1_grp_0 db 'boss1.grp',0
public _phase
_phase label word
dw 0 ; ax
dw 0 ; phase_6_pattern
public _kikuri_invincibility_flash_color
_kikuri_invincibility_flash_color db 6, 11, 8, 2
extern _game_cleared:byte
extern _unused_boss_stage_flag:word
extern _pellet_destroy_score_delta:word
@ -15343,9 +15301,6 @@ _INIT_ segment word public 'INITDATA' use16
db 1
db 20h
dd sub_21819
db 1
db 20h
dd sub_24DFF
_INIT_ ends
.data?
@ -15619,39 +15574,6 @@ speed_3A385 dw ?
angle_3A387 db ?
byte_3A388 db ?
point_3A389 Point <?>
db ?
public _boss_palette, _kikuri_phase
_boss_palette palette_t <?>
_kikuri_phase db ?
KIKURI_TEAR_COUNT = 10
public _kikuri_tear_anim_frame, _kikuri_souls, _kikuri_tears
_kikuri_tear_anim_frame db KIKURI_TEAR_COUNT dup(?)
_kikuri_souls CBossEntity 5 dup (<?>)
_kikuri_tears CBossEntity 10 dup (<?>)
public _kikuri_pattern_state
_kikuri_pattern_state dw ?
public _pattern0_angle, _pattern0_drift, _pattern0_distance
_pattern0_angle db ?
_pattern0_drift db ?
_pattern0_distance dw ?
public _pattern6_angle
_pattern6_angle db ?
public _pattern9_random_range_x_half
_pattern9_random_range_x_half dw ?
public _kikuri_hit
public _kikuri_entrance_ring_radius_base, _kikuri_initial_hp_rendered
_kikuri_hit label byte
dw ? ; invincible
dw ? ; invincibility_frame
_kikuri_entrance_ring_radius_base dw ?
_kikuri_initial_hp_rendered db ?
extern _boss_hp:word
extern _boss_phase_frame:word
extern _boss_phase:byte