mirror of https://github.com/nmlgc/ReC98.git
[C decompilation] Finish TH02's OP.EXE
This commit is contained in:
parent
c5f53d9cf1
commit
75b8765e44
|
@ -43,7 +43,7 @@ bin\th01\fuuin.exe: bin\th01\fuuin.obj th01\fuuin_06.c th01\fuuin_11.c th01\fuui
|
|||
$**
|
||||
|
|
||||
|
||||
bin\th02\op.exe: bin\th02\op.obj th02\op_02_1.c th02\op_02_2.c th02\op_03.c th02\op_04.c th02\op_05.c th02\op_06.c
|
||||
bin\th02\op.exe: th02\op_01.c bin\th02\op.obj th02\op_02_1.c th02\op_02_2.c th02\op_03.c th02\op_04.c th02\op_05.c th02\op_06.c
|
||||
$(CC) $(CFLAGS) -ml -Z -DGAME=2 -nbin\th02\ -eOP.EXE @&&|
|
||||
$**
|
||||
|
|
||||
|
|
8
ReC98.h
8
ReC98.h
|
@ -4,6 +4,14 @@
|
|||
*/
|
||||
|
||||
#include <master.h>
|
||||
#include <stddef.h>
|
||||
|
||||
// master.lib extensions
|
||||
// ---------------------
|
||||
#define palette_entry_rgb_show(fn) \
|
||||
palette_entry_rgb(fn); \
|
||||
palette_show();
|
||||
// ---------------------
|
||||
|
||||
// Macros
|
||||
// ------
|
||||
|
|
|
@ -10,10 +10,6 @@
|
|||
|
||||
#define frame_delay_2 frame_delay
|
||||
|
||||
extern char snd_active;
|
||||
extern char snd_interrupt_if_midi;
|
||||
extern char snd_fm_possible;
|
||||
|
||||
extern const char pf_fn[];
|
||||
|
||||
#include "th02/hardware/input.c"
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
* Code segment #3 of TH02's MAINE.EXE
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include "th02\th02.h"
|
||||
|
||||
char rank = RANK_NORMAL;
|
||||
|
@ -23,7 +22,7 @@ int pascal cfg_load(void)
|
|||
{
|
||||
int resident_sgm;
|
||||
|
||||
file_ropen("huuma.cfg");
|
||||
file_ropen(CFG_FN);
|
||||
file_seek(offsetof(huuma_cfg_t, resident_sgm), 0);
|
||||
file_read(&resident_sgm, sizeof(resident_sgm));
|
||||
file_close();
|
||||
|
|
|
@ -7,14 +7,11 @@
|
|||
|
||||
#include "th02\score.c"
|
||||
|
||||
extern char rank;
|
||||
extern long score;
|
||||
|
||||
long score_highest;
|
||||
score_file_t hi;
|
||||
|
||||
void pascal sub_B4B7(void);
|
||||
|
||||
void pascal score_defaults_set(void)
|
||||
{
|
||||
int i;
|
||||
|
|
|
@ -0,0 +1,670 @@
|
|||
/* ReC98
|
||||
* -----
|
||||
* Code segment #1 of TH02's OP.EXE
|
||||
*/
|
||||
|
||||
#include <process.h>
|
||||
#include "th02/th02.h"
|
||||
|
||||
#pragma option -d
|
||||
|
||||
typedef void pascal near putfunc_t(int sel, unsigned int atrb);
|
||||
|
||||
char menu_sel = 0;
|
||||
char in_option = 0;
|
||||
char quit = 0;
|
||||
char unused_1 = 0;
|
||||
|
||||
char snd_bgm_mode;
|
||||
static int unused_2;
|
||||
unsigned int idle_frames;
|
||||
unsigned char demo_num;
|
||||
unsigned int mikoconfig_sgm;
|
||||
putfunc_t near *putfunc;
|
||||
|
||||
// No, we don't want to put these two into th02.h. Apparently, declaring
|
||||
// variables with extern before definining them for real within the same
|
||||
// compilation unit causes Turbo C++ to emit *everything* in a different
|
||||
// order... really, I couldn't make this up.
|
||||
extern char extra_unlocked;
|
||||
extern unsigned int score_duration;
|
||||
|
||||
int game_init_op(void);
|
||||
void game_exit_to_dos(void);
|
||||
|
||||
void title_flash(void);
|
||||
void pascal score_menu(void);
|
||||
void pascal shottype_menu(void);
|
||||
void pascal musicroom(void);
|
||||
|
||||
int cfg_load(void)
|
||||
{
|
||||
huuma_cfg_t cfg;
|
||||
const char *cfg_fn = CFG_FN;
|
||||
|
||||
if(file_exist(cfg_fn)) {
|
||||
file_ropen(cfg_fn);
|
||||
file_read(&cfg, sizeof(cfg));
|
||||
rank = cfg.rank;
|
||||
snd_bgm_mode = cfg.bgm_mode;
|
||||
bombs = cfg.bombs;
|
||||
lives = cfg.lives;
|
||||
mikoconfig_sgm = cfg.resident_sgm;
|
||||
if(!mikoconfig_sgm) {
|
||||
return 1;
|
||||
}
|
||||
mikoconfig = MK_FP(mikoconfig_sgm, 0);
|
||||
mikoconfig->perf = cfg.perf;
|
||||
mikoconfig->debug = cfg.debug;
|
||||
file_close();
|
||||
|
||||
if(snd_bgm_mode == SND_BGM_OFF) {
|
||||
snd_fm_possible = 0;
|
||||
snd_active = 0;
|
||||
} else if(snd_bgm_mode == SND_BGM_FM) {
|
||||
snd_midi_active = 0;
|
||||
snd_determine_mode();
|
||||
} else {
|
||||
snd_midi_active = snd_midi_possible;
|
||||
snd_determine_mode();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cfg_save(void)
|
||||
{
|
||||
const char *cfg_fn = CFG_FN;
|
||||
huuma_cfg_t cfg;
|
||||
|
||||
cfg.debug = 0;
|
||||
cfg.rank = rank;
|
||||
cfg.bgm_mode = snd_bgm_mode;
|
||||
cfg.bombs = bombs;
|
||||
cfg.lives = lives;
|
||||
cfg.perf = mikoconfig->perf;
|
||||
|
||||
file_create(cfg_fn);
|
||||
file_write(&cfg, offsetof(huuma_cfg_t, resident_sgm));
|
||||
file_write(&mikoconfig_sgm, sizeof(mikoconfig_sgm));
|
||||
file_write(&cfg.debug, sizeof(cfg.debug));
|
||||
file_close();
|
||||
}
|
||||
|
||||
void text_wipe(void)
|
||||
{
|
||||
text_clear();
|
||||
text_fillca(' ', TX_BLACK | TX_REVERSE);
|
||||
}
|
||||
|
||||
void pascal near pi_load_put_free_to(const char near *fn, char page)
|
||||
{
|
||||
pi_slot_load(0, fn);
|
||||
graph_accesspage(page);
|
||||
pi_slot_palette_apply(0);
|
||||
pi_slot_put(0, 0, 0);
|
||||
graph_pi_free(&pi_slot_headers[0], pi_slot_buffers[0]);
|
||||
}
|
||||
|
||||
void op_animate(void)
|
||||
{
|
||||
int door_x, door_y; // Sony Vegas calls this a "Barn Door" transition.
|
||||
const char gbZUN[] = {gb_Z_, gb_U_, gb_N_, 0};
|
||||
|
||||
text_wipe();
|
||||
snd_load("huuma.efc", SND_LOAD_SE);
|
||||
pi_load_put_free_to("op2.pi", 1);
|
||||
pi_load_put_free_to("op.pi", 0);
|
||||
pi_slot_load(0, "opa.pi");
|
||||
pi_slot_load(1, "opb.pi");
|
||||
pi_slot_load(2, "opc.pi");
|
||||
palette_white();
|
||||
|
||||
for(door_x = 0; door_x < 40; door_x++) {
|
||||
for(door_y = 0; door_y < 25; door_y++) {
|
||||
text_putca(39 - door_x, door_y, ' ', TX_WHITE);
|
||||
text_putca(door_x + 40, door_y, ' ', TX_WHITE);
|
||||
}
|
||||
palette_settone(200 - (door_x * 2));
|
||||
frame_delay(1);
|
||||
}
|
||||
for(door_x = 40; door_x < 50; door_x++) {
|
||||
palette_settone(200 - (door_x * 2));
|
||||
frame_delay(1);
|
||||
}
|
||||
palette_100();
|
||||
|
||||
if(mikoconfig->demo_num == 0) {
|
||||
door_x = 0;
|
||||
if(snd_midi_possible) {
|
||||
door_x = snd_midi_active;
|
||||
snd_midi_active = 1;
|
||||
snd_load("op.m", SND_LOAD_SONG);
|
||||
}
|
||||
snd_midi_active = 0;
|
||||
snd_load("op.m", SND_LOAD_SONG);
|
||||
snd_midi_active = door_x;
|
||||
}
|
||||
|
||||
frame_delay(18);
|
||||
title_flash();
|
||||
|
||||
palette_white();
|
||||
graph_accesspage(1);
|
||||
|
||||
graph_gaiji_putc(548, 384, gs_COPYRIGHT, 0);
|
||||
graph_gaiji_puts(564, 384, 16, gbZUN, 0);
|
||||
graph_gaiji_putc(544, 380, gs_COPYRIGHT, 6);
|
||||
graph_gaiji_puts(560, 380, 16, gbZUN, 6);
|
||||
graph_copy_page(0);
|
||||
|
||||
if(mikoconfig->demo_num == 0) {
|
||||
snd_kaja_func(KAJA_SONG_PLAY, 0);
|
||||
}
|
||||
mikoconfig->demo_num = 0;
|
||||
palette_entry_rgb_show("op.rgb");
|
||||
palette_white_in(6);
|
||||
}
|
||||
|
||||
void pascal near start_init(void)
|
||||
{
|
||||
snd_se_reset();
|
||||
snd_se_play(13);
|
||||
snd_se_update();
|
||||
frame_delay(20);
|
||||
|
||||
mikoconfig->rem_lives = lives;
|
||||
mikoconfig->rem_bombs = bombs;
|
||||
mikoconfig->start_lives = lives;
|
||||
mikoconfig->start_bombs = bombs;
|
||||
mikoconfig->bgm_mode = snd_bgm_mode;
|
||||
mikoconfig->start_power = 0;
|
||||
mikoconfig->score = 0;
|
||||
mikoconfig->continues_used = 0;
|
||||
mikoconfig->unused_3 = 0;
|
||||
mikoconfig->unused_1 = 0;
|
||||
mikoconfig->demo_num = 0;
|
||||
mikoconfig->score_highest = 0;
|
||||
}
|
||||
|
||||
#define start_exec() \
|
||||
cfg_save(); \
|
||||
pi_slot_load(0, "ts1.pi"); \
|
||||
text_clear(); \
|
||||
shottype_menu(); \
|
||||
snd_kaja_func(KAJA_SONG_FADE, 15); \
|
||||
gaiji_restore(); \
|
||||
super_free(); \
|
||||
game_exit(); \
|
||||
if(mikoconfig->debug) { \
|
||||
execl("select", "select", 0, 0); \
|
||||
} else { \
|
||||
execl("main", "main", 0, 0); \
|
||||
}
|
||||
|
||||
void start_game(void)
|
||||
{
|
||||
start_init();
|
||||
mikoconfig->rank = rank;
|
||||
mikoconfig->stage = 0;
|
||||
start_exec();
|
||||
}
|
||||
|
||||
void start_demo(void)
|
||||
{
|
||||
mikoconfig->rem_lives = 2;
|
||||
mikoconfig->rem_bombs = 3;
|
||||
mikoconfig->start_lives = 2;
|
||||
mikoconfig->start_bombs = 3;
|
||||
mikoconfig->bgm_mode = snd_bgm_mode;
|
||||
mikoconfig->rank = RANK_NORMAL;
|
||||
mikoconfig->continues_used = 0;
|
||||
mikoconfig->unused_3 = 0;
|
||||
mikoconfig->demo_num = demo_num;
|
||||
mikoconfig->shottype = 0;
|
||||
cfg_save();
|
||||
text_clear();
|
||||
graph_pi_free(&pi_slot_headers[0], pi_slot_buffers[0]);
|
||||
graph_pi_free(&pi_slot_headers[1], pi_slot_buffers[1]);
|
||||
graph_pi_free(&pi_slot_headers[2], pi_slot_buffers[2]);
|
||||
gaiji_restore();
|
||||
super_free();
|
||||
game_exit();
|
||||
execl("main", "main", 0, 0);
|
||||
}
|
||||
|
||||
void start_extra(void)
|
||||
{
|
||||
start_init();
|
||||
mikoconfig->rank = RANK_EXTRA;
|
||||
mikoconfig->stage = 5;
|
||||
mikoconfig->rem_lives = 2;
|
||||
mikoconfig->rem_bombs = 1;
|
||||
mikoconfig->start_lives = 2;
|
||||
mikoconfig->start_bombs = 1;
|
||||
start_exec();
|
||||
}
|
||||
|
||||
#pragma option -d-
|
||||
|
||||
#include "th02/strings/ranks_c.c"
|
||||
const unsigned char gbHIT_KEY[] = {
|
||||
gb_H_, gb_I_, gb_T_, gb_SP, gb_K_, gb_E_, gb_Y_, 0
|
||||
};
|
||||
const unsigned char gb7SPACES[] = {
|
||||
gb_SP, gb_SP, gb_SP, gb_SP, gb_SP, gb_SP, gb_SP, 0
|
||||
};
|
||||
|
||||
const unsigned char gbSTART[] = {
|
||||
gb_S_,gb_T_,gb_A_,gb_R_,gb_T_, 0, 0, 0, 0, 0
|
||||
};
|
||||
const unsigned char gbEXTRA_START[] = {
|
||||
gb_E_,gb_X_,gb_T_,gb_R_,gb_A_,gb_SP,gb_S_,gb_T_,gb_A_,gb_R_,gb_T_, 0
|
||||
};
|
||||
const unsigned char gbHISCORE[] = {
|
||||
gb_H_,gb_I_,gb_S_,gb_C_,gb_O_,gb_R_,gb_E_, 0, 0, 0
|
||||
};
|
||||
const unsigned char gbOPTION[] = {
|
||||
gb_O_,gb_P_,gb_T_,gb_I_,gb_O_,gb_N_, 0, 0, 0, 0
|
||||
};
|
||||
const unsigned char gbQUIT[] = {
|
||||
gb_Q_,gb_U_,gb_I_,gb_T_, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
const unsigned char gbRANK[] = {
|
||||
gb_R_,gb_A_,gb_N_,gb_K_, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
const unsigned char gbPLAYER[] = {
|
||||
gb_P_,gb_L_,gb_A_,gb_Y_,gb_E_,gb_R_, 0, 0, 0, 0
|
||||
};
|
||||
const unsigned char gbMUSIC[] = {
|
||||
gb_M_,gb_U_,gb_S_,gb_I_,gb_C_, 0, 0, 0, 0, 0
|
||||
};
|
||||
const unsigned char gbBOMB[] = {
|
||||
gb_B_,gb_O_,gb_M_,gb_B_, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
const unsigned char gbMUSIC_MODE[] = {
|
||||
gb_M_,gb_U_,gb_S_,gb_I_,gb_C_,gb_SP,gb_M_,gb_O_,gb_D_,gb_E_, 0
|
||||
};
|
||||
const unsigned char gbRESET[] = {
|
||||
gb_R_,gb_E_,gb_S_,gb_E_,gb_T_, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
const unsigned char gsRANKS[4][3] = {
|
||||
gs_EA, gs_SY, 0,
|
||||
gs_NOR, gs_MAL, 0,
|
||||
gs_HA, gs_RD, 0,
|
||||
gs_LUN, gs_ATIC, 0
|
||||
};
|
||||
|
||||
const unsigned char gbcBGM_MODE[3][5] = {
|
||||
gb_O_, gb_F_, gb_F_, gb_SP, 0,
|
||||
gb_SP, gb_F_, gb_M_, gb_SP, 0,
|
||||
gb_M_, gb_I_, gb_D_, gb_I_, 0
|
||||
};
|
||||
|
||||
const char *PERF_TITLE = "‰‰<EFBFBD>o";
|
||||
const char *PERF_OPTIONS[2] = {"<EFBFBD>@’Ê<E28099>í ", "ˆê•”ŒyŒ¸"};
|
||||
|
||||
#pragma option -d
|
||||
|
||||
void pascal near main_put_shadow(void)
|
||||
{
|
||||
graph_gaiji_puts(284, 260, 16, gbSTART, 0);
|
||||
graph_gaiji_puts(236, 276, 16, gbEXTRA_START, 0);
|
||||
graph_gaiji_puts(268, 292, 16, gbHISCORE, 0);
|
||||
graph_gaiji_puts(276, 308, 16, gbOPTION, 0);
|
||||
graph_gaiji_puts(244, 324, 16, gbMUSIC_MODE, 0);
|
||||
graph_gaiji_puts(292, 340, 16, gbQUIT, 0);
|
||||
|
||||
graph_gaiji_puts(212, 372, 16, gbRANK, 0);
|
||||
graph_gaiji_puts(308, 372, 16, gbcRANKS[rank], 0);
|
||||
}
|
||||
|
||||
void pascal near main_put(int sel, unsigned int atrb)
|
||||
{
|
||||
if(sel == 0) {
|
||||
gaiji_putsa(35, 16, gbSTART, atrb);
|
||||
} else if(sel == 2) {
|
||||
gaiji_putsa(33, 18, gbHISCORE, atrb);
|
||||
} else if(sel == 3) {
|
||||
gaiji_putsa(34, 19, gbOPTION, atrb);
|
||||
} else if(sel == 4) {
|
||||
gaiji_putsa(30, 20, gbMUSIC_MODE, atrb);
|
||||
} else if(sel == 5) {
|
||||
gaiji_putsa(36, 21, gbQUIT, atrb);
|
||||
}
|
||||
if(sel == 1) {
|
||||
if(extra_unlocked) {
|
||||
gaiji_putsa(29, 17, gbEXTRA_START, atrb);
|
||||
} else {
|
||||
gaiji_putsa(29, 17, gbEXTRA_START, TX_BLUE);
|
||||
}
|
||||
}
|
||||
gaiji_putsa(26, 23, gbRANK, TX_GREEN);
|
||||
gaiji_putsa(38, 23, gbcRANKS[rank], TX_GREEN);
|
||||
}
|
||||
|
||||
void pascal near menu_sel_move(char sel_count, char direction)
|
||||
{
|
||||
putfunc(menu_sel, TX_YELLOW);
|
||||
menu_sel += direction;
|
||||
if(!in_option && !extra_unlocked && menu_sel == 1) {
|
||||
menu_sel += direction;
|
||||
}
|
||||
if(menu_sel < 0) {
|
||||
menu_sel = sel_count;
|
||||
}
|
||||
if(menu_sel > sel_count) {
|
||||
menu_sel = 0;
|
||||
}
|
||||
putfunc(menu_sel, TX_WHITE);
|
||||
}
|
||||
|
||||
void main_update_and_render(void)
|
||||
{
|
||||
static char input_allowed;
|
||||
static char initialized = 0;
|
||||
if(!initialized) {
|
||||
int i;
|
||||
input_allowed = 0;
|
||||
initialized = 1;
|
||||
text_clear();
|
||||
graph_showpage(1);
|
||||
graph_copy_page(0);
|
||||
main_put_shadow();
|
||||
graph_showpage(0);
|
||||
idle_frames = 0;
|
||||
for(i = 0; i < 6; i++) {
|
||||
main_put(i, menu_sel == i ? TX_WHITE : TX_YELLOW);
|
||||
}
|
||||
putfunc = main_put;
|
||||
}
|
||||
if(!input) {
|
||||
input_allowed = 1;
|
||||
}
|
||||
if(input_allowed) {
|
||||
if(input & INPUT_UP) {
|
||||
menu_sel_move(5, -1);
|
||||
}
|
||||
if(input & INPUT_DOWN) {
|
||||
menu_sel_move(5, 1);
|
||||
}
|
||||
if(input & INPUT_SHOT || input & INPUT_OK) {
|
||||
switch(menu_sel) {
|
||||
case 0:
|
||||
start_game();
|
||||
break;
|
||||
case 1:
|
||||
start_extra();
|
||||
break;
|
||||
case 2:
|
||||
score_duration = 2000;
|
||||
text_clear();
|
||||
score_menu();
|
||||
graph_accesspage(1);
|
||||
graph_showpage(0);
|
||||
pi_load_put_free(0, "op2.pi");
|
||||
palette_entry_rgb_show("op.rgb");
|
||||
graph_copy_page(0);
|
||||
graph_accesspage(0);
|
||||
initialized = 0;
|
||||
break;
|
||||
case 3:
|
||||
menu_sel = 0;
|
||||
in_option = 1;
|
||||
initialized = 0;
|
||||
break;
|
||||
case 4:
|
||||
text_clear();
|
||||
musicroom();
|
||||
initialized = 0;
|
||||
break;
|
||||
case 5:
|
||||
quit = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(input & INPUT_CANCEL) {
|
||||
quit = 1;
|
||||
}
|
||||
if(input) {
|
||||
input_allowed = 0;
|
||||
idle_frames = 0;
|
||||
}
|
||||
}
|
||||
if(idle_frames > 640) {
|
||||
start_demo();
|
||||
}
|
||||
}
|
||||
|
||||
void pascal near option_put_shadow(void)
|
||||
{
|
||||
graph_gaiji_puts(196, 260, 16, gbRANK, 0);
|
||||
graph_gaiji_puts(196, 276, 16, gbMUSIC, 0);
|
||||
graph_gaiji_puts(196, 292, 16, gbPLAYER, 0);
|
||||
graph_gaiji_puts(196, 308, 16, gbBOMB, 0);
|
||||
graph_putsa_fx(196, 324, 0, PERF_TITLE);
|
||||
graph_gaiji_puts(284, 340, 16, gbRESET, 0);
|
||||
graph_gaiji_puts(292, 372, 16, gbQUIT, 0);
|
||||
}
|
||||
|
||||
void pascal near option_put(int sel, unsigned int atrb)
|
||||
{
|
||||
if(sel == 0) {
|
||||
gaiji_putsa(24, 16, gbRANK, atrb);
|
||||
gaiji_putsa(42, 16, gbcRANKS[rank], atrb);
|
||||
graph_copy_rect_1_to_0(336, 260, 128, 16);
|
||||
graph_gaiji_puts(340, 260, 16, gbcRANKS[rank], 0);
|
||||
} else if(sel == 1) {
|
||||
gaiji_putsa(24, 17, gbMUSIC, atrb);
|
||||
gaiji_putsa(47, 17, gbcBGM_MODE[snd_bgm_mode], atrb);
|
||||
graph_copy_rect_1_to_0(376, 276, 64, 16);
|
||||
graph_gaiji_puts(380, 276, 16, gbcBGM_MODE[snd_bgm_mode], 0);
|
||||
} else if(sel == 2) {
|
||||
gaiji_putsa(24, 18, gbPLAYER, atrb);
|
||||
gaiji_putca(49, 18, lives + 1 + GB_DIGITS, atrb);
|
||||
graph_copy_rect_1_to_0(392, 292, 32, 16);
|
||||
graph_gaiji_putc(396, 292, lives + 1 + GB_DIGITS, 0);
|
||||
} else if(sel == 3) {
|
||||
gaiji_putsa(24, 19, gbBOMB, atrb);
|
||||
gaiji_putca(49, 19, bombs + GB_DIGITS, atrb);
|
||||
graph_copy_rect_1_to_0(392, 308, 32, 16);
|
||||
graph_gaiji_putc(396, 308, bombs + GB_DIGITS, 0);
|
||||
} else if(sel == 4) {
|
||||
text_putsa(24, 20, PERF_TITLE, atrb);
|
||||
text_putsa(45, 20, PERF_OPTIONS[mikoconfig->perf], atrb);
|
||||
graph_copy_rect_1_to_0(360, 324, 128, 16);
|
||||
graph_putsa_fx(364, 324, 0, PERF_OPTIONS[mikoconfig->perf]);
|
||||
} else if(sel == 5) {
|
||||
gaiji_putsa(35, 21, gbRESET, atrb);
|
||||
} else if(sel == 6) {
|
||||
gaiji_putsa(36, 23, gbQUIT, atrb);
|
||||
}
|
||||
}
|
||||
|
||||
void pascal near snd_bgm_restart(void)
|
||||
{
|
||||
if(snd_bgm_mode == SND_BGM_OFF) {
|
||||
snd_fm_possible = 0;
|
||||
snd_kaja_func(KAJA_SONG_STOP, 0);
|
||||
snd_active = 0;
|
||||
return;
|
||||
} else if(snd_bgm_mode == SND_BGM_FM) {
|
||||
snd_kaja_func(KAJA_SONG_STOP, 0);
|
||||
snd_midi_active = 0;
|
||||
snd_determine_mode();
|
||||
snd_kaja_func(KAJA_SONG_PLAY, 0);
|
||||
} else if(snd_bgm_mode == SND_BGM_MIDI) {
|
||||
snd_kaja_func(KAJA_SONG_STOP, 0);
|
||||
snd_midi_active = snd_midi_possible;
|
||||
snd_determine_mode();
|
||||
snd_kaja_func(KAJA_SONG_PLAY, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void option_update_and_render(void)
|
||||
{
|
||||
static char input_allowed = 0;
|
||||
static char initialized = 0;
|
||||
|
||||
#define OPTION_CHANGE(direction) \
|
||||
option_put(menu_sel, TX_YELLOW); \
|
||||
switch(menu_sel) { \
|
||||
case 0: \
|
||||
RING_##direction##(rank, RANK_LUNATIC); \
|
||||
break; \
|
||||
case 1: \
|
||||
RING_##direction##(snd_bgm_mode, SND_BGM_MIDI); \
|
||||
snd_bgm_restart(); \
|
||||
break; \
|
||||
case 2: \
|
||||
RING_##direction##(lives, 4); \
|
||||
break; \
|
||||
case 3: \
|
||||
RING_##direction##(bombs, 3); \
|
||||
break; \
|
||||
case 4: \
|
||||
mikoconfig->perf = 1 - mikoconfig->perf; \
|
||||
break; \
|
||||
} \
|
||||
option_put(menu_sel, TX_WHITE);
|
||||
|
||||
#define OPTION_QUIT \
|
||||
menu_sel = 3; \
|
||||
in_option = 0; \
|
||||
initialized = 0;
|
||||
|
||||
if(!initialized) {
|
||||
int i;
|
||||
input_allowed = 0;
|
||||
initialized = 1;
|
||||
text_clear();
|
||||
graph_showpage(1);
|
||||
graph_copy_page(0);
|
||||
option_put_shadow();
|
||||
graph_showpage(0);
|
||||
for(i = 0; i < 7; i++) {
|
||||
option_put(i, menu_sel == i ? TX_WHITE : TX_YELLOW);
|
||||
}
|
||||
putfunc = option_put;
|
||||
}
|
||||
if(!input) {
|
||||
input_allowed = 1;
|
||||
}
|
||||
if(input_allowed) {
|
||||
if(input & INPUT_UP) {
|
||||
menu_sel_move(6, -1);
|
||||
}
|
||||
if(input & INPUT_DOWN) {
|
||||
menu_sel_move(6, 1);
|
||||
}
|
||||
if(input & INPUT_RIGHT) {
|
||||
OPTION_CHANGE(INC);
|
||||
}
|
||||
if(input & INPUT_LEFT) {
|
||||
OPTION_CHANGE(DEC);
|
||||
}
|
||||
if(input & INPUT_SHOT || input & INPUT_OK) {
|
||||
switch(menu_sel) {
|
||||
case 5:
|
||||
rank = RANK_NORMAL;
|
||||
snd_bgm_mode = SND_BGM_FM;
|
||||
snd_kaja_func(KAJA_SONG_STOP, 0);
|
||||
snd_midi_active = 0;
|
||||
snd_determine_mode();
|
||||
snd_kaja_func(KAJA_SONG_PLAY ,0);
|
||||
lives = 2;
|
||||
bombs = 3;
|
||||
mikoconfig->unused_2 = 1;
|
||||
mikoconfig->perf = 0;
|
||||
option_put(0, TX_YELLOW);
|
||||
option_put(1, TX_YELLOW);
|
||||
option_put(2, TX_YELLOW);
|
||||
option_put(3, TX_YELLOW);
|
||||
option_put(4, TX_YELLOW);
|
||||
break;
|
||||
case 6:
|
||||
OPTION_QUIT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(input & INPUT_CANCEL) {
|
||||
OPTION_QUIT;
|
||||
}
|
||||
if(input) {
|
||||
input_allowed = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unsigned char ret;
|
||||
if(snd_pmd_resident()) {
|
||||
snd_mmd_resident();
|
||||
if(game_init_op()) {
|
||||
zun_error(ERROR_OUT_OF_MEMORY);
|
||||
return 1;
|
||||
}
|
||||
extra_unlocked = score_cleared_load();
|
||||
if(cfg_load() == 1) {
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
gaiji_backup();
|
||||
gaiji_entry_bfnt("MIKOFT.bft");
|
||||
if(mikoconfig->demo_num == 0) {
|
||||
demo_num = 1;
|
||||
snd_kaja_func(KAJA_SONG_STOP, 0);
|
||||
} else {
|
||||
demo_num = mikoconfig->demo_num + 1;
|
||||
if(demo_num > 3) {
|
||||
demo_num = 1;
|
||||
}
|
||||
score_duration = 350;
|
||||
score_menu();
|
||||
graph_showpage(0);
|
||||
graph_accesspage(0);
|
||||
}
|
||||
input = 0;
|
||||
|
||||
snd_active = snd_bgm_mode;
|
||||
if(!mikoconfig->demo_num && snd_midi_possible) {
|
||||
char midi_active = snd_midi_active;
|
||||
|
||||
snd_midi_active = 1;
|
||||
snd_load("gminit.m", SND_LOAD_SONG);
|
||||
snd_kaja_func(KAJA_SONG_PLAY, 0);
|
||||
snd_midi_active = midi_active;
|
||||
}
|
||||
|
||||
op_animate();
|
||||
pi_slot_load(2, "ts3.pi");
|
||||
pi_slot_load(1, "ts2.pi");
|
||||
input = 0;
|
||||
idle_frames = 0;
|
||||
|
||||
while(!quit) {
|
||||
input_sense();
|
||||
if(in_option == 0) {
|
||||
main_update_and_render();
|
||||
} else if(in_option == 1) {
|
||||
option_update_and_render();
|
||||
}
|
||||
mikoconfig->frame++;
|
||||
idle_frames++;
|
||||
frame_delay(1);
|
||||
}
|
||||
|
||||
ret = mikoconfig->op_main_retval;
|
||||
mikoconfig_sgm = 0;
|
||||
cfg_save();
|
||||
text_clear();
|
||||
graph_clear();
|
||||
game_exit_to_dos();
|
||||
gaiji_restore();
|
||||
return ret;
|
||||
}
|
10
th02/op_04.c
10
th02/op_04.c
|
@ -11,19 +11,20 @@ char rank = RANK_NORMAL;
|
|||
|
||||
#include "th02\score.c"
|
||||
|
||||
const unsigned char gbcRANK[4][8] = {
|
||||
const unsigned char gbcRANKS[4][8] = {
|
||||
gb_SP, gb_E_, gb_A_, gb_S_, gb_Y_, gb_SP, gb_SP, 0,
|
||||
gb_N_, gb_O_, gb_R_, gb_M_, gb_A_, gb_L_, gb_SP, 0,
|
||||
gb_SP, gb_H_, gb_A_, gb_R_, gb_D_, gb_SP, gb_SP, 0,
|
||||
gb_L_, gb_U_, gb_N_, gb_A_, gb_T_, gb_I_, gb_C_, 0,
|
||||
};
|
||||
|
||||
const char *SHOTTYPES[] = {"高機動", "防御", "攻撃"};
|
||||
int logo_step = 0;
|
||||
char need_op_h_bft = 1;
|
||||
|
||||
score_file_t hi;
|
||||
char extra_unlocked;
|
||||
unsigned score_duration;
|
||||
unsigned int score_duration;
|
||||
|
||||
#include "th02\scorelod.c"
|
||||
|
||||
|
@ -89,7 +90,7 @@ void pascal near scores_put(int place_to_highlight)
|
|||
unsigned atrb = TX_WHITE;
|
||||
int i;
|
||||
gaiji_putsa(22, 2, gbHI_SCORE, TX_GREEN);
|
||||
gaiji_putsa(40, 2, gbcRANK[rank], TX_GREEN);
|
||||
gaiji_putsa(40, 2, gbcRANKS[rank], TX_GREEN);
|
||||
text_putsa(
|
||||
8, 4,
|
||||
" お名前 得点 STAGE TYPE 日付",
|
||||
|
@ -156,8 +157,7 @@ void pascal score_menu(void)
|
|||
need_op_h_bft = 0;
|
||||
super_entry_bfnt("op_h.bft");
|
||||
}
|
||||
palette_entry_rgb("op_h.rgb");
|
||||
palette_show();
|
||||
palette_entry_rgb_show("op_h.rgb");
|
||||
grc_setclip(128, 96, 512, 304);
|
||||
grcg_setcolor(GC_RMW, 10);
|
||||
grcg_fill();
|
||||
|
|
|
@ -334,8 +334,7 @@ controls:
|
|||
graph_clear();
|
||||
graph_accesspage(1);
|
||||
pi_load_put_free(0, "op2.pi");
|
||||
palette_entry_rgb("op.rgb");
|
||||
palette_show();
|
||||
palette_entry_rgb_show("op.rgb");
|
||||
graph_copy_page(0);
|
||||
graph_accesspage(0);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,2 @@
|
|||
char snd_active = 0;
|
||||
char snd_unused = 0;
|
||||
|
||||
extern char snd_interrupt_if_midi;
|
||||
extern char snd_fm_possible;
|
||||
extern char snd_midi_active;
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
extern char snd_fm_possible;
|
||||
|
||||
extern unsigned char snd_se_playing;
|
||||
extern unsigned char snd_se_priorities[];
|
||||
extern unsigned char snd_se_priority_frames[];
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
// Moved to the right by one character compared to the one in op_04.c.
|
||||
static const unsigned char gbcRANKS[4][8] = {
|
||||
gb_SP, gb_SP, gb_E_, gb_A_, gb_S_, gb_Y_, gb_SP, 0,
|
||||
gb_SP, gb_N_, gb_O_, gb_R_, gb_M_, gb_A_, gb_L_, 0,
|
||||
gb_SP, gb_SP, gb_H_, gb_A_, gb_R_, gb_D_, gb_SP, 0,
|
||||
gb_L_, gb_U_, gb_N_, gb_A_, gb_T_, gb_I_, gb_C_, 0,
|
||||
};
|
50
th02/th02.h
50
th02/th02.h
|
@ -40,7 +40,7 @@ void pi_slot_put(int x, int y, int slot);
|
|||
pi_slot_put(0, 0, slot); \
|
||||
graph_pi_free(&pi_slot_headers[slot], pi_slot_buffers[slot]);
|
||||
|
||||
// ""東方封魔.録" in Shift-JIS
|
||||
// "東方封魔.録" in Shift-JIS
|
||||
#define PF_FN "\x93\x8C\x95\xFB\x95\x95\x96\x82\x2E\x98\x5E"
|
||||
#define PF_KEY 0x12
|
||||
// -------
|
||||
|
@ -55,9 +55,12 @@ void pi_slot_put(int x, int y, int slot);
|
|||
#define FX(color, weight, spacing) \
|
||||
(color | (weight & 3) << 4 | (spacing & 7) << 6)
|
||||
void graph_putsa_fx(int x, int y, int fx, const unsigned char *str);
|
||||
|
||||
void pascal graph_copy_rect_1_to_0(int x, int y, int w, int h);
|
||||
// -------
|
||||
|
||||
// Gaiji characters
|
||||
// ----------------
|
||||
/* ZUN messed up and swapped M and N in MIKOFT.BFT for both regular and bold
|
||||
* fonts. Therefore, other code shouldn't really use the straightforward
|
||||
* solution of just adding char literals to a defined start offset, as it may
|
||||
|
@ -124,8 +127,16 @@ typedef enum {
|
|||
gs_ARROW_LEFT, // ←
|
||||
gs_ARROW_RIGHT, // →
|
||||
gs_END, // "End"
|
||||
gs_ALL = 240 // "All"
|
||||
|
||||
// Unused 32x16 rank sprites
|
||||
gs_EA, gs_SY, // "Ea", "sy"
|
||||
gs_NOR, gs_MAL, // "Nor, "mal"
|
||||
gs_HA, gs_RD, // "Ha, "rd"
|
||||
gs_LUN, gs_ATIC, // "Lun", "atic"
|
||||
|
||||
gs_ALL, // "All"
|
||||
} gaiji_symbols_t;
|
||||
// ----------------
|
||||
|
||||
typedef enum {
|
||||
INPUT_UP = 0x1,
|
||||
|
@ -154,15 +165,29 @@ void key_delay(void);
|
|||
|
||||
// Sound
|
||||
// -----
|
||||
typedef enum {
|
||||
SND_BGM_OFF,
|
||||
SND_BGM_FM,
|
||||
SND_BGM_MIDI
|
||||
} snd_bgm_mode_t;
|
||||
|
||||
#include "libs\kaja\kaja.h"
|
||||
|
||||
extern char snd_midi_active;
|
||||
extern char snd_active;
|
||||
extern char snd_interrupt_if_midi;
|
||||
extern unsigned char snd_midi_active;
|
||||
extern char snd_midi_possible;
|
||||
extern char snd_fm_possible;
|
||||
|
||||
int snd_pmd_resident(void);
|
||||
int snd_mmd_resident(void);
|
||||
|
||||
int snd_determine_mode(void);
|
||||
int snd_kaja_interrupt(int ax);
|
||||
#define snd_kaja_func(func, param) snd_kaja_interrupt((func) << 8 | (param))
|
||||
|
||||
#define SND_LOAD_SONG (KAJA_GET_SONG_ADDRESS << 8)
|
||||
#define SND_LOAD_SE (PMD_GET_SE_ADDRESS << 8)
|
||||
|
||||
void snd_load(const char *fn, kaja_func_t func);
|
||||
|
||||
|
@ -177,10 +202,12 @@ void snd_se_update(void);
|
|||
#define MUSIC_CMT_LINE_COUNT 20
|
||||
|
||||
// Configuration file
|
||||
// ------------------
|
||||
#define CFG_FN "huuma.cfg"
|
||||
#pragma option -a1
|
||||
typedef struct {
|
||||
char rank;
|
||||
char music;
|
||||
char bgm_mode;
|
||||
char bombs;
|
||||
char lives;
|
||||
char perf;
|
||||
|
@ -188,8 +215,10 @@ typedef struct {
|
|||
char debug;
|
||||
} huuma_cfg_t;
|
||||
#pragma option -a2
|
||||
// ------------------
|
||||
|
||||
// Resident structure
|
||||
// ------------------
|
||||
typedef struct {
|
||||
char id[11]; // = "MIKOConfig"
|
||||
char stage;
|
||||
|
@ -206,8 +235,8 @@ typedef struct {
|
|||
long frame;
|
||||
int unused_1;
|
||||
char unused_2;
|
||||
char op_main_retval;
|
||||
char perf;
|
||||
unsigned char op_main_retval;
|
||||
unsigned char perf;
|
||||
char unused_3;
|
||||
char shottype;
|
||||
char demo_num;
|
||||
|
@ -218,9 +247,15 @@ typedef struct {
|
|||
|
||||
extern resident_t *mikoconfig;
|
||||
|
||||
extern char rank;
|
||||
extern char bombs;
|
||||
extern char lives;
|
||||
// ------------------
|
||||
|
||||
#define SHOTTYPE_COUNT 3
|
||||
|
||||
// Highscores
|
||||
// ---------
|
||||
#define SCORE_PLACES 10
|
||||
#define SCORE_NAME_LEN 6 /* excluding the terminating 0 */
|
||||
#define EXTRA_CLEAR_FLAGS {1, 2, 4}
|
||||
|
@ -263,6 +298,9 @@ typedef struct {
|
|||
extern char cleared_game_with[SHOTTYPE_COUNT];
|
||||
extern char cleared_extra_with[SHOTTYPE_COUNT];
|
||||
|
||||
int pascal score_cleared_load(void);
|
||||
// ---------
|
||||
|
||||
// Debugging
|
||||
// ---------
|
||||
// Calls ZUN's interrupt vector set up in ZUNINIT.COM to display an error
|
||||
|
|
1777
th02_op.asm
1777
th02_op.asm
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue