[Decompilation] [th03/th04/th05] Music Room: Main function

Part of P0265, funded by [Anonymous] and iruleatgames.
This commit is contained in:
nmlgc 2024-01-13 23:49:25 +01:00
parent 78728f6780
commit b7c8f13d19
15 changed files with 469 additions and 797 deletions

View File

@ -5,30 +5,55 @@
#include "planar.h"
#include "shiftjis.hpp"
#include "master.hpp"
#include "libs/kaja/kaja.h"
#include "game/coords.hpp"
#include "th02/v_colors.hpp"
#include "th02/hardware/frmdelay.h"
#include "th02/formats/musiccmt.hpp"
#if (GAME >= 3)
#include "th03/math/polar.hpp"
#else
#include "th01/math/polar.hpp"
#endif
extern "C" {
#if (GAME >= 4)
#include "th04/hardware/bgimage.hpp"
#include "th04/hardware/grppsafx.h"
#if (GAME == 5)
#include "th05/hardware/input.h"
#else
#include "th04/hardware/input.h"
#endif
#include "th04/snd/snd.h"
#else
#include "th01/hardware/grppsafx.h"
#if (GAME == 3)
#include "th03/hardware/input.h"
#else
#include "th02/hardware/input.hpp"
#endif
#include "th02/snd/snd.h"
#endif
}
#if (GAME >= 3)
extern "C" {
#include "th03/formats/cdg.h"
}
#include "th03/math/polar.hpp"
#else
#include "th01/math/polar.hpp"
#endif
#include "th02/op/m_music.hpp"
#if (GAME == 5)
#include "th01/math/clamp.hpp"
extern "C" {
#include "th05/formats/pi.hpp"
}
#include "th05/op/piano.hpp"
#include "th05/shiftjis/fns.hpp"
#include "th05/shiftjis/music.hpp"
int game_sel = (GAME_COUNT - 1);
extern const int TRACK_COUNT[GAME_COUNT] = { 14, 18, 24, 28, 23 };
const int TRACK_COUNT[GAME_COUNT] = { 14, 18, 24, 28, 23 };
#else
extern "C" {
#include "th02/formats/pi.h"
}
#if (GAME == 4)
#include "th04/shiftjis/music.hpp"
#elif (GAME == 3)
@ -36,6 +61,9 @@ extern "C" {
#elif (GAME == 2)
#include "th02/shiftjis/music.hpp"
#endif
static const size_t TRACK_COUNT = (
sizeof(MUSIC_FILES) / sizeof(MUSIC_FILES[0])
);
#endif
// Colors
@ -464,11 +492,9 @@ void pascal near cmt_load(int track)
FN[6] = ('0' + game_sel);
file_ropen(FN);
#elif (GAME == 4)
file_ropen("_MUSIC.TXT\0music.pi");
#elif (GAME == 3)
file_ropen(reinterpret_cast<const char *>(MK_FP(_DS, 0x09D1)));
#elif (GAME == 2)
file_ropen(reinterpret_cast<const char *>(MK_FP(_DS, 0x0C13)));
file_ropen("_MUSIC.TXT");
#else
file_ropen("MUSIC.TXT");
#endif
file_seek((track * int(sizeof(cmt))), SEEK_SET);
file_read(cmt, sizeof(cmt));
@ -590,6 +616,10 @@ void pascal near cmt_load(int track)
music_flip();
cmt_put();
}
// ZUN bloat: Redundant; this is the first thing done in music_flip(),
// which runs almost immediately after this function on every code
// path.
nopoly_B_put();
}
#else
@ -627,3 +657,408 @@ void pascal near cmt_load(int track)
}
}
#endif
// Input wrappers
// --------------
// The Music Room is the only piece of UI that is more or less the same across
// 4 of the 5 games. Therefore, it makes sense to define these here rather than
// adding more complexity to the headers.
#if (GAME == 3)
#define key_det input_sp
#endif
// Same game-specific branches as in the TH03/TH04/TH05 cutscene system, but
// with a different, much smaller effect here.
//
// ZUN quirk: After processing an input, the Music Room loop wants to prevent
// held keys from having any effect by spinning in a different loop until all
// keys have been released. However, due to the different sensing functions,
// the actual handling of held keys differs depending on the game:
//
// • TH02 and TH04 use raw input sensing functions that don't address the
// hardware quirk documented in the `Research/HOLDKEY` example. Therefore,
// the eventual key release scancode for a held key is not filtered and gets
// through to [key_det], breaking the spinning loop despite the key still
// being held.
// • In TH03 and TH05, this eventual key release scancode is accurately
// detected and filtered. Thus, held keys truly don't have any effect, but at
// the cost of an additional 614.4 µs for every call to this function.
inline void music_input_sense(void) {
#if (GAME == 5)
input_reset_sense_held();
#elif (GAME == 4)
input_reset_sense();
#elif (GAME == 3)
input_mode_interface();
#else
input_sense();
#endif
}
// --------------
#define wait_for_key_release_animate() { \
while(1) { \
music_input_sense(); \
if(key_det) { \
music_flip(); \
} else { \
break; \
} \
} \
}
#if (GAME == 5)
void pascal near tracklist_unput_and_put_both_animate(int sel)
{
bgimage_put_rect_16(0, LABEL_GAME_TOP, CMT_TITLE_LEFT, GLYPH_H);
bgimage_put_rect_16(0, TRACKLIST_TOP, CMT_TITLE_LEFT, TRACKLIST_H);
tracklist_put(sel);
music_flip();
bgimage_put_rect_16(0, LABEL_GAME_TOP, CMT_TITLE_LEFT, GLYPH_H);
bgimage_put_rect_16(0, TRACKLIST_TOP, CMT_TITLE_LEFT, TRACKLIST_H);
tracklist_put(sel);
}
inline void track_unput_and_put_both_animate(
const uint8_t& sel_prev, const uint8_t& sel_new
) {
track_unput_or_put(sel_prev, false);
track_unput_or_put(sel_new, true);
music_flip();
track_unput_or_put(sel_prev, false);
track_unput_or_put(sel_new, true);
}
inline void game_switch(void) {
music_sel = 0;
track_playing = 0;
track_id_at_top = 0;
track_count_cur = TRACK_COUNT[game_sel];
tracklist_unput_and_put_both_animate(0);
snd_kaja_func(KAJA_SONG_FADE, 32);
cmt_load_unput_and_put_both_animate(0);
snd_load(MUSIC_FILES[game_sel][0], SND_LOAD_SONG);
snd_kaja_func(KAJA_SONG_PLAY, 0);
}
#endif
void MUSICROOM_DISTANCE musicroom_menu(void)
{
#if (GAME == 5)
int frames_since_last_input = 0;
uint8_t sel_prev;
track_id_at_top = 0;
track_playing = 0;
music_sel = 0;
track_count_cur = TRACK_COUNT[game_sel];
#define SEL_QUIT track_count_cur
#else
enum {
SEL_QUIT = (TRACK_COUNT + 1),
};
#endif
#if (GAME >= 4)
cmt_shown_initial = false;
#endif
// ZUN bloat: The call site would have been a better place for this.
#if (GAME >= 4)
cdg_free_all();
text_clear();
#elif (GAME == 3)
for(int i = 0; i < CDG_SLOT_COUNT; i++) {
cdg_free(i);
}
super_free();
text_clear();
#endif
music_page = 1;
palette_black();
graph_showpage(0);
// ZUN bloat: We copy page 1 to page 0 below anyway. The hardware palette
// is also entirely black, so no one will ever see a difference.
graph_accesspage(0);
graph_clear();
graph_accesspage(1);
#if (GAME >= 4)
pi_load_put_8_free(0, "music.pi");
#else
pi_load_put_8_free(0, "op3.pi");
#endif
#if (GAME == 5)
piano_setup_and_put_initial();
nopoly_B_snap();
bgimage_snap();
#else
music_sel = track_playing;
#endif
tracklist_put(music_sel);
graph_copy_page(0);
#if (GAME == 4)
bgimage_snap();
#endif
graph_accesspage(1);
graph_showpage(0);
#if (GAME == 5)
pfend();
pfstart("music.dat");
cmt_load_unput_and_put_both_animate(music_sel);
#else
nopoly_B_snap();
#if (GAME >= 4)
cmt_load_unput_and_put_both_animate(track_playing);
#else
cmt_bg_snap();
graph_accesspage(1); cmt_load_unput_and_put(track_playing);
graph_accesspage(0); cmt_load_unput_and_put(track_playing);
#endif
#endif
palette_100();
while(1) {
#if (GAME == 5)
// This loop also ignores any ← or → inputs while ↑ or ↓ are held,
// and vice versa.
while(1) {
music_input_sense();
if(!key_det) {
break;
}
if(frames_since_last_input >= 24) {
if((key_det == INPUT_UP) || (key_det == INPUT_DOWN)) {
frames_since_last_input = 20;
break;
}
}
frames_since_last_input++;
music_flip();
}
#else
// ZUN bloat: None of this `goto` business would have been
// necessary if the loop clearly defined its update and render
// steps. Especially since it does want to render the polygon
// animation every frame.
wait_for_key_release_animate();
#endif
controls:
// ZUN bloat: We already did that for this frame if we came from above,
// but not if we came from the `goto` below.
music_input_sense();
#if (GAME == 5)
if(key_det & INPUT_UP) {
sel_prev = music_sel;
if(music_sel > 0) {
music_sel--;
if(music_sel < track_id_at_top) {
track_id_at_top = music_sel;
tracklist_unput_and_put_both_animate(music_sel);
// ZUN quirk: This prevents game switches via ← or → ,
// but only in the very specific case of
// 1) the cursor being at the top of the list,
// 2) highlighting a track other than the first one of
// the respective game, and
// 3) ←/→ being pressed simultaneously with ↑.
// In any other case, ←/→ are processed as expected,
// and override this cursor movement with a game
// switch.
goto skip_processing_of_left_and_right;
} else {
track_unput_and_put_both_animate(sel_prev, music_sel);
}
} else {
music_sel = SEL_QUIT;
track_id_at_top = (
SEL_QUIT - (TRACKLIST_VISIBLE_COUNT - 1)
);
tracklist_unput_and_put_both_animate(SEL_QUIT);
}
}
if(key_det & INPUT_DOWN) {
sel_prev = music_sel;
if(music_sel < SEL_QUIT) {
music_sel++;
if(
music_sel >=
(track_id_at_top + TRACKLIST_VISIBLE_COUNT)
) {
track_id_at_top = (
music_sel - (TRACKLIST_VISIBLE_COUNT - 1)
);
tracklist_unput_and_put_both_animate(music_sel);
// Same as the quirk above, applying to the
// corresponding very specific case of
// 1) the cursor being at the bottom of the list,
// 2) highlighting anything except [SEL_QUIT], and
// 3) ←/→ being pressed simultaneously with ↓.
goto skip_processing_of_left_and_right;
} else {
track_unput_and_put_both_animate(sel_prev, music_sel);
}
} else {
music_sel = 0;
track_id_at_top = 0;
tracklist_unput_and_put_both_animate(music_sel);
}
}
if(key_det & INPUT_LEFT) {
ring_dec(game_sel, (GAME_COUNT - 1));
game_switch();
} else if(key_det & INPUT_RIGHT) {
ring_inc_ge(game_sel, GAME_COUNT);
game_switch();
}
#else
if(key_det & INPUT_UP) {
track_put(music_sel, COL_TRACKLIST);
if(music_sel > 0) {
music_sel--;
} else {
music_sel = SEL_QUIT;
}
// Skip over the empty line
if(music_sel == TRACK_COUNT) {
music_sel--;
}
track_put(music_sel, COL_TRACKLIST_SELECTED);
}
if(key_det & INPUT_DOWN) {
track_put(music_sel, COL_TRACKLIST);
if(music_sel < SEL_QUIT) {
music_sel++;
} else {
music_sel = 0;
}
// Skip over the empty line
if(music_sel == TRACK_COUNT) {
music_sel++;
}
track_put(music_sel, COL_TRACKLIST_SELECTED);
}
#endif
skip_processing_of_left_and_right:
if(key_det & INPUT_SHOT || key_det & INPUT_OK) {
if(music_sel != SEL_QUIT) {
#if (GAME >= 4)
snd_kaja_func(KAJA_SONG_FADE, 32);
#elif (GAME == 3)
// Avoids the snd_load() landmine that is still present in
// this game.
snd_kaja_func(KAJA_SONG_STOP, 0);
#elif (GAME == 2)
// ZUN landmine: Should have stopped the currently playing
// track according to snd_load()'s header comment.
// Especially since this game simultaneously loads both the
// PMD and MIDI versions and is therefore inherently slower
// than the others.
#endif
#if (GAME == 5)
sel_prev = track_playing;
track_playing = music_sel;
track_unput_and_put_both_animate(sel_prev, music_sel);
cmt_load_unput_and_put_both_animate(music_sel);
snd_load(MUSIC_FILES[game_sel][music_sel], SND_LOAD_SONG);
snd_kaja_func(KAJA_SONG_PLAY, 0);
#elif (GAME == 4)
track_playing = music_sel;
cmt_load_unput_and_put_both_animate(music_sel);
snd_load(MUSIC_FILES[music_sel], SND_LOAD_SONG);
snd_kaja_func(KAJA_SONG_PLAY, 0);
#else
#if (GAME == 3)
snd_load(MUSIC_FILES[music_sel], SND_LOAD_SONG);
#else
// Load both the MIDI and PMD versions of the selected
// track. Makes sense given that the track continues
// playing when leaving the Music Room changing the
// music mode in the Option menu will then play the
// same selected track.
bool midi_active = snd_midi_active;
snd_midi_active = snd_midi_possible;
snd_load(MUSIC_FILES[music_sel], SND_LOAD_SONG);
snd_midi_active = 0;
snd_load(MUSIC_FILES[music_sel], SND_LOAD_SONG);
snd_midi_active = midi_active;
#endif
snd_kaja_func(KAJA_SONG_PLAY, 0);
track_playing = music_sel;
cmt_load_unput_and_put(music_sel);
music_flip();
cmt_load_unput_and_put(music_sel);
#endif
} else {
break;
}
}
if(key_det & INPUT_CANCEL) {
break;
}
if(!key_det) {
#if (GAME == 5)
frames_since_last_input = 0;
#endif
music_flip();
goto controls;
}
};
wait_for_key_release_animate();
#if (GAME >= 4)
#if (GAME == 5)
pfend();
pfstart(OP_AND_END_PF_FN);
#endif
snd_kaja_func(KAJA_SONG_FADE, 16);
nopoly_B_free();
graph_showpage(0);
graph_accesspage(0);
palette_black_out(1);
bgimage_free();
snd_load(BGM_MENU_MAIN_FN, SND_LOAD_SONG);
snd_kaja_func(KAJA_SONG_PLAY, 0);
#else
nopoly_B_free();
cmt_bg_free();
graph_showpage(0);
// ZUN quirk: graph_clear() sets all of VRAM to hardware color #0,
// which is purple in the original images, not black.
//
// ZUN bloat: Unlike the graph_clear() call at the beginning of the
// function, this one is not useless because we haven't reset the
// hardware palette yet. Still, setting all hardware colors to color #0
// would have been a more efficient way to accomplish the same hiding
// effect before the graph_copy_page() call below.
graph_accesspage(0);
graph_clear();
graph_accesspage(1);
#if (GAME == 2)
// ZUN bloat: The call site would have been a better place for this.
pi_load_put_8_free(0, "op2.pi");
palette_entry_rgb_show("op.rgb");
graph_copy_page(0);
#endif
graph_accesspage(0);
#endif
}

10
th02/op/m_music.hpp Normal file
View File

@ -0,0 +1,10 @@
#if (GAME >= 4)
#define MUSICROOM_DISTANCE near
#else
#define MUSICROOM_DISTANCE
#endif
// Runs the Music Room menu and returns with VRAM page #0 as the shown and
// accessed one. TH02 reblits the title screen background to that page before
// returning; the other games return with a black screen.
void MUSICROOM_DISTANCE musicroom_menu(void);

View File

@ -1,3 +0,0 @@
@nopoly_B_snap$qv procdesc near
@nopoly_B_free$qv procdesc near
@music_flip$qv procdesc near

View File

@ -1,3 +0,0 @@
extern _music_sel:byte
extern _music_page:byte
extern _cmt_shown_initial:byte

View File

@ -35,6 +35,7 @@ extern "C" {
#include "th02/shiftjis/fns.hpp"
#include "th02/op/op.h"
#include "th02/op/menu.hpp"
#include "th02/op/m_music.hpp"
#pragma option -d -a2
@ -60,7 +61,6 @@ extern unsigned int score_duration;
void title_flash(void);
void pascal score_menu(void);
void pascal shottype_menu(void);
void pascal musicroom(void);
int cfg_load(void)
{
@ -439,7 +439,7 @@ void main_update_and_render(void)
break;
case 4:
text_clear();
musicroom();
musicroom_menu();
initialized = false;
break;
case 5:

View File

@ -1,145 +1,11 @@
#pragma option -zCOP_MUSIC_TEXT
#include "platform.h"
#include "x86real.h"
#include "pc98.h"
#include "planar.h"
#include "master.hpp"
#include "shiftjis.hpp"
#include "libs/kaja/kaja.h"
#include "th02/v_colors.hpp"
extern "C" {
#include "th02/hardware/input.hpp"
#include "th02/formats/pi.h"
#include "th02/snd/snd.h"
}
extern const char* MUSIC_FILES[15];
extern uint8_t track_playing;
static const int MUSIC_CMT_LINE_LEN = 42;
static const int MUSIC_CMT_LINE_COUNT = 20;
#define SEL_QUIT TRACK_COUNT + 1
#define TRACK_COUNT sizeof(MUSIC_FILES) / sizeof(MUSIC_FILES[0])
extern unsigned char music_sel;
extern page_t music_page;
dots8_t *nopoly_B;
Planar<dots8_t far *> cmt_bg;
shiftjis_t music_cmt[MUSIC_CMT_LINE_COUNT][MUSIC_CMT_LINE_LEN];
void pascal near track_put(uint8_t sel, vc_t col);
void pascal near tracklist_put(uint8_t sel);
void near nopoly_B_snap(void);
void near nopoly_B_free(void);
void near music_flip(void);
void near cmt_bg_snap(void);
void near cmt_bg_free(void);
void pascal near cmt_load_unput_and_put(int track);
void pascal musicroom(void)
{
music_page = 1;
palette_black();
graph_showpage(0);
graph_accesspage(0);
graph_clear();
graph_accesspage(1);
pi_load_put_8_free(0, reinterpret_cast<const char *>(MK_FP(_DS, 0x0C1D)));
music_sel = track_playing;
tracklist_put(music_sel);
graph_copy_page(0);
graph_accesspage(1);
graph_showpage(0);
nopoly_B_snap();
cmt_bg_snap();
graph_accesspage(1); cmt_load_unput_and_put(track_playing);
graph_accesspage(0); cmt_load_unput_and_put(track_playing);
palette_100();
do {
input_sense();
if(key_det) {
music_flip();
continue;
}
controls:
input_sense();
if(key_det & INPUT_UP) {
track_put(music_sel, 3);
if(music_sel > 0) {
music_sel--;
} else {
music_sel = SEL_QUIT;
}
if(music_sel == TRACK_COUNT) {
music_sel--;
}
track_put(music_sel, V_WHITE);
}
if(key_det & INPUT_DOWN) {
track_put(music_sel, 3);
if(music_sel < SEL_QUIT) {
music_sel++;
} else {
music_sel = 0;
}
if(music_sel == TRACK_COUNT) {
music_sel++;
}
track_put(music_sel, V_WHITE);
}
if(key_det & INPUT_SHOT || key_det & INPUT_OK) {
if(music_sel != SEL_QUIT) {
bool midi_active = snd_midi_active;
snd_midi_active = snd_midi_possible;
snd_load(MUSIC_FILES[music_sel], SND_LOAD_SONG);
snd_midi_active = 0;
snd_load(MUSIC_FILES[music_sel], SND_LOAD_SONG);
snd_midi_active = midi_active;
snd_kaja_func(KAJA_SONG_PLAY, 0);
track_playing = music_sel;
cmt_load_unput_and_put(music_sel);
music_flip();
cmt_load_unput_and_put(music_sel);
} else {
break;
}
}
if(key_det & INPUT_CANCEL) {
break;
}
if(!key_det) {
music_flip();
goto controls;
}
} while(1);
while(1) {
input_sense();
if(key_det) {
music_flip();
} else {
break;
}
};
nopoly_B_free();
cmt_bg_free();
graph_showpage(0);
graph_accesspage(0);
graph_clear();
graph_accesspage(1);
pi_load_put_8_free(0, "op2.pi");
palette_entry_rgb_show("op.rgb");
graph_copy_page(0);
graph_accesspage(0);
}

View File

@ -38,5 +38,5 @@ const char* MUSIC_FILES[] = {
"end1.m",
"ending.m",
"stage5.m",
"boss5.m\0MUSIC.TXT\0op3.pi",
"boss5.m",
};

View File

@ -169,6 +169,9 @@ extern uint8_t text_fx; // TH04 and TH05 directly set [graph_putsa_fx_func].
#endif
// -----------------------
// Same game-specific branches as in the Music Room, but they have a much
// bigger impact here:
//
// ZUN quirk: The cutscene system features both
// 1) a top-level input sensing mechanism (for updating the fast-forward flag),
// and

View File

@ -44,5 +44,5 @@ const char* MUSIC_FILES[] = {
"demo4.m",
"demo5.m",
"ed.m",
"score.m\0MUSIC.TXT\0op3.pi",
"score.m",
};

View File

@ -917,7 +917,7 @@ loc_A19A:
; ---------------------------------------------------------------------------
menu_sel_musicroom:
nopcall musicroom
nopcall @musicroom_menu$qv
jmp short loc_A19A
; ---------------------------------------------------------------------------
@ -1317,178 +1317,7 @@ _main endp
op_01_TEXT ends
OP_MUSIC_TEXT segment byte public 'CODE' use16
@TRACK_PUT$QUCUC procdesc pascal near \
sel:byte, col:byte
@TRACKLIST_PUT$QUC procdesc pascal near \
sel:byte
@cmt_bg_snap$qv procdesc near
@cmt_bg_free$qv procdesc near
@CMT_LOAD_UNPUT_AND_PUT$QI procdesc pascal near \
track:word
include th02/op/music.asm
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
public MUSICROOM
musicroom proc far
push bp
mov bp, sp
push si
xor si, si
jmp short loc_AC15
; ---------------------------------------------------------------------------
loc_AC0E:
call cdg_free pascal, si
inc si
loc_AC15:
cmp si, CDG_SLOT_COUNT
jl short loc_AC0E
call super_free
call text_clear
mov _music_page, 1
mov PaletteTone, 0
call far ptr palette_show
graph_showpage 0
graph_accesspage al
call graph_clear
graph_accesspage 1
call pi_load pascal, 0, ds, offset aOp3_pi
call pi_palette_apply pascal, 0
call pi_put_8 pascal, large 0, 0
freePISlotLarge 0
mov al, _track_playing
mov _music_sel, al
call @tracklist_put$quc pascal, word ptr _music_sel
call graph_copy_page pascal, 0
graph_accesspage 1
graph_showpage 0
call @nopoly_B_snap$qv
call @cmt_bg_snap$qv
graph_accesspage 1
mov al, _track_playing
mov ah, 0
call @cmt_load_unput_and_put$qi pascal, ax
graph_accesspage 0
mov al, _track_playing
mov ah, 0
call @cmt_load_unput_and_put$qi pascal, ax
mov PaletteTone, 100
call far ptr palette_show
loc_ACC2:
call input_mode_interface
cmp _input_sp, INPUT_NONE
jz short loc_ACD3
call @music_flip$qv
jmp short loc_ACC2
; ---------------------------------------------------------------------------
loc_ACD3:
call input_mode_interface
test _input_sp.lo, low INPUT_UP
jz short loc_AD0E
call @track_put$qucuc pascal, word ptr _music_sel, 3
cmp _music_sel, 0
jbe short loc_ACF5
dec _music_sel
jmp short loc_ACFA
; ---------------------------------------------------------------------------
loc_ACF5:
mov _music_sel, 14h
loc_ACFA:
cmp _music_sel, 13h
jnz short loc_AD05
dec _music_sel
loc_AD05:
call @track_put$qucuc pascal, word ptr _music_sel, V_WHITE
loc_AD0E:
test _input_sp.lo, low INPUT_DOWN
jz short loc_AD44
call @track_put$qucuc pascal, word ptr _music_sel, 3
cmp _music_sel, 14h
jnb short loc_AD2B
inc _music_sel
jmp short loc_AD30
; ---------------------------------------------------------------------------
loc_AD2B:
mov _music_sel, 0
loc_AD30:
cmp _music_sel, 13h
jnz short loc_AD3B
inc _music_sel
loc_AD3B:
call @track_put$qucuc pascal, word ptr _music_sel, V_WHITE
loc_AD44:
test _input_sp.lo, low INPUT_SHOT
jnz short loc_AD52
test _input_sp.hi, high INPUT_OK
jz short loc_AD9A
loc_AD52:
cmp _music_sel, 14h
jz short loc_ADB0
kajacall KAJA_SONG_STOP
push SND_LOAD_SONG
mov al, _music_sel
mov ah, 0
shl ax, 2
mov bx, ax
pushd _MUSIC_FILES[bx]
call _snd_load
add sp, 6
kajacall KAJA_SONG_PLAY
mov al, _music_sel
mov _track_playing, al
mov ah, 0
call @cmt_load_unput_and_put$qi pascal, ax
call @music_flip$qv
mov al, _music_sel
mov ah, 0
call @cmt_load_unput_and_put$qi pascal, ax
loc_AD9A:
test _input_sp.hi, high INPUT_CANCEL
jnz short loc_ADB0
cmp _input_sp, INPUT_NONE
jnz loc_ACC2
call @music_flip$qv
jmp loc_ACD3
; ---------------------------------------------------------------------------
loc_ADB0:
call input_mode_interface
cmp _input_sp, INPUT_NONE
jz short loc_ADC1
call @music_flip$qv
jmp short loc_ADB0
; ---------------------------------------------------------------------------
loc_ADC1:
call @nopoly_B_free$qv
call @cmt_bg_free$qv
graph_showpage 0
graph_accesspage al
call graph_clear
graph_accesspage 1
mov al, 0
out dx, al
pop si
pop bp
retf
musicroom endp
extern @musicroom_menu$qv:proc
; =============== S U B R O U T I N E =======================================
@ -3222,11 +3051,6 @@ SHARED ends
extern _SinTable8:word:256
extern _CosTable8:word:256
extern _MUSIC_FILES:dword
extern _track_playing:byte
_aMUSIC_TXT = (aOp3_pi - 10)
aOp3_pi = ($ - 7)
aOpwin_bft db 'opwin.bft',0
aOp_m db 'op.m',0
aTl01_pi db 'TL01.PI',0
@ -3316,7 +3140,6 @@ aTlsl_rgb db 'TLSL.RGB',0
extern _pi_buffers:dword
extern _pi_headers:PiHeader
include th02/op/music[bss].asm
include th03/op/cmt_back[bss].asm
include th02/op/music_cmt[bss].asm
public _hi

View File

@ -18,6 +18,7 @@
#include "th02/v_colors.hpp"
#include "th02/hardware/frmdelay.h"
#include "th02/op/menu.hpp"
#include "th02/op/m_music.hpp"
#include "th03/core/initexit.h"
extern "C" {
#include "th04/hardware/grppsafx.h"
@ -383,7 +384,7 @@ void near main_update_and_render(void)
initialized = false;
break;
case MC_MUSICROOM:
musicroom();
musicroom_menu();
main_cdg_load();
// ZUN quirk: Moving to MC_GAME in TH04?

View File

@ -14,8 +14,6 @@ void near main_cdg_free(void);
// and page 0 shown.
void near op_animate(void);
void near musicroom(void);
void near regist_view_menu(void);
// Initializes the game clear/extra unlock variables from the score file, and

View File

@ -44,7 +44,6 @@ _TEXT segment word public 'CODE' use16
extern GRAPH_PI_FREE:proc
extern PALETTE_SHOW:proc
extern IRAND:proc
extern TEXT_CLEAR:proc
extern SUPER_FREE:proc
extern SUPER_ENTRY_BFNT:proc
extern SUPER_PUT_RECT:proc
@ -65,153 +64,6 @@ include th04/zunsoft.asm
OP_SETUP_TEXT ends
op_01_TEXT segment byte public 'CODE' use16
@TRACK_PUT$QUCUC procdesc pascal near \
sel:byte, col:byte
@TRACKLIST_PUT$QUC procdesc pascal near \
sel:byte
@CMT_LOAD_UNPUT_AND_PUT_BOTH_ANIM$QI procdesc pascal near \
track:word
include th02/op/music.asm
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
public _musicroom
_musicroom proc near
push bp
mov bp, sp
mov _cmt_shown_initial, 0
call cdg_free_all
call text_clear
mov _music_page, 1
mov PaletteTone, 0
call far ptr palette_show
graph_showpage 0
graph_accesspage al
call graph_clear
graph_accesspage 1
call pi_load pascal, 0, ds, offset aMusic_pi
call pi_palette_apply pascal, 0
call pi_put_8 pascal, large 0, 0
freePISlotLarge 0
mov al, _track_playing
mov _music_sel, al
call @tracklist_put$quc pascal, word ptr _music_sel
call graph_copy_page pascal, 0
call _bgimage_snap
graph_accesspage 1
graph_showpage 0
call @nopoly_B_snap$qv
mov al, _track_playing
mov ah, 0
call @cmt_load_unput_and_put_both_anim$qi pascal, ax
mov PaletteTone, 100
call far ptr palette_show
loc_C454:
call far ptr _input_reset_sense
cmp _key_det, INPUT_NONE
jz short loc_C465
call @music_flip$qv
jmp short loc_C454
; ---------------------------------------------------------------------------
loc_C465:
call far ptr _input_reset_sense
test _key_det.lo, low INPUT_UP
jz short loc_C4A0
call @track_put$qucuc pascal, word ptr _music_sel, 5
cmp _music_sel, 0
jbe short loc_C487
dec _music_sel
jmp short loc_C48C
; ---------------------------------------------------------------------------
loc_C487:
mov _music_sel, 17h
loc_C48C:
cmp _music_sel, 16h
jnz short loc_C497
dec _music_sel
loc_C497:
call @track_put$qucuc pascal, word ptr _music_sel, 3
loc_C4A0:
test _key_det.lo, low INPUT_DOWN
jz short loc_C4D6
call @track_put$qucuc pascal, word ptr _music_sel, 5
cmp _music_sel, 17h
jnb short loc_C4BD
inc _music_sel
jmp short loc_C4C2
; ---------------------------------------------------------------------------
loc_C4BD:
mov _music_sel, 0
loc_C4C2:
cmp _music_sel, 16h
jnz short loc_C4CD
inc _music_sel
loc_C4CD:
call @track_put$qucuc pascal, word ptr _music_sel, 3
loc_C4D6:
test _key_det.lo, low INPUT_SHOT
jnz short loc_C4E4
test _key_det.hi, high INPUT_OK
jz short loc_C51D
loc_C4E4:
cmp _music_sel, 17h
jz short loc_C533
kajacall KAJA_SONG_FADE, 32
mov al, _music_sel
mov _track_playing, al
mov ah, 0
call @cmt_load_unput_and_put_both_anim$qi pascal, ax
mov al, _music_sel
mov ah, 0
shl ax, 2
mov bx, ax
call snd_load pascal, dword ptr _MUSIC_FILES[bx], SND_LOAD_SONG
kajacall KAJA_SONG_PLAY
loc_C51D:
test _key_det.hi, high INPUT_CANCEL
jnz short loc_C533
cmp _key_det, INPUT_NONE
jnz loc_C454
call @music_flip$qv
jmp loc_C465
; ---------------------------------------------------------------------------
loc_C533:
call far ptr _input_reset_sense
cmp _key_det, INPUT_NONE
jz short loc_C544
call @music_flip$qv
jmp short loc_C533
; ---------------------------------------------------------------------------
loc_C544:
kajacall KAJA_SONG_FADE, 16
call @nopoly_B_free$qv
graph_showpage 0
graph_accesspage al
push 1
call palette_black_out
call _bgimage_free
call snd_load pascal, ds, offset aOp_2, SND_LOAD_SONG
kajacall KAJA_SONG_PLAY
pop bp
retn
_musicroom endp
include th04/formats/scoredat_decode_both.asm
include th04/formats/scoredat_encode.asm
include th04/formats/scoredat_recreate.asm
@ -954,11 +806,6 @@ SHARED ends
include th04/zunsoft[data].asm
extern _MUSIC_FILES:dword
extern _track_playing:byte
aOp_2 = ($ - 138)
aMusic_pi = ($ - 9)
aGensou_scr db 'GENSOU.SCR',0
aName db 'name',0
aHi01_pi db 'hi01.pi',0
@ -998,7 +845,6 @@ aOp1_pi_1 db 'op1.pi',0
extern _key_det:word
include th04/zunsoft[bss].asm
include th02/op/music[bss].asm
include th03/op/cmt_back[bss].asm
include th02/op/music_cmt[bss].asm
include th04/formats/scoredat_op[bss].asm

View File

@ -2,6 +2,7 @@
#include "th03/shiftjis/bgm.hpp"
#include "th04/shiftjis/bgm.hpp"
#include "th05/shiftjis/bgm.hpp"
#include "th04/shiftjis/fnshared.hpp"
static const unsigned int GAME_COUNT = 5;
static const unsigned int TRACKS_MAX = 30;
@ -254,7 +255,7 @@ const char* MUSIC_FILES[GAME_COUNT][TRACKS_MAX] = {{
"g_ng04",
"g_ng05",
}, {
"op",
BGM_MENU_MAIN_FN,
"st00",
"st00b",
"st01",

View File

@ -43,7 +43,6 @@ _TEXT segment word public 'CODE' use16
extern GRAPH_COPY_PAGE:proc
extern PALETTE_SHOW:proc
extern IRAND:proc
extern TEXT_CLEAR:proc
extern HMEM_FREE:proc
extern SUPER_FREE:proc
extern SUPER_ENTRY_BFNT:proc
@ -51,8 +50,6 @@ _TEXT segment word public 'CODE' use16
extern SUPER_PUT:proc
extern GRAPH_GAIJI_PUTS:proc
extern GRAPH_GAIJI_PUTC:proc
extern PFSTART:proc
extern PFEND:proc
_TEXT ends
; ===========================================================================
@ -66,294 +63,6 @@ include th04/zunsoft.asm
OP_SETUP_TEXT ends
op_01_TEXT segment byte public 'CODE' use16
@TRACK_UNPUT_OR_PUT$QUCI procdesc pascal near \
track_sel:byte, boot:word
@TRACKLIST_PUT$QUC procdesc pascal near \
sel:byte
@CMT_LOAD_UNPUT_AND_PUT_BOTH_ANIM$QI procdesc pascal near \
track:word
include th02/op/music.asm
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_C441 proc near
arg_0 = word ptr 4
push bp
mov bp, sp
push si
mov si, [bp+arg_0]
call bgimage_put_rect_16 pascal, large (0 shl 16) or 32, (320 shl 16) or 16
call bgimage_put_rect_16 pascal, large (0 shl 16) or 96, (320 shl 16) or 192
call @tracklist_put$quc pascal, si
call @music_flip$qv
call bgimage_put_rect_16 pascal, large (0 shl 16) or 32, (320 shl 16) or 16
call bgimage_put_rect_16 pascal, large (0 shl 16) or 96, (320 shl 16) or 192
call @tracklist_put$quc pascal, si
pop si
pop bp
retn 2
sub_C441 endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
public _musicroom
_musicroom proc near
@@sel = byte ptr -1
enter 2, 0
push si
xor si, si
mov _track_id_at_top, 0
mov _track_playing, 0
mov _music_sel, 0
mov bx, _game_sel
add bx, bx
mov ax, _TRACK_COUNT[bx]
mov _track_count_cur, ax
mov _cmt_shown_initial, 0
call cdg_free_all
call text_clear
mov _music_page, 1
mov PaletteTone, 0
call far ptr palette_show
graph_showpage 0
graph_accesspage al
call graph_clear
graph_accesspage 1
call pi_load pascal, 0, ds, offset aMusic_pi
call pi_palette_apply pascal, 0
call pi_put_8 pascal, large 0, 0
call pi_free pascal, 0
call @piano_setup_and_put_initial$qv
call @nopoly_B_snap$qv
call _bgimage_snap
call @tracklist_put$quc pascal, word ptr _music_sel
call graph_copy_page pascal, 0
graph_accesspage 1
graph_showpage 0
call pfend
call pfstart pascal, ds, offset aMusic_dat ; "music.dat"
mov al, _music_sel
mov ah, 0
call @cmt_load_unput_and_put_both_anim$qi pascal, ax
mov PaletteTone, 100
call far ptr palette_show
loc_C555:
call _input_reset_sense_held
cmp _key_det, INPUT_NONE
jz short loc_C57F
cmp si, 18h
jl short loc_C579
cmp _key_det, INPUT_UP
jz short loc_C574
cmp _key_det, INPUT_DOWN
jnz short loc_C579
loc_C574:
mov si, 14h
jmp short loc_C57F
; ---------------------------------------------------------------------------
loc_C579:
inc si
call @music_flip$qv
jmp short loc_C555
; ---------------------------------------------------------------------------
loc_C57F:
call _input_reset_sense_held
test _key_det.lo, low INPUT_UP
jz short loc_C5EB
mov al, _music_sel
mov [bp+@@sel], al
cmp _music_sel, 0
jbe short loc_C5D5
dec _music_sel
mov al, _music_sel
mov ah, 0
cmp ax, _track_id_at_top
jge short loc_C5AE
mov al, _music_sel
mov ah, 0
jmp short loc_C61C
; ---------------------------------------------------------------------------
loc_C5AE:
call @track_unput_or_put$quci pascal, word ptr [bp+@@sel], 0
call @track_unput_or_put$quci pascal, word ptr _music_sel, 1
call @music_flip$qv
call @track_unput_or_put$quci pascal, word ptr [bp+@@sel], 0
call @track_unput_or_put$quci pascal, word ptr _music_sel, 1
jmp short loc_C5EB
; ---------------------------------------------------------------------------
loc_C5D5:
mov al, byte ptr _track_count_cur
mov _music_sel, al
mov ax, _track_count_cur
add ax, -11
mov _track_id_at_top, ax
push _track_count_cur
call sub_C441
loc_C5EB:
test _key_det.lo, low INPUT_DOWN
jz short loc_C666
mov al, _music_sel
mov [bp+@@sel], al
mov ah, 0
cmp ax, _track_count_cur
jge short loc_C652
inc _music_sel
mov al, _music_sel
mov ah, 0
mov dx, _track_id_at_top
add dx, 12
cmp ax, dx
jl short loc_C62B
mov al, _music_sel
mov ah, 0
add ax, -11
loc_C61C:
mov _track_id_at_top, ax
mov al, _music_sel
mov ah, 0
push ax
call sub_C441
jmp loc_C6E3
; ---------------------------------------------------------------------------
loc_C62B:
call @track_unput_or_put$quci pascal, word ptr [bp+@@sel], 0
call @track_unput_or_put$quci pascal, word ptr _music_sel, 1
call @music_flip$qv
call @track_unput_or_put$quci pascal, word ptr [bp+@@sel], 0
call @track_unput_or_put$quci pascal, word ptr _music_sel, 1
jmp short loc_C666
; ---------------------------------------------------------------------------
loc_C652:
mov _music_sel, 0
mov _track_id_at_top, 0
mov al, _music_sel
mov ah, 0
push ax
call sub_C441
loc_C666:
test _key_det.lo, low INPUT_LEFT
jz short loc_C680
dec _game_sel
cmp _game_sel, 0
jge short loc_C698
mov _game_sel, 4
jmp short loc_C698
; ---------------------------------------------------------------------------
loc_C680:
test _key_det.lo, low INPUT_RIGHT
jz short loc_C6E3
inc _game_sel
cmp _game_sel, 5
jl short loc_C698
mov _game_sel, 0
loc_C698:
mov _music_sel, 0
mov _track_playing, 0
mov _track_id_at_top, 0
mov bx, _game_sel
add bx, bx
mov ax, _TRACK_COUNT[bx]
mov _track_count_cur, ax
push 0
call sub_C441
kajacall KAJA_SONG_FADE, 32
call @cmt_load_unput_and_put_both_anim$qi pascal, 0
mov bx, _game_sel
imul bx, 78h
call snd_load pascal, dword ptr _MUSIC_FILES[bx], SND_LOAD_SONG
kajacall KAJA_SONG_PLAY
loc_C6E3:
test _key_det.lo, low INPUT_SHOT
jnz short loc_C6F1
test _key_det.hi, high INPUT_OK
jz short loc_C767
loc_C6F1:
mov al, _music_sel
mov ah, 0
cmp ax, _track_count_cur
jz loc_C77F
kajacall KAJA_SONG_FADE, 32
mov al, byte ptr _track_playing
mov [bp+@@sel], al
mov al, _music_sel
mov ah, 0
mov _track_playing, ax
call @track_unput_or_put$quci pascal, word ptr [bp+@@sel], 0
call @track_unput_or_put$quci pascal, word ptr _music_sel, 1
call @music_flip$qv
call @track_unput_or_put$quci pascal, word ptr [bp+@@sel], 0
call @track_unput_or_put$quci pascal, word ptr _music_sel, 1
mov al, _music_sel
mov ah, 0
call @cmt_load_unput_and_put_both_anim$qi pascal, ax
mov bx, _game_sel
imul bx, 78h
mov al, _music_sel
mov ah, 0
shl ax, 2
add bx, ax
call snd_load pascal, dword ptr _MUSIC_FILES[bx], SND_LOAD_SONG
kajacall KAJA_SONG_PLAY
loc_C767:
test _key_det.hi, high INPUT_CANCEL
jnz short loc_C77F
cmp _key_det, INPUT_NONE
jnz loc_C555
xor si, si
call @music_flip$qv
jmp loc_C57F
; ---------------------------------------------------------------------------
loc_C77F:
call _input_reset_sense_held
cmp _key_det, INPUT_NONE
jz short loc_C790
call @music_flip$qv
jmp short loc_C77F
; ---------------------------------------------------------------------------
loc_C790:
call pfend
call pfstart pascal, ds, offset aKaikidan1_dat1
kajacall KAJA_SONG_FADE, 16
call @nopoly_B_free$qv
graph_showpage 0
graph_accesspage al
push 1
call palette_black_out
call _bgimage_free
call snd_load pascal, ds, offset aH_op+2, SND_LOAD_SONG
kajacall KAJA_SONG_PLAY
pop si
leave
retn
_musicroom endp
include th04/formats/scoredat_decode_both.asm
include th04/formats/scoredat_encode.asm
include th05/formats/scoredat_recreate_op.asm
@ -732,8 +441,6 @@ include th02/snd/snd.inc
extern _bgimage_put:proc
extern _bgimage_free:proc
extern @POLAR$QIII:proc
extern @piano_setup_and_put_initial$qv:proc
extern BGIMAGE_PUT_RECT_16:proc
extern SND_LOAD:proc
extern SND_KAJA_INTERRUPT:proc
extern PI_LOAD:proc
@ -743,7 +450,6 @@ include th02/snd/snd.inc
extern _input_reset_sense_held:proc
extern SND_DELAY_UNTIL_MEASURE:proc
extern @FRAME_DELAY$QI:proc
extern CDG_FREE_ALL:proc
SHARED ends
.data
@ -756,16 +462,6 @@ SHARED ends
extern _CosTable8:word:256
include th04/zunsoft[data].asm
extern _MUSIC_FILES:dword
extern _game_sel:word
extern _TRACK_COUNT:word:5
aH_op = ($ - 542)
aMusic_pi db 'music.pi',0
aMusic_dat db 'music.dat',0
aKaikidan1_dat1 db '‰öãYk1.dat',0
db 0
include th05/formats/scoredat_load_for[data].asm
aName db 'name',0
aHi01_pi db 'hi01.pi',0
@ -786,7 +482,6 @@ aOp_1 db 'op',0
extern _key_det:word
include th04/zunsoft[bss].asm
include th02/op/music[bss].asm
include th03/op/cmt_back[bss].asm
include th02/op/music_cmt[bss].asm
public _track_id_at_top, _track_playing, _track_count_cur