[Decompilation] [th01] Elis: Random bat movement

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.
This commit is contained in:
nmlgc 2022-05-15 16:56:32 +02:00
parent dfb0c43b86
commit 5d93a5038b
2 changed files with 87 additions and 110 deletions

View File

@ -2,6 +2,7 @@
/// --------------------------
#include <stddef.h>
#include <stdlib.h>
#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
}

View File

@ -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 ?