2020-05-10 17:05:43 +00:00
|
|
|
/* ReC98
|
|
|
|
* -----
|
2022-08-12 14:50:34 +00:00
|
|
|
* Code segment #1 of TH01's REIIDEN.EXE
|
2020-05-10 17:05:43 +00:00
|
|
|
*/
|
|
|
|
|
2022-08-12 18:26:05 +00:00
|
|
|
#include <process.h>
|
2021-08-25 20:22:31 +00:00
|
|
|
#include <stddef.h>
|
2021-09-09 09:20:07 +00:00
|
|
|
#include <stdio.h>
|
2021-11-03 12:32:53 +00:00
|
|
|
#include <string.h>
|
2021-01-14 20:02:16 +00:00
|
|
|
#include "platform.h"
|
2021-08-25 20:22:31 +00:00
|
|
|
#include "x86real.h"
|
2021-09-07 00:43:30 +00:00
|
|
|
#include "decomp.hpp"
|
2021-08-25 20:22:31 +00:00
|
|
|
#include "pc98.h"
|
2021-09-07 00:43:30 +00:00
|
|
|
#include "planar.h"
|
2021-01-14 20:02:16 +00:00
|
|
|
#include "master.hpp"
|
2021-01-10 14:46:26 +00:00
|
|
|
#include "pc98kbd.h"
|
2022-08-09 01:24:33 +00:00
|
|
|
#include "shiftjis.hpp"
|
2022-08-12 14:41:02 +00:00
|
|
|
#include "th01/common.h"
|
|
|
|
#include "th01/resident.hpp"
|
2022-08-12 02:27:17 +00:00
|
|
|
#include "th01/v_colors.hpp"
|
2022-08-12 18:26:05 +00:00
|
|
|
#include "th01/core/initexit.hpp"
|
2022-08-12 02:27:17 +00:00
|
|
|
#include "th01/math/subpixel.hpp"
|
|
|
|
#include "th01/hardware/egc.h"
|
2021-09-09 09:20:07 +00:00
|
|
|
#include "th01/hardware/frmdelay.h"
|
2021-11-03 12:32:53 +00:00
|
|
|
#include "th01/hardware/graph.h"
|
2022-08-12 14:41:02 +00:00
|
|
|
#include "th01/hardware/grppsafx.h"
|
2020-05-10 17:05:43 +00:00
|
|
|
#include "th01/hardware/input.hpp"
|
2021-11-03 12:32:53 +00:00
|
|
|
#include "th01/hardware/palette.h"
|
|
|
|
#include "th01/hardware/text.h"
|
|
|
|
#include "th01/hardware/tram_x16.hpp"
|
2022-08-12 00:35:50 +00:00
|
|
|
#include "th01/hardware/ztext.hpp"
|
2021-11-03 12:32:53 +00:00
|
|
|
#include "th01/snd/mdrv2.h"
|
|
|
|
#include "th01/formats/grp.h"
|
2021-11-01 16:32:20 +00:00
|
|
|
#include "th01/formats/pf.hpp"
|
|
|
|
#include "th01/formats/ptn.hpp"
|
2021-11-01 11:16:07 +00:00
|
|
|
#include "th01/formats/scoredat.hpp"
|
2020-05-10 17:05:43 +00:00
|
|
|
#include "th01/main/debug.hpp"
|
2021-11-03 12:32:53 +00:00
|
|
|
#include "th01/main/playfld.hpp"
|
|
|
|
#include "th01/main/vars.hpp"
|
|
|
|
#include "th01/formats/stagedat.hpp"
|
2021-11-01 16:32:20 +00:00
|
|
|
#include "th01/main/player/anim.hpp"
|
2021-09-12 14:04:24 +00:00
|
|
|
#include "th01/main/player/bomb.hpp"
|
2021-11-03 12:32:53 +00:00
|
|
|
#include "th01/main/player/player.hpp"
|
2021-11-01 16:32:20 +00:00
|
|
|
#include "th01/main/bullet/laser_s.hpp"
|
2022-08-12 02:27:17 +00:00
|
|
|
#include "th01/main/bullet/pellet.hpp"
|
|
|
|
#include "th01/main/stage/card.hpp"
|
2021-11-03 12:32:53 +00:00
|
|
|
#include "th01/main/stage/item.hpp"
|
2022-08-12 02:27:17 +00:00
|
|
|
#include "th01/main/stage/palette.hpp"
|
2021-11-01 16:32:20 +00:00
|
|
|
#include "th01/main/stage/stages.hpp"
|
2021-11-03 12:32:53 +00:00
|
|
|
#include "th01/main/stage/stageobj.hpp"
|
2021-11-01 16:32:20 +00:00
|
|
|
#include "th01/main/hud/hud.hpp"
|
2021-11-03 12:32:53 +00:00
|
|
|
#include "th01/shiftjis/entrance.hpp"
|
2021-11-01 16:32:20 +00:00
|
|
|
#include "th01/shiftjis/fns.hpp"
|
2020-05-10 17:05:43 +00:00
|
|
|
|
2022-08-12 00:35:50 +00:00
|
|
|
int8_t temporary_padding = 0;
|
2021-09-09 09:20:07 +00:00
|
|
|
|
2022-07-07 12:36:07 +00:00
|
|
|
inline void bomb_doubletap_update(uint8_t& pressed, uint8_t& other) {
|
2020-05-10 17:05:43 +00:00
|
|
|
if(bomb_doubletap_frames < BOMB_DOUBLETAP_WINDOW) {
|
|
|
|
pressed++;
|
|
|
|
} else {
|
|
|
|
bomb_doubletap_frames = 0;
|
|
|
|
pressed = 1;
|
|
|
|
other = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void input_sense(bool16 reset_repeat)
|
|
|
|
{
|
|
|
|
extern uint8_t input_prev[16];
|
|
|
|
int group_1, group_2, group_3, group_4;
|
|
|
|
|
|
|
|
if(reset_repeat == true) {
|
|
|
|
input_prev[0] = 0;
|
|
|
|
input_prev[1] = 0;
|
|
|
|
input_prev[2] = 0;
|
|
|
|
input_prev[3] = 0;
|
|
|
|
input_prev[8] = 0;
|
|
|
|
input_prev[9] = 0;
|
|
|
|
input_prev[10] = 0;
|
|
|
|
input_prev[11] = 0;
|
|
|
|
input_prev[4] = 0;
|
|
|
|
input_prev[5] = 0;
|
|
|
|
input_prev[6] = 0;
|
|
|
|
input_prev[7] = 0;
|
|
|
|
input_prev[12] = 0;
|
|
|
|
input_prev[13] = 0;
|
|
|
|
// Yup, no reset for 14 or 15.
|
|
|
|
input_bomb = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
#define bomb_doubletap_shot input_prev[12]
|
|
|
|
#define bomb_doubletap_strike input_prev[13]
|
|
|
|
|
|
|
|
group_1 = key_sense(7);
|
|
|
|
group_2 = key_sense(5);
|
|
|
|
group_3 = key_sense(8);
|
|
|
|
group_4 = key_sense(9);
|
|
|
|
group_1 |= key_sense(7);
|
|
|
|
group_2 |= key_sense(5);
|
|
|
|
group_3 |= key_sense(8);
|
|
|
|
group_4 |= key_sense(9);
|
|
|
|
|
|
|
|
input_onchange_bool_2(0, 8,
|
|
|
|
input_up, (group_1 & K7_ARROW_UP), (group_3 & K8_NUM_8)
|
|
|
|
);
|
|
|
|
input_onchange_bool_2(1, 9,
|
|
|
|
input_down, (group_1 & K7_ARROW_DOWN), (group_4 & K9_NUM_2)
|
|
|
|
);
|
|
|
|
input_onchange_flag_2(2, 10,
|
|
|
|
input_lr, INPUT_LEFT, (group_1 & K7_ARROW_LEFT), (group_3 & K8_NUM_4)
|
|
|
|
);
|
|
|
|
input_onchange_flag_2(3, 11,
|
|
|
|
input_lr, INPUT_RIGHT, (group_1 & K7_ARROW_RIGHT), (group_4 & K9_NUM_6)
|
|
|
|
);
|
|
|
|
input_onchange(4, (group_2 & K5_Z), {
|
|
|
|
input_shot = true;
|
|
|
|
bomb_doubletap_update(bomb_doubletap_shot, bomb_doubletap_strike);
|
|
|
|
} else {
|
|
|
|
input_shot = false;
|
|
|
|
});
|
|
|
|
input_onchange(5, (group_2 & K5_X), {
|
|
|
|
input_strike = true;
|
|
|
|
bomb_doubletap_update(bomb_doubletap_strike, bomb_doubletap_shot);
|
|
|
|
} else {
|
|
|
|
input_strike = false;
|
|
|
|
});
|
|
|
|
|
|
|
|
input_pause_ok_sense(6, 7, group_1, group_2);
|
|
|
|
|
|
|
|
if(
|
|
|
|
(bomb_doubletap_strike >= 2 && bomb_doubletap_shot >= 2) ||
|
2021-10-13 13:25:30 +00:00
|
|
|
((input_lr == INPUT_LEFT_RIGHT) && input_shot)
|
2020-05-10 17:05:43 +00:00
|
|
|
) {
|
|
|
|
input_bomb = true;
|
|
|
|
bomb_doubletap_strike = 0;
|
|
|
|
bomb_doubletap_shot = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(mode_test == true) {
|
|
|
|
group_1 = key_sense(6);
|
|
|
|
group_1 |= key_sense(6);
|
|
|
|
|
2022-08-12 21:43:22 +00:00
|
|
|
// Hilarious bug: debug_mem() itself renders a sub-screen in a blocking
|
2020-05-10 17:05:43 +00:00
|
|
|
// way, and senses input after a 3-frame delay, thus recursing back
|
2022-08-12 21:43:22 +00:00
|
|
|
// into this function. Therefore, debug_mem() will also be recursively
|
2020-05-10 17:05:43 +00:00
|
|
|
// called for every 3 frames you're holding this key.
|
|
|
|
// [input_prev[14]], which is supposed to prevent that, isn't set
|
2022-08-12 21:43:22 +00:00
|
|
|
// until debug_mem() returns, making this variable entirely pointless.
|
2020-05-10 17:05:43 +00:00
|
|
|
input_onchange(14, (group_1 & K6_ROLL_UP), {
|
|
|
|
input_mem_enter = true;
|
|
|
|
/* TODO: Replace with the decompiled call
|
2022-08-12 21:43:22 +00:00
|
|
|
* debug_mem();
|
2020-05-10 17:05:43 +00:00
|
|
|
* once that function is part of this translation unit */
|
2022-08-12 21:43:22 +00:00
|
|
|
_asm { nop; push cs; call near ptr debug_mem; }
|
2020-05-10 17:05:43 +00:00
|
|
|
} else {
|
|
|
|
input_mem_enter = false;
|
|
|
|
});
|
|
|
|
// And since this works as intended and only sets [input_mem_leave] to
|
|
|
|
// true on the first non-repeated key down event, you need to actually
|
2022-08-12 21:43:22 +00:00
|
|
|
// press and release this key once for every call to debug_mem() to get
|
|
|
|
// back into the game - even though debug_show_game() will make it
|
2020-05-10 17:05:43 +00:00
|
|
|
// appear as if you're already back in the game.
|
|
|
|
input_onchange(15, (group_1 & K6_ROLL_DOWN), {
|
|
|
|
input_mem_leave = true;
|
|
|
|
/* TODO: Replace with the decompiled call
|
2022-08-12 21:43:22 +00:00
|
|
|
* debug_show_game();
|
2020-05-10 17:05:43 +00:00
|
|
|
* once that function is part of this translation unit */
|
2022-08-12 21:43:22 +00:00
|
|
|
_asm { nop; push cs; call near ptr debug_show_game; }
|
2020-05-10 17:05:43 +00:00
|
|
|
} else {
|
|
|
|
input_mem_leave = false;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#include "th01/hardware/input_rs.cpp"
|
2021-08-25 20:22:31 +00:00
|
|
|
#include "th01/hardware/tram_x16.cpp"
|
2020-05-10 17:05:43 +00:00
|
|
|
|
2021-09-10 07:43:42 +00:00
|
|
|
// Largely copy-pasted from harryup_animate().
|
2021-09-09 09:20:07 +00:00
|
|
|
void pascal stage_num_animate(unsigned int stage_num)
|
|
|
|
{
|
|
|
|
utram_kanji_amount_t x;
|
|
|
|
upixel_t glyph_y;
|
|
|
|
TRAMx16Row<dots_t(GLYPH_HALF_W)> row;
|
|
|
|
TRAMCursor tram_cursor;
|
|
|
|
unsigned int stage_num_local = stage_num;
|
|
|
|
unsigned int i;
|
|
|
|
REGS in;
|
|
|
|
StupidBytewiseWrapperAround<pc98_glyph_ank_8x16_t> glyphs[7];
|
|
|
|
|
|
|
|
fontrom_get(in, glyphs[0].t, 'S');
|
|
|
|
fontrom_get(in, glyphs[1].t, 'T');
|
|
|
|
fontrom_get(in, glyphs[2].t, 'A');
|
|
|
|
fontrom_get(in, glyphs[3].t, 'G');
|
|
|
|
fontrom_get(in, glyphs[4].t, 'E');
|
|
|
|
// Yes, these are technically fontrom_get() calls as well, and were just
|
|
|
|
// inlined for code generation reasons.
|
|
|
|
int18h_14h(in, glyphs[5].t, (0x8000 + '0' + (stage_num_local / 10)));
|
|
|
|
int18h_14h(in, glyphs[6].t, (0x8000 + '0' + (stage_num_local % 10)));
|
|
|
|
|
|
|
|
tram_cursor.rewind_to_topleft();
|
|
|
|
tram_cursor.putkanji_for_5_rows(' ', TX_BLACK);
|
|
|
|
|
|
|
|
glyph_y = offsetof(pc98_glyph_ank_8x16_t, dots);
|
|
|
|
while(glyph_y <= (sizeof(pc98_glyph_ank_8x16_t) - 1)) {
|
|
|
|
for(i = 0; i < 5; i++) {
|
|
|
|
tram_x16_row_put_red(row, tram_cursor, x, glyphs[i].byte[glyph_y]);
|
|
|
|
}
|
|
|
|
// 5 halfwidth glyphs scaled a factor of 16 just happen to exactly fit
|
|
|
|
// into one TRAM row, so we're already at the next one here.
|
|
|
|
glyph_y++;
|
|
|
|
}
|
|
|
|
tram_cursor.putkanji_until_end(' ', TX_BLACK);
|
|
|
|
|
|
|
|
frame_delay(35);
|
|
|
|
|
|
|
|
tram_cursor.rewind_to_topleft();
|
|
|
|
tram_cursor.putkanji_for_5_rows(' ', TX_BLACK);
|
|
|
|
|
|
|
|
glyph_y = offsetof(pc98_glyph_ank_8x16_t, dots);
|
|
|
|
while(glyph_y <= (sizeof(pc98_glyph_ank_8x16_t) - 1)) {
|
|
|
|
tram_x16_put_center_margin(tram_cursor, x, TX_BLACK);
|
|
|
|
for(i = 5; i < 7; i++) {
|
|
|
|
tram_x16_row_put_red(row, tram_cursor, x, glyphs[i].byte[glyph_y]);
|
|
|
|
}
|
|
|
|
tram_x16_put_center_margin(tram_cursor, x, TX_BLACK);
|
|
|
|
glyph_y++;
|
|
|
|
}
|
|
|
|
tram_cursor.putkanji_until_end(' ', TX_BLACK);
|
|
|
|
|
|
|
|
frame_delay(35);
|
2022-08-12 00:35:50 +00:00
|
|
|
z_text_clear_inlined();
|
2021-09-09 09:20:07 +00:00
|
|
|
}
|
|
|
|
|
2021-11-01 16:32:20 +00:00
|
|
|
void load_and_init_stuff_used_in_all_stages(void)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
scoredat_load_hiscore();
|
2022-08-12 00:35:50 +00:00
|
|
|
hud_bg_load("mask.grf");
|
|
|
|
player_48x48.load("miko_ac.bos");
|
|
|
|
player_48x32.load("miko_ac2.bos");
|
2021-11-01 16:32:20 +00:00
|
|
|
ptn_load(PTN_SLOT_STG, PTN_STG_CARDFLIP_FN);
|
2022-08-12 00:35:50 +00:00
|
|
|
ptn_load(PTN_SLOT_MIKO, "miko.ptn");
|
2022-05-31 18:53:33 +00:00
|
|
|
ptn_new(PTN_SLOT_BG_HUD, ((PTN_BG_last - PTN_BG_first) + 1));
|
2022-06-30 01:54:14 +00:00
|
|
|
bomb_kuji_load();
|
2021-11-01 16:32:20 +00:00
|
|
|
shootout_lasers_init(i);
|
|
|
|
ptn_slot_stg_has_reduced_sprites = false;
|
|
|
|
}
|
2021-11-03 12:32:53 +00:00
|
|
|
|
|
|
|
void stage_entrance(int stage_id, const char* bg_fn, bool16 clear_vram_page_0)
|
|
|
|
{
|
|
|
|
int x;
|
|
|
|
int y;
|
|
|
|
|
|
|
|
if(first_stage_in_scene == true) {
|
2022-08-12 00:35:50 +00:00
|
|
|
text_fill_black(x, y);
|
|
|
|
text_color_reset();
|
2021-11-01 16:32:20 +00:00
|
|
|
|
2022-08-12 00:35:50 +00:00
|
|
|
if(strcmp(bg_fn, "empty.grf")) {
|
2021-11-03 12:32:53 +00:00
|
|
|
grp_put_palette_show(bg_fn);
|
|
|
|
}
|
2022-08-12 12:56:52 +00:00
|
|
|
stage_palette_set(z_Palettes);
|
2021-11-03 12:32:53 +00:00
|
|
|
graph_copy_accessed_page_to_other(); // 0 → 1, redundant
|
|
|
|
} else {
|
|
|
|
graph_accesspage_func(1);
|
|
|
|
graph_copy_accessed_page_to_other();
|
|
|
|
graph_accesspage_func(0);
|
2022-08-14 01:39:08 +00:00
|
|
|
player_put_default(); // redundant
|
2021-11-03 12:32:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
stageobjs_init_and_render(stage_id); // rendered to page 0
|
|
|
|
|
|
|
|
if(first_stage_in_scene == true) {
|
|
|
|
graph_copy_accessed_page_to_other(); // 0 → 1
|
|
|
|
} else if(first_stage_in_scene == false) {
|
|
|
|
// Yes, this entire function would not have been necessary.
|
|
|
|
stageobjs_copy_0_to_1(stage_id);
|
|
|
|
|
|
|
|
// :zunpet:
|
|
|
|
graph_accesspage_func(0);
|
|
|
|
graph_accesspage_func(1);
|
|
|
|
graph_accesspage_func(0);
|
2022-08-14 01:39:08 +00:00
|
|
|
player_put_default();
|
2021-11-03 12:32:53 +00:00
|
|
|
items_bomb_render();
|
|
|
|
items_point_render();
|
|
|
|
}
|
|
|
|
if(clear_vram_page_0) {
|
|
|
|
z_graph_clear();
|
|
|
|
}
|
|
|
|
if(
|
|
|
|
((stage_id % STAGES_PER_SCENE) == 0) ||
|
|
|
|
((stage_id % STAGES_PER_SCENE) == BOSS_STAGE)
|
|
|
|
) {
|
|
|
|
touhou_reiiden_animate();
|
|
|
|
}
|
|
|
|
stage_num_animate(stage_num);
|
2020-05-10 17:05:43 +00:00
|
|
|
}
|
2022-06-30 01:54:14 +00:00
|
|
|
|
|
|
|
#include "th01/main/player/bomb.cpp"
|
2022-08-12 12:56:52 +00:00
|
|
|
#include "th01/main/stage/palette.cpp"
|
|
|
|
#include "th01/main/player/inv_spr.cpp"
|
|
|
|
#include "th01/main/player/orb.cpp"
|
2022-08-12 14:41:02 +00:00
|
|
|
#include "th01/main/hud/menu.cpp"
|