diff --git a/th01/main/boss/b20m.cpp b/th01/main/boss/b20m.cpp index 96d1ca50..88879e6c 100644 --- a/th01/main/boss/b20m.cpp +++ b/th01/main/boss/b20m.cpp @@ -9,7 +9,9 @@ extern "C" { #include "planar.h" #include "master.hpp" #include "th01/common.h" +#include "th01/v_colors.hpp" #include "th01/math/area.hpp" +#include "th01/math/dir.hpp" #include "th01/math/overlap.hpp" #include "th01/math/subpixel.hpp" #include "th01/hardware/frmdelay.h" @@ -64,6 +66,7 @@ enum sariel_colors_t { #define invincibility_frame sariel_invincibility_frame #define initial_hp_rendered sariel_initial_hp_rendered extern union { + int frame; int unknown; } pattern_state; extern bool16 invincible; @@ -125,6 +128,25 @@ inline void sariel_grc_free(void) { #define sloppy_unput_32x32(left, top) \ egc_copy_rect_1_to_0_16(left, top, 48, 32); +// Vortex and debris sprites (BOSS6GR1.GRC) +// ---------------------------------------- + +static const pixel_t VORTEX_W = 32; +static const pixel_t VORTEX_H = 32; + +static const int VORTEX_COUNT = 2; + +enum vortex_or_debris_cel_t { + VORTEX_CELS = 3, + + C_VORTEX = 0, + C_VORTEX_last = (C_VORTEX + VORTEX_CELS - 1), +}; + +#define vortex_or_debris_put_8(left, top, cel) \ + grc_put_8(left, top, GRC_SLOT_VORTEX_DEBRIS, cel, V_WHITE); +// ---------------------------------------- + // Birds (BOSS6GR2.GRC) // -------------------- @@ -521,3 +543,193 @@ void near dress_render_both(void) graph_accesspage_func(1); anm_dress.put_8(); graph_accesspage_func(0); anm_dress.put_8(); } + +static const subpixel_t VORTEX_PELLET_SPEED = TO_SP(7); + +#define vortex_pellet_left(vortex_left) \ + ((vortex_left) + ((VORTEX_W / 2) - (PELLET_W / 2))) + +#define vortex_pellet_top(vortex_top) \ + ((vortex_top) + ((VORTEX_H / 2) - (PELLET_H / 2))) + +inline screen_y_t vortex_pellet_bottom(screen_y_t vortex_bottom) { + return (vortex_bottom - ((VORTEX_H / 2) - (PELLET_H / 2))); +} + +// Shouldn't really take [angle] as a parameter... +void pascal near vortex_fire_3_spread( + const screen_x_t left[VORTEX_COUNT], + const vram_y_t top[VORTEX_COUNT], + int i, + unsigned char angle +) +{ + Pellets.add_single( + vortex_pellet_left(left[i]), + vortex_pellet_top(top[i]), + 0x40, + VORTEX_PELLET_SPEED + ); + angle = iatan2( + (vortex_pellet_bottom(PLAYFIELD_BOTTOM) - top[i]), + (left[1 - i] - left[i]) + ); + Pellets.add_single( + vortex_pellet_left(left[i]), + vortex_pellet_top(top[i]), + angle, + VORTEX_PELLET_SPEED + ); + Pellets.add_single( + vortex_pellet_left(left[i]), + vortex_pellet_top(top[i]), + (0x80 - angle), + VORTEX_PELLET_SPEED + ); +} + +void near pattern_vortices(void) +{ + #define wand_raise_animation_done pattern1_wand_raise_animation_done + #define cur_left pattern1_cur_left + #define cur_top pattern1_cur_top + #define prev_left pattern1_prev_left + #define prev_top pattern1_prev_top + #define dir_first pattern1_dir_first + #define dir_second pattern1_dir_second + + extern bool16 wand_raise_animation_done; + extern screen_x_t cur_left[VORTEX_COUNT]; + extern vram_y_t cur_top[VORTEX_COUNT]; + extern screen_x_t prev_left[VORTEX_COUNT]; + extern vram_y_t prev_top[VORTEX_COUNT]; + extern bool16 dir_first; // x_direction_t + extern bool16 dir_second; // x_direction_t + + #define vortex_unput_and_put_8(i) { \ + sloppy_unput_32x32(prev_left[i], prev_top[i]); \ + vortex_or_debris_put_8( \ + cur_left[i], \ + cur_top[i], \ + (C_VORTEX + (boss_phase_frame % VORTEX_CELS)) \ + ); \ + } + + #define vortex_fire_down(i) { \ + Pellets.add_group( \ + vortex_pellet_left(cur_left[i]), \ + vortex_pellet_top(cur_top[i]), \ + PG_1, \ + VORTEX_PELLET_SPEED \ + ); \ + } + + #define vortex_unput_put_3_spread(i) { \ + vortex_unput_and_put_8(i); \ + if((boss_phase_frame % 4) == 0) { \ + vortex_fire_3_spread(cur_left, cur_top, i, angle); \ + } \ + } + + unsigned char angle; + + if(wand_raise_animation_done == false) { + wand_raise_animation_done = wand_render_raise_both(); + } + + if(boss_phase_frame < 50) { + return; + } else if(boss_phase_frame == 50) { + select_for_rank(pattern_state.frame, 140, 145, 150, 155); + } + if(boss_phase_frame < 100) { + for(int i = 0; i < VORTEX_COUNT; i++) { + cur_left[i] = (i * (PLAYFIELD_RIGHT - VORTEX_W)); + cur_top[i] = (PLAYFIELD_TOP + playfield_fraction_y(17 / 42.0f)); + + vortex_unput_and_put_8(i); + if((boss_phase_frame % 4) == 0) { + vortex_fire_down(i); + } + prev_left[i] = cur_left[i]; + prev_top[i] = cur_top[i]; + } + } else if(boss_phase_frame < pattern_state.frame) { + for(int i = 0; i < VORTEX_COUNT; i++) { + cur_left[i] += (i == 0) ? 5 : -5; + cur_top[i] -= 2; + + vortex_unput_and_put_8(i); + if((boss_phase_frame % 4) == 0) { + vortex_fire_down(i); + angle = iatan2( + vortex_pellet_top(PLAYFIELD_BOTTOM - cur_top[i]), + vortex_pellet_left(cur_left[i] + + (i * ((PLAYFIELD_W / 8) * 2)) - (PLAYFIELD_W / 8) - + cur_left[i]) + ); + Pellets.add_single( + vortex_pellet_left(cur_left[i]), + vortex_pellet_top(cur_top[i]), + angle, + VORTEX_PELLET_SPEED + ); + } + prev_left[i] = cur_left[i]; + prev_top[i] = cur_top[i]; + } + } else if(boss_phase_frame < 200) { + for(int i = 0; i < VORTEX_COUNT; i++) { + vortex_unput_put_3_spread(i); + } + } else if(boss_phase_frame < 240) { + if(boss_phase_frame == 200) { + static_cast(dir_first) = (rand() % 2); + if(dir_first == X_LEFT) { + wand_lower_both(); + } + } + for(int i = 0; i < VORTEX_COUNT; i++) { + cur_left[i] += (2 - (dir_first * 4)); + vortex_unput_put_3_spread(i); + prev_left[i] = cur_left[i]; + } + } else if(boss_phase_frame < 320) { + if(boss_phase_frame == 240) { + static_cast(dir_second) = (rand() % 2); + if((dir_second == X_RIGHT) && (dir_second == dir_first)) { + wand_lower_both(); + } else if((dir_second == X_LEFT) && (dir_second == dir_first)) { + wand_raise_animation_done = false; + } + } + for(int i = 0; i < VORTEX_COUNT; i++) { + if(dir_second != dir_first) { + cur_left[i] -= (2 - (dir_second * 4)); + } else { + cur_left[i] -= (4 - (dir_second * 8)); + } + vortex_unput_put_3_spread(i); + prev_left[i] = cur_left[i]; + } + } else if(boss_phase_frame > 300) { + for(int i = 0; i < VORTEX_COUNT; i++) { + sloppy_unput_32x32(cur_left[i], cur_top[i]); + } + wand_lower_both(); + boss_phase_frame = 0; + wand_raise_animation_done = false; + } + + #undef vortex_unput_put_3_spread + #undef vortex_fire_down + #undef vortex_unput_and_put_8 + + #undef dir_second + #undef dir_first + #undef prev_top + #undef prev_left + #undef cur_top + #undef cur_left + #undef wand_raise_animation_done +} diff --git a/th01_reiiden.asm b/th01_reiiden.asm index f0807416..8f60ecc1 100644 --- a/th01_reiiden.asm +++ b/th01_reiiden.asm @@ -22438,6 +22438,7 @@ main_36_TEXT segment byte public 'CODE' use16 restart:word @wand_lower_both$qv procdesc near @dress_render_both$qv procdesc near + @pattern_vortices$qv procdesc near main_36_TEXT ends main_36__TEXT segment byte public 'CODE' use16 @@ -22449,616 +22450,6 @@ include th01/main/boss/anim.inc sariel_shield equ -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_29015 proc near - -@@angle = byte ptr 4 -arg_2 = word ptr 6 -arg_4 = dword ptr 8 -arg_8 = dword ptr 0Ch - - push bp - mov bp, sp - push si - mov si, [bp+arg_2] - pushd 0 or (0 shl 16) - pushd PM_NORMAL or (0 shl 16) - push (7 shl 4) - push 40h - mov ax, si - add ax, ax - les bx, [bp+arg_4] - add bx, ax - mov ax, es:[bx] - add ax, 12 - push ax - mov ax, si - add ax, ax - les bx, [bp+arg_8] - add bx, ax - mov ax, es:[bx] - add ax, 12 - push ax - push ds - push offset _Pellets - call @CPellets@add_single$qiiuci15pellet_motion_tiii - mov ax, si - add ax, ax - les bx, [bp+arg_4] - add bx, ax - mov ax, 388 - sub ax, es:[bx] - push ax - mov ax, 1 - sub ax, si - add ax, ax - les bx, [bp+arg_8] - add bx, ax - mov ax, es:[bx] - mov dx, si - add dx, dx - mov bx, word ptr [bp+arg_8] - add bx, dx - sub ax, es:[bx] - push ax - call iatan2 - mov [bp+@@angle], al - pushd 0 or (0 shl 16) - pushd PM_NORMAL or (0 shl 16) - push (7 shl 4) - push word ptr [bp+@@angle] - mov ax, si - add ax, ax - les bx, [bp+arg_4] - add bx, ax - mov ax, es:[bx] - add ax, 12 - push ax - mov ax, si - add ax, ax - les bx, [bp+arg_8] - add bx, ax - mov ax, es:[bx] - add ax, 12 - push ax - push ds - push offset _Pellets - call @CPellets@add_single$qiiuci15pellet_motion_tiii - add sp, 28h - pushd 0 or (0 shl 16) - pushd PM_NORMAL or (0 shl 16) - push (7 shl 4) - mov al, 80h - sub al, [bp+@@angle] - push ax - mov ax, si - add ax, ax - les bx, [bp+arg_4] - add bx, ax - mov ax, es:[bx] - add ax, 12 - push ax - mov ax, si - add ax, ax - les bx, [bp+arg_8] - add bx, ax - mov ax, es:[bx] - add ax, 12 - push ax - push ds - push offset _Pellets - call @CPellets@add_single$qiiuci15pellet_motion_tiii - add sp, 14h - pop si - pop bp - retn 0Ch -sub_29015 endp - - -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_290F9 proc near - -@@angle = byte ptr -1 - - enter 2, 0 - push si - cmp word_35DDF, 0 - jnz short loc_2910D - call @wand_render_raise_both$qi pascal, 0 - mov word_35DDF, ax - -loc_2910D: - cmp _boss_phase_frame, 50 - jl loc_29589 - cmp _boss_phase_frame, 50 - jnz short loc_29134 - call @sariel_select_for_rank$qmiiiii c, offset _sariel_pattern_state, ds, large 140 or (145 shl 16), large 150 or (155 shl 16) - -loc_29134: - cmp _boss_phase_frame, 100 - jge loc_291FD - xor si, si - jmp loc_291F3 -; --------------------------------------------------------------------------- - -loc_29142: - mov ax, si - imul ax, 260h - mov bx, si - add bx, bx - mov [bx+61FCh], ax - mov bx, si - add bx, bx - mov word ptr [bx+6200h], 0C8h ; '?' - push (32 shl 16) or 48 - mov bx, si - add bx, bx - push word ptr [bx+6208h] - mov bx, si - add bx, bx - push word ptr [bx+6204h] - call _egc_copy_rect_1_to_0_16 - push 7 ; col - mov ax, _boss_phase_frame - mov bx, 3 - cwd - idiv bx - push dx ; image - push GRC_SLOT_BOSS_1 ; slot - mov bx, si - add bx, bx - push word ptr [bx+6200h] ; top - mov bx, si - add bx, bx - push word ptr [bx+61FCh] ; left - call _grc_put_8 - add sp, 12h - mov ax, _boss_phase_frame - mov bx, 4 - cwd - idiv bx - or dx, dx - jnz short loc_291D2 - push PG_1 or ((7 shl 4) shl 16) - mov bx, si - add bx, bx - mov ax, [bx+6200h] - add ax, 12 - push ax - mov bx, si - add bx, bx - mov ax, [bx+61FCh] - add ax, 12 - push ax - push ds - push offset _Pellets - call @CPellets@add_group$qii14pellet_group_ti - add sp, 0Ch - -loc_291D2: - mov bx, si - add bx, bx - mov ax, [bx+61FCh] - mov bx, si - add bx, bx - mov [bx+6204h], ax - mov bx, si - add bx, bx - mov ax, [bx+6200h] - mov bx, si - add bx, bx - mov [bx+6208h], ax - inc si - -loc_291F3: - cmp si, 2 - jl loc_29142 - jmp loc_29589 -; --------------------------------------------------------------------------- - -loc_291FD: - mov ax, _boss_phase_frame - cmp ax, _sariel_pattern_state - jge loc_29331 - xor si, si - jmp loc_29327 -; --------------------------------------------------------------------------- - -loc_2920D: - or si, si - jnz short loc_29216 - mov ax, 5 - jmp short loc_29219 -; --------------------------------------------------------------------------- - -loc_29216: - mov ax, 0FFFBh - -loc_29219: - mov bx, si - add bx, bx - add [bx+61FCh], ax - mov bx, si - add bx, bx - sub word ptr [bx+6200h], 2 - push (32 shl 16) or 48 - mov bx, si - add bx, bx - push word ptr [bx+6208h] - mov bx, si - add bx, bx - push word ptr [bx+6204h] - call _egc_copy_rect_1_to_0_16 - push 7 ; col - mov ax, _boss_phase_frame - mov bx, 3 - cwd - idiv bx - push dx ; image - push GRC_SLOT_BOSS_1 ; slot - mov bx, si - add bx, bx - push word ptr [bx+6200h] ; top - mov bx, si - add bx, bx - push word ptr [bx+61FCh] ; left - call _grc_put_8 - add sp, 12h - mov ax, _boss_phase_frame - mov bx, 4 - cwd - idiv bx - or dx, dx - jnz loc_29306 - push PG_1 or ((7 shl 4) shl 16) - mov bx, si - add bx, bx - mov ax, [bx+6200h] - add ax, 12 - push ax - mov bx, si - add bx, bx - mov ax, [bx+61FCh] - add ax, 12 - push ax - push ds - push offset _Pellets - call @CPellets@add_group$qii14pellet_group_ti - mov bx, si - add bx, bx - mov ax, PLAYFIELD_BOTTOM - sub ax, [bx+6200h] - add ax, 12 - push ax - mov bx, si - add bx, bx - mov ax, [bx+61FCh] - mov dx, si - imul dx, 160 - add ax, dx - add ax, -80 - mov bx, si - add bx, bx - sub ax, [bx+61FCh] - add ax, 12 - push ax - call iatan2 - mov [bp+@@angle], al - pushd 0 or (0 shl 16) - pushd PM_NORMAL or (0 shl 16) - push (7 shl 4) - push word ptr [bp+@@angle] - mov bx, si - add bx, bx - mov ax, [bx+6200h] - add ax, 12 - push ax - mov bx, si - add bx, bx - mov ax, [bx+61FCh] - add ax, 12 - push ax - push ds - push offset _Pellets - call @CPellets@add_single$qiiuci15pellet_motion_tiii - add sp, 20h - -loc_29306: - mov bx, si - add bx, bx - mov ax, [bx+61FCh] - mov bx, si - add bx, bx - mov [bx+6204h], ax - mov bx, si - add bx, bx - mov ax, [bx+6200h] - mov bx, si - add bx, bx - mov [bx+6208h], ax - inc si - -loc_29327: - cmp si, 2 - jl loc_2920D - jmp loc_29589 -; --------------------------------------------------------------------------- - -loc_29331: - cmp _boss_phase_frame, 200 - jge short loc_293A3 - xor si, si - jmp short loc_2939B -; --------------------------------------------------------------------------- - -loc_2933D: - push (32 shl 16) or 48 - mov bx, si - add bx, bx - push word ptr [bx+6208h] - mov bx, si - add bx, bx - push word ptr [bx+6204h] - call _egc_copy_rect_1_to_0_16 - push 7 ; col - mov ax, _boss_phase_frame - mov bx, 3 - cwd - idiv bx - push dx ; image - push GRC_SLOT_BOSS_1 ; slot - mov bx, si - add bx, bx - push word ptr [bx+6200h] ; top - mov bx, si - add bx, bx - push word ptr [bx+61FCh] ; left - call _grc_put_8 - add sp, 12h - mov ax, _boss_phase_frame - mov bx, 4 - cwd - idiv bx - or dx, dx - jnz short loc_2939A - push ds - push offset unk_3AB9C - push ds - push offset unk_3ABA0 - push si - push word ptr [bp+@@angle] - call sub_29015 - -loc_2939A: - inc si - -loc_2939B: - cmp si, 2 - jl short loc_2933D - jmp loc_29589 -; --------------------------------------------------------------------------- - -loc_293A3: - cmp _boss_phase_frame, 240 - jge loc_2945E - cmp _boss_phase_frame, 200 - jnz short loc_293CE - call IRand - mov bx, 2 - cwd - idiv bx - mov word_3ABAC, dx - cmp word_3ABAC, 1 - jnz short loc_293CE - call @wand_lower_both$qv - -loc_293CE: - xor si, si - jmp loc_29454 -; --------------------------------------------------------------------------- - -loc_293D3: - mov ax, word_3ABAC - shl ax, 2 - mov dx, 2 - sub dx, ax - mov bx, si - add bx, bx - add [bx+61FCh], dx - push (32 shl 16) or 48 - mov bx, si - add bx, bx - push word ptr [bx+6208h] - mov bx, si - add bx, bx - push word ptr [bx+6204h] - call _egc_copy_rect_1_to_0_16 - push 7 ; col - mov ax, _boss_phase_frame - mov bx, 3 - cwd - idiv bx - push dx ; image - push GRC_SLOT_BOSS_1 ; slot - mov bx, si - add bx, bx - push word ptr [bx+6200h] ; top - mov bx, si - add bx, bx - push word ptr [bx+61FCh] ; left - call _grc_put_8 - add sp, 12h - mov ax, _boss_phase_frame - mov bx, 4 - cwd - idiv bx - or dx, dx - jnz short loc_29443 - push ds - push offset unk_3AB9C - push ds - push offset unk_3ABA0 - push si - push word ptr [bp+@@angle] - call sub_29015 - -loc_29443: - mov bx, si - add bx, bx - mov ax, [bx+61FCh] - mov bx, si - add bx, bx - mov [bx+6204h], ax - inc si - -loc_29454: - cmp si, 2 - jl loc_293D3 - jmp loc_29589 -; --------------------------------------------------------------------------- - -loc_2945E: - cmp _boss_phase_frame, 320 - jge loc_2954A - cmp _boss_phase_frame, 240 - jnz short loc_294AA - call IRand - mov bx, 2 - cwd - idiv bx - mov word_3ABAE, dx - cmp word_3ABAE, 0 - jnz short loc_29494 - mov ax, word_3ABAE - cmp ax, word_3ABAC - jnz short loc_29494 - call @wand_lower_both$qv - jmp short loc_294AA -; --------------------------------------------------------------------------- - -loc_29494: - cmp word_3ABAE, 1 - jnz short loc_294AA - mov ax, word_3ABAE - cmp ax, word_3ABAC - jnz short loc_294AA - mov word_35DDF, 0 - -loc_294AA: - xor si, si - jmp loc_29541 -; --------------------------------------------------------------------------- - -loc_294AF: - mov ax, word_3ABAE - cmp ax, word_3ABAC - jz short loc_294C0 - shl ax, 2 - mov dx, 2 - jmp short loc_294C9 -; --------------------------------------------------------------------------- - -loc_294C0: - mov ax, word_3ABAE - shl ax, 3 - mov dx, 4 - -loc_294C9: - sub dx, ax - mov bx, si - add bx, bx - sub [bx+61FCh], dx - push (32 shl 16) or 48 - mov bx, si - add bx, bx - push word ptr [bx+6208h] - mov bx, si - add bx, bx - push word ptr [bx+6204h] - call _egc_copy_rect_1_to_0_16 - push 7 ; col - mov ax, _boss_phase_frame - mov bx, 3 - cwd - idiv bx - push dx ; image - push GRC_SLOT_BOSS_1 ; slot - mov bx, si - add bx, bx - push word ptr [bx+6200h] ; top - mov bx, si - add bx, bx - push word ptr [bx+61FCh] ; left - call _grc_put_8 - add sp, 12h - mov ax, _boss_phase_frame - mov bx, 4 - cwd - idiv bx - or dx, dx - jnz short loc_29530 - push ds - push offset unk_3AB9C - push ds - push offset unk_3ABA0 - push si - push word ptr [bp+@@angle] - call sub_29015 - -loc_29530: - mov bx, si - add bx, bx - mov ax, [bx+61FCh] - mov bx, si - add bx, bx - mov [bx+6204h], ax - inc si - -loc_29541: - cmp si, 2 - jl loc_294AF - jmp short loc_29589 -; --------------------------------------------------------------------------- - -loc_2954A: - cmp _boss_phase_frame, 300 - jle short loc_29589 - xor si, si - jmp short loc_29575 -; --------------------------------------------------------------------------- - -loc_29556: - push (32 shl 16) or 48 - mov bx, si - add bx, bx - push word ptr [bx+6200h] - mov bx, si - add bx, bx - push word ptr [bx+61FCh] - call _egc_copy_rect_1_to_0_16 - add sp, 8 - inc si - -loc_29575: - cmp si, 2 - jl short loc_29556 - call @wand_lower_both$qv - mov _boss_phase_frame, 0 - mov word_35DDF, 0 - -loc_29589: - pop si - leave - retn -sub_290F9 endp - - ; =============== S U B R O U T I N E ======================================= ; Attributes: bp-based frame @@ -27651,7 +27042,7 @@ loc_2C3BE: loc_2C40D: cmp word_35E95, 1 jnz short loc_2C419 - call sub_290F9 + call @pattern_vortices$qv jmp short loc_2C423 ; --------------------------------------------------------------------------- @@ -29186,6 +28577,7 @@ _spawnray_target_prev_x dw 999 _spawnray_target_prev_y dw 999 BIRD_COUNT = 30 +VORTEX_COUNT = 2 public _birds_alive _birds_alive db BIRD_COUNT dup(0) @@ -29193,7 +28585,9 @@ _birds_alive db BIRD_COUNT dup(0) public _wand_raise_frames _wand_raise_frames dw 0 -word_35DDF dw 0 +public _pattern1_wand_raise_animation_do +_pattern1_wand_raise_animation_do dw 0 + byte_35DE1 db 0 byte_35DE2 db 0 word_35DE3 dw 0 @@ -29636,12 +29030,17 @@ CBirds ends public _birds _birds CBirds -unk_3AB9C db ? ; - db 3 dup(?) -unk_3ABA0 db ? ; - db 11 dup(?) -word_3ABAC dw ? -word_3ABAE dw ? + +public _pattern1_cur_left, _pattern1_cur_top +public _pattern1_prev_left, _pattern1_prev_top +public _pattern1_dir_first, _pattern1_dir_second +_pattern1_cur_left dw VORTEX_COUNT dup(?) +_pattern1_cur_top dw VORTEX_COUNT dup(?) +_pattern1_prev_left dw VORTEX_COUNT dup(?) +_pattern1_prev_top dw VORTEX_COUNT dup(?) +_pattern1_dir_first dw ? +_pattern1_dir_second dw ? + db 160 dup(?) subpixel_point_3AC50 Point word_3AC54 dw ?