mirror of https://github.com/nmlgc/ReC98.git
[Decompilation] [th04/th05] Bullets: Update function
… (24 + (difficulty * 8) + rank) in TH04, and (42 + (difficulty * 8)) in TH05. Also, TH05 only doesn't have TH04's bullet zap animation because ZUN didn't consistently use constants… Completes P0151, funded by Blue Bolt and -Tom-.
This commit is contained in:
parent
0d7fc5af77
commit
4d24ca53bd
|
@ -138,7 +138,7 @@ bin\th04\op.exe: bin\th04\op.obj th04\m_char.cpp bin\th01\vplanset.obj bin\frmde
|
|||
$**
|
||||
|
|
||||
|
||||
bin\th04\main.exe: bin\th04\main.obj bin\th04\slowdown.obj bin\th04\player_p.obj bin\th04\scoreupd.obj th04\main011.cpp bin\th04\cfg_lres.obj bin\th01\vplanset.obj bin\th03\vector2.obj bin\frmdely1.obj bin\hfliplut.obj th04\mpn_free.cpp bin\th04\input_w.obj th04\mpn_l_i.cpp bin\th04\vector.obj bin\th04\snd_pmdr.obj bin\th04\snd_mmdr.obj bin\th04\snd_kaja.obj bin\th04\snd_mode.obj bin\th04\snd_load.obj bin\th04\cdg_put.obj bin\th04\exit.obj bin\th04\initmain.obj bin\th04\cdg_p_na.obj bin\th04\cdg_p_pr.obj bin\th04\input_s.obj bin\th04\snd_se_r.obj bin\th04\snd_se.obj bin\th04\cdg_load.obj th04\gather.cpp bin\th04\scrolly3.obj bin\th04\motion_3.obj th04\main032.cpp
|
||||
bin\th04\main.exe: bin\th04\main.obj bin\th04\slowdown.obj bin\th04\player_p.obj bin\th04\scoreupd.obj th04\main011.cpp bin\th04\cfg_lres.obj bin\th01\vplanset.obj bin\th03\vector2.obj bin\frmdely1.obj bin\hfliplut.obj th04\mpn_free.cpp bin\th04\input_w.obj th04\mpn_l_i.cpp bin\th04\vector.obj bin\th04\snd_pmdr.obj bin\th04\snd_mmdr.obj bin\th04\snd_kaja.obj bin\th04\snd_mode.obj bin\th04\snd_load.obj bin\th04\cdg_put.obj bin\th04\exit.obj bin\th04\initmain.obj bin\th04\cdg_p_na.obj bin\th04\cdg_p_pr.obj bin\th04\input_s.obj bin\th04\snd_se_r.obj bin\th04\snd_se.obj bin\th04\cdg_load.obj th04\gather.cpp bin\th04\scrolly3.obj bin\th04\motion_3.obj th04\bullet_u.cpp th04\main032.cpp
|
||||
$(CC) $(CFLAGS) $(LARGE_LFLAGS) -DGAME=4 -DBINARY='M' -3 -Z -nbin\th04\ -eMAIN.EXE @&&|
|
||||
$**
|
||||
|
|
||||
|
@ -161,7 +161,7 @@ bin\th05\op.exe: th05\op010.cpp bin\th05\op.obj th05\op011.cpp th05\m_char.cpp b
|
|||
$**
|
||||
|
|
||||
|
||||
bin\th05\main.exe: bin\th05\main.obj bin\th04\slowdown.obj bin\th05\cfg_lres.obj th05\main010.cpp th05\main011.cpp th05\p_common.cpp th05\p_reimu.cpp th05\p_marisa.cpp th05\p_mima.cpp th05\p_yuuka.cpp bin\th05\player.obj bin\th05\hud_bar.obj bin\th05\scoreupd.obj th05\main012.cpp bin\th04\player_p.obj th05\main013.cpp bin\th03\vector2.obj bin\hfliplut.obj bin\th04\snd_pmdr.obj bin\th04\snd_mmdr.obj bin\th04\snd_mode.obj bin\th05\bullet.obj bin\th04\cdg_p_na.obj bin\th04\snd_se_r.obj bin\th04\snd_se.obj bin\th05\cdg_put.obj bin\th04\exit.obj bin\th05\vector.obj bin\th05\snd_load.obj bin\th05\snd_kaja.obj bin\th05\initmain.obj bin\th05\input_s.obj bin\th05\inp_h_w.obj bin\th05\frmdelay.obj bin\th04\cdg_load.obj bin\th04\scrolly3.obj bin\th04\motion_3.obj th05\main031.cpp th05\gather.cpp th05\main032.cpp th05\main034.cpp th05\main035.cpp
|
||||
bin\th05\main.exe: bin\th05\main.obj bin\th04\slowdown.obj bin\th05\cfg_lres.obj th05\main010.cpp th05\main011.cpp th05\p_common.cpp th05\p_reimu.cpp th05\p_marisa.cpp th05\p_mima.cpp th05\p_yuuka.cpp bin\th05\player.obj bin\th05\hud_bar.obj bin\th05\scoreupd.obj th05\main012.cpp bin\th04\player_p.obj th05\main013.cpp bin\th03\vector2.obj bin\hfliplut.obj bin\th04\snd_pmdr.obj bin\th04\snd_mmdr.obj bin\th04\snd_mode.obj bin\th05\bullet.obj bin\th04\cdg_p_na.obj bin\th04\snd_se_r.obj bin\th04\snd_se.obj bin\th05\cdg_put.obj bin\th04\exit.obj bin\th05\vector.obj bin\th05\snd_load.obj bin\th05\snd_kaja.obj bin\th05\initmain.obj bin\th05\input_s.obj bin\th05\inp_h_w.obj bin\th05\frmdelay.obj bin\th04\cdg_load.obj bin\th04\scrolly3.obj bin\th04\motion_3.obj th05\main031.cpp th05\gather.cpp th05\main032.cpp th05\bullet_u.cpp th05\main034.cpp th05\main035.cpp
|
||||
$(CC) $(CFLAGS) $(LARGE_LFLAGS) -3 -Z -DGAME=5 -DBINARY='M' -nbin\th05\ -eMAIN.EXE @&&|
|
||||
$**
|
||||
|
|
||||
|
|
|
@ -345,6 +345,22 @@ void foo(int i) {
|
|||
|
||||
## Flags
|
||||
|
||||
### `-G` (Generate for speed)
|
||||
|
||||
* Replaces
|
||||
|
||||
```asm
|
||||
ENTER <stack size>, 0
|
||||
```
|
||||
|
||||
with
|
||||
|
||||
```asm
|
||||
PUSH BP
|
||||
MOV BP, SP
|
||||
SUB SP, <stack size>
|
||||
```
|
||||
|
||||
### `-Z` (Suppress register reloads)
|
||||
|
||||
* The tracked contents of `ES` are reset after a conditional statement. If the
|
||||
|
|
|
@ -23,6 +23,24 @@
|
|||
#define overlap_xy_xywh_le_ge(x1, y1, x2, y2, w2, h2) \
|
||||
overlap_xy_ltrb_le_ge(x1, y1, x2, y2, (x2 + w2), (y2 + h2))
|
||||
|
||||
// Ugly, and should not exist, but generates one fewer instruction when used
|
||||
// with _AX and _DX register pseudovariables...
|
||||
#define overlap_offcenter_1d_inplace_fast(delta, dist_edge1, dist_edge2) ( \
|
||||
(unsigned int)((delta) += dist_edge1, delta) <= (dist_edge1 + dist_edge2) \
|
||||
)
|
||||
|
||||
#define overlap_offcenter_inplace_fast( \
|
||||
delta_x, delta_y, dist_to_left, dist_to_top, dist_to_right, dist_to_bottom \
|
||||
) ( \
|
||||
overlap_offcenter_1d_inplace_fast(delta_x, dist_to_left, dist_to_right) && \
|
||||
overlap_offcenter_1d_inplace_fast(delta_y, dist_to_top, dist_to_bottom) \
|
||||
)
|
||||
|
||||
#define overlap_wh_inplace_fast(delta_x, delta_y, w, h) \
|
||||
overlap_offcenter_inplace_fast( \
|
||||
delta_x, delta_y, (w / 2), (w / 2), (h / 2), (h / 2) \
|
||||
)
|
||||
|
||||
#define overlap_points_wh_fast(p1, p2, p1_w, p1_h) ( \
|
||||
((unsigned int)((p1.x - p2.x) + (p1_w / 2)) <= (p1_w)) && \
|
||||
((unsigned int)((p1.y - p2.y) + (p1_h / 2)) <= (p1_h)) \
|
||||
|
|
|
@ -24,11 +24,22 @@
|
|||
void far playfield_tram_wipe(void);
|
||||
#endif
|
||||
|
||||
#define playfield_encloses_yx_lt_ge(center_x, center_y, w, h) ( \
|
||||
/* Casting the center coordinate allows macro to easily be used with */ \
|
||||
/* the _AX and _DX pseudoregisters after motion_update(). */ \
|
||||
(static_cast<subpixel_t>(center_y) >= to_sp(0 - (h / 2))) && \
|
||||
(static_cast<subpixel_t>(center_y) < to_sp(PLAYFIELD_H + (h / 2))) && \
|
||||
(static_cast<subpixel_t>(center_x) >= to_sp(0 - (w / 2))) && \
|
||||
(static_cast<subpixel_t>(center_x) < to_sp(PLAYFIELD_W + (w / 2))) \
|
||||
)
|
||||
|
||||
#define playfield_encloses(center_x, center_y, w, h) ( \
|
||||
(center_x > to_sp(0 - (w / 2))) && \
|
||||
(center_x < to_sp(PLAYFIELD_W + (w / 2))) && \
|
||||
(center_y > to_sp(0 - (h / 2))) && \
|
||||
(center_y < to_sp(PLAYFIELD_H + (h / 2))) \
|
||||
/* Casting the center coordinate allows macro to easily be used with */ \
|
||||
/* the _AX and _DX pseudoregisters after motion_update(). */ \
|
||||
(static_cast<subpixel_t>(center_x) > to_sp(0 - (w / 2))) && \
|
||||
(static_cast<subpixel_t>(center_x) < to_sp(PLAYFIELD_W + (w / 2))) && \
|
||||
(static_cast<subpixel_t>(center_y) > to_sp(0 - (h / 2))) && \
|
||||
(static_cast<subpixel_t>(center_y) < to_sp(PLAYFIELD_H + (h / 2))) \
|
||||
)
|
||||
|
||||
#define playfield_encloses_point(center, w, h) \
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
#pragma option -zCmain_032_TEXT -zPmain_03
|
||||
#include "th04/main/bullet/update.cpp"
|
|
@ -433,6 +433,9 @@ bool near bullet_template_clip(void)
|
|||
{
|
||||
if(
|
||||
(bullet_clear_time > 0) &&
|
||||
// If a newly spawned bullet wouldn't fully decay during the remaining
|
||||
// time, let's simply not spawn it at all? This way, they don't award
|
||||
// points either.
|
||||
(bullet_clear_time <= (BMS_DECAY_FRAMES + 1))
|
||||
) {
|
||||
return true;
|
||||
|
|
|
@ -13,8 +13,9 @@
|
|||
/// ----------------
|
||||
/// Everything here needs to be kept in sync with the ASM versions in
|
||||
/// bullet.hpp!
|
||||
static const int BMS_DECAY_FRAMES_PER_CEL = 4;
|
||||
#define BSS_CLOUD_FRAMES (BULLET_CLOUD_CELS * 4)
|
||||
#define BMS_DECAY_FRAMES (BULLET_DECAY_CELS * 4)
|
||||
#define BMS_DECAY_FRAMES (BULLET_DECAY_CELS * BMS_DECAY_FRAMES_PER_CEL)
|
||||
|
||||
// Regular bullets with a given speed below BMS_SLOWDOWN_THRESHOLD are set to
|
||||
// BMS_SLOWDOWN. This fires them at BMS_SLOWDOWN_BASE_SPEED instead, and then
|
||||
|
@ -39,6 +40,8 @@ enum bullet_spawn_state_t {
|
|||
BSS_CLOUD_FORWARDS = 4,
|
||||
BSS_CLOUD_END = (BSS_CLOUD_FORWARDS + BSS_CLOUD_FRAMES),
|
||||
/// ------------------------
|
||||
|
||||
_bullet_spawn_state_t_FORCE_UINT8 = 0xFF
|
||||
};
|
||||
|
||||
enum bullet_move_state_t {
|
||||
|
@ -57,6 +60,8 @@ enum bullet_move_state_t {
|
|||
BMS_DECAY = 4,
|
||||
BMS_DECAY_END = (BMS_DECAY + BMS_DECAY_FRAMES),
|
||||
/// ----------------
|
||||
|
||||
_bullet_move_state_t_FORCE_UINT8 = 0xFF
|
||||
};
|
||||
|
||||
enum bullet_special_motion_t {
|
||||
|
@ -65,7 +70,7 @@ enum bullet_special_motion_t {
|
|||
|
||||
// Needs to be kept in sync with the ASM version in bullet.inc!
|
||||
struct bullet_t {
|
||||
char flag;
|
||||
unsigned char flag;
|
||||
char age;
|
||||
PlayfieldMotion pos;
|
||||
unsigned char from_group; // unused
|
||||
|
@ -75,12 +80,14 @@ struct bullet_t {
|
|||
bullet_spawn_state_t spawn_state;
|
||||
bullet_move_state_t move_state;
|
||||
bullet_special_motion_t special_motion;
|
||||
unsigned char speed_final;
|
||||
SubpixelLength8 speed_final;
|
||||
union {
|
||||
unsigned char slowdown_time; // with BMS_SLOWDOWN
|
||||
unsigned char turn_count; // with BMS_SPECIAL
|
||||
} ax;
|
||||
union {
|
||||
// Difference between [speed_final] and the BMS_SLOWDOWN_BASE_SPEED.
|
||||
// Always positive for BMS_SLOWDOWN bullets.
|
||||
unsigned char slowdown_speed_delta; // with BMS_SLOWDOWN
|
||||
unsigned char turn_angle; // with BMS_SPECIAL
|
||||
} dx;
|
||||
|
@ -113,6 +120,8 @@ int pascal near bullet_patnum_for_angle(int patnum_base, unsigned char angle);
|
|||
// Updates [bullet]'s patnum based on its current angle.
|
||||
void pascal near bullet_update_patnum(bullet_t near *bullet);
|
||||
|
||||
// Turns every 4th bullet into a point item when zapping bullets.
|
||||
extern bool bullet_zap_drop_point_items;
|
||||
#else
|
||||
# define PELLET_COUNT 240
|
||||
# define BULLET16_COUNT 200
|
||||
|
@ -120,9 +129,6 @@ void pascal near bullet_update_patnum(bullet_t near *bullet);
|
|||
// Returns the offset for a directional bullet sprite that shows the given
|
||||
// [angle].
|
||||
unsigned char pascal near bullet_patnum_for_angle(unsigned char angle);
|
||||
|
||||
// Turns every 4th bullet into a point item when zapping bullets.
|
||||
extern bool bullet_zap_drop_point_items;
|
||||
#endif
|
||||
|
||||
#define BULLET_COUNT (PELLET_COUNT + BULLET16_COUNT)
|
||||
|
@ -144,6 +150,7 @@ extern union {
|
|||
unsigned char frames; // doubles as the animation timer
|
||||
} bullet_zap;
|
||||
static const int BULLET_ZAP_FRAMES_PER_CEL = 4;
|
||||
// ZUN bug: Effectively 1 in TH05, see bullets_update() for the cause.
|
||||
static const int BULLET_ZAP_FRAMES = (
|
||||
BULLET_ZAP_CELS * BULLET_ZAP_FRAMES_PER_CEL
|
||||
);
|
||||
|
|
|
@ -1,6 +1,341 @@
|
|||
#pragma option -G
|
||||
|
||||
extern "C" {
|
||||
#include "platform.h"
|
||||
#include "pc98.h"
|
||||
#include "planar.h"
|
||||
#include "th01/math/overlap.hpp"
|
||||
#include "th01/math/subpixel.hpp"
|
||||
#include "th04/math/motion.hpp"
|
||||
#include "th04/math/vector.hpp"
|
||||
#include "th04/main/frames.h"
|
||||
#include "th04/main/scroll.hpp"
|
||||
#include "th04/main/playfld.hpp"
|
||||
#include "th04/main/playperf.hpp"
|
||||
#include "th04/main/rank.hpp"
|
||||
#include "th04/main/score.hpp"
|
||||
#include "th04/main/slowdown.hpp"
|
||||
#include "th04/main/spark.hpp"
|
||||
#include "th04/main/bullet/bullet.hpp"
|
||||
#include "th04/main/hud/hud.h"
|
||||
#include "th04/main/hud/popup.hpp"
|
||||
#include "th04/main/player/player.hpp"
|
||||
#include "th04/main/pointnum/pointnum.hpp"
|
||||
#include "th04/main/gather.hpp"
|
||||
|
||||
#if (GAME == 5)
|
||||
#include "th04/main/item/items.hpp"
|
||||
#include "th05/sprites/main_pat.h"
|
||||
|
||||
static const int SLOWDOWN_BULLET_THRESHOLD_UNUSED = 32;
|
||||
#else
|
||||
#include "th04/sprites/main_pat.h"
|
||||
|
||||
static const int SLOWDOWN_BULLET_THRESHOLD_UNUSED = 24;
|
||||
#endif
|
||||
|
||||
#pragma option -a2
|
||||
|
||||
void pascal near bullet_turn_x(bullet_t near &bullet)
|
||||
;
|
||||
void pascal near bullet_turn_y(bullet_t near &bullet)
|
||||
;
|
||||
|
||||
void pascal near bullet_update_special(bullet_t near &bullet);
|
||||
|
||||
#pragma option -G
|
||||
|
||||
void bullets_update(void)
|
||||
{
|
||||
int i;
|
||||
int bullets_seen = 0;
|
||||
#if (GAME == 5)
|
||||
pellet_clouds_render_count = 0;
|
||||
#endif
|
||||
pellets_render_count = 0;
|
||||
bullet_t near *bullet = &bullets[BULLET_COUNT - 1];
|
||||
|
||||
// Since we iterate over the bullet array backwards, we encounter the 16×16
|
||||
// bullets first.
|
||||
#define is_bullet16(i) \
|
||||
(i < BULLET16_COUNT)
|
||||
|
||||
#define is_pellet(i) \
|
||||
!is_bullet16(i)
|
||||
|
||||
if(bullet_zap.active == false) {
|
||||
for(i = 0; i < BULLET_COUNT; i++, bullet--) {
|
||||
if(bullet->flag == 0) {
|
||||
continue;
|
||||
}
|
||||
if(bullet->flag == 2) {
|
||||
bullet->flag = 0;
|
||||
continue;
|
||||
}
|
||||
bullets_seen++;
|
||||
if(bullet_clear_time) {
|
||||
if(bullet->move_state < BMS_DECAY) {
|
||||
bullet->move_state = BMS_DECAY;
|
||||
bullet->patnum = is_bullet16(i)
|
||||
? PAT_DECAY_BULLET16
|
||||
: PAT_DECAY_PELLET;
|
||||
|
||||
if(bullet->age != 0) {
|
||||
score_delta += 100;
|
||||
} else {
|
||||
score_delta += 10;
|
||||
}
|
||||
} else {
|
||||
reinterpret_cast<unsigned char &>(bullet->move_state)++;
|
||||
if(bullet->move_state >= BMS_DECAY_END) {
|
||||
bullet->pos.update_seg3();
|
||||
bullet->flag = 2;
|
||||
continue;
|
||||
}
|
||||
if((bullet->move_state % BMS_DECAY_FRAMES_PER_CEL) == 0) {
|
||||
bullet->patnum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
bullet->age++;
|
||||
if(bullet->spawn_state >= BSS_ACTIVE) {
|
||||
if(bullet->spawn_state == BSS_ACTIVE) {
|
||||
bullet->spawn_state = BSS_GRAZEABLE;
|
||||
} else {
|
||||
// In delay cloud state
|
||||
if(bullet->spawn_state == BSS_CLOUD_BACKWARDS) {
|
||||
bullet->pos.prev = bullet->pos.cur;
|
||||
bullet->pos.cur.x.v -= (bullet->pos.velocity.x.v << 3);
|
||||
bullet->pos.cur.y.v -= (bullet->pos.velocity.y.v << 3);
|
||||
bullet->spawn_state = BSS_CLOUD_FORWARDS;
|
||||
} else if(bullet->spawn_state == BSS_CLOUD_FORWARDS) {
|
||||
bullet->pos.update_seg3();
|
||||
} else {
|
||||
bullet->pos.prev = bullet->pos.cur;
|
||||
bullet->pos.cur.x.v += (bullet->pos.velocity.x.v / 3);
|
||||
bullet->pos.cur.y.v += (bullet->pos.velocity.y.v / 3);
|
||||
}
|
||||
reinterpret_cast<unsigned char &>(bullet->spawn_state)++;
|
||||
if(bullet->spawn_state >= BSS_CLOUD_END) {
|
||||
#if (GAME == 5)
|
||||
if(!playfield_encloses_yx_lt_ge(
|
||||
bullet->pos.cur.x,
|
||||
bullet->pos.cur.y,
|
||||
BULLET16_W,
|
||||
BULLET16_H
|
||||
)) {
|
||||
bullet->flag = 2;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
bullet->spawn_state = BSS_ACTIVE;
|
||||
}
|
||||
#if (GAME == 5)
|
||||
else if(is_pellet(i)) {
|
||||
pellet_clouds_render[pellet_clouds_render_count++] =
|
||||
bullet;
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(bullet->move_state == BMS_SPECIAL) {
|
||||
bullet_update_special(*bullet);
|
||||
} else if(bullet->move_state == BMS_SLOWDOWN) {
|
||||
bullet->ax.slowdown_time--;
|
||||
bullet->speed_cur.v = (bullet->speed_final.v + ((
|
||||
bullet->ax.slowdown_time * bullet->dx.slowdown_speed_delta
|
||||
) / BMS_SLOWDOWN_FRAMES));
|
||||
if(bullet->ax.slowdown_time == 0) {
|
||||
bullet->speed_cur = bullet->speed_final;
|
||||
bullet->move_state = BMS_REGULAR;
|
||||
}
|
||||
vector2_near(
|
||||
bullet->pos.velocity, bullet->angle, bullet->speed_cur
|
||||
);
|
||||
}
|
||||
|
||||
/* DX:AX = */ bullet->pos.update_seg3();
|
||||
if(!playfield_encloses(_AX, _DX, BULLET16_W, BULLET16_H)) {
|
||||
bullet->flag = 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(bullet_clear_time != 0) {
|
||||
continue;
|
||||
}
|
||||
_AX -= player_pos.cur.x.v;
|
||||
_DX -= player_pos.cur.y.v;
|
||||
if(player_invincibility_time == 0) {
|
||||
// Yup, a bullet must have been grazed in a previous frame
|
||||
// before it can be collided with.
|
||||
if(bullet->spawn_state != BSS_GRAZEABLE) {
|
||||
if(overlap_wh_inplace_fast(
|
||||
_AX, _DX, BULLET_KILLBOX_W, BULLET_KILLBOX_H
|
||||
)) {
|
||||
bullet->flag = 2;
|
||||
player_is_hit = true;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// Yes, the graze box is biased to the right, and taller
|
||||
// than wide.
|
||||
if(overlap_offcenter_inplace_fast(
|
||||
_AX, _DX,
|
||||
to_sp(16.0f), to_sp(22.0f), to_sp(20.0f), to_sp(22.0f)
|
||||
)) {
|
||||
/* TODO: Replace with the decompiled call
|
||||
* sparks_add_random(bullet->pos.cur.x, bullet->pos.cur.y, to_sp(2.0f), 2);
|
||||
* once that function is part of this translation unit */
|
||||
__asm {
|
||||
db 0xFF, 0x74, 0x02;
|
||||
db 0xFF, 0x74, 0x04;
|
||||
db 0x66, 0x68, 2, 0x00, (2 * 16), 0x00;
|
||||
nop;
|
||||
push cs;
|
||||
call near ptr sparks_add_random;
|
||||
}
|
||||
bullet->spawn_state = BSS_GRAZED;
|
||||
if(stage_graze < STAGE_GRAZE_CAP) {
|
||||
stage_graze++;
|
||||
hud_graze_put();
|
||||
score_delta += graze_score;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(is_pellet(i)) {
|
||||
pellets_render[pellets_render_count].top.left = (
|
||||
bullet->pos.cur.to_screen_left(PELLET_W)
|
||||
);
|
||||
pellets_render[pellets_render_count].top.top = (
|
||||
bullet->pos.cur.to_vram_top_scrolled_seg3(PELLET_H)
|
||||
);
|
||||
pellets_render_count++;
|
||||
}
|
||||
}
|
||||
if(turbo_mode == false) {
|
||||
#if (GAME == 5)
|
||||
slowdown_caused_by_bullets = false;
|
||||
i = 42;
|
||||
#else
|
||||
i = 24;
|
||||
i += playperf;
|
||||
#endif
|
||||
i += (rank * 8);
|
||||
if(bullets_seen >= i) {
|
||||
if(!stage_frame_mod2) {
|
||||
slowdown_factor = 2;
|
||||
#if (GAME == 5)
|
||||
slowdown_caused_by_bullets = true;
|
||||
#endif
|
||||
}
|
||||
} else if(bullets_seen >= (i + SLOWDOWN_BULLET_THRESHOLD_UNUSED)) {
|
||||
// Yes, never executed, as the first condition would then have
|
||||
// been true as well
|
||||
slowdown_factor = 2;
|
||||
#if (GAME == 5)
|
||||
slowdown_caused_by_bullets = true;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// A bit wasteful to run all of this every frame, since no new bullets
|
||||
// are spawned while [bullet_zap] is active; the bullet spawn wrapper
|
||||
// functions prevent that. Then again, this means that the code here
|
||||
// does kind of rely on bullets not being spawned through other methods.
|
||||
|
||||
unsigned int score_per_bullet;
|
||||
unsigned int score_step;
|
||||
|
||||
// Without this cap, the [popup_bonus] formula would be
|
||||
// 0.5n³ - n² + 1.5n
|
||||
// with n = [bullets_seen].
|
||||
unsigned int score_per_bullet_cap;
|
||||
unsigned char patnum;
|
||||
|
||||
patnum =
|
||||
(PAT_BULLET_ZAP + (bullet_zap.frames / BULLET_ZAP_FRAMES_PER_CEL)
|
||||
);
|
||||
score_per_bullet = 1;
|
||||
score_step = 1;
|
||||
#if (GAME == 5)
|
||||
// ZUN bug: All code below uses TH04's patnum for that sprite. This
|
||||
// causes the decay animation to never actually play in TH05.
|
||||
#define PAT_BULLET_ZAP 72
|
||||
|
||||
score_per_bullet_cap = (rank == RANK_EXTRA)
|
||||
? 1600
|
||||
: select_for_rank(960, 1280, 1280, 1280);
|
||||
#else
|
||||
switch(rank) {
|
||||
case RANK_EASY:
|
||||
score_per_bullet_cap = 1000;
|
||||
break;
|
||||
case RANK_NORMAL:
|
||||
case RANK_HARD:
|
||||
case RANK_LUNATIC:
|
||||
score_per_bullet_cap = 1600;
|
||||
break;
|
||||
case RANK_EXTRA:
|
||||
score_per_bullet_cap = 2000;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
popup_bonus = 0;
|
||||
for(i = 0; i < BULLET_COUNT; i++, bullet--) {
|
||||
if(bullet->flag != 1) {
|
||||
continue;
|
||||
}
|
||||
bullet->pos.velocity.set(0.0f, 0.0f);
|
||||
bullet->pos.update_seg3();
|
||||
|
||||
// ZUN bug: Always false in TH05, see above
|
||||
if(patnum < (PAT_BULLET_ZAP + BULLET_DECAY_CELS)) {
|
||||
bullet->patnum = patnum;
|
||||
#if (GAME == 5)
|
||||
bullets_seen++;
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
popup_bonus += score_per_bullet;
|
||||
score_delta += score_per_bullet;
|
||||
pointnums_add_white(
|
||||
bullet->pos.cur.x, bullet->pos.cur.y, score_per_bullet
|
||||
);
|
||||
|
||||
score_per_bullet += score_step;
|
||||
score_step += 3;
|
||||
if(score_per_bullet > score_per_bullet_cap) {
|
||||
score_per_bullet = score_per_bullet_cap;
|
||||
}
|
||||
|
||||
bullet->flag = 2;
|
||||
#if (GAME == 5)
|
||||
if(bullet_zap_drop_point_items && ((bullets_seen % 4) == 0)) {
|
||||
items_add(bullet->pos.cur.x, bullet->pos.cur.y, IT_POINT);
|
||||
}
|
||||
bullets_seen++;
|
||||
#endif
|
||||
}
|
||||
// Note that this would show only one popup even *if* bullets could
|
||||
// spawn during the zap frames: Popups can be changed at least every
|
||||
// 64 frames, and BULLET_ZAP_FRAMES is smaller.
|
||||
if(popup_bonus) {
|
||||
popup_show(POPUP_ID_BONUS);
|
||||
}
|
||||
bullet_zap.frames++;
|
||||
|
||||
// ZUN bug: Always true in TH05, see above
|
||||
if(patnum >= (PAT_BULLET_ZAP + BULLET_ZAP_CELS)) {
|
||||
bullet_zap.active = false;
|
||||
}
|
||||
}
|
||||
if(bullet_clear_time) {
|
||||
bullet_clear_time--;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,4 +23,7 @@ void pascal hud_hp_put(int bar_value);
|
|||
// Renders the HP bar at the fraction of ([hp_cur] / [hp_max]), or instead
|
||||
// takes asingle fill step if the previous bar value was lower.
|
||||
void pascal hud_hp_update_and_render(int hp_cur, int hp_max);
|
||||
|
||||
// Displays [stage_graze] in the graze row.
|
||||
void pascal hud_graze_put();
|
||||
// ----------
|
||||
|
|
|
@ -3,8 +3,6 @@ PLAYER_OPTION_W = 16
|
|||
PLAYER_OPTION_H = 16
|
||||
PLAYER_OPTION_DISTANCE = (PLAYER_W / 2) + (PLAYER_OPTION_W / 2)
|
||||
|
||||
GRAZE_MAX = 999
|
||||
|
||||
; Shots
|
||||
; -----
|
||||
SHOT_W = 16
|
||||
|
|
|
@ -54,10 +54,10 @@ extern unsigned char pointnum_white_p;
|
|||
);
|
||||
#endif
|
||||
|
||||
int pascal pointnum_add_white(
|
||||
void pascal near pointnums_add_white(
|
||||
Subpixel center_x, Subpixel center_y, uint16_t points
|
||||
);
|
||||
int pascal pointnum_add_yellow(
|
||||
void pascal near pointnums_add_yellow(
|
||||
Subpixel center_x, Subpixel center_y, uint16_t points
|
||||
);
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "th04/score.h"
|
||||
|
||||
static const unsigned int STAGE_GRAZE_CAP = 999;
|
||||
|
||||
extern unsigned int graze_score; // Set per difficulty.
|
||||
extern unsigned int stage_graze; // Reset to 0 when moving to a new stage.
|
||||
|
||||
|
|
|
@ -16,10 +16,19 @@ extern "C" {
|
|||
#include "th04/math/randring.h"
|
||||
#include "th04/math/vector.hpp"
|
||||
#include "th04/sprites/main_pat.h"
|
||||
#include "th04/main/frames.h"
|
||||
#include "th04/main/playfld.hpp"
|
||||
#include "th04/main/playperf.hpp"
|
||||
#include "th04/main/player/player.hpp"
|
||||
#include "th04/main/bullet/bullet.hpp"
|
||||
#include "th04/main/hud/hud.h"
|
||||
#include "th04/main/hud/popup.hpp"
|
||||
#include "th04/main/pointnum/pointnum.hpp"
|
||||
#include "th04/main/rank.hpp"
|
||||
#include "th04/main/spark.hpp"
|
||||
#include "th04/main/score.hpp"
|
||||
#include "th04/main/scroll.hpp"
|
||||
#include "th04/main/slowdown.hpp"
|
||||
#include "th04/main/gather.hpp"
|
||||
|
||||
#pragma option -a2
|
||||
|
|
|
@ -3,6 +3,5 @@ include th02/sprites/cels.inc
|
|||
HITSHOT_CELS = 4
|
||||
BULLET_CLOUD_CELS = 4
|
||||
BULLET_DECAY_CELS = 4
|
||||
BULLET_ZAP_CELS = 4
|
||||
BULLET_D_CELS = 16
|
||||
BULLET_V_CELS = 32
|
||||
|
|
|
@ -101,4 +101,6 @@ typedef enum {
|
|||
PAT_YUUKA6_VANISH_3 = 180,
|
||||
// --------
|
||||
/// =======
|
||||
|
||||
_main_patnum_t_FORCE_INT16 = 0x7FFF,
|
||||
} main_patnum_t;
|
||||
|
|
|
@ -19,12 +19,9 @@ PAT_BULLET16_N_SMALL_BALL_RED = 60
|
|||
PAT_BULLET16_N_BALL_RED = 61
|
||||
PAT_BULLET16_N_HEART_BALL_RED = 62
|
||||
PAT_EXPLOSION_SMALL = 68
|
||||
PAT_BULLET_ZAP = 72
|
||||
PAT_BULLET16_D = 76
|
||||
PAT_BULLET16_D_BLUE = PAT_BULLET16_D
|
||||
PAT_BULLET16_D_YELLOW = 92
|
||||
PAT_DECAY_PELLET = 108
|
||||
PAT_DECAY_BULLET16 = 112
|
||||
|
||||
PAT_YUUKA6_PARASOL_BACK_OPEN = 128
|
||||
PAT_YUUKA6_PARASOL_BACK_HALFOPEN = 130
|
||||
|
|
389
th04_main.asm
389
th04_main.asm
|
@ -27808,396 +27808,10 @@ off_1C8B6 dw offset loc_1C755
|
|||
dw offset loc_1C885
|
||||
dw offset loc_1C8A2
|
||||
bullet_update_special endp
|
||||
|
||||
; =============== S U B R O U T I N E =======================================
|
||||
|
||||
; Attributes: bp-based frame
|
||||
public _bullets_update
|
||||
_bullets_update proc far
|
||||
|
||||
@@patnum = byte ptr -9
|
||||
var_8 = word ptr -8
|
||||
var_6 = word ptr -6
|
||||
@@points = word ptr -4
|
||||
var_2 = word ptr -2
|
||||
|
||||
push bp
|
||||
mov bp, sp
|
||||
sub sp, 0Ah
|
||||
push si
|
||||
push di
|
||||
mov [bp+var_2], 0
|
||||
mov _pellets_render_count, 0
|
||||
mov si, offset _bullets[(BULLET_COUNT - 1) * size bullet_t]
|
||||
cmp _bullet_zap_active, 0
|
||||
jnz loc_1CB44
|
||||
xor di, di
|
||||
jmp loc_1CAFC
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1C8EC:
|
||||
cmp [si+bullet_t.flag], 0
|
||||
jz loc_1CAF8
|
||||
cmp [si+bullet_t.flag], 2
|
||||
jnz short loc_1C8FE
|
||||
mov [si+bullet_t.flag], 0
|
||||
jmp loc_1CAF8
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1C8FE:
|
||||
inc [bp+var_2]
|
||||
cmp _bullet_clear_time, 0
|
||||
jz short loc_1C961
|
||||
cmp [si+bullet_t.move_state], BMS_DECAY
|
||||
jnb short loc_1C939
|
||||
mov [si+bullet_t.move_state], BMS_DECAY
|
||||
cmp di, BULLET16_COUNT
|
||||
jge short loc_1C91D
|
||||
mov ax, PAT_DECAY_BULLET16
|
||||
jmp short loc_1C920
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1C91D:
|
||||
mov ax, PAT_DECAY_PELLET
|
||||
|
||||
loc_1C920:
|
||||
mov [si+bullet_t.BULLET_patnum], ax
|
||||
cmp [si+bullet_t.age], 0
|
||||
jz short loc_1C931
|
||||
add _score_delta, 100
|
||||
jmp short loc_1C961
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1C931:
|
||||
add _score_delta, 10
|
||||
jmp short loc_1C961
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1C939:
|
||||
inc [si+bullet_t.move_state]
|
||||
cmp [si+bullet_t.move_state], BMS_DECAY_END
|
||||
jb short loc_1C94F
|
||||
lea ax, [si+bullet_t.pos]
|
||||
call @PlayfieldMotion@update_seg3$qv pascal, ax
|
||||
mov [si+bullet_t.flag], 2
|
||||
jmp loc_1CAF8
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1C94F:
|
||||
mov al, [si+bullet_t.move_state]
|
||||
mov ah, 0
|
||||
mov bx, (BMS_DECAY_FRAMES / BULLET_DECAY_CELS)
|
||||
cwd
|
||||
idiv bx
|
||||
or dx, dx
|
||||
jnz short loc_1C961
|
||||
inc [si+bullet_t.BULLET_patnum]
|
||||
|
||||
loc_1C961:
|
||||
inc [si+bullet_t.age]
|
||||
cmp [si+bullet_t.spawn_state], BSS_ACTIVE
|
||||
jb short loc_1C9DA
|
||||
cmp [si+bullet_t.spawn_state], BSS_ACTIVE
|
||||
jnz short loc_1C976
|
||||
mov [si+bullet_t.spawn_state], BSS_GRAZEABLE
|
||||
jmp short loc_1C9DA
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1C976:
|
||||
cmp [si+bullet_t.spawn_state], BSS_CLOUD_BACKWARDS
|
||||
jnz short loc_1C99C
|
||||
mov eax, dword ptr [si+bullet_t.pos.cur]
|
||||
mov dword ptr [si+bullet_t.pos.prev], eax
|
||||
mov ax, [si+bullet_t.pos.velocity.x]
|
||||
shl ax, 3
|
||||
sub [si+bullet_t.pos.cur.x], ax
|
||||
mov ax, [si+bullet_t.pos.velocity.y]
|
||||
shl ax, 3
|
||||
sub [si+bullet_t.pos.cur.y], ax
|
||||
mov [si+bullet_t.spawn_state], BSS_CLOUD_FORWARDS
|
||||
jmp short loc_1C9C8
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1C99C:
|
||||
cmp [si+bullet_t.spawn_state], BSS_CLOUD_FORWARDS
|
||||
jnz short loc_1C9AB
|
||||
lea ax, [si+bullet_t.pos]
|
||||
call @PlayfieldMotion@update_seg3$qv pascal, ax
|
||||
jmp short loc_1C9C8
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1C9AB:
|
||||
mov eax, dword ptr [si+bullet_t.pos.cur]
|
||||
mov dword ptr [si+bullet_t.pos.prev], eax
|
||||
mov ax, [si+bullet_t.pos.velocity.x]
|
||||
mov bx, 3
|
||||
cwd
|
||||
idiv bx
|
||||
add [si+bullet_t.pos.cur.x], ax
|
||||
mov ax, [si+bullet_t.pos.velocity.y]
|
||||
cwd
|
||||
idiv bx
|
||||
add [si+bullet_t.pos.cur.y], ax
|
||||
|
||||
loc_1C9C8:
|
||||
inc [si+bullet_t.spawn_state]
|
||||
cmp [si+bullet_t.spawn_state], BSS_CLOUD_END
|
||||
jb loc_1CAF8
|
||||
mov [si+bullet_t.spawn_state], BSS_ACTIVE
|
||||
jmp loc_1CAF8
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1C9DA:
|
||||
cmp [si+bullet_t.move_state], BMS_SPECIAL
|
||||
jnz short loc_1C9E6
|
||||
call bullet_update_special pascal, si
|
||||
jmp short loc_1CA27
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1C9E6:
|
||||
cmp [si+bullet_t.move_state], BMS_SLOWDOWN
|
||||
jnz short loc_1CA27
|
||||
dec [si+bullet_t.slowdown_time]
|
||||
mov al, [si+bullet_t.slowdown_time]
|
||||
mov ah, 0
|
||||
mov dl, [si+bullet_t.slowdown_speed_delta]
|
||||
mov dh, 0
|
||||
imul dx
|
||||
mov bx, BMS_SLOWDOWN_FRAMES
|
||||
cwd
|
||||
idiv bx
|
||||
add al, [si+bullet_t.speed_final]
|
||||
mov [si+bullet_t.speed_cur], al
|
||||
cmp [si+bullet_t.slowdown_time], 0
|
||||
jnz short loc_1CA17
|
||||
mov al, [si+bullet_t.speed_final]
|
||||
mov [si+bullet_t.speed_cur], al
|
||||
mov [si+bullet_t.move_state], BMS_REGULAR
|
||||
|
||||
loc_1CA17:
|
||||
lea ax, [si+bullet_t.pos.velocity]
|
||||
push ax
|
||||
push word ptr [si+bullet_t.BULLET_angle]
|
||||
mov al, [si+bullet_t.speed_cur]
|
||||
mov ah, 0
|
||||
push ax
|
||||
call vector2_near
|
||||
|
||||
loc_1CA27:
|
||||
lea ax, [si+bullet_t.pos]
|
||||
call @PlayfieldMotion@update_seg3$qv pascal, ax
|
||||
cmp ax, (-8 shl 4)
|
||||
jle short loc_1CA43
|
||||
cmp ax, ((PLAYFIELD_W + 8) shl 4)
|
||||
jge short loc_1CA43
|
||||
cmp dx, (-8 shl 4)
|
||||
jle short loc_1CA43
|
||||
cmp dx, ((PLAYFIELD_H + 8) shl 4)
|
||||
jl short loc_1CA49
|
||||
|
||||
loc_1CA43:
|
||||
mov [si+bullet_t.flag], 2
|
||||
jmp loc_1CAF8
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1CA49:
|
||||
cmp _bullet_clear_time, 0
|
||||
jnz loc_1CAF8
|
||||
sub ax, _player_pos.cur.x
|
||||
sub dx, _player_pos.cur.y
|
||||
cmp _player_invincibility_time, 0
|
||||
jnz short loc_1CAC5
|
||||
cmp [si+bullet_t.spawn_state], BSS_GRAZEABLE
|
||||
jz short loc_1CA82
|
||||
add ax, (4 shl 4)
|
||||
cmp ax, (8 shl 4)
|
||||
ja short loc_1CAC5
|
||||
add dx, (4 shl 4)
|
||||
cmp dx, (8 shl 4)
|
||||
ja short loc_1CAC5
|
||||
mov [si+bullet_t.flag], 2
|
||||
mov _player_is_hit, 1
|
||||
jmp short loc_1CAF8
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1CA82:
|
||||
add ax, (16 shl 4)
|
||||
cmp ax, (36 shl 4)
|
||||
ja short loc_1CAC5
|
||||
add dx, (22 shl 4)
|
||||
cmp dx, (44 shl 4)
|
||||
ja short loc_1CAC5
|
||||
push [si+bullet_t.pos.cur.x]
|
||||
push [si+bullet_t.pos.cur.y]
|
||||
push large (((2 shl 4) shl 16) or 2)
|
||||
nopcall sparks_add_random
|
||||
mov [si+bullet_t.spawn_state], BSS_GRAZED
|
||||
cmp _stage_graze, GRAZE_MAX
|
||||
jnb short loc_1CAC5
|
||||
inc _stage_graze
|
||||
call hud_graze_put
|
||||
movzx eax, _graze_score
|
||||
add _score_delta, eax
|
||||
|
||||
loc_1CAC5:
|
||||
cmp di, BULLET16_COUNT
|
||||
jl short loc_1CAF8
|
||||
mov ax, [si+bullet_t.pos.cur.x]
|
||||
sar ax, 4
|
||||
add ax, (PLAYFIELD_LEFT - (PELLET_W / 2))
|
||||
mov bx, _pellets_render_count
|
||||
shl bx, 2
|
||||
mov _pellets_render[bx].PRT_left, ax
|
||||
mov ax, [si+bullet_t.pos.cur.y]
|
||||
add ax, ((PLAYFIELD_TOP - (PELLET_H / 2)) shl 4)
|
||||
call scroll_subpixel_y_to_vram_seg3 pascal, ax
|
||||
mov bx, _pellets_render_count
|
||||
shl bx, 2
|
||||
mov _pellets_render[bx].PRT_top, ax
|
||||
inc _pellets_render_count
|
||||
|
||||
loc_1CAF8:
|
||||
inc di
|
||||
sub si, size bullet_t
|
||||
|
||||
loc_1CAFC:
|
||||
cmp di, BULLET_COUNT
|
||||
jl loc_1C8EC
|
||||
cmp _turbo_mode, 0
|
||||
jnz loc_1CC19
|
||||
mov di, 24
|
||||
mov al, _playperf
|
||||
mov ah, 0
|
||||
add di, ax
|
||||
mov al, _rank
|
||||
mov ah, 0
|
||||
shl ax, 3
|
||||
add di, ax
|
||||
cmp [bp+var_2], di
|
||||
jl short loc_1CB31
|
||||
cmp _stage_frame_mod2, 0
|
||||
jnz loc_1CC19
|
||||
jmp short loc_1CB3B
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1CB31:
|
||||
lea ax, [di+18h]
|
||||
cmp ax, [bp+var_2]
|
||||
jg loc_1CC19
|
||||
|
||||
loc_1CB3B:
|
||||
mov _slowdown_factor, 2
|
||||
jmp loc_1CC19
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1CB44:
|
||||
mov al, _bullet_zap_active
|
||||
mov ah, 0
|
||||
mov bx, BULLET_ZAP_CELS
|
||||
cwd
|
||||
idiv bx
|
||||
add al, PAT_BULLET_ZAP
|
||||
mov [bp+@@patnum], al
|
||||
mov [bp+@@points], 1
|
||||
mov [bp+var_6], 1
|
||||
mov al, _rank
|
||||
mov ah, 0
|
||||
mov bx, ax
|
||||
cmp bx, RANK_EXTRA
|
||||
ja short loc_1CB84
|
||||
add bx, bx
|
||||
jmp cs:off_1CC29[bx]
|
||||
|
||||
loc_1CB71:
|
||||
mov [bp+var_8], 1000
|
||||
jmp short loc_1CB84
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1CB78:
|
||||
mov [bp+var_8], 1600
|
||||
jmp short loc_1CB84
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1CB7F:
|
||||
mov [bp+var_8], 2000
|
||||
|
||||
loc_1CB84:
|
||||
mov _popup_bonus, 0
|
||||
xor di, di
|
||||
jmp short loc_1CBF1
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1CB91:
|
||||
cmp [si+bullet_t.flag], 1
|
||||
jnz short loc_1CBED
|
||||
mov [si+bullet_t.pos.velocity.x], 0
|
||||
mov [si+bullet_t.pos.velocity.y], 0
|
||||
lea ax, [si+bullet_t.pos]
|
||||
call @PlayfieldMotion@update_seg3$qv pascal, ax
|
||||
cmp [bp+@@patnum], PAT_BULLET16_D
|
||||
jnb short loc_1CBB7
|
||||
mov al, [bp+@@patnum]
|
||||
mov ah, 0
|
||||
mov [si+bullet_t.BULLET_patnum], ax
|
||||
jmp short loc_1CBED
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1CBB7:
|
||||
movzx eax, [bp+@@points]
|
||||
add _popup_bonus, eax
|
||||
add _score_delta, eax
|
||||
call pointnums_add_white pascal, [si+bullet_t.pos.cur.x], [si+bullet_t.pos.cur.y], [bp+@@points]
|
||||
mov ax, [bp+var_6]
|
||||
add [bp+@@points], ax
|
||||
add [bp+var_6], 3
|
||||
mov ax, [bp+@@points]
|
||||
cmp ax, [bp+var_8]
|
||||
jbe short loc_1CBEA
|
||||
mov ax, [bp+var_8]
|
||||
mov [bp+@@points], ax
|
||||
|
||||
loc_1CBEA:
|
||||
mov [si+bullet_t.flag], 2
|
||||
|
||||
loc_1CBED:
|
||||
inc di
|
||||
sub si, size bullet_t
|
||||
|
||||
loc_1CBF1:
|
||||
cmp di, BULLET_COUNT
|
||||
jl short loc_1CB91
|
||||
cmp _popup_bonus, 0
|
||||
jz short loc_1CC0A
|
||||
mov _popup_id_new, POPUP_ID_BONUS
|
||||
mov _popup, offset popup_update_and_render
|
||||
|
||||
loc_1CC0A:
|
||||
inc _bullet_zap_active
|
||||
cmp [bp+@@patnum], PAT_BULLET16_D
|
||||
jb short loc_1CC19
|
||||
mov _bullet_zap_active, 0
|
||||
|
||||
loc_1CC19:
|
||||
cmp _bullet_clear_time, 0
|
||||
jz short loc_1CC24
|
||||
dec _bullet_clear_time
|
||||
|
||||
loc_1CC24:
|
||||
pop di
|
||||
pop si
|
||||
leave
|
||||
retf
|
||||
; ---------------------------------------------------------------------------
|
||||
db 0
|
||||
off_1CC29 dw offset loc_1CB71
|
||||
dw offset loc_1CB78
|
||||
dw offset loc_1CB78
|
||||
dw offset loc_1CB78
|
||||
dw offset loc_1CB7F
|
||||
_bullets_update endp
|
||||
main_032_TEXT ends
|
||||
|
||||
main_033_TEXT segment byte public 'CODE' use16
|
||||
extern _bullets_update:proc
|
||||
BULLET_TEMPLATE_TUNE_EASY procdesc near
|
||||
BULLET_TEMPLATE_TUNE_NORMAL procdesc near
|
||||
BULLET_TEMPLATE_TUNE_HARD procdesc near
|
||||
|
@ -34220,6 +33834,7 @@ word_25678 dw ?
|
|||
db 6 dup(?)
|
||||
word_25680 dw ?
|
||||
db 6 dup(?)
|
||||
public _rank
|
||||
_rank db ?
|
||||
include th04/main/score[bss].asm
|
||||
byte_256A2 db ?
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
#pragma option -zCmain_033_TEXT -zPmain_03
|
||||
#include "th04/main/bullet/update.cpp"
|
|
@ -134,4 +134,6 @@ typedef enum {
|
|||
PAT_DECAY_B6BALL_last = (PAT_DECAY_B6BALL + BULLET_DECAY_CELS - 1),
|
||||
/// -------
|
||||
/// =======
|
||||
|
||||
_main_patnum_t_FORCE_INT16 = 0x7FFF,
|
||||
} main_patnum_t;
|
||||
|
|
|
@ -30,9 +30,6 @@ PAT_BULLET16_V = 84
|
|||
PAT_BULLET16_V_RED = PAT_BULLET16_V
|
||||
PAT_BULLET16_V_BLUE = 116
|
||||
PAT_CLOUD_PELLET = 148
|
||||
PAT_BULLET_ZAP = 152
|
||||
PAT_DECAY_PELLET = 156
|
||||
PAT_DECAY_BULLET16 = 160
|
||||
PAT_EXPLOSION_SMALL = 164
|
||||
PAT_FIREWAVE_LEFT = 168
|
||||
PAT_FIREWAVE_RIGHT = 169
|
||||
|
|
408
th05_main.asm
408
th05_main.asm
|
@ -12836,413 +12836,7 @@ off_17BF0 dw offset loc_17A4E
|
|||
dw offset loc_17BBA
|
||||
bullet_update_special endp
|
||||
|
||||
; =============== S U B R O U T I N E =======================================
|
||||
|
||||
; Attributes: bp-based frame
|
||||
|
||||
_bullets_update proc far
|
||||
|
||||
@@patnum = byte ptr -9
|
||||
var_8 = word ptr -8
|
||||
var_6 = word ptr -6
|
||||
@@points = word ptr -4
|
||||
var_2 = word ptr -2
|
||||
|
||||
push bp
|
||||
mov bp, sp
|
||||
sub sp, 0Ah
|
||||
push si
|
||||
push di
|
||||
mov [bp+var_2], 0
|
||||
mov _pellet_clouds_render_count, 0
|
||||
mov _pellets_render_count, 0
|
||||
mov si, offset _bullets[(BULLET_COUNT - 1) * size bullet_t]
|
||||
cmp _bullet_zap_active, 0
|
||||
jnz loc_17EC3
|
||||
xor di, di
|
||||
jmp loc_17E78
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17C2E:
|
||||
cmp [si+bullet_t.flag], 0
|
||||
jz loc_17E74
|
||||
cmp [si+bullet_t.flag], 2
|
||||
jnz short loc_17C40
|
||||
mov [si+bullet_t.flag], 0
|
||||
jmp loc_17E74
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17C40:
|
||||
inc [bp+var_2]
|
||||
cmp _bullet_clear_time, 0
|
||||
jz short loc_17CA3
|
||||
cmp [si+bullet_t.move_state], BMS_DECAY
|
||||
jnb short loc_17C7B
|
||||
mov [si+bullet_t.move_state], BMS_DECAY
|
||||
cmp di, BULLET16_COUNT
|
||||
jge short loc_17C5F
|
||||
mov ax, PAT_DECAY_BULLET16
|
||||
jmp short loc_17C62
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17C5F:
|
||||
mov ax, PAT_DECAY_PELLET
|
||||
|
||||
loc_17C62:
|
||||
mov [si+bullet_t.BULLET_patnum], ax
|
||||
cmp [si+bullet_t.age], 0
|
||||
jz short loc_17C73
|
||||
add _score_delta, 100
|
||||
jmp short loc_17CA3
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17C73:
|
||||
add _score_delta, 10
|
||||
jmp short loc_17CA3
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17C7B:
|
||||
inc [si+bullet_t.move_state]
|
||||
cmp [si+bullet_t.move_state], BMS_DECAY_END
|
||||
jb short loc_17C91
|
||||
lea ax, [si+bullet_t.pos]
|
||||
call @PlayfieldMotion@update_seg3$qv pascal, ax
|
||||
mov [si+bullet_t.flag], 2
|
||||
jmp loc_17E74
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17C91:
|
||||
mov al, [si+bullet_t.move_state]
|
||||
mov ah, 0
|
||||
mov bx, (BMS_DECAY_FRAMES / BULLET_DECAY_CELS)
|
||||
cwd
|
||||
idiv bx
|
||||
or dx, dx
|
||||
jnz short loc_17CA3
|
||||
inc [si+bullet_t.BULLET_patnum]
|
||||
|
||||
loc_17CA3:
|
||||
inc [si+bullet_t.age]
|
||||
cmp [si+bullet_t.spawn_state], BSS_ACTIVE
|
||||
jb loc_17D56
|
||||
cmp [si+bullet_t.spawn_state], BSS_ACTIVE
|
||||
jnz short loc_17CBB
|
||||
mov [si+bullet_t.spawn_state], BSS_GRAZEABLE
|
||||
jmp loc_17D56
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17CBB:
|
||||
cmp [si+bullet_t.spawn_state], BSS_CLOUD_BACKWARDS
|
||||
jnz short loc_17CE1
|
||||
mov eax, dword ptr [si+bullet_t.pos.cur]
|
||||
mov dword ptr [si+bullet_t.pos.prev], eax
|
||||
mov ax, [si+bullet_t.pos.velocity.x]
|
||||
shl ax, 3
|
||||
sub [si+bullet_t.pos.cur.x], ax
|
||||
mov ax, [si+bullet_t.pos.velocity.y]
|
||||
shl ax, 3
|
||||
sub [si+bullet_t.pos.cur.y], ax
|
||||
mov [si+bullet_t.spawn_state], BSS_CLOUD_FORWARDS
|
||||
jmp short loc_17D0D
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17CE1:
|
||||
cmp [si+bullet_t.spawn_state], BSS_CLOUD_FORWARDS
|
||||
jnz short loc_17CF0
|
||||
lea ax, [si+bullet_t.pos]
|
||||
call @PlayfieldMotion@update_seg3$qv pascal, ax
|
||||
jmp short loc_17D0D
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17CF0:
|
||||
mov eax, dword ptr [si+bullet_t.pos.cur]
|
||||
mov dword ptr [si+bullet_t.pos.prev], eax
|
||||
mov ax, [si+bullet_t.pos.velocity.x]
|
||||
mov bx, 3
|
||||
cwd
|
||||
idiv bx
|
||||
add [si+bullet_t.pos.cur.x], ax
|
||||
mov ax, [si+bullet_t.pos.velocity.y]
|
||||
cwd
|
||||
idiv bx
|
||||
add [si+bullet_t.pos.cur.y], ax
|
||||
|
||||
loc_17D0D:
|
||||
inc [si+bullet_t.spawn_state]
|
||||
cmp [si+bullet_t.spawn_state], BSS_CLOUD_END
|
||||
jb short loc_17D3D
|
||||
cmp [si+bullet_t.pos.cur.y], (-8 shl 4)
|
||||
jl short loc_17D30
|
||||
cmp [si+bullet_t.pos.cur.y], ((PLAYFIELD_H + 8) shl 4)
|
||||
jge short loc_17D30
|
||||
cmp [si+bullet_t.pos.cur.x], (-8 shl 4)
|
||||
jl short loc_17D30
|
||||
cmp [si+bullet_t.pos.cur.x], ((PLAYFIELD_W + 8) shl 4)
|
||||
jl short loc_17D36
|
||||
|
||||
loc_17D30:
|
||||
mov [si+bullet_t.flag], 2
|
||||
jmp loc_17E74
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17D36:
|
||||
mov [si+bullet_t.spawn_state], BSS_ACTIVE
|
||||
jmp loc_17E74
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17D3D:
|
||||
cmp di, BULLET16_COUNT
|
||||
jl loc_17E74
|
||||
mov bx, _pellet_clouds_render_count
|
||||
add bx, bx
|
||||
mov _pellet_clouds_render[bx], si
|
||||
inc _pellet_clouds_render_count
|
||||
jmp loc_17E74
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17D56:
|
||||
cmp [si+bullet_t.move_state], BMS_SPECIAL
|
||||
jnz short loc_17D62
|
||||
call bullet_update_special pascal, si
|
||||
jmp short loc_17DA3
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17D62:
|
||||
cmp [si+bullet_t.move_state], BMS_SLOWDOWN
|
||||
jnz short loc_17DA3
|
||||
dec [si+bullet_t.slowdown_time]
|
||||
mov al, [si+bullet_t.slowdown_time]
|
||||
mov ah, 0
|
||||
mov dl, [si+bullet_t.slowdown_speed_delta]
|
||||
mov dh, 0
|
||||
imul dx
|
||||
mov bx, BMS_SLOWDOWN_FRAMES
|
||||
cwd
|
||||
idiv bx
|
||||
add al, [si+bullet_t.speed_final]
|
||||
mov [si+bullet_t.speed_cur], al
|
||||
cmp [si+bullet_t.slowdown_time], 0
|
||||
jnz short loc_17D93
|
||||
mov al, [si+bullet_t.speed_final]
|
||||
mov [si+bullet_t.speed_cur], al
|
||||
mov [si+bullet_t.move_state], BMS_REGULAR
|
||||
|
||||
loc_17D93:
|
||||
lea ax, [si+bullet_t.pos.velocity]
|
||||
push ax
|
||||
push word ptr [si+bullet_t.BULLET_angle]
|
||||
mov al, [si+bullet_t.speed_cur]
|
||||
mov ah, 0
|
||||
push ax
|
||||
call vector2_near
|
||||
|
||||
loc_17DA3:
|
||||
lea ax, [si+bullet_t.pos]
|
||||
call @PlayfieldMotion@update_seg3$qv pascal, ax
|
||||
cmp ax, (-8 shl 4)
|
||||
jle short loc_17DBF
|
||||
cmp ax, ((PLAYFIELD_W + 8) shl 4)
|
||||
jge short loc_17DBF
|
||||
cmp dx, (-8 shl 4)
|
||||
jle short loc_17DBF
|
||||
cmp dx, ((PLAYFIELD_H + 8) shl 4)
|
||||
jl short loc_17DC5
|
||||
|
||||
loc_17DBF:
|
||||
mov [si+bullet_t.flag], 2
|
||||
jmp loc_17E74
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17DC5:
|
||||
cmp _bullet_clear_time, 0
|
||||
jnz loc_17E74
|
||||
sub ax, _player_pos.cur.x
|
||||
sub dx, _player_pos.cur.y
|
||||
cmp _player_invincibility_time, 0
|
||||
jnz short loc_17E41
|
||||
cmp [si+bullet_t.spawn_state], BSS_GRAZEABLE
|
||||
jz short loc_17DFE
|
||||
add ax, (4 shl 4)
|
||||
cmp ax, (8 shl 4)
|
||||
ja short loc_17E41
|
||||
add dx, (4 shl 4)
|
||||
cmp dx, (8 shl 4)
|
||||
ja short loc_17E41
|
||||
mov [si+bullet_t.flag], 2
|
||||
mov _player_is_hit, 1
|
||||
jmp short loc_17E74
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17DFE:
|
||||
add ax, (16 shl 4)
|
||||
cmp ax, (36 shl 4)
|
||||
ja short loc_17E41
|
||||
add dx, (22 shl 4)
|
||||
cmp dx, (44 shl 4)
|
||||
ja short loc_17E41
|
||||
push [si+bullet_t.pos.cur.x]
|
||||
push [si+bullet_t.pos.cur.y]
|
||||
push large (((2 shl 4) shl 16) or 2)
|
||||
nopcall sparks_add_random
|
||||
mov [si+bullet_t.spawn_state], BSS_GRAZED
|
||||
cmp _stage_graze, GRAZE_MAX
|
||||
jnb short loc_17E41
|
||||
inc _stage_graze
|
||||
call hud_graze_put
|
||||
movzx eax, _graze_score
|
||||
add _score_delta, eax
|
||||
|
||||
loc_17E41:
|
||||
cmp di, BULLET16_COUNT
|
||||
jl short loc_17E74
|
||||
mov ax, [si+bullet_t.pos.cur.x]
|
||||
sar ax, 4
|
||||
add ax, (PLAYFIELD_LEFT - (PELLET_W / 2))
|
||||
mov bx, _pellets_render_count
|
||||
shl bx, 2
|
||||
mov _pellets_render[bx].PRT_left, ax
|
||||
mov ax, [si+bullet_t.pos.cur.y]
|
||||
add ax, ((PLAYFIELD_TOP - (PELLET_H / 2)) shl 4)
|
||||
call scroll_subpixel_y_to_vram_seg3 pascal, ax
|
||||
mov bx, _pellets_render_count
|
||||
shl bx, 2
|
||||
mov _pellets_render[bx].PRT_top, ax
|
||||
inc _pellets_render_count
|
||||
|
||||
loc_17E74:
|
||||
inc di
|
||||
sub si, size bullet_t
|
||||
|
||||
loc_17E78:
|
||||
cmp di, BULLET_COUNT
|
||||
jl loc_17C2E
|
||||
cmp _turbo_mode, 0
|
||||
jnz loc_17FB7
|
||||
mov _slowdown_caused_by_bullets, 0
|
||||
mov di, 2Ah ; '*'
|
||||
mov al, _rank
|
||||
mov ah, 0
|
||||
shl ax, 3
|
||||
add di, ax
|
||||
cmp [bp+var_2], di
|
||||
jl short loc_17EAB
|
||||
cmp _stage_frame_mod2, 0
|
||||
jnz loc_17FB7
|
||||
jmp short loc_17EB5
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17EAB:
|
||||
lea ax, [di+20h]
|
||||
cmp ax, [bp+var_2]
|
||||
jg loc_17FB7
|
||||
|
||||
loc_17EB5:
|
||||
mov _slowdown_factor, 2
|
||||
mov _slowdown_caused_by_bullets, 1
|
||||
jmp loc_17FB7
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17EC3:
|
||||
mov al, _bullet_zap_active
|
||||
mov ah, 0
|
||||
mov bx, BULLET_ZAP_CELS
|
||||
cwd
|
||||
idiv bx
|
||||
add al, PAT_BULLET_ZAP
|
||||
mov [bp+@@patnum], al
|
||||
mov [bp+@@points], 1
|
||||
mov [bp+var_6], 1
|
||||
cmp _rank, RANK_EXTRA
|
||||
jnz short loc_17EE9
|
||||
mov ax, 1600
|
||||
jmp short loc_17EFA
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17EE9:
|
||||
push ( 960 shl 16) or 1280
|
||||
push (1280 shl 16) or 1280
|
||||
call select_for_rank
|
||||
|
||||
loc_17EFA:
|
||||
mov [bp+var_8], ax
|
||||
mov _popup_bonus, 0
|
||||
xor di, di
|
||||
jmp loc_17F8D
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17F0B:
|
||||
cmp [si+bullet_t.flag], 1
|
||||
jnz short loc_17F89
|
||||
mov [si+bullet_t.pos.velocity.x], 0
|
||||
mov [si+bullet_t.pos.velocity.y], 0
|
||||
lea ax, [si+bullet_t.pos]
|
||||
call @PlayfieldMotion@update_seg3$qv pascal, ax
|
||||
cmp [bp+@@patnum], 76 ; TH04 leftover; PAT_BULLET16_D in that game, unused here
|
||||
jnb short loc_17F31
|
||||
mov al, [bp+@@patnum]
|
||||
mov ah, 0
|
||||
mov [si+bullet_t.BULLET_patnum], ax
|
||||
jmp short loc_17F86
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_17F31:
|
||||
movzx eax, [bp+@@points]
|
||||
add _popup_bonus, eax
|
||||
add _score_delta, eax
|
||||
call pointnums_add_white pascal, [si+bullet_t.pos.cur.x], [si+bullet_t.pos.cur.y], [bp+@@points]
|
||||
mov ax, [bp+var_6]
|
||||
add [bp+@@points], ax
|
||||
add [bp+var_6], 3
|
||||
mov ax, [bp+@@points]
|
||||
cmp ax, [bp+var_8]
|
||||
jbe short loc_17F64
|
||||
mov ax, [bp+var_8]
|
||||
mov [bp+@@points], ax
|
||||
|
||||
loc_17F64:
|
||||
mov [si+bullet_t.flag], 2
|
||||
cmp _bullet_zap_drop_point_items, 0
|
||||
jz short loc_17F86
|
||||
mov ax, [bp+var_2]
|
||||
mov bx, 4
|
||||
cwd
|
||||
idiv bx
|
||||
or dx, dx
|
||||
jnz short loc_17F86
|
||||
call items_add pascal, [si+bullet_t.pos.cur.x], [si+bullet_t.pos.cur.y], IT_POINT
|
||||
|
||||
loc_17F86:
|
||||
inc [bp+var_2]
|
||||
|
||||
loc_17F89:
|
||||
inc di
|
||||
sub si, size bullet_t
|
||||
|
||||
loc_17F8D:
|
||||
cmp di, BULLET_COUNT
|
||||
jl loc_17F0B
|
||||
cmp _popup_bonus, 0
|
||||
jz short loc_17FA8
|
||||
mov _popup_id_new, POPUP_ID_BONUS
|
||||
mov _popup, offset popup_update_and_render
|
||||
|
||||
loc_17FA8:
|
||||
inc _bullet_zap_active
|
||||
cmp [bp+@@patnum], 76 ; TH04 leftover; PAT_BULLET16_D in that game, unused here
|
||||
jb short loc_17FB7
|
||||
mov _bullet_zap_active, 0
|
||||
|
||||
loc_17FB7:
|
||||
cmp _bullet_clear_time, 0
|
||||
jz short loc_17FC2
|
||||
dec _bullet_clear_time
|
||||
|
||||
loc_17FC2:
|
||||
pop di
|
||||
pop si
|
||||
leave
|
||||
retf
|
||||
_bullets_update endp
|
||||
extern _bullets_update:proc
|
||||
main_033_TEXT ends
|
||||
|
||||
main_034_TEXT segment byte public 'CODE' use16
|
||||
|
|
Loading…
Reference in New Issue