[Decompilation] [th04] Bullets: Regular spawn function

Part of P0150, funded by Blue Bolt.
This commit is contained in:
nmlgc 2021-06-27 15:28:58 +02:00
parent d876eeb7bd
commit 18e755d99b
9 changed files with 123 additions and 140 deletions

View File

@ -15,6 +15,9 @@ Example:
| `[bp-1]` | `char var_2;` |
| `[bp-2]` | `char var_3;` |
* Local `enum` variables with underlying 1-byte types are always word-aligned,
regardless of the value of `-a`.
### Grouping
Any structures or classes that contain more than a single scalar-type member

View File

@ -87,7 +87,15 @@ template <class T> struct SPPointBase {
// 16-bit (Q12.4)
typedef SubpixelBase<subpixel_t, pixel_t> Subpixel;
typedef SPPointBase<Subpixel> SPPoint;
struct SPPoint : public SPPointBase<Subpixel> {
void set_long(subpixel_t subpixel_x, subpixel_t subpixel_y) {
reinterpret_cast<uint32_t &>(x) = (
subpixel_x | (static_cast<uint32_t>(subpixel_y) << 16)
);
}
};
// 8-bit (Q4.4)
typedef SubpixelBase<unsigned char, unsigned char> SubpixelLength8;
typedef SubpixelBase<char, char> Subpixel8;

View File

@ -458,3 +458,102 @@ bool near bullet_template_clip(void)
}
return false;
}
#define bullet_set_spawn_vars(ptr, available, spawn_state, spawn_type) \
spawn_state = BSS_GRAZEABLE; \
switch(spawn_type) { \
case BST_PELLET: \
ptr = &pellets[PELLET_COUNT - 1]; \
available = PELLET_COUNT; \
break; \
case BST_BULLET16_CLOUD_BACKWARDS: \
spawn_state = BSS_CLOUD_BACKWARDS; \
goto bullet16; \
case BST_BULLET16_CLOUD_FORWARDS: \
spawn_state = BSS_CLOUD_FORWARDS; \
goto bullet16; \
default: \
bullet16: \
ptr = &bullets16[BULLET16_COUNT - 1]; \
available = BULLET16_COUNT; \
break; \
}
#define bullet_init_from_template(bullet, group_done, group_i, spawn_state) \
bullet->age = 0; \
bullet->pos.cur = bullet_template.origin; \
bullet->from_group = bullet_template.group; \
bullet->patnum = bullet_template.patnum; \
bullet->spawn_state = static_cast<bullet_spawn_state_t>(spawn_state); \
\
group_done = bullet_velocity_and_angle_set(group_i); \
\
if(bullet_template.patnum >= PAT_BULLET16_D) { \
bullet->patnum += bullet_patnum_for_angle(group_i_absolute_angle); \
} \
\
bullet->pos.velocity = bullet_template.velocity; \
bullet->angle = group_i_absolute_angle; \
bullet->speed_final = bullet_template.speed; \
bullet->speed_cur = bullet_template.speed; \
void pascal near bullets_add_regular_raw(void)
{
bullet_t near *bullet;
int group_i;
int bullets_available;
unsigned char move_state;
bool group_done;
unsigned char spawn_state; // MODDERS: Should be bullet_spawn_state_t
if(bullet_template.spawn_type == BST_GATHER_PELLET) {
gather_template.center = bullet_template.origin;
gather_template.velocity.set_long(0.0f, 0.0f);
gather_template.radius.set(GATHER_RADIUS_START);
gather_template.angle_delta = 0x02;
gather_template.col = 9;
gather_template.ring_points = 8;
bullet_template.spawn_type = BST_PELLET;
gather_add_bullets();
return;
}
if(bullet_template_clip()) {
return;
}
bullet_set_spawn_vars(
bullet, bullets_available, spawn_state, bullet_template.spawn_type
);
move_state = BMS_REGULAR;
if(
(bullet_template.speed < to_sp8(BMS_SLOWDOWN_THRESHOLD)) ||
bullet_clear_time
) {
if(
(bullet_template.group != BG_STACK) &&
(bullet_template.group != BG_STACK_AIMED)
) {
move_state = BMS_SLOWDOWN;
}
}
group_i = 0;
while(bullets_available > 0) {
if(bullet->flag == 0) {
bullet->flag = 1;
bullet->move_state = static_cast<bullet_move_state_t>(move_state);
bullet->ax.slowdown_time = BMS_SLOWDOWN_FRAMES;
bullet->dx.slowdown_speed_delta = (
to_sp8(BMS_SLOWDOWN_BASE_SPEED) - bullet_template.speed
);
bullet_init_from_template(bullet, group_done, group_i, spawn_state);
if(group_done) {
break;
}
group_i++;
}
bullets_available--;
bullet--;
}
}

View File

@ -15,7 +15,14 @@
/// bullet.hpp!
#define BSS_CLOUD_FRAMES (BULLET_CLOUD_CELS * 4)
#define BMS_DECAY_FRAMES (BULLET_DECAY_CELS * 4)
// 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
// gradually slows them down to their given speed over the next
// BMS_SLOWDOWN_FRAMES.
// • In TH04, this is not done for stacks.
#define BMS_SLOWDOWN_BASE_SPEED 4.5f
#define BMS_SLOWDOWN_THRESHOLD (BMS_SLOWDOWN_BASE_SPEED - 0.5f)
#define BMS_SLOWDOWN_FRAMES 32
enum bullet_spawn_state_t {

View File

@ -6,6 +6,7 @@
BSS_CLOUD_FRAMES = 16
BMS_DECAY_FRAMES = 16
BMS_SLOWDOWN_BASE_SPEED = (4 shl 4) + 8
BMS_SLOWDOWN_THRESHOLD = (BMS_SLOWDOWN_BASE_SPEED - 8)
BMS_SLOWDOWN_FRAMES = 32
; bullet_spawn_state_t

View File

@ -34,6 +34,7 @@ struct gather_template_t {
#define GATHER_POINT_W 8
#define GATHER_POINT_H 8
#define GATHER_FRAMES 32
#define GATHER_RADIUS_START 64.0f
#define GATHER_RADIUS_END 2.0f
#define GATHER_COUNT 16

View File

@ -28,6 +28,7 @@ gather_template_t ends
GATHER_POINT_W = 8
GATHER_POINT_H = 8
GATHER_FRAMES = 32
GATHER_RADIUS_START = (64 shl 4)
GATHER_RADIUS_END = (2 shl 4)
GATHER_COUNT = 16

View File

@ -15,10 +15,12 @@ extern "C" {
#include "th04/math/motion.hpp"
#include "th04/math/randring.h"
#include "th04/math/vector.hpp"
#include "th04/sprites/main_pat.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/gather.hpp"
#pragma option -a2
#include "th04/main/bullet/add.cpp"

View File

@ -28232,145 +28232,6 @@ main_033_TEXT segment byte public 'CODE' use16
angle:byte
_bullet_template_clip procdesc near
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
public BULLETS_ADD_REGULAR_RAW
bullets_add_regular_raw proc near
@@spawn_state = byte ptr -5
@@done = byte ptr -4
@@move_state = byte ptr -3
@@i = word ptr -2
push bp
mov bp, sp
sub sp, 6
push si
push di
cmp _bullet_template.spawn_type, BST_GATHER_PELLET
jnz short loc_1D2D5
mov eax, _bullet_template.BT_origin
mov _gather_template.GT_center, eax
mov _gather_template.GT_velocity, 0
mov _gather_template.GT_radius, (64 shl 4)
mov _gather_template.GT_angle_delta, 2
mov _gather_template.GT_col, 9
mov _gather_template.GT_ring_points, 8
mov _bullet_template.spawn_type, BST_PELLET
call _gather_add_bullets
jmp loc_1D3BB
; ---------------------------------------------------------------------------
loc_1D2D5:
call _bullet_template_clip
or al, al
jnz loc_1D3BB
mov [bp+@@spawn_state], BSS_GRAZEABLE
mov al, _bullet_template.spawn_type
mov ah, 0
cmp ax, BST_PELLET
jz short @@pellet
cmp ax, BST_BULLET16_CLOUD_FORWARDS
jz short @@cloud_forwards
cmp ax, BST_BULLET16_CLOUD_BACKWARDS
jz short @@cloud_backwards
jmp short loc_1D30C
; ---------------------------------------------------------------------------
@@pellet:
mov si, offset _pellets[(PELLET_COUNT - 1) * size bullet_t]
mov [bp+@@i], PELLET_COUNT
jmp short loc_1D314
; ---------------------------------------------------------------------------
@@cloud_backwards:
mov [bp+@@spawn_state], BSS_CLOUD_BACKWARDS
jmp short loc_1D30C
; ---------------------------------------------------------------------------
@@cloud_forwards:
mov [bp+@@spawn_state], BSS_CLOUD_FORWARDS
loc_1D30C:
mov si, offset _bullets16[(BULLET16_COUNT - 1) * size bullet_t]
mov [bp+@@i], BULLET16_COUNT
loc_1D314:
mov [bp+@@move_state], BMS_REGULAR
cmp _bullet_template.speed, (4 shl 4)
jb short loc_1D326
cmp _bullet_clear_time, 0
jz short loc_1D338
loc_1D326:
cmp _bullet_template.BT_group, BG_STACK
jz short loc_1D338
cmp _bullet_template.BT_group, BG_STACK_AIMED
jz short loc_1D338
mov [bp+@@move_state], BMS_SLOWDOWN
loc_1D338:
xor di, di
jmp short loc_1D3B5
; ---------------------------------------------------------------------------
loc_1D33C:
cmp [si+bullet_t.flag], 0
jnz short loc_1D3AF
mov [si+bullet_t.flag], 1
mov al, [bp+@@move_state]
mov [si+bullet_t.move_state], al
mov [si+bullet_t.slowdown_time], BMS_SLOWDOWN_FRAMES
mov al, BMS_SLOWDOWN_BASE_SPEED
sub al, _bullet_template.speed
mov [si+bullet_t.slowdown_speed_delta], al
mov [si+bullet_t.age], 0
mov eax, _bullet_template.BT_origin
mov dword ptr [si+bullet_t.pos.cur], eax
mov al, _bullet_template.BT_group
mov [si+bullet_t.from_group], al
mov al, _bullet_template.patnum
mov ah, 0
mov [si+bullet_t.BULLET_patnum], ax
mov al, [bp+@@spawn_state]
mov [si+bullet_t.spawn_state], al
call BULLET_VELOCITY_AND_ANGLE_SET pascal, di
mov [bp+@@done], al
cmp _bullet_template.patnum, PAT_BULLET16_D
jb short loc_1D391
call bullet_patnum_for_angle pascal, word ptr _group_i_absolute_angle
mov ah, 0
add [si+bullet_t.BULLET_patnum], ax
loc_1D391:
mov eax, _bullet_template.BT_velocity
mov dword ptr [si+bullet_t.pos.velocity], eax
mov al, _group_i_absolute_angle
mov [si+bullet_t.BULLET_angle], al
mov al, _bullet_template.speed
mov [si+bullet_t.speed_final], al
mov [si+bullet_t.speed_cur], al
cmp [bp+@@done], 0
jnz short loc_1D3BB
inc di
loc_1D3AF:
dec [bp+@@i]
sub si, size bullet_t
loc_1D3B5:
cmp [bp+@@i], 0
jg short loc_1D33C
loc_1D3BB:
pop di
pop si
leave
retn
bullets_add_regular_raw endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame