2019-09-15 17:36:17 +00:00
|
|
|
/* ReC98
|
|
|
|
* -----
|
|
|
|
* Types shared between TH04 and TH05
|
|
|
|
*/
|
|
|
|
|
2019-10-13 19:52:02 +00:00
|
|
|
#define DEFCONV pascal
|
|
|
|
|
2019-09-15 17:36:17 +00:00
|
|
|
/// Math
|
|
|
|
/// ----
|
2019-10-13 19:52:02 +00:00
|
|
|
typedef int subpixel_t;
|
|
|
|
|
|
|
|
inline subpixel_t to_sp(float screen_v) {
|
|
|
|
return static_cast<subpixel_t>(screen_v * 16.0f);
|
|
|
|
}
|
|
|
|
|
2019-09-15 17:36:17 +00:00
|
|
|
class Subpixel {
|
|
|
|
public:
|
2019-10-14 20:30:54 +00:00
|
|
|
// Code generation will require direct access to v, if performing
|
|
|
|
// arithmetic with a local variable...
|
|
|
|
subpixel_t v;
|
2019-09-15 17:36:17 +00:00
|
|
|
|
2019-10-13 19:52:02 +00:00
|
|
|
void operator +=(float screen_v) {
|
|
|
|
this->v += to_sp(screen_v);
|
|
|
|
}
|
|
|
|
|
|
|
|
void operator -=(float screen_v) {
|
|
|
|
this->v -= to_sp(screen_v);
|
|
|
|
}
|
|
|
|
|
|
|
|
void operator =(float screen_v) {
|
|
|
|
v = to_sp(screen_v);
|
2019-09-15 17:36:17 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct SPPoint {
|
|
|
|
Subpixel x, y;
|
|
|
|
|
|
|
|
void set(float screen_x, float screen_y) {
|
|
|
|
x = screen_x;
|
|
|
|
y = screen_y;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
SPPoint cur;
|
|
|
|
SPPoint prev;
|
|
|
|
SPPoint velocity;
|
|
|
|
|
|
|
|
void init(float screen_x, float screen_y) {
|
|
|
|
cur.x = screen_x;
|
|
|
|
prev.x = screen_x;
|
|
|
|
cur.y = screen_y;
|
|
|
|
prev.y = screen_y;
|
|
|
|
}
|
|
|
|
} motion_t;
|
2019-10-13 19:52:02 +00:00
|
|
|
|
2019-11-09 19:09:33 +00:00
|
|
|
// Vectors
|
|
|
|
// -------
|
|
|
|
int pascal near vector2_near(Point near *ret, unsigned char angle, int r);
|
|
|
|
// -------
|
|
|
|
|
2019-10-13 19:52:02 +00:00
|
|
|
#include "th03/math/randring.h"
|
|
|
|
|
|
|
|
inline char randring_angle(char random_range, char offset)
|
|
|
|
{
|
|
|
|
return randring1_next16_and(random_range) + offset;
|
|
|
|
}
|
2019-09-15 17:36:17 +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
|
|
|
/// Rank
|
|
|
|
/// ----
|
|
|
|
int pascal far select_for_rank(
|
|
|
|
int for_easy, int for_normal,
|
|
|
|
int for_hard, int for_lunatic
|
|
|
|
);
|
|
|
|
/// ----
|
|
|
|
|
2019-09-16 11:01:53 +00:00
|
|
|
/// Formats
|
|
|
|
/// -------
|
[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
|
|
|
#include "th03/formats/cdg.h"
|
2019-09-16 11:01:53 +00:00
|
|
|
#include "th04/formats/bb.h"
|
|
|
|
/// -------
|
[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-10-13 19:52:02 +00:00
|
|
|
/// Sound
|
|
|
|
/// -----
|
|
|
|
#include "th02/snd/snd.h"
|
|
|
|
/// -----
|
|
|
|
|
2019-10-06 12:25:54 +00:00
|
|
|
/// Player
|
|
|
|
/// ------
|
2019-10-07 19:51:11 +00:00
|
|
|
#include "th04/player/player.h"
|
|
|
|
|
2019-10-06 12:25:54 +00:00
|
|
|
// Shots
|
|
|
|
// -----
|
|
|
|
// Sets [velocity] to a vector with the given [angle] and a 12-pixel length.
|
|
|
|
//
|
|
|
|
// TH05 also insists on setting shot_t::angle via a ridiculous out-of-bounds
|
|
|
|
// access, and therefore *must* be called with [velocity] pointing inside a
|
|
|
|
// shot_t structure!
|
|
|
|
SPPoint pascal near shot_velocity_set(
|
|
|
|
SPPoint near* velocity, unsigned char angle
|
|
|
|
);
|
2019-10-13 19:52:02 +00:00
|
|
|
|
|
|
|
struct shot_t {
|
|
|
|
char flag;
|
|
|
|
char age;
|
|
|
|
motion_t pos;
|
|
|
|
// The displayed sprite changes between this one and
|
|
|
|
// [patnum_base + 1] every two frames.
|
|
|
|
#if GAME == 5
|
|
|
|
char patnum_base;
|
|
|
|
char type;
|
|
|
|
#else
|
|
|
|
int patnum_base;
|
|
|
|
#endif
|
|
|
|
char damage;
|
|
|
|
char angle; // Unused in TH04
|
|
|
|
|
|
|
|
void from_option_l(float offset = 0.0f) {
|
|
|
|
this->pos.cur.x -= PLAYER_OPTION_DISTANCE + offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
void from_option_r(float offset = 0.0f) {
|
|
|
|
this->pos.cur.x += PLAYER_OPTION_DISTANCE + offset;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_option_sprite() {
|
|
|
|
this->patnum_base = 22;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_option_sprite_and_damage(char damage) {
|
|
|
|
set_option_sprite();
|
|
|
|
this->damage = damage;
|
|
|
|
}
|
|
|
|
|
|
|
|
void set_random_angle_forwards(char random_range = 15, char offset = 184) {
|
|
|
|
shot_velocity_set(
|
|
|
|
(SPPoint near*)&this->pos.velocity,
|
|
|
|
randring_angle(random_range, offset)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
// Searches and returns the next free shot slot, or NULL if there are no more
|
|
|
|
// free ones.
|
|
|
|
shot_t near* pascal near shots_add(void);
|
2019-10-06 12:25:54 +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
|
|
|
|
/// ------
|
|
|
|
extern nearfunc_t_near stage_invalidate;
|
|
|
|
extern nearfunc_t_near stage_render;
|
|
|
|
/// ------
|
|
|
|
|
|
|
|
/// Midbosses
|
|
|
|
/// ---------
|
|
|
|
typedef struct {
|
|
|
|
motion_t pos;
|
|
|
|
unsigned int frames_until;
|
|
|
|
int hp;
|
|
|
|
unsigned char sprite;
|
|
|
|
unsigned char phase;
|
|
|
|
int phase_frame;
|
|
|
|
// Treated as a bool in TH04
|
|
|
|
unsigned char damage_this_frame;
|
|
|
|
unsigned char angle;
|
|
|
|
} midboss_stuff_t;
|
|
|
|
|
|
|
|
extern midboss_stuff_t midboss;
|
|
|
|
|
|
|
|
// Callbacks
|
|
|
|
extern farfunc_t_near midboss_update_func;
|
|
|
|
extern nearfunc_t_near midboss_render_func;
|
|
|
|
|
|
|
|
#define MIDBOSS_DEC(stage) \
|
|
|
|
void pascal far midboss##stage##_update(void); \
|
|
|
|
void pascal near midboss##stage##_render(void);
|
|
|
|
/// ---------
|
|
|
|
|
|
|
|
// Bosses
|
|
|
|
// ------
|
|
|
|
typedef struct {
|
|
|
|
motion_t pos;
|
|
|
|
int hp;
|
|
|
|
unsigned char sprite;
|
|
|
|
unsigned char phase;
|
|
|
|
int phase_frame;
|
|
|
|
unsigned char damage_this_frame;
|
|
|
|
unsigned char mode;
|
|
|
|
// Used for both movement and bullet angles.
|
|
|
|
unsigned char angle;
|
|
|
|
unsigned char mode_change;
|
|
|
|
int phase_end_hp;
|
|
|
|
} boss_stuff_t;
|
|
|
|
|
|
|
|
extern boss_stuff_t boss;
|
|
|
|
extern SPPoint boss_hitbox_radius;
|
|
|
|
|
|
|
|
// Callbacks
|
2019-09-16 12:07:37 +00:00
|
|
|
extern farfunc_t_near boss_update;
|
|
|
|
extern nearfunc_t_near boss_fg_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 farfunc_t_near boss_update_func;
|
|
|
|
extern nearfunc_t_near boss_backdrop_colorfill;
|
|
|
|
extern nearfunc_t_near boss_bg_render_func;
|
|
|
|
extern nearfunc_t_near boss_fg_render_func;
|
|
|
|
|
|
|
|
#define BOSS_DEC(name) \
|
|
|
|
void pascal far name##_update(void); \
|
|
|
|
void pascal near name##_bg_render(void); \
|
|
|
|
void pascal near name##_fg_render(void);
|
2019-09-16 12:07:37 +00:00
|
|
|
|
|
|
|
// Explosions
|
|
|
|
void pascal far explosions_small_reset(void);
|
[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-15 17:36:17 +00:00
|
|
|
/// Score
|
|
|
|
/// -----
|
2019-09-18 16:33:38 +00:00
|
|
|
#define score_delta SCORE_DELTA
|
2019-09-15 17:36:17 +00:00
|
|
|
extern unsigned long score_delta;
|
|
|
|
|
|
|
|
void pascal near score_update_and_render(void);
|
|
|
|
|
|
|
|
// Adds the entire score delta at once to the current score.
|
|
|
|
void pascal score_delta_commit(void);
|
|
|
|
/// -----
|