[Decompilation] [th04/th05] Dialog: Script loading functions

Part of P0186, funded by [Anonymous] and Blue Bolt.
This commit is contained in:
nmlgc 2022-03-13 19:29:08 +01:00
parent b33631daf4
commit 903d824c48
9 changed files with 135 additions and 179 deletions

View File

@ -126,7 +126,7 @@ bin\th04\op.exe: bin\th04\op.obj th04\m_char.cpp bin\th01\vplanset.obj bin\th02\
$**
|
bin\th04\main.exe: bin\th04\main.obj bin\th04\slowdown.obj th04\ems.cpp th04\playfld.cpp th04\dialog.cpp bin\th04\player_p.obj bin\th04\scoreupd.obj th04\hud_ovrl.cpp bin\th04\cfg_lres.obj bin\th01\vplanset.obj bin\th03\vector2.obj bin\th02\frmdely1.obj bin\th03\hfliplut.obj th04\mpn_free.cpp bin\th04\input_w.obj th04\mpn_l_i.cpp bin\th04\vector.obj bin\th04\snd_pmdr.obj bin\th04\snd_mmdr.obj bin\th04\snd_kaja.obj bin\th04\snd_mode.obj bin\th04\snd_load.obj bin\th04\cdg_put.obj bin\th04\exit.obj bin\th04\initmain.obj bin\th04\cdg_p_na.obj bin\th04\cdg_p_pr.obj bin\th04\input_s.obj bin\th04\snd_se_r.obj bin\th04\snd_se.obj bin\th04\cdg_load.obj th04\gather.cpp bin\th04\scrolly3.obj bin\th04\motion_3.obj th04\mb_dft.cpp bin\th04\it_spl_u.obj th04\bullet_u.cpp th04\bullet_a.cpp
bin\th04\main.exe: bin\th04\main.obj bin\th04\slowdown.obj th04\ems.cpp th04\playfld.cpp th04\f_dialog.cpp th04\dialog.cpp bin\th04\player_p.obj bin\th04\scoreupd.obj th04\hud_ovrl.cpp bin\th04\cfg_lres.obj bin\th01\vplanset.obj bin\th03\vector2.obj bin\th02\frmdely1.obj bin\th03\hfliplut.obj th04\mpn_free.cpp bin\th04\input_w.obj th04\mpn_l_i.cpp bin\th04\vector.obj bin\th04\snd_pmdr.obj bin\th04\snd_mmdr.obj bin\th04\snd_kaja.obj bin\th04\snd_mode.obj bin\th04\snd_load.obj bin\th04\cdg_put.obj bin\th04\exit.obj bin\th04\initmain.obj bin\th04\cdg_p_na.obj bin\th04\cdg_p_pr.obj bin\th04\input_s.obj bin\th04\snd_se_r.obj bin\th04\snd_se.obj bin\th04\cdg_load.obj th04\gather.cpp bin\th04\scrolly3.obj bin\th04\motion_3.obj th04\mb_dft.cpp bin\th04\it_spl_u.obj th04\bullet_u.cpp th04\bullet_a.cpp
$(CC) $(CFLAGS) $(LARGE_LFLAGS) -DGAME=4 -DBINARY='M' -3 -Z -nbin\th04\ -eMAIN.EXE @&&|
$**
|
@ -149,7 +149,7 @@ bin\th05\op.exe: th05\op010.cpp bin\th05\op.obj th05\op011.cpp th05\m_char.cpp b
$**
|
bin\th05\main.exe: bin\th05\main.obj bin\th04\slowdown.obj th05\ems.cpp bin\th05\cfg_lres.obj th05\main010.cpp th05\dialog.cpp th05\playfld.cpp th05\main011.cpp th05\p_common.cpp th05\p_reimu.cpp th05\p_marisa.cpp th05\p_mima.cpp th05\p_yuuka.cpp bin\th05\player.obj bin\th05\hud_bar.obj bin\th05\scoreupd.obj th05\hud_ovrl.cpp bin\th04\player_p.obj th05\main014.cpp th05\player_a.cpp bin\th05\bullet_1.obj th05\bullet_c.cpp bin\th03\vector2.obj bin\th03\hfliplut.obj bin\th04\snd_pmdr.obj bin\th04\snd_mmdr.obj bin\th04\snd_mode.obj bin\th05\bullet.obj th05\bullet_t.cpp bin\th04\cdg_p_na.obj bin\th04\snd_se_r.obj bin\th04\snd_se.obj bin\th05\cdg_put.obj bin\th04\exit.obj bin\th05\vector.obj bin\th05\snd_load.obj bin\th05\snd_kaja.obj bin\th05\initmain.obj bin\th05\input_s.obj bin\th05\inp_h_w.obj bin\th05\frmdelay.obj bin\th04\cdg_load.obj bin\th04\scrolly3.obj bin\th04\motion_3.obj th05\gather.cpp th05\main032.cpp th05\mb_dft.cpp th05\laser_sc.cpp th05\curveb_u.cpp bin\th04\it_spl_u.obj th05\bullet_u.cpp th05\main034.cpp th05\main035.cpp th05\boss.cpp
bin\th05\main.exe: bin\th05\main.obj bin\th04\slowdown.obj th05\ems.cpp bin\th05\cfg_lres.obj th05\main010.cpp th05\f_dialog.cpp th05\dialog.cpp th05\playfld.cpp th05\main011.cpp th05\p_common.cpp th05\p_reimu.cpp th05\p_marisa.cpp th05\p_mima.cpp th05\p_yuuka.cpp bin\th05\player.obj bin\th05\hud_bar.obj bin\th05\scoreupd.obj th05\hud_ovrl.cpp bin\th04\player_p.obj th05\main014.cpp th05\player_a.cpp bin\th05\bullet_1.obj th05\bullet_c.cpp bin\th03\vector2.obj bin\th03\hfliplut.obj bin\th04\snd_pmdr.obj bin\th04\snd_mmdr.obj bin\th04\snd_mode.obj bin\th05\bullet.obj th05\bullet_t.cpp bin\th04\cdg_p_na.obj bin\th04\snd_se_r.obj bin\th04\snd_se.obj bin\th05\cdg_put.obj bin\th04\exit.obj bin\th05\vector.obj bin\th05\snd_load.obj bin\th05\snd_kaja.obj bin\th05\initmain.obj bin\th05\input_s.obj bin\th05\inp_h_w.obj bin\th05\frmdelay.obj bin\th04\cdg_load.obj bin\th04\scrolly3.obj bin\th04\motion_3.obj th05\gather.cpp th05\main032.cpp th05\mb_dft.cpp th05\laser_sc.cpp th05\curveb_u.cpp bin\th04\it_spl_u.obj th05\bullet_u.cpp th05\main034.cpp th05\main035.cpp th05\boss.cpp
$(CC) $(CFLAGS) $(LARGE_LFLAGS) -3 -Z -DGAME=5 -DBINARY='M' -nbin\th05\ -eMAIN.EXE @&&|
$**
|

1
th04/f_dialog.cpp Normal file
View File

@ -0,0 +1 @@
#include "th04/formats/dialog.cpp"

43
th04/formats/dialog.cpp Normal file
View File

@ -0,0 +1,43 @@
#pragma option -zCmain_TEXT
#include <stddef.h>
#include "platform.h"
#include "master.hpp"
#include "th04/score.h"
#include "th04/resident.hpp"
#include "th04/formats/dialog.hpp"
void pascal near dialog_load(const char *fn)
{
size_t size;
// While hmem_free() isn't specified to perform a NULL check, it does in
// practice. So while this is *technically* fine, it's not the cleanest
// solution. Fixed in TH05.
hmem_free(reinterpret_cast<void __seg *>(dialog_p));
file_ropen(fn);
size = file_size();
dialog_p = reinterpret_cast<unsigned char far *>(hmem_allocbyte(size));
file_read(dialog_p, size);
file_close();
}
void near dialog_load(void)
{
#define fn dialog_fn
extern char *fn;
dialog_fn[3] = resident->playchar_ascii;
dialog_fn[4] = resident->stage_ascii;
dialog_load(dialog_fn);
#undef fn
}
void dialog_load_yuuka5_defeat_bad(void)
{
#define fn dialog_fn_yuuka5_defeat_bad
extern char *fn;
fn[3] = resident->playchar_ascii;
dialog_load(fn);
#undef fn
}

View File

@ -1,2 +1,13 @@
// Script buffer pointer
extern unsigned char far *dialog_p;
// Loads a dialog script from the file with the given name. `near` in this
// game, as it's only used internally.
void pascal near dialog_load(const char *fn);
// Loads the dialog script after defeating Stage 5 Yuuka with continues or on
// Easy mode, shown before the Bad Ending.
void dialog_load_yuuka5_defeat_bad(void);
// Loads the dialog script for the current player character and stage.
void near dialog_load(void);

View File

@ -859,7 +859,7 @@ loc_B141:
loc_B144:
call main_01:map_load
call main_01:std_load
call main_01:sub_CED4
call @dialog_load$qv
call tiles_fill_initial
graph_accesspage 0
@ -2212,82 +2212,11 @@ loc_CE8F:
leave
retn
midboss4_render endp
main_TEXT ends
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_CE93 proc near
arg_0 = dword ptr 4
push bp
mov bp, sp
push si
push word ptr _dialog_p+2
call hmem_free
pushd [bp+arg_0]
call file_ropen
call file_size
mov si, ax
push ax
call hmem_allocbyte
mov word ptr _dialog_p+2, ax
mov word ptr _dialog_p, 0
push ax
push word ptr _dialog_p
push si
call file_read
call file_close
pop si
pop bp
retn 4
sub_CE93 endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_CED4 proc near
push bp
mov bp, sp
les bx, _resident
assume es:nothing
mov al, es:[bx+resident_t.playchar_ascii]
les bx, off_22BAA
mov es:[bx+3], al
les bx, _resident
mov al, es:[bx+resident_t.stage_ascii]
les bx, off_22BAA
mov es:[bx+4], al
push word ptr off_22BAA+2
push bx
call main_01:sub_CE93
pop bp
retn
sub_CED4 endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_CF01 proc far
push bp
mov bp, sp
les bx, _resident
mov al, es:[bx+resident_t.playchar_ascii]
les bx, off_22BAE
mov es:[bx+3], al
push word ptr off_22BAE+2
push bx
call main_01:sub_CE93
pop bp
retf
sub_CF01 endp
DIALOG_TEXT segment byte public 'CODE' use16
@dialog_load$qv procdesc near
extern @dialog_load_yuuka5_defeat_bad$qv:proc
; =============== S U B R O U T I N E =======================================
@ -3170,9 +3099,7 @@ public @dialog_animate$qv
pop bp
retf
@dialog_animate$qv endp
main_TEXT ends
DIALOG_TEXT segment byte public 'CODE' use16
@dialog_init$qv procdesc near
@dialog_exit$qv procdesc near
DIALOG_TEXT ends
@ -28452,7 +28379,7 @@ loc_1E7B5:
jnz short loc_1E801
loc_1E7F2:
call sub_CF01
call @dialog_load_yuuka5_defeat_bad$qv
call @dialog_animate$qv
call @end_game_bad$qv
@ -32105,10 +32032,9 @@ include th04/main/playfld[data].asm
byte_22B9E db 1
db 0
include th04/main/frames[data].asm
off_22BAA dd a_dm00_txt
; "_DM00.TXT"
off_22BAE dd a_dm04b_txt
; "_DM04B.txt"
public _dialog_fn, _dialog_fn_yuuka5_defeat_bad
_dialog_fn dd a_dm00_txt
_dialog_fn_yuuka5_defeat_bad dd a_dm04b_txt
include th04/main/dialog/dialog[data].asm
public _number_of_calls_to_this_function
_number_of_calls_to_this_function db 0

1
th05/f_dialog.cpp Normal file
View File

@ -0,0 +1 @@
#include "th05/formats/dialog.cpp"

41
th05/formats/dialog.cpp Normal file
View File

@ -0,0 +1,41 @@
#pragma option -zCmain_TEXT
#include <stddef.h>
#include "platform.h"
#include "master.hpp"
#include "th04/common.h"
#include "th04/score.h"
#include "th04/main/stage/stage.hpp"
#include "th05/playchar.h"
#include "th05/resident.hpp"
#include "th05/formats/dialog.hpp"
void pascal dialog_load(const char *fn)
{
size_t size;
tx2_header_t header;
if(dialog_p) {
hmem_free(reinterpret_cast<void __seg *>(dialog_p));
}
file_ropen(fn);
file_read(&header, sizeof(header));
// A sanity check here would have been particularly helpful for
// translators, who tend to start out by just blindly editing a .TX2 file.
size = (header.offset_for[playchar + 1] - header.offset_for[playchar]);
dialog_p = reinterpret_cast<unsigned char far *>(hmem_allocbyte(size));
file_seek(header.offset_for[playchar], SEEK_SET);
file_read(dialog_p, size);
file_close();
}
void near dialog_load(void)
{
#define fn dialog_fn
extern char *fn;
fn[4] = ('0' + stage_id);
dialog_load(fn);
#undef fn
}

View File

@ -1,8 +1,26 @@
/// TH05 in-game dialog script format
/// ---------------------------------
struct tx2_header_t {
// The dialog script for player character N is stored between
// `offset_for[N]` and `offset_for[N + 1]`.
uint16_t offset_for[PLAYCHAR_COUNT + 1];
};
const uint8_t FACE_NONE = 0xFF;
// Script buffer pointer
extern unsigned char far *dialog_p;
// Loading and freeing
// -------------------
// Loads the dialog script for the current player character from the .TX2 file
// with the given name. `far` in this game, as it's also called from outside
// its segment.
void pascal dialog_load(const char *fn);
// Loads the dialog script for the current player character and stage.
void near dialog_load(void);
// -------------------
/// ---------------------------------

View File

@ -978,7 +978,7 @@ loc_B4A6:
loc_B4A9:
call map_load
call std_load
call sub_EE17
call @dialog_load$qv
call tiles_fill_initial
graph_accesspage 0
@ -3703,90 +3703,11 @@ sub_EACE endp
include th04/main/enemy/render.asm
include th04/main/circle.asm
main_TEXT ends
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_ED87 proc far
var_A = byte ptr -0Ah
var_8 = byte ptr -8
arg_0 = dword ptr 6
enter 0Ah, 0
push si
cmp _dialog_p, 0
jz short loc_ED9D
push word ptr _dialog_p+2
call hmem_free
loc_ED9D:
pushd [bp+arg_0]
call file_ropen
push ss
lea ax, [bp+var_A]
push ax
push 0Ah
call file_read
mov al, _playchar
mov ah, 0
add ax, ax
lea dx, [bp+var_8]
add ax, dx
mov bx, ax
mov ax, ss:[bx]
mov dl, _playchar
mov dh, 0
add dx, dx
lea bx, [bp+var_A]
add dx, bx
mov bx, dx
sub ax, ss:[bx]
mov si, ax
push ax
call hmem_allocbyte
mov word ptr _dialog_p+2, ax
mov word ptr _dialog_p, 0
mov al, _playchar
mov ah, 0
add ax, ax
lea dx, [bp+var_A]
add ax, dx
mov bx, ax
movzx eax, word ptr ss:[bx]
push eax
push 0
call file_seek
pushd [_dialog_p]
push si
call file_read
call file_close
pop si
leave
retf 4
sub_ED87 endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_EE17 proc near
push bp
mov bp, sp
les bx, off_221D0
assume es:nothing
mov al, _stage_id
add al, 30h ; '0'
mov es:[bx+4], al
push word ptr off_221D0+2
push bx
call sub_ED87
pop bp
retn
sub_EE17 endp
DIALOG_TEXT segment byte public 'CODE' use16
extern @DIALOG_LOAD$QNXC:proc
@dialog_load$qv procdesc near
; =============== S U B R O U T I N E =======================================
@ -4313,9 +4234,7 @@ loc_F333:
pop bp
retf
@dialog_animate$qv endp
main_TEXT ends
DIALOG_TEXT segment byte public 'CODE' use16
@DIALOG_FACE_LOAD_UNPUT_PUT_FREE_$QIII procdesc pascal near \
left:word, top:word, cel:word
@dialog_exit$qv procdesc near
@ -16075,9 +15994,7 @@ loc_1AF24:
jnz short loc_1AFA7 ; default
cmp _boss2_mode_change, 0
jnz short loc_1AF66
push ds
push offset a_dm09_tx2 ; "_DM09.TX2"
call sub_ED87
call @dialog_load$qnxc pascal, ds, offset a_dm09_tx2 ; "_DM09.TX2"
mov word ptr _boss_bgm_title+2, ds
mov word ptr _boss_bgm_title, offset aTH05_10
mov eax, _yuki_pos.cur
@ -16087,9 +16004,7 @@ loc_1AF24:
; ---------------------------------------------------------------------------
loc_1AF66:
push ds
push offset a_dm08_tx2 ; "_DM08.TX2"
call sub_ED87
call @dialog_load$qnxc pascal, ds, offset a_dm08_tx2 ; "_DM08.TX2"
mov word ptr _boss_bgm_title+2, ds
mov word ptr _boss_bgm_title, offset aTH05_11
setfarfp _boss_update, sub_1C518
@ -23869,8 +23784,8 @@ _group_is_special db 0
_enemies_gone dw 0
_enemies_killed dw 0
include th04/main/frames[data].asm
off_221D0 dd a_dm00_tx2
; "_DM00.TX2"
public _dialog_fn
_dialog_fn dd a_dm00_tx2
include th04/main/dialog/dialog[data].asm
byte_221EC db 0
a_dm00_tx2 db '_DM00.TX2',0