[Reverse-engineering] [th04/th05] Bullet-related sprite IDs

IDs based on Maribel Hearn's jargon page
(https://maribelhearn.com/jargon) as well as Sparen's Danmaku Design
Guide (https://sparen.github.io/ph3tutorials/ddsga1.html#sub2).

Part of P0074, funded by Myles.
This commit is contained in:
nmlgc 2020-02-12 21:22:49 +01:00
parent d6f356da45
commit eb0cf6820f
9 changed files with 191 additions and 54 deletions

View File

@ -2,8 +2,8 @@
/// ----------------
#pragma option -b-
#define BSS_CLOUD_FRAMES 16
#define BMS_DECAY_FRAMES 16
#define BSS_CLOUD_FRAMES (BULLET_CLOUD_CELS * 4)
#define BMS_DECAY_FRAMES (BULLET_DECAY_CELS * 4)
#define BMS_SLOWDOWN_BASE_SPEED 4.5f
#define BMS_SLOWDOWN_FRAMES 32

10
th04/sprites/cels.h Normal file
View File

@ -0,0 +1,10 @@
/// Animation frame counts
/// ----------------------
#define BULLET_CLOUD_CELS 4
#define BULLET_DECAY_CELS 4
// Directional bullets with one axis of symmetry; sprites cover 180 degrees
#define BULLET_D_CELS 16
// Vector bullets with no axis of symmetry; sprites cover all 360 degrees
#define BULLET_V_CELS 32
/// ----------------------

4
th04/sprites/cels.inc Normal file
View File

@ -0,0 +1,4 @@
BULLET_CLOUD_CELS = 4
BULLET_DECAY_CELS = 4
BULLET_D_CELS = 16
BULLET_V_CELS = 32

View File

@ -1,14 +1,48 @@
#include "th04/sprites/cels.h"
/// Stage-independent pattern numbers for the super_*() functions
/// -------------------------------------------------------------
/// Since super_entry_bfnt() doesn't take a "start patnum" parameter, the
/// order in which the files are loaded has to match the order here.
typedef enum {
// miko32.bft
// ----------
PAT_CLOUD_BULLET16_BLUE = 20,
PAT_CLOUD_BULLET16_BLUE_last = (PAT_CLOUD_BULLET16_BLUE + BULLET_CLOUD_CELS - 1),
PAT_CLOUD_BULLET16_RED,
// ----------
// miko16.bft
// ----------
PAT_OPTION_REIMU = 38,
PAT_OPTION_MARISA,
PAT_ITEM = 44,
PAT_BULLET16_N_OUTLINED_BALL_WHITE = 52,
PAT_BULLET16_N_OUTLINED_BALL_RED,
PAT_BULLET16_N_OUTLINED_BALL_GREEN,
PAT_BULLET16_N_OUTLINED_BALL_BLUE,
PAT_BULLET16_N_STAR,
PAT_BULLET16_N_BALL_BLUE,
PAT_BULLET16_N_SMALL_BALL_YELLOW,
PAT_BULLET16_N_CROSS_YELLOW,
PAT_BULLET16_N_SMALL_BALL_RED,
PAT_BULLET16_N_BALL_RED,
PAT_BULLET16_N_HEART_BALL_RED,
PAT_EXPLOSION_SMALL = 68,
PAT_BULLET_KILL = 72,
PAT_BULLET_KILL_last = (PAT_BULLET_KILL + BULLET_DECAY_CELS - 1),
PAT_BULLET16_D,
PAT_BULLET16_D_BLUE = PAT_BULLET16_D,
PAT_BULLET16_D_BLUE_last = (PAT_BULLET16_D_BLUE + BULLET_D_CELS - 1),
PAT_BULLET16_D_YELLOW, // Purple during the EX-Alice battle
PAT_BULLET16_D_YELLOW_last = (PAT_BULLET16_D_YELLOW + BULLET_D_CELS - 1),
PAT_DECAY_PELLET,
PAT_DECAY_PELLET_last = (PAT_DECAY_PELLET + BULLET_DECAY_CELS - 1),
PAT_DECAY_BULLET16,
PAT_DECAY_BULLET16_last = (PAT_DECAY_BULLET16 + BULLET_DECAY_CELS - 1),
// ----------
} main_patnum_t;
/// -------------------------------------------------------------

View File

@ -1,4 +1,25 @@
include th04/sprites/cels.inc
PAT_CLOUD_BULLET16_BLUE = 20
PAT_CLOUD_BULLET16_RED = 24
PAT_OPTION_REIMU = 38
PAT_OPTION_MARISA = 39
PAT_ITEM = 44
PAT_BULLET16_N_OUTLINED_BALL_WHITE = 52
PAT_BULLET16_N_OUTLINED_BALL_RED = 53
PAT_BULLET16_N_OUTLINED_BALL_GREEN = 54
PAT_BULLET16_N_OUTLINED_BALL_BLUE = 55
PAT_BULLET16_N_STAR = 56
PAT_BULLET16_N_BALL_BLUE = 57
PAT_BULLET16_N_SMALL_BALL_YELLOW = 58
PAT_BULLET16_N_CROSS_YELLOW = 59
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_KILL = 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

View File

@ -14116,32 +14116,32 @@ loc_12D24:
cmp [si+bullet_t.pos.cur.x], (PLAYFIELD_W shl 4)
jge short @@sprite_bullet_next
mov ax, [si+bullet_t.BULLET_patnum]
cmp ax, 54
cmp ax, PAT_BULLET16_N_OUTLINED_BALL_GREEN
jz short loc_12D50
cmp ax, 55
cmp ax, PAT_BULLET16_N_OUTLINED_BALL_BLUE
jz short loc_12D50
cmp ax, 57
cmp ax, PAT_BULLET16_N_BALL_BLUE
jnz short loc_12D57
loc_12D50:
mov [bp+@@patnum], 19
mov [bp+@@patnum], (PAT_CLOUD_BULLET16_BLUE - 1)
jmp short loc_12D5C
; ---------------------------------------------------------------------------
loc_12D57:
mov [bp+@@patnum], 23
mov [bp+@@patnum], (PAT_CLOUD_BULLET16_RED - 1)
loc_12D5C:
cmp [si+bullet_t.BULLET_patnum], 76
cmp [si+bullet_t.BULLET_patnum], PAT_BULLET16_D_BLUE
jl short loc_12D6D
cmp [si+bullet_t.BULLET_patnum], 92
cmp [si+bullet_t.BULLET_patnum], PAT_BULLET16_D_YELLOW
jge short loc_12D6D
mov [bp+@@patnum], 19
mov [bp+@@patnum], (PAT_CLOUD_BULLET16_BLUE - 1)
loc_12D6D:
mov al, [si+bullet_t.spawn_state]
mov ah, 0
mov bx, 4
mov bx, (BSS_CLOUD_FRAMES / BULLET_CLOUD_CELS)
cwd
idiv bx
add [bp+@@patnum], ax
@ -31041,7 +31041,7 @@ bullet_update_special endp
public BULLETS_UPDATE
bullets_update proc far
var_9 = byte ptr -9
@@patnum = byte ptr -9
var_8 = word ptr -8
var_6 = word ptr -6
var_4 = word ptr -4
@ -31079,12 +31079,12 @@ loc_1C8FE:
mov [si+bullet_t.move_state], BMS_DECAY
cmp di, BULLET16_COUNT
jge short loc_1C91D
mov ax, 112
mov ax, PAT_DECAY_BULLET16
jmp short loc_1C920
; ---------------------------------------------------------------------------
loc_1C91D:
mov ax, 108
mov ax, PAT_DECAY_PELLET
loc_1C920:
mov [si+bullet_t.BULLET_patnum], ax
@ -31112,7 +31112,7 @@ loc_1C939:
loc_1C94F:
mov al, [si+bullet_t.move_state]
mov ah, 0
mov bx, 4
mov bx, (BMS_DECAY_FRAMES / BULLET_DECAY_CELS)
cwd
idiv bx
or dx, dx
@ -31319,11 +31319,11 @@ loc_1CB3B:
loc_1CB44:
mov al, _bullet_clear_trigger
mov ah, 0
mov bx, 4
mov bx, BULLET_DECAY_CELS
cwd
idiv bx
add al, 48h ; 'H'
mov [bp+var_9], al
add al, PAT_BULLET_KILL
mov [bp+@@patnum], al
mov [bp+var_4], 1
mov [bp+var_6], 1
mov al, _rank
@ -31360,9 +31360,9 @@ loc_1CB91:
mov [si+bullet_t.pos.velocity.y], 0
lea ax, [si+bullet_t.pos]
call _motion_update_2 pascal, ax
cmp [bp+var_9], 76
cmp [bp+@@patnum], PAT_BULLET16_D
jnb short loc_1CBB7
mov al, [bp+var_9]
mov al, [bp+@@patnum]
mov ah, 0
mov [si+bullet_t.BULLET_patnum], ax
jmp short loc_1CBED
@ -31402,7 +31402,7 @@ loc_1CBF1:
loc_1CC0A:
inc _bullet_clear_trigger
cmp [bp+var_9], 4Ch ; 'L'
cmp [bp+@@patnum], PAT_BULLET16_D
jb short loc_1CC19
mov _bullet_clear_trigger, 0
@ -32554,7 +32554,7 @@ loc_1D33C:
push di
call sub_1CFC8
mov [bp+var_4], al
cmp byte_266E3, 4Ch ; 'L'
cmp byte_266E3, PAT_BULLET16_D
jb short loc_1D391
push word_2D008
call sub_1D218
@ -32665,7 +32665,7 @@ loc_1D40A:
push di
call sub_1CFC8
mov [bp+var_3], al
cmp byte_266E3, 4Ch ; 'L'
cmp byte_266E3, PAT_BULLET16_D
jb short loc_1D460
push word_2D008
call sub_1D218

View File

@ -1,8 +1,16 @@
#include "th04/sprites/cels.h"
/// Stage-independent pattern numbers for the super_*() functions
/// -------------------------------------------------------------
/// Since super_entry_bfnt() doesn't take a "start patnum" parameter, the
/// order in which the files are loaded has to match the order here.
typedef enum {
// miko32.bft
// ----------
PAT_CLOUD_BULLET16_BLUE = 12,
PAT_CLOUD_BULLET16_BLUE_last = (PAT_CLOUD_BULLET16_BLUE + BULLET_CLOUD_CELS - 1),
PAT_CLOUD_BULLET16_RED,
// ----------
// reimu16.bft / mari16.bft / mima16.bft / yuka16.bft
// --------------------------------------------------
PAT_SHOT_SUB = 22,
@ -11,7 +19,43 @@ typedef enum {
// miko16.bft
// ----------
PAT_ITEM = 36,
PAT_EXPLOSION_SMALL = 164,
// Non-directional bullets
PAT_BULLET16_N_BLUE = 44,
PAT_BULLET16_N_BALL_BLUE = PAT_BULLET16_N_BLUE,
PAT_BULLET16_N_OUTLINED_BALL_BLUE,
PAT_BULLET16_N_SMALL_BALL_BLUE,
PAT_BULLET16_N_CROSS_BLUE, // Green during the EX-Alice battle
PAT_BULLET16_N_RED,
PAT_BULLET16_N_BALL_RED = PAT_BULLET16_N_RED,
PAT_BULLET16_N_OUTLINED_BALL_RED,
PAT_BULLET16_N_SMALL_BALL_RED,
PAT_BULLET16_N_STAR,
// Directional bullets
PAT_BULLET16_D,
PAT_BULLET16_D_BLUE = PAT_BULLET16_D,
PAT_BULLET16_D_BLUE_last = (PAT_BULLET16_D_BLUE + BULLET_D_CELS - 1),
PAT_BULLET16_D_GREEN, // Purple during the EX-Alice battle
PAT_BULLET16_D_GREEN_last = (PAT_BULLET16_D_GREEN + BULLET_D_CELS - 1),
// Vector bullets
PAT_BULLET16_V,
PAT_BULLET16_V_RED = PAT_BULLET16_V,
PAT_BULLET16_V_RED_last = (PAT_BULLET16_V_RED + BULLET_V_CELS - 1),
PAT_BULLET16_V_BLUE, // Yellow during the EX-Alice battle
PAT_BULLET16_V_BLUE_last = (PAT_BULLET16_V_BLUE + BULLET_V_CELS - 1),
PAT_CLOUD_PELLET,
PAT_CLOUD_PELLET_last = (PAT_CLOUD_PELLET + BULLET_CLOUD_CELS - 1),
PAT_BULLET_KILL,
PAT_BULLET_KILL_last = (PAT_BULLET_KILL + BULLET_DECAY_CELS - 1),
PAT_DECAY_PELLET,
PAT_DECAY_PELLET_last = (PAT_DECAY_PELLET + BULLET_DECAY_CELS - 1),
PAT_DECAY_BULLET16,
PAT_DECAY_BULLET16_last = (PAT_DECAY_BULLET16 + BULLET_DECAY_CELS - 1),
PAT_EXPLOSION_SMALL,
// ----------
} main_patnum_t;
/// -------------------------------------------------------------

View File

@ -1,4 +1,28 @@
include th04/sprites/cels.inc
PAT_CLOUD_BULLET16_BLUE = 12
PAT_CLOUD_BULLET16_RED = 16
PAT_SHOT_SUB = 22
PAT_OPTION = 26
PAT_ITEM = 36
PAT_BULLET16_N_BLUE = 44
PAT_BULLET16_N_BALL_BLUE = PAT_BULLET16_N_BLUE
PAT_BULLET16_N_OUTLINED_BALL_BLUE = 45
PAT_BULLET16_N_SMALL_BALL_BLUE = 46
PAT_BULLET16_N_CROSS_BLUE = 47
PAT_BULLET16_N_RED = 48
PAT_BULLET16_N_BALL_RED = PAT_BULLET16_N_RED
PAT_BULLET16_N_OUTLINED_BALL_RED = 49
PAT_BULLET16_N_SMALL_BALL_RED = 50
PAT_BULLET16_STAR = 51
PAT_BULLET16_D = 52
PAT_BULLET16_D_BLUE = PAT_BULLET16_D
PAT_BULLET16_D_GREEN = 68
PAT_BULLET16_V = 84
PAT_BULLET16_V_RED = PAT_BULLET16_V
PAT_BULLET16_V_BLUE = 116
PAT_CLOUD_PELLET = 148
PAT_BULLET_KILL = 152
PAT_DECAY_PELLET = 156
PAT_DECAY_BULLET16 = 160
PAT_EXPLOSION_SMALL = 164

View File

@ -8366,31 +8366,31 @@ loc_10108:
jl short loc_1016B
cmp [si+bullet_t.pos.cur.x], ((PLAYFIELD_W + 16) shl 4) ; Huh?
jge short loc_1016B
cmp [si+bullet_t.BULLET_patnum], 48
cmp [si+bullet_t.BULLET_patnum], PAT_BULLET16_N_RED
jl short loc_10141
cmp [si+bullet_t.BULLET_patnum], 52
cmp [si+bullet_t.BULLET_patnum], PAT_BULLET16_D_BLUE
jl short loc_10134
cmp [si+bullet_t.BULLET_patnum], 68
cmp [si+bullet_t.BULLET_patnum], PAT_BULLET16_D_GREEN
jl short loc_10141
loc_10134:
cmp [si+bullet_t.BULLET_patnum], 116
cmp [si+bullet_t.BULLET_patnum], PAT_BULLET16_V_BLUE
jl short loc_10146
cmp [si+bullet_t.BULLET_patnum], 152
cmp [si+bullet_t.BULLET_patnum], (PAT_CLOUD_PELLET + BULLET_CLOUD_CELS)
jge short loc_10146
loc_10141:
mov di, 11
mov di, (PAT_CLOUD_BULLET16_BLUE - 1)
jmp short loc_10149
; ---------------------------------------------------------------------------
loc_10146:
mov di, 15
mov di, (PAT_CLOUD_BULLET16_RED - 1)
loc_10149:
mov al, [si+bullet_t.spawn_state]
mov ah, 0
mov bx, 4
mov bx, (BSS_CLOUD_FRAMES / BULLET_CLOUD_CELS)
cwd
idiv bx
add di, ax
@ -8421,10 +8421,10 @@ loc_1018A:
mov si, [bx-3D50h]
mov al, [si+bullet_t.spawn_state]
mov ah, 0
mov bx, 4
mov bx, (BSS_CLOUD_FRAMES / BULLET_CLOUD_CELS)
cwd
idiv bx
add ax, 147
add ax, (PAT_CLOUD_PELLET - 1)
mov di, ax
mov ax, [si+bullet_t.pos.cur.y]
add ax, (8 shl 4)
@ -13774,7 +13774,7 @@ sub_159E6 proc near
mov al, ss:[bx+2]
mov bx, ss:[bx+4]
add al, 3
cmp bx, 54h ; 'T'
cmp bx, PAT_BULLET16_V
jnb short loc_159F9
and al, 7Fh
@ -14272,7 +14272,7 @@ loc_15D95:
mov cl, al
mov al, byte ptr word_25FFA+1
mov ah, 0
cmp al, 34h ; '4'
cmp al, PAT_BULLET16_D
jb short loc_15DB5
push ax
push word ptr byte_25349
@ -17279,30 +17279,30 @@ var_1 = byte ptr -1
sub sp, 2
push si
mov si, [bp+@@bullet]
cmp [si+bullet_t.BULLET_patnum], 52
cmp [si+bullet_t.BULLET_patnum], PAT_BULLET16_D_BLUE
jl short loc_179BC
cmp [si+bullet_t.BULLET_patnum], 68
cmp [si+bullet_t.BULLET_patnum], PAT_BULLET16_D_GREEN
jge short loc_1798F
mov [bp+var_1], 52
mov [bp+var_1], PAT_BULLET16_D_BLUE
jmp short loc_179AB
; ---------------------------------------------------------------------------
loc_1798F:
cmp [si+bullet_t.BULLET_patnum], 84
cmp [si+bullet_t.BULLET_patnum], PAT_BULLET16_V_RED
jge short loc_1799B
mov [bp+var_1], 68
mov [bp+var_1], PAT_BULLET16_D_GREEN
jmp short loc_179AB
; ---------------------------------------------------------------------------
loc_1799B:
cmp [si+bullet_t.BULLET_patnum], 116
cmp [si+bullet_t.BULLET_patnum], PAT_BULLET16_V_BLUE
jge short loc_179A7
mov [bp+var_1], 84
mov [bp+var_1], PAT_BULLET16_V_RED
jmp short loc_179AB
; ---------------------------------------------------------------------------
loc_179A7:
mov [bp+var_1], 116
mov [bp+var_1], PAT_BULLET16_V_BLUE
loc_179AB:
mov al, [bp+var_1]
@ -17644,7 +17644,7 @@ bullet_update_special endp
sub_17C04 proc far
var_9 = byte ptr -9
@@patnum = byte ptr -9
var_8 = word ptr -8
var_6 = word ptr -6
var_4 = word ptr -4
@ -17683,12 +17683,12 @@ loc_17C40:
mov [si+bullet_t.move_state], BMS_DECAY
cmp di, BULLET16_COUNT
jge short loc_17C5F
mov ax, 160
mov ax, PAT_DECAY_BULLET16
jmp short loc_17C62
; ---------------------------------------------------------------------------
loc_17C5F:
mov ax, 156
mov ax, PAT_DECAY_PELLET
loc_17C62:
mov [si+bullet_t.BULLET_patnum], ax
@ -17716,7 +17716,7 @@ loc_17C7B:
loc_17C91:
mov al, [si+bullet_t.move_state]
mov ah, 0
mov bx, 4
mov bx, (BMS_DECAY_FRAMES / BULLET_DECAY_CELS)
cwd
idiv bx
or dx, dx
@ -17947,11 +17947,11 @@ loc_17EB5:
loc_17EC3:
mov al, _bullet_clear_trigger
mov ah, 0
mov bx, 4
mov bx, BULLET_DECAY_CELS
cwd
idiv bx
add al, 98h
mov [bp+var_9], al
add al, PAT_BULLET_KILL
mov [bp+@@patnum], al
mov [bp+var_4], 1
mov [bp+var_6], 1
cmp _rank, RANK_EXTRA
@ -17979,9 +17979,9 @@ loc_17F0B:
mov [si+bullet_t.pos.velocity.y], 0
lea ax, [si+bullet_t.pos]
call _motion_update_2 pascal, ax
cmp [bp+var_9], 4Ch ; 'L'
cmp [bp+@@patnum], 76 ; TH04 leftover; PAT_BULLET16_D in that game, unused here
jnb short loc_17F31
mov al, [bp+var_9]
mov al, [bp+@@patnum]
mov ah, 0
mov [si+bullet_t.BULLET_patnum], ax
jmp short loc_17F86
@ -18033,7 +18033,7 @@ loc_17F8D:
loc_17FA8:
inc _bullet_clear_trigger
cmp [bp+var_9], 4Ch ; 'L'
cmp [bp+@@patnum], 76 ; TH04 leftover; PAT_BULLET16_D in that game, unused here
jb short loc_17FB7
mov _bullet_clear_trigger, 0