diff --git a/Makefile.mak b/Makefile.mak index 2fd374e6..e001e2ec 100644 --- a/Makefile.mak +++ b/Makefile.mak @@ -152,17 +152,17 @@ bin\th05\res_kso.com: th05\res_kso.cpp $** | masters.lib -bin\th05\op.exe: th05\op010.cpp bin\th05\op.obj th05\op011.cpp th05\m_char.cpp bin\th05\snd_kaja.obj bin\th05\pi_cpp_1.obj bin\th05\pi_asm_1.obj bin\th05\pi_cpp_2.obj bin\th05\pi_asm_2.obj bin\th05\initop.obj bin\th05\input_s.obj bin\th05\inp_h_w.obj bin\th05\snd_dlym.obj th05\cdg_p_nc.cpp bin\th05\frmdelay.obj bin\th04\cdg_load.obj bin\th05\egcrect.obj bin\hfliplut.obj +bin\th05\op.exe: th05\op010.cpp bin\th05\op.obj th05\op011.cpp th05\m_char.cpp bin\th05\snd_load.obj bin\th05\snd_kaja.obj bin\th05\pi_cpp_1.obj bin\th05\pi_asm_1.obj bin\th05\pi_cpp_2.obj bin\th05\pi_asm_2.obj bin\th05\initop.obj bin\th05\input_s.obj bin\th05\inp_h_w.obj bin\th05\snd_dlym.obj th05\cdg_p_nc.cpp bin\th05\frmdelay.obj bin\th04\cdg_load.obj bin\th05\egcrect.obj bin\hfliplut.obj $(CC) $(CFLAGS) $(LARGE_LFLAGS) -DGAME=5 -DBINARY='O' -3 -Z -nbin\th05\ -eOP.EXE @&&| $** | -bin\th05\main.exe: bin\th05\main.obj th05\main010.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\main012.cpp th05\main013.cpp bin\hfliplut.obj bin\th05\bullet.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 th05\main031.cpp th05\main032.cpp th05\main033.cpp th05\main034.cpp +bin\th05\main.exe: bin\th05\main.obj th05\main010.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\main012.cpp th05\main013.cpp bin\hfliplut.obj bin\th05\bullet.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 th05\main031.cpp th05\main032.cpp th05\main033.cpp th05\main034.cpp $(CC) $(CFLAGS) $(LARGE_LFLAGS) -3 -Z -DGAME=5 -DBINARY='M' -nbin\th05\ -eMAIN.EXE @&&| $** | -bin\th05\maine.exe: bin\th05\maine.obj th05\maine011.cpp th05\regist.cpp th05\staff.cpp bin\th05\snd_kaja.obj bin\th05\pi_cpp_1.obj bin\th05\pi_asm_1.obj bin\th05\pi_cpp_2.obj bin\th05\pi_asm_2.obj bin\th05\initmain.obj bin\th05\input_s.obj bin\th05\inp_h_w.obj bin\th05\snd_dlym.obj bin\th05\frmdelay.obj bin\th04\cdg_load.obj bin\th05\egcrect.obj bin\hfliplut.obj +bin\th05\maine.exe: bin\th05\maine.obj th05\maine011.cpp th05\regist.cpp th05\staff.cpp bin\th05\snd_load.obj bin\th05\snd_kaja.obj bin\th05\pi_cpp_1.obj bin\th05\pi_asm_1.obj bin\th05\pi_cpp_2.obj bin\th05\pi_asm_2.obj bin\th05\initmain.obj bin\th05\input_s.obj bin\th05\inp_h_w.obj bin\th05\snd_dlym.obj bin\th05\frmdelay.obj bin\th04\cdg_load.obj bin\th05\egcrect.obj bin\hfliplut.obj $(CC) $(CFLAGS) $(LARGE_LFLAGS) -DGAME=5 -DBINARY='E' -Z -nbin\th05\ -eMAINE.EXE @&&| $** | diff --git a/master.hpp b/master.hpp index 81fb15dd..ae656a0a 100644 --- a/master.hpp +++ b/master.hpp @@ -77,6 +77,7 @@ extern "C" { int MASTER_RET bgm_init(int bufsiz); void MASTER_RET bgm_finish(void); +int MASTER_RET bgm_read_sdata(const char MASTER_PTR *fn); int MASTER_RET bgm_sound(int num); // ---------------------------------------- diff --git a/th02/snd/load.c b/th02/snd/load.c index 0813328d..025ab60c 100644 --- a/th02/snd/load.c +++ b/th02/snd/load.c @@ -5,7 +5,7 @@ #include "libs/kaja/kaja.h" #include "th02/snd/snd.h" -extern char snd_load_fn[13]; +extern char snd_load_fn[SND_FN_LEN]; void snd_load(const char *fn, kaja_func_t func) { diff --git a/th02/snd/load[bss].asm b/th02/snd/load[bss].asm index 526b1cec..2ff65aa1 100644 --- a/th02/snd/load[bss].asm +++ b/th02/snd/load[bss].asm @@ -1,4 +1,3 @@ -; Shorter symbols for the [func] parameter of snd_load() SND_LOAD_SONG equ (KAJA_GET_SONG_ADDRESS shl 8) SND_LOAD_SE equ (PMD_GET_SE_ADDRESS shl 8) diff --git a/th02/snd/snd.h b/th02/snd/snd.h index 4410569f..8fb5a741 100644 --- a/th02/snd/snd.h +++ b/th02/snd/snd.h @@ -49,15 +49,18 @@ void snd_delay_until_volume(uint8_t volume); void snd_delay_until_measure(int measure); #endif +// Shorter symbols for the [func] parameter of snd_load() #define SND_LOAD_SONG (kaja_func_t)(KAJA_GET_SONG_ADDRESS << 8) #define SND_LOAD_SE (kaja_func_t)(PMD_GET_SE_ADDRESS << 8) +#define SND_FN_LEN 13 + #if defined(PMD) && (GAME <= 3) /* requires kaja.h */ // Loads a song in .M format ([func] = SND_LOAD_SONG) or a sound effect // bank in EFC format ([func] = SND_LOAD_SE) into the respective work // buffer of the sound driver. If MIDI is used, 'md' is appended to the // file name. - void DEFCONV snd_load(const char *fn, kaja_func_t func); + void DEFCONV snd_load(const char fn[SND_FN_LEN], kaja_func_t func); #endif void snd_se_reset(void); diff --git a/th04/snd/load.asm b/th04/snd/load.asm index c79f71be..ab9871ec 100644 --- a/th04/snd/load.asm +++ b/th04/snd/load.asm @@ -1,14 +1,3 @@ -; Loads a song ([func] = SND_LOAD_SONG) or a sound effect bank ([func] = -; SND_LOAD_SE) into the respective work buffer of the sound driver. [fn] must -; not have any extension. Depending on snd_bgm_mode and snd_se_mode, the -; following file is loaded: -; • '[fn].m26' if SND_BGM_FM26 -; • '[fn].m86' if SND_BGM_FM86 -; • '[fn].mmd' if SND_BGM_MIDI -; • '[fn].efc' if SND_SE_FM -; • '[fn].efs' if SND_SE_BEEP (using master.lib's BGM driver) - -; void __stdcall snd_load(int func, const char *fn) snd_load proc arg @@func:word, @@fn:ptr diff --git a/th04/snd/snd.h b/th04/snd/snd.h index c1cd1cd8..2f19b32b 100644 --- a/th04/snd/snd.h +++ b/th04/snd/snd.h @@ -30,3 +30,25 @@ static inline bool snd_is_active() { // Checks the requested BGM and SE modes against the available hardware and // sets [snd_se_mode] and [snd_bgm_mode] accordingly. Returns [snd_bgm_mode]. unsigned char pascal snd_determine_modes(int req_bgm_mode, int req_se_mode); + +// Loads a song ([func] = SND_LOAD_SONG) or a sound effect bank ([func] = +// SND_LOAD_SE) into the respective work buffer of the sound driver. [fn] must +// not have any extension. Depending on [snd_bgm_mode], [snd_se_mode], and +// game, the following file is loaded: +// +// | | TH04 | TH05 | +// |----------------+------------+-----------| +// | [snd_bgm_mode] | [func] = SND_LOAD_SONG | +// |----------------+------------+-----------| +// | SND_BGM_FM26 | [fn].m26 | [fn].m | +// | SND_BGM_FM86 | [fn].m86 | [fn].m2 | +// | SND_BGM_MIDI | [fn].mmd | [fn].md | (yes, see TH05's load[data].asm) +// |----------------+------------+-----------| +// | [snd_se_mode] | [func] = SND_LOAD_SE | +// |----------------+------------+-----------| +// | SND_SE_FM | [fn].efc | [fn].efc | +// | SND_SE_BEEP | [fn].efs | [fn].efs | (using master.lib's BGM driver) +// +// Note that the TH05 version will infinitely loop if neither the file for the +// current [snd_bgm_mode] nor "[fn].m" exist. +void pascal snd_load(const char fn[SND_FN_LEN], int16_t func); diff --git a/th05/snd/load.asm b/th05/snd/load.asm deleted file mode 100644 index 9adefe4f..00000000 --- a/th05/snd/load.asm +++ /dev/null @@ -1,97 +0,0 @@ -; Loads a song ([func] = SND_LOAD_SONG) or a sound effect bank ([func] = -; SND_LOAD_SE) into the respective work buffer of the sound driver. [fn] must -; not have any extension. Depending on snd_bgm_mode and snd_se_mode, the -; following file is loaded: -; • '[fn].m' if SND_BGM_FM26 -; • '[fn].m2' if SND_BGM_FM86 -; • '[fn].md' if SND_BGM_MIDI (yes, see this game's snd_load[data].asm) -; • '[fn].efc' if SND_SE_FM -; • '[fn].efs' if SND_SE_BEEP (using master.lib's BGM driver) -; Note that the TH05 version will infinitely loop if neither the file for the -; current snd_bgm_mode nor '[fn].m' exist. - -; void __stdcall snd_load(int func, const char *fn) -snd_load proc - arg @@func:word, @@fn:far ptr - - push bp - mov bp, sp - push si - push di - mov dx, ds - mov es, dx - mov di, offset _snd_load_fn - lds si, @@fn - mov bp, @@func - mov cx, SND_LOAD_FN_LEN - rep movsb - mov ds, dx - mov di, offset _snd_load_fn - dec cx - xor ax, ax - repne scasb - dec di - mov byte ptr [di], '.' - inc di - cmp bp, SND_LOAD_SE - jnz short @@song - cmp _snd_se_mode, SND_SE_OFF - jz short @@ret - xor bx, bx - cmp _snd_se_mode, SND_SE_BEEP - jnz short @@set_ext - mov dword ptr [di], 'sfe' - call bgm_finish - call bgm_init pascal, 2048 - call bgm_read_sdata pascal, ds, offset _snd_load_fn - jmp short @@ret - -@@song: - cmp _snd_bgm_mode, SND_BGM_OFF - jz short @@ret - kajacall KAJA_SONG_STOP - movzx bx, _snd_bgm_mode - shl bx, 2 - -@@set_ext: - mov eax, dword ptr aSND_LOAD_EXT[bx] - -@@open: - mov [di], eax - mov dx, offset _snd_load_fn - mov ax, 3D00h - int 21h - jnb short @@which_driver? - cmp ax, 2 ; ENOFILE, from - jnz short @@ret - mov eax, dword ptr aSND_LOAD_EXT_FM26 - jmp short @@open - -@@which_driver?: - mov bx, ax - mov ax, bp - cmp ah, KAJA_GET_SONG_ADDRESS - jnz short @@PMD - cmp _snd_bgm_mode, SND_BGM_MIDI - jnz short @@PMD - int 61h - jmp short @@read - -@@PMD: - int 60h - -@@read: - mov ax, 3F00h - mov cx, 0FFFFh - int 21h - mov ah, 3Eh - int 21h - push es - pop ds - -@@ret: - pop di - pop si - pop bp - ret 6 -snd_load endp diff --git a/th05/snd/load.cpp b/th05/snd/load.cpp new file mode 100644 index 00000000..1f4f57a4 --- /dev/null +++ b/th05/snd/load.cpp @@ -0,0 +1,121 @@ +#pragma codeseg SHARED_ +#pragma option -3 + +extern "C" { +#include +#include "platform.h" +#include "x86real.h" +#include "decomp.h" +#include "master.hpp" +#include "libs/kaja/kaja.h" +#include "th05/snd/snd.h" + +extern char snd_load_fn[SND_FN_LEN]; +extern const char SND_LOAD_EXT[4][4]; + +void pascal snd_load(const char fn[SND_FN_LEN], int16_t func) +{ + #define _DI reinterpret_cast(_DI) + #define func_local _BP + #define ext _EAX + + __asm { mov dx, ds; } + + // memcpy(snd_load_fn, fn, sizeof(SND_LOAD_FN)); + _ES = _DX; + _DI = snd_load_fn; + __asm { lds si, fn; } + func_local = func; + _CX = sizeof(snd_load_fn); + __asm { rep movsb; } + + // _DI = strchr(str, '\0'); + _DS = _DX; + _DI = snd_load_fn; + _CX--; // = -1 + _AX = '\0'; + __asm { repne scasb; } + + _DI--; + *(_DI) = '.'; + _DI++; + if(func_local == SND_LOAD_SE) { + // Only not decompilable because the jump distance happens to exactly + // be 127 bytes, for which Turbo C++ doesn't emit short jumps anymore. + __asm { + cmp snd_se_mode, SND_SE_OFF; + jz short ret; + } + _BX = 0; + if(snd_se_mode == SND_SE_BEEP) { + *reinterpret_cast(_DI) = 0x00736665; // "efs\0" + bgm_finish(); + bgm_init(2048); + bgm_read_sdata(snd_load_fn); + return; + } + } else { + if(snd_bgm_mode == SND_BGM_OFF) { + return; + } + /* TODO: Replace with the decompiled expressions + * snd_kaja_func(KAJA_SONG_STOP, 0); + * _BX = (snd_bgm_mode << 2); + * Since snd_kaja_interrupt() is undecompilable, this can never work + * with the original translation unit structure. */ + __asm { + push (KAJA_SONG_STOP shl 8); + push cs; + call near ptr snd_kaja_interrupt; + db 0x0F, 0xB6, 0x1E; // MOVZX BX, + dw offset snd_bgm_mode; // snd_bgm_mode + shl bx, 2 + } + } + ext = *reinterpret_cast(&SND_LOAD_EXT[0][_BX]); + + // ZUN bug: Infinite loop if neither the file for the current + // [snd_bgm_mode] nor "[fn].m" exist. + while(1) { + *reinterpret_cast(_DI) = ext; + + // DOS file open + reinterpret_cast(_DX) = snd_load_fn; + _AX = 0x3D00; + geninterrupt(0x21); + if(!FLAGS_CARRY) { + break; + } + if(_AX != ENOFILE) { + return; + } + ext = *reinterpret_cast(SND_LOAD_EXT[SND_BGM_FM26]); + } + + _BX = _AX; // Unnecessary, just remove this line + _AX = func_local; + if((_AH == KAJA_GET_SONG_ADDRESS) && (snd_bgm_mode == SND_BGM_MIDI)) { + geninterrupt(MMD); + } else { + geninterrupt(PMD); + } + + // DOS file read; song data address is in DS:DX + _AX = 0x3F00; + _CX = 0xFFFF; + geninterrupt(0x21); + + // DOS file close + _AH = 0x3E; + geninterrupt(0x21); + + __asm { push es; } + __asm { pop ds; } + +ret: + #undef func_local + #undef ext + #undef _DI +} + +} diff --git a/th05/snd/load[data].asm b/th05/snd/load[data].asm index 2135df65..49e7eae9 100644 --- a/th05/snd/load[data].asm +++ b/th05/snd/load[data].asm @@ -1,4 +1,6 @@ -aSND_LOAD_EXT db 'efc',0 -aSND_LOAD_EXT_FM26 db 'm',0,0,0 -aSND_LOAD_EXT_FM86 db 'm2',0,'m' ; Yes, that's how it's addressed. -aSND_LOAD_EXT_MIDI db 'md',0 +public _SND_LOAD_EXT +_SND_LOAD_EXT label dword + db 'efc',0 + db 'm',0,0,0 + db 'm2',0,'m' ; Yes, that's how it's addressed. + db 'md',0 diff --git a/th05/snd_load.cpp b/th05/snd_load.cpp new file mode 100644 index 00000000..91d469a2 --- /dev/null +++ b/th05/snd_load.cpp @@ -0,0 +1 @@ +#include "th05/snd/load.cpp" diff --git a/th05_main.asm b/th05_main.asm index 119c2c98..2513aa05 100644 --- a/th05_main.asm +++ b/th05_main.asm @@ -10561,7 +10561,7 @@ include th04/formats/cdg_put.asm include th02/exit.asm include th04/math/vector1_at.asm include th04/math/vector2_at.asm -include th05/snd/load.asm + extern SND_LOAD:proc extern SND_KAJA_INTERRUPT:proc extern GAME_INIT_MAIN:proc extern _input_reset_sense:proc diff --git a/th05_maine.asm b/th05_maine.asm index a4708218..45bfa98c 100644 --- a/th05_maine.asm +++ b/th05_maine.asm @@ -7536,7 +7536,7 @@ include th02/exit.asm include th04/math/vector1_at.asm include th04/math/vector2_at.asm include th04/bgimage_put_rect.asm -include th05/snd/load.asm + extern SND_LOAD:proc extern SND_KAJA_INTERRUPT:proc extern PI_PUT_QUARTER_MASKED_8:proc extern PI_LOAD:proc diff --git a/th05_op.asm b/th05_op.asm index d3e832ad..338b4659 100644 --- a/th05_op.asm +++ b/th05_op.asm @@ -2541,7 +2541,7 @@ include th05/music/piano.asm GRCG_SETCOLOR_DIRECT_DEF 1 db 0 include th04/bgimage_put_rect.asm -include th05/snd/load.asm + extern SND_LOAD:proc extern SND_KAJA_INTERRUPT:proc extern PI_PUT_MASKED_8:proc extern PI_LOAD:proc