[Decompilation] [th04/th05] Setup menu: BGM and SE mode menus

I think this is the first time that function pointers as `inline`
function parameters actually inlined perfectly?

Part of P0263, funded by [Anonymous].
This commit is contained in:
nmlgc 2023-11-29 21:02:38 +01:00
parent 449aa37343
commit 7aa0459306
6 changed files with 130 additions and 430 deletions

View File

@ -2,11 +2,19 @@
#include "pc98.h"
#include "master.hpp"
#include "shiftjis.hpp"
#include "th01/math/clamp.hpp"
#include "th01/hardware/egc.h"
#include "th02/v_colors.hpp"
extern "C" {
#include "th02/hardware/frmdelay.h"
#include "th04/score.h"
#if (GAME == 5)
#include "th05/resident.hpp"
#else
#include "th04/resident.hpp"
#endif
#include "th04/hardware/grppsafx.h"
#include "th04/hardware/input.h"
#include "th04/snd/snd.h"
}
#include "th04/shiftjis/m_setup.hpp"
@ -24,6 +32,9 @@ enum setup_window_patnum_t {
MSWIN_RIGHT_TOP,
};
static const vc2 COL_INACTIVE = 0;
static const vc2 COL_ACTIVE = V_WHITE;
// Coordinates
// -----------
@ -38,11 +49,15 @@ static const pixel_t MSWIN_H = 16;
static const pixel_t DROP_SPEED = (MSWIN_H / 2);
static const int DROP_FRAMES_PER_TILE = (MSWIN_H / DROP_SPEED);
static const screen_x_t CAPTION_LEFT = ((RES_X / 2) - (CAPTION_W / 2));
static const screen_y_t CAPTION_TOP = 88;
inline void assert_that_all_choices_are_equally_wide(void) {
static_assert(shiftjis_w(BGM_CHOICE_FM86) == shiftjis_w(BGM_CHOICE_FM26));
static_assert(shiftjis_w(BGM_CHOICE_FM86) == shiftjis_w(BGM_CHOICE_OFF));
static_assert(shiftjis_w(BGM_CHOICE_FM86) == shiftjis_w(SE_CHOICE_BEEP));
static_assert(shiftjis_w(BGM_CHOICE_FM86) == shiftjis_w(SE_CHOICE_FM));
static_assert(shiftjis_w(BGM_CHOICE_FM86) == shiftjis_w(SE_CHOICE_OFF));
}
static const pixel_t CHOICE_W = shiftjis_w(BGM_CHOICE_FM86);
@ -56,7 +71,6 @@ static const screen_x_t HELP_TOP = CHOICE_TOP;
typedef int mswin_tile_amount_t;
#define window window_tiles
static Palette8 palette_unused; // ZUN bloat
struct {
mswin_tile_amount_t w;
@ -154,6 +168,22 @@ void pascal near rollup(screen_x_t left, screen_y_t top)
}
}
inline void window_animate(
screen_x_t content_left,
screen_y_t content_top,
pixel_t content_w,
int content_lines,
void (near pascal *near animate_func)(screen_x_t, screen_y_t)
) {
window.w = (window_w_for_content_w(content_w) / MSWIN_W);
if(content_lines != 1) {
window.h = (
((MSWIN_BORDER_H * 2) + (content_lines * GLYPH_H)) / MSWIN_H
);
}
animate_func((content_left - MSWIN_W), (content_top - MSWIN_BORDER_H));
}
// ZUN bloat: Could have been a single function with a value/string array
// parameter.
void pascal near bgm_choice_put(int bgm_mode, vc2 col)
@ -182,7 +212,7 @@ void pascal near se_choice_put(int se_mode, vc2 col)
graph_putsa_fx(CHOICE_LEFT, top, col, str);
}
// ZUN bloat: Could have been a single function with a string array parameter.
// ZUN bloat: Could have been inlined into setup_submenu().
void near bgm_help_put(void)
{
screen_y_t top = HELP_TOP;
@ -198,3 +228,86 @@ void near se_help_put(void)
graph_putsa_fx(HELP_LEFT, top, V_WHITE, SE_HELP[i]);
}
}
#define setup_submenu( \
sel, \
caption, \
choice_count, \
choice_default, \
choice_put, \
help_put, \
increment_input \
) { \
window_animate(CAPTION_LEFT, CAPTION_TOP, CAPTION_W, 1, singleline); \
graph_putsa_fx(CAPTION_LEFT, CAPTION_TOP, V_WHITE, caption); \
\
window_animate(CHOICE_LEFT, CHOICE_TOP, CHOICE_W, choice_count, dropdown); \
for(sel = 0; sel < choice_count; sel++) { \
choice_put( \
sel, ((sel == choice_default) ? COL_ACTIVE : COL_INACTIVE) \
); \
} \
\
window_animate(HELP_LEFT, HELP_TOP, HELP_W, HELP_LINES, dropdown); \
help_put(); \
\
sel = choice_default; \
while(1) { \
input_wait_for_change(0); \
frame_delay(1); \
if((key_det & INPUT_OK) || (key_det & INPUT_SHOT)) { \
break; \
} \
if(key_det & increment_input) { \
choice_put(sel, COL_INACTIVE); \
if(sel == (choice_count - 1)) { \
sel = 0; \
} else { \
sel++; \
} \
choice_put(sel, COL_ACTIVE); \
} \
if(key_det & (~increment_input & (INPUT_UP | INPUT_DOWN))) { \
choice_put(sel, COL_INACTIVE); \
if(sel == 0) { \
sel = (choice_count - 1); \
} else { \
sel--; \
} \
choice_put(sel, COL_ACTIVE); \
} \
} \
\
window_animate(HELP_LEFT, HELP_TOP, HELP_W, HELP_LINES, rollup); \
window_animate(CHOICE_LEFT, CHOICE_TOP, CHOICE_W, choice_count, rollup); \
}
void near setup_bgm_menu(void)
{
int sel;
setup_submenu(
sel,
SETUP_BGM_CAPTION,
SND_BGM_MODE_COUNT,
SND_BGM_FM86,
bgm_choice_put,
bgm_help_put,
INPUT_UP
);
resident->bgm_mode = sel;
}
void near setup_se_menu(void)
{
int sel;
setup_submenu(
sel,
SETUP_SE_CAPTION,
SND_SE_MODE_COUNT,
SND_SE_FM,
se_choice_put,
se_help_put,
INPUT_DOWN
);
resident->se_mode = sel;
}

View File

@ -1,14 +1,2 @@
@DROPDOWN$QII procdesc pascal near \
topleft:dword
@SINGLELINE$QII procdesc pascal near \
topleft:dword
@ROLLUP$QII procdesc pascal near \
topleft:dword
@BGM_CHOICE_PUT$QIUI procdesc pascal near \
se_mode:word, col:word
@SE_CHOICE_PUT$QIUI procdesc pascal near \
se_mode:word, col:word
@bgm_help_put$qv procdesc near
@se_help_put$qv procdesc near
WINDOW_TILE_W = 16
@setup_bgm_menu$qv procdesc near
@setup_se_menu$qv procdesc near

View File

@ -1,5 +1,2 @@
aSETUP_BGM_HEAD = $ - 43
aSETUP_SE_HEAD db '    効果音に使用する音源を選択してね☆',0
aMswin_bft db 'mswin.bft',0
aMs_pi db 'ms.pi',0
even
aMswin_bft = $ - 17
aMs_pi = $ - 7

View File

@ -1,4 +1,5 @@
static const int HELP_LINES = 9;
static const pixel_t HELP_W = (46 * GLYPH_HALF_W);
shiftjis_t* BGM_HELP[HELP_LINES] = {
"ステレオ音源PC-9801-86(互換)ボード   ",
@ -30,6 +31,11 @@ shiftjis_t* SE_HELP[HELP_LINES] = {
#define SE_CHOICE_FM "  FM音源  "
#define SE_CHOICE_BEEP " Beep音源 "
#define SE_CHOICE_OFF "  効果音無し  \0" SETUP_BGM_CAPTION
#define SE_CHOICE_OFF "  効果音無し  "
// ZUN bloat: Why not centered? That's why we have to hardcode the length for
// those as well, even though we could infer it.
#define SETUP_BGM_CAPTION "     使用する音源を選択して下さいね☆"
#define SETUP_SE_CAPTION "    効果音に使用する音源を選択してね☆\0mswin.bft\0ms.pi"
static const pixel_t CAPTION_W = (52 * GLYPH_HALF_W);

View File

@ -67,206 +67,6 @@ OP_SETUP_TEXT segment byte public 'CODE' use16
include th04/setup.asm
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_B794 proc near
var_2 = word ptr -2
enter 2, 0
mov _window_tiles.x, (448 / WINDOW_TILE_W)
call @singleline$qii pascal, (96 shl 16) or 80
call graph_putsa_fx pascal, (112 shl 16) or 88, V_WHITE, ds, offset aSETUP_BGM_HEAD
mov _window_tiles.x, (160 / WINDOW_TILE_W)
mov _window_tiles.y, 1 + 3
call @dropdown$qii pascal, ( 32 shl 16) or 128
mov [bp+var_2], 0
jmp short loc_B7EB
; ---------------------------------------------------------------------------
loc_B7D4:
push [bp+var_2]
cmp [bp+var_2], 2
jnz short loc_B7E2
mov ax, V_WHITE
jmp short loc_B7E4
; ---------------------------------------------------------------------------
loc_B7E2:
xor ax, ax
loc_B7E4:
push ax
call @bgm_choice_put$qiui
inc [bp+var_2]
loc_B7EB:
cmp [bp+var_2], 3
jl short loc_B7D4
mov _window_tiles.x, (400 / WINDOW_TILE_W)
mov _window_tiles.y, 1 + 9
call @dropdown$qii pascal, (192 shl 16) or 128
call @bgm_help_put$qv
mov [bp+var_2], 2
loc_B80E:
call input_wait_for_change pascal, 0
push 1
call frame_delay
test _key_det.hi, high INPUT_OK
jnz short loc_B87A
test _key_det.lo, low INPUT_SHOT
jnz short loc_B87A
test _key_det.lo, low INPUT_UP
jz short loc_B851
call @bgm_choice_put$qiui pascal, [bp+var_2], 0
cmp [bp+var_2], 2
jnz short loc_B846
mov [bp+var_2], 0
jmp short loc_B849
; ---------------------------------------------------------------------------
loc_B846:
inc [bp+var_2]
loc_B849:
call @bgm_choice_put$qiui pascal, [bp+var_2], V_WHITE
loc_B851:
test _key_det.lo, low INPUT_DOWN
jz short loc_B80E
call @bgm_choice_put$qiui pascal, [bp+var_2], 0
cmp [bp+var_2], 0
jnz short loc_B86D
mov [bp+var_2], 2
jmp short loc_B870
; ---------------------------------------------------------------------------
loc_B86D:
dec [bp+var_2]
loc_B870:
call @bgm_choice_put$qiui pascal, [bp+var_2], V_WHITE
jmp short loc_B80E
; ---------------------------------------------------------------------------
loc_B87A:
mov _window_tiles.x, (400 / WINDOW_TILE_W)
mov _window_tiles.y, 1 + 9
call @rollup$qii pascal, (192 shl 16) or 128
mov _window_tiles.x, (160 / WINDOW_TILE_W)
mov _window_tiles.y, 1 + 3
call @rollup$qii pascal, ( 32 shl 16) or 128
les bx, _resident
mov al, byte ptr [bp+var_2]
mov es:[bx+resident_t.bgm_mode], al
leave
retn
sub_B794 endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_B8B1 proc near
var_2 = word ptr -2
enter 2, 0
mov _window_tiles.x, (448 / WINDOW_TILE_W)
call @singleline$qii pascal, (96 shl 16) or 80
call graph_putsa_fx pascal, (112 shl 16) or 88, V_WHITE, ds, offset aSETUP_SE_HEAD
mov _window_tiles.x, (160 / WINDOW_TILE_W)
mov _window_tiles.y, 1 + 3
call @dropdown$qii pascal, ( 32 shl 16) or 128
mov [bp+var_2], 0
jmp short loc_B908
; ---------------------------------------------------------------------------
loc_B8F1:
push [bp+var_2]
cmp [bp+var_2], 1
jnz short loc_B8FF
mov ax, V_WHITE
jmp short loc_B901
; ---------------------------------------------------------------------------
loc_B8FF:
xor ax, ax
loc_B901:
push ax
call @se_choice_put$qiui
inc [bp+var_2]
loc_B908:
cmp [bp+var_2], 3
jl short loc_B8F1
mov _window_tiles.x, (400 / WINDOW_TILE_W)
mov _window_tiles.y, 1 + 9
call @dropdown$qii pascal, (192 shl 16) or 128
call @se_help_put$qv
mov [bp+var_2], 1
loc_B92B:
call input_wait_for_change pascal, 0
push 1
call frame_delay
test _key_det.hi, high INPUT_OK
jnz short loc_B997
test _key_det.lo, low INPUT_SHOT
jnz short loc_B997
test _key_det.lo, low INPUT_DOWN
jz short loc_B96E
call @se_choice_put$qiui pascal, [bp+var_2], 0
cmp [bp+var_2], 2
jnz short loc_B963
mov [bp+var_2], 0
jmp short loc_B966
; ---------------------------------------------------------------------------
loc_B963:
inc [bp+var_2]
loc_B966:
call @se_choice_put$qiui pascal, [bp+var_2], V_WHITE
loc_B96E:
test _key_det.lo, low INPUT_UP
jz short loc_B92B
call @se_choice_put$qiui pascal, [bp+var_2], 0
cmp [bp+var_2], 0
jnz short loc_B98A
mov [bp+var_2], 2
jmp short loc_B98D
; ---------------------------------------------------------------------------
loc_B98A:
dec [bp+var_2]
loc_B98D:
call @se_choice_put$qiui pascal, [bp+var_2], V_WHITE
jmp short loc_B92B
; ---------------------------------------------------------------------------
loc_B997:
mov _window_tiles.x, (400 / WINDOW_TILE_W)
mov _window_tiles.y, 1 + 9
call @rollup$qii pascal, (192 shl 16) or 128
mov _window_tiles.x, (160 / WINDOW_TILE_W)
mov _window_tiles.y, 1 + 3
call @rollup$qii pascal, ( 32 shl 16) or 128
les bx, _resident
mov al, byte ptr [bp+var_2]
mov es:[bx+resident_t.se_mode], al
leave
retn
sub_B8B1 endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
@ -285,11 +85,11 @@ _setup_menu proc near
call graph_copy_page pascal, 0
push 1
call palette_black_in
call sub_B794
call @setup_bgm_menu$qv
push 1
call frame_delay
call graph_copy_page pascal, 0
call sub_B8B1
call @setup_se_menu$qv
push 1
call palette_black_out
call super_free
@ -1380,7 +1180,6 @@ include th02/snd/snd.inc
extern PI_PALETTE_APPLY:proc
extern PI_PUT_8:proc
extern PI_LOAD:proc
extern INPUT_WAIT_FOR_CHANGE:proc
extern @POLAR$QIII:proc
extern SND_KAJA_INTERRUPT:proc
extern SND_DELAY_UNTIL_MEASURE:proc
@ -1555,7 +1354,6 @@ aOp1_pi_1 db 'op1.pi',0
; th02/hardware/input_sense[bss].asm
extern _key_det:word
extern _window_tiles:Point
include th04/zunsoft[bss].asm
db 56 dup(?)
include th02/op/music[bss].asm

View File

@ -70,206 +70,6 @@ CFG_TEXT segment byte public 'CODE' use16
include th04/setup.asm
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_B36C proc near
var_2 = word ptr -2
enter 2, 0
mov _window_tiles.x, (448 / WINDOW_TILE_W)
call @singleline$qii pascal, (96 shl 16) or 80
call graph_putsa_fx pascal, (112 shl 16) or 88, V_WHITE, ds, offset aSETUP_BGM_HEAD
mov _window_tiles.x, (160 / WINDOW_TILE_W)
mov _window_tiles.y, 1 + 3
call @dropdown$qii pascal, ( 32 shl 16) or 128
mov [bp+var_2], 0
jmp short loc_B3C3
; ---------------------------------------------------------------------------
loc_B3AC:
push [bp+var_2]
cmp [bp+var_2], 2
jnz short loc_B3BA
mov ax, V_WHITE
jmp short loc_B3BC
; ---------------------------------------------------------------------------
loc_B3BA:
xor ax, ax
loc_B3BC:
push ax
call @bgm_choice_put$qiui
inc [bp+var_2]
loc_B3C3:
cmp [bp+var_2], 3
jl short loc_B3AC
mov _window_tiles.x, (400 / WINDOW_TILE_W)
mov _window_tiles.y, 1 + 9
call @dropdown$qii pascal, (192 shl 16) or 128
call @bgm_help_put$qv
mov [bp+var_2], 2
loc_B3E6:
call input_wait_for_change pascal, 0
push 1
call frame_delay
test _key_det.hi, high INPUT_OK
jnz short loc_B452
test _key_det.lo, low INPUT_SHOT
jnz short loc_B452
test _key_det.lo, low INPUT_UP
jz short loc_B429
call @bgm_choice_put$qiui pascal, [bp+var_2], 0
cmp [bp+var_2], 2
jnz short loc_B41E
mov [bp+var_2], 0
jmp short loc_B421
; ---------------------------------------------------------------------------
loc_B41E:
inc [bp+var_2]
loc_B421:
call @bgm_choice_put$qiui pascal, [bp+var_2], V_WHITE
loc_B429:
test _key_det.lo, low INPUT_DOWN
jz short loc_B3E6
call @bgm_choice_put$qiui pascal, [bp+var_2], 0
cmp [bp+var_2], 0
jnz short loc_B445
mov [bp+var_2], 2
jmp short loc_B448
; ---------------------------------------------------------------------------
loc_B445:
dec [bp+var_2]
loc_B448:
call @bgm_choice_put$qiui pascal, [bp+var_2], V_WHITE
jmp short loc_B3E6
; ---------------------------------------------------------------------------
loc_B452:
mov _window_tiles.x, (400 / WINDOW_TILE_W)
mov _window_tiles.y, 1 + 9
call @rollup$qii pascal, (192 shl 16) or 128
mov _window_tiles.x, (160 / WINDOW_TILE_W)
mov _window_tiles.y, 1 + 3
call @rollup$qii pascal, ( 32 shl 16) or 128
les bx, _resident
mov al, byte ptr [bp+var_2]
mov es:[bx+resident_t.bgm_mode], al
leave
retn
sub_B36C endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_B489 proc near
var_2 = word ptr -2
enter 2, 0
mov _window_tiles.x, (448 / WINDOW_TILE_W)
call @singleline$qii pascal, (96 shl 16) or 80
call graph_putsa_fx pascal, (112 shl 16) or 88, V_WHITE, ds, offset aSETUP_SE_HEAD
mov _window_tiles.x, (160 / WINDOW_TILE_W)
mov _window_tiles.y, 1 + 3
call @dropdown$qii pascal, ( 32 shl 16) or 128
mov [bp+var_2], 0
jmp short loc_B4E0
; ---------------------------------------------------------------------------
loc_B4C9:
push [bp+var_2]
cmp [bp+var_2], 1
jnz short loc_B4D7
mov ax, V_WHITE
jmp short loc_B4D9
; ---------------------------------------------------------------------------
loc_B4D7:
xor ax, ax
loc_B4D9:
push ax
call @se_choice_put$qiui
inc [bp+var_2]
loc_B4E0:
cmp [bp+var_2], 3
jl short loc_B4C9
mov _window_tiles.x, (400 / WINDOW_TILE_W)
mov _window_tiles.y, 1 + 9
call @dropdown$qii pascal, (192 shl 16) or 128
call @se_help_put$qv
mov [bp+var_2], 1
loc_B503:
call input_wait_for_change pascal, 0
push 1
call frame_delay
test _key_det.hi, high INPUT_OK
jnz short loc_B56F
test _key_det.lo, low INPUT_SHOT
jnz short loc_B56F
test _key_det.lo, low INPUT_DOWN
jz short loc_B546
call @se_choice_put$qiui pascal, [bp+var_2], 0
cmp [bp+var_2], 2
jnz short loc_B53B
mov [bp+var_2], 0
jmp short loc_B53E
; ---------------------------------------------------------------------------
loc_B53B:
inc [bp+var_2]
loc_B53E:
call @se_choice_put$qiui pascal, [bp+var_2], V_WHITE
loc_B546:
test _key_det.lo, low INPUT_UP
jz short loc_B503
call @se_choice_put$qiui pascal, [bp+var_2], 0
cmp [bp+var_2], 0
jnz short loc_B562
mov [bp+var_2], 2
jmp short loc_B565
; ---------------------------------------------------------------------------
loc_B562:
dec [bp+var_2]
loc_B565:
call @se_choice_put$qiui pascal, [bp+var_2], V_WHITE
jmp short loc_B503
; ---------------------------------------------------------------------------
loc_B56F:
mov _window_tiles.x, (400 / WINDOW_TILE_W)
mov _window_tiles.y, 1 + 9
call @rollup$qii pascal, (192 shl 16) or 128
mov _window_tiles.x, (160 / WINDOW_TILE_W)
mov _window_tiles.y, 1 + 3
call @rollup$qii pascal, ( 32 shl 16) or 128
les bx, _resident
mov al, byte ptr [bp+var_2]
mov es:[bx+resident_t.se_mode], al
leave
retn
sub_B489 endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
@ -288,11 +88,11 @@ _setup_menu proc near
call graph_copy_page pascal, 0
push 1
call palette_black_in
call sub_B36C
call @setup_bgm_menu$qv
push 1
call frame_delay
call graph_copy_page pascal, 0
call sub_B489
call @setup_se_menu$qv
push 1
call palette_black_out
call super_free
@ -1421,7 +1221,6 @@ include th02/snd/snd.inc
extern PI_PALETTE_APPLY:proc
extern PI_FREE:proc
extern _input_reset_sense_held:proc
extern INPUT_WAIT_FOR_CHANGE:proc
extern SND_DELAY_UNTIL_MEASURE:proc
extern FRAME_DELAY:proc
extern CDG_LOAD_SINGLE_NOALPHA:proc
@ -2015,7 +1814,6 @@ aOp_1 db 'op',0
; th02/hardware/input_sense[bss].asm
extern _key_det:word
extern _window_tiles:Point
include th04/zunsoft[bss].asm
db 104 dup(?)
include th02/op/music[bss].asm