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

The one with the single snowflake, detonating into a 94-pixel hitbox…

Part of P0177, funded by Yanga.
This commit is contained in:
nmlgc 2022-01-02 03:24:44 +01:00
parent c5dc45b1c4
commit 5d557a2437
3 changed files with 188 additions and 274 deletions

View File

@ -31,6 +31,7 @@ extern "C" {
#include "th01/formats/ptn.hpp"
#include "th01/formats/stagedat.hpp"
#include "th01/sprites/pellet.h"
#include "th01/sprites/shape8x8.hpp"
#include "th01/main/spawnray.hpp"
#include "th01/main/vars.hpp"
#include "th01/main/boss/entity_a.hpp"
@ -73,6 +74,8 @@ static const pixel_t WAND_H = 96;
enum sariel_colors_t {
COL_LASER = 4,
COL_PARTICLE2X2 = 4,
COL_DETONATION = 5,
COL_DETONATION_START = 6,
COL_AIR = 12,
COL_BIRD = 15, // Yes, just a single one, changed by the background image.
};
@ -86,6 +89,7 @@ extern union {
int frame;
int speed_multiplied_by_8;
int interval;
int start_frame;
int unknown;
} pattern_state;
extern bool16 invincible;
@ -1263,3 +1267,168 @@ void pascal near particles2x2_vertical_unput_update_render(bool16 from_bottom)
#undef left
#undef col
}
void near pattern_detonating_snowflake(void)
{
enum {
HITBOX_W = 96,
RADIUS_MAX = (HITBOX_W / 2),
STEP_OUTER = 0x08,
STEP_INNER = 0x06,
};
enum phase_t {
P_RESET = -1,
P_WAND_RAISE = 0,
P_FLAKE_SPAWN = 1,
P_FLAKE_MOVING = 2,
P_DETONATION_START = 3,
P_DETONATION_ACTIVE = 5,
_phase_t_FORCE_INT16 = 0x7FFF
};
#define state pattern3_state
#define left pattern3_left
#define star_left pattern3_star_left
#define top pattern3_top
#define star_top pattern3_star_top
#define velocity_y pattern3_velocity_y
#define velocity_x pattern3_velocity_x
#define radius_outer_1 pattern3_radius_outer_1
#define radius_outer_2 pattern3_radius_outer_2
#define radius_inner pattern3_radius_inner
extern union {
phase_t phase;
int detonation_frame;
} state;
extern Subpixel left;
extern screen_x_t star_left;
extern Subpixel top;
extern vram_y_t star_top;
extern Subpixel velocity_y;
extern Subpixel velocity_x;
extern pixel_t radius_outer_1;
extern pixel_t radius_outer_2;
extern pixel_t radius_inner;
#define ellipse_put(radius_x, radius_y, col, angle_step) { \
shape_ellipse_arc_put( \
left.to_pixel(), player_center_y(), radius_x, radius_y, \
col, angle_step, 0x00, 0xFF \
); \
}
#define ellipse_sloppy_unput(radius_x, radius_y, angle_step) { \
shape_ellipse_arc_sloppy_unput( \
left.to_pixel(), player_center_y(), radius_x, radius_y, \
angle_step, 0x00, 0xFF \
); \
}
if(boss_phase_frame < 10) {
state.phase = P_RESET;
select_for_rank(pattern_state.start_frame, 160, 160, 160, 160);
}
if((boss_phase_frame % pattern_state.start_frame) == 0) {
state.phase = P_WAND_RAISE;
}
if(state.phase == P_WAND_RAISE) {
state.phase = static_cast<phase_t>(wand_render_raise_both());
}
if(state.phase == P_FLAKE_SPAWN) {
mdrv2_se_play(6);
left.v = to_sp(WAND_EMIT_LEFT);
top.v = to_sp(WAND_EMIT_TOP);
vector2_between(
WAND_EMIT_LEFT,
WAND_EMIT_TOP,
(player_left + (PLAYER_W / 2) - (FLAKE_W / 2)),
(player_top + (PLAYER_H / 2) - (FLAKE_H / 2)),
velocity_x.v,
velocity_y.v,
to_sp(7.0f)
);
state.phase = P_FLAKE_MOVING;
}
if(state.phase == P_FLAKE_MOVING) {
shape8x8_sloppy_unput(left.to_pixel(), top.to_pixel());
top.v += velocity_y.v;
if(top.v >= to_sp(PLAYFIELD_BOTTOM - (FLAKE_H / 2))) {
state.phase = P_DETONATION_START;
wand_lower_both();
return;
}
left.v += velocity_x.v;
shape8x8_flake_put(left.to_pixel(), top.to_pixel(), V_WHITE);
}
if(state.phase == P_DETONATION_START) {
ellipse_put(RADIUS_MAX, 16, COL_DETONATION_START, STEP_OUTER);
ellipse_put(16, RADIUS_MAX, COL_DETONATION_START, STEP_OUTER);
ellipse_put(24, 24, V_WHITE, STEP_INNER);
radius_outer_1 = RADIUS_MAX;
radius_outer_2 = 16;
radius_inner = 24;
// ZUN bug: Assigning a subpixel to a regular pixel. Will affect a
// single frame, until the X position is randomized again.
star_left = left.v;
star_top = (PLAYFIELD_BOTTOM - (rand() % RADIUS_MAX));
mdrv2_se_play(10);
}
if(state.phase >= P_DETONATION_START) {
state.detonation_frame++;
}
if(
(state.phase >= P_DETONATION_ACTIVE) &&
((state.detonation_frame % 8) == 0)
) {
shape8x8_sloppy_unput(star_left, star_top);
ellipse_sloppy_unput(radius_outer_1, radius_outer_2, STEP_OUTER);
ellipse_sloppy_unput(radius_outer_2, radius_outer_1, STEP_OUTER);
ellipse_sloppy_unput(radius_inner, radius_inner, STEP_INNER);
radius_outer_1 -= 6;
radius_outer_2 += 6;
radius_inner += 4;
star_left = ((rand() % ((HITBOX_W * 2) / 3)) + left.to_pixel() - (
((HITBOX_W * 2) / 6) - (FLAKE_W / 2)
));
star_top = (PLAYFIELD_BOTTOM - (rand() % RADIUS_MAX));
if(radius_outer_1 <= 8) {
state.phase = P_RESET;
return;
}
ellipse_put(radius_outer_1, radius_outer_2, COL_DETONATION, STEP_OUTER);
ellipse_put(radius_outer_2, radius_outer_1, COL_DETONATION, STEP_OUTER);
ellipse_put(radius_inner, radius_inner, V_WHITE, STEP_INNER);
shape8x8_star_put(star_left, star_top, V_WHITE);
}
if(
!player_invincible &&
((left.to_pixel() + ((HITBOX_W / 2) - (PLAYER_W / 2))) > player_left) &&
((left.to_pixel() - ((HITBOX_W / 2) + (PLAYER_W / 2))) < player_left) &&
(state.phase >= P_DETONATION_START)
) {
done = true;
}
#undef ellipse_put
#undef ellipse_sloppy_unput
#undef radius_inner
#undef radius_outer_2
#undef radius_outer_1
#undef velocity_x
#undef velocity_y
#undef star_top
#undef top
#undef star_left
#undef left
#undef state
}

View File

@ -14,5 +14,7 @@ typedef enum {
// For consistency in usage code...
static const pixel_t DIAMOND_W = 8;
static const pixel_t DIAMOND_H = 8;
static const pixel_t FLAKE_W = 8;
static const pixel_t FLAKE_H = 8;
extern const dot_rect_t(8, 8) sSHAPE8X8[SHAPE8X8_COUNT];

View File

@ -5160,8 +5160,6 @@ main_23_TEXT segment byte public 'CODE' use16
extern _grc_load:proc
extern _grc_put_8:proc
extern _grcg_put_8x8_mono:proc
extern @shape8x8_star_put$qiii:proc
extern @shape8x8_flake_put$qiii:proc
extern @shape_ellipse_arc_put$qiiiiiucucuc:proc
extern @shape_ellipse_arc_sloppy_unput$qiiiiucucuc:proc
extern _graph_r_lineloop_put:proc
@ -22434,7 +22432,6 @@ main_36_TEXT segment byte public 'CODE' use16
@shield_render_both$qv procdesc near
@WAND_RENDER_RAISE_BOTH$QI procdesc pascal near \
restart:word
@wand_lower_both$qv procdesc near
@dress_render_both$qv procdesc near
@pattern_vortices$qv procdesc near
@pattern_random_purple_lasers$qv procdesc near
@ -22443,6 +22440,7 @@ main_36_TEXT segment byte public 'CODE' use16
image_id_new:word
@PARTICLES2X2_VERTICAL_UNPUT_UPDA$QI procdesc pascal near \
from_bottom:word
@pattern_detonating_snowflake$qv procdesc near
main_36_TEXT ends
main_36__TEXT segment byte public 'CODE' use16
@ -22454,266 +22452,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_29FE9 proc near
push bp
mov bp, sp
cmp _boss_phase_frame, 10
jge short loc_2A010
mov word_35E03, 0FFFFh
call @sariel_select_for_rank$qmiiiii c, offset _sariel_pattern_state, ds, large 160 or (160 shl 16), large 160 or (160 shl 16)
loc_2A010:
mov ax, _boss_phase_frame
cwd
idiv _sariel_pattern_state
or dx, dx
jnz short loc_2A022
mov word_35E03, 0
loc_2A022:
cmp word_35E03, 0
jnz short loc_2A031
call @wand_render_raise_both$qi pascal, 0
mov word_35E03, ax
loc_2A031:
cmp word_35E03, 1
jnz short loc_2A073
push 6
call _mdrv2_se_play
mov subpixel_x_3AF32, (340 shl 4)
mov subpixel_y_3AF36, (64 shl 4)
push 112
push ds
push offset y_3AF3A
push ds
push offset x_3AF3C
push 380
mov ax, _player_left
add ax, 12
push ax
push (64 shl 16) or 340
call _vector2_between
add sp, 14h
mov word_35E03, 2
loc_2A073:
cmp word_35E03, 2
jnz short loc_2A0CF
push (8 shl 16) or 16
mov ax, subpixel_y_3AF36
sar ax, 4
push ax
mov ax, subpixel_x_3AF32
sar ax, 4
push ax
call _egc_copy_rect_1_to_0_16
add sp, 8
mov ax, y_3AF3A
add subpixel_y_3AF36, ax
cmp subpixel_y_3AF36, (396 shl 4)
jl short loc_2A0B0
mov word_35E03, 3
call @wand_lower_both$qv
pop bp
retn
; ---------------------------------------------------------------------------
loc_2A0B0:
mov ax, x_3AF3C
add subpixel_x_3AF32, ax
push 7 ; col
mov ax, subpixel_y_3AF36
sar ax, 4
push ax ; top
mov ax, subpixel_x_3AF32
sar ax, 4
push ax ; left
call @shape8x8_flake_put$qiii
add sp, 6
loc_2A0CF:
cmp word_35E03, 3
jnz loc_2A16A
push 255 ; angle_end
push 0 ; angle_start
push 8 ; angle_step
push 16 or (6 shl 16) ; (radius_y) or (col shl 16)
push 384 or (48 shl 16) ; (center_y) or (radius_x shl 16)
mov ax, subpixel_x_3AF32
sar ax, 4
push ax ; center_x
call @shape_ellipse_arc_put$qiiiiiucucuc
push 255
push 0 ; angle_start
push 8 ; angle_step
push 48 or (6 shl 16) ; (radius_y) or (col shl 16)
push 384 or (16 shl 16) ; (center_y) or (radius_x shl 16)
mov ax, subpixel_x_3AF32
sar ax, 4
push ax ; center_x
call @shape_ellipse_arc_put$qiiiiiucucuc
push 255 ; angle_end
push 0 ; angle_start
push 6 ; angle_step
push 24 or (7 shl 16) ; (radius_y) or (col shl 16)
push 384 or (24 shl 16) ; (center_y) or (radius_x shl 16)
mov ax, subpixel_x_3AF32
sar ax, 4
push ax ; center_x
call @shape_ellipse_arc_put$qiiiiiucucuc
mov pixel_3AF3E, 48
mov pixel_3AF40, 16
mov pixel_3AF42, 24
mov ax, subpixel_x_3AF32
mov x_3AF34, ax
call IRand
mov bx, 48
cwd
idiv bx
mov ax, RES_Y
sub ax, dx
mov y_3AF38, ax
push 0Ah
call _mdrv2_se_play
add sp, 32h
loc_2A16A:
cmp word_35E03, 3
jl short loc_2A175
inc word_35E03
loc_2A175:
cmp word_35E03, 5
jl loc_2A2BA
mov ax, word_35E03
mov bx, 8
cwd
idiv bx
or dx, dx
jnz loc_2A2BA
call _egc_copy_rect_1_to_0_16 stdcall, x_3AF34, y_3AF38, 16, bx
push 255 ; angle_end
push 0 ; angle_start
push 8 ; angle_step
push pixel_3AF40 ; radius_y
push pixel_3AF3E ; radius_x
push 384 ; center_y
mov ax, subpixel_x_3AF32
sar ax, 4
push ax ; center_x
call @shape_ellipse_arc_sloppy_unput$qiiiiucucuc
push 255 ; angle_end
push 0 ; angle_start
push 8 ; angle_step
push pixel_3AF3E ; radius_y
push pixel_3AF40 ; radius_x
push 384 ; center_y
mov ax, subpixel_x_3AF32
sar ax, 4
push ax ; center_x
call @shape_ellipse_arc_sloppy_unput$qiiiiucucuc
push 255 ; angle_end
push 0 ; angle_start
push 6 ; angle_step
push pixel_3AF42 ; radius_y
push pixel_3AF42 ; radius_x
push 384 ; center_y
mov ax, subpixel_x_3AF32
sar ax, 4
push ax ; center_x
call @shape_ellipse_arc_sloppy_unput$qiiiiucucuc
add sp, 32h
sub pixel_3AF3E, 6
add pixel_3AF40, 6
add pixel_3AF42, 4
call IRand
mov bx, 40h
cwd
idiv bx
mov ax, subpixel_x_3AF32
sar ax, 4
add dx, ax
add dx, -28
mov x_3AF34, dx
call IRand
mov bx, 48
cwd
idiv bx
mov ax, RES_Y
sub ax, dx
mov y_3AF38, ax
cmp pixel_3AF3E, 8
jg short loc_2A245
mov word_35E03, 0FFFFh
pop bp
retn
; ---------------------------------------------------------------------------
loc_2A245:
push 255 ; angle_end
push 0 ; angle_start
push 8 ; angle_step
push 5 ; col
push pixel_3AF40 ; radius_y
push pixel_3AF3E ; radius_x
push 384 ; center_y
mov ax, subpixel_x_3AF32
sar ax, 4
push ax ; center_x
call @shape_ellipse_arc_put$qiiiiiucucuc
push 255 ; angle_end
push 0 ; angle_start
push 8 ; angle_step
push 5 ; col
push pixel_3AF3E ; radius_y
push pixel_3AF40 ; radius_x
push 384 ; center_y
mov ax, subpixel_x_3AF32
sar ax, 4
push ax ; center_x
call @shape_ellipse_arc_put$qiiiiiucucuc
push 255 ; angle_end
push 0 ; angle_start
push 6 ; angle_step
push 7 ; col
push pixel_3AF42 ; radius_y
push pixel_3AF42 ; radius_x
push 384 ; center_y
mov ax, subpixel_x_3AF32
sar ax, 4
push ax ; center_x
call @shape_ellipse_arc_put$qiiiiiucucuc
add sp, 30h
call @shape8x8_star_put$qiii c, x_3AF34, y_3AF38, 7
loc_2A2BA:
cmp _player_invincible, 0
jnz short loc_2A2EB
mov ax, subpixel_x_3AF32
sar ax, 4
add ax, 32
cmp ax, _player_left
jle short loc_2A2EB
mov ax, subpixel_x_3AF32
sar ax, 4
add ax, -64
cmp ax, _player_left
jge short loc_2A2EB
cmp word_35E03, 3
jl short loc_2A2EB
mov _done, 1
loc_2A2EB:
pop bp
retn
sub_29FE9 endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
@ -26012,7 +25750,7 @@ loc_2C4D8:
call @particles2x2_vertical_unput_upda$qi pascal, 0
cmp word_35E95, 0
jnz short loc_2C502
call sub_29FE9
call @pattern_detonating_snowflake$qv
jmp short loc_2C50C
; ---------------------------------------------------------------------------
@ -27472,7 +27210,8 @@ _pattern2_eggs_alive dw 0
public _particles2x2_vertical_col
_particles2x2_vertical_col db PARTICLE2X2_COUNT dup(0)
word_35E03 dw 0FFFFh
public _pattern3_state
_pattern3_state dw -1
dd 0
dd 0
dd 0
@ -27939,15 +27678,19 @@ _particles2x2_vertical_left dq PARTICLE2X2_COUNT dup(?)
_particles2x2_vertical_top dq PARTICLE2X2_COUNT dup(?)
_particles2x2_vertical_velocity_y dq PARTICLE2X2_COUNT dup(?)
subpixel_x_3AF32 dw ?
x_3AF34 dw ?
subpixel_y_3AF36 dw ?
y_3AF38 dw ?
y_3AF3A dw ?
x_3AF3C dw ?
pixel_3AF3E dw ?
pixel_3AF40 dw ?
pixel_3AF42 dw ?
public _pattern3_left, _pattern3_star_left, _pattern3_top, _pattern3_star_top
public _pattern3_velocity_y, _pattern3_velocity_x, _pattern3_radius_outer_1
public _pattern3_radius_outer_2, _pattern3_radius_inner
_pattern3_left dw ?
_pattern3_star_left dw ?
_pattern3_top dw ?
_pattern3_star_top dw ?
_pattern3_velocity_y dw ?
_pattern3_velocity_x dw ?
_pattern3_radius_outer_1 dw ?
_pattern3_radius_outer_2 dw ?
_pattern3_radius_inner dw ?
angle_3AF44 db ?
word_3AF45 dw ?
db 240 dup(?)