mirror of https://github.com/nmlgc/ReC98.git
[C decompilation] [th02/op] Shot type selection
Oh, OK, so this is what the PC-98 GRCG is all about. You call grcg_setcolor(), and that puts the PC-98 hardware in some sort of "monochromatic mode". Then, you just write your pixels into any *single* one of the 4 VRAM bitplanes. This causes the hardware to automatically write to *all* bitplanes in such a way that the final palette index for each of the 8, 16, or 32 pixels you just wrote a 1 value to will actually end up to match the color you set earlier. Don't forget to call grcg_off() at the end though, or you can't draw any non-monochromatic graphics, heh.
This commit is contained in:
parent
cd33367b51
commit
1f514b5a6c
|
@ -37,5 +37,7 @@ bin\th01\reiiden.exe: bin\th01\reiiden.obj th01\main_16.c
|
|||
bin\th01\fuuin.exe: bin\th01\fuuin.obj th01\fuuin_13.c
|
||||
$(CC) $(CFLAGS) -ml -3 -nbin\th01\ -eFUUIN.EXE $**
|
||||
|
||||
bin\th02\op.exe: bin\th02\op.obj th02\op_03.c th02\op_06.c
|
||||
$(CC) $(CFLAGS) -ml -Z -DGAME=2 -nbin\th02\ -eOP.EXE $**
|
||||
bin\th02\op.exe: bin\th02\op.obj th02\op_03.c th02\op_05.c th02\op_06.c
|
||||
$(CC) $(CFLAGS) -ml -Z -DGAME=2 -nbin\th02\ -eOP.EXE @&&|
|
||||
$**
|
||||
|
|
||||
|
|
2
pc98.h
2
pc98.h
|
@ -24,4 +24,6 @@ extern char *VRAM_PLANE_E;
|
|||
for(p = 0; p < PLANE_SIZE; p += 4) { \
|
||||
*(long*)((dst) + p) = *(long*)((src) + p); \
|
||||
}
|
||||
|
||||
#define VRAM_OFFSET(x, y) ((x) >> 3) + (y << 6) + (y << 4)
|
||||
// -----------
|
||||
|
|
|
@ -0,0 +1,220 @@
|
|||
/* ReC98
|
||||
* -----
|
||||
* Code segment #5 of TH02's OP.EXE
|
||||
*/
|
||||
|
||||
#include <master.h>
|
||||
#include "th02\th02.h"
|
||||
|
||||
char sel = 1;
|
||||
|
||||
const char *DESC[SHOTTYPE_COUNT][3] = {
|
||||
" 陰陽玉の力を使わない ",
|
||||
" 広範囲でかつ機動力に ",
|
||||
" 強い高機動力タイプ ",
|
||||
|
||||
" 靈撃が優れている ",
|
||||
" バランスの取れた ",
|
||||
" 防御重視タイプ ",
|
||||
|
||||
" 陰陽玉の力で戦う ",
|
||||
" 攻撃力が優れている ",
|
||||
" 攻撃重視タイプ "
|
||||
};
|
||||
const char *CHOOSE = "靈夢の戦闘スタイルを、下の3つからえらんでね";
|
||||
const char *EXTRA_NOTE[] = {
|
||||
"注) エキストラステージでは、難易度、プレイヤー、ボム数は変更出来ません",
|
||||
" それぞれ、難易度EXTRA、プレイヤー3人、ボム1個となります "
|
||||
};
|
||||
const char *CLEARED = " ☆☆CLEARED☆☆ ";
|
||||
|
||||
char cleared_game_with[SHOTTYPE_COUNT];
|
||||
char cleared_extra_with[SHOTTYPE_COUNT];
|
||||
long unused[2];
|
||||
|
||||
void pascal graph_copy_region_from_1_to_0(int x, int y, int w, int h);
|
||||
|
||||
void copy_pic_back(int sel, int highlight)
|
||||
{
|
||||
int x, y;
|
||||
if(!highlight) {
|
||||
switch(sel) {
|
||||
case 0: x = 16; y = 128; break;
|
||||
case 1: x = 224; y = 224; break;
|
||||
case 2: x = 432; y = 128; break;
|
||||
}
|
||||
graph_copy_region_from_1_to_0(x, y, 16, 144);
|
||||
graph_copy_region_from_1_to_0(x, y, 192, 10);
|
||||
} else {
|
||||
switch(sel) {
|
||||
case 0: x = 208; y = 136; break;
|
||||
case 1: x = 416; y = 232; break;
|
||||
case 2: x = 624; y = 136; break;
|
||||
}
|
||||
graph_copy_region_from_1_to_0(x, y, 16, 144);
|
||||
switch(sel) {
|
||||
case 0: x = 24; y = 272; break;
|
||||
case 1: x = 232; y = 368; break;
|
||||
case 2: x = 440; y = 272; break;
|
||||
}
|
||||
graph_copy_region_from_1_to_0(x, y, 192, 8);
|
||||
}
|
||||
}
|
||||
|
||||
void darken_pic_at(int x, int y)
|
||||
{
|
||||
int row_p = VRAM_OFFSET(x, y);
|
||||
int row, col;
|
||||
|
||||
grcg_setcolor(GC_RMW, 0);
|
||||
for(row = 0; row < 144; row++, row_p += 640 / 8) {
|
||||
for(col = 0; col < 192 / 8; col += 2) {
|
||||
*(int*)(VRAM_PLANE_B + row_p + col) =
|
||||
row & 1 ? 0xAAAA : 0x5555
|
||||
;
|
||||
}
|
||||
}
|
||||
grcg_off();
|
||||
}
|
||||
|
||||
void draw_shottype_desc(int sel, int color)
|
||||
{
|
||||
int x, y;
|
||||
switch(sel) {
|
||||
case 0: x = 16; y = 296; break;
|
||||
case 1: x = 224; y = 136; break;
|
||||
case 2: x = 432; y = 296; break;
|
||||
}
|
||||
grcg_setcolor(GC_RMW, color);
|
||||
grcg_round_boxfill(x + 8, y + 8, x + 200, y + 72, 8);
|
||||
grcg_setcolor(GC_RMW, 0);
|
||||
grcg_round_boxfill(x, y, x + 192, y + 64, 8);
|
||||
grcg_off();
|
||||
|
||||
graph_putsa_fx(x + 8, y + 8 + 0, color | 0x20, DESC[sel][0]);
|
||||
graph_putsa_fx(x + 8, y + 8 + 16, color | 0x20, DESC[sel][1]);
|
||||
graph_putsa_fx(x + 8, y + 8 + 32, color | 0x20, DESC[sel][2]);
|
||||
}
|
||||
|
||||
void pascal draw_header(void)
|
||||
{
|
||||
grcg_setcolor(GC_RMW, 12); grcg_round_boxfill(136, 24, 520, 56, 8);
|
||||
grcg_setcolor(GC_RMW, 0); grcg_round_boxfill(128, 16, 512, 48, 8);
|
||||
grcg_off();
|
||||
|
||||
graph_putsa_fx(144, 24, 12 | 0x20, CHOOSE);
|
||||
if(mikoconfig->stage == 5) {
|
||||
grcg_setcolor(GC_RMW, 12); grcg_round_boxfill(24, 56, 632, 104, 8);
|
||||
grcg_setcolor(GC_RMW, 0); grcg_round_boxfill(16, 48, 624, 96, 8);
|
||||
grcg_off();
|
||||
|
||||
graph_putsa_fx(32, 56, 15 | 0x20, EXTRA_NOTE[0]);
|
||||
graph_putsa_fx(32, 72, 15 | 0x20, EXTRA_NOTE[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void pascal shottype_menu_init(void)
|
||||
{
|
||||
#define DRAW_CLEARED_FOR(mode) \
|
||||
if(cleared_##mode##_with[0]) { \
|
||||
graph_putsa_fx(16, 112, 15 | 0x20, CLEARED); \
|
||||
} \
|
||||
if(cleared_##mode##_with[1]) { \
|
||||
graph_putsa_fx(224, 112, 15 | 0x20, CLEARED); \
|
||||
} \
|
||||
if(cleared_##mode##_with[2]) { \
|
||||
graph_putsa_fx(432, 112, 15 | 0x20, CLEARED); \
|
||||
}
|
||||
|
||||
palette_black();
|
||||
graph_accesspage(0);
|
||||
pi_load_put_free(3, "TSELECT.pi");
|
||||
graph_copy_page(1);
|
||||
graph_accesspage(0);
|
||||
if(mikoconfig->stage != 5) {
|
||||
DRAW_CLEARED_FOR(game);
|
||||
} else {
|
||||
DRAW_CLEARED_FOR(extra);
|
||||
}
|
||||
pi_slot_put( 24, 136, 0);
|
||||
pi_slot_put(224, 224, 1);
|
||||
pi_slot_put(440, 136, 2);
|
||||
mikoconfig->shottype = 1;
|
||||
darken_pic_at( 24, 136);
|
||||
darken_pic_at(440, 136);
|
||||
|
||||
draw_shottype_desc(0, 7);
|
||||
draw_shottype_desc(1, 12);
|
||||
draw_shottype_desc(2, 7);
|
||||
|
||||
draw_header();
|
||||
palette_black_in(2);
|
||||
}
|
||||
|
||||
void pascal shottype_menu(void)
|
||||
{
|
||||
int input_locked = 0;
|
||||
int pic_x[] = { 16, 224, 432};
|
||||
int pic_y[] = {128, 224, 128};
|
||||
unsigned int input_delay = 0;
|
||||
shottype_menu_init();
|
||||
|
||||
#define DRAW_NEW_SEL() \
|
||||
frame_delay(1); copy_pic_back(sel, 1); \
|
||||
frame_delay(1); draw_shottype_desc(sel, 12); \
|
||||
frame_delay(1); pi_slot_put(pic_x[sel], pic_y[sel], sel);
|
||||
|
||||
do {
|
||||
input_sense();
|
||||
if(!input_locked) {
|
||||
if(input & INPUT_LEFT) {
|
||||
draw_shottype_desc(sel, 7);
|
||||
frame_delay(1);
|
||||
copy_pic_back(sel, 0);
|
||||
frame_delay(1);
|
||||
pi_slot_put(pic_x[sel] + 8, pic_y[sel] + 8, sel);
|
||||
frame_delay(1);
|
||||
darken_pic_at(pic_x[sel] + 8, pic_y[sel] + 8);
|
||||
|
||||
sel--;
|
||||
if(sel < 0) {
|
||||
sel = SHOTTYPE_COUNT - 1;
|
||||
}
|
||||
DRAW_NEW_SEL();
|
||||
}
|
||||
if(input & INPUT_RIGHT) {
|
||||
copy_pic_back(sel, 0);
|
||||
frame_delay(1);
|
||||
pi_slot_put(pic_x[sel] + 8, pic_y[sel] + 8, sel);
|
||||
frame_delay(1);
|
||||
draw_shottype_desc(sel, 7);
|
||||
frame_delay(1);
|
||||
darken_pic_at(pic_x[sel] + 8, pic_y[sel] + 8);
|
||||
|
||||
sel++;
|
||||
if(sel > SHOTTYPE_COUNT - 1) {
|
||||
sel = 0;
|
||||
}
|
||||
DRAW_NEW_SEL();
|
||||
}
|
||||
if(input & INPUT_SHOT || input & INPUT_OK) {
|
||||
mikoconfig->shottype = sel;
|
||||
break;
|
||||
}
|
||||
}
|
||||
frame_delay(1);
|
||||
input_locked = input;
|
||||
if(input_locked) {
|
||||
input_delay++;
|
||||
if(input_delay > 30) {
|
||||
input_locked = 0;
|
||||
}
|
||||
} else {
|
||||
input_delay = 0;
|
||||
}
|
||||
} while(1);
|
||||
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]);
|
||||
palette_black_out(1);
|
||||
}
|
|
@ -172,7 +172,7 @@ void pascal near music_flip(void)
|
|||
ps = 0; \
|
||||
for(y = 64; y < 80; y++) { \
|
||||
for(x = 160; x < 480; x += (4 * 8)) { \
|
||||
pd = (x >> 3) + (y * 64) + (y * 16); \
|
||||
pd = VRAM_OFFSET(x, y); \
|
||||
*(long*)(dst[PL_B] + (dp)) = *(long*)(src[PL_B] + (sp)); \
|
||||
*(long*)(dst[PL_R] + (dp)) = *(long*)(src[PL_R] + (sp)); \
|
||||
*(long*)(dst[PL_G] + (dp)) = *(long*)(src[PL_G] + (sp)); \
|
||||
|
@ -182,7 +182,7 @@ void pascal near music_flip(void)
|
|||
} \
|
||||
for(y = 80; y < 384; y++) { \
|
||||
for(x = 304; x < 624; x += (4 * 8)) { \
|
||||
pd = (x >> 3) + (y * 64) + (y * 16); \
|
||||
pd = VRAM_OFFSET(x, y); \
|
||||
*(long*)(dst[PL_B] + (dp)) = *(long*)(src[PL_B] + (sp)); \
|
||||
*(long*)(dst[PL_R] + (dp)) = *(long*)(src[PL_R] + (sp)); \
|
||||
*(long*)(dst[PL_G] + (dp)) = *(long*)(src[PL_G] + (sp)); \
|
||||
|
@ -246,7 +246,7 @@ void pascal musicroom(void)
|
|||
graph_clear();
|
||||
graph_accesspage(1);
|
||||
|
||||
pi_load_put_free("op3.pi");
|
||||
pi_load_put_free(0, "op3.pi");
|
||||
music_sel = track_playing;
|
||||
draw_tracks(music_sel);
|
||||
graph_copy_page(0);
|
||||
|
@ -334,7 +334,7 @@ controls:
|
|||
graph_accesspage(0);
|
||||
graph_clear();
|
||||
graph_accesspage(1);
|
||||
pi_load_put_free("op2.pi");
|
||||
pi_load_put_free(0, "op2.pi");
|
||||
palette_entry_rgb("op.rgb");
|
||||
palette_show();
|
||||
graph_copy_page(0);
|
||||
|
|
41
th02/th02.h
41
th02/th02.h
|
@ -15,11 +15,11 @@ void pi_slot_load(int slot, const char *fn);
|
|||
void pi_slot_palette_apply(int slot);
|
||||
void pi_slot_put(int x, int y, int slot);
|
||||
|
||||
#define pi_load_put_free(fn) \
|
||||
pi_slot_load(0, (fn)); \
|
||||
pi_slot_palette_apply(0); \
|
||||
pi_slot_put(0, 0, 0); \
|
||||
graph_pi_free(&pi_slot_headers[0], pi_slot_buffers[0]);
|
||||
#define pi_load_put_free(slot, fn) \
|
||||
pi_slot_load(slot, (fn)); \
|
||||
pi_slot_palette_apply(slot); \
|
||||
pi_slot_put(0, 0, slot); \
|
||||
graph_pi_free(&pi_slot_headers[slot], pi_slot_buffers[slot]);
|
||||
|
||||
// Hardware
|
||||
void graph_putsa_fx(int x, int y, int color, const char *str);
|
||||
|
@ -65,3 +65,34 @@ void snd_se_update(void);
|
|||
#define MUSIC_CMT_FILE "MUSIC.TXT"
|
||||
#define MUSIC_CMT_LINE_LEN 42
|
||||
#define MUSIC_CMT_LINE_COUNT 20
|
||||
|
||||
// Resident structure
|
||||
typedef struct {
|
||||
char id[11]; // = "MIKOConfig"
|
||||
char stage;
|
||||
char debug;
|
||||
long score;
|
||||
int continues_used;
|
||||
char rem_bombs;
|
||||
char rem_lives;
|
||||
char rank;
|
||||
char start_power;
|
||||
char bgm_mode;
|
||||
char start_bombs;
|
||||
char start_lives;
|
||||
long frame;
|
||||
int unused_1;
|
||||
char unused_2;
|
||||
char op_main_retval;
|
||||
char perf;
|
||||
char unused_3;
|
||||
char shottype;
|
||||
char demo_num;
|
||||
int skill;
|
||||
int unused_4;
|
||||
long score_highest;
|
||||
} mikoconfig_t;
|
||||
|
||||
extern mikoconfig_t *mikoconfig;
|
||||
|
||||
#define SHOTTYPE_COUNT 3
|
||||
|
|
922
th02_op.asm
922
th02_op.asm
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue