diff --git a/th01/main/boss/b15m.cpp b/th01/main/boss/b15m.cpp index 47d1b489..28249d12 100644 --- a/th01/main/boss/b15m.cpp +++ b/th01/main/boss/b15m.cpp @@ -83,6 +83,7 @@ enum elis_starpattern_ret_t { extern union { int angle_range; // ACTUAL TYPE: unsigned char pellet_group_t group; + int ring; int speed_multiplied_by_8; } pattern_state; // -------- @@ -116,6 +117,8 @@ enum elis_entity_cel_t { // ENT_ATTACK C_PREPARE = 0, + C_ATTACK_1 = 1, + C_ATTACK_2 = 2, }; #define ent_still_or_wave boss_entities[ENT_STILL_OR_WAVE] @@ -140,6 +143,9 @@ inline void ent_sync(elis_entity_t dst, elis_entity_t src) { ); } +// It's needed in the functions below... +void girl_bg_put(int unncessary_parameter_that_still_needs_to_be_1_or_2); + // [unput_0] should theoretically always be `true`. Making sure that both VRAM // pages are identical avoids visual glitches from blitting cels with different // transparent areas on top of each other (see: Mima's third arm)… but you can @@ -147,8 +153,6 @@ inline void ent_sync(elis_entity_t dst, elis_entity_t src) { inline void ent_unput_and_put_both( elis_entity_t ent, elis_entity_cel_t cel, bool unput_0 = true ) { - void girl_bg_put(int unncessary_parameter_that_still_needs_to_be_1_or_2); - graph_accesspage_func(1); girl_bg_put(ent + 1); boss_entities[ent].move_lock_and_put_image_8(cel); @@ -158,6 +162,19 @@ inline void ent_unput_and_put_both( } boss_entities[ent].move_lock_and_put_image_8(cel); } + +inline void ent_put_both(elis_entity_t ent, elis_entity_cel_t cel) { + graph_accesspage_func(1); boss_entities[ent].move_lock_and_put_image_8(cel); + graph_accesspage_func(0); boss_entities[ent].move_lock_and_put_image_8(cel); +} + +#define ent_attack_render() { \ + if((boss_phase_frame % 8) == 0) { \ + ent_unput_and_put_both(ENT_ATTACK, C_ATTACK_1); \ + } else if((boss_phase_frame % 8) == 4) { \ + ent_put_both(ENT_ATTACK, C_ATTACK_2); \ + } \ +} // -------- // Form-relative coordinates @@ -844,3 +861,47 @@ elis_starpattern_ret_t near star_of_david(void) #undef circle } + +int pattern_curved_5_stack_rings(void) +{ + #define fire_ring(i, angle_offset, speed) { \ + for(int i = 0; i < pattern_state.ring; i++) { \ + Pellets.add_single( \ + (form_center_x(F_GIRL) - (PELLET_W / 2)), \ + (form_center_y(F_GIRL) - (PELLET_H / 2)), \ + (((0x100 / pattern_state.ring) * i) + angle_offset), \ + to_sp(speed) \ + ); \ + } \ + } + + ent_attack_render(); + if(boss_phase_frame == 10) { + select_for_rank(pattern_state.ring, 14, 16, 18, 20); + fire_ring(i, 0x00, 3.0f); + } else if(boss_phase_frame == 16) { + fire_ring(i, 0x02, 3.375f); + } else if(boss_phase_frame == 24) { + fire_ring(i, 0x04, 4.0f); + } else if(boss_phase_frame == 32) { + fire_ring(i, 0x06, 4.5f); + } else if(boss_phase_frame == 40) { + fire_ring(i, 0x08, 5.0f); + } else if(boss_phase_frame > 60) { + boss_phase_frame = 0; + + // ZUN bug: A completely unnecessary unblitting call that doesn't even + // switch back to VRAM page 0. At first, this might look like it has no + // effect since Elis runs a wave_teleport() animation afterwards. But + // if any player shot, bomb, or Orb sprites overlap Elis between the + // end of this pattern and the start of the teleport animation, their + // corresponding unblitting calls will rip holes into the Elis sprite. + graph_accesspage_func(1); + girl_bg_put(2); + + return CHOOSE_NEW; + } + return 1; + + #undef fire_ring +} diff --git a/th01_reiiden.asm b/th01_reiiden.asm index d3bb6eab..8c82f150 100644 --- a/th01_reiiden.asm +++ b/th01_reiiden.asm @@ -17410,257 +17410,11 @@ ELIS_BASE_TOP = (PLAYFIELD_TOP + ((PLAYFIELD_H / 21) * 5) - (ELIS_GIRL_H / 2)) extern @elis_select_for_rank$qmiiiii:proc extern @phase_1$qi:proc @star_of_david$qv procdesc near + extern @pattern_curved_5_stack_rings$qv:proc main_35_TEXT ends main_35__TEXT segment byte public 'CODE' use16 -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_260DC proc far - push bp - mov bp, sp - push si - mov ax, _boss_phase_frame - mov bx, 8 - cwd - idiv bx - or dx, dx - jnz short loc_26136 - push 1 - call _graph_accesspage_func - call @girl_bg_put$qi stdcall, 2 - mov elis_attack.BE_move_lock_frame, 0 - mov elis_attack.BE_bos_image, 1 - call @CBossEntity@move_lock_and_put_8$qiiii stdcall, offset elis_attack, ds, large 0, large 0 or (3 shl 16) - push 0 - call _graph_accesspage_func - call @girl_bg_put$qi stdcall, 2 - add sp, 14h - mov elis_attack.BE_move_lock_frame, 0 - mov elis_attack.BE_bos_image, 1 - jmp short loc_2617F -; --------------------------------------------------------------------------- - -loc_26136: - mov ax, _boss_phase_frame - mov bx, 8 - cwd - idiv bx - cmp dx, 4 - jnz short loc_26194 - push 1 - call _graph_accesspage_func - mov elis_attack.BE_move_lock_frame, 0 - mov elis_attack.BE_bos_image, 2 - call @CBossEntity@move_lock_and_put_8$qiiii stdcall, offset elis_attack, ds, large 0, large 0 or (3 shl 16) - push 0 - call _graph_accesspage_func - add sp, 10h - mov elis_attack.BE_move_lock_frame, 0 - mov elis_attack.BE_bos_image, 2 - -loc_2617F: - call @CBossEntity@move_lock_and_put_8$qiiii c, offset elis_attack, ds, large 0, large 0 or (3 shl 16) - -loc_26194: - cmp _boss_phase_frame, 10 - jnz short loc_261ED - call @elis_select_for_rank$qmiiiii c, offset _elis_pattern_state, ds, large 14 or (16 shl 16), large 18 or (20 shl 16) - xor si, si - jmp short loc_261E4 -; --------------------------------------------------------------------------- - -loc_261B6: - pushd 0 or (0 shl 16) - pushd PM_REGULAR or (0 shl 16) - push (3 shl 4) - mov ax, 256 - cwd - idiv _elis_pattern_state - imul si - push ax - mov ax, elis_still_or_wave.BE_cur_top - add ax, 44 - push ax - mov ax, elis_still_or_wave.BE_cur_left - add ax, 60 - push ax - push ds - push offset _Pellets - call @CPellets@add_single$qiiuci15pellet_motion_tiii - add sp, 14h - inc si - -loc_261E4: - cmp si, _elis_pattern_state - jl short loc_261B6 - jmp loc_2631C -; --------------------------------------------------------------------------- - -loc_261ED: - cmp _boss_phase_frame, 16 - jnz short loc_26231 - xor si, si - jmp short loc_26228 -; --------------------------------------------------------------------------- - -loc_261F8: - pushd 0 or (0 shl 16) - pushd PM_REGULAR or (0 shl 16) - push (3 shl 4) + 6 - mov ax, 256 - cwd - idiv _elis_pattern_state - imul si - add al, 2 - push ax - mov ax, elis_still_or_wave.BE_cur_top - add ax, 44 - push ax - mov ax, elis_still_or_wave.BE_cur_left - add ax, 60 - push ax - push ds - push offset _Pellets - call @CPellets@add_single$qiiuci15pellet_motion_tiii - add sp, 14h - inc si - -loc_26228: - cmp si, _elis_pattern_state - jl short loc_261F8 - jmp loc_2631C -; --------------------------------------------------------------------------- - -loc_26231: - cmp _boss_phase_frame, 24 - jnz short loc_26275 - xor si, si - jmp short loc_2626C -; --------------------------------------------------------------------------- - -loc_2623C: - pushd 0 or (0 shl 16) - pushd PM_REGULAR or (0 shl 16) - push (4 shl 4) - mov ax, 256 - cwd - idiv _elis_pattern_state - imul si - add al, 4 - push ax - mov ax, elis_still_or_wave.BE_cur_top - add ax, 44 - push ax - mov ax, elis_still_or_wave.BE_cur_left - add ax, 60 - push ax - push ds - push offset _Pellets - call @CPellets@add_single$qiiuci15pellet_motion_tiii - add sp, 14h - inc si - -loc_2626C: - cmp si, _elis_pattern_state - jl short loc_2623C - jmp loc_2631C -; --------------------------------------------------------------------------- - -loc_26275: - cmp _boss_phase_frame, 32 - jnz short loc_262B8 - xor si, si - jmp short loc_262B0 -; --------------------------------------------------------------------------- - -loc_26280: - pushd 0 or (0 shl 16) - pushd PM_REGULAR or (0 shl 16) - push (4 shl 4) + 8 - mov ax, 256 - cwd - idiv _elis_pattern_state - imul si - add al, 6 - push ax - mov ax, elis_still_or_wave.BE_cur_top - add ax, 44 - push ax - mov ax, elis_still_or_wave.BE_cur_left - add ax, 60 - push ax - push ds - push offset _Pellets - call @CPellets@add_single$qiiuci15pellet_motion_tiii - add sp, 14h - inc si - -loc_262B0: - cmp si, _elis_pattern_state - jl short loc_26280 - jmp short loc_2631C -; --------------------------------------------------------------------------- - -loc_262B8: - cmp _boss_phase_frame, 40 - jnz short loc_262FB - xor si, si - jmp short loc_262F3 -; --------------------------------------------------------------------------- - -loc_262C3: - pushd 0 or (0 shl 16) - pushd PM_REGULAR or (0 shl 16) - push (5 shl 4) - mov ax, 256 - cwd - idiv _elis_pattern_state - imul si - add al, 8 - push ax - mov ax, elis_still_or_wave.BE_cur_top - add ax, 44 - push ax - mov ax, elis_still_or_wave.BE_cur_left - add ax, 60 - push ax - push ds - push offset _Pellets - call @CPellets@add_single$qiiuci15pellet_motion_tiii - add sp, 14h - inc si - -loc_262F3: - cmp si, _elis_pattern_state - jl short loc_262C3 - jmp short loc_2631C -; --------------------------------------------------------------------------- - -loc_262FB: - cmp _boss_phase_frame, 60 - jle short loc_2631C - mov _boss_phase_frame, 0 - push 1 - call _graph_accesspage_func - call @girl_bg_put$qi stdcall, 2 - add sp, 4 - xor ax, ax - jmp short loc_2631F -; --------------------------------------------------------------------------- - -loc_2631C: - mov ax, 1 - -loc_2631F: - pop si - pop bp - retf -sub_260DC endp - - ; =============== S U B R O U T I N E ======================================= ; Attributes: bp-based frame @@ -18261,7 +18015,7 @@ loc_268E8: ; --------------------------------------------------------------------------- loc_268FA: - call sub_260DC + call @pattern_curved_5_stack_rings$qv jmp short loc_2692E ; ---------------------------------------------------------------------------