diff --git a/th01/main/boss/b10j.cpp b/th01/main/boss/b10j.cpp index 12930b7c..56c20993 100644 --- a/th01/main/boss/b10j.cpp +++ b/th01/main/boss/b10j.cpp @@ -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 +} diff --git a/th01_reiiden.asm b/th01_reiiden.asm index ca39393e..1aff4a8a 100644 --- a/th01_reiiden.asm +++ b/th01_reiiden.asm @@ -8783,298 +8783,11 @@ mima_still equ 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 ; ---------------------------------------------------------------------------