New font, decoupling menus.

This commit is contained in:
Andrea Orrù 2014-05-28 11:31:58 +02:00
parent b39d0c28b4
commit 240793027f
4 changed files with 114 additions and 83 deletions

BIN
res/font.ttf Executable file → Normal file

Binary file not shown.

View file

@ -51,7 +51,7 @@ void init()
mainMenu.add("Load ROM", []{ menu = fileMenu->reset(); });
mainMenu.add("Settings", []{ menu = settingsMenu.reset(); });
mainMenu.add("Exit" , []{ exit(0); });
settingsMenu.add("<-", []{ menu = mainMenu.reset(); });
settingsMenu.add("<", []{ menu = mainMenu.reset(); });
settingsMenu.add("Controls");
settingsMenu.add("Video");
fileMenu = new FileMenu;
@ -122,6 +122,7 @@ void render()
SDL_RenderPresent(renderer);
}
/* Play/stop the game */
void toggle_pause()
{
pause = not pause;

98
src/menu.cpp Normal file
View file

@ -0,0 +1,98 @@
#include <dirent.h>
#include <unistd.h>
#include "cartridge.hpp"
#include "gui.hpp"
#include "menu.hpp"
namespace GUI {
using namespace std;
MenuEntry::MenuEntry(string label, function<void()> callback)
{
this->label = label;
this->callback = callback;
unselected = gen_text(label, white);
selected = gen_text(label, red);
}
MenuEntry::~MenuEntry()
{
SDL_DestroyTexture(selected);
SDL_DestroyTexture(unselected);
}
void Menu::add(string label, function<void()> callback)
{
entries.push_back(new MenuEntry(label, callback));
}
void Menu::update(u8 const* keys)
{
if (keys[SDL_SCANCODE_DOWN] and cursor < entries.size() - 1)
cursor++;
else if (keys[SDL_SCANCODE_UP] and cursor > 0)
cursor--;
else if (keys[SDL_SCANCODE_RETURN])
entries[cursor]->callback();
}
void Menu::render()
{
for (int i = 0; i < entries.size(); i++)
render_texture(entries[i]->unselected, -1, i * fontPt);
render_texture(entries[cursor]->selected, -1, cursor * fontPt);
}
Menu* Menu::reset()
{
cursor = 0;
return this;
}
void FileMenu::change_dir(string dir)
{
for (auto entry : entries)
delete entry;
entries.clear();
cursor = 0;
struct dirent* dirp;
DIR* dp = opendir(dir.c_str());
while ((dirp = readdir(dp)) != NULL)
{
string name = dirp->d_name;
string path = dir + "/" + name;
if (name[0] == '.' and name != "..") continue;
if (dirp->d_type == DT_DIR)
add(name + "/", [=]{ change_dir(path); });
else
add(name, [=]{ Cartridge::load(path.c_str()); toggle_pause(); });
}
closedir(dp);
}
void FileMenu::render()
{
for (int i = 0; i < entries.size(); i++)
render_texture(entries[i]->unselected, 10, i * fontPt);
render_texture(entries[cursor]->selected, 10, cursor * fontPt);
}
Menu* FileMenu::reset()
{
change_dir(getwd(NULL));
return this;
}
FileMenu::FileMenu()
{
reset();
}
}

View file

@ -1,116 +1,48 @@
#pragma once
#include <dirent.h>
#include <functional>
#include <SDL2/SDL.h>
#include <unistd.h>
#include <string>
#include <vector>
#include "cartridge.hpp"
#include "gui.hpp"
namespace GUI {
using namespace std;
struct MenuEntry
{
SDL_Color white = { 255, 255, 255 };
SDL_Color red = { 255, 0, 0 };
string label;
function<void()> callback;
std::string label;
std::function<void()> callback;
SDL_Texture* selected;
SDL_Texture* unselected;
MenuEntry(string label, function<void()> callback = []{})
{
this->label = label;
this->callback = callback;
unselected = gen_text(label, white);
selected = gen_text(label, red);
}
~MenuEntry()
{
SDL_DestroyTexture(selected);
SDL_DestroyTexture(unselected);
}
MenuEntry(std::string label, std::function<void()> callback);
~MenuEntry();
};
class Menu
{
protected:
vector<MenuEntry*> entries;
std::vector<MenuEntry*> entries;
int cursor = 0;
public:
void add(string label, function<void()> callback = []{})
{
entries.push_back(new MenuEntry(label, callback));
}
void update(u8 const* keys)
{
if (keys[SDL_SCANCODE_DOWN] and cursor < entries.size() - 1)
cursor++;
else if (keys[SDL_SCANCODE_UP] and cursor > 0)
cursor--;
else if (keys[SDL_SCANCODE_RETURN])
entries[cursor]->callback();
}
void render()
{
for (int i = 0; i < entries.size(); i++)
render_texture(entries[i]->unselected, -1, i * fontPt);
render_texture(entries[cursor]->selected, -1, cursor * fontPt);
}
virtual Menu* reset()
{
cursor = 0;
return this;
}
void add(std::string label, std::function<void()> callback = []{});
void update(u8 const* keys);
virtual void render();
virtual Menu* reset();
};
class FileMenu : public Menu
{
void change_dir(string dir)
{
for (auto entry : entries)
delete entry;
entries.clear();
cursor = 0;
struct dirent* dirp;
DIR* dp = opendir(dir.c_str());
while ((dirp = readdir(dp)) != NULL)
{
string name = dirp->d_name;
string path = dir + "/" + name;
if (name[0] == '.' and name != "..") continue;
if (dirp->d_type == DT_DIR)
add(name + "/", [=]{ change_dir(path); });
else
add(name, [=]{ Cartridge::load(path.c_str()); toggle_pause(); });
}
closedir(dp);
}
void change_dir(std::string dir);
public:
Menu* reset()
{
change_dir(getwd(NULL));
return this;
}
FileMenu()
{
reset();
}
void render();
Menu* reset();
FileMenu();
};