[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.
This commit is contained in:
nmlgc 2021-08-13 02:09:32 +02:00
parent 27c7ffaaa3
commit 9c7981fc59
4 changed files with 85 additions and 102 deletions

View File

@ -390,6 +390,8 @@ SUB SP, <stack size>
}
```
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,

View File

@ -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";

View File

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

View File

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