Commit 6a71d6f9 authored by Jack's avatar Jack
Browse files

working on MenuView

parent 7c37cd90
......@@ -168,6 +168,7 @@
<ClCompile Include="..\..\..\src\main.cpp" />
<ClCompile Include="..\..\..\src\test\test.cpp" />
<ClCompile Include="..\..\..\src\views\game_view.cpp" />
<ClCompile Include="..\..\..\src\views\menu_view.cpp" />
<ClCompile Include="..\..\..\src\views\view_manager.cpp" />
<ClCompile Include="..\..\..\src\vm\gfx.cpp" />
<ClCompile Include="..\..\..\src\vm\lua_bridge.cpp" />
......
......@@ -278,5 +278,8 @@
<ClCompile Include="..\..\..\src\vm\memory.cpp">
<Filter>src\vm</Filter>
</ClCompile>
<ClCompile Include="..\..\..\src\views\menu_view.cpp">
<Filter>src\views</Filter>
</ClCompile>
</ItemGroup>
</Project>
\ No newline at end of file
......@@ -64,24 +64,13 @@ void GameView::render()
_frameCounter = 0;
//SDL_FreeFormat(format);
// save previous button state for btnp function
machine.init(_output);
namespace r8 = retro8;
SDL_Surface* font = IMG_Load("pico8_font.png");
machine.font().load(font);
_font = SDL_CreateTextureFromSurface(manager->renderer(), font);
SDL_FreeSurface(font);
machine.code().loadAPI();
retro8::io::Loader loader;
r8::io::Loader loader;
if (_path.empty())
_path = "cartridges/pico-racer.png";
_path = "cartridges/pico-checkmate.p8";
loader.load(_path, machine);
machine.memory().backupCartridge();
......@@ -139,10 +128,10 @@ else
SDL_RenderCopy(renderer, _outputTexture, nullptr, &dest);
text(_path.c_str(), 10, 10);
manager->text(_path.c_str(), 10, 10);
char buffer[16];
sprintf(buffer, "%.0f/%c0", 1000.0f / manager->lastFrameTicks(), machine.code().require60fps() ? '6' : '3');
text(buffer, 10, 22);
manager->text(buffer, 10, 22);
++_frameCounter;
......@@ -227,19 +216,6 @@ else
#endif
}
void GameView::text(const std::string& text, int32_t x, int32_t y)
{
constexpr float scale = 2.0;
constexpr int32_t GLYPHS_PER_ROW = 16;
for (size_t i = 0; i < text.length(); ++i)
{
SDL_Rect src = { 8 * (text[i] % GLYPHS_PER_ROW), 8 * (text[i] / GLYPHS_PER_ROW), 4, 6 };
SDL_Rect dest = { x + 4 * i * scale, y, 4 * scale, 6 * scale };
SDL_RenderCopy(manager->renderer(), _font, &src, &dest);
}
}
void GameView::manageKeyRepeat()
{
static constexpr uint32_t TICKS_FOR_FIRST_REPEAT = 15;
......@@ -347,6 +323,6 @@ GameView::~GameView()
{
SDL_FreeSurface(_output);
SDL_DestroyTexture(_outputTexture);
//TODO: the _init future is not destroyed
machine.sound().close();
}
......@@ -31,7 +31,6 @@ namespace ui
SDL_Surface* _output;
SDL_Texture* _outputTexture;
SDL_Texture* _font;
std::string _path;
......@@ -66,6 +65,20 @@ namespace ui
void loadCartridge(const std::string& path) { _path = path; }
void text(const std::string& text, int32_t x, int32_t y);
};
class MenuView : public View
{
private:
ViewManager* _gvm;
public:
MenuView(ViewManager* manager);
~MenuView();
void handleKeyboardEvent(const SDL_Event& event) override;
void handleMouseEvent(const SDL_Event& event) override;
void render() override;
};
}
#include "main_view.h"
using namespace ui;
struct MenuEntry
{
enum class Type
{
SUB_MENU,
ENTRY
};
Type type;
std::string caption;
mutable std::function<void(void)> lambda;
MenuEntry(const std::string& caption) : type(Type::ENTRY), caption(caption) { }
};
static const std::vector<MenuEntry> mainMenu = {
MenuEntry("resume"),
MenuEntry("help"),
MenuEntry("options"),
MenuEntry("reset"),
MenuEntry("exit")
};
const std::vector<MenuEntry>* menu = &mainMenu;
std::vector<MenuEntry>::const_iterator selected = menu->begin();
MenuView::MenuView(ViewManager* gvm) : _gvm(gvm)
{
mainMenu[4].lambda = [this]() {
_gvm->exit();
};
}
MenuView::~MenuView() { }
void MenuView::handleKeyboardEvent(const SDL_Event& event)
{
if (event.type == SDL_KEYDOWN)
{
switch (event.key.keysym.sym)
{
case SDLK_UP: if (selected > menu->begin()) --selected; else selected = menu->end() - 1; break;
case SDLK_DOWN: if (selected < menu->end() - 1) ++selected; else selected = menu->begin(); break;
}
}
}
void MenuView::handleMouseEvent(const SDL_Event& event)
{
}
void MenuView::render()
{
constexpr int32_t W = 320;
constexpr int32_t H = 240;
auto renderer = _gvm->renderer();
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_SetRenderDrawColor(renderer, 20, 20, 40, 255);
SDL_Rect border = { 0, 0, W, H };
SDL_RenderDrawRect(renderer, &border);
_gvm->text("retro8", W / 2 + 2, 20 + 2, { 0, 22, 120 }, TextAlign::CENTER, 4.0f);
_gvm->text("retro8", W / 2, 20, { 0, 47, 255 }, TextAlign::CENTER, 4.0f);
_gvm->text("v0.1", W / 2 + _gvm->textWidth("retro8", 4.0)/2 + 3, 34, { 0, 47, 255 }, TextAlign::LEFT, 2.0f);
retro8::point_t menuBase = { W / 2, 80 };
for (auto it = menu->begin(); it != menu->end(); ++it)
{
const SDL_Color color = it == selected ? SDL_Color{ 255, 255, 0 } : SDL_Color{ 255,255,255 };
_gvm->text(it->caption, menuBase.x, menuBase.y, color, TextAlign::CENTER, 2.0f);
menuBase.y += 16;
}
}
\ No newline at end of file
......@@ -8,24 +8,37 @@
#define PREFIX ""
#endif
ui::ViewManager::ViewManager() : SDL<ui::ViewManager, ui::ViewManager>(*this, *this)
using namespace ui;
extern retro8::Machine machine;
ui::ViewManager::ViewManager() : SDL<ui::ViewManager, ui::ViewManager>(*this, *this), _font(nullptr)
{
views[0] = new GameView(this);
view = views[0];
views[1] = new MenuView(this);
view = views[1];
}
void ui::ViewManager::deinit()
{
SDL_DestroyTexture(_font);
SDL::deinit();
}
bool ui::ViewManager::loadData()
{
SDL_Surface* font = IMG_Load("pico8_font.png");
machine.font().load(font);
_font = SDL_CreateTextureFromSurface(_renderer, font);
SDL_SetTextureBlendMode(_font, SDL_BLENDMODE_BLEND);
SDL_FreeSurface(font);
return true;
}
bool pressed = false;
void ui::ViewManager::handleKeyboardEvent(const SDL_Event& event, bool press)
{
view->handleKeyboardEvent(event);
......@@ -40,4 +53,40 @@ void ui::ViewManager::handleMouseEvent(const SDL_Event& event)
void ui::ViewManager::render()
{
view->render();
}
void ui::ViewManager::text(const std::string& text, int32_t x, int32_t y)
{
constexpr float scale = 2.0;
constexpr int32_t GLYPHS_PER_ROW = 16;
for (size_t i = 0; i < text.length(); ++i)
{
SDL_Rect src = { 8 * (text[i] % GLYPHS_PER_ROW), 8 * (text[i] / GLYPHS_PER_ROW), 4, 6 };
SDL_Rect dest = { x + 4 * i * scale, y, 4 * scale, 6 * scale };
SDL_RenderCopy(_renderer, _font, &src, &dest);
}
}
void ViewManager::text(const std::string& text, int32_t x, int32_t y, SDL_Color color, TextAlign align, float scale)
{
constexpr int32_t GLYPHS_PER_ROW = 16;
const int32_t width = text.size() * 4 * scale;
if (align == TextAlign::CENTER)
x -= width / 2;
else if (align == TextAlign::RIGHT)
x -= width;
SDL_SetTextureColorMod(_font, color.r, color.g, color.b);
for (size_t i = 0; i < text.length(); ++i)
{
SDL_Rect src = { 8 * (text[i] % GLYPHS_PER_ROW), 8 * (text[i] / GLYPHS_PER_ROW), 4, 6 };
SDL_Rect dest = { x + 4 * i * scale, y, 4 * scale, 6 * scale };
SDL_RenderCopy(_renderer, _font, &src, &dest);
}
SDL_SetTextureColorMod(_font, 255, 255, 255);
}
\ No newline at end of file
......@@ -14,10 +14,9 @@ namespace ui
virtual void handleMouseEvent(const SDL_Event& event) = 0;
};
struct ButtonStyle
enum TextAlign
{
bool pressed;
bool hovered;
LEFT, CENTER, RIGHT
};
class GameView;
......@@ -28,6 +27,8 @@ namespace ui
using view_t = View;
static const size_t VIEW_COUNT = 1;
SDL_Texture* _font;
private:
std::array<view_t*, 2> views;
view_t* view;
......@@ -43,8 +44,14 @@ namespace ui
void deinit();
SDL_Texture* font() { return _font; }
//TODO: hacky cast to avoid header inclusion
GameView* gameView() { return (GameView*)views[0]; }
int32_t textWidth(const std::string& text, float scale = 2.0f) const { return text.length() * scale * 4; }
void text(const std::string& text, int32_t x, int32_t y, SDL_Color color, TextAlign align, float scale = 2.0f);
void text(const std::string& text, int32_t x, int32_t y);
};
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment