[Decompilation] [th05] Shinki: Pattern 10/11

There one where… nah, you all know The Devil Pattern™.

Completes P0190, funded by nrook.
This commit is contained in:
nmlgc 2022-04-19 12:50:55 +02:00
parent 2027639c81
commit 293e16a052
3 changed files with 213 additions and 275 deletions

View File

@ -426,3 +426,211 @@ void near pattern_aimed_b6balls_and_symmetric_spreads(void)
#undef b6ball_interval
}
void near pattern_devil(void)
{
enum {
CLOCKWISE = 0,
COUNTERCLOCKWISE = 1,
COLUMN_COUNT = 4,
SHINKI_TO_LAST_COLUMN_DISTANCE = (
(SHINKI_WING_W / 2) - (SHINKI_WING_W / 8)
),
COLUMN_W = (SHINKI_WING_W / 4),
};
// Since the columns are symmetrical, it's only necessary to track the
// inner and outer angles for spread bullets and lasers.
#define laser_direction boss_statebyte[7]
#define laser_angle_inner boss_statebyte[8]
#define laser_angle_outer boss_statebyte[9]
#define lasers_active static_cast<bool>(boss_statebyte[10])
#define bullet_direction boss_statebyte[11]
#define bullet_intro_done static_cast<bool>(boss_statebyte[12])
#define b6ball_interval boss_statebyte[13]
#define bullet_angle_inner boss_statebyte[14]
#define bullet_angle_outer boss_statebyte[15]
#define laser_grow_delay shinki_devil_laser_grow_delay
extern int laser_grow_delay;
if(boss.phase_frame < 192) {
return;
}
int phase_frame_minus_startup_delay = (boss.phase_frame - 192);
// Laser activation
if((boss.hp <= 5600) || (boss.phase_frame >= 1800)) {
if(laser_grow_delay == 0) {
laser_template.coords.width = 6;
laser_template.coords.angle = 0x40;
laser_template.col = 0xE;
// Assign laser IDs from right to left
laser_template.coords.origin.x += SHINKI_TO_LAST_COLUMN_DISTANCE;
laser_manual_fixed_spawn(0);
laser_template.coords.origin.x -= COLUMN_W;
laser_manual_fixed_spawn(1);
laser_template.coords.origin.x -= COLUMN_W;
laser_manual_fixed_spawn(2);
laser_template.coords.origin.x -= COLUMN_W;
laser_manual_fixed_spawn(3);
laser_grow_delay++;
boss_explode_small(ET_CIRCLE);
}
}
// Spread bullets
if((boss.phase_frame % 4) == 0) {
if(phase_frame_minus_startup_delay == 0) {
bullet_angle_inner = 0x20;
bullet_angle_outer = 0x00;
b6ball_interval = select_for_rank(64, 40, 32, 28);
bullet_intro_done = false;
bullet_direction = CLOCKWISE;
lasers_active = false;
laser_angle_inner = 0x40;
laser_angle_outer = 0x40;
laser_direction = CLOCKWISE;
}
bullet_template.spawn_type = (BST_CLOUD_FORWARDS | BST_NO_SLOWDOWN);
bullet_template.patnum = PAT_BULLET16_V_RED;
bullet_template.group = BG_SPREAD;
if((bullet_angle_outer == 0x40) && (bullet_intro_done == 0)) {
bullet_intro_done++;
}
if(!bullet_intro_done) {
bullet_template.spread = 1;
} else {
bullet_template.spread = 3;
}
bullet_template.spread_angle_delta = 0x30;
bullet_template.speed.set(7.0f);
bullet_template.origin.x += SHINKI_TO_LAST_COLUMN_DISTANCE;
bullet_template.angle = bullet_angle_outer;
bullets_add_regular_fixedspeed();
bullet_template.origin.x -= COLUMN_W;
bullet_template.angle = bullet_angle_inner;
bullets_add_regular_fixedspeed();
bullet_template.origin.x -= COLUMN_W;
bullet_template.angle = (0x80 - bullet_angle_inner);
bullets_add_regular_fixedspeed();
bullet_template.origin.x -= COLUMN_W;
bullet_template.angle = (0x80 - bullet_angle_outer);
bullets_add_regular_fixedspeed();
if(!bullet_intro_done) {
bullet_angle_outer += 0x04;
bullet_angle_inner += 0x02;
} else {
// "Decorative" pellets aimed to the top of the playfield
bullet_template.patnum = 0;
bullet_template.spawn_type = BST_NO_SLOWDOWN;
bullet_template.set_spread(3, 0x30); // technically redundant
bullet_template.angle = (0x80 + bullet_angle_outer);
bullet_template.origin.x += (COLUMN_W * (COLUMN_COUNT - 1)),
bullets_add_regular_fixedspeed();
bullet_template.origin.x -= COLUMN_W,
bullet_template.angle = (0x80 + bullet_angle_inner);
bullets_add_regular_fixedspeed();
bullet_template.origin.x -= COLUMN_W,
bullet_template.angle = (0x00 - bullet_angle_inner);
bullets_add_regular_fixedspeed();
bullet_template.origin.x -= COLUMN_W,
bullet_template.angle = (0x00 - bullet_angle_outer);
bullets_add_regular_fixedspeed();
if(bullet_direction == CLOCKWISE) {
bullet_angle_outer -= 0x02;
bullet_angle_inner--;
if(bullet_angle_outer == 0x30) {
bullet_direction++; // = COUNTERCLOCKWISE;
}
} else /* if(bullet_direction == COUNTERCLOCKWISE) */ {
bullet_angle_outer += 0x02;
bullet_angle_inner++;
if(bullet_angle_outer == 0x40) {
bullet_direction--; // = CLOCKWISE;
}
}
}
// Aimed 32×32 balls
if(bullet_intro_done && ((boss.phase_frame % b6ball_interval) == 0)) {
b6ball_template.origin.x.v = shinki_wing_random_x();
b6ball_template.origin.y.v = shinki_wing_random_y();
b6ball_template.angle = player_angle_from(b6ball_template.origin);
b6ball_template.speed.set(3.75f);
b6ball_template.patnum_tiny = PAT_B6BALL_PURPLE;
b6balls_add();
}
snd_se_play(3);
}
// Lasers
if(laser_grow_delay == 0) {
return;
} else if(laser_grow_delay < 64) {
laser_grow_delay++;
} else if(laser_grow_delay == 64) {
// MODDERS: Turn into a loop
laser_manual_grow(0);
laser_manual_grow(1);
laser_manual_grow(2);
laser_manual_grow(3);
laser_grow_delay++;
} else if(!lasers_active) {
if(bullet_angle_outer == 0x30) {
lasers_active++;
}
} else if((boss.phase_frame % 8) == 0) {
lasers[0].coords.angle = laser_angle_outer;
lasers[1].coords.angle = laser_angle_inner;
lasers[2].coords.angle = (0x80 - lasers[1].coords.angle);
lasers[3].coords.angle = (0x80 - lasers[0].coords.angle);
if(laser_direction == CLOCKWISE) {
laser_angle_outer++;
laser_angle_inner--;
if(laser_angle_inner == 0x38) {
laser_direction++; // = COUNTERCLOCKWISE;
}
} else /* if(laser_direction == COUNTERCLOCKWISE) */ {
laser_angle_outer--;
laser_angle_inner++;
if(laser_angle_inner == 0x41) {
laser_direction--; // = CLOCKWISE;
}
}
if((boss.hp <= 3800) || (boss.phase_frame >= 2500)) {
if((laser_grow_delay++) == 65) {
b6ball_interval = select_for_rank(52, 20, 16, 12);
boss_explode_small(ET_CIRCLE);
}
}
}
#undef laser_grow_delay
#undef bullet_angle_outer
#undef bullet_angle_inner
#undef b6ball_interval
#undef bullet_intro_done
#undef bullet_direction
#undef lasers_active
#undef laser_angle_outer
#undef laser_angle_inner
#undef laser_direction
}

View File

@ -138,7 +138,7 @@ b6ball_t struc
B6B_patnum_tiny dw ?
dw ?
dw ?
B6B_speed db ?
db ?
db ?
b6ball_t ends

View File

@ -19186,282 +19186,11 @@ BOSS_6_TEXT segment byte public 'CODE' use16
@pattern_cheetos_within_spread_wa$qv procdesc near
@pattern_wings_to_purple$qv procdesc near
@pattern_aimed_b6balls_and_symmet$qv procdesc near
@pattern_devil$qv procdesc near
BOSS_6_TEXT ends
BOSS_X_TEXT segment byte public 'CODE' use16
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_1DD00 proc near
var_2 = word ptr -2
enter 2, 0
cmp _boss_phase_frame, 192
jl locret_1E020
mov ax, _boss_phase_frame
add ax, -192
mov [bp+var_2], ax
cmp _boss_hp, 5600
jle short loc_1DD27
cmp _boss_phase_frame, 1800
jl short loc_1DD72
loc_1DD27:
cmp word_22852, 0
jnz short loc_1DD72
mov _laser_template.coords.LASER_width, 6
mov _laser_template.coords.angle, 64
mov _laser_template.LASER_color, 14
add _laser_template.coords.origin.x, (96 shl 4)
call @laser_manual_fixed_spawn$qi pascal, 0
sub _laser_template.coords.origin.x, (64 shl 4)
call @laser_manual_fixed_spawn$qi pascal, 1
sub _laser_template.coords.origin.x, (64 shl 4)
call @laser_manual_fixed_spawn$qi pascal, 2
sub _laser_template.coords.origin.x, (64 shl 4)
call @laser_manual_fixed_spawn$qi pascal, 3
inc word_22852
call @boss_explode_small$q16explosion_type_t pascal, ET_CIRCLE
loc_1DD72:
mov ax, _boss_phase_frame
mov bx, 4
cwd
idiv bx
or dx, dx
jnz loc_1DF48
cmp [bp+var_2], 0
jnz short loc_1DDC3
mov _boss_statebyte[14], 20h
mov _boss_statebyte[15], 0
push (64 shl 16) or 40
push (32 shl 16) or 28
call select_for_rank
mov _boss_statebyte[13], al
mov _boss_statebyte[12], 0
mov _boss_statebyte[11], 0
mov _boss_statebyte[10], 0
mov _boss_statebyte[8], 40h
mov _boss_statebyte[9], 40h
mov _boss_statebyte[7], 0
loc_1DDC3:
mov _bullet_template.spawn_type, BST_CLOUD_FORWARDS or BST_NO_SLOWDOWN
mov _bullet_template.patnum, PAT_BULLET16_V_RED
mov _bullet_template.BT_group, BG_SPREAD
cmp _boss_statebyte[15], 40h
jnz short loc_1DDE4
cmp _boss_statebyte[12], 0
jnz short loc_1DDE4
inc _boss_statebyte[12]
loc_1DDE4:
cmp _boss_statebyte[12], 0
jnz short loc_1DDF2
mov _bullet_template.spread, 1
jmp short loc_1DDF7
; ---------------------------------------------------------------------------
loc_1DDF2:
mov _bullet_template.spread, 3
loc_1DDF7:
mov _bullet_template.spread_angle_delta, 48
mov _bullet_template.speed, (7 shl 4)
add _bullet_template.BT_origin.x, (96 shl 4)
mov al, _boss_statebyte[15]
mov _bullet_template.BT_angle, al
call _bullets_add_regular_fixedspeed
sub _bullet_template.BT_origin.x, (64 shl 4)
mov al, _boss_statebyte[14]
mov _bullet_template.BT_angle, al
call _bullets_add_regular_fixedspeed
sub _bullet_template.BT_origin.x, (64 shl 4)
mov al, 80h
sub al, _boss_statebyte[14]
mov _bullet_template.BT_angle, al
call _bullets_add_regular_fixedspeed
sub _bullet_template.BT_origin.x, (64 shl 4)
mov al, 80h
sub al, _boss_statebyte[15]
mov _bullet_template.BT_angle, al
call _bullets_add_regular_fixedspeed
cmp _boss_statebyte[12], 0
jnz short loc_1DE5D
mov al, _boss_statebyte[15]
add al, 4
mov _boss_statebyte[15], al
mov al, _boss_statebyte[14]
add al, 2
mov _boss_statebyte[14], al
jmp loc_1DEEA
; ---------------------------------------------------------------------------
loc_1DE5D:
mov _bullet_template.patnum, 0
mov _bullet_template.spawn_type, BST_NO_SLOWDOWN
mov word ptr _bullet_template.spread, (48 shl 8) or 3
mov al, _boss_statebyte[15]
add al, 80h
mov _bullet_template.BT_angle, al
add _bullet_template.BT_origin.x, (192 shl 4)
call _bullets_add_regular_fixedspeed
sub _bullet_template.BT_origin.x, (64 shl 4)
mov al, _boss_statebyte[14]
add al, 80h
mov _bullet_template.BT_angle, al
call _bullets_add_regular_fixedspeed
sub _bullet_template.BT_origin.x, (64 shl 4)
mov al, 0
sub al, _boss_statebyte[14]
mov _bullet_template.BT_angle, al
call _bullets_add_regular_fixedspeed
sub _bullet_template.BT_origin.x, (64 shl 4)
mov al, 0
sub al, _boss_statebyte[15]
mov _bullet_template.BT_angle, al
call _bullets_add_regular_fixedspeed
cmp _boss_statebyte[11], 0
jnz short loc_1DED3
mov al, _boss_statebyte[15]
add al, -2
mov _boss_statebyte[15], al
dec _boss_statebyte[14]
cmp _boss_statebyte[15], 30h
jnz short loc_1DEEA
inc _boss_statebyte[11]
jmp short loc_1DEEA
; ---------------------------------------------------------------------------
loc_1DED3:
mov al, _boss_statebyte[15]
add al, 2
mov _boss_statebyte[15], al
inc _boss_statebyte[14]
cmp _boss_statebyte[15], 40h
jnz short loc_1DEEA
dec _boss_statebyte[11]
loc_1DEEA:
cmp _boss_statebyte[12], 0
jz short loc_1DF41
mov al, _boss_statebyte[13]
mov ah, 0
push ax
mov ax, _boss_phase_frame
cwd
pop bx
idiv bx
or dx, dx
jnz short loc_1DF41
push (256 shl 4)
call randring2_next16_mod
add ax, _boss_pos.cur.x
sub ax, (128 shl 4)
mov b6ball_template.pos.cur.x, ax
push (64 shl 4)
call randring2_next16_mod
mov dx, _boss_pos.cur.y
sub dx, ax
add dx, (16 shl 4)
mov b6ball_template.pos.cur.y, dx
call @player_angle_from$q20%SubpixelBase$ti$ti%t1uc pascal, b6ball_template.pos.cur.x, dx, 0
mov b6ball_template.B6B_angle, al
mov b6ball_template.B6B_speed, (3 shl 4) + 12
mov b6ball_template.B6B_patnum_tiny, PAT_B6BALL_PURPLE
call @b6balls_add$qv
loc_1DF41:
call snd_se_play pascal, 3
loc_1DF48:
cmp word_22852, 0
jz locret_1E020
cmp word_22852, 40h
jl short loc_1DF73
cmp word_22852, 40h
jnz short loc_1DF79
call @laser_manual_grow$qi pascal, 0
call @laser_manual_grow$qi pascal, 1
call @laser_manual_grow$qi pascal, 2
call @laser_manual_grow$qi pascal, 3
loc_1DF73:
inc word_22852
leave
retn
; ---------------------------------------------------------------------------
loc_1DF79:
cmp _boss_statebyte[10], 0
jnz short loc_1DF8F
cmp _boss_statebyte[15], 30h
jnz locret_1E020
inc _boss_statebyte[10]
leave
retn
; ---------------------------------------------------------------------------
loc_1DF8F:
mov ax, _boss_phase_frame
mov bx, 8
cwd
idiv bx
or dx, dx
jnz locret_1E020
mov al, _boss_statebyte[9]
mov _lasers[0 * size laser_t].coords.angle, al
mov al, _boss_statebyte[8]
mov _lasers[1 * size laser_t].coords.angle, al
mov al, 128
sub al, _lasers[1 * size laser_t].coords.angle
mov _lasers[2 * size laser_t].coords.angle, al
mov al, 128
sub al, _lasers[0 * size laser_t].coords.angle
mov _lasers[3 * size laser_t].coords.angle, al
cmp _boss_statebyte[7], 0
jnz short loc_1DFD8
inc _boss_statebyte[9]
dec _boss_statebyte[8]
cmp _boss_statebyte[8], 38h ; '8'
jnz short loc_1DFEB
inc _boss_statebyte[7]
jmp short loc_1DFEB
; ---------------------------------------------------------------------------
loc_1DFD8:
dec _boss_statebyte[9]
inc _boss_statebyte[8]
cmp _boss_statebyte[8], 41h ; 'A'
jnz short loc_1DFEB
dec _boss_statebyte[7]
loc_1DFEB:
cmp _boss_hp, 3800
jle short loc_1DFFB
cmp _boss_phase_frame, 2500
jl short locret_1E020
loc_1DFFB:
mov ax, word_22852
inc word_22852
cmp ax, 41h ; 'A'
jnz short locret_1E020
push (52 shl 16) or 20
push (16 shl 16) or 12
call select_for_rank
mov _boss_statebyte[13], al
call @boss_explode_small$q16explosion_type_t pascal, ET_CIRCLE
locret_1E020:
leave
retn
sub_1DD00 endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
@ -19882,7 +19611,7 @@ loc_1E465:
cmp _boss_statebyte[10], 0
jnz short loc_1E488
call @boss_phase_next$q16explosion_type_ti pascal, (ET_SW_NE shl 16) or 2800
mov fp_2CE4A, offset sub_1DD00
mov fp_2CE4A, offset @pattern_devil$qv
loc_1E47B:
mov _boss_phase_frame, 0
@ -22502,7 +22231,8 @@ off_2284A dw offset @pattern_curved_rings$qv
dw offset @pattern_dualspeed_rings$qv
dw offset @pattern_random_directional_and_k$qv
dw offset @pattern_dense_blue_stacks$qv
word_22852 dw 0
public _shinki_devil_laser_grow_delay
_shinki_devil_laser_grow_delay dw 0
byte_22854 db 0
db 0
word_22856 dw 0