mirror of https://github.com/nmlgc/ReC98.git
[Decompilation] [th01] Pellets: Spawn functions
Completes P0100, funded by Yanga.
This commit is contained in:
parent
8f33b9717c
commit
ceb81db49c
|
@ -1,6 +1,7 @@
|
||||||
#include "th01/sprites/pellet.h"
|
#include "th01/sprites/pellet.h"
|
||||||
#include "th01/math/subpixel.hpp"
|
#include "th01/math/subpixel.hpp"
|
||||||
#include "th01/math/vector.hpp"
|
#include "th01/math/vector.hpp"
|
||||||
|
#include "th01/main/vars.hpp"
|
||||||
#include "th01/main/bullet/pellet.hpp"
|
#include "th01/main/bullet/pellet.hpp"
|
||||||
#include "th01/main/playfld.hpp"
|
#include "th01/main/playfld.hpp"
|
||||||
#include "th01/main/player/player.hpp"
|
#include "th01/main/player/player.hpp"
|
||||||
|
@ -21,6 +22,172 @@
|
||||||
pellet_t near *pellet_cur;
|
pellet_t near *pellet_cur;
|
||||||
/// -------
|
/// -------
|
||||||
|
|
||||||
|
// Sets the velocity for pellet #[i] in the given [pattern]. Returns true if
|
||||||
|
// this was the last pellet for this pattern.
|
||||||
|
bool16 pattern_velocity_set(
|
||||||
|
Subpixel &ret_x,
|
||||||
|
Subpixel &ret_y,
|
||||||
|
pellet_pattern_t pattern,
|
||||||
|
subpixel_t speed,
|
||||||
|
int &i,
|
||||||
|
int pellet_left,
|
||||||
|
int pellet_top
|
||||||
|
);
|
||||||
|
|
||||||
|
inline subpixel_t base_speed_for_rank(void)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
(static_cast<int>(rank) == RANK_EASY) ? to_sp(0.0f) :
|
||||||
|
(static_cast<int>(rank) == RANK_NORMAL) ? to_sp(0.375f) :
|
||||||
|
(static_cast<int>(rank) == RANK_HARD) ? to_sp(0.75f) :
|
||||||
|
to_sp(1.125f);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define speed_set(speed) \
|
||||||
|
speed += base_speed_for_rank(); \
|
||||||
|
speed += ((resident->pellet_speed * speed) / to_sp(2.5f)); \
|
||||||
|
if(speed < to_sp(1.0f)) { \
|
||||||
|
speed = to_sp(1.0f); \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define pellet_init(pellet, left, top, pattern) \
|
||||||
|
pellet->decay_frame = 0; \
|
||||||
|
pellet->cur_left.v = TO_SP(left); \
|
||||||
|
pellet->cur_top = top; \
|
||||||
|
pellet->cloud_left = left; \
|
||||||
|
pellet->cloud_top = top; \
|
||||||
|
if(spawn_with_cloud) { \
|
||||||
|
pellet->cloud_frame = 1; \
|
||||||
|
} else { \
|
||||||
|
pellet->moving = true; \
|
||||||
|
} \
|
||||||
|
pellet->from_pattern = pattern;
|
||||||
|
|
||||||
|
void CPellets::add_pattern(
|
||||||
|
int left, int top, pellet_pattern_t pattern, subpixel_t speed
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int pattern_i = 0;
|
||||||
|
int pattern_done;
|
||||||
|
Subpixel vel_x;
|
||||||
|
Subpixel vel_y;
|
||||||
|
|
||||||
|
// Should be >=, but yeah, it's just an inconsequential oversight.
|
||||||
|
if(alive_count > PELLET_COUNT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(
|
||||||
|
(left >= PLAYFIELD_RIGHT) ||
|
||||||
|
(top < (PLAYFIELD_TOP - PELLET_H)) ||
|
||||||
|
(left < (PLAYFIELD_LEFT - PELLET_W)) ||
|
||||||
|
(top > PLAYFIELD_BOTTOM)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
speed_set(speed);
|
||||||
|
|
||||||
|
#define p pellet_cur
|
||||||
|
p = iteration_start();
|
||||||
|
for(i = 0; i < PELLET_COUNT; i++, p++) {
|
||||||
|
if(p->moving == true) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(p->cloud_frame) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pellet_init(p, left, top, pattern);
|
||||||
|
p->prev_left.v = -1;
|
||||||
|
p->age = 0;
|
||||||
|
alive_count++;
|
||||||
|
/* TODO: Replace with the decompiled call
|
||||||
|
* pattern_done = pattern_velocity_set(
|
||||||
|
vel_x, vel_y, pattern, speed, pattern_i, left, top
|
||||||
|
);
|
||||||
|
* once that function is part of this translation unit */
|
||||||
|
__asm {
|
||||||
|
push top;
|
||||||
|
db 0x57; // PUSH DI
|
||||||
|
push ss;
|
||||||
|
lea ax, pattern_i;
|
||||||
|
push ax;
|
||||||
|
db 0x56; // PUSH SI
|
||||||
|
push pattern;
|
||||||
|
push ss;
|
||||||
|
lea ax, vel_y;
|
||||||
|
push ax
|
||||||
|
push ss;
|
||||||
|
lea ax, vel_x;
|
||||||
|
push ax;
|
||||||
|
push cs;
|
||||||
|
call near ptr pattern_velocity_set;
|
||||||
|
add sp, 0x14;
|
||||||
|
}
|
||||||
|
pattern_done = _AX;
|
||||||
|
p->velocity.x.v = vel_x.v;
|
||||||
|
p->velocity.y.v = vel_y.v;
|
||||||
|
if(pattern_done == true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#undef p
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPellets::add_single(
|
||||||
|
int left,
|
||||||
|
int top,
|
||||||
|
int angle,
|
||||||
|
subpixel_t speed_base,
|
||||||
|
pellet_motion_t motion_type,
|
||||||
|
subpixel_t speed_for_motion_fixed,
|
||||||
|
int spin_center_x,
|
||||||
|
int spin_center_y
|
||||||
|
)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
Subpixel vel_x;
|
||||||
|
Subpixel vel_y;
|
||||||
|
|
||||||
|
// Should be >=, but yeah, it's just an inconsequential oversight.
|
||||||
|
if(alive_count > PELLET_COUNT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
speed_set(speed_base);
|
||||||
|
|
||||||
|
#define p pellet_cur
|
||||||
|
p = iteration_start();
|
||||||
|
for(i = 0; i < PELLET_COUNT; i++, p++) {
|
||||||
|
if(p->moving == true) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if(p->cloud_frame) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pellet_init(p, left, top, 0);
|
||||||
|
p->motion_type = motion_type;
|
||||||
|
p->prev_left.v = -1;
|
||||||
|
p->age = 0;
|
||||||
|
alive_count++;
|
||||||
|
p->spin_center.x.v = TO_SP(spin_center_x);
|
||||||
|
p->spin_center.y = spin_center_y;
|
||||||
|
if(motion_type == PM_SPIN) {
|
||||||
|
vector2(vel_x.v, vel_y.v, speed_for_motion_fixed, angle);
|
||||||
|
p->spin_velocity.x.v = vel_x.v;
|
||||||
|
p->spin_velocity.y.v = vel_y.v;
|
||||||
|
p->angle = iatan2(
|
||||||
|
(p->cur_top - p->spin_center.y),
|
||||||
|
(p->cur_left - p->spin_center.x)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
vector2(vel_x.v, vel_y.v, speed_base, angle);
|
||||||
|
p->speed.v = speed_for_motion_fixed;
|
||||||
|
p->velocity.x.v = vel_x.v;
|
||||||
|
p->velocity.y.v = vel_y.v;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#undef p
|
||||||
|
}
|
||||||
|
|
||||||
void CPellets::motion_type_apply_for_cur(void)
|
void CPellets::motion_type_apply_for_cur(void)
|
||||||
{
|
{
|
||||||
#define p pellet_cur
|
#define p pellet_cur
|
||||||
|
|
|
@ -103,9 +103,39 @@ public:
|
||||||
bool spawn_with_cloud;
|
bool spawn_with_cloud;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
pellet_t near* iteration_start(void) {
|
||||||
|
return static_cast<pellet_t near *>(pellets);
|
||||||
|
}
|
||||||
|
|
||||||
// Updates the velocity of the currently iterated pellet, depending on its
|
// Updates the velocity of the currently iterated pellet, depending on its
|
||||||
// [motion_type].
|
// [motion_type].
|
||||||
void motion_type_apply_for_cur(void);
|
void motion_type_apply_for_cur(void);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Spawns a number of bullets according to the given [pattern], with their
|
||||||
|
// corresponding velocities, at (left, top). [speed_base] is tuned
|
||||||
|
// according to the currently played difficulty and the resident
|
||||||
|
// [pellet_speed]. The [motion_type] for the new pellets is PM_NORMAL.
|
||||||
|
void add_pattern(
|
||||||
|
int left, int top, pellet_pattern_t pattern, subpixel_t speed_base
|
||||||
|
);
|
||||||
|
|
||||||
|
// Spawns a single new pellet with a customizable [motion_type].
|
||||||
|
// [speed_base] is tuned according to the currently played difficulty and
|
||||||
|
// the resident [pellet_speed]; [speed_for_motion_fixed] is never tuned.
|
||||||
|
//
|
||||||
|
// [spin_center_x] and [spin_center_y] are only used with PM_SPIN,
|
||||||
|
// while [speed_base] is *ignored* for PM_SPIN.
|
||||||
|
void add_single(
|
||||||
|
int left,
|
||||||
|
int top,
|
||||||
|
int angle,
|
||||||
|
subpixel_t speed_base,
|
||||||
|
pellet_motion_t motion_type,
|
||||||
|
subpixel_t speed_for_motion_fixed = to_sp(0.0f),
|
||||||
|
int spin_center_x = 0,
|
||||||
|
int spin_center_y = 0
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Globals
|
/// Globals
|
||||||
|
|
|
@ -5,3 +5,5 @@ extern bool bgm_mode;
|
||||||
extern char bombs;
|
extern char bombs;
|
||||||
extern char credit_bombs;
|
extern char credit_bombs;
|
||||||
extern char lives_extra;
|
extern char lives_extra;
|
||||||
|
|
||||||
|
extern resident_t far *resident;
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
#pragma option -Z
|
#pragma option -Z
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include "ReC98.h"
|
#include "th01/th01.h"
|
||||||
#include "th01/hardware/graph.h"
|
#include "th01/ranks.h"
|
||||||
|
|
||||||
#include "th01/main/bullet/pellet.cpp"
|
#include "th01/main/bullet/pellet.cpp"
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
|
|
||||||
typedef int subpixel_t;
|
typedef int subpixel_t;
|
||||||
|
|
||||||
|
#define TO_SP(v) \
|
||||||
|
(v << 4)
|
||||||
|
|
||||||
inline subpixel_t to_sp(float screen_v) {
|
inline subpixel_t to_sp(float screen_v) {
|
||||||
return static_cast<subpixel_t>(screen_v * 16.0f);
|
return static_cast<subpixel_t>(screen_v * 16.0f);
|
||||||
}
|
}
|
||||||
|
@ -13,6 +16,10 @@ public:
|
||||||
// arithmetic with a local variable...
|
// arithmetic with a local variable...
|
||||||
T v;
|
T v;
|
||||||
|
|
||||||
|
subpixel_t operator -(const SubpixelBase<T> &other) {
|
||||||
|
return (this->v - other.v);
|
||||||
|
}
|
||||||
|
|
||||||
void operator +=(float screen_v) {
|
void operator +=(float screen_v) {
|
||||||
this->v += static_cast<T>(to_sp(screen_v));
|
this->v += static_cast<T>(to_sp(screen_v));
|
||||||
}
|
}
|
||||||
|
@ -26,7 +33,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator =(const T &screen_v) {
|
void operator =(const T &screen_v) {
|
||||||
v = (screen_v << 4);
|
v = TO_SP(screen_v);
|
||||||
}
|
}
|
||||||
|
|
||||||
T to_screen() const {
|
T to_screen() const {
|
||||||
|
|
|
@ -42,7 +42,7 @@ typedef struct {
|
||||||
char snd_need_init;
|
char snd_need_init;
|
||||||
char unused_2;
|
char unused_2;
|
||||||
char mode;
|
char mode;
|
||||||
int bullet_speed;
|
int pellet_speed;
|
||||||
long rand;
|
long rand;
|
||||||
long score;
|
long score;
|
||||||
long continues_total;
|
long continues_total;
|
||||||
|
|
647
th01_reiiden.asm
647
th01_reiiden.asm
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue