basic sign rendering
All defined signs are now interactable, but the sign message is not dismissable yet, and only the first paragraph is displayed in multi-paragraph signs.
This commit is contained in:
parent
c2ea17d25a
commit
60c346406c
BIN
derived/font.png
BIN
derived/font.png
Binary file not shown.
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
3
font.cpp
3
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;
|
||||
|
1
font.hpp
1
font.hpp
@ -3,3 +3,4 @@
|
||||
#include <cstdint>
|
||||
|
||||
uint32_t load_font(uint32_t top);
|
||||
uint8_t ascii_to_font(uint8_t c);
|
||||
|
48
graphic.cpp
48
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++;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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; }
|
||||
};
|
||||
|
20
main.cpp
20
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<uint32_t>(&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;
|
||||
|
@ -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;
|
||||
|
@ -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 <cstdint>'
|
||||
yield ''
|
||||
yield '#include "maps.hpp"'
|
||||
yield '#include "text_pointers.hpp"'
|
||||
yield ''
|
||||
|
||||
def generate_source():
|
||||
|
Loading…
x
Reference in New Issue
Block a user