File browser.

This commit is contained in:
Andrea Orrù 2014-05-28 10:31:54 +02:00
parent b36e315265
commit b39d0c28b4
6 changed files with 110 additions and 22 deletions

View file

@ -1,4 +1,5 @@
#include <cstdio> #include <cstdio>
#include "cpu.hpp"
#include "mappers/mapper0.hpp" #include "mappers/mapper0.hpp"
#include "mappers/mapper1.hpp" #include "mappers/mapper1.hpp"
#include "mappers/mapper4.hpp" #include "mappers/mapper4.hpp"
@ -7,7 +8,7 @@
namespace Cartridge { namespace Cartridge {
Mapper* mapper; // Mapper chip. Mapper* mapper = nullptr; // Mapper chip.
/* PRG-ROM access */ /* PRG-ROM access */
template <bool wr> u8 access(u16 addr, u8 v) template <bool wr> u8 access(u16 addr, u8 v)
@ -50,6 +51,13 @@ void load(const char* fileName)
case 1: mapper = new Mapper1(rom); break; case 1: mapper = new Mapper1(rom); break;
case 4: mapper = new Mapper4(rom); break; case 4: mapper = new Mapper4(rom); break;
} }
CPU::power();
}
bool loaded()
{
return mapper != nullptr;
} }

View file

@ -8,6 +8,7 @@ template <bool wr> u8 access(u16 addr, u8 v = 0);
template <bool wr> u8 chr_access(u16 addr, u8 v = 0); template <bool wr> u8 chr_access(u16 addr, u8 v = 0);
void signal_scanline(); void signal_scanline();
void load(const char* fname); void load(const char* fname);
bool loaded();
} }

View file

@ -1,5 +1,6 @@
#include <csignal> #include <csignal>
#include <SDL2/SDL_ttf.h> #include <SDL2/SDL_ttf.h>
#include "cartridge.hpp"
#include "cpu.hpp" #include "cpu.hpp"
#include "menu.hpp" #include "menu.hpp"
#include "gui.hpp" #include "gui.hpp"
@ -14,16 +15,22 @@ SDL_Texture* gameTexture;
TTF_Font* font; TTF_Font* font;
u8 const* keys; u8 const* keys;
// Status: // Menus:
bool pause = false;
Menu* menu; Menu* menu;
Menu mainMenu;
Menu settingsMenu;
FileMenu* fileMenu;
bool pause = true;
/* Initialize GUI */ /* Initialize GUI */
void init() void init()
{ {
// Initialize graphics system:
SDL_Init(SDL_INIT_VIDEO); SDL_Init(SDL_INIT_VIDEO);
TTF_Init(); TTF_Init();
// Initialize graphics structures:
window = SDL_CreateWindow ("LaiNES", window = SDL_CreateWindow ("LaiNES",
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
width, height, 0); width, height, 0);
@ -38,11 +45,17 @@ void init()
font = TTF_OpenFont("res/font.ttf", fontPt); font = TTF_OpenFont("res/font.ttf", fontPt);
keys = SDL_GetKeyboardState(0); keys = SDL_GetKeyboardState(0);
signal(SIGINT, SIG_DFL); signal(SIGINT, SIG_DFL); // CTRL+C kills the application.
menu = new Menu({ "Load ROM", // Menus:
"Settings", mainMenu.add("Load ROM", []{ menu = fileMenu->reset(); });
"Exit" }); mainMenu.add("Settings", []{ menu = settingsMenu.reset(); });
mainMenu.add("Exit" , []{ exit(0); });
settingsMenu.add("<-", []{ menu = mainMenu.reset(); });
settingsMenu.add("Controls");
settingsMenu.add("Video");
fileMenu = new FileMenu;
menu = &mainMenu;
} }
/* Render a texture on screen (-1 to center on an axis) */ /* Render a texture on screen (-1 to center on an axis) */
@ -109,6 +122,12 @@ void render()
SDL_RenderPresent(renderer); SDL_RenderPresent(renderer);
} }
void toggle_pause()
{
pause = not pause;
menu = mainMenu.reset();
}
/* Run the emulator */ /* Run the emulator */
void run() void run()
{ {
@ -129,11 +148,13 @@ void run()
{ {
case SDL_QUIT: return; case SDL_QUIT: return;
case SDL_KEYDOWN: case SDL_KEYDOWN:
if (keys[SDL_SCANCODE_ESCAPE]) if (keys[SDL_SCANCODE_ESCAPE] and Cartridge::loaded())
pause = not pause; toggle_pause();
else if (pause) menu->update(keys); else if (pause)
menu->update(keys);
} }
if (not pause) CPU::run_frame(); if (not pause) CPU::run_frame();
render(); render();

View file

@ -12,6 +12,7 @@ const unsigned height = 240;
const unsigned fontPt = 16; // Font size. const unsigned fontPt = 16; // Font size.
void init(); void init();
void toggle_pause();
void run(); void run();
SDL_Texture* gen_text(std::string text, SDL_Color color); SDL_Texture* gen_text(std::string text, SDL_Color color);

View file

@ -1,15 +1,9 @@
#include "cartridge.hpp"
#include "cpu.hpp"
#include "gui.hpp" #include "gui.hpp"
#include "ppu.hpp"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
GUI::init(); GUI::init();
Cartridge::load(argv[1]);
CPU::power();
GUI::run(); GUI::run();
return 0; return 0;

View file

@ -1,37 +1,53 @@
#pragma once #pragma once
#include <dirent.h>
#include <functional>
#include <SDL2/SDL.h>
#include <unistd.h>
#include <vector> #include <vector>
#include "cartridge.hpp"
#include "gui.hpp" #include "gui.hpp"
namespace GUI { namespace GUI {
using namespace std;
struct MenuEntry struct MenuEntry
{ {
SDL_Color white = { 255, 255, 255 }; SDL_Color white = { 255, 255, 255 };
SDL_Color red = { 255, 0, 0 }; SDL_Color red = { 255, 0, 0 };
std::string label; string label;
function<void()> callback;
SDL_Texture* selected; SDL_Texture* selected;
SDL_Texture* unselected; SDL_Texture* unselected;
MenuEntry(std::string label) MenuEntry(string label, function<void()> callback = []{})
{ {
this->label = label; this->label = label;
this->callback = callback;
unselected = gen_text(label, white); unselected = gen_text(label, white);
selected = gen_text(label, red); selected = gen_text(label, red);
} }
~MenuEntry()
{
SDL_DestroyTexture(selected);
SDL_DestroyTexture(unselected);
}
}; };
class Menu class Menu
{ {
std::vector<MenuEntry*> entries; protected:
vector<MenuEntry*> entries;
int cursor = 0; int cursor = 0;
public: public:
Menu(std::vector<std::string> labels) void add(string label, function<void()> callback = []{})
{ {
for (auto label : labels) entries.push_back(new MenuEntry(label, callback));
entries.push_back(new MenuEntry(label));
} }
void update(u8 const* keys) void update(u8 const* keys)
@ -40,6 +56,8 @@ class Menu
cursor++; cursor++;
else if (keys[SDL_SCANCODE_UP] and cursor > 0) else if (keys[SDL_SCANCODE_UP] and cursor > 0)
cursor--; cursor--;
else if (keys[SDL_SCANCODE_RETURN])
entries[cursor]->callback();
} }
void render() void render()
@ -48,6 +66,51 @@ class Menu
render_texture(entries[i]->unselected, -1, i * fontPt); render_texture(entries[i]->unselected, -1, i * fontPt);
render_texture(entries[cursor]->selected, -1, cursor * fontPt); render_texture(entries[cursor]->selected, -1, cursor * fontPt);
} }
virtual Menu* reset()
{
cursor = 0;
return this;
}
};
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);
}
public:
Menu* reset()
{
change_dir(getwd(NULL));
return this;
}
FileMenu()
{
reset();
}
}; };