[Decompilation] [th04] Bullets: Clipping and pre-spawn hit test

First place to confirm the hitbox of both the 8×8 pellets and the 16×16
sprite bullets!

Well, "hitbox". It's really more of a kill delta of 8×8 pixels between
the center points of a bullet and the player. You can distribute these
pixels to any combination of bullet and player "hitboxes" that make up
8×8. 4×4 around both the player and bullets? 1×1 for bullets, and 8×8
for the player? All equally valid… or perhaps none of them, once you
keep in mind that other entity types might have different kill deltas,
which turns the concept of a "hitbox" into just a confusing abstraction.

Part of P0150, funded by Blue Bolt.
This commit is contained in:
nmlgc 2021-06-26 15:30:39 +02:00
parent a49c854adc
commit d876eeb7bd
7 changed files with 49 additions and 56 deletions

View File

@ -22,3 +22,8 @@
#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))
#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)) \
)

View File

@ -1,6 +1,8 @@
#define PLAYER_W 32
#define PLAYER_H 48
extern bool player_is_hit;
// Grants invincibility when >0. Decrements by 1 each frame in that case.
// In TH02, this works independently from [player_invincible_via_bomb].
extern unsigned char player_invincibility_time;

View File

@ -428,3 +428,33 @@ unsigned char pascal near bullet_patnum_for_angle(unsigned char angle)
((angle + (ANGLE_PER_SPRITE / 2) - 1) & (0x80 - 1)) / ANGLE_PER_SPRITE
);
}
bool near bullet_template_clip(void)
{
if(
(bullet_clear_time > 0) &&
(bullet_clear_time <= (BMS_DECAY_FRAMES + 1))
) {
return true;
}
// Also applies to 8×8 pellets, because why wouldn't you combine both
// cases. #goodcode
if(!playfield_encloses_point(
bullet_template.origin, BULLET16_W, BULLET16_H
)) {
return true;
}
if(overlap_points_wh_fast(
bullet_template.origin,
player_pos.cur,
BULLET_KILLBOX_W,
BULLET_KILLBOX_H
)) {
player_is_hit = true;
return true;
}
if(!group_fixedspeed) {
bullet_template_speedtune_for_playperf();
}
return false;
}

View File

@ -91,6 +91,11 @@ struct bullet_t {
#define BULLET16_W 16
#define BULLET16_H 16
// Symmetrical around the center point of each bullet, and treated in relation
// to a 1×1 "hitbox" around the player's center point.
static const subpixel_t BULLET_KILLBOX_W = TO_SP(8);
static const subpixel_t BULLET_KILLBOX_H = TO_SP(8);
#if GAME == 5
# define PELLET_COUNT 180
# define BULLET16_COUNT 220

View File

@ -11,6 +11,7 @@ extern "C" {
#include "planar.h"
#include "master.hpp"
#include "th01/math/subpixel.hpp"
#include "th01/math/overlap.hpp"
#include "th04/math/motion.hpp"
#include "th04/math/randring.h"
#include "th04/math/vector.hpp"

View File

@ -28230,57 +28230,7 @@ main_033_TEXT segment byte public 'CODE' use16
_bullet_template_speedtune_for_pl procdesc near
BULLET_PATNUM_FOR_ANGLE procdesc pascal near \
angle:byte
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_1D230 proc near
push bp
mov bp, sp
cmp _bullet_clear_time, 0
jbe short loc_1D241
cmp _bullet_clear_time, 17
jbe short loc_1D282
loc_1D241:
cmp _bullet_template.BT_origin.x, (-8 shl 4)
jle short loc_1D282
cmp _bullet_template.BT_origin.x, ((PLAYFIELD_W + 8) shl 4)
jge short loc_1D282
cmp _bullet_template.BT_origin.y, (-8 shl 4)
jle short loc_1D282
cmp _bullet_template.BT_origin.y, ((PLAYFIELD_H + 8) shl 4)
jge short loc_1D282
mov ax, _bullet_template.BT_origin.x
sub ax, _player_pos.cur.x
add ax, (4 shl 4)
cmp ax, (8 shl 4)
ja short loc_1D286
mov ax, _bullet_template.BT_origin.y
sub ax, _player_pos.cur.y
add ax, (4 shl 4)
cmp ax, (8 shl 4)
ja short loc_1D286
mov _player_is_hit, 1
loc_1D282:
mov al, 1
pop bp
retn
; ---------------------------------------------------------------------------
loc_1D286:
cmp _group_fixedspeed, 0
jnz short loc_1D290
call _bullet_template_speedtune_for_pl
loc_1D290:
mov al, 0
pop bp
retn
sub_1D230 endp
_bullet_template_clip procdesc near
; =============== S U B R O U T I N E =======================================
@ -28313,7 +28263,7 @@ bullets_add_regular_raw proc near
; ---------------------------------------------------------------------------
loc_1D2D5:
call sub_1D230
call _bullet_template_clip
or al, al
jnz loc_1D3BB
mov [bp+@@spawn_state], BSS_GRAZEABLE
@ -28436,7 +28386,7 @@ bullets_add_special_raw proc near
sub sp, 4
push si
push di
call sub_1D230
call _bullet_template_clip
or al, al
jnz loc_1D48A
mov [bp+@@spawn_state], 0

View File

@ -10388,7 +10388,7 @@ sub_15AAA endp
; =============== S U B R O U T I N E =======================================
sub_15C36 proc near
_bullet_template_clip proc near
cmp _bullet_clear_time, 0
jz short loc_15C47
cmp _bullet_clear_time, 17
@ -10430,7 +10430,7 @@ loc_15C81:
loc_15C91:
mov al, 0
retn
sub_15C36 endp
_bullet_template_clip endp
; ---------------------------------------------------------------------------
@ -10463,7 +10463,7 @@ locret_15CE4:
; ---------------------------------------------------------------------------
loc_15CE5:
call sub_15C36
call _bullet_template_clip
or al, al
jnz short locret_15CE4
push si