[Decompilation] [th01] Pause menu

Part of P0214, funded by Ember2528.
This commit is contained in:
nmlgc 2022-08-12 16:41:02 +02:00
parent 402bb38324
commit 191a3497d8
8 changed files with 208 additions and 223 deletions

View File

@ -35,6 +35,13 @@ void input_sense(bool16 reset_repeat);
// keyboard state.
void input_reset_sense(void);
// Resets just menu-related inputs.
inline void input_reset_menu_related(void) {
input_lr = INPUT_NONE;
input_shot = false;
input_ok = false;
}
#define input_func_flag(var, flag) { var |= flag; } else { var &= ~flag; }
#define input_onchange(prev_slot, cur_sensed, if_pressed) \

157
th01/main/hud/menu.cpp Normal file
View File

@ -0,0 +1,157 @@
#include "th01/math/clamp.hpp"
#include "th01/main/hud/menu.hpp"
#include "th01/shiftjis/hud.hpp"
// Pause menu
// ----------
// Not quite the center.
static const screen_x_t PAUSE_CENTER_X = (PLAYFIELD_CENTER_X - GLYPH_HALF_W);
inline screen_y_t pause_top(int line) {
return (PLAYFIELD_TOP + ((PLAYFIELD_H / 21) * 4) + (line * GLYPH_H));
}
void z_palette_settone_but_keep_white(int tone)
{
int col;
int comp;
for(col = 0; col < COLOR_COUNT; col++) {
if(col == V_WHITE) {
continue;
}
for(comp = 0; comp < COMPONENT_COUNT; comp++) {
z_Palettes[col].v[comp] = ((z_Palettes[col].v[comp]) * tone / 100);
// ZUN bloat: Already done by z_palette_set_all_show().
if(z_Palettes[col].v[comp] < 0x0) {
z_Palettes[col].v[comp] = 0x0;
}
if(z_Palettes[col].v[comp] > 0xF) {
z_Palettes[col].v[comp] = 0xF;
}
}
}
z_palette_set_all_show(z_Palettes);
}
inline void pause_cursor_unput(screen_x_t left) {
egc_copy_rect_1_to_0_16(
left, pause_top(1), shiftjis_w(PAUSE_CURSOR), GLYPH_H
);
}
inline void pause_cursor_put(screen_x_t left, const shiftjis_t* str) {
graph_putsa_fx(left, pause_top(1), V_WHITE, str);
}
inline void pause_str_put(screen_x_t left, int line, const shiftjis_t* str) {
graph_putsa_fx(left, pause_top(line), (V_WHITE | FX_WEIGHT_BLACK), str);
}
#define pause_select_loop(ret, sel_0_left, sel_1_left) { \
while(paused) { \
input_sense(false); \
/**
* ZUN bloat: Just replace with \
* \
* ((input_shot == true) && (input_ok == true)) \
* \
* No need to complicate input handling and abuse this variable. \
* (And yes, you *can* trigger this one instead of the `break` case \
* below. \
*/ \
if(player_is_hit == true) { \
return true; \
} \
if(input_lr == INPUT_LEFT) { \
pause_cursor_unput(sel_1_left); \
pause_cursor_put(sel_0_left, PAUSE_CURSOR); \
sel = 0; \
} \
if(input_lr == INPUT_RIGHT) { \
pause_cursor_unput(sel_0_left); \
pause_cursor_put(sel_1_left, PAUSE_CURSOR); \
sel = 1; \
} \
if(input_shot || input_ok) { \
break; \
} \
frame_delay(1); \
} \
}
bool16 pause_menu(void)
{
enum {
PAUSE_TITLE_W = shiftjis_w(PAUSE_TITLE),
PAUSE_CHOICES_W = shiftjis_w(PAUSE_CHOICES),
PAUSE_TITLE_LEFT = (PAUSE_CENTER_X - (PAUSE_TITLE_W / 2)),
PAUSE_CHOICES_LEFT = (PAUSE_CENTER_X - (PAUSE_CHOICES_W / 2)),
PAUSE_CHOICE_0_LEFT = PAUSE_CHOICES_LEFT,
PAUSE_CHOICE_1_LEFT = (
PAUSE_CHOICE_0_LEFT + shiftjis_w(PAUSE_CHOICE_0)
),
QUIT_TITLE_W = shiftjis_w(QUIT_TITLE),
QUIT_CHOICES_W = shiftjis_w(QUIT_CHOICES),
QUIT_TITLE_LEFT = (PAUSE_CENTER_X - (QUIT_TITLE_W / 2)),
QUIT_CHOICES_LEFT = (PAUSE_CENTER_X - (QUIT_CHOICES_W / 2)),
QUIT_CHOICE_0_LEFT = QUIT_CHOICES_LEFT,
QUIT_CHOICE_1_LEFT = (QUIT_CHOICE_0_LEFT + shiftjis_w(QUIT_CHOICE_0)),
TITLE_W = max_macro(PAUSE_TITLE_W, QUIT_TITLE_W),
OPTIONS_W = max_macro(PAUSE_CHOICES_W, QUIT_CHOICES_W),
MENU_W = max_macro(TITLE_W, OPTIONS_W),
};
int8_t sel = 0;
pause_str_put(PAUSE_TITLE_LEFT, 0, PAUSE_TITLE);
pause_str_put(PAUSE_CHOICES_LEFT, 1, PAUSE_CHOICES);
pause_cursor_put(PAUSE_CHOICE_0_LEFT, PAUSE_CURSOR_INITIAL);
z_palette_settone_but_keep_white(40);
input_reset_menu_related();
pause_select_loop(sel, PAUSE_CHOICE_0_LEFT, PAUSE_CHOICE_1_LEFT);
// ZUN bug: Wrong left coordinate. Thankfully doesn't matter due to that
// function's word alignment.
egc_copy_rect_1_to_0_16(
(PAUSE_TITLE_LEFT + 4), pause_top(0), shiftjis_w(PAUSE_TITLE), GLYPH_H
);
egc_copy_rect_1_to_0_16(
PAUSE_CHOICES_LEFT, pause_top(1), shiftjis_w(PAUSE_CHOICES), GLYPH_H
);
frame_delay(20);
input_reset_menu_related();
if((sel != 0) && paused) {
pause_str_put(QUIT_TITLE_LEFT, 0, QUIT_TITLE);
pause_str_put(QUIT_CHOICES_LEFT, 1, QUIT_CHOICES);
pause_cursor_put(QUIT_CHOICE_0_LEFT, PAUSE_CURSOR);
sel = 0;
pause_select_loop(sel, QUIT_CHOICE_0_LEFT, QUIT_CHOICE_1_LEFT);
if(sel != 0) {
resident_continue_use();
return true;
}
}
z_palette_set_all_show(stage_palette);
input_reset_sense();
// ZUN bug: Same as above.
egc_copy_rect_1_to_0_16(
((PAUSE_CENTER_X - (MENU_W / 2)) + 8),
pause_top(0),
MENU_W,
(pause_top(2) - pause_top(0))
);
return false;
}
// -----------

2
th01/main/hud/menu.hpp Normal file
View File

@ -0,0 +1,2 @@
// Shows the pause menu, and returns `true` if the player selected to quit.
bool16 pause_menu(void);

View File

@ -14,11 +14,14 @@
#include "master.hpp"
#include "pc98kbd.h"
#include "shiftjis.hpp"
#include "th01/common.h"
#include "th01/resident.hpp"
#include "th01/v_colors.hpp"
#include "th01/math/subpixel.hpp"
#include "th01/hardware/egc.h"
#include "th01/hardware/frmdelay.h"
#include "th01/hardware/graph.h"
#include "th01/hardware/grppsafx.h"
#include "th01/hardware/input.hpp"
#include "th01/hardware/palette.h"
#include "th01/hardware/text.h"
@ -295,3 +298,4 @@ void stage_entrance(int stage_id, const char* bg_fn, bool16 clear_vram_page_0)
#include "th01/main/stage/palette.cpp"
#include "th01/main/player/inv_spr.cpp"
#include "th01/main/player/orb.cpp"
#include "th01/main/hud/menu.cpp"

View File

@ -1,3 +1,7 @@
#define max_macro(a, b) ( \
(a > b) ? a : b \
)
// Yes, these are exactly what every tutorial presents as a bad example of C
// macros, especially if they are nested within each other.
// MODDERS: Turn into template functions.

View File

@ -54,7 +54,7 @@ typedef struct {
// of the current scene, without the boss stage
long bonus_per_stage[STAGES_PER_SCENE - 1];
int stage_id;
unsigned int stage_id;
unsigned long hiscore;
long score_highest; // among all continues
uint16_t point_value;
@ -64,3 +64,9 @@ extern long continues_total;
extern route_t route;
extern resident_t far *resident;
inline void resident_continue_use(void) {
resident->continues_total++;
continues_total++;
resident->continues_per_scene[resident->stage_id / STAGES_PER_SCENE]++;
}

25
th01/shiftjis/hud.hpp Normal file
View File

@ -0,0 +1,25 @@
// Pause menu
// ----------
#define PAUSE_TITLE ""
#define PAUSE_CHOICE_RESUME "再開"
#define PAUSE_CHOICE_QUIT "終了"
#define QUIT_TITLE "本当に終了しちゃうの?"
#define QUIT_CHOICE_NO "うそですぅ"
#define QUIT_CHOICE_YES "はいっ"
// ZUN bloat: Does this mean that this menu used to be shown in text RAM?
#define PAUSE_CURSOR_INITIAL "●      "
#define PAUSE_CURSOR "●"
// Leaving one fullwidth space for the cursor in front of each, and another
// one to right-pad the first option.
#define PAUSE_CHOICE_0 " " PAUSE_CHOICE_RESUME " "
#define PAUSE_CHOICE_1 " " PAUSE_CHOICE_QUIT
#define QUIT_CHOICE_0 " " QUIT_CHOICE_NO " "
#define QUIT_CHOICE_1 " " QUIT_CHOICE_YES
#define PAUSE_CHOICES PAUSE_CHOICE_0 PAUSE_CHOICE_1
#define QUIT_CHOICES QUIT_CHOICE_0 QUIT_CHOICE_1
// ----------

View File

@ -104,217 +104,7 @@ main_010_TEXT ends
main_012_TEXT segment byte public 'CODE' use16
extern @invincibility_sprites_update_and$qi:proc
extern @ORB_AND_PELLETS_AND_STAGE_UNPUT_$QI:proc
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_C8C7 proc far
arg_0 = word ptr 6
push bp
mov bp, sp
push si
push di
xor si, si
jmp short loc_C92D
; ---------------------------------------------------------------------------
loc_C8D0:
cmp si, 7
jz short loc_C92C
xor di, di
jmp short loc_C927
; ---------------------------------------------------------------------------
loc_C8D9:
mov bx, si
imul bx, 3
mov al, _z_Palettes[bx+di]
cbw
imul [bp+arg_0]
mov bx, 100
cwd
idiv bx
mov bx, si
imul bx, 3
mov _z_Palettes[bx+di], al
mov bx, si
imul bx, 3
mov al, _z_Palettes[bx+di]
cbw
or ax, ax
jge short loc_C90D
mov bx, si
imul bx, 3
mov byte ptr _z_Palettes[bx+di], 0
loc_C90D:
mov bx, si
imul bx, 3
mov al, _z_Palettes[bx+di]
cbw
cmp ax, 0Fh
jle short loc_C926
mov bx, si
imul bx, 3
mov byte ptr _z_Palettes[bx+di], 0Fh
loc_C926:
inc di
loc_C927:
cmp di, 3
jl short loc_C8D9
loc_C92C:
inc si
loc_C92D:
cmp si, 10h
jl short loc_C8D0
call @z_palette_set_all_show$qmx27%Palette$t14%RGB$tc$ii$16%% c, offset _z_Palettes, ds
pop di
pop si
pop bp
retf
sub_C8C7 endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
sub_C942 proc far
var_1 = byte ptr -1
enter 2, 0
mov [bp+var_1], 0
call @graph_putsa_fx$qiiinxuc c, 272, large ((7 or FX_WEIGHT_BLACK) shl 16) or 128, offset aVovVtvrvd, ds ; ""
call @graph_putsa_fx$qiiinxuc c, 256, large ((7 or FX_WEIGHT_BLACK) shl 16) or 144, offset aB@nKjb@b@pic, ds ; " 再開  終了"
call @graph_putsa_fx$qiiinxuc c, 256, large (7 shl 16) or 144, offset aBB@b@b@b@b@b@, ds ; "●      "
push 28h ; '('
call sub_C8C7
pop cx
mov _input_lr, 0
mov _input_shot, 0
mov _input_ok, 0
jmp loc_CA30
; ---------------------------------------------------------------------------
loc_C9A2:
call @input_sense$qi stdcall, 0
pop cx
cmp _player_is_hit, 1
jz loc_CB91
cmp _input_lr, INPUT_LEFT
jnz short loc_C9E6
call @egc_copy_rect_1_to_0_16$qiiii c, large (144 shl 16) or 320, large (16 shl 16) or 16
call @graph_putsa_fx$qiiinxuc c, 256, large (7 shl 16) or 144, offset aB, ds ; "●"
mov [bp+var_1], 0
loc_C9E6:
cmp _input_lr, INPUT_RIGHT
jnz short loc_CA1A
call @egc_copy_rect_1_to_0_16$qiiii c, large (144 shl 16) or 256, large (16 shl 16) or 16
call @graph_putsa_fx$qiiinxuc c, 320, large (7 shl 16) or 144, offset aB, ds ; "●"
mov [bp+var_1], 1
loc_CA1A:
cmp _input_shot, 0
jnz short loc_CA39
cmp _input_ok, 0
jnz short loc_CA39
push 1
call @frame_delay$qui
pop cx
loc_CA30:
cmp _paused, 0
jnz loc_C9A2
loc_CA39:
call @egc_copy_rect_1_to_0_16$qiiii c, large (128 shl 16) or 276, large (16 shl 16) or 80
call @egc_copy_rect_1_to_0_16$qiiii c, large (144 shl 16) or 256, large (16 shl 16) or 112
push 14h
call @frame_delay$qui
pop cx
mov _input_lr, 0
mov _input_shot, 0
mov _input_ok, 0
cmp [bp+var_1], 0
jz loc_CB96
cmp _paused, 0
jz loc_CB96
call @graph_putsa_fx$qiiinxuc c, 224, large ((7 or FX_WEIGHT_BLACK) shl 16) or 128, offset aCUcvPicVVVsvdv, ds ; "本当に終了しちゃうの?"
call @graph_putsa_fx$qiiinxuc c, 224, large ((7 or FX_WEIGHT_BLACK) shl 16) or 144, offset aB@vdvVVVgb@b@v, ds ; " うそですぅ  はいっ"
call @graph_putsa_fx$qiiinxuc c, 224, large (7 shl 16) or 144, offset aB, ds ; "●"
mov [bp+var_1], 0
jmp loc_CB5D
; ---------------------------------------------------------------------------
loc_CACF:
call @input_sense$qi stdcall, 0
pop cx
cmp _player_is_hit, 1
jz loc_CB91
cmp _input_lr, INPUT_LEFT
jnz short loc_CB13
call @egc_copy_rect_1_to_0_16$qiiii c, large (144 shl 16) or 336, large (16 shl 16) or 16
call @graph_putsa_fx$qiiinxuc c, 224, large (7 shl 16) or 144, offset aB, ds ; "●"
mov [bp+var_1], 0
loc_CB13:
cmp _input_lr, INPUT_RIGHT
jnz short loc_CB47
call @egc_copy_rect_1_to_0_16$qiiii c, large (144 shl 16) or 224, large (16 shl 16) or 16
call @graph_putsa_fx$qiiinxuc c, 336, large (7 shl 16) or 144, offset aB, ds ; "●"
mov [bp+var_1], 1
loc_CB47:
cmp _input_shot, 0
jnz short loc_CB66
cmp _input_ok, 0
jnz short loc_CB66
push 1
call @frame_delay$qui
pop cx
loc_CB5D:
cmp _paused, 0
jnz loc_CACF
loc_CB66:
cmp [bp+var_1], 0
jz short loc_CB96
les bx, _resident
inc es:[bx+reiidenconfig_t.continues_total]
inc _continues_total
mov ax, es:[bx+reiidenconfig_t.stage]
mov bx, 5
xor dx, dx
div bx
add ax, ax
mov bx, word ptr _resident
add bx, ax
inc es:[bx+reiidenconfig_t.continues_per_scene]
loc_CB91:
mov ax, 1
leave
retf
; ---------------------------------------------------------------------------
loc_CB96:
call @z_palette_set_all_show$qmx27%Palette$t14%RGB$tc$ii$16%% c, offset _stage_palette, ds
call @input_reset_sense$qv
call @egc_copy_rect_1_to_0_16$qiiii c, large (128 shl 16) or 232, large (32 shl 16) or 176
xor ax, ax
leave
retf
sub_C942 endp
extern @pause_menu$qv:proc
main_012_TEXT ends
main_013_TEXT segment byte public 'CODE' use16
@ -2137,7 +1927,7 @@ loc_DD6B:
call @orb_and_pellets_and_stage_unput_$qi stdcall, [bp+@@stage]
cmp _paused, 1
jnz short loc_DDF8
call sub_C942
call @pause_menu$qv
mov [bp+var_4], ax
loc_DDF8:
@ -2876,12 +2666,6 @@ main_38_TEXT ends
.data
aVovVtvrvd db '',0
aB@nKjb@b@pic db ' 再開  終了',0
aBB@b@b@b@b@b@ db '●      ',0
aB db '●',0
aCUcvPicVVVsvdv db '本当に終了しちゃうの?',0
aB@vdvVVVgb@b@v db ' うそですぅ  はいっ',0
aVgvpvovfvivovx db '    ',0
aVxvevub@b@B@ db '    ',0
aVmvpb@b@B@ db '     ',0
@ -3004,8 +2788,6 @@ include th01/hiscore/routes[data].asm
; char aOp[3]
aOp db 'op',0
INPUT_RIGHT = 01h
INPUT_LEFT = 02h
BOMB_DOUBLETAP_WINDOW = 20
OVX_4_LEFT = 1
@ -3055,7 +2837,6 @@ OVX_4_LEFT = 1
extern byte_34AD5:byte
extern byte_34ADF:byte
extern _z_Palettes:byte:(size rgb_t * COLOR_COUNT)
PTN_SLOT_COUNT = 8
extern _ptn_image_count:byte:PTN_SLOT_COUNT
@ -3227,7 +3008,6 @@ CObstacles ends
extern _resident:dword
extern _shootout_lasers:byte
extern _stage_palette:palette_t
extern _hud_bg:dword
extern _hud_bg_size:word
extern _stage_timer:word