mirror of https://github.com/nmlgc/ReC98.git
744 lines
19 KiB
C++
744 lines
19 KiB
C++
#include "th01/hardware/egc.h"
|
||
#include "th01/hardware/grp2xscs.h"
|
||
#include "th01/hardware/input.hpp"
|
||
#include "th01/hardware/vsync.h"
|
||
#include "th01/score.h"
|
||
|
||
#define COL_SELECTED 3
|
||
#define COL_REGULAR 7
|
||
|
||
#define TITLE_LEFT 48
|
||
#define TITLE_TOP 0
|
||
static const screen_x_t TITLE_BACK_LEFT = 0;
|
||
static const screen_y_t TITLE_BACK_TOP = (RES_Y - GLYPH_H);
|
||
static const pixel_t TITLE_BACK_W = 288;
|
||
static const pixel_t TITLE_BACK_H = GLYPH_H;
|
||
static const screen_x_t TITLE_BACK_RIGHT = (TITLE_BACK_LEFT + TITLE_BACK_W);
|
||
static const screen_y_t TITLE_BACK_BOTTOM = (TITLE_BACK_TOP + TITLE_BACK_H);
|
||
|
||
/// Table
|
||
/// -----
|
||
#define TABLE_TOP 48
|
||
#define TABLE_ROW_H GLYPH_H
|
||
#define TABLE_BODY_TOP (TABLE_TOP + TABLE_ROW_H)
|
||
|
||
#define table_row_top(place) (TABLE_BODY_TOP + (place * TABLE_ROW_H))
|
||
|
||
// Recursively defining column positions \o/
|
||
inline screen_x_t table_left(int x_kanji) {
|
||
return 32 + (x_kanji * GLYPH_FULL_W);
|
||
}
|
||
|
||
inline screen_x_t table_place_left(int x_kanji) {
|
||
return table_left(x_kanji);
|
||
}
|
||
|
||
inline screen_x_t table_name_left(int x_kanji) {
|
||
return table_place_left(7 + x_kanji);
|
||
}
|
||
|
||
inline screen_x_t table_points_left(int x_kanji) {
|
||
return table_name_left(SCOREDAT_NAME_KANJI + 5 + x_kanji);
|
||
}
|
||
|
||
inline screen_x_t table_stage_route_left(int x_kanji) {
|
||
return table_points_left(SCORE_DIGITS + 3 + x_kanji);
|
||
}
|
||
|
||
inline screen_x_t table_stage_left(int x_kanji) {
|
||
return table_stage_route_left(1 + x_kanji);
|
||
}
|
||
|
||
// Code generation actually prohibits this from being a Point!
|
||
extern screen_x_t entered_name_left;
|
||
extern screen_y_t entered_name_top;
|
||
/// -----
|
||
|
||
/// Alphabet
|
||
/// --------
|
||
#define ALPHABET_TOP 240
|
||
#define MARGIN_W 32
|
||
#define KANJI_PADDING_X 16
|
||
#define KANJI_PADDING_Y 8
|
||
|
||
#define KANJI_PADDED_W (GLYPH_FULL_W + KANJI_PADDING_X)
|
||
#define KANJI_PADDED_H (GLYPH_H + KANJI_PADDING_Y)
|
||
|
||
#define KANJI_PER_ROW \
|
||
((RES_X - (MARGIN_W * 2)) / KANJI_PADDED_W)
|
||
|
||
#define relative_top(row) \
|
||
((row) * KANJI_PADDED_H)
|
||
|
||
inline pixel_t relative_top_for(int kanji_id)
|
||
{
|
||
return relative_top(kanji_id / KANJI_PER_ROW);
|
||
}
|
||
|
||
inline int row_ceil(int count)
|
||
{
|
||
return ((count + (KANJI_PER_ROW - 1)) / KANJI_PER_ROW);
|
||
}
|
||
|
||
inline pixel_t left_for(int kanji_id)
|
||
{
|
||
return (((kanji_id % KANJI_PER_ROW) * KANJI_PADDED_W) + MARGIN_W);
|
||
}
|
||
|
||
#define alphabet_putca_fx(top_for_0, i, fx, fmt_instance, kanji) \
|
||
graph_putkanji_fx( \
|
||
left_for(i), (top_for_0 + relative_top_for(i)), fx, fmt_instance, kanji \
|
||
);
|
||
|
||
#define alphabet_putsa_fx(top_for_0, i, fx, str) \
|
||
extern const char str[]; \
|
||
graph_printf_fx(left_for(i), (top_for_0 + relative_top_for(i)), fx, str);
|
||
|
||
#define A_TO_Z_COUNT 26
|
||
#define NUM_COUNT 10
|
||
// TODO: Should be derived via `sizeof()` once the array is declared here.
|
||
#define SYM_COUNT 18
|
||
extern const uint16_t ALPHABET_SYMS[];
|
||
|
||
// Rows
|
||
#define LOWER_TOP (ALPHABET_TOP)
|
||
#define LOWER2_TOP (LOWER_TOP + relative_top(1))
|
||
#define UPPER_TOP (LOWER_TOP + relative_top(row_ceil(A_TO_Z_COUNT)))
|
||
#define UPPER2_TOP (UPPER_TOP + relative_top(1))
|
||
#define SYM_TOP (UPPER_TOP + relative_top(row_ceil(A_TO_Z_COUNT)))
|
||
#define NUM_TOP (SYM_TOP + relative_top(row_ceil(SYM_COUNT)))
|
||
|
||
// Columns
|
||
#define A_TO_Z_2_END_LEFT left_for(A_TO_Z_COUNT - KANJI_PER_ROW)
|
||
#define SPACE_LEFT left_for(NUM_COUNT)
|
||
#define LEFT_COLUMN (KANJI_PER_ROW - 3)
|
||
#define LEFT_LEFT left_for(LEFT_COLUMN + 0)
|
||
#define RIGHT_LEFT left_for(LEFT_COLUMN + 1)
|
||
#define ENTER_LEFT left_for(LEFT_COLUMN + 2)
|
||
|
||
inline uint16_t kanji_swap(uint16_t kanji)
|
||
{
|
||
return (kanji << 8) | (kanji >> 8);
|
||
}
|
||
|
||
inline unsigned char kanji_hi(int16_t kanji)
|
||
{
|
||
return (kanji >> 8);
|
||
}
|
||
|
||
inline unsigned char kanji_lo(int16_t kanji)
|
||
{
|
||
return (kanji & 0xFF);
|
||
}
|
||
/// --------
|
||
|
||
void alphabet_put_initial()
|
||
{
|
||
int16_t col_and_fx = (COL_REGULAR | FX_WEIGHT_BOLD);
|
||
uint16_t kanji;
|
||
int i;
|
||
#if (BINARY == 'M')
|
||
char kanji_str[3];
|
||
#endif
|
||
|
||
kanji = kanji_swap('<EFBFBD><EFBFBD>');
|
||
for(i = 1; i < A_TO_Z_COUNT; i++) {
|
||
alphabet_putca_fx(LOWER_TOP, i, col_and_fx, 0, kanji);
|
||
kanji++;
|
||
}
|
||
extern const char ALPHABET_A[];
|
||
graph_putsa_fx(
|
||
MARGIN_W,
|
||
LOWER_TOP,
|
||
(COL_SELECTED | FX_WEIGHT_BOLD | FX_REVERSE),
|
||
ALPHABET_A
|
||
);
|
||
|
||
kanji = kanji_swap('<EFBFBD>`');
|
||
for(i = 0; i < A_TO_Z_COUNT; i++) {
|
||
alphabet_putca_fx(UPPER_TOP, i, col_and_fx, 1, kanji);
|
||
kanji++;
|
||
}
|
||
|
||
for(i = 0; i < SYM_COUNT; i++) {
|
||
kanji = ALPHABET_SYMS[i];
|
||
alphabet_putca_fx(SYM_TOP, i, col_and_fx, 2, kanji);
|
||
}
|
||
|
||
kanji = kanji_swap('<EFBFBD>O');
|
||
for(i = 0; i < NUM_COUNT; i++) {
|
||
alphabet_putca_fx(NUM_TOP, i, col_and_fx, 3, kanji);
|
||
kanji++;
|
||
}
|
||
alphabet_putsa_fx(NUM_TOP, i, col_and_fx, ALPHABET_SPACE); i = LEFT_COLUMN;
|
||
alphabet_putsa_fx(NUM_TOP, i, col_and_fx, ALPHABET_LEFT); i++;
|
||
alphabet_putsa_fx(NUM_TOP, i, col_and_fx, ALPHABET_RIGHT); i++;
|
||
alphabet_putsa_fx(NUM_TOP, i, col_and_fx, ALPHABET_ENTER); i++;
|
||
}
|
||
|
||
inline void header_cell_put(screen_x_t left, const char str[])
|
||
{
|
||
graph_putsa_fx(left, TABLE_TOP, (COL_SELECTED | FX_WEIGHT_BLACK), str);
|
||
}
|
||
|
||
#define place_cell_put(top, col_and_fx, str) \
|
||
graph_putsa_fx(table_place_left(0), top, col_and_fx, str)
|
||
|
||
void regist_put_initial(
|
||
int entered_place,
|
||
long entered_points,
|
||
int entered_stage,
|
||
const char entered_route[SCOREDAT_ROUTE_LEN + 1],
|
||
const scoredat_name_z_t names_z[SCOREDAT_PLACES]
|
||
)
|
||
{
|
||
struct hack {
|
||
unsigned char byte[SCOREDAT_NAME_BYTES + 1];
|
||
};
|
||
extern const hack REGIST_NAME_BLANK;
|
||
extern const char REGIST_HEADER_PLACE[];
|
||
extern const char REGIST_HEADER_NAME[];
|
||
extern const char REGIST_HEADER_POINTS[];
|
||
extern const char REGIST_HEADER_STAGE_ROUTE[];
|
||
extern const char REGIST_PLACE_0[];
|
||
extern const char REGIST_PLACE_1[];
|
||
extern const char REGIST_PLACE_2[];
|
||
extern const char REGIST_PLACE_3[];
|
||
extern const char REGIST_PLACE_4[];
|
||
extern const char REGIST_PLACE_5[];
|
||
extern const char REGIST_PLACE_6[];
|
||
extern const char REGIST_PLACE_7[];
|
||
extern const char REGIST_PLACE_8[];
|
||
extern const char REGIST_PLACE_9[];
|
||
extern const char REGIST_STAGE_MAKAI[];
|
||
extern const char REGIST_STAGE_JIGOKU[];
|
||
extern const char REGIST_STAGE_ROUTE_DASH[];
|
||
|
||
hack name = REGIST_NAME_BLANK;
|
||
|
||
graph_accesspage_func(0);
|
||
|
||
header_cell_put(table_place_left(0), REGIST_HEADER_PLACE);
|
||
header_cell_put(table_name_left(0), REGIST_HEADER_NAME);
|
||
header_cell_put(table_points_left(0), REGIST_HEADER_POINTS);
|
||
header_cell_put(table_stage_route_left(0), REGIST_HEADER_STAGE_ROUTE);
|
||
|
||
for(int i = 0; i < SCOREDAT_PLACES; i++) {
|
||
#define stage_expr(i, entered_place, expr) \
|
||
(i != entered_place && scoredat_stages[i] expr) || \
|
||
(i == entered_place && entered_stage expr)
|
||
|
||
#define col_and_fx_text (place_col | FX_WEIGHT_BOLD)
|
||
|
||
#if (BINARY == 'E')
|
||
# define place_col ((i == entered_place) ? COL_SELECTED : COL_REGULAR)
|
||
# define top table_row_top(i)
|
||
#else
|
||
int place_col = (i == entered_place) ? COL_SELECTED : COL_REGULAR;
|
||
vram_y_t top = table_row_top(i);
|
||
#endif
|
||
|
||
switch(i) {
|
||
case 0: place_cell_put(top, col_and_fx_text, REGIST_PLACE_0); break;
|
||
case 1: place_cell_put(top, col_and_fx_text, REGIST_PLACE_1); break;
|
||
case 2: place_cell_put(top, col_and_fx_text, REGIST_PLACE_2); break;
|
||
case 3: place_cell_put(top, col_and_fx_text, REGIST_PLACE_3); break;
|
||
case 4: place_cell_put(top, col_and_fx_text, REGIST_PLACE_4); break;
|
||
case 5: place_cell_put(top, col_and_fx_text, REGIST_PLACE_5); break;
|
||
case 6: place_cell_put(top, col_and_fx_text, REGIST_PLACE_6); break;
|
||
case 7: place_cell_put(top, col_and_fx_text, REGIST_PLACE_7); break;
|
||
case 8: place_cell_put(top, col_and_fx_text, REGIST_PLACE_8); break;
|
||
case 9: place_cell_put(top, col_and_fx_text, REGIST_PLACE_9); break;
|
||
}
|
||
graph_putsa_fx(
|
||
table_name_left(0),
|
||
top,
|
||
col_and_fx_text,
|
||
(i == entered_place) ? name.byte : names_z[i].byte
|
||
);
|
||
graph_putfwnum_fx(
|
||
table_points_left(0),
|
||
top,
|
||
(place_col | FX_WEIGHT_BLACK),
|
||
SCORE_DIGITS,
|
||
(entered_place == i) ? entered_points : scoredat_points[i],
|
||
0,
|
||
false
|
||
);
|
||
if(stage_expr(i, entered_place, < SCOREDAT_CLEARED)) {
|
||
graph_putfwnum_fx(
|
||
table_stage_left(0),
|
||
top,
|
||
col_and_fx_text,
|
||
2,
|
||
(i == entered_place) ? entered_stage : scoredat_stages[i],
|
||
0,
|
||
false
|
||
);
|
||
} else if(stage_expr(i, entered_place, == SCOREDAT_CLEARED_MAKAI)) {
|
||
graph_putsa_fx(
|
||
table_stage_left(0), top, col_and_fx_text, REGIST_STAGE_MAKAI
|
||
);
|
||
} else if(stage_expr(i, entered_place, == SCOREDAT_CLEARED_JIGOKU)) {
|
||
graph_putsa_fx(
|
||
table_stage_left(0), top, col_and_fx_text, REGIST_STAGE_JIGOKU
|
||
);
|
||
}
|
||
graph_putsa_fx(
|
||
table_stage_left(2), top, col_and_fx_text, REGIST_STAGE_ROUTE_DASH
|
||
);
|
||
regist_route_put(
|
||
table_stage_left(3),
|
||
top,
|
||
col_and_fx_text,
|
||
(i == entered_place)
|
||
? entered_route[0] : scoredat_routes[i * SCOREDAT_ROUTE_LEN],
|
||
(i == entered_place)
|
||
? entered_route[1] : scoredat_route_byte(i, 1)
|
||
);
|
||
if(entered_place == i) {
|
||
entered_name_left = table_name_left(0);
|
||
entered_name_top = table_row_top(i);
|
||
}
|
||
#undef top
|
||
#undef place_col
|
||
#undef col_and_fx_text
|
||
#undef stage_expr
|
||
}
|
||
}
|
||
|
||
#define alphabet_left_to_column(left) \
|
||
((left - left_for(0)) / KANJI_PADDED_W)
|
||
|
||
#define alphabet_left_to_kanji(left, kanji_at_0) \
|
||
(alphabet_left_to_column(left) + kanji_swap(kanji_at_0))
|
||
|
||
#define alphabet_if(kanji, left, top, on_space, on_left, on_right, on_enter) \
|
||
if(top == LOWER_TOP) { \
|
||
kanji = alphabet_left_to_kanji(left, '<27><>'); \
|
||
} else if(top == LOWER2_TOP) { \
|
||
kanji = alphabet_left_to_kanji(left, '<27><>') + KANJI_PER_ROW; \
|
||
} else if(top == UPPER_TOP) { \
|
||
kanji = alphabet_left_to_kanji(left, '<27>`'); \
|
||
} else if(top == UPPER2_TOP) { \
|
||
kanji = alphabet_left_to_kanji(left, '<27>`') + KANJI_PER_ROW; \
|
||
} else if(top == SYM_TOP) { \
|
||
kanji = ALPHABET_SYMS[alphabet_left_to_column(left)]; \
|
||
} else if(top == NUM_TOP && left < SPACE_LEFT) { \
|
||
kanji = alphabet_left_to_kanji(left, '<27>O'); \
|
||
} else if((top == NUM_TOP) && (left == SPACE_LEFT)) { \
|
||
on_space \
|
||
} else if((top == NUM_TOP) && (left == LEFT_LEFT)) { \
|
||
on_left \
|
||
} else if((top == NUM_TOP) && (left == RIGHT_LEFT)) { \
|
||
on_right \
|
||
} else if((top == NUM_TOP) && (left == ENTER_LEFT)) { \
|
||
on_enter \
|
||
}
|
||
|
||
void alphabet_put_at(screen_x_t left, screen_y_t top, bool16 is_selected)
|
||
{
|
||
// Placement matters with -O-!
|
||
extern const char ALPHABET_SPACE_0[];
|
||
extern const char ALPHABET_LEFT_0[];
|
||
extern const char ALPHABET_RIGHT_0[];
|
||
extern const char ALPHABET_ENTER_0[];
|
||
|
||
int16_t kanji = '\0';
|
||
|
||
egc_copy_rect_1_to_0_16(left, top, KANJI_PADDED_W, GLYPH_H);
|
||
|
||
// TODO OCTOBER 2020: Try flipping
|
||
int16_t col_and_fx = (
|
||
FX_WEIGHT_BOLD | (
|
||
!is_selected ? (COL_REGULAR) : (FX_REVERSE | COL_SELECTED)
|
||
)
|
||
);
|
||
|
||
alphabet_if(kanji, left, top,
|
||
{ graph_printf_fx(left, top, col_and_fx, ALPHABET_SPACE_0); },
|
||
{ graph_printf_fx(left, top, col_and_fx, ALPHABET_LEFT_0); },
|
||
{ graph_printf_fx(left, top, col_and_fx, ALPHABET_RIGHT_0); },
|
||
{ graph_printf_fx(left, top, col_and_fx, ALPHABET_ENTER_0); }
|
||
);
|
||
if(kanji != '\0') {
|
||
#if (BINARY == 'M')
|
||
char kanji_str[3];
|
||
#endif
|
||
graph_putkanji_fx(left, top, col_and_fx, 4, kanji);
|
||
}
|
||
}
|
||
|
||
#if (BINARY == 'M')
|
||
extern bool regist_jump_to_enter;
|
||
#endif
|
||
|
||
#define set_kanji_at(name, pos, kanji) \
|
||
name.byte[(pos * 2) + 0] = kanji_hi(kanji); \
|
||
name.byte[(pos * 2) + 1] = kanji_lo(kanji);
|
||
|
||
int regist_on_shot(
|
||
screen_x_t left,
|
||
screen_y_t top,
|
||
scoredat_name_z_t &entered_name,
|
||
int &entered_name_cursor
|
||
)
|
||
{
|
||
int16_t kanji = '\0';
|
||
struct hack {
|
||
unsigned char byte[SCOREDAT_NAME_BYTES + 1];
|
||
};
|
||
extern const hack REGIST_NAME_SPACES;
|
||
hack cursor_str = REGIST_NAME_SPACES;
|
||
|
||
alphabet_if(kanji, left, top,
|
||
{ kanji = kanji_swap('<EFBFBD>@'); },
|
||
{ CLAMP_DEC(entered_name_cursor, 0); },
|
||
{ CLAMP_INC(entered_name_cursor, (SCOREDAT_NAME_KANJI - 1)); },
|
||
{ return 1; }
|
||
);
|
||
|
||
if(kanji != '\0') {
|
||
set_kanji_at(entered_name, entered_name_cursor, kanji);
|
||
#if (BINARY == 'M')
|
||
if(entered_name_cursor == (SCOREDAT_NAME_KANJI - 1)) {
|
||
regist_jump_to_enter = true;
|
||
}
|
||
#endif
|
||
if(entered_name_cursor < (SCOREDAT_NAME_KANJI - 1)) {
|
||
entered_name_cursor++;
|
||
}
|
||
}
|
||
|
||
egc_copy_rect_1_to_0_16(
|
||
entered_name_left,
|
||
entered_name_top,
|
||
(SCOREDAT_NAME_KANJI * GLYPH_FULL_W),
|
||
GLYPH_H
|
||
);
|
||
graph_printf_s_fx(
|
||
entered_name_left,
|
||
entered_name_top,
|
||
(COL_SELECTED | FX_WEIGHT_BOLD),
|
||
0,
|
||
entered_name.byte
|
||
);
|
||
|
||
set_kanji_at(cursor_str, entered_name_cursor, kanji_swap('<EFBFBD>Q'));
|
||
graph_printf_s_fx(
|
||
entered_name_left, entered_name_top, COL_SELECTED, 1, cursor_str.byte
|
||
);
|
||
return 0;
|
||
}
|
||
|
||
#pragma option -b
|
||
enum regist_input_ret_t {
|
||
RI_REGULAR = 0,
|
||
RI_ENTER = 1,
|
||
RI_NONE = 2
|
||
};
|
||
#pragma option -b.
|
||
|
||
regist_input_ret_t regist_on_input(
|
||
screen_x_t &left, screen_y_t &top,
|
||
scoredat_name_z_t& entered_name, int& entered_name_cursor
|
||
)
|
||
{
|
||
if(input_up == true) {
|
||
alphabet_put_at(left, top, false);
|
||
|
||
top -= KANJI_PADDED_H;
|
||
if(top < LOWER_TOP) {
|
||
top = NUM_TOP;
|
||
}
|
||
if(top == LOWER2_TOP && left >= A_TO_Z_2_END_LEFT) {
|
||
top = LOWER_TOP;
|
||
}
|
||
if(top == UPPER2_TOP && left >= A_TO_Z_2_END_LEFT) {
|
||
top = UPPER_TOP;
|
||
}
|
||
if(top == NUM_TOP && left > SPACE_LEFT && left < LEFT_LEFT) {
|
||
top = SYM_TOP;
|
||
}
|
||
|
||
alphabet_put_at(left, top, true);
|
||
input_up = false;
|
||
} else if(input_down == true) {
|
||
alphabet_put_at(left, top, false);
|
||
|
||
top += KANJI_PADDED_H;
|
||
if(top > NUM_TOP) {
|
||
top = LOWER_TOP;
|
||
}
|
||
if(top == LOWER2_TOP && left >= A_TO_Z_2_END_LEFT) {
|
||
top = UPPER_TOP;
|
||
}
|
||
if(top == UPPER2_TOP && left >= A_TO_Z_2_END_LEFT) {
|
||
top = SYM_TOP;
|
||
}
|
||
if(top == NUM_TOP && left > SPACE_LEFT && left < LEFT_LEFT) {
|
||
top = LOWER_TOP;
|
||
}
|
||
|
||
alphabet_put_at(left, top, true);
|
||
input_down = false;
|
||
} else if(input_lr == INPUT_LEFT) {
|
||
alphabet_put_at(left, top, false);
|
||
|
||
left -= KANJI_PADDED_W;
|
||
if(left < left_for(0)) {
|
||
left = left_for(KANJI_PER_ROW - 1);
|
||
}
|
||
if(top == LOWER2_TOP && left >= A_TO_Z_2_END_LEFT) {
|
||
left = left_for(A_TO_Z_COUNT - 1);
|
||
}
|
||
if(top == UPPER2_TOP && left >= A_TO_Z_2_END_LEFT) {
|
||
left = left_for(A_TO_Z_COUNT - 1);
|
||
}
|
||
if(top == NUM_TOP && left > SPACE_LEFT && left < LEFT_LEFT) {
|
||
left = SPACE_LEFT;
|
||
}
|
||
|
||
alphabet_put_at(left, top, true);
|
||
input_lr = 0;
|
||
} else if(input_lr == INPUT_RIGHT) {
|
||
alphabet_put_at(left, top, false);
|
||
|
||
left += KANJI_PADDED_W;
|
||
if(left > left_for(KANJI_PER_ROW - 1)) {
|
||
left = left_for(0);
|
||
}
|
||
if(top == LOWER2_TOP && left >= A_TO_Z_2_END_LEFT) {
|
||
left = left_for(0);
|
||
}
|
||
if(top == UPPER2_TOP && left >= A_TO_Z_2_END_LEFT) {
|
||
left = left_for(0);
|
||
}
|
||
if(top == NUM_TOP && left > SPACE_LEFT && left < LEFT_LEFT) {
|
||
left = LEFT_LEFT;
|
||
}
|
||
|
||
alphabet_put_at(left, top, true);
|
||
input_lr = 0;
|
||
} else if(input_shot == true) {
|
||
if(regist_on_shot(left, top, entered_name, entered_name_cursor)) {
|
||
return RI_ENTER;
|
||
}
|
||
#if (BINARY == 'M')
|
||
if(regist_jump_to_enter) {
|
||
alphabet_put_at(left, top, false);
|
||
|
||
left = ENTER_LEFT;
|
||
top = NUM_TOP;
|
||
|
||
alphabet_put_at(left, top, true);
|
||
regist_jump_to_enter = false;
|
||
}
|
||
#endif
|
||
input_shot = false;
|
||
} else if(input_strike == true) {
|
||
regist_on_shot(LEFT_LEFT, NUM_TOP, entered_name, entered_name_cursor);
|
||
input_strike = false;
|
||
} else {
|
||
return RI_NONE;
|
||
}
|
||
return RI_REGULAR;
|
||
}
|
||
|
||
#if (BINARY == 'E')
|
||
inline void scoredat_free(void)
|
||
#else
|
||
void scoredat_free(void)
|
||
#endif
|
||
{
|
||
delete[] scoredat_names;
|
||
delete[] scoredat_stages;
|
||
delete[] scoredat_routes;
|
||
delete[] scoredat_points;
|
||
}
|
||
|
||
void scoredat_save(void)
|
||
{
|
||
extern const char SCOREDAT_FN_EASY_2[];
|
||
extern const char SCOREDAT_FN_NORMAL_2[];
|
||
extern const char SCOREDAT_FN_HARD_2[];
|
||
extern const char SCOREDAT_FN_LUNATIC_2[];
|
||
extern const char SCOREDAT_FOPEN_WB[];
|
||
|
||
struct hack {
|
||
char x[sizeof(SCOREDAT_MAGIC)];
|
||
};
|
||
#undef SCOREDAT_MAGIC
|
||
extern const hack SCOREDAT_MAGIC;
|
||
|
||
FILE* fp;
|
||
const hack magic = SCOREDAT_MAGIC;
|
||
char fn[16];
|
||
scoredat_fn(fn, 2);
|
||
|
||
if( (fp = fopen(fn, SCOREDAT_FOPEN_WB)) == NULL) {
|
||
return;
|
||
}
|
||
write(fileno(fp), magic.x, sizeof(SCOREDAT_MAGIC) - 1);
|
||
for(int i = 0; i < SCOREDAT_NAMES_SIZE; i++) {
|
||
scoredat_names[i] = scoredat_name_byte_encode(scoredat_names[i]);
|
||
}
|
||
write(fileno(fp), scoredat_names, SCOREDAT_NAMES_SIZE);
|
||
write(fileno(fp), scoredat_points, sizeof(uint32_t) * SCOREDAT_PLACES);
|
||
write(fileno(fp), scoredat_stages, sizeof(int16_t) * SCOREDAT_PLACES);
|
||
write(fileno(fp), scoredat_routes, sizeof(twobyte_t) * SCOREDAT_PLACES);
|
||
fclose(fp);
|
||
}
|
||
|
||
void regist_name_enter(int entered_place)
|
||
{
|
||
scoredat_name_z_t entered_name;
|
||
regist_input_timeout_declare();
|
||
screen_x_t left;
|
||
screen_y_t top;
|
||
int entered_name_cursor;
|
||
int i;
|
||
|
||
entered_name_cursor = 0;
|
||
regist_input_timeout_reset();
|
||
left = left_for(0);
|
||
top = LOWER_TOP;
|
||
|
||
for(i = 0; i < SCOREDAT_NAME_BYTES; i++) {
|
||
entered_name.byte[i] = ' ';
|
||
}
|
||
entered_name.byte[SCOREDAT_NAME_BYTES] = '\0';
|
||
|
||
input_reset_sense();
|
||
while(1) {
|
||
input_sense(false);
|
||
int input_ret = regist_on_input(
|
||
left, top, entered_name, entered_name_cursor
|
||
);
|
||
// Code generation for FUUIN.EXE forces these to be in separate
|
||
// statements...
|
||
if(input_ret == RI_ENTER) {
|
||
break;
|
||
}
|
||
if(input_ok) {
|
||
break;
|
||
}
|
||
regist_input_timeout_if_reached({ break; });
|
||
if(input_ret == RI_NONE) {
|
||
continue;
|
||
}
|
||
frame_delay(4);
|
||
regist_input_timeout_inc();
|
||
}
|
||
input_ok = false;
|
||
for(i = 0; i < SCOREDAT_NAME_BYTES; i++) {
|
||
scoredat_names[
|
||
(entered_place * SCOREDAT_NAME_BYTES) + i
|
||
] = entered_name.byte[i];
|
||
}
|
||
scoredat_save();
|
||
}
|
||
|
||
static const int PLACE_NONE = (SCOREDAT_PLACES + 20);
|
||
static const int SCOREDAT_NOT_CLEARED = (SCOREDAT_CLEARED - 10);
|
||
|
||
void regist(
|
||
int32_t points, int16_t stage, const char route[SCOREDAT_ROUTE_LEN + 1]
|
||
)
|
||
{
|
||
struct hack {
|
||
const char *r[4];
|
||
};
|
||
extern const hack REGIST_TITLE_RANKS;
|
||
|
||
scoredat_name_z_t names[SCOREDAT_PLACES];
|
||
const hack RANKS = REGIST_TITLE_RANKS;
|
||
long place;
|
||
|
||
regist_bg_put(stage);
|
||
|
||
graph_accesspage_func(1);
|
||
|
||
regist_title_put(
|
||
TITLE_BACK_LEFT,
|
||
stage,
|
||
RANKS.r,
|
||
(COL_REGULAR | FX_WEIGHT_BOLD | FX_CLEAR_BG)
|
||
);
|
||
// On page 1, the title should now at (TITLE_BACK_LEFT, TITLE_BACK_TOP) if
|
||
// not cleared, or at (TITLE_BACK_LEFT, TITLE_TOP) if cleared.
|
||
|
||
graph_accesspage_func(0);
|
||
if(stage < SCOREDAT_NOT_CLEARED) {
|
||
graph_2xscale_byterect_1_to_0_slow(
|
||
TITLE_LEFT, TITLE_TOP,
|
||
TITLE_BACK_LEFT, TITLE_BACK_TOP, TITLE_BACK_W, TITLE_BACK_H
|
||
);
|
||
graph_move_byterect_interpage(
|
||
TITLE_BACK_LEFT, TITLE_BACK_TOP,
|
||
TITLE_BACK_RIGHT, TITLE_BACK_BOTTOM,
|
||
TITLE_BACK_LEFT, TITLE_BACK_TOP,
|
||
0, 1
|
||
);
|
||
} else {
|
||
graph_2xscale_byterect_1_to_0_slow(
|
||
TITLE_LEFT, TITLE_TOP,
|
||
TITLE_BACK_LEFT, TITLE_TOP, TITLE_BACK_W, TITLE_BACK_H
|
||
);
|
||
}
|
||
|
||
if(scoredat_load()) {
|
||
return;
|
||
}
|
||
for(place = 0; place < SCOREDAT_PLACES; place++) {
|
||
scoredat_name_get(place, names[place].byte);
|
||
}
|
||
for(place = 0; place < SCOREDAT_PLACES; place++) {
|
||
if(points >= scoredat_points[place]) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
input_reset_sense();
|
||
|
||
if(place < SCOREDAT_PLACES) {
|
||
for(long shift = (SCOREDAT_PLACES - 1); shift > place; shift--) {
|
||
strcpy(names[shift].byte, names[shift - 1].byte);
|
||
scoredat_points[shift] = scoredat_points[shift - 1];
|
||
scoredat_stages[shift] = scoredat_stages[shift - 1];
|
||
scoredat_route_byte(shift, 0) = scoredat_route_byte(shift, -2);
|
||
scoredat_route_byte(shift, 1) = scoredat_route_byte(shift, -1);
|
||
}
|
||
long p = (SCOREDAT_NAMES_SIZE - 1);
|
||
while(((place * SCOREDAT_NAME_BYTES) + SCOREDAT_NAME_BYTES) <= p) {
|
||
scoredat_names[p] = scoredat_names[p - SCOREDAT_NAME_BYTES];
|
||
p--;
|
||
}
|
||
regist_put_initial(place, points, stage, route, names);
|
||
alphabet_put_initial();
|
||
|
||
scoredat_points[place] = points;
|
||
scoredat_stages[place] = stage;
|
||
scoredat_route_byte(place, 0) = route[0];
|
||
scoredat_route_byte(place, 1) = route[1];
|
||
|
||
// Writes the new name to scoredat_names[] and calls scoredat_save()
|
||
regist_name_enter(place);
|
||
|
||
_ES = FP_SEG(graph_accesspage_func); // Yes, no point to this at all.
|
||
scoredat_free();
|
||
return;
|
||
}
|
||
regist_put_initial(PLACE_NONE, points, stage, route, names);
|
||
input_ok = true;
|
||
input_shot = true;
|
||
while(1) {
|
||
input_sense(false);
|
||
if(!input_ok || !input_shot) {
|
||
break;
|
||
}
|
||
}
|
||
_ES = FP_SEG(graph_accesspage_func); // Yes, no point to this at all.
|
||
scoredat_free();
|
||
}
|