[Decompilation] [th04/th05] Dialog: Blocking main function

Part of P0259, funded by Splashman and Yanga.
This commit is contained in:
nmlgc 2023-10-12 02:36:32 +02:00
parent 0f45a5a89f
commit 63e9257279
8 changed files with 119 additions and 118 deletions

View File

@ -1,11 +1,10 @@
// Properly declared, DEMO?.REC uses this structure:
//
// template <size_t Frames> struct REC {
// input_replay_t input[Frames];
// bool shift[Frames];
// };
//
// This declaration would also work with the overly large TH05 Extra Stage
template <size_t Frames> struct REC {
input_replay_t input[Frames];
bool shift[Frames];
};
// The above declaration would also work with the overly long TH05 Extra Stage
// Clear replay. However, ZUN not only uses the same pointer for both that
// replay and regular ones, he also only accesses the [shift] flag via adding
// either DEMO_N or DEMO_N_EXTRA to the stage frame index. TH05 calculates that

View File

@ -227,3 +227,23 @@ void near dialog_run(void)
}
overlay_wipe();
}
void dialog_animate(void)
{
dialog_init();
dialog_pre();
dialog_run();
/* TODO: Replace with the decompiled call
* tiles_activate_and_render_all_for_next_N_frames(2);
* once that function is part of the same segment */
_asm {
push 2;
nop;
push cs;
call near ptr tiles_activate_and_render_all_for_next_N_frames;
}
dialog_exit();
dialog_post();
}

View File

@ -27,14 +27,7 @@ bool near std_update_frames_then_animate_dialog_and_activate_boss_if_done(void)
}
#endif
/* TODO: Replace with the decompiled call
* dialog_animate();
* once that function is part of this translation unit */
_asm {
nop;
push cs;
call near ptr dialog_animate;
}
dialog_animate();
std_update = std_update_done;
bg_render_not_bombing = boss_bg_render_func;

View File

@ -167,6 +167,19 @@ inline void dialog_text_put(shiftjis_t* const& text) {
} \
}
inline void dialog_pre(void) {
overlay_wipe();
palette_settone(100);
graph_accesspage(page_front);
dialog_box_fade_in_animate();
playfield_copy_front_to_back();
}
inline void dialog_post(void) {
graph_accesspage(page_back);
frame_delay(1);
}
// Script commands
// ---------------

View File

@ -1764,7 +1764,6 @@ public @TILES_RENDER$QV
@tiles_render$qv endp
extern @tiles_activate$qv:proc
extern @TILES_ACTIVATE_AND_RENDER_ALL_FO$QUC:proc
TILE_TEXT ends
mai_TEXT segment word public 'CODE' use16
@ -1905,37 +1904,7 @@ DIALOG_TEXT segment byte public 'CODE' use16
extern @dialog_load_yuuka5_defeat_bad$qv:proc
@dialog_free$qv procdesc near
@std_update_frames_then_animate_d$qv procdesc near
@playfield_copy_front_to_back$qv procdesc near
@dialog_box_fade_in_animate$qv procdesc near
@dialog_run$qv procdesc pascal near
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
public @dialog_animate$qv
@dialog_animate$qv proc far
push bp
mov bp, sp
call @dialog_init$qv
call @overlay_wipe$qv
mov PaletteTone, 100
call far ptr palette_show
graph_accesspage _page_front
call @dialog_box_fade_in_animate$qv
call @playfield_copy_front_to_back$qv
call @dialog_run$qv
push 2
nopcall @tiles_activate_and_render_all_fo$quc
call @dialog_exit$qv
graph_accesspage _page_back
push 1
call frame_delay
pop bp
retf
@dialog_animate$qv endp
@dialog_init$qv procdesc near
@dialog_exit$qv procdesc near
extern @dialog_animate$qv:proc
DIALOG_TEXT ends
BOSS_EXP_TEXT segment byte public 'CODE' use16

View File

@ -8,8 +8,13 @@ void near main_pat_exalice_override_and_super_clean_stage(void);
// -----------------------
#include <string.h>
#include "th02/main/execl.hpp"
#include "th04/main/dialog/shared.cpp"
#include "th04/main/demo.hpp"
#include "th04/score.h"
#include "th05/mem.h"
#include "th05/playchar.h"
#include "th05/resident.hpp"
#include "th05/formats/dialog.hpp"
#include "th05/main/dialog/dialog.hpp"
#include "th05/sprites/main_pat.h"
@ -225,3 +230,58 @@ void near dialog_run(void)
}
overlay_wipe();
}
void dialog_animate(void)
{
// If we get here during a replay, we assume it's the hidden Extra Stage
// one because it's the only one that's long enough, and then skip the
// dialog.
// You might argue that this is gross and ZUN should have just added a
// proper skip feature that would still run through the script for its side
// effects, but the only bad aspect I can see is that this happens here and
// not at the call site. In regular gameplay, the (hardcoded) boss render
// functions rely on the dialog scripts for loading their sprites at the
// intended patnums, so it would have made much more sense to hardcode all
// of these load calls and completely remove the dependency on game data.
if(resident->demo_num != 0) {
extern int8_t dialog_sequence_id;
if(dialog_sequence_id == 0) {
// Pre-boss. Replicate all asset load calls that would be done if
// `_DM06.TX2` would run normally, ...
#undef BGM_EXTRA_BOSS_FN
#undef DEMO_EXTRA_PART_2_FN
extern const char st06_bb1[];
extern const char st06_bb2[];
extern const char BGM_EXTRA_BOSS_FN[];
extern const char DEMO_EXTRA_PART_2_FN[];
main_pat_exalice_override_and_super_clean_stage();
super_entry_bfnt(st06_bb1);
super_entry_bfnt(st06_bb2);
snd_load(BGM_EXTRA_BOSS_FN, SND_LOAD_SONG);
snd_kaja_func(KAJA_SONG_PLAY, 0);
// ... then load the second half of the replay.
// ZUN bloat: This could have definitely been integrated into
// demo_load(), including the avoided reallocation.
file_ropen(DEMO_EXTRA_PART_2_FN);
file_read(DemoBuf, (DEMO_N_EXTRA * sizeof(REC<1>)));
file_close();
stage_frame = 0; // This is actually the index into [DemoBuf].
dialog_sequence_id++;
} else {
// Post-boss. Just return to the title screen.
#undef BINARY_OP
#define BINARY_OP DIALOG_BINARY_OP
extern const char BINARY_OP[];
demo_end();
}
return;
}
cdg_free(CDG_BG_PLAYCHAR_BOMB); // "dialog_init()"
dialog_pre();
dialog_run();
dialog_exit();
dialog_post();
}

View File

@ -1,3 +1,9 @@
#define BINARY_OP "op"
#define BGM_EXTRA_BOSS_FN "st06b"
#define DEMO_EXTRA_PART_2_FN "DEMO5.REC"
#define EYECATCH_FN "eye.cdg"
#define FACESET_PLAYCHAR_FORMAT "KaO0.cD2"

View File

@ -3183,69 +3183,7 @@ DIALOG_TEXT segment byte public 'CODE' use16
@dialog_load$qv procdesc near
@dialog_free$qv procdesc near
@std_update_frames_then_animate_d$qv procdesc near
@playfield_copy_front_to_back$qv procdesc near
@dialog_box_fade_in_animate$qv procdesc near
@dialog_run$qv procdesc near
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
public @dialog_animate$qv
@dialog_animate$qv proc far
push bp
mov bp, sp
les bx, _resident
cmp es:[bx+resident_t.demo_num], 0
jz short loc_F333
cmp byte_221EC, 0
jnz short loc_F318
call @main_pat_exalice_override_and_su$qv
call super_entry_bfnt pascal, ds, offset aSt06_bb1 ; "st06.bb1"
call super_entry_bfnt pascal, ds, offset aSt06_bb2 ; "st06.bb2"
call snd_load pascal, ds, offset aSt06b, SND_LOAD_SONG
kajacall KAJA_SONG_PLAY
push ds
push offset aDemo5_rec ; "DEMO5.REC"
call file_ropen
call file_read pascal, large [_DemoBuf], (DEMO_N * 4) * 2
call file_close
mov _stage_frame, 0
inc byte_221EC
pop bp
retf
; ---------------------------------------------------------------------------
loc_F318:
push word ptr _DemoBuf+2
call hmem_free
push 8
call palette_black_out
push ds
push offset aOp_0 ; "op"
nopcall @GameExecl$qnxc
pop bp
retf
; ---------------------------------------------------------------------------
loc_F333:
call cdg_free pascal, CDG_BG_PLAYCHAR_BOMB
call @overlay_wipe$qv
mov PaletteTone, 100
call far ptr palette_show
graph_accesspage _page_front
call @dialog_box_fade_in_animate$qv
call @playfield_copy_front_to_back$qv
call @dialog_run$qv
call @dialog_exit$qv
graph_accesspage _page_back
push 1
call frame_delay
pop bp
retf
@dialog_animate$qv endp
@dialog_exit$qv procdesc near
@main_pat_exalice_override_and_su$qv procdesc near
extern @dialog_animate$qv:proc
DIALOG_TEXT ends
BOSS_EXP_TEXT segment byte public 'CODE' use16
@ -19882,16 +19820,19 @@ include th04/main/frames[data].asm
public _dialog_fn
_dialog_fn dd a_dm00_tx2
include th04/main/dialog/dialog[data].asm
byte_221EC db 0
public _dialog_sequence_id
_dialog_sequence_id db 0
a_dm00_tx2 db '_DM00.TX2',0
public _dialog_kanji_buf
public _dialog_kanji_buf, _st06_bb1, _st06_bb2, _BGM_EXTRA_BOSS_FN
public _DEMO_EXTRA_PART_2_FN, _DIALOG_BINARY_OP
_dialog_kanji_buf db ' ',0
aSt06_bb1 db 'st06.bb1',0
aSt06_bb2 db 'st06.bb2',0
aSt06b db 'st06b',0
aDemo5_rec db 'DEMO5.REC',0
; char aOp_0[]
aOp_0 db 'op',0
_st06_bb1 db 'st06.bb1',0
_st06_bb2 db 'st06.bb2',0
_BGM_EXTRA_BOSS_FN db 'st06b',0
_DEMO_EXTRA_PART_2_FN db 'DEMO5.REC',0
_DIALOG_BINARY_OP db 'op',0
public _faceset_boss_format, _faceset_playchar_format
public _BOMB_BG_REIMU_FN, _BOMB_BG_MARISA_FN, _BOMB_BG_MIMA_FN
public _BOMB_BG_YUUKA_FN, _MIKO16_EXALICE_FN