menu: add basic non-interactable menus
This commit is contained in:
parent
853457a79d
commit
f821ac9e6d
1
Makefile
1
Makefile
@ -21,6 +21,7 @@ SRC += input.cpp
|
|||||||
SRC += vram.cpp
|
SRC += vram.cpp
|
||||||
SRC += font.cpp
|
SRC += font.cpp
|
||||||
SRC += graphic.cpp
|
SRC += graphic.cpp
|
||||||
|
SRC += menu.cpp
|
||||||
|
|
||||||
DEP = $(patsubst %.cpp,%.cpp.d,$(SRC))
|
DEP = $(patsubst %.cpp,%.cpp.d,$(SRC))
|
||||||
|
|
||||||
|
@ -31,6 +31,9 @@ struct extended_t {
|
|||||||
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; //
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -21,6 +21,11 @@ struct block_t {
|
|||||||
int32_t y;
|
int32_t y;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct screen_cell_t {
|
||||||
|
uint32_t x;
|
||||||
|
uint32_t y;
|
||||||
|
};
|
||||||
|
|
||||||
struct screen_t {
|
struct screen_t {
|
||||||
int32_t x;
|
int32_t x;
|
||||||
int32_t y;
|
int32_t y;
|
||||||
|
91
graphic.cpp
91
graphic.cpp
@ -1,19 +1,16 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#include "vdp2.h"
|
|
||||||
|
|
||||||
#include "coordinates.hpp"
|
|
||||||
#include "graphic.hpp"
|
#include "graphic.hpp"
|
||||||
|
#include "coordinates.hpp"
|
||||||
#include "font.hpp"
|
#include "font.hpp"
|
||||||
#include "start_size.hpp"
|
#include "start_size.hpp"
|
||||||
#include "control.hpp"
|
#include "control.hpp"
|
||||||
#include "render_map.hpp"
|
|
||||||
|
|
||||||
struct dialog_border {
|
struct dialog_border {
|
||||||
static constexpr uint8_t corner_top_left = 105;
|
static constexpr uint8_t corner_top_left = 105;
|
||||||
static constexpr uint8_t corner_top_right = 106;
|
static constexpr uint8_t corner_top_right = 106;
|
||||||
static constexpr uint8_t corner_bot_left = 107;
|
static constexpr uint8_t corner_bot_left = 107;
|
||||||
static constexpr uint8_t corner_bot_right = 108;
|
static constexpr uint8_t corner_bottom_right = 108;
|
||||||
static constexpr uint8_t vertical_end_cap = 109;
|
static constexpr uint8_t vertical_end_cap = 109;
|
||||||
static constexpr uint8_t vertical = 110;
|
static constexpr uint8_t vertical = 110;
|
||||||
static constexpr uint8_t horizontal = 111;
|
static constexpr uint8_t horizontal = 111;
|
||||||
@ -21,7 +18,7 @@ struct dialog_border {
|
|||||||
|
|
||||||
struct battle_border {
|
struct battle_border {
|
||||||
static constexpr uint8_t horizontal = 96;
|
static constexpr uint8_t horizontal = 96;
|
||||||
static constexpr uint8_t corner_bot_right = 97;
|
static constexpr uint8_t corner_bottom_right = 97;
|
||||||
static constexpr uint8_t arrow_right = 98;
|
static constexpr uint8_t arrow_right = 98;
|
||||||
static constexpr uint8_t vertical = 99;
|
static constexpr uint8_t vertical = 99;
|
||||||
static constexpr uint8_t corner_bot_left = 100;
|
static constexpr uint8_t corner_bot_left = 100;
|
||||||
@ -31,38 +28,84 @@ struct battle_border {
|
|||||||
static constexpr uint8_t arrow_left = 104;
|
static constexpr uint8_t arrow_left = 104;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void put_char(const uint32_t base_pattern,
|
#define S reinterpret_cast<const uint8_t *>
|
||||||
const int32_t x, const int32_t y,
|
|
||||||
const uint8_t c)
|
void draw_text(const uint32_t base_pattern,
|
||||||
|
const uint8_t * text,
|
||||||
|
const uint32_t x, const uint32_t y)
|
||||||
{
|
{
|
||||||
const int32_t ix = (0x2000 / 2)
|
uint8_t i = 0, x_o = 0;
|
||||||
+ ((cell_offset::y + y) * 64 + (cell_offset::x + x));
|
uint8_t c;
|
||||||
vdp2.vram.u16[ix] = ((base_pattern + c) & 0xfff) | PATTERN_NAME_TABLE_1WORD__PALETTE(1);
|
|
||||||
|
auto draw_ligature = [&](const uint8_t * l_text)
|
||||||
|
{
|
||||||
|
uint8_t j = 0;
|
||||||
|
uint8_t d;
|
||||||
|
while ((d = l_text[j++]) != 0)
|
||||||
|
put_char(base_pattern, x + x_o++, y, ascii_to_font(d));
|
||||||
|
};
|
||||||
|
while ((c = text[i++]) != 0) {
|
||||||
|
switch (c) {
|
||||||
|
case ligatures_t::pkmn:
|
||||||
|
{
|
||||||
|
static const uint8_t * pkmn = S("\xb2\xb3");
|
||||||
|
draw_ligature(pkmn);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ligatures_t::poke:
|
||||||
|
{
|
||||||
|
static const uint8_t * poke = S("POK\xe9");
|
||||||
|
draw_ligature(poke);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case ligatures_t::trainer:
|
||||||
|
{
|
||||||
|
static const uint8_t * trainer = S("TRAINER");
|
||||||
|
draw_ligature(trainer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
put_char(base_pattern, x + x_o++, y, ascii_to_font(c));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef S
|
||||||
|
|
||||||
void draw_box_border(const uint32_t base_pattern,
|
void draw_box_border(const uint32_t base_pattern,
|
||||||
const screen_t& top_left, const screen_t& bot_right)
|
const screen_cell_t& top_left, const screen_cell_t& bottom_right)
|
||||||
{
|
{
|
||||||
// place corners
|
// place corners
|
||||||
put_char(base_pattern, top_left.x, top_left.y, dialog_border::corner_top_left);
|
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, bottom_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, bottom_right.x, bottom_right.y, dialog_border::corner_bottom_right);
|
||||||
put_char(base_pattern, top_left.x, bot_right.y, dialog_border::corner_bot_left);
|
put_char(base_pattern, top_left.x, bottom_right.y, dialog_border::corner_bot_left);
|
||||||
|
|
||||||
for (int32_t y = top_left.y + 1; y < bot_right.y; y++) {
|
for (uint32_t y = top_left.y + 1; y < bottom_right.y; y++) {
|
||||||
// left vertical bar
|
// left vertical bar
|
||||||
put_char(base_pattern, top_left.x, y, dialog_border::vertical);
|
put_char(base_pattern, top_left.x, y, dialog_border::vertical);
|
||||||
// right vertical bar
|
// right vertical bar
|
||||||
put_char(base_pattern, bot_right.x, y, dialog_border::vertical);
|
put_char(base_pattern, bottom_right.x, y, dialog_border::vertical);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (int32_t x = top_left.x + 1; x < bot_right.x; x++) {
|
for (uint32_t x = top_left.x + 1; x < bottom_right.x; x++) {
|
||||||
// top horizontal bar
|
// top horizontal bar
|
||||||
put_char(base_pattern, x, top_left.y, dialog_border::horizontal);
|
put_char(base_pattern, x, top_left.y, dialog_border::horizontal);
|
||||||
|
|
||||||
// bottom horizontal bar
|
// bottom horizontal bar
|
||||||
put_char(base_pattern, x, bot_right.y, dialog_border::horizontal);
|
put_char(base_pattern, x, bottom_right.y, dialog_border::horizontal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_box_background(const uint32_t base_pattern,
|
||||||
|
const screen_cell_t& top_left, const screen_cell_t& bottom_right)
|
||||||
|
{
|
||||||
|
for (uint32_t x = top_left.x + 1; x < bottom_right.x; x++) {
|
||||||
|
for (uint32_t y = top_left.y + 1; y < bottom_right.y; y++) {
|
||||||
|
put_char(base_pattern, x, y, ascii_to_font(' '));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,13 +113,7 @@ void dialog_t::draw(const uint32_t base_pattern,
|
|||||||
const start_size_t& text)
|
const start_size_t& text)
|
||||||
{
|
{
|
||||||
draw_box_border(base_pattern, top_left, bottom_right);
|
draw_box_border(base_pattern, top_left, bottom_right);
|
||||||
|
draw_box_background(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 ix = 0;
|
||||||
uint32_t x = top_left.x + 1;
|
uint32_t x = top_left.x + 1;
|
||||||
|
26
graphic.hpp
26
graphic.hpp
@ -1,11 +1,33 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "coordinates.hpp"
|
||||||
#include "start_size.hpp"
|
#include "start_size.hpp"
|
||||||
|
#include "render_map.hpp" // for cell_offset
|
||||||
|
#include "vdp2.h"
|
||||||
|
|
||||||
|
static inline void put_char(const uint32_t base_pattern,
|
||||||
|
const int32_t x, const int32_t y, // in cells
|
||||||
|
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_text(const uint32_t base_pattern,
|
||||||
|
const uint8_t * text,
|
||||||
|
const uint32_t x, const uint32_t y);
|
||||||
|
|
||||||
|
void draw_box_border(const uint32_t base_pattern,
|
||||||
|
const screen_cell_t& top_left, const screen_cell_t& bottom_right);
|
||||||
|
|
||||||
|
void draw_box_background(const uint32_t base_pattern,
|
||||||
|
const screen_cell_t& top_left, const screen_cell_t& bottom_right);
|
||||||
|
|
||||||
struct dialog_t
|
struct dialog_t
|
||||||
{
|
{
|
||||||
static constexpr screen_t top_left = { 0, 12};
|
static constexpr screen_cell_t top_left = { 0, 12};
|
||||||
static constexpr screen_t bottom_right = {19, 17};
|
static constexpr screen_cell_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);
|
const start_size_t& text);
|
||||||
|
7
main.cpp
7
main.cpp
@ -24,6 +24,7 @@
|
|||||||
#include "ledge_tiles.hpp"
|
#include "ledge_tiles.hpp"
|
||||||
|
|
||||||
#include "graphic.hpp"
|
#include "graphic.hpp"
|
||||||
|
#include "menu.hpp"
|
||||||
|
|
||||||
struct draw_t {
|
struct draw_t {
|
||||||
struct {
|
struct {
|
||||||
@ -420,7 +421,7 @@ void update()
|
|||||||
else if (event::cursor_right()) collision_move(maps[state.map], actor_t::right);
|
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_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::cursor_down() ) collision_move(maps[state.map], actor_t::down);
|
||||||
else if (event::button_a() ) check_sign();
|
//else if (event::button_a() ) check_sign();
|
||||||
}
|
}
|
||||||
|
|
||||||
void render()
|
void render()
|
||||||
@ -437,6 +438,10 @@ void render()
|
|||||||
vdp2.reg.SCYDN0 = 0;
|
vdp2.reg.SCYDN0 = 0;
|
||||||
|
|
||||||
render_map();
|
render_map();
|
||||||
|
|
||||||
|
draw_menu(state.draw.base_pattern.font, fight_menu);
|
||||||
|
cursor_t cursor = { 1, 1 };
|
||||||
|
draw_menu_cursor(state.draw.base_pattern.font, fight_menu, cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
|
73
menu.cpp
Normal file
73
menu.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#include "graphic.hpp"
|
||||||
|
#include "menu.hpp"
|
||||||
|
#include "control.hpp"
|
||||||
|
|
||||||
|
#define POKE "\x94"
|
||||||
|
#define TRAINER "\x92"
|
||||||
|
#define PKMN "\x96"
|
||||||
|
#define S(v) reinterpret_cast<const uint8_t *>(v)
|
||||||
|
|
||||||
|
const menu_t start_menu = {
|
||||||
|
.top_left = {10, 0},
|
||||||
|
.bottom_right = {19, 15},
|
||||||
|
.width = 1,
|
||||||
|
.height = 7,
|
||||||
|
.h_advance = 0,
|
||||||
|
.v_advance = 2,
|
||||||
|
|
||||||
|
.items = (menu_item_t[]){
|
||||||
|
{ S(POKE "DEX") },
|
||||||
|
{ S(POKE "MON") },
|
||||||
|
{ S("ITEM" ) },
|
||||||
|
{ S(TRAINER ) },
|
||||||
|
{ S("SAVE" ) },
|
||||||
|
{ S("OPTION" ) },
|
||||||
|
{ S("EXIT" ) },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const menu_t fight_menu = {
|
||||||
|
.top_left = {8, 12},
|
||||||
|
.bottom_right = {19, 17},
|
||||||
|
.width = 2,
|
||||||
|
.height = 2,
|
||||||
|
.h_advance = 6,
|
||||||
|
.v_advance = 2,
|
||||||
|
|
||||||
|
.items = (menu_item_t[]) {
|
||||||
|
{ S("FIGHT") }, { S(PKMN ) },
|
||||||
|
{ S("ITEM" ) }, { S("RUN") },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef S
|
||||||
|
|
||||||
|
void draw_menu(const uint32_t base_pattern,
|
||||||
|
const menu_t& menu)
|
||||||
|
{
|
||||||
|
draw_box_border(base_pattern,
|
||||||
|
menu.top_left, menu.bottom_right);
|
||||||
|
draw_box_background(base_pattern,
|
||||||
|
menu.top_left, menu.bottom_right);
|
||||||
|
|
||||||
|
for (uint32_t y = 0; y < menu.height; y++) {
|
||||||
|
for (uint32_t x = 0; x < menu.width; x++) {
|
||||||
|
const menu_item_t& item = menu.items[menu.width * y + x];
|
||||||
|
|
||||||
|
const uint32_t cell_x = menu.top_left.x + 2 + (menu.h_advance * x);
|
||||||
|
const uint32_t cell_y = menu.top_left.y + menu.v_advance + (menu.v_advance * y);
|
||||||
|
|
||||||
|
draw_text(base_pattern, item.label, cell_x, cell_y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_menu_cursor(const uint32_t base_pattern,
|
||||||
|
const menu_t& menu,
|
||||||
|
const cursor_t& cursor)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
31
menu.hpp
Normal file
31
menu.hpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include "coordinates.hpp"
|
||||||
|
|
||||||
|
struct menu_item_t {
|
||||||
|
const uint8_t * label;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct menu_t {
|
||||||
|
screen_cell_t top_left; // in cells
|
||||||
|
screen_cell_t bottom_right; // in cells
|
||||||
|
uint8_t width; // in menu items
|
||||||
|
uint8_t height; // in menu items
|
||||||
|
uint8_t h_advance; // in cells
|
||||||
|
uint8_t v_advance; // in cells
|
||||||
|
|
||||||
|
const menu_item_t * items;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cursor_t {
|
||||||
|
uint16_t x; // in menu items
|
||||||
|
uint16_t y; // in menu items
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const menu_t start_menu;
|
||||||
|
extern const menu_t fight_menu;
|
||||||
|
|
||||||
|
void draw_menu(const uint32_t base_pattern,
|
||||||
|
const menu_t& menu);
|
||||||
|
|
||||||
|
void draw_menu_cursor(const uint32_t base_pattern,
|
||||||
|
const menu_t& menu,
|
||||||
|
const cursor_t& cursor);
|
Loading…
x
Reference in New Issue
Block a user