From d876eeb7bd98859c6eb78ea61346bd612d6c08c0 Mon Sep 17 00:00:00 2001 From: nmlgc Date: Sat, 26 Jun 2021 15:30:39 +0200 Subject: [PATCH] [Decompilation] [th04] Bullets: Clipping and pre-spawn hit test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- th01/math/overlap.hpp | 5 ++++ th02/main/player/player.h | 2 ++ th04/main/bullet/add.cpp | 30 ++++++++++++++++++++ th04/main/bullet/bullet.hpp | 5 ++++ th04/main032.cpp | 1 + th04_main.asm | 56 ++----------------------------------- th05_main.asm | 6 ++-- 7 files changed, 49 insertions(+), 56 deletions(-) diff --git a/th01/math/overlap.hpp b/th01/math/overlap.hpp index 1470c6c6..ac09f9b6 100644 --- a/th01/math/overlap.hpp +++ b/th01/math/overlap.hpp @@ -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)) \ +) diff --git a/th02/main/player/player.h b/th02/main/player/player.h index 9113bcb3..242467c2 100644 --- a/th02/main/player/player.h +++ b/th02/main/player/player.h @@ -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; diff --git a/th04/main/bullet/add.cpp b/th04/main/bullet/add.cpp index 6b9d3845..f4ca6448 100644 --- a/th04/main/bullet/add.cpp +++ b/th04/main/bullet/add.cpp @@ -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; +} diff --git a/th04/main/bullet/bullet.hpp b/th04/main/bullet/bullet.hpp index 1f036ada..503f0498 100644 --- a/th04/main/bullet/bullet.hpp +++ b/th04/main/bullet/bullet.hpp @@ -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 diff --git a/th04/main032.cpp b/th04/main032.cpp index c3ae1d0e..01c5f3e0 100644 --- a/th04/main032.cpp +++ b/th04/main032.cpp @@ -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" diff --git a/th04_main.asm b/th04_main.asm index 14c7bbd0..3cf774c7 100644 --- a/th04_main.asm +++ b/th04_main.asm @@ -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 diff --git a/th05_main.asm b/th05_main.asm index f342d37c..7ae50fb3 100644 --- a/th05_main.asm +++ b/th05_main.asm @@ -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