types: add type name strings

This also parses, generates, and displays nidoran male/female name
strings correctly.
This commit is contained in:
Zack Buhman 2023-08-04 05:26:23 +00:00
parent abe7bde678
commit 4909a1f089
15 changed files with 141 additions and 60 deletions

View File

@ -26,6 +26,7 @@ GEN_SRC += gen/text.cpp
GEN_SRC += gen/text_pointers.cpp GEN_SRC += gen/text_pointers.cpp
GEN_SRC += gen/pokemon/moves.cpp GEN_SRC += gen/pokemon/moves.cpp
GEN_SRC += gen/pokemon/pokemon.cpp GEN_SRC += gen/pokemon/pokemon.cpp
GEN_SRC += gen/pokemon/types.cpp
SRC = SRC =
SRC += $(GEN_SRC) SRC += $(GEN_SRC)

View File

@ -24,16 +24,15 @@ struct ligatures_t {
}; };
struct extended_t { struct extended_t {
static constexpr uint8_t male = 0xa2; //
static constexpr uint8_t female = 0xa3; //
static constexpr uint8_t jpy = 0xa5; // ¥ static constexpr uint8_t jpy = 0xa5; // ¥
static constexpr uint8_t colon_sm = 0xa6; // (small ':' symbol) static constexpr uint8_t colon_sm = 0xa6; // (small ':' symbol)
static constexpr uint8_t e = 0xe9; // é
static constexpr uint8_t ellipsis = 0xa8; // … static constexpr uint8_t ellipsis = 0xa8; // …
static constexpr uint8_t e = 0xe9; // é
static constexpr uint8_t pk = 0xb2; // ᴾₖ static constexpr uint8_t pk = 0xb2; // ᴾₖ
static constexpr uint8_t mn = 0xb3; // ᴹₙ static constexpr uint8_t mn = 0xb3; // ᴹₙ
static constexpr uint8_t times = 0xd7; // × static constexpr uint8_t times = 0xd7; // ×
static constexpr uint8_t l_arrow = 0x75; // →
static constexpr uint8_t l_arrow_solid = 0x76; // →
static constexpr uint8_t d_arrow = 0x77; //
}; };
/* /*

View File

@ -39,6 +39,8 @@ uint8_t ascii_to_font(uint8_t c)
case extended_t::mn: return 0x73; // ᴹₙ case extended_t::mn: return 0x73; // ᴹₙ
case extended_t::jpy: return 0x78; // ¥ case extended_t::jpy: return 0x78; // ¥
case extended_t::times: return 0x79; // × case extended_t::times: return 0x79; // ×
case extended_t::male: return 0x7a; //
case extended_t::female: return 0x7b; //
default: return 0x7e; // "invalid" character default: return 0x7e; // "invalid" character
} }
} }

View File

@ -7,52 +7,10 @@
#include "control.hpp" #include "control.hpp"
#include "number.hpp" #include "number.hpp"
#include "gen/pokemon/types.hpp"
#include "pokemon_instance.hpp" #include "pokemon_instance.hpp"
struct dialog_border {
static constexpr uint8_t corner_top_left = 105;
static constexpr uint8_t corner_top_right = 106;
static constexpr uint8_t corner_bottom_left = 107;
static constexpr uint8_t corner_bottom_right = 108;
static constexpr uint8_t vertical_end_cap = 109;
static constexpr uint8_t vertical = 110;
static constexpr uint8_t horizontal = 111;
};
struct battle_border {
static constexpr uint8_t horizontal = 96;
static constexpr uint8_t corner_bottom_right = 97;
static constexpr uint8_t arrow_right = 98;
static constexpr uint8_t vertical = 99;
static constexpr uint8_t corner_bottom_left = 100;
static constexpr uint8_t three_dots = 101;
static constexpr uint8_t vertical_end_cap = 102;
static constexpr uint8_t level = 103;
static constexpr uint8_t arrow_left = 104;
};
struct hp_bar {
static constexpr uint8_t hp = 0x50;
static constexpr uint8_t start_cap = 0x51;
static constexpr uint8_t seg0 = 0x52;
static constexpr uint8_t seg1 = 0x53;
static constexpr uint8_t seg2 = 0x54;
static constexpr uint8_t seg3 = 0x55;
static constexpr uint8_t seg4 = 0x56;
static constexpr uint8_t seg5 = 0x57;
static constexpr uint8_t seg6 = 0x58;
static constexpr uint8_t seg7 = 0x59;
static constexpr uint8_t seg8 = 0x5a;
static constexpr uint8_t end_cap_nobar = 0x5b;
static constexpr uint8_t end_cap_bar = 0x66;
};
struct stats {
static constexpr uint8_t id = 0x70; // ID
static constexpr uint8_t no = 0x71; // No
static constexpr uint8_t no_dot = 0x4e; // .
};
#define S reinterpret_cast<const uint8_t *> #define S reinterpret_cast<const uint8_t *>
void draw_text(const uint32_t base_pattern, void draw_text(const uint32_t base_pattern,
@ -236,10 +194,15 @@ void draw_stats1(const uint32_t base_pattern,
{ {
draw_battle_border(base_pattern, {19, 9}, {12, 17}); draw_battle_border(base_pattern, {19, 9}, {12, 17});
for (int32_t ix = 0; ix < 2; ix++) { int32_t distinct_types = (pokemon[pokemon_instance.species].types[0]
!= pokemon[pokemon_instance.species].types[1]) + 1;
for (int32_t ix = 0; ix < distinct_types; ix++) {
const enum type_t::type type = pokemon[pokemon_instance.species].types[ix];
draw_text(base_pattern, S("TYPE"), 10, 9 + (2 * ix)); draw_text(base_pattern, S("TYPE"), 10, 9 + (2 * ix));
put_char(base_pattern, 15, 9 + (2 * ix), ascii_to_font('1' + ix)); put_char(base_pattern, 14, 9 + (2 * ix), ascii_to_font('1' + ix));
put_char(base_pattern, 15, 9 + (2 * ix), ascii_to_font('/')); put_char(base_pattern, 15, 9 + (2 * ix), ascii_to_font('/'));
draw_text(base_pattern, types[type].name, 11, 10 + (2 * ix));
} }
} }

View File

@ -7,6 +7,56 @@
#include "pokemon_instance.hpp" #include "pokemon_instance.hpp"
struct interactive {
static constexpr uint8_t l_arrow = 0x75; // →
static constexpr uint8_t l_arrow_solid = 0x76; // →
static constexpr uint8_t d_arrow = 0x77; //
};
struct dialog_border {
static constexpr uint8_t corner_top_left = 105;
static constexpr uint8_t corner_top_right = 106;
static constexpr uint8_t corner_bottom_left = 107;
static constexpr uint8_t corner_bottom_right = 108;
static constexpr uint8_t vertical_end_cap = 109;
static constexpr uint8_t vertical = 110;
static constexpr uint8_t horizontal = 111;
};
struct battle_border {
static constexpr uint8_t horizontal = 96;
static constexpr uint8_t corner_bottom_right = 97;
static constexpr uint8_t arrow_right = 98;
static constexpr uint8_t vertical = 99;
static constexpr uint8_t corner_bottom_left = 100;
static constexpr uint8_t three_dots = 101;
static constexpr uint8_t vertical_end_cap = 102;
static constexpr uint8_t level = 103;
static constexpr uint8_t arrow_left = 104;
};
struct hp_bar {
static constexpr uint8_t hp = 0x50;
static constexpr uint8_t start_cap = 0x51;
static constexpr uint8_t seg0 = 0x52;
static constexpr uint8_t seg1 = 0x53;
static constexpr uint8_t seg2 = 0x54;
static constexpr uint8_t seg3 = 0x55;
static constexpr uint8_t seg4 = 0x56;
static constexpr uint8_t seg5 = 0x57;
static constexpr uint8_t seg6 = 0x58;
static constexpr uint8_t seg7 = 0x59;
static constexpr uint8_t seg8 = 0x5a;
static constexpr uint8_t end_cap_nobar = 0x5b;
static constexpr uint8_t end_cap_bar = 0x66;
};
struct stats {
static constexpr uint8_t id = 0x70; // ID
static constexpr uint8_t no = 0x71; // No
static constexpr uint8_t no_dot = 0x4e; // .
};
static inline void put_char(const uint32_t base_pattern, static inline void put_char(const uint32_t base_pattern,
const int32_t x, const int32_t y, // in cells const int32_t x, const int32_t y, // in cells
const uint8_t c) const uint8_t c)

View File

@ -69,5 +69,5 @@ void draw_menu_cursor(const uint32_t base_pattern,
const uint32_t cell_x = menu.top_left.x + 1 + (menu.h_advance * cursor.x); const uint32_t cell_x = menu.top_left.x + 1 + (menu.h_advance * cursor.x);
const uint32_t cell_y = menu.top_left.y + menu.v_advance + (menu.v_advance * cursor.y); const uint32_t cell_y = menu.top_left.y + menu.v_advance + (menu.v_advance * cursor.y);
put_char(base_pattern, cell_x, cell_y, extended_t::l_arrow_solid); put_char(base_pattern, cell_x, cell_y, interactive::l_arrow_solid);
} }

View File

@ -58,7 +58,7 @@ struct pokemon_t {
const uint8_t * name; const uint8_t * name;
base_stat_values_t base_stat_values; base_stat_values_t base_stat_values;
type_t types[2]; enum type_t::type types[2];
uint8_t catch_rate; uint8_t catch_rate;
uint8_t base_exp; uint8_t base_exp;
growth_t growth_rate; growth_t growth_rate;

View File

@ -27,6 +27,7 @@ files = [
(moves.generate_header, "pokemon/moves.hpp"), (moves.generate_header, "pokemon/moves.hpp"),
(moves.generate_source, "pokemon/moves.cpp"), (moves.generate_source, "pokemon/moves.cpp"),
(types.generate_header, "pokemon/types.hpp"), (types.generate_header, "pokemon/types.hpp"),
(types.generate_source, "pokemon/types.cpp"),
(pokemon.generate_enum_inc, "pokemon/pokemon_enum.inc.hpp"), (pokemon.generate_enum_inc, "pokemon/pokemon_enum.inc.hpp"),
(pokemon.generate_source, "pokemon/pokemon.cpp"), (pokemon.generate_source, "pokemon/pokemon.cpp"),
] ]

View File

@ -62,7 +62,7 @@ struct evolution_t {
struct pokemon_t { struct pokemon_t {
base_stat_values_t stat_values; base_stat_values_t stat_values;
type_t types[2]; enum type_t::type types[2];
uint8_t catch_rate; uint8_t catch_rate;
uint8_t base_exp; uint8_t base_exp;
uint8_t growth_rate; uint8_t growth_rate;
@ -245,18 +245,36 @@ def growth_name(growth_constant):
def dex_constant_name_to_constant_index(dex_constant_name): def dex_constant_name_to_constant_index(dex_constant_name):
return parse.pokemon_dex_order_list().index(dex_constant_name) return parse.pokemon_dex_order_list().index(dex_constant_name)
def escape_pokemon_name(pokemon_name):
cs = []
def maybe_yield():
nonlocal cs
if cs:
s = "".join(cs)
yield f'"{s}"'
cs = []
for c in pokemon_name:
if ord(c) < 127:
cs.append(c)
else:
yield from maybe_yield()
yield f'"\\x{ord(c):x}"'
yield from maybe_yield()
def pokemon(base_stats, evos_moves): def pokemon(base_stats, evos_moves):
constant_index = dex_constant_name_to_constant_index(base_stats.pokedex_id) constant_index = dex_constant_name_to_constant_index(base_stats.pokedex_id)
pokemon_name = parse.pokemon_names_list()[constant_index] pokemon_name = parse.pokemon_names_list()[constant_index]
escaped_name = " ".join(escape_pokemon_name(pokemon_name))
enum_name = dex_constant_to_enum_name(base_stats.pokedex_id) enum_name = dex_constant_to_enum_name(base_stats.pokedex_id)
types = ", ".join( types = ", ".join(
f"type_t::{type.lower()}" f"type_t::{type.removesuffix('_TYPE').lower()}"
for type in base_stats.types for type in base_stats.types
) )
growth_rate = growth_name(base_stats.growth_rate) growth_rate = growth_name(base_stats.growth_rate)
return [ return [
f"[pokemon_t::{enum_name}] = {{", f"[pokemon_t::{enum_name}] = {{",
f'.name = reinterpret_cast<const uint8_t *>("{pokemon_name}"),', f'.name = reinterpret_cast<const uint8_t *>({escaped_name}),',
".base_stat_values = {", ".base_stat_values = {",
*stat_values(base_stats.stat_values), *stat_values(base_stats.stat_values),
"},", "},",

View File

@ -4,14 +4,21 @@ from parse import parse
def includes_header(): def includes_header():
yield "#pragma once" yield "#pragma once"
yield "" yield ""
yield "#include <cstdint>"
def struct_type_t(): def struct_type_t():
_type_constants = parse.type_constants_list() _type_constants = parse.type_constants_list()
_type_constants_str = (f"{s.lower()}," for s in _type_constants) _type_constants_str = (f"{s.lower()}," for s in _type_constants)
return [ return [
"enum struct type_t {", "struct type_t {",
"enum type {",
*_type_constants_str, *_type_constants_str,
"};", "};",
"",
"const uint8_t * name;",
"};",
"",
"extern const type_t types[];"
] ]
def generate_header(): def generate_header():
@ -19,3 +26,27 @@ def generate_header():
render(includes_header()) render(includes_header())
render(struct_type_t()) render(struct_type_t())
return out return out
def includes_source():
yield '#include "types.hpp"'
yield ""
def type(constant_index, constant_name):
_type_name = parse.type_names_list()[constant_index]
return [
f'[type_t::{constant_name.lower()}] = {{',
f'.name = reinterpret_cast<const uint8_t *>("{_type_name}"),',
'},'
]
def types():
yield "const type_t types[] = {"
for constant_index, constant_name in enumerate(parse.type_constants_list()):
yield from type(constant_index, constant_name)
yield "};"
def generate_source():
render, out = renderer()
render(includes_source())
render(types())
return out

View File

@ -96,3 +96,5 @@ pic_list = memoize(lambda: pic.parse_all(prefix))
# type # type
type_constants_list = memoize(lambda: types.constants.parse(prefix)) type_constants_list = memoize(lambda: types.constants.parse(prefix))
type_names_list = memoize(lambda: types.names.parse(prefix))
type_names_list()

View File

@ -9,7 +9,10 @@ lines = partial(tokenize.lines, prefix="db ")
def flatten(tokens): def flatten(tokens):
for _, (s,) in tokens: for _, (s,) in tokens:
yield string.parse(s).rstrip('@') s = string.parse(s).rstrip('@') \
.replace('', '\xa2') \
.replace('', '\xa3')
yield s
def parse(prefix): def parse(prefix):
path = prefix / "data/pokemon/names.asm" path = prefix / "data/pokemon/names.asm"

View File

@ -1 +1,2 @@
from parse.types import constants from parse.types import constants
from parse.types import names

View File

@ -1,4 +1,7 @@
from functools import partial
from parse.generic import constants from parse.generic import constants
parse = partial(constants.parse, path='constants/type_constants.asm') def parse(prefix):
# this is a silly hack, but I'm too lazy to parse the actual
# names.asm
result = constants.parse(prefix, path='constants/type_constants.asm')
return [r.removesuffix('_TYPE') for r in result]

View File

@ -0,0 +1,7 @@
from parse.types import constants
def parse(prefix):
# this is a silly hack, but I'm too lazy to parse the actual
# names.asm
result = constants.parse(prefix)
return result