From 5d93a5038b47909a4fb4e86214403dad4335ec66 Mon Sep 17 00:00:00 2001 From: nmlgc Date: Sun, 15 May 2022 16:56:32 +0200 Subject: [PATCH] [Decompilation] [th01] Elis: Random bat movement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Which would look even nicer if the bat wasn't exclusively rendered on the byte-aligned 8×1-pixel grid. Completes P0194, funded by Ember2528. --- th01/main/boss/b15m.cpp | 80 +++++++++++++++++++++++++++ th01_reiiden.asm | 117 +++------------------------------------- 2 files changed, 87 insertions(+), 110 deletions(-) diff --git a/th01/main/boss/b15m.cpp b/th01/main/boss/b15m.cpp index 0703bd85..2216ed8a 100644 --- a/th01/main/boss/b15m.cpp +++ b/th01/main/boss/b15m.cpp @@ -2,6 +2,7 @@ /// -------------------------- #include +#include #include "platform.h" #include "pc98.h" #include "planar.h" @@ -83,6 +84,13 @@ enum elis_starpattern_ret_t { _elis_starpattern_ret_t_FORCE_INT16 = 0x7FFF, }; +enum elis_phase_5_subphase_t { + P5_PATTERN = false, + P5_TRANSFORM = true, + + _elis_phase_5_subphase_t_FORCE_INT16 = 0x7FFF, +}; + // Returns `CHOOSE_NEW` if done, or the pattern ID within the phase if still // ongoing. typedef int (*elis_phase_1_3_pattern_func_t)(void); @@ -116,6 +124,7 @@ enum elis_entity_t { }; static const int BAT_CELS = 3; +static const int BAT_SPEED_DIVISOR = 3; enum elis_entity_cel_t { // ENT_STILL_OR_WAVE @@ -243,6 +252,18 @@ inline screen_y_t surround_random_top(elis_entity_t relative_to) { } // ------------- +// Random teleport and bat movement coordinates +// -------------------------------------------- + +inline screen_x_t elis_playfield_random_left(void) { + return (PLAYFIELD_LEFT + (rand() % (PLAYFIELD_W - GIRL_W))); +} + +inline screen_y_t elis_playfield_random_top(void) { + return (PLAYFIELD_TOP + playfield_rand_y(17 / 42.0f)); +} +// -------------------------------------------- + // .GRC entities // ------------- @@ -1250,3 +1271,62 @@ elis_form_t transform_bat_to_girl(void) #undef rifts } + +// Like the flystep functions in later games, just without the "step" part, and +// with explicit pattern/transformation semantics. +elis_phase_5_subphase_t bat_fly_random(pixel_t &velocity_x, pixel_t &velocity_y) +{ + enum { + SPEED = 2, + }; + + #define target_left bat_target_left + #define target_top bat_target_top + #define frames_until_target bat_frames_until_target + + extern screen_x_t target_left; // should be local + extern screen_y_t target_top; // should be local + extern int frames_until_target; + + if(boss_phase_frame < BAT_SPEED_DIVISOR) { + velocity_x = 0; + velocity_y = 0; + return P5_PATTERN; + } + if(boss_phase_frame == BAT_SPEED_DIVISOR) { + do { + target_left = elis_playfield_random_left(); + target_top = (elis_playfield_random_top() + ((GIRL_H - BAT_H) / 2)); + } while( + (abs(ent_bat.cur_left - target_left) < (PLAYFIELD_W / 5)) && + (abs(ent_bat.cur_top - target_top) < ((PLAYFIELD_H * 4) / 21)) + ); + vector2_between( + ent_bat.cur_left, + ent_bat.cur_top, + target_left, + target_top, + velocity_x, + velocity_y, + SPEED + ); + frames_until_target = (abs(target_left - ent_bat.cur_left) / SPEED); + } + + // What is something like "gravity" doing in a bat movement function? + // Quite the interesting interpretation as well, even if it wasn't always + // zero. MODDERS: Remove. + velocity_y += (((rand() % 5) - 2) / 10); + + if((boss_phase_frame / BAT_SPEED_DIVISOR) >= frames_until_target) { + velocity_x = 0; + velocity_y = 0; + boss_phase_frame = 0; + return P5_TRANSFORM; + } + return P5_PATTERN; + + #undef frames_until_target + #undef target_top + #undef target_left +} diff --git a/th01_reiiden.asm b/th01_reiiden.asm index 8ec4f581..b710dba7 100644 --- a/th01_reiiden.asm +++ b/th01_reiiden.asm @@ -17413,113 +17413,11 @@ ELIS_BASE_TOP = (PLAYFIELD_TOP + ((PLAYFIELD_H / 21) * 5) - (ELIS_GIRL_H / 2)) extern @phase_3$qi:proc extern @transform_girl_to_bat$qv:proc extern @transform_bat_to_girl$qv:proc + extern @bat_fly_random$qmit1: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_26D12 proc far - -var_6 = word ptr -6 -var_4 = word ptr -4 -var_2 = word ptr -2 -arg_0 = dword ptr 6 -arg_4 = dword ptr 0Ah - - enter 6, 0 - cmp _boss_phase_frame, 3 - jge short loc_26D30 - les bx, [bp+arg_0] - mov word ptr es:[bx], 0 - les bx, [bp+arg_4] - mov word ptr es:[bx], 0 - jmp loc_26DFE -; --------------------------------------------------------------------------- - -loc_26D30: - cmp _boss_phase_frame, 3 - jnz loc_26DB8 - -loc_26D39: - call IRand - mov bx, 200h - cwd - idiv bx - mov x_3A765, dx - call IRand - mov bx, 88h - cwd - idiv bx - add dx, 96 - mov y_3A767, dx - mov ax, elis_bat.BE_cur_left - sub ax, x_3A765 - mov [bp+var_2], ax - cwd - xor ax, dx - sub ax, dx - cmp ax, 80h ; '?' - jge short loc_26D82 - mov ax, elis_bat.BE_cur_top - sub ax, y_3A767 - mov [bp+var_4], ax - cwd - xor ax, dx - sub ax, dx - cmp ax, 40h - jl short loc_26D39 - -loc_26D82: - call _vector2_between c, large [dword ptr elis_bat.BE_cur_left], x_3A765, y_3A767, large [bp+arg_0], large [bp+arg_4], 2 - mov ax, x_3A765 - sub ax, elis_bat.BE_cur_left - mov [bp+var_6], ax - cwd - xor ax, dx - sub ax, dx - cwd - sub ax, dx - sar ax, 1 - mov word_3A769, ax - -loc_26DB8: - call IRand - mov bx, 5 - cwd - idiv bx - add dx, 0FFFEh - mov bx, 0Ah - mov ax, dx - cwd - idiv bx - les bx, [bp+arg_4] - add es:[bx], ax - mov ax, _boss_phase_frame - mov bx, 3 - cwd - idiv bx - cmp ax, word_3A769 - jl short loc_26DFE - les bx, [bp+arg_0] - mov word ptr es:[bx], 0 - les bx, [bp+arg_4] - mov word ptr es:[bx], 0 - mov _boss_phase_frame, 0 - mov ax, 1 - leave - retf -; --------------------------------------------------------------------------- - -loc_26DFE: - xor ax, ax - leave - retf -sub_26D12 endp - - ; =============== S U B R O U T I N E ======================================= ; Attributes: bp-based frame @@ -18847,10 +18745,7 @@ loc_27B85: jnz short loc_27C06 cmp word_35D48, 0 jnz short loc_27BE7 - pushd [bp+arg_8] - pushd [bp+arg_4] - call sub_26D12 - add sp, 8 + call @bat_fly_random$qmit1 c, large [bp+arg_4], [bp+arg_8] mov word_35D48, ax cmp word_35D4A, 0 jnz short loc_27BBE @@ -20819,9 +20714,11 @@ CEntities _pattern5_rifts, 5 CEntities _girl_to_bat_rifts, 5 CEntities _bat_to_girl_rifts, 5 -x_3A765 dw ? -y_3A767 dw ? -word_3A769 dw ? +public _bat_target_left, _bat_target_top, _bat_frames_until_target +_bat_target_left dw ? +_bat_target_top dw ? +_bat_frames_until_target dw ? + word_3A76B dw ? word_3A76D dw ? angle_3A76F db ?