[Decompilation] [th01] Sariel: Pattern 13/16

The one where decelerating pellets form a curve shape, by being fired
from the center and aimed along the bottom left and right edges of the
playfield.

First pattern of Sariel's second form… which is where ZUN apparently
learned to pass the frame count as a parameter. Would have been even
nicer if the return value indicated when the pattern is done instead of
mutating a reference to the frame count.

Completes P0179, funded by Ember2528.
This commit is contained in:
nmlgc 2022-01-17 13:11:00 +01:00
parent 28e2780050
commit 9e5b344af1
2 changed files with 99 additions and 98 deletions

View File

@ -108,6 +108,7 @@ extern union {
int speed_multiplied_by_8;
int interval;
int start_frame;
pixel_t velocity_x;
int unknown;
} pattern_state;
extern bool16 invincible;
@ -2284,3 +2285,88 @@ void pascal near particles2x2_horizontal_unput_update_render(int frame)
#undef left
#undef col
}
struct CurvedSpray {
screen_point_t target;
Subpixel speed;
unsigned char angle; // should be local
int subpattern_id; // controlled by the pattern
void init(void) {
target.x = PLAYFIELD_LEFT;
target.y = PLAYFIELD_BOTTOM;
speed.set(7.0f);
subpattern_id = 0;
// Divisor = number of pellets effectively fired per direction.
select_for_rank(pattern_state.velocity_x,
(PLAYFIELD_W / 20),
(PLAYFIELD_W / 26.66),
(PLAYFIELD_W / 35.55),
(PLAYFIELD_W / 40)
);
}
void fire_and_advance(x_direction_t dir) {
angle = iatan2((target.y - SEAL_CENTER_Y), (target.x - SEAL_CENTER_X));
Pellets.add_single(SEAL_CENTER_X, SEAL_CENTER_Y, angle, speed);
speed -= 0.25f;
if(dir == X_RIGHT) {
target.x += pattern_state.velocity_x;
} else {
target.x -= pattern_state.velocity_x;
}
}
void reset(screen_x_t new_target) {
speed.set(7.0f);
target.x = new_target;
}
};
void pascal near pattern_curved_spray_leftright_once(int &frame)
{
#define spray pattern12_spray
extern CurvedSpray spray;
if(frame < 50) {
return;
} else if(frame == 50) {
dottedcircle_unput_update_render(
SEAL_CENTER_X, SEAL_CENTER_Y, 1, 4, 16, V_WHITE, 32, 160
);
}
// The duration can be calculated as:
//
// target_radius = √((RES_X - SEAL_CENTER_X)² + (RES_Y - SEAL_CENTER_Y)²)
// duration = (((target_radius - radius_initial) / radius_step) * interval)
//
// Good luck doing that at compile time, but given the variables defined
// here, the result does come out as 88.38. So, close enough.
dottedcircle_unput_update_render(
SEAL_CENTER_X, SEAL_CENTER_Y, ((frame - 50) + 1), 4, 16, V_WHITE, 32, 90
);
if(frame < 100) {
return;
} else if(frame == 100) {
spray.init();
}
if(spray.subpattern_id == 0) {
spray.fire_and_advance(X_RIGHT);
if(spray.target.x >= PLAYFIELD_RIGHT) {
spray.subpattern_id = 1;
spray.reset(PLAYFIELD_RIGHT);
}
} else {
spray.fire_and_advance(X_LEFT);
if(spray.target.x < PLAYFIELD_LEFT) {
frame = 0;
}
}
#undef spray
}

View File

@ -22450,10 +22450,10 @@ main_36_TEXT segment byte public 'CODE' use16
@pattern_symmetric_birds_from_bot$qv procdesc near
@pattern_four_semicircle_spreads$qv procdesc near
@pattern_vertical_stacks_from_bot$qv procdesc near
@DOTTEDCIRCLE_UNPUT_UPDATE_RENDER$QIIIIIIII procdesc pascal near \
center:dword, frame_interval:dword, radius_step_col:dword, radius_initial_duration:dword
@PARTICLES2X2_HORIZONTAL_UNPUT_UP$QI procdesc pascal near \
frame:word
@PATTERN_CURVED_SPRAY_LEFTRIGHT_O$QMI procdesc pascal near \
frame_seg:word, frame_off:word
main_36_TEXT ends
main_36__TEXT segment byte public 'CODE' use16
@ -22465,94 +22465,6 @@ include th01/main/boss/anim.inc
sariel_shield equ <boss_entity_0>
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_2B6EA proc near
arg_0 = dword ptr 4
push bp
mov bp, sp
les bx, [bp+arg_0]
cmp word ptr es:[bx], 32h ; '2'
jl loc_2B838
les bx, [bp+arg_0]
cmp word ptr es:[bx], 32h ; '2'
jnz short loc_2B71C
call @dottedcircle_unput_update_render$qiiiiiiii pascal, large (320 shl 16) or 185, large (1 shl 16) or 4, large (16 shl 16) or 7, large (32 shl 16) or 160
loc_2B71C:
push (320 shl 16) or 185 ; (center_x) or (center_y)
les bx, [bp+arg_0]
mov ax, es:[bx]
add ax, -49
push ax ; frame_1based
push (4 shl 16) or 16 ; (interval) or (radius_step)
push (7 shl 16) or 32 ; (col) or (radius_initial)
push 90 ; duration
call @dottedcircle_unput_update_render$qiiiiiiii
les bx, [bp+arg_0]
cmp word ptr es:[bx], 64h ; 'd'
jl loc_2B838
les bx, [bp+arg_0]
cmp word ptr es:[bx], 64h ; 'd'
jnz short loc_2B780
mov x_3B327, 0
mov y_3B329, PLAYFIELD_BOTTOM
mov speed_3B32B, (7 shl 4)
mov word_3B32E, 0
call @sariel_select_for_rank$qmiiiii c, offset _sariel_pattern_state, ds, large 32 or (24 shl 16), large 18 or (16 shl 16)
loc_2B780:
cmp word_3B32E, 0
jnz short loc_2B7E7
mov ax, y_3B329
add ax, -185
push ax
mov ax, x_3B327
add ax, -320
push ax
call iatan2
mov angle_3B32D, al
call @CPellets@add_single$qiiuci15pellet_motion_tiii c, offset _Pellets, ds, large 320 or (185 shl 16), word ptr angle_3B32D, speed_3B32B, large PM_NORMAL or (0 shl 16), large 0 or (0 shl 16)
sub speed_3B32B, 4
mov ax, _sariel_pattern_state
add x_3B327, ax
cmp x_3B327, PLAYFIELD_RIGHT
jl short loc_2B838
mov word_3B32E, 1
mov speed_3B32B, (7 shl 4)
mov x_3B327, PLAYFIELD_RIGHT
pop bp
retn 4
; ---------------------------------------------------------------------------
loc_2B7E7:
mov ax, y_3B329
add ax, -185
push ax
mov ax, x_3B327
add ax, -320
push ax
call iatan2
mov angle_3B32D, al
call @CPellets@add_single$qiiuci15pellet_motion_tiii c, offset _Pellets, ds, large 320 or (185 shl 16), word ptr angle_3B32D, speed_3B32B, large PM_NORMAL or (0 shl 16), large 0 or (0 shl 16)
sub speed_3B32B, 4
mov ax, _sariel_pattern_state
sub x_3B327, ax
cmp x_3B327, 0
jge short loc_2B838
les bx, [bp+arg_0]
mov word ptr es:[bx], 0
loc_2B838:
pop bp
retn 4
sub_2B6EA endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
@ -24360,9 +24272,7 @@ loc_2CB59:
call sub_2BB46
loc_2CB6A:
push ds
push offset _boss_phase_frame
call sub_2B6EA
call @pattern_curved_spray_leftright_o$qmi pascal, ds, offset _boss_phase_frame
jmp short loc_2CBA4
; ---------------------------------------------------------------------------
@ -25779,11 +25689,16 @@ _particles2x2_horizontal_left dq PARTICLE2X2_COUNT dup(?)
_particles2x2_horizontal_top dq PARTICLE2X2_COUNT dup(?)
_particles2x2_horizontal_velocity dq PARTICLE2X2_COUNT dup(?)
x_3B327 dw ?
y_3B329 dw ?
speed_3B32B dw ?
angle_3B32D db ?
word_3B32E dw ?
CurvedSpray struc
Point <?> ; target
dw ? ; speed
db ? ; angle
dw ? ; subpattern_id
CurvedSpray ends
public _pattern12_spray
_pattern12_spray CurvedSpray <?>
point_3B330 Point <?>
grc_image_3B334 dw ?
word_3B336 dw ?