diff --git a/derived/font.png b/derived/font.png index 3dc7acb..3e60100 100644 Binary files a/derived/font.png and b/derived/font.png differ diff --git a/font.cpp b/font.cpp index 97279f6..959146a 100644 --- a/font.cpp +++ b/font.cpp @@ -6,7 +6,7 @@ #include "font.hpp" #include "control.hpp" -constexpr inline uint8_t ascii_to_font(uint8_t c) +uint8_t ascii_to_font(uint8_t c) { if (c >= 'A' && c <= 'Z') return (c - 'A') + 0; @@ -16,6 +16,7 @@ constexpr inline uint8_t ascii_to_font(uint8_t c) return (c - '0') + 64; switch (c) { + case ' ': return 0x4f; case '!': return 0x1a; case '(': return 0x1b; case ')': return 0x1c; diff --git a/font.hpp b/font.hpp index 0ce032e..b33598d 100644 --- a/font.hpp +++ b/font.hpp @@ -3,3 +3,4 @@ #include uint32_t load_font(uint32_t top); +uint8_t ascii_to_font(uint8_t c); diff --git a/graphic.cpp b/graphic.cpp index 05313fb..23d7a61 100644 --- a/graphic.cpp +++ b/graphic.cpp @@ -4,7 +4,9 @@ #include "coordinates.hpp" #include "graphic.hpp" - +#include "font.hpp" +#include "start_size.hpp" +#include "control.hpp" #include "render_map.hpp" struct dialog_border { @@ -64,7 +66,49 @@ void draw_box_border(const uint32_t base_pattern, } } -void dialog_t::draw(const uint32_t base_pattern) +void dialog_t::draw(const uint32_t base_pattern, + const start_size_t& text) { draw_box_border(base_pattern, top_left, bottom_right); + + for (uint32_t x = top_left.x + 1; x < bottom_right.x; x++) { + put_char(base_pattern, x, top_left.y + 1, ascii_to_font(' ')); + put_char(base_pattern, x, top_left.y + 2, ascii_to_font(' ')); + put_char(base_pattern, x, top_left.y + 3, ascii_to_font(' ')); + put_char(base_pattern, x, top_left.y + 4, ascii_to_font(' ')); + } + + uint32_t ix = 0; + uint32_t x = top_left.x + 1; + uint32_t y = top_left.y + 2; + // ignore C-string null terminator + while (ix < (text.size - 1)) { + const uint8_t c = text.start[ix]; + switch (c) { + case control_t::text: break; + case control_t::done: break; + case control_t::prompt: break; + case control_t::page: break; + + case control_t::next: [[fallthrough]]; + case control_t::line: + while (x < bottom_right.x) { + put_char(base_pattern, x, y, ascii_to_font(' ')); + x++; + } + x = top_left.x + 1; + y += 2; + break; + case control_t::para: [[fallthrough]]; + case control_t::cont: + // fixme: + ix = text.size; + break; + default: + put_char(base_pattern, x, y, ascii_to_font(c)); + x += 1; + break; + } + ix++; + } } diff --git a/graphic.hpp b/graphic.hpp index 44c3313..2da2324 100644 --- a/graphic.hpp +++ b/graphic.hpp @@ -1,9 +1,12 @@ #pragma once +#include "start_size.hpp" + struct dialog_t { static constexpr screen_t top_left = { 0, 12}; static constexpr screen_t bottom_right = {19, 17}; - static void draw(const uint32_t base_pattern); + static void draw(const uint32_t base_pattern, + const start_size_t& text); }; diff --git a/input.hpp b/input.hpp index 638c417..fb1ee62 100644 --- a/input.hpp +++ b/input.hpp @@ -56,4 +56,5 @@ struct event { static inline bool cursor_right() { return input_flopped(input.right) >= 1; } static inline bool cursor_up() { return input_flopped(input.up ) >= 1; } static inline bool cursor_down() { return input_flopped(input.down ) >= 1; } + static inline bool button_a() { return input_flopped(input.a ) == 1; } }; diff --git a/main.cpp b/main.cpp index 3caaa12..39b7135 100644 --- a/main.cpp +++ b/main.cpp @@ -394,6 +394,22 @@ void update_warp() } } +void check_sign() +{ + const world_t coord = direction_offset(state.player.world, state.player.facing); + const map_t& map = maps[state.map]; + const object_t& obj = map_objects[state.map]; + + for (uint32_t i = 0; i < obj.bg_length; i++) { + const bg_event_t& event = obj.bg_events[i]; + const bool position_match = event.position.x == coord.x && event.position.y == coord.y; + if (position_match && event.sign_id != 0xff) { + const start_size_t& text = map.text_pointers[event.sign_id]; + dialog_t::draw(state.draw.base_pattern.font, text); + } + } +} + void update() { state.player.tick(); @@ -404,6 +420,7 @@ void update() else if (event::cursor_right()) collision_move(maps[state.map], actor_t::right); else if (event::cursor_up() ) collision_move(maps[state.map], actor_t::up); else if (event::cursor_down() ) collision_move(maps[state.map], actor_t::down); + else if (event::button_a() ) check_sign(); } void render() @@ -559,14 +576,13 @@ void init_vdp2() const uint32_t value = ((base_pattern + 127) & 0xfff) | PATTERN_NAME_TABLE_1WORD__PALETTE(1); fill(&vdp2.vram.u32[0x2000 / 4], value | value << 16, 0x2000); - dialog_t::draw(state.draw.base_pattern.font); - palette_data(); } void main() { state.map = map_t::pallet_town; + //state.map = map_t::pewter_gym; //state.map = map_t::viridian_forest; //state.map = map_t::route_2; state.player.world.x = 6; diff --git a/start_size.hpp b/start_size.hpp index 776059c..0d20088 100644 --- a/start_size.hpp +++ b/start_size.hpp @@ -6,3 +6,5 @@ struct start_size_t { uint8_t const * const start; uint32_t size; }; + +typedef start_size_t const * const start_size_ptr_t; diff --git a/tools/generate/maps.py b/tools/generate/maps.py index e86e7b4..5fb103b 100644 --- a/tools/generate/maps.py +++ b/tools/generate/maps.py @@ -64,7 +64,7 @@ def struct_map_t(): *struct_connection_t(), "", "start_size_t blocks;", - "start_size_t text_pointers;", + "start_size_ptr_t text_pointers;", "uint32_t width;", "uint32_t height;", "connection_t connections[4];", @@ -106,9 +106,18 @@ def connections(map_header): yield f".offset = {connection.offset}," yield "}," +def text_pointers(map_header): + if map_header.name1 == "ViridianMart": + # fixme: viridianmart + return + else: + #array_size = f"(sizeof ({map_header.text_pointers()}))" + #type_size = f"(sizeof (start_size_t))" + #yield f".start = &{map_header.text_pointers()}[0]," + #yield f".length = {array_size} / {type_size}," + yield f".text_pointers = &{map_header.text_pointers()}[0]," + def map(map_header): - - block_path = parse.maps_blocks_list()[map_header.blocks()] map_constant = parse.map_constants_list()[map_header.name2] return [ @@ -116,9 +125,7 @@ def map(map_header): ".blocks = {", *start_size_value(block_path), "},", - ".text_pointers = {", - - "},", + *text_pointers(map_header), f".width = {map_constant.width},", f".height = {map_constant.height},", ".connections = {", @@ -149,6 +156,7 @@ def includes_source(): yield '#include ' yield '' yield '#include "maps.hpp"' + yield '#include "text_pointers.hpp"' yield '' def generate_source():