2019-09-14 14:41:16 +00:00
|
|
|
|
/* ReC98
|
|
|
|
|
* -----
|
|
|
|
|
* Include file for TH05
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "ReC98.h"
|
2019-09-15 17:36:17 +00:00
|
|
|
|
#include "th04/shared.hpp"
|
[Decompilation] [th05] Stage setup
"Yeah, let's do this real quick, how can this possibly be hard, it's
just MOVs and a few function calls"…
…except that these MOVs access quite a lot of data, which we now all
have to declare in the C world, hooray.
Once it came to midbosses and bosses, I just turned them into C structs
after all. Despite what I said in 260edd8… after all, the ASM world
doesn't care about the representation in the C world, so they don't
necessarily have to be the same.
Since these structs can't contain everything related to midbosses and
bosses (really, why did all those variables have to be spread out like
this, ZUN?), it also made for a nice occasion to continue the "stuff"
naming scheme, describing "an obviously incomplete collection of
variables related to a thing", first seen in 160d4eb.
Also, PROCDESC apparently is the only syntactically correct option to
declare an extern near proc?
Also, that `boss_phase_timed_out` variable only needs to be here
already because TCC enforces word alignment for the .data segment…
yeah, it's technically not related to this commit, but why waste time
working around it if we can just include that one variable.
Completes P0030, funded by zorg.
2019-09-15 18:14:00 +00:00
|
|
|
|
|
2019-09-16 11:01:53 +00:00
|
|
|
|
/// Formats
|
|
|
|
|
/// -------
|
|
|
|
|
bb_seg_t pascal near bb_load(const char far *fn);
|
|
|
|
|
/// -------
|
|
|
|
|
|
2019-10-13 18:52:53 +00:00
|
|
|
|
/// Player
|
|
|
|
|
/// ------
|
|
|
|
|
// Shots
|
|
|
|
|
// -----
|
2019-10-14 20:30:54 +00:00
|
|
|
|
// Shot types
|
|
|
|
|
#define ST_NORMAL 0
|
|
|
|
|
#define ST_HOMING 1
|
|
|
|
|
#define ST_MISSILE_LEFT 2
|
|
|
|
|
#define ST_MISSILE_RIGHT 3
|
|
|
|
|
#define ST_MISSILE_STRAIGHT 4
|
|
|
|
|
|
2019-10-13 18:52:53 +00:00
|
|
|
|
// Shot cycle bitflags
|
|
|
|
|
#define SC_1X 0x8 // Triggered 1× per cycle
|
|
|
|
|
#define SC_2X 0x2 // Triggered 2× per cycle
|
|
|
|
|
#define SC_3X 0x1 // Triggered 3× per cycle
|
|
|
|
|
#define SC_6X 0x4 // Triggered 6× per cycle
|
|
|
|
|
|
|
|
|
|
// Returns the current shot cycle, and prepares everything for more shots
|
|
|
|
|
// being added.
|
|
|
|
|
char pascal near shot_cycle_init(void);
|
2019-10-13 19:52:02 +00:00
|
|
|
|
|
|
|
|
|
// Common per-iteration data for shot type control functions.
|
|
|
|
|
// (Yeah, code generation mandated additions to [i] to be wrapped into
|
|
|
|
|
// functions, so why not bundle all of the rather intricate shot handling
|
|
|
|
|
// stuff as well.)
|
|
|
|
|
struct ShotAddIterator {
|
|
|
|
|
unsigned char angle;
|
|
|
|
|
unsigned char i;
|
|
|
|
|
|
|
|
|
|
ShotAddIterator(unsigned char count)
|
|
|
|
|
: i(count) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void add_secondary(unsigned char n) {
|
|
|
|
|
i += n;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned char next(void) {
|
|
|
|
|
return i -= 1;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Requires [cycle] to be defined in some way. (It's _AL in the original game,
|
|
|
|
|
// and I didn't want to pollute the namespace)
|
|
|
|
|
#define SHOT_FUNC_INIT(count, primary_cycle, secondary_cycle, secondary_offset_expr) \
|
|
|
|
|
shot_t near *shot; \
|
|
|
|
|
ShotAddIterator sai(count); \
|
|
|
|
|
\
|
|
|
|
|
cycle = shot_cycle_init(); \
|
|
|
|
|
if((cycle & (primary_cycle | secondary_cycle)) == 0) { \
|
|
|
|
|
return; \
|
|
|
|
|
} \
|
|
|
|
|
if(cycle & secondary_cycle) { \
|
|
|
|
|
sai.secondary_offset_expr; \
|
|
|
|
|
}
|
2019-10-13 18:52:53 +00:00
|
|
|
|
// -----
|
|
|
|
|
/// ------
|
|
|
|
|
|
[Decompilation] [th05] Stage setup
"Yeah, let's do this real quick, how can this possibly be hard, it's
just MOVs and a few function calls"…
…except that these MOVs access quite a lot of data, which we now all
have to declare in the C world, hooray.
Once it came to midbosses and bosses, I just turned them into C structs
after all. Despite what I said in 260edd8… after all, the ASM world
doesn't care about the representation in the C world, so they don't
necessarily have to be the same.
Since these structs can't contain everything related to midbosses and
bosses (really, why did all those variables have to be spread out like
this, ZUN?), it also made for a nice occasion to continue the "stuff"
naming scheme, describing "an obviously incomplete collection of
variables related to a thing", first seen in 160d4eb.
Also, PROCDESC apparently is the only syntactically correct option to
declare an extern near proc?
Also, that `boss_phase_timed_out` variable only needs to be here
already because TCC enforces word alignment for the .data segment…
yeah, it's technically not related to this commit, but why waste time
working around it if we can just include that one variable.
Completes P0030, funded by zorg.
2019-09-15 18:14:00 +00:00
|
|
|
|
/// Stages
|
|
|
|
|
/// ------
|
|
|
|
|
void pascal near stage2_update(void);
|
|
|
|
|
void pascal near stage2_invalidate(void);
|
|
|
|
|
/// ------
|
|
|
|
|
|
|
|
|
|
/// Midbosses
|
|
|
|
|
/// ---------
|
|
|
|
|
MIDBOSS_DEC(1);
|
|
|
|
|
MIDBOSS_DEC(2);
|
|
|
|
|
MIDBOSS_DEC(3);
|
|
|
|
|
MIDBOSS_DEC(4);
|
|
|
|
|
MIDBOSS_DEC(5);
|
|
|
|
|
MIDBOSS_DEC(x);
|
|
|
|
|
/// ---------
|
|
|
|
|
|
|
|
|
|
/// Bosses
|
|
|
|
|
/// ------
|
2019-09-16 12:07:37 +00:00
|
|
|
|
// Callbacks
|
|
|
|
|
extern nearfunc_t_near boss_custombullets_render;
|
|
|
|
|
|
[Decompilation] [th05] Stage setup
"Yeah, let's do this real quick, how can this possibly be hard, it's
just MOVs and a few function calls"…
…except that these MOVs access quite a lot of data, which we now all
have to declare in the C world, hooray.
Once it came to midbosses and bosses, I just turned them into C structs
after all. Despite what I said in 260edd8… after all, the ASM world
doesn't care about the representation in the C world, so they don't
necessarily have to be the same.
Since these structs can't contain everything related to midbosses and
bosses (really, why did all those variables have to be spread out like
this, ZUN?), it also made for a nice occasion to continue the "stuff"
naming scheme, describing "an obviously incomplete collection of
variables related to a thing", first seen in 160d4eb.
Also, PROCDESC apparently is the only syntactically correct option to
declare an extern near proc?
Also, that `boss_phase_timed_out` variable only needs to be here
already because TCC enforces word alignment for the .data segment…
yeah, it's technically not related to this commit, but why waste time
working around it if we can just include that one variable.
Completes P0030, funded by zorg.
2019-09-15 18:14:00 +00:00
|
|
|
|
extern unsigned int boss_sprite_left;
|
|
|
|
|
extern unsigned int boss_sprite_right;
|
|
|
|
|
extern unsigned int boss_sprite_stay;
|
|
|
|
|
|
|
|
|
|
extern boss_stuff_t boss2;
|
|
|
|
|
|
|
|
|
|
BOSS_DEC(sara);
|
|
|
|
|
BOSS_DEC(louise);
|
|
|
|
|
BOSS_DEC(alice);
|
|
|
|
|
|
|
|
|
|
BOSS_DEC(mai_yuki);
|
|
|
|
|
// Pointing to the same address as `boss2`! Might not be possible anymore once
|
|
|
|
|
// that variable has to be moved to a C++ translation unit...
|
|
|
|
|
extern boss_stuff_t yuki;
|
|
|
|
|
|
|
|
|
|
BOSS_DEC(yumeko);
|
|
|
|
|
extern unsigned char yumeko_interval_phase4;
|
|
|
|
|
extern unsigned char yumeko_interval_phase7;
|
|
|
|
|
|
|
|
|
|
BOSS_DEC(shinki);
|
|
|
|
|
BOSS_DEC(exalice);
|
2019-09-15 17:36:17 +00:00
|
|
|
|
/// ------
|