mirror of https://github.com/nmlgc/ReC98.git
[Decompilation] [th01] Mima: Pattern 3/8
The one where Mima takes the final static part from the first pattern, and replicates it with two squares that rotate in opposite directions. Also demonstrates the 34th unblitting bug in this game. Part of P0205, funded by [Anonymous] and Yanga.
This commit is contained in:
parent
12eb04cc9c
commit
1772a2907a
|
@ -67,10 +67,12 @@ extern int invincibility_frame;
|
|||
extern bool16 invincible;
|
||||
extern bool initial_hp_rendered;
|
||||
|
||||
// Whether meteor_put() has any effect.
|
||||
extern bool meteor_active;
|
||||
|
||||
// Amount of frames between the individual steps of the spread-in transition
|
||||
extern uint8_t spreadin_interval;
|
||||
|
||||
// Sprite pixels to spread in per frame, in one half of Mima's sprite
|
||||
extern uint8_t spreadin_speed;
|
||||
|
||||
|
@ -172,7 +174,12 @@ void meteor_put(void)
|
|||
|
||||
void mima_put_cast_both(void)
|
||||
{
|
||||
// ZUN bug: Does not unblit the meteor if `true`, and C_CAST does not
|
||||
// completely overlap any C_METEOR cel. In that case, small parts of the
|
||||
// meteor are guaranteed to be left in VRAM until they're unblitted as a
|
||||
// result of another sprite flying over them.
|
||||
meteor_active = false;
|
||||
|
||||
ent_anim_sync_with_still_and_put_both(C_CAST);
|
||||
}
|
||||
|
||||
|
@ -398,6 +405,14 @@ struct SquareState {
|
|||
screen_x_t name##_center_x; \
|
||||
screen_y_t name##_center_y;
|
||||
|
||||
#define SquareLocal2(name) \
|
||||
screen_x_t name##_corners_ccw_x[SQUARE_POINTS]; \
|
||||
screen_y_t name##_corners_ccw_y[SQUARE_POINTS]; \
|
||||
screen_x_t name##_corners_cw_x[SQUARE_POINTS]; \
|
||||
screen_y_t name##_corners_cw_y[SQUARE_POINTS]; \
|
||||
screen_x_t name##_center_x; \
|
||||
screen_y_t name##_center_y;
|
||||
|
||||
#define square_center_set(sql) { \
|
||||
sql##_center_x = ent_still.cur_center_x(); \
|
||||
sql##_center_y = ent_still.cur_center_y(); \
|
||||
|
@ -563,3 +578,74 @@ void pattern_aimed_missiles_from_square_corners(void)
|
|||
#undef target_left
|
||||
#undef sq
|
||||
}
|
||||
|
||||
void pattern_static_pellets_from_corners_of_two_squares(void)
|
||||
{
|
||||
#define sq pattern2_sq
|
||||
|
||||
extern SquareState sq;
|
||||
SquareLocal2(sql);
|
||||
|
||||
if(boss_phase_frame == 50) {
|
||||
mima_put_cast_both();
|
||||
}
|
||||
if(boss_phase_frame < 100) {
|
||||
return;
|
||||
}
|
||||
if(boss_phase_frame == 100) {
|
||||
sq.init();
|
||||
select_subpixel_for_rank(pattern_state.speed, 4.0f, 4.5f, 5.0f, 5.5f);
|
||||
mdrv2_se_play(8);
|
||||
}
|
||||
if((boss_phase_frame % SQUARE_INTERVAL) == 0) {
|
||||
square_center_set(sql);
|
||||
square_corners_set(sql, sql_corners_ccw, sq.radius, sq.angle);
|
||||
square_corners_set(sql, sql_corners_cw, sq.radius, (0x00 - sq.angle));
|
||||
square_unput(sql_corners_ccw);
|
||||
square_unput(sql_corners_cw);
|
||||
|
||||
sq.angle -= 0x06;
|
||||
Pellets.spawn_with_cloud = true;
|
||||
|
||||
if(sq.radius < SEAL_CIRCUMSQUARE_RADIUS) {
|
||||
sq.radius += SQUARE_RADIUS_STEP;
|
||||
} else {
|
||||
// Same corner coordinate quirk as seen in the first pattern.
|
||||
|
||||
for(int i = 0; i < SQUARE_POINTS; i++) {
|
||||
unsigned char angle;
|
||||
fire_static_from_corner(
|
||||
angle,
|
||||
sql,
|
||||
sql_corners_ccw_x[i],
|
||||
sql_corners_ccw_y[i],
|
||||
pattern_state.speed
|
||||
);
|
||||
fire_static_from_corner(
|
||||
angle,
|
||||
sql,
|
||||
sql_corners_cw_x[i],
|
||||
sql_corners_cw_y[i],
|
||||
pattern_state.speed
|
||||
);
|
||||
mdrv2_se_play(7);
|
||||
}
|
||||
}
|
||||
square_corners_set(sql, sql_corners_ccw, sq.radius, sq.angle);
|
||||
square_corners_set(sql, sql_corners_cw, sq.radius, (0x00 - sq.angle));
|
||||
square_put(sql_corners_ccw);
|
||||
square_put(sql_corners_cw);
|
||||
Pellets.spawn_with_cloud = false;
|
||||
}
|
||||
if(boss_phase_frame > 320) {
|
||||
square_center_set(sql); // Not redundant!
|
||||
square_corners_set(sql, sql_corners_ccw, sq.radius, sq.angle);
|
||||
square_corners_set(sql, sql_corners_cw, sq.radius, (0x00 - sq.angle));
|
||||
square_unput(sql_corners_ccw);
|
||||
square_unput(sql_corners_cw);
|
||||
boss_phase_frame = 0;
|
||||
meteor_activate();
|
||||
}
|
||||
|
||||
#undef sq
|
||||
}
|
||||
|
|
291
th01_reiiden.asm
291
th01_reiiden.asm
|
@ -8783,298 +8783,11 @@ mima_still equ <boss_entity_0>
|
|||
corners_x:dword, corners_y:dword, center_x:word, center_y:word, radius:word, angle:byte, points:word
|
||||
extern @pattern_aimed_then_static_pellet$qv:proc
|
||||
extern @pattern_aimed_missiles_from_squa$qv:proc
|
||||
extern @pattern_static_pellets_from_corn$qv:proc
|
||||
main_29_TEXT ends
|
||||
|
||||
main_29__TEXT segment byte public 'CODE' use16
|
||||
|
||||
; =============== S U B R O U T I N E =======================================
|
||||
|
||||
; Attributes: bp-based frame
|
||||
|
||||
sub_1ECF0 proc far
|
||||
|
||||
@@angle = byte ptr -23h
|
||||
@@sq_center_y = word ptr -22h
|
||||
@@corners_y_2 = byte ptr -20h
|
||||
@@corners_x_2 = byte ptr -18h
|
||||
@@corners_y_1 = byte ptr -10h
|
||||
@@corners_x_1 = byte ptr -8
|
||||
|
||||
enter 24h, 0
|
||||
push si
|
||||
push di
|
||||
cmp _boss_phase_frame, 50
|
||||
jnz short loc_1ED01
|
||||
call @mima_put_cast_both$qv
|
||||
|
||||
loc_1ED01:
|
||||
cmp _boss_phase_frame, 100
|
||||
jl loc_1EF81
|
||||
cmp _boss_phase_frame, 100
|
||||
jnz short loc_1ED3A
|
||||
mov _pattern2_sq.S_radius, 32
|
||||
mov _pattern2_sq.S_angle, 0
|
||||
call @mima_select_for_rank$qmiiiii stdcall, offset _mima_pattern_state, ds, large 40h or (48h shl 16), large 50h or (58h shl 16)
|
||||
push 8
|
||||
call _mdrv2_se_play
|
||||
add sp, 0Eh
|
||||
|
||||
loc_1ED3A:
|
||||
mov ax, _boss_phase_frame
|
||||
mov bx, 8
|
||||
cwd
|
||||
idiv bx
|
||||
or dx, dx
|
||||
jnz loc_1EF00
|
||||
mov ax, mima_still.BE_cur_left
|
||||
add ax, 64
|
||||
mov di, ax
|
||||
mov ax, mima_still.BE_cur_top
|
||||
add ax, 80
|
||||
mov [bp+@@sq_center_y], ax
|
||||
push ss ; corners_x (segment)
|
||||
lea ax, [bp+@@corners_x_1]
|
||||
push ax ; corners_x (offset)
|
||||
push ss ; corners_y (segment)
|
||||
lea ax, [bp+@@corners_y_1]
|
||||
push ax ; corners_y (offset)
|
||||
push di ; center_x
|
||||
push [bp+@@sq_center_y] ; center_y
|
||||
push _pattern2_sq.S_radius ; radius
|
||||
push word ptr _pattern2_sq.S_angle ; angle
|
||||
push 4 ; points
|
||||
call @regular_polygon$qnit1iiiuci
|
||||
push ss ; corners_x (segment)
|
||||
lea ax, [bp+@@corners_x_2]
|
||||
push ax ; corners_x (offset)
|
||||
push ss ; corners_y (segment)
|
||||
lea ax, [bp+@@corners_y_2]
|
||||
push ax ; corners_y (offset)
|
||||
push di ; center_x
|
||||
push [bp+@@sq_center_y] ; center_y
|
||||
push _pattern2_sq.S_radius ; radius
|
||||
mov al, 0
|
||||
sub al, _pattern2_sq.S_angle ; angle
|
||||
push ax ; angle
|
||||
push 4 ; points
|
||||
call @regular_polygon$qnit1iiiuci
|
||||
push 4 ; point_count
|
||||
push ss
|
||||
lea ax, [bp+@@corners_y_1]
|
||||
push ax
|
||||
push ss
|
||||
lea ax, [bp+@@corners_x_1]
|
||||
push ax
|
||||
call _graph_r_lineloop_unput
|
||||
push 4 ; point_count
|
||||
push ss
|
||||
lea ax, [bp+@@corners_y_2]
|
||||
push ax
|
||||
push ss
|
||||
lea ax, [bp+@@corners_x_2]
|
||||
push ax
|
||||
call _graph_r_lineloop_unput
|
||||
add sp, 14h
|
||||
mov al, _pattern2_sq.S_angle
|
||||
add al, -06h
|
||||
mov _pattern2_sq.S_angle, al
|
||||
mov _Pellets.PELLET_spawn_with_cloud, 1
|
||||
cmp _pattern2_sq.S_radius, 112
|
||||
jge short loc_1EDD4
|
||||
add _pattern2_sq.S_radius, 8
|
||||
jmp loc_1EE95
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1EDD4:
|
||||
xor si, si
|
||||
jmp loc_1EE8E
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
loc_1EDD9:
|
||||
mov bx, si
|
||||
add bx, bx
|
||||
lea ax, [bp+@@corners_y_1]
|
||||
add bx, ax
|
||||
mov ax, ss:[bx]
|
||||
sub ax, [bp+@@sq_center_y]
|
||||
push ax
|
||||
mov bx, si
|
||||
add bx, bx
|
||||
lea ax, [bp+@@corners_x_1]
|
||||
add bx, ax
|
||||
mov ax, ss:[bx]
|
||||
sub ax, di
|
||||
push ax
|
||||
call iatan2
|
||||
mov [bp+@@angle], al
|
||||
pushd 0 or (0 shl 16)
|
||||
pushd PM_REGULAR or (0 shl 16)
|
||||
push _mima_pattern_state
|
||||
push word ptr [bp+@@angle]
|
||||
mov bx, si
|
||||
add bx, bx
|
||||
lea ax, [bp+@@corners_y_1]
|
||||
add bx, ax
|
||||
push word ptr ss:[bx]
|
||||
mov bx, si
|
||||
add bx, bx
|
||||
lea ax, [bp+@@corners_x_1]
|
||||
add bx, ax
|
||||
push word ptr ss:[bx]
|
||||
push ds
|
||||
push offset _Pellets
|
||||
call @CPellets@add_single$qiiuci15pellet_motion_tiii
|
||||
mov bx, si
|
||||
add bx, bx
|
||||
lea ax, [bp+@@corners_y_2]
|
||||
add bx, ax
|
||||
mov ax, ss:[bx]
|
||||
sub ax, [bp+@@sq_center_y]
|
||||
push ax
|
||||
mov bx, si
|
||||
add bx, bx
|
||||
lea ax, [bp+@@corners_x_2]
|
||||
add bx, ax
|
||||
mov ax, ss:[bx]
|
||||
sub ax, di
|
||||
push ax
|
||||
call iatan2
|
||||
mov [bp+@@angle], al
|
||||
pushd 0 or (0 shl 16)
|
||||
pushd PM_REGULAR or (0 shl 16)
|
||||
push _mima_pattern_state
|
||||
push word ptr [bp+@@angle]
|
||||
mov bx, si
|
||||
add bx, bx
|
||||
lea ax, [bp+@@corners_y_2]
|
||||
add bx, ax
|
||||
push word ptr ss:[bx]
|
||||
mov bx, si
|
||||
add bx, bx
|
||||
lea ax, [bp+@@corners_x_2]
|
||||
add bx, ax
|
||||
push word ptr ss:[bx]
|
||||
push ds
|
||||
push offset _Pellets
|
||||
call @CPellets@add_single$qiiuci15pellet_motion_tiii
|
||||
push 7
|
||||
call _mdrv2_se_play
|
||||
add sp, 2Ah
|
||||
inc si
|
||||
|
||||
loc_1EE8E:
|
||||
cmp si, 4
|
||||
jl loc_1EDD9
|
||||
|
||||
loc_1EE95:
|
||||
push ss ; corners_x (segment)
|
||||
lea ax, [bp+@@corners_x_1]
|
||||
push ax ; corners_x (offset)
|
||||
push ss ; corners_y (segment)
|
||||
lea ax, [bp+@@corners_y_1]
|
||||
push ax ; corners_y (offset)
|
||||
push di ; center_x
|
||||
push [bp+@@sq_center_y] ; center_y
|
||||
push _pattern2_sq.S_radius ; radius
|
||||
push word ptr _pattern2_sq.S_angle ; angle
|
||||
push 4 ; points
|
||||
call @regular_polygon$qnit1iiiuci
|
||||
push ss ; corners_x (segment)
|
||||
lea ax, [bp+@@corners_x_2]
|
||||
push ax ; corners_x (offset)
|
||||
push ss ; corners_y (segment)
|
||||
lea ax, [bp+@@corners_y_2]
|
||||
push ax ; corners_y (offset)
|
||||
push di ; center_x
|
||||
push [bp+@@sq_center_y] ; center_y
|
||||
push _pattern2_sq.S_radius ; radius
|
||||
mov al, 0
|
||||
sub al, _pattern2_sq.S_angle ; angle
|
||||
push ax ; angle
|
||||
push 4 ; points
|
||||
call @regular_polygon$qnit1iiiuci
|
||||
push 4 or (7 shl 16) ; (point_count) or (col shl 16)
|
||||
push ss
|
||||
lea ax, [bp+@@corners_y_1]
|
||||
push ax
|
||||
push ss
|
||||
lea ax, [bp+@@corners_x_1]
|
||||
push ax
|
||||
call _graph_r_lineloop_put
|
||||
push 4 or (7 shl 16) ; (point_count) or (col shl 16)
|
||||
push ss
|
||||
lea ax, [bp+@@corners_y_2]
|
||||
push ax
|
||||
push ss
|
||||
lea ax, [bp+@@corners_x_2]
|
||||
push ax
|
||||
call _graph_r_lineloop_put
|
||||
add sp, 18h
|
||||
mov _Pellets.PELLET_spawn_with_cloud, 0
|
||||
|
||||
loc_1EF00:
|
||||
cmp _boss_phase_frame, 320
|
||||
jle short loc_1EF81
|
||||
mov ax, mima_still.BE_cur_left
|
||||
add ax, 64
|
||||
mov di, ax
|
||||
mov ax, mima_still.BE_cur_top
|
||||
add ax, 80
|
||||
mov [bp+@@sq_center_y], ax
|
||||
push ss ; corners_x (segment)
|
||||
lea ax, [bp+@@corners_x_1]
|
||||
push ax ; corners_x (offset)
|
||||
push ss ; corners_y (segment)
|
||||
lea ax, [bp+@@corners_y_1]
|
||||
push ax ; corners_y (offset)
|
||||
push di ; center_x
|
||||
push [bp+@@sq_center_y] ; center_y
|
||||
push _pattern2_sq.S_radius ; radius
|
||||
push word ptr _pattern2_sq.S_angle ; angle
|
||||
push 4 ; points
|
||||
call @regular_polygon$qnit1iiiuci
|
||||
push ss ; corners_x (segment)
|
||||
lea ax, [bp+@@corners_x_2]
|
||||
push ax ; corners_x (offset)
|
||||
push ss ; corners_y (segment)
|
||||
lea ax, [bp+@@corners_y_2]
|
||||
push ax ; corners_y (offset)
|
||||
push di ; center_x
|
||||
push [bp+@@sq_center_y] ; center_y
|
||||
push _pattern2_sq.S_radius ; radius
|
||||
mov al, 0
|
||||
sub al, _pattern2_sq.S_angle ; angle
|
||||
push ax ; angle
|
||||
push 4 ; points
|
||||
call @regular_polygon$qnit1iiiuci
|
||||
push 4 ; point_count
|
||||
push ss
|
||||
lea ax, [bp+@@corners_y_1]
|
||||
push ax
|
||||
push ss
|
||||
lea ax, [bp+@@corners_x_1]
|
||||
push ax
|
||||
call _graph_r_lineloop_unput
|
||||
push 4 ; point_count
|
||||
push ss
|
||||
lea ax, [bp+@@corners_y_2]
|
||||
push ax
|
||||
push ss
|
||||
lea ax, [bp+@@corners_x_2]
|
||||
push ax
|
||||
call _graph_r_lineloop_unput
|
||||
add sp, 14h
|
||||
mov _boss_phase_frame, 0
|
||||
call @meteor_activate$qv
|
||||
|
||||
loc_1EF81:
|
||||
pop di
|
||||
pop si
|
||||
leave
|
||||
retf
|
||||
sub_1ECF0 endp
|
||||
|
||||
|
||||
; =============== S U B R O U T I N E =======================================
|
||||
|
||||
; Attributes: bp-based frame
|
||||
|
@ -10325,7 +10038,7 @@ loc_1FB5E:
|
|||
loc_1FB6B:
|
||||
cmp word_39E78, 2
|
||||
jnz short loc_1FB78
|
||||
call sub_1ECF0
|
||||
call @pattern_static_pellets_from_corn$qv
|
||||
jmp short loc_1FB86
|
||||
; ---------------------------------------------------------------------------
|
||||
|
||||
|
|
Loading…
Reference in New Issue