diff --git a/Makefile b/Makefile index 66a736e..9e166b4 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,7 @@ GEN_SRC += gen/text.cpp GEN_SRC += gen/text_pointers.cpp GEN_SRC += gen/pokemon/moves.cpp GEN_SRC += gen/pokemon/pokemon.cpp +GEN_SRC += gen/pokemon/types.cpp SRC = SRC += $(GEN_SRC) diff --git a/control.hpp b/control.hpp index 97072ce..b34dd46 100644 --- a/control.hpp +++ b/control.hpp @@ -24,16 +24,15 @@ struct ligatures_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 colon_sm = 0xa6; // (small ':' symbol) - static constexpr uint8_t e = 0xe9; // é static constexpr uint8_t ellipsis = 0xa8; // … + static constexpr uint8_t e = 0xe9; // é static constexpr uint8_t pk = 0xb2; // ᴾₖ static constexpr uint8_t mn = 0xb3; // ᴹₙ 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; // }; /* diff --git a/font.cpp b/font.cpp index 959146a..2c3dc8c 100644 --- a/font.cpp +++ b/font.cpp @@ -39,6 +39,8 @@ uint8_t ascii_to_font(uint8_t c) case extended_t::mn: return 0x73; // ᴹₙ case extended_t::jpy: return 0x78; // ¥ case extended_t::times: return 0x79; // × + case extended_t::male: return 0x7a; // + case extended_t::female: return 0x7b; // default: return 0x7e; // "invalid" character } } diff --git a/graphic.cpp b/graphic.cpp index db737e9..ae20524 100644 --- a/graphic.cpp +++ b/graphic.cpp @@ -7,52 +7,10 @@ #include "control.hpp" #include "number.hpp" +#include "gen/pokemon/types.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 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}); - 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)); - 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('/')); + draw_text(base_pattern, types[type].name, 11, 10 + (2 * ix)); } } diff --git a/graphic.hpp b/graphic.hpp index f9f5a7e..e3f9aec 100644 --- a/graphic.hpp +++ b/graphic.hpp @@ -7,6 +7,56 @@ #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, const int32_t x, const int32_t y, // in cells const uint8_t c) diff --git a/menu.cpp b/menu.cpp index 3128049..3acb6b6 100644 --- a/menu.cpp +++ b/menu.cpp @@ -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_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); } diff --git a/pokemon.hpp b/pokemon.hpp index a81ce56..a9a7ea4 100644 --- a/pokemon.hpp +++ b/pokemon.hpp @@ -58,7 +58,7 @@ struct pokemon_t { const uint8_t * name; base_stat_values_t base_stat_values; - type_t types[2]; + enum type_t::type types[2]; uint8_t catch_rate; uint8_t base_exp; growth_t growth_rate; diff --git a/tools/generate/files.py b/tools/generate/files.py index 4264dab..0063e4c 100644 --- a/tools/generate/files.py +++ b/tools/generate/files.py @@ -27,6 +27,7 @@ files = [ (moves.generate_header, "pokemon/moves.hpp"), (moves.generate_source, "pokemon/moves.cpp"), (types.generate_header, "pokemon/types.hpp"), + (types.generate_source, "pokemon/types.cpp"), (pokemon.generate_enum_inc, "pokemon/pokemon_enum.inc.hpp"), (pokemon.generate_source, "pokemon/pokemon.cpp"), ] diff --git a/tools/generate/pokemon/pokemon.py b/tools/generate/pokemon/pokemon.py index afe66eb..9eaacdc 100644 --- a/tools/generate/pokemon/pokemon.py +++ b/tools/generate/pokemon/pokemon.py @@ -62,7 +62,7 @@ struct evolution_t { struct pokemon_t { base_stat_values_t stat_values; - type_t types[2]; + enum type_t::type types[2]; uint8_t catch_rate; uint8_t base_exp; uint8_t growth_rate; @@ -245,18 +245,36 @@ def growth_name(growth_constant): def dex_constant_name_to_constant_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): constant_index = dex_constant_name_to_constant_index(base_stats.pokedex_id) 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) types = ", ".join( - f"type_t::{type.lower()}" + f"type_t::{type.removesuffix('_TYPE').lower()}" for type in base_stats.types ) growth_rate = growth_name(base_stats.growth_rate) return [ f"[pokemon_t::{enum_name}] = {{", - f'.name = reinterpret_cast("{pokemon_name}"),', + f'.name = reinterpret_cast({escaped_name}),', ".base_stat_values = {", *stat_values(base_stats.stat_values), "},", diff --git a/tools/generate/pokemon/types.py b/tools/generate/pokemon/types.py index 7a164ff..1b296e8 100644 --- a/tools/generate/pokemon/types.py +++ b/tools/generate/pokemon/types.py @@ -4,14 +4,21 @@ from parse import parse def includes_header(): yield "#pragma once" yield "" + yield "#include " def struct_type_t(): _type_constants = parse.type_constants_list() _type_constants_str = (f"{s.lower()}," for s in _type_constants) return [ - "enum struct type_t {", - *_type_constants_str, + "struct type_t {", + "enum type {", + *_type_constants_str, + "};", + "", + "const uint8_t * name;", "};", + "", + "extern const type_t types[];" ] def generate_header(): @@ -19,3 +26,27 @@ def generate_header(): render(includes_header()) render(struct_type_t()) 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("{_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 diff --git a/tools/parse/parse.py b/tools/parse/parse.py index 4121b94..4d6d23c 100644 --- a/tools/parse/parse.py +++ b/tools/parse/parse.py @@ -96,3 +96,5 @@ pic_list = memoize(lambda: pic.parse_all(prefix)) # type type_constants_list = memoize(lambda: types.constants.parse(prefix)) +type_names_list = memoize(lambda: types.names.parse(prefix)) +type_names_list() diff --git a/tools/parse/pokemon/names.py b/tools/parse/pokemon/names.py index cc7a3bf..42dd296 100644 --- a/tools/parse/pokemon/names.py +++ b/tools/parse/pokemon/names.py @@ -9,7 +9,10 @@ lines = partial(tokenize.lines, prefix="db ") def flatten(tokens): for _, (s,) in tokens: - yield string.parse(s).rstrip('@') + s = string.parse(s).rstrip('@') \ + .replace('♂', '\xa2') \ + .replace('♀', '\xa3') + yield s def parse(prefix): path = prefix / "data/pokemon/names.asm" diff --git a/tools/parse/types/__init__.py b/tools/parse/types/__init__.py index e0a2092..c70f903 100644 --- a/tools/parse/types/__init__.py +++ b/tools/parse/types/__init__.py @@ -1 +1,2 @@ from parse.types import constants +from parse.types import names diff --git a/tools/parse/types/constants.py b/tools/parse/types/constants.py index ed51574..ae91acb 100644 --- a/tools/parse/types/constants.py +++ b/tools/parse/types/constants.py @@ -1,4 +1,7 @@ -from functools import partial 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] diff --git a/tools/parse/types/names.py b/tools/parse/types/names.py new file mode 100644 index 0000000..9a8a733 --- /dev/null +++ b/tools/parse/types/names.py @@ -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