From b39d0c28b40073e0af09703a724cf758432a92aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrea=20Orr=C3=B9?= Date: Wed, 28 May 2014 10:31:54 +0200 Subject: [PATCH] File browser. --- src/cartridge.cpp | 10 ++++++- src/cartridge.hpp | 1 + src/gui.cpp | 39 ++++++++++++++++++------ src/gui.hpp | 1 + src/main.cpp | 6 ---- src/menu.hpp | 75 +++++++++++++++++++++++++++++++++++++++++++---- 6 files changed, 110 insertions(+), 22 deletions(-) diff --git a/src/cartridge.cpp b/src/cartridge.cpp index 84e46ab..aedd85a 100644 --- a/src/cartridge.cpp +++ b/src/cartridge.cpp @@ -1,4 +1,5 @@ #include +#include "cpu.hpp" #include "mappers/mapper0.hpp" #include "mappers/mapper1.hpp" #include "mappers/mapper4.hpp" @@ -7,7 +8,7 @@ namespace Cartridge { -Mapper* mapper; // Mapper chip. +Mapper* mapper = nullptr; // Mapper chip. /* PRG-ROM access */ template u8 access(u16 addr, u8 v) @@ -50,6 +51,13 @@ void load(const char* fileName) case 1: mapper = new Mapper1(rom); break; case 4: mapper = new Mapper4(rom); break; } + + CPU::power(); +} + +bool loaded() +{ + return mapper != nullptr; } diff --git a/src/cartridge.hpp b/src/cartridge.hpp index 7816682..c3bd104 100644 --- a/src/cartridge.hpp +++ b/src/cartridge.hpp @@ -8,6 +8,7 @@ template u8 access(u16 addr, u8 v = 0); template u8 chr_access(u16 addr, u8 v = 0); void signal_scanline(); void load(const char* fname); +bool loaded(); } diff --git a/src/gui.cpp b/src/gui.cpp index 4af013e..9762b56 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -1,5 +1,6 @@ #include #include +#include "cartridge.hpp" #include "cpu.hpp" #include "menu.hpp" #include "gui.hpp" @@ -14,16 +15,22 @@ SDL_Texture* gameTexture; TTF_Font* font; u8 const* keys; -// Status: -bool pause = false; +// Menus: Menu* menu; +Menu mainMenu; +Menu settingsMenu; +FileMenu* fileMenu; + +bool pause = true; /* Initialize GUI */ void init() { + // Initialize graphics system: SDL_Init(SDL_INIT_VIDEO); TTF_Init(); + // Initialize graphics structures: window = SDL_CreateWindow ("LaiNES", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, 0); @@ -38,11 +45,17 @@ void init() font = TTF_OpenFont("res/font.ttf", fontPt); keys = SDL_GetKeyboardState(0); - signal(SIGINT, SIG_DFL); + signal(SIGINT, SIG_DFL); // CTRL+C kills the application. - menu = new Menu({ "Load ROM", - "Settings", - "Exit" }); + // Menus: + 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("Controls"); + settingsMenu.add("Video"); + fileMenu = new FileMenu; + menu = &mainMenu; } /* Render a texture on screen (-1 to center on an axis) */ @@ -109,6 +122,12 @@ void render() SDL_RenderPresent(renderer); } +void toggle_pause() +{ + pause = not pause; + menu = mainMenu.reset(); +} + /* Run the emulator */ void run() { @@ -129,11 +148,13 @@ void run() { case SDL_QUIT: return; case SDL_KEYDOWN: - if (keys[SDL_SCANCODE_ESCAPE]) - pause = not pause; - else if (pause) menu->update(keys); + if (keys[SDL_SCANCODE_ESCAPE] and Cartridge::loaded()) + toggle_pause(); + else if (pause) + menu->update(keys); } + if (not pause) CPU::run_frame(); render(); diff --git a/src/gui.hpp b/src/gui.hpp index bf12372..4cc3970 100644 --- a/src/gui.hpp +++ b/src/gui.hpp @@ -12,6 +12,7 @@ const unsigned height = 240; const unsigned fontPt = 16; // Font size. void init(); +void toggle_pause(); void run(); SDL_Texture* gen_text(std::string text, SDL_Color color); diff --git a/src/main.cpp b/src/main.cpp index e36a671..4e0aee0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,15 +1,9 @@ -#include "cartridge.hpp" -#include "cpu.hpp" #include "gui.hpp" -#include "ppu.hpp" int main(int argc, char *argv[]) { GUI::init(); - Cartridge::load(argv[1]); - CPU::power(); - GUI::run(); return 0; diff --git a/src/menu.hpp b/src/menu.hpp index ddb66d7..bab20f5 100644 --- a/src/menu.hpp +++ b/src/menu.hpp @@ -1,37 +1,53 @@ #pragma once +#include +#include +#include +#include #include +#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 }; - std::string label; + string label; + function callback; + SDL_Texture* selected; SDL_Texture* unselected; - MenuEntry(std::string label) + MenuEntry(string label, function callback = []{}) { this->label = label; + this->callback = callback; unselected = gen_text(label, white); selected = gen_text(label, red); } + + ~MenuEntry() + { + SDL_DestroyTexture(selected); + SDL_DestroyTexture(unselected); + } }; class Menu { - std::vector entries; + protected: + vector entries; int cursor = 0; public: - Menu(std::vector labels) + void add(string label, function callback = []{}) { - for (auto label : labels) - entries.push_back(new MenuEntry(label)); + entries.push_back(new MenuEntry(label, callback)); } void update(u8 const* keys) @@ -40,6 +56,8 @@ class Menu cursor++; else if (keys[SDL_SCANCODE_UP] and cursor > 0) cursor--; + else if (keys[SDL_SCANCODE_RETURN]) + entries[cursor]->callback(); } void render() @@ -48,6 +66,51 @@ class Menu render_texture(entries[i]->unselected, -1, i * 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(); + } };