[Decompilation] [th05] Player character selection menu

The TH04 one might have the same function structure, but the only thing
that's actually identical in both games is the picture darkening loop.

Part of P0119, funded by [Anonymous] and -Tom-.
This commit is contained in:
nmlgc 2020-09-19 19:18:59 +02:00
parent 5990ccd3b9
commit 3c27fbc3bd
15 changed files with 326 additions and 537 deletions

View File

@ -137,8 +137,8 @@ bin\th05\res_kso.com: th05\res_kso.cpp
$**
| masters.lib
bin\th05\op.exe: bin\th05\op.obj th05\op_01.cpp bin\hfliplut.obj
$(CC) $(CFLAGS) -ml -DGAME=5 -DBINARY='O' -nbin\th05\ -eOP.EXE @&&|
bin\th05\op.exe: bin\th05\op.obj th05\op_01.cpp th05\m_char.cpp bin\hfliplut.obj
$(CC) $(CFLAGS) -ml -DGAME=5 -DBINARY='O' -3 -Z -nbin\th05\ -eOP.EXE @&&|
$**
|

View File

@ -17,3 +17,5 @@
#define INPUT_MOVEMENT \
INPUT_UP | INPUT_DOWN | INPUT_LEFT | INPUT_RIGHT | \
INPUT_UP_LEFT | INPUT_UP_RIGHT | INPUT_DOWN_LEFT | INPUT_DOWN_RIGHT
extern int16_t key_det; /* ZUN symbol [MAGNet2010] */

21
th04/op/darken.cpp Normal file
View File

@ -0,0 +1,21 @@
// Darkens the [w]×[h] area starting at [vram_offset], by writing an
// alternating dot pattern in the given [col]. [x] and [y] store the currently
// iterated position.
#define darken(vram_offset, x, y, w, h, col) \
grcg_setcolor(GC_RMW, 1); \
dots32_t pattern = 0xAAAAAAAA; \
\
y = 0; \
while(y < h) { \
pattern = ((y & 1) == 0) ? 0xAAAAAAAA : 0x55555555; \
\
x = 0; \
while(x < (w / BYTE_DOTS)) { \
VRAM_PUT(B, vram_offset, pattern, 32); \
x += static_cast<vram_byte_amount_t>(sizeof(pattern)); \
vram_offset += static_cast<vram_offset_t>(sizeof(pattern)); \
} \
y++; \
vram_offset += (ROW_SIZE - (w / BYTE_DOTS)); \
} \
grcg_off();

6
th04/op/op.h Normal file
View File

@ -0,0 +1,6 @@
extern unsigned char cleared_with[PLAYCHAR_COUNT][RANK_COUNT];
// Shows the player character / shot type selection menu, writing the
// selection to [resident]. Returns whether to start the game (false) or
// return to the main menu (true).
bool16 near playchar_menu(void);

View File

@ -2,6 +2,15 @@
int pascal pi_free(int slot);
#undef pi_load_put_free
static inline void pi_load_put_free(int slot, const char *fn) {
pi_load(slot, fn);
pi_palette_apply(slot);
pi_put(0, 0, slot);
pi_free(0);
}
// Like pi_put() and pi_put_quarter(), but applying the mask with the given ID
// while blitting.
int pascal pi_put_mask(screen_x_t left, vram_y_t top, int slot, int mask_id);

View File

@ -1,3 +1,4 @@
public PI_FREE
func pi_free
@@slot = word ptr 4

View File

@ -1,3 +1,4 @@
public PI_LOAD
func pi_load
@@fn = dword ptr (cPtrSize + 2)
@@slot = word ptr (cPtrSize + 2 + dPtrSize)

View File

@ -1,3 +1,4 @@
public PI_PALETTE_APPLY
pi_palette_apply proc
@@slot = word ptr cPtrSize

View File

@ -1,4 +1,4 @@
; int __cdecl frame_delay(int frames)
public FRAME_DELAY
frame_delay proc
@@frames = word ptr (cPtrSize + 2)

265
th05/m_char.cpp Normal file
View File

@ -0,0 +1,265 @@
/* ReC98
* -----
* TH05 player character selection menu
*/
#pragma codeseg op_01_TEXT
extern "C" {
#include "ReC98.h"
#include "th01/ranks.h"
#include "th02/hardware/frmdelay.h"
#include "th04/formats/cdg.h"
#include "th04/bgimage.h"
#include "th04/score.h"
#include "th04/common.h"
#include "th05/chars.h"
#include "th04/op/op.h"
#include "th05/sprites/op_cdg.h"
#include "th05/snd/snd.h"
#include "th05/hardware/input.h"
#include "th05/formats/pi.h"
#include "th05/resident.hpp"
#pragma option -a2
static const pixel_t PIC_W = 224;
static const pixel_t PIC_H = 160;
static const pixel_t CLEARED_W = 64;
static const pixel_t CLEARED_H = 16;
static const pixel_t RAISE_W = 8;
static const pixel_t RAISE_H = 8;
static const screen_x_t REIMU_LEFT = 16;
static const vram_y_t REIMU_TOP = 48;
static const screen_x_t MARISA_LEFT = 272;
static const vram_y_t MARISA_TOP = 48;
static const screen_x_t MIMA_LEFT = 160;
static const vram_y_t MIMA_TOP = 224;
static const screen_x_t YUUKA_LEFT = 400;
static const vram_y_t YUUKA_TOP = 224;
unsigned char playchar_menu_sel;
static uint8_t unused_1;
unsigned char playchar_menu_rank;
static uint8_t unused_0[4];
bool extra_playable_with[PLAYCHAR_COUNT];
bool selectable_with[PLAYCHAR_COUNT];
#include "th04/op/darken.cpp"
void pascal near pic_darken(unsigned char playchar)
{
vram_offset_t vram_offset;
vram_byte_amount_t x;
pixel_t y;
switch(playchar) {
case PLAYCHAR_REIMU:
vram_offset = vram_offset_shift(REIMU_LEFT, REIMU_TOP);
break;
case PLAYCHAR_MARISA:
vram_offset = vram_offset_shift(MARISA_LEFT, MARISA_TOP);
break;
case PLAYCHAR_MIMA:
vram_offset = vram_offset_shift(MIMA_LEFT, MIMA_TOP);
break;
case PLAYCHAR_YUUKA:
vram_offset = vram_offset_shift(YUUKA_LEFT, YUUKA_TOP);
break;
}
darken(vram_offset, x, y, PIC_W, PIC_H, 1);
}
void pascal near pic_put(bool16 darkened)
{
screen_x_t pic_left;
vram_y_t pic_top;
screen_x_t cleared_left;
vram_y_t cleared_top;
#define set_coords_for(playchar) \
pic_left = playchar##_LEFT; \
pic_top = playchar##_TOP; \
cleared_left = (playchar##_LEFT + (PIC_W - CLEARED_W)); \
cleared_top = (playchar##_TOP + (PIC_H - CLEARED_H));
switch(playchar_menu_sel) {
case PLAYCHAR_REIMU: set_coords_for(REIMU); break;
case PLAYCHAR_MARISA: set_coords_for(MARISA); break;
case PLAYCHAR_MIMA: set_coords_for(MIMA); break;
case PLAYCHAR_YUUKA: set_coords_for(YUUKA); break;
}
#define pic_raised_left (pic_left - RAISE_W)
#define pic_raised_top (pic_top - RAISE_H)
if(!darkened) {
// Pic
if(selectable_with[playchar_menu_sel]) {
cdg_put_noalpha_8(
pic_raised_left, pic_raised_top, (CDG_PIC + playchar_menu_sel)
);
} else {
cdg_put_noalpha_8(
pic_raised_left, pic_raised_top, CDG_PIC_NOT_CLEARED
);
}
// Drop shadow
grcg_setcolor(GC_RMW, 1);
grcg_byteboxfill_x(
((pic_raised_left + PIC_W) / BYTE_DOTS),
pic_top,
((pic_left + PIC_W - 1) / BYTE_DOTS),
(pic_raised_top + PIC_H - 1)
);
grcg_byteboxfill_x(
(pic_left / BYTE_DOTS),
(pic_raised_top + PIC_H),
((pic_left + PIC_W - 1) / BYTE_DOTS),
(pic_top + PIC_H - 1)
);
grcg_off();
// "Cleared!!" sprite
if(cleared_with[playchar_menu_sel][playchar_menu_rank]) {
cdg_put_8(
(cleared_left - RAISE_W), (cleared_top - RAISE_H), CDG_CLEARED
);
}
} else {
// Raised area of the highlighted pic
bgimage_put_rect(pic_raised_left, pic_raised_top, PIC_W, RAISE_H);
bgimage_put_rect(pic_raised_left, pic_top, RAISE_W, PIC_H);
// Pic
if(selectable_with[playchar_menu_sel]) {
cdg_put_noalpha_8(pic_left, pic_top, (CDG_PIC + playchar_menu_sel));
} else {
cdg_put_noalpha_8(pic_left, pic_top, CDG_PIC_NOT_CLEARED);
}
// "Cleared!!" sprite
if(cleared_with[playchar_menu_sel][playchar_menu_rank]) {
cdg_put_8(cleared_left, cleared_top, CDG_CLEARED);
}
pic_darken(playchar_menu_sel);
}
#undef set_coords_for
#undef pic_raised_top
#undef pic_raised_left
}
void near playchar_menu_put_initial(void)
{
int selected = playchar_menu_sel;
palette_settone(0);
graph_accesspage(1);
pi_load_put_free(0, "slb1.pi");
graph_copy_page(0);
bgimage_snap();
graph_accesspage(1);
graph_showpage(0);
int i = PLAYCHAR_REIMU;
playchar_menu_sel = PLAYCHAR_REIMU;
while(i < PLAYCHAR_COUNT) {
pic_put(playchar_menu_sel != selected ? true : false);
i++;
playchar_menu_sel++;
}
playchar_menu_sel = selected;
graph_copy_page(0);
palette_black_in(1);
}
inline void near on_directional_input(uint8_t sel_xorval) {
snd_se_play_force(1);
graph_accesspage(1);
pic_put(true);
playchar_menu_sel ^= sel_xorval;
pic_put(false);
vsync_reset1();
frame_delay(1);
graph_showpage(1);
graph_copy_page(0);
vsync_reset1();
frame_delay(1);
graph_showpage(0);
}
bool16 near playchar_menu(void)
{
uint8_t input_prev;
int i;
for(i = PLAYCHAR_REIMU; i < PLAYCHAR_COUNT; i++) {
selectable_with[i] = extra_playable_with[i];
}
if(resident->stage == STAGE_EXTRA) {
playchar_menu_rank = RANK_EXTRA;
playchar_menu_sel = 0xFF;
for(i = PLAYCHAR_REIMU; i < PLAYCHAR_COUNT; i++) {
if(playchar_menu_sel == 0xFF) {
if(selectable_with[i]) {
playchar_menu_sel = i;
}
}
}
} else {
for(i = PLAYCHAR_REIMU; i < PLAYCHAR_COUNT; i++) {
selectable_with[i] = true;
}
playchar_menu_rank = resident->rank;
playchar_menu_sel = PLAYCHAR_REIMU;
}
playchar_menu_put_initial();
while(1) {
input_reset_sense_held();
if(input_prev == INPUT_NONE) {
if((key_det & INPUT_LEFT) || (key_det & INPUT_RIGHT)) {
on_directional_input(1); // 0<->1, 2<->3
}
if((key_det & INPUT_UP) || (key_det & INPUT_DOWN)) {
on_directional_input(2); // 0<->2, 1<->3
}
if((key_det & INPUT_OK) || (key_det & INPUT_SHOT)) {
if(selectable_with[playchar_menu_sel]) {
snd_se_play_force(11);
resident->playchar = playchar_menu_sel;
palette_black_out(1);
bgimage_free();
return false;
}
}
if(key_det & INPUT_CANCEL) {
palette_black_out(1);
bgimage_free();
return true;
}
input_prev = key_det;
} else {
if(key_det == INPUT_NONE) {
input_prev = INPUT_NONE;
}
}
frame_delay(1);
}
}
}

View File

@ -5,10 +5,11 @@
extern "C" {
#include "platform.h"
#include "ReC98.h"
#include "th01/ranks.h"
#include "th04/formats/scoredat.h"
#include "th05/chars.h"
#include "th04/op/op.h"
scoredat_section_t hi;
scoredat_section_t hi2;
@ -17,12 +18,6 @@ static uint8_t scoredat_unused;
unsigned char hiscore_rank;
unsigned char cleared_with[PLAYCHAR_COUNT][RANK_COUNT];
bool extra_unlocked;
static uint8_t unused_2;
unsigned char playchar_menu_sel;
static uint8_t unused_1;
unsigned char rank;
static uint8_t unused_0[4];
bool extra_playable_with[PLAYCHAR_COUNT];
bool selectable_with[PLAYCHAR_COUNT];
}

View File

@ -46,3 +46,5 @@ typedef struct {
score_lebcd_t stage_score[MAIN_STAGE_COUNT];
int32_t unused_3;
} resident_t;
extern resident_t *resident;

View File

@ -1,2 +1,4 @@
#include "th04/snd/snd.h"
// Gets the currently playing BGM measure, or -1 if BGM has been disabled.
int snd_bgm_measure(void);

7
th05/sprites/op_cdg.h Normal file
View File

@ -0,0 +1,7 @@
/// CDG slots for TH05's OP.EXE
typedef enum {
CDG_PIC = 40,
CDG_PIC_last = (CDG_PIC + PLAYCHAR_COUNT - 1),
CDG_CLEARED,
CDG_PIC_NOT_CLEARED
} op_cdg_slot_t;

View File

@ -171,7 +171,7 @@ start_game proc near
mov es:[bx+resident_t.credit_lives], al
mov al, es:[bx+resident_t.cfg_bombs]
mov es:[bx+resident_t.credit_bombs], al
call playchar_menu
call _playchar_menu
or ax, ax
jnz short loc_A443
xor si, si
@ -253,7 +253,7 @@ start_extra proc near
mov es:[bx+resident_t.stage], STAGE_EXTRA
mov es:[bx+resident_t.credit_lives], 3
mov es:[bx+resident_t.credit_bombs], 3
call playchar_menu
call _playchar_menu
or ax, ax
jnz short loc_A4CB
xor si, si
@ -2943,525 +2943,7 @@ loc_CE5D:
retn
scoredat_cleared_load endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
darken_pic proc near
var_6 = dword ptr -6
var_2 = word ptr -2
arg_0 = byte ptr 4
enter 6, 0
push si
push di
mov al, [bp+arg_0]
mov ah, 0
mov bx, ax
cmp bx, 3
ja short loc_CE90
add bx, bx
jmp cs:off_CEF7[bx]
loc_CE7E:
mov si, ( 48 * ROW_SIZE) + ( 16 / 8)
jmp short loc_CE90
; ---------------------------------------------------------------------------
loc_CE83:
mov si, ( 48 * ROW_SIZE) + (272 / 8)
jmp short loc_CE90
; ---------------------------------------------------------------------------
loc_CE88:
mov si, (224 * ROW_SIZE) + (160 / 8)
jmp short loc_CE90
; ---------------------------------------------------------------------------
loc_CE8D:
mov si, (224 * ROW_SIZE) + (400 / 8)
loc_CE90:
call grcg_setcolor pascal, (GC_RMW shl 16) + 1
mov [bp+var_6], 0AAAAAAAAh
xor di, di
jmp short loc_CEE5
; ---------------------------------------------------------------------------
loc_CEA7:
test di, 1
jnz short loc_CEB5
mov eax, 0AAAAAAAAh
jmp short loc_CEBB
; ---------------------------------------------------------------------------
loc_CEB5:
mov eax, 55555555h
loc_CEBB:
mov [bp+var_6], eax
mov [bp+var_2], 0
jmp short loc_CEDB
; ---------------------------------------------------------------------------
loc_CEC6:
les bx, _VRAM_PLANE_B
add bx, si
mov eax, [bp+var_6]
mov es:[bx], eax
add [bp+var_2], 4
add si, 4
loc_CEDB:
cmp [bp+var_2], (224 / 8)
jl short loc_CEC6
inc di
add si, ROW_SIZE - (224 / 8)
loc_CEE5:
cmp di, 160
jl short loc_CEA7
GRCG_OFF_CLOBBERING dx
pop di
pop si
leave
retn 2
darken_pic endp
; ---------------------------------------------------------------------------
off_CEF7 dw offset loc_CE7E
dw offset loc_CE83
dw offset loc_CE88
dw offset loc_CE8D
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
put_pic proc near
@@y = word ptr -4
@@x = word ptr -2
@@highlight = word ptr 4
enter 4, 0
push si
push di
mov al, _playchar_menu_sel
mov ah, 0
mov bx, ax
cmp bx, PLAYCHAR_COUNT - 1
ja short loc_CF59
add bx, bx
jmp cs:off_D08D[bx]
@@reimu:
mov si, 16
mov di, 48
mov [bp+@@x], 176
mov [bp+@@y], 192
jmp short loc_CF59
; ---------------------------------------------------------------------------
@@marisa:
mov si, 272
mov di, 48
mov [bp+@@x], 432
mov [bp+@@y], 192
jmp short loc_CF59
; ---------------------------------------------------------------------------
@@mima:
mov si, 160
mov di, 224
mov [bp+@@x], 320
jmp short loc_CF54
; ---------------------------------------------------------------------------
@@yuuka:
mov si, 400
mov di, 224
mov [bp+@@x], 560
loc_CF54:
mov [bp+@@y], 368
loc_CF59:
cmp [bp+@@highlight], 0
jnz loc_D012
mov al, _playchar_menu_sel
mov ah, 0
mov bx, ax
cmp _selectable_with[bx], 0
jz short loc_CF82
lea ax, [si-8]
push ax
lea ax, [di-8]
push ax
mov al, _playchar_menu_sel
mov ah, 0
add ax, 40
push ax
jmp short loc_CF8C
; ---------------------------------------------------------------------------
loc_CF82:
lea ax, [si-8]
push ax
lea ax, [di-8]
push ax
push 45
loc_CF8C:
call cdg_put_noalpha_8
call grcg_setcolor pascal, (GC_RMW shl 16) + 1
lea ax, [si+216]
mov bx, 8
cwd
idiv bx
push ax
push di
lea ax, [si+223]
cwd
idiv bx
push ax
lea ax, [di+151]
push ax
call grcg_byteboxfill_x
mov ax, si
mov bx, 8
cwd
idiv bx
push ax
lea ax, [di+152]
push ax
lea ax, [si+223]
cwd
idiv bx
push ax
lea ax, [di+159]
push ax
call grcg_byteboxfill_x
GRCG_OFF_CLOBBERING dx
mov al, _playchar_menu_sel
mov ah, 0
imul ax, RANK_COUNT
mov dl, _rank
mov dh, 0
add ax, dx
mov bx, ax
cmp _cleared_with[bx], 0
jz loc_D086
mov ax, [bp+@@x]
add ax, -8
push ax
mov ax, [bp+@@y]
add ax, -8
push ax
push 44
call cdg_put_8
jmp short loc_D086
; ---------------------------------------------------------------------------
loc_D012:
lea ax, [si-8]
push ax
lea ax, [di-8]
push ax
push (224 shl 16) or 8
call bgimage_put_rect
lea ax, [si-8]
call bgimage_put_rect pascal, ax, di, (8 shl 16) or 160
mov al, _playchar_menu_sel
mov ah, 0
mov bx, ax
cmp _selectable_with[bx], 0
jz short loc_D050
push si
push di
mov al, _playchar_menu_sel
mov ah, 0
add ax, 40
push ax
jmp short loc_D054
; ---------------------------------------------------------------------------
loc_D050:
push si
push di
push 45
loc_D054:
call cdg_put_noalpha_8
mov al, _playchar_menu_sel
mov ah, 0
imul ax, RANK_COUNT
mov dl, _rank
mov dh, 0
add ax, dx
mov bx, ax
cmp _cleared_with[bx], 0
jz short loc_D07F
call cdg_put_8 pascal, [bp+@@x], [bp+@@y], 44
loc_D07F:
call darken_pic pascal, word ptr _playchar_menu_sel
loc_D086:
pop di
pop si
leave
retn 2
db 0
off_D08D dw offset @@reimu
dw offset @@marisa
dw offset @@mima
dw offset @@yuuka
put_pic endp
; ---------------------------------------------------------------------------
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
playchar_menu_init proc near
@@i = word ptr -2
enter 2, 0
push si
mov al, _playchar_menu_sel
mov ah, 0
mov [bp+@@i], ax
mov PaletteTone, 0
call far ptr palette_show
graph_accesspage 1
call pi_load pascal, 0, ds, offset aSlb1_pi
call pi_palette_apply pascal, 0
call pi_put pascal, large 0, 0
call pi_free pascal, 0
call graph_copy_page pascal, 0
call bgimage_snap
graph_accesspage 1
graph_showpage 0
xor si, si
mov _playchar_menu_sel, PLAYCHAR_REIMU
jmp short loc_D111
; ---------------------------------------------------------------------------
loc_D0F7:
mov al, _playchar_menu_sel
mov ah, 0
cmp ax, [bp+@@i]
jz short loc_D106
mov ax, 1
jmp short loc_D108
; ---------------------------------------------------------------------------
loc_D106:
xor ax, ax
loc_D108:
push ax
call put_pic
inc si
inc _playchar_menu_sel
loc_D111:
cmp si, PLAYCHAR_COUNT
jl short loc_D0F7
mov al, byte ptr [bp+@@i]
mov _playchar_menu_sel, al
call graph_copy_page pascal, 0
push 1
call palette_black_in
pop si
leave
retn
playchar_menu_init endp
; =============== S U B R O U T I N E =======================================
; Attributes: bp-based frame
playchar_menu proc near
@@i = word ptr -4
@@input_locked = byte ptr -1
enter 4, 0
mov [bp+@@i], 0
jmp short loc_D146
; ---------------------------------------------------------------------------
loc_D138:
mov bx, [bp+@@i]
mov al, _extra_playable_with[bx]
mov _selectable_with[bx], al
inc [bp+@@i]
loc_D146:
cmp [bp+@@i], PLAYCHAR_COUNT
jl short loc_D138
les bx, _resident
cmp es:[bx+resident_t.stage], STAGE_EXTRA
jnz short @@not_extra
mov _rank, RANK_EXTRA
mov _playchar_menu_sel, -1
mov [bp+@@i], 0
jmp short loc_D182
; ---------------------------------------------------------------------------
loc_D168:
cmp _playchar_menu_sel, -1
jnz short loc_D17F
mov bx, [bp+@@i]
cmp _selectable_with[bx], 0
jz short loc_D17F
mov al, byte ptr [bp+@@i]
mov _playchar_menu_sel, al
loc_D17F:
inc [bp+@@i]
loc_D182:
cmp [bp+@@i], PLAYCHAR_COUNT
jl short loc_D168
jmp short loc_D1B2
; ---------------------------------------------------------------------------
@@not_extra:
mov [bp+@@i], 0
jmp short loc_D19C
; ---------------------------------------------------------------------------
loc_D191:
mov bx, [bp+@@i]
mov _selectable_with[bx], 1
inc [bp+@@i]
loc_D19C:
cmp [bp+@@i], PLAYCHAR_COUNT
jl short loc_D191
les bx, _resident
mov al, es:[bx+resident_t.rank]
mov _rank, al
mov _playchar_menu_sel, PLAYCHAR_REIMU
loc_D1B2:
call playchar_menu_init
loc_D1B5:
call _input_reset_sense_held
cmp [bp+@@input_locked], 0
jnz loc_D2EC
test _key_det.lo, low INPUT_LEFT
jnz short @@left_or_right_pressed
test _key_det.lo, low INPUT_RIGHT
jz short loc_D223
@@left_or_right_pressed:
call _snd_se_reset
call snd_se_play pascal, 1
call _snd_se_update
graph_accesspage 1
call put_pic pascal, 1
xor _playchar_menu_sel, 1 ; 0<->1 2<->3
call put_pic pascal, 0
mov vsync_Count1, 0
call frame_delay pascal, 1
graph_showpage 1
call graph_copy_page pascal, 0
mov vsync_Count1, 0
call frame_delay pascal, 1
graph_showpage 0
loc_D223:
test _key_det.lo, low INPUT_UP
jnz short @@up_or_down_pressed
test _key_det.lo, low INPUT_DOWN
jz short loc_D284
@@up_or_down_pressed:
call _snd_se_reset
call snd_se_play pascal, 1
call _snd_se_update
graph_accesspage 1
call put_pic pascal, 1
xor _playchar_menu_sel, 2 ; 0<->2 1<->3
call put_pic pascal, 0
mov vsync_Count1, 0
call frame_delay pascal, 1
graph_showpage 1
call graph_copy_page pascal, 0
mov vsync_Count1, 0
call frame_delay pascal, 1
graph_showpage 0
loc_D284:
test _key_det.hi, high INPUT_OK
jnz short @@z_pressed
test _key_det.lo, low INPUT_SHOT
jz short @@unable_to_select
@@z_pressed:
mov al, _playchar_menu_sel
mov ah, 0
mov bx, ax
cmp _selectable_with[bx], 0
jz short @@unable_to_select
call _snd_se_reset
call snd_se_play pascal, 11
call _snd_se_update
les bx, _resident
mov al, _playchar_menu_sel
mov es:[bx+resident_t.playchar], al
push 1
call palette_black_out
call bgimage_free
xor ax, ax
leave
retn
@@unable_to_select:
test _key_det.hi, high INPUT_CANCEL
jz short loc_D2E4
call palette_black_out pascal, 1
call bgimage_free
mov ax, 1
leave
retn
; ---------------------------------------------------------------------------
loc_D2E4:
mov al, _key_det.lo
mov [bp+@@input_locked], al
jmp short loc_D2F7
; ---------------------------------------------------------------------------
loc_D2EC:
cmp _key_det, INPUT_NONE
jnz short loc_D2F7
mov [bp+@@input_locked], 0
loc_D2F7:
call frame_delay pascal, 1
jmp loc_D1B5
; ---------------------------------------------------------------------------
leave
retn
playchar_menu endp
; ---------------------------------------------------------------------------
db 0
_playchar_menu procdesc near
op_01_TEXT ends
; ===========================================================================
@ -4181,8 +3663,6 @@ aOp1_pi_1 db 'op1.pi',0
aOp_1 db 'op',0
aScnum_bft db 'scnum.bft',0
aHi_m_bft db 'hi_m.bft',0
db 0
aSlb1_pi db 'slb1.pi',0
.data?
@ -4229,9 +3709,6 @@ musicroom_trackcount dw ?
extern _hiscore_rank:byte
extern _cleared_with:byte
extern _extra_unlocked:byte
extern _playchar_menu_sel:byte
extern _rank:byte
extern _extra_playable_with:byte
extern _selectable_with:byte
end