mirror of https://github.com/nmlgc/ReC98.git
[Maintenance] [th05] Minimize #includes for the shot type translation units
Since a few annoying alignment bytes suggested more translation units
than previously expected, using many small headers has proved to be
better than one big shared TH04/TH05 header file. Or should we *really*
pepper the code with lots of `#pragma codestring`? 😛
And in case we have multiple translation units which all #include the
same set of headers, we'll just go with situational shared headers,
using a common prefix.
Part of P0062, funded by Touhou Patch Center.
This commit is contained in:
parent
c5b07b746e
commit
765eae82e8
|
@ -1,2 +1,7 @@
|
|||
uint16_t pascal near randring1_next16(void);
|
||||
uint16_t pascal near randring1_next16_and(uint16_t mask);
|
||||
|
||||
inline char randring_angle(char random_range, char offset)
|
||||
{
|
||||
return randring1_next16_and(random_range) + offset;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
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;
|
|
@ -0,0 +1,52 @@
|
|||
// 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
|
||||
);
|
||||
|
||||
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);
|
|
@ -8,26 +8,8 @@
|
|||
/// Math
|
||||
/// ----
|
||||
#include "th03/math/subpixel.hpp"
|
||||
|
||||
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;
|
||||
|
||||
#include "th04/math/motion.hpp"
|
||||
#include "th03/math/randring.h"
|
||||
|
||||
inline char randring_angle(char random_range, char offset)
|
||||
{
|
||||
return randring1_next16_and(random_range) + offset;
|
||||
}
|
||||
/// ----
|
||||
|
||||
/// Rank
|
||||
|
@ -52,62 +34,6 @@ int pascal far select_for_rank(
|
|||
/// Player
|
||||
/// ------
|
||||
#include "th04/player/player.h"
|
||||
|
||||
// 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
|
||||
);
|
||||
|
||||
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);
|
||||
// -----
|
||||
/// ------
|
||||
|
||||
/// Stages
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
/* ReC98
|
||||
* -----
|
||||
* Shared #includes for the shot type control translation units
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "platform.h"
|
||||
#include "th03/math/subpixel.hpp"
|
||||
#include "th03/math/randring.h"
|
||||
#include "th04/math/motion.hpp"
|
||||
#include "th04/player/player.h"
|
||||
#include "th05/player/shot.hpp"
|
|
@ -6,8 +6,7 @@
|
|||
#pragma codeseg main_01_TEXT
|
||||
|
||||
extern "C" {
|
||||
#include "th05/th05.hpp"
|
||||
#include "th05/player/shot.h"
|
||||
#include "th05/i_shot.hpp"
|
||||
#define cycle _AL
|
||||
|
||||
#define STAR_DISTANCE (16)
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
#pragma codeseg main_01_TEXT
|
||||
|
||||
extern "C" {
|
||||
#include "th05/th05.hpp"
|
||||
#include "th05/player/shot.h"
|
||||
#include "th05/i_shot.hpp"
|
||||
#define cycle _AL
|
||||
|
||||
void pascal near shot_mima_l2(void)
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#pragma codeseg main_01_TEXT
|
||||
|
||||
extern "C" {
|
||||
#include "th05/th05.hpp"
|
||||
#include "th05/i_shot.hpp"
|
||||
#define cycle _AL
|
||||
|
||||
#define YUUKA_INNER_L4 \
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
// We *really* want to fit those on a line...
|
||||
#define OPT_L shot->from_option_l()
|
||||
#define OPT_R shot->from_option_r()
|
||||
#define MISSILE_L shot->type = ST_MISSILE_LEFT
|
||||
#define MISSILE_R shot->type = ST_MISSILE_RIGHT
|
||||
#define MISSILE_S shot->type = ST_MISSILE_STRAIGHT
|
||||
|
||||
#define VELOCITY_X(screen_x) shot->pos.velocity.x = screen_x;
|
||||
#define VELOCITY_Y(screen_y) shot->pos.velocity.y = screen_y;
|
||||
|
||||
#define VELOCITY_XY(screen_x, screen_y) \
|
||||
VELOCITY_X(screen_x); \
|
||||
VELOCITY_Y(screen_y);
|
||||
|
||||
#define VELOCITY_YX(screen_y, screen_x) \
|
||||
VELOCITY_Y(screen_y); \
|
||||
VELOCITY_X(screen_x);
|
|
@ -0,0 +1,72 @@
|
|||
#include "th04/player/shot.hpp"
|
||||
|
||||
// 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
|
||||
|
||||
// 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);
|
||||
|
||||
// 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; \
|
||||
}
|
||||
// -----
|
||||
|
||||
// We *really* want to fit those on a line...
|
||||
#define OPT_L shot->from_option_l()
|
||||
#define OPT_R shot->from_option_r()
|
||||
#define MISSILE_L shot->type = ST_MISSILE_LEFT
|
||||
#define MISSILE_R shot->type = ST_MISSILE_RIGHT
|
||||
#define MISSILE_S shot->type = ST_MISSILE_STRAIGHT
|
||||
|
||||
#define VELOCITY_X(screen_x) shot->pos.velocity.x = screen_x;
|
||||
#define VELOCITY_Y(screen_y) shot->pos.velocity.y = screen_y;
|
||||
|
||||
#define VELOCITY_XY(screen_x, screen_y) \
|
||||
VELOCITY_X(screen_x); \
|
||||
VELOCITY_Y(screen_y);
|
||||
|
||||
#define VELOCITY_YX(screen_y, screen_x) \
|
||||
VELOCITY_Y(screen_y); \
|
||||
VELOCITY_X(screen_x);
|
|
@ -11,64 +11,6 @@
|
|||
bb_seg_t pascal near bb_load(const char far *fn);
|
||||
/// -------
|
||||
|
||||
/// Player
|
||||
/// ------
|
||||
// Shots
|
||||
// -----
|
||||
// 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
|
||||
|
||||
// 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);
|
||||
|
||||
// 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; \
|
||||
}
|
||||
// -----
|
||||
/// ------
|
||||
|
||||
/// Stages
|
||||
/// ------
|
||||
void pascal near stage2_update(void);
|
||||
|
|
Loading…
Reference in New Issue