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

The one where evenly spaced, randomly aimed pellets rain down from an
imaginary horizontal line at the seal's center Y coordinate. Featuring
an equally broken symmetric spawn ray variant.

Part of P0180, funded by Yanga.
This commit is contained in:
nmlgc 2022-01-18 01:51:27 +01:00
parent 9e5b344af1
commit 0393af6f0f
2 changed files with 115 additions and 190 deletions

View File

@ -109,6 +109,7 @@ extern union {
int interval;
int start_frame;
pixel_t velocity_x;
int pellet_count;
int unknown;
} pattern_state;
extern bool16 invincible;
@ -459,6 +460,19 @@ template <
: (((PLAYFIELD_RIGHT - DebrisOffsetX) - target_l_x) + offset);
}
// Almost a correct unblitting call, except for the top coordinate...
void debris_sloppy_unput(
x_direction_t ray_id, pixel_t offset = 0, pixel_t additional_h = 0
) const {
egc_copy_rect_1_to_0_16(
debris_left(ray_id),
((target_y - (DEBRIS_H / 4)) + offset),
DEBRIS_W,
(DEBRIS_H + additional_h)
);
}
// Worse.
void unput_and_put(
x_direction_t ray_id,
const vortex_or_debris_cel_t &debris_cel,
@ -488,6 +502,19 @@ template <
);
}
// Better.
void unput_and_put(
x_direction_t ray_id, const vortex_or_debris_cel_t &debris_cel
) const {
debris_sloppy_unput(ray_id);
spawnray_unput_and_put(
OriginX, OriginY, target_x(ray_id), target_y, V_WHITE
);
vortex_or_debris_put_8(
debris_left(ray_id), (target_y - (DEBRIS_H / 2)), debris_cel
);
}
void ray_unput_right(pixel_t velocity_x) const {
// spawnray_unput_and_put() could have done this as well, no need to
// change APIs...
@ -498,6 +525,25 @@ template <
);
}
void unput_broken(pixel_t velocity_y) const {
debris_sloppy_unput(X_RIGHT, -velocity_y, velocity_y);
debris_sloppy_unput(X_LEFT, -velocity_y, (velocity_y + 10)); // ???
// ZUN bug: Should of course be [velocity_y] rather than 4. These calls
// therefore unblit lines at angles that completely differ from the
// intended spawn rays. It doesn't matter for the left one, which
// actually isn't visible when this code gets to run, but the right one
// does indeed stay visible after this function. You only barely notice
// it because the one pattern that calls this function then spawns
// pellets on top of both rays, and it's *their* sloppy unblitting code
// that ends up gradually unblitting the right ray over the next few
// frames, as a side effect.
// Again, spawnray_unput_and_put() would have just done the correct
// thing.
graph_r_line_unput(OriginX, OriginY, target_x(X_LEFT), (target_y + 4));
graph_r_line_unput(OriginX, OriginY, target_x(X_RIGHT), (target_y + 4));
}
void fire_random_to_bottom(
unsigned char &angle, x_direction_t from_dir, subpixel_t speed
) const {
@ -2370,3 +2416,64 @@ void pascal near pattern_curved_spray_leftright_once(int &frame)
#undef spray
}
void pascal near pattern_rain_from_seal_center(int &frame)
{
enum {
VELOCITY_Y = 8,
};
#define rays pattern13_rays
#define debris_cel_cur pattern13_debris_cel_cur
#define debris_cel_prev pattern13_debris_cel_prev
extern struct SymmetricSpawnraysWithDebris<
SEAL_CENTER_X, SEAL_CENTER_Y, DEBRIS_W
> rays;
extern vortex_or_debris_cel_t debris_cel_cur;
extern vortex_or_debris_cel_t debris_cel_prev;
if(frame < 50) {
return;
} else if(frame == 50) {
rays.target_l_x = PLAYFIELD_LEFT;
rays.target_y = (PLAYFIELD_BOTTOM - 1);
debris_cel_cur = C_DEBRIS;
debris_cel_prev = C_DEBRIS;
sariel_select_for_rank(pattern_state.pellet_count, 30, 35, 40, 45);
}
if(rays.target_y > SEAL_CENTER_Y) {
if((frame % 2) == 0) {
rays.unput_and_put(X_LEFT, debris_cel_cur);
} else if((frame % 2) == 1) {
rays.unput_and_put(X_RIGHT, debris_cel_cur);
debris_cel_prev = debris_cel_cur;
debris_cel_cur = debris_cel_next(debris_cel_cur);
rays.target_y -= VELOCITY_Y;
}
if((frame % 10) == 0) {
mdrv2_se_play(6);
}
return;
}
mdrv2_se_play(3);
rays.unput_broken(VELOCITY_Y);
for(int i = 0; i < pattern_state.pellet_count; i++) {
Pellets.add_single(
(PLAYFIELD_LEFT + ((PLAYFIELD_W / pattern_state.pellet_count) * i)),
SEAL_CENTER_Y,
rand(),
to_sp(1.0f),
PM_GRAVITY,
to_sp(0.1f)
);
}
frame = 0;
#undef debris_cel_prev
#undef debris_cel_cur
#undef ray
}

View File

@ -22425,8 +22425,6 @@ main_36_TEXT segment byte public 'CODE' use16
extern @sariel_load_and_init$qv:proc
@wand_lowered_snap$qv procdesc near
extern @sariel_free$qv:proc
@SPAWNRAY_UNPUT_AND_PUT$QIIIII procdesc pascal near \
origin:Point, target_x:word, target_y:word, col:word
@BIRDS_RESET_FIRE_SPAWN_UNPUT_UPD$QDDDDC procdesc pascal near
@shield_render_both$qv procdesc near
@WAND_RENDER_RAISE_BOTH$QI procdesc pascal near \
@ -22454,6 +22452,8 @@ main_36_TEXT segment byte public 'CODE' use16
frame:word
@PATTERN_CURVED_SPRAY_LEFTRIGHT_O$QMI procdesc pascal near \
frame_seg:word, frame_off:word
@PATTERN_RAIN_FROM_SEAL_CENTER$QMI procdesc pascal near \
frame_seg:word, frame_off:word
main_36_TEXT ends
main_36__TEXT segment byte public 'CODE' use16
@ -22465,188 +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_2B83C proc near
arg_0 = dword ptr 4
push bp
mov bp, sp
push si
les bx, [bp+arg_0]
cmp word ptr es:[bx], 32h ; '2'
jl loc_2BA24
les bx, [bp+arg_0]
cmp word ptr es:[bx], 32h ; '2'
jnz short loc_2B883
mov point_3B330.x, 0
mov point_3B330.y, RES_Y - 1
mov grc_image_3B334, 3
mov word_3B336, 3
call @sariel_select_for_rank$qmiiiii c, offset _sariel_pattern_state, ds, large 30 or (35 shl 16), large 40 or (45 shl 16)
loc_2B883:
cmp point_3B330.y, 185
jle loc_2B97C
les bx, [bp+arg_0]
mov ax, es:[bx]
mov bx, 2
cwd
idiv bx
or dx, dx
jnz short loc_2B8E3
push (32 shl 16) or 32
mov ax, point_3B330.y
add ax, -8
push ax
push point_3B330.x
call _egc_copy_rect_1_to_0_16
call @spawnray_unput_and_put$qiiiii pascal, ((RES_X / 2) shl 16) or 185, point_3B330.x, point_3B330.y, 7
push 7 ; col
push grc_image_3B334 ; image
push GRC_SLOT_BOSS_1 ; slot
mov ax, point_3B330.y
add ax, -16
push ax ; top
push point_3B330.x ; left
call _grc_put_8
add sp, 12h
jmp short loc_2B95F
; ---------------------------------------------------------------------------
loc_2B8E3:
les bx, [bp+arg_0]
mov ax, es:[bx]
mov bx, 2
cwd
idiv bx
cmp dx, 1
jnz short loc_2B95F
push (32 shl 16) or 32
mov ax, point_3B330.y
add ax, -8
push ax
mov ax, 608
sub ax, point_3B330.x
push ax
call _egc_copy_rect_1_to_0_16
push ((RES_X / 2) shl 16) or 185
mov ax, RES_X - 1
sub ax, point_3B330.x
push ax
push point_3B330.y
push 7
call @spawnray_unput_and_put$qiiiii
push 7 ; col
push grc_image_3B334 ; image
push GRC_SLOT_BOSS_1 ; slot
mov ax, point_3B330.y
add ax, -16
push ax ; top
mov ax, 608
sub ax, point_3B330.x
push ax ; left
call _grc_put_8
add sp, 12h
mov ax, grc_image_3B334
mov word_3B336, ax
cmp grc_image_3B334, 5
jge short loc_2B954
inc ax
jmp short loc_2B957
; ---------------------------------------------------------------------------
loc_2B954:
mov ax, 3
loc_2B957:
mov grc_image_3B334, ax
sub point_3B330.y, 8
loc_2B95F:
les bx, [bp+arg_0]
mov ax, es:[bx]
mov bx, 0Ah
cwd
idiv bx
or dx, dx
jnz loc_2BA24
push 6
call _mdrv2_se_play
pop cx
jmp loc_2BA24
; ---------------------------------------------------------------------------
loc_2B97C:
push 3
call _mdrv2_se_play
push (40 shl 16) or 32
mov ax, point_3B330.y
add ax, -16
push ax
mov ax, 608
sub ax, point_3B330.x
push ax
call _egc_copy_rect_1_to_0_16
push (50 shl 16) or 32
mov ax, point_3B330.y
add ax, -16
push ax
push point_3B330.x
call _egc_copy_rect_1_to_0_16
mov ax, point_3B330.y
add ax, 4
push ax
push point_3B330.x
push (185 shl 16) or 320
call _graph_r_line_unput
mov ax, point_3B330.y
add ax, 4
push ax
mov ax, RES_X - 1
sub ax, point_3B330.x
push ax
push (185 shl 16) or 320
call _graph_r_line_unput
add sp, 22h
xor si, si
jmp short loc_2BA16
; ---------------------------------------------------------------------------
loc_2B9EA:
pushd 0 or (0 shl 16)
push PM_GRAVITY or (1 shl 16)
push (1 shl 4)
call IRand
push ax
push 185
mov ax, PLAYFIELD_RIGHT
cwd
idiv _sariel_pattern_state
imul si
push ax
push ds
push offset _Pellets
call @CPellets@add_single$qiiuci15pellet_motion_tiii
add sp, 14h
inc si
loc_2BA16:
cmp si, _sariel_pattern_state
jl short loc_2B9EA
les bx, [bp+arg_0]
mov word ptr es:[bx], 0
loc_2BA24:
pop si
pop bp
retn 4
sub_2B83C endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
@ -24285,9 +24103,7 @@ loc_2CB73:
call sub_2BB46
loc_2CB84:
push ds
push offset _boss_phase_frame
call sub_2B83C
call @pattern_rain_from_seal_center$qmi pascal, ds, offset _boss_phase_frame
jmp short loc_2CBA4
; ---------------------------------------------------------------------------
@ -25699,9 +25515,11 @@ CurvedSpray ends
public _pattern12_spray
_pattern12_spray CurvedSpray <?>
point_3B330 Point <?>
grc_image_3B334 dw ?
word_3B336 dw ?
public _pattern13_rays, _pattern13_debris_cel_cur, _pattern13_debris_cel_prev
_pattern13_rays SymmetricSpawnraysWithDebris <?>
_pattern13_debris_cel_cur dw ?
_pattern13_debris_cel_prev dw ?
x_3B338 dw ?
y_3B338 dw ?
speed_3B33C dw ?