#include #include "vdp2.h" #include "coordinates.hpp" #include "graphic.hpp" #include "font.hpp" #include "start_size.hpp" #include "control.hpp" #include "render_map.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_bot_left = 107; static constexpr uint8_t corner_bot_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_bot_right = 97; static constexpr uint8_t arrow_right = 98; static constexpr uint8_t vertical = 99; static constexpr uint8_t corner_bot_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; }; static inline void put_char(const uint32_t base_pattern, const int32_t x, const int32_t y, const uint8_t c) { const int32_t ix = (0x2000 / 2) + ((cell_offset::y + y) * 64 + (cell_offset::x + x)); vdp2.vram.u16[ix] = ((base_pattern + c) & 0xfff) | PATTERN_NAME_TABLE_1WORD__PALETTE(1); } void draw_box_border(const uint32_t base_pattern, const screen_t& top_left, const screen_t& bot_right) { // place corners put_char(base_pattern, top_left.x, top_left.y, dialog_border::corner_top_left); put_char(base_pattern, bot_right.x, top_left.y, dialog_border::corner_top_right); put_char(base_pattern, bot_right.x, bot_right.y, dialog_border::corner_bot_right); put_char(base_pattern, top_left.x, bot_right.y, dialog_border::corner_bot_left); for (int32_t y = top_left.y + 1; y < bot_right.y; y++) { // left vertical bar put_char(base_pattern, top_left.x, y, dialog_border::vertical); // right vertical bar put_char(base_pattern, bot_right.x, y, dialog_border::vertical); } for (int32_t x = top_left.x + 1; x < bot_right.x; x++) { // top horizontal bar put_char(base_pattern, x, top_left.y, dialog_border::horizontal); // bottom horizontal bar put_char(base_pattern, x, bot_right.y, dialog_border::horizontal); } } 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++; } }