From 9c7981fc5951af6a26caf69782e33f4b82a2de14 Mon Sep 17 00:00:00 2001 From: nmlgc Date: Fri, 13 Aug 2021 02:09:32 +0200 Subject: [PATCH] [Decompilation] [th01] Konngara: Pattern 10/12 The one with lasers fired from the sword across the whole playfield, either from left to right or from right to left, together with aimed 3-way spreads, every 10 frames. Part of P0155, funded by Ember2528. --- Research/Borland C++ decompilation.md | 2 + th01/main/boss/b20j.cpp | 74 +++++++++++++++++ th01/main/bullet/laser_s[bss].asm | 1 + th01_reiiden.asm | 110 ++------------------------ 4 files changed, 85 insertions(+), 102 deletions(-) diff --git a/Research/Borland C++ decompilation.md b/Research/Borland C++ decompilation.md index b577cde0..3b1b35d2 100644 --- a/Research/Borland C++ decompilation.md +++ b/Research/Borland C++ decompilation.md @@ -390,6 +390,8 @@ SUB SP, } ``` + This also applies to divisors stored in `BX`. + ### `-3` (80386 Instructions) + `-Z` (Suppress register reloads) Bundles two consecutive 16-bit function parameters into a single 32-bit one, diff --git a/th01/main/boss/b20j.cpp b/th01/main/boss/b20j.cpp index c2d23993..b907154f 100644 --- a/th01/main/boss/b20j.cpp +++ b/th01/main/boss/b20j.cpp @@ -37,6 +37,7 @@ extern "C" { #include "th01/main/boss/boss.hpp" #include "th01/main/boss/palette.hpp" #include "th01/main/bullet/pellet.hpp" +#include "th01/main/bullet/laser_s.hpp" #include "th01/main/hud/hp.hpp" // Coordinates @@ -101,6 +102,7 @@ extern union { int group; // pellet_group_t int interval; subpixel_t speed; + pixel_t delta_x; int unused; } pattern_state; extern bool16 invincible; @@ -1382,6 +1384,78 @@ void pattern_slash_triangular(void) #undef spawner_left } +void pattern_lasers_and_3_spread(void) +{ + #define target_left pattern9_target_left + #define target_y pattern9_target_y + #define right_to_left pattern9_right_to_left + + // These have no reason to be static. + extern screen_x_t target_left; + extern screen_y_t target_y; + + extern bool16 right_to_left; + + enum { + INTERVAL = 10, + }; + + if(boss_phase_frame == 10) { + face_expression_set_and_put(FE_AIM); + } + if(boss_phase_frame < 100) { + return; + } + if(boss_phase_frame == 100) { + right_to_left = (rand() % 2); + + // Divisor = number of lasers that are effectively fired. + select_for_rank(pattern_state.delta_x, + (PLAYFIELD_W / 5), + (PLAYFIELD_W / 6.66), + (PLAYFIELD_W / 8), + (PLAYFIELD_W / 10) + ); + } + if((boss_phase_frame % INTERVAL) == 0) { + if(right_to_left == 0) { + target_left = (PLAYFIELD_LEFT + ( + ((boss_phase_frame - 100) / INTERVAL) * pattern_state.delta_x + )); + } else { + target_left = (PLAYFIELD_RIGHT - ( + ((boss_phase_frame - 100) / INTERVAL) * pattern_state.delta_x + )); + } + target_y = PLAYFIELD_BOTTOM; + + // Quite a roundabout way of preventing a buffer overflow, but fine. + shootout_lasers[ + (boss_phase_frame / INTERVAL) % SHOOTOUT_LASER_COUNT + ].spawn( + SWORD_CENTER_X, SWORD_CENTER_Y, + target_left, target_y, + (to_sp(8.5f) / 2), 7, 30, 5 + ); + mdrv2_se_play(6); + + if( + ((right_to_left == false) && (target_left >= PLAYFIELD_RIGHT)) || + ((right_to_left == true) && (target_left <= PLAYFIELD_LEFT)) + ) { + boss_phase_frame = 0; + } + + Pellets.add_group( + SWORD_CENTER_X, SWORD_CENTER_Y, PG_3_SPREAD_WIDE_AIMED, to_sp(4.5f) + ); + } + + #undef right_to_left + #undef target_y + #undef target_left +} + char konngara_esc_cls[] = "\x1B*"; char konngara_esc_mode_graph[] = "\x1B)3"; char konngara_esc_color_bg_black_fg_black[] = "\x1B[16;40m"; diff --git a/th01/main/bullet/laser_s[bss].asm b/th01/main/bullet/laser_s[bss].asm index 885409a2..60312478 100644 --- a/th01/main/bullet/laser_s[bss].asm +++ b/th01/main/bullet/laser_s[bss].asm @@ -29,6 +29,7 @@ CShootoutLaser struc db ? CShootoutLaser ends +public _shootout_lasers _shootout_lasers CShootoutLaser SHOOTOUT_LASER_COUNT dup() shootout_laser_0 equ <_shootout_lasers[0 * size CShootoutLaser]> shootout_laser_1 equ <_shootout_lasers[1 * size CShootoutLaser]> diff --git a/th01_reiiden.asm b/th01_reiiden.asm index d7af1d69..406a16e3 100644 --- a/th01_reiiden.asm +++ b/th01_reiiden.asm @@ -37649,6 +37649,7 @@ main_37_TEXT segment byte public 'CODE' use16 extern @slash_animate$qv:proc extern @pattern_slash_rain$qv:proc extern @pattern_slash_triangular$qv:proc + extern @pattern_lasers_and_3_spread$qv:proc main_37_TEXT ends main_37__TEXT segment byte public 'CODE' use16 @@ -37666,103 +37667,6 @@ FD_UNINITIALIZED = 9 FE_NEUTRAL = 0 FE_AIM = 3 -; =============== S U B R O U T I N E ======================================= - -; Attributes: bp-based frame - -sub_2EB91 proc far - push bp - mov bp, sp - cmp _boss_phase_frame, 10 - jnz short loc_2EBA2 - call @face_expression_set_and_put$q17face_expression_t stdcall, FE_AIM - pop cx - -loc_2EBA2: - cmp _boss_phase_frame, 100 - jl loc_2EC98 - cmp _boss_phase_frame, 100 - jnz short loc_2EBD8 - call IRand - mov bx, 2 - cwd - idiv bx - mov word_3B523, dx - call @konngara_select_for_rank$qmiiiii c, offset _konngara_pattern_state, ds, large 128 or (96 shl 16), large 80 or (64 shl 16) - -loc_2EBD8: - mov ax, _boss_phase_frame - mov bx, 10 - cwd - idiv bx - or dx, dx - jnz loc_2EC98 - cmp word_3B523, 0 - jnz short loc_2EC00 - mov ax, _boss_phase_frame - add ax, -100 - cwd - idiv bx - imul _konngara_pattern_state - mov laser_target_left_3B51F, ax - jmp short loc_2EC19 -; --------------------------------------------------------------------------- - -loc_2EC00: - mov ax, _boss_phase_frame - add ax, -100 - mov bx, 10 - cwd - idiv bx - imul _konngara_pattern_state - mov dx, PLAYFIELD_RIGHT - sub dx, ax - mov laser_target_left_3B51F, dx - -loc_2EC19: - mov laser_target_y_3B521, PLAYFIELD_BOTTOM - push 30 or (5 shl 16) ; (moveout_at_age) or (w shl 16) - push ((8 * 8) + 4) or (7 shl 16) ; (speed_multiplied_by_8) or (col shl 16) - push laser_target_y_3B521 ; target_y - push laser_target_left_3B51F ; target_left - push 410 or (70 shl 16) ; (origin_left) or (origin_y shl 16) - mov ax, _boss_phase_frame - mov bx, 10 - cwd - idiv bx - cwd - idiv bx - imul dx, size CShootoutLaser - add dx, offset _shootout_lasers - push ds ; this (segment) - push dx ; this (offset) - call @CShootoutLaser@spawn$qiiiiiiii - push 6 - call _mdrv2_se_play - add sp, 16h - cmp word_3B523, 0 - jnz short loc_2EC6C - cmp laser_target_left_3B51F, PLAYFIELD_RIGHT - jge short loc_2EC7A - -loc_2EC6C: - cmp word_3B523, 1 - jnz short loc_2EC80 - cmp laser_target_left_3B51F, 0 - jg short loc_2EC80 - -loc_2EC7A: - mov _boss_phase_frame, 0 - -loc_2EC80: - call @CPellets@add_group$qii14pellet_group_ti c, offset _Pellets, ds, large 410 or (70 shl 16), large PG_3_SPREAD_WIDE_AIMED or (((4 shl 4) + 8) shl 16) - -loc_2EC98: - pop bp - retf -sub_2EB91 endp - - ; =============== S U B R O U T I N E ======================================= ; Attributes: bp-based frame @@ -38475,7 +38379,7 @@ loc_2F3B5: loc_2F3CB: cmp word_35FF8, 1 jnz short loc_2F3D8 - call sub_2EB91 + call @pattern_lasers_and_3_spread$qv jmp short loc_2F42A ; --------------------------------------------------------------------------- @@ -38772,7 +38676,7 @@ loc_2F69A: loc_2F6A7: cmp word_35FF8, 8 jnz short loc_2F6B4 - call sub_2EB91 + call @pattern_lasers_and_3_spread$qv jmp short loc_2F720 ; --------------------------------------------------------------------------- @@ -40471,9 +40375,11 @@ public _pattern8_spawner_left, _pattern8_spawner_top _pattern8_spawner_left dw ? _pattern8_spawner_top dw ? -laser_target_left_3B51F dw ? -laser_target_y_3B521 dw ? -word_3B523 dw ? +public _pattern9_target_left, _pattern9_target_y, _pattern9_right_to_left +_pattern9_target_left dw ? +_pattern9_target_y dw ? +_pattern9_right_to_left dw ? + word_3B525 dw ? word_3B527 dw ? public _konngara_invincible, _konngara_invincibility_frame