diff --git a/src/ui/SDL2/README.md b/src/ui/SDL2/README.md new file mode 100644 index 0000000..976fb7f --- /dev/null +++ b/src/ui/SDL2/README.md @@ -0,0 +1,16 @@ +# SDL GUI + +It's not the cleanest code, but it works, and is pretty modular. + +- `SDL_GUI` - `gui.h/cc` - Core SDL functionality + - Set up + teardown main Renderer, Window, Controllers, etc... + - Contains main Loop + - Initializes and routes events / output to and from `GUIModules` +- `gui_modules` - Individual components of the UI + - Implement simple interface (accept input, update self, render output) + - `EmuModule` - ANESE core + - Owns, updates, and presents the output of ANESE core + - Handles loading / unloading ROMs, Movies, and savs + - `MenuModule` - Menu system + - Runs the menu system + - Has reference to `EmuModule` (to load ROMs) diff --git a/src/ui/SDL2/config.cc b/src/ui/SDL2/config.cc index ec478f7..2dacf03 100644 --- a/src/ui/SDL2/config.cc +++ b/src/ui/SDL2/config.cc @@ -1,14 +1,67 @@ #include "config.h" +#include + +#include +#include + Config::Config() { this->ini.SetUnicode(); } -void Config::load(const char* filename) { +void Config::load(int argc, char* argv[]) { + // --------------------------- Argument Parsing --------------------------- // + + bool show_help = false; + auto cli + = clara::Help(show_help) + | clara::Opt(this->cli.log_cpu) + ["--log-cpu"] + ("Output CPU execution over STDOUT") + | clara::Opt(this->cli.no_sav) + ["--no-sav"] + ("Don't load/create sav files") + | clara::Opt(this->cli.ppu_timing_hack) + ["--alt-nmi-timing"] + ("Enable NMI timing fix \n" + "(fixes some games, eg: Bad Dudes, Solomon's Key)") + | clara::Opt(this->cli.record_fm2_path, "path") + ["--record-fm2"] + ("Record a movie in the fm2 format") + | clara::Opt(this->cli.replay_fm2_path, "path") + ["--replay-fm2"] + ("Replay a movie in the fm2 format") + | clara::Opt(this->cli.config_file, "path") + ["--config"] + ("Use custom config file") + | clara::Arg(this->cli.rom, "rom") + ("an iNES rom"); + + auto result = cli.parse(clara::Args(argc, argv)); + if(!result) { + std::cerr << "Error: " << result.errorMessage() << "\n"; + std::cerr << cli; + exit(1); + } + + if (show_help) { + std::cout << cli; + exit(1); + } + + // ------------------------- Config File Parsing ------------------------- -// + + // Get cross-platform config path (if no custom path specified) + if (this->cli.config_file.empty()) { + cfgpath::get_user_config_file(this->filename, 260, "anese"); + } else { + strcpy(this->filename, this->cli.config_file.c_str()); + } + // Try to load config, setting up a new one if none exists - if (SI_Error err = this->ini.LoadFile(filename)) { + if (SI_Error err = this->ini.LoadFile(this->filename)) { (void)err; // TODO: handle me? - fprintf(stderr, "[Config] Could not open config file %s!\n", filename); + fprintf(stderr, "[Config] Could not open config file %s!\n", this->filename); fprintf(stderr, "[Config] Will generate a new one.\n"); - this->save(filename); + this->save(); } // Load config vals @@ -16,12 +69,12 @@ void Config::load(const char* filename) { strcpy(this->roms_dir, this->ini.GetValue("paths", "roms_dir")); } -void Config::save(const char* filename) { +void Config::save() { this->ini.SetLongValue("ui", "window_scale", this->window_scale); this->ini.SetValue ("paths", "roms_dir", this->roms_dir); - if (SI_Error err = this->ini.SaveFile(filename)) { + if (SI_Error err = this->ini.SaveFile(this->filename)) { (void)err; // TODO: handle me? - fprintf(stderr, "[Config] Could not save config file %s!\n", filename); + fprintf(stderr, "[Config] Could not save config file %s!\n", this->filename); } } diff --git a/src/ui/SDL2/config.h b/src/ui/SDL2/config.h index a8d4837..dc72ea9 100644 --- a/src/ui/SDL2/config.h +++ b/src/ui/SDL2/config.h @@ -4,35 +4,36 @@ #include "common/util.h" -struct CLIArgs { - bool log_cpu = false; - bool no_sav = false; - bool ppu_timing_hack = false; - - std::string record_fm2_path; - std::string replay_fm2_path; - - std::string config_file; - - std::string rom; -}; - +// Config Manager, both CLI parsing and INI parse/save struct Config { private: CSimpleIniA ini; + char filename [260]; public: Config(); - void load(const char* filename); - void save(const char* filename); + void load(int argc, char* argv[]); + void save(); public: + /*---------- INI Config Args (saved) ----------*/ // UI uint window_scale = 2; - // Paths - char roms_dir [256] = { '.', '\0' }; - // I _would_ write `char roms_dir [256] = "."`, but I can;t. - // You know why? - // because g++4 has a compiler bug, and Travis fails on it. - // Weeeeeeeeeeeeeeeeee + char roms_dir [260] = { '.', '\0' }; + // I _would_ write `char roms_dir [260] = "."`, but I can't. + // Why? g++4 has a compiler bug, and Travis fails with that _valid_ syntax. + + /*---------- CLI Args (not saved) ----------*/ + struct { + bool log_cpu = false; + bool no_sav = false; + bool ppu_timing_hack = false; + + std::string record_fm2_path; + std::string replay_fm2_path; + + std::string config_file; + + std::string rom; + } cli; }; diff --git a/src/ui/SDL2/fs/util.h b/src/ui/SDL2/fs/util.h index c3b7a66..2eefe65 100644 --- a/src/ui/SDL2/fs/util.h +++ b/src/ui/SDL2/fs/util.h @@ -11,12 +11,12 @@ namespace ANESE_fs { namespace util { // this is pretty jank -static inline void get_abs_path(const char* path, char* out, unsigned int n) { +static inline void get_abs_path(char* abs_path, const char* path, unsigned int n) { #ifdef WIN32 - GetFullPathName(path, n, out, nullptr); + GetFullPathName(path, n, abs_path, nullptr); #else (void)n; - (void)realpath(path, out); + (void)realpath(path, abs_path); #endif } diff --git a/src/ui/SDL2/gui.cc b/src/ui/SDL2/gui.cc index fa51f81..8acde75 100644 --- a/src/ui/SDL2/gui.cc +++ b/src/ui/SDL2/gui.cc @@ -1,72 +1,13 @@ #include "gui.h" #include -#include -#include -#include #include -#include #include "common/util.h" -#include "common/serializable.h" - -#include "nes/cartridge/cartridge.h" -#include "nes/joy/controllers/standard.h" -#include "nes/nes.h" - -#include "fs/util.h" int SDL_GUI::init(int argc, char* argv[]) { - // --------------------------- Argument Parsing --------------------------- // - - bool show_help = false; - auto cli - = clara::Help(show_help) - | clara::Opt(this->args.log_cpu) - ["--log-cpu"] - ("Output CPU execution over STDOUT") - | clara::Opt(this->args.no_sav) - ["--no-sav"] - ("Don't load/create sav files") - | clara::Opt(this->args.ppu_timing_hack) - ["--alt-nmi-timing"] - ("Enable NMI timing fix \n" - "(fixes some games, eg: Bad Dudes, Solomon's Key)") - | clara::Opt(this->args.record_fm2_path, "path") - ["--record-fm2"] - ("Record a movie in the fm2 format") - | clara::Opt(this->args.replay_fm2_path, "path") - ["--replay-fm2"] - ("Replay a movie in the fm2 format") - | clara::Opt(this->args.config_file, "path") - ["--config"] - ("Use custom config file") - | clara::Arg(this->args.rom, "rom") - ("an iNES rom"); - - auto result = cli.parse(clara::Args(argc, argv)); - if(!result) { - std::cerr << "Error: " << result.errorMessage() << "\n"; - std::cerr << cli; - exit(1); - } - - if (show_help) { - std::cout << cli; - exit(1); - } - - // ------------------------- Config File Parsing ------------------------- -// - - // Get cross-platform config path (if no custom path specified) - if (this->args.config_file == "") { - char config_f_path [256]; - cfgpath::get_user_config_file(config_f_path, 256, "anese"); - this->args.config_file = config_f_path; - } - - this->config.load(this->args.config_file.c_str()); + this->config.load(argc, argv); // --------------------------- Init SDL2 Common --------------------------- // @@ -116,56 +57,15 @@ int SDL_GUI::init(int argc, char* argv[]) { SDL2_inprint::prepare_inline_font(); /*---------- Init GUI modules ----------*/ - this->emu = new EmuModule(this->sdl_common, this->args, this->config); - this->menu = new MenuModule(this->sdl_common, this->args, this->config, *this->emu); - - // TODO: put this somewhere else... - strcpy(this->menu->menu.directory, this->config.roms_dir); - - // ------------------------------ NES Params ------------------------------ // - - if (this->args.log_cpu) { this->emu->params.log_cpu = true; } - if (this->args.ppu_timing_hack) { this->emu->params.ppu_timing_hack = true; } - this->emu->nes.updated_params(); - - // ---------------------------- Movie Support ----------------------------- // - - if (this->args.replay_fm2_path != "") { - bool did_load = this->emu->fm2_replay.init(this->args.replay_fm2_path.c_str()); - if (!did_load) - fprintf(stderr, "[Replay][fm2] Movie loading failed!\n"); - fprintf(stderr, "[Replay][fm2] Movie successfully loaded!\n"); - } - - if (this->args.record_fm2_path != "") { - bool did_load = this->emu->fm2_record.init(this->args.record_fm2_path.c_str()); - if (!did_load) - fprintf(stderr, "[Record][fm2] Failed to setup Movie recording!\n"); - fprintf(stderr, "[Record][fm2] Movie recording is setup!\n"); - } - - // -------------------------- NES Initialization -------------------------- // - - // pass controllers to this->fm2_record - this->emu->fm2_record.set_joy(0, FM2_Controller::SI_GAMEPAD, &this->emu->joy_1); - this->emu->fm2_record.set_joy(1, FM2_Controller::SI_GAMEPAD, &this->emu->joy_2); - - // Check if there is fm2 to replay - if (this->emu->fm2_replay.is_enabled()) { - // plug in fm2 controllers - this->emu->nes.attach_joy(0, this->emu->fm2_replay.get_joy(0)); - this->emu->nes.attach_joy(1, this->emu->fm2_replay.get_joy(1)); - } else { - // plug in physical nes controllers - this->emu->nes.attach_joy(0, &this->emu->joy_1); - this->emu->nes.attach_joy(1, &this->emu->zap_2); - } + this->emu = new EmuModule(this->sdl_common, this->config); + this->menu = new MenuModule(this->sdl_common, this->config, *this->emu); // Load ROM if one has been passed as param - if (this->args.rom != "") { + if (this->config.cli.rom != "") { this->menu->in_menu = false; - int error = this->emu->load_rom(this->args.rom.c_str()); - if (error) return error; + int error = this->emu->load_rom(this->config.cli.rom.c_str()); + if (error) + return error; } return 0; @@ -174,21 +74,12 @@ int SDL_GUI::init(int argc, char* argv[]) { SDL_GUI::~SDL_GUI() { fprintf(stderr, "[SDL2] Stopping SDL2 GUI\n"); - // Cleanup ROM (unloading also creates savs) - this->emu->unload_rom(this->emu->cart); - delete this->emu->cart; - - // Update config - // TODO: put this somewhere else... - char new_roms_dir [256]; - ANESE_fs::util::get_abs_path(this->menu->menu.directory, new_roms_dir, 256); - strcpy(this->config.roms_dir, new_roms_dir); - - this->config.save(this->args.config_file.c_str()); - + // order matters (menu has ref to emu) delete this->menu; delete this->emu; + this->config.save(); + // SDL Cleanup // SDL_CloseAudioDevice(this->sdl_common.nes_audiodev); SDL_GameControllerClose(this->sdl_common.controller); diff --git a/src/ui/SDL2/gui.h b/src/ui/SDL2/gui.h index db4522d..d5918b5 100644 --- a/src/ui/SDL2/gui.h +++ b/src/ui/SDL2/gui.h @@ -1,39 +1,14 @@ #pragma once -#include -#include - -#include "nes/cartridge/cartridge.h" -#include "nes/joy/controllers/standard.h" -#include "nes/joy/controllers/zapper.h" -#include "nes/nes.h" - -#include "movies/fm2/record.h" -#include "movies/fm2/replay.h" - -#include -#include "util/Sound_Queue.h" - -#include - #include "config.h" -#include "nes/params.h" #include "gui_modules/module.h" #include "gui_modules/emu.h" #include "gui_modules/menu.h" -/** - * Implementations are strewn-across multiple files, as having everything in a - * single file became unwieldy. - */ - class SDL_GUI final { private: - // Command-line args - CLIArgs args; - - // Global config + // Config manager (also has CLI args) Config config; // Initialized once, passed by const-ref to all gui modules diff --git a/src/ui/SDL2/gui_modules/emu.cc b/src/ui/SDL2/gui_modules/emu.cc index 8e40d44..611949b 100644 --- a/src/ui/SDL2/gui_modules/emu.cc +++ b/src/ui/SDL2/gui_modules/emu.cc @@ -1,14 +1,16 @@ #include "emu.h" +#include + #include "../fs/load.h" #include "../fs/util.h" -EmuModule::EmuModule(const SDLCommon& sdl_common, const CLIArgs& cli_args, Config& config) -: GUIModule(sdl_common, cli_args, config) +EmuModule::EmuModule(const SDLCommon& sdl_common, Config& config) +: GUIModule(sdl_common, config) , params { this->sdl_common.SAMPLE_RATE, 100, false, false } , nes { this->params } { - /*---------- SDL init ----------*/ + /*------------------------------- SDL init -------------------------------*/ // nes screen texture this->sdl.screen_texture = SDL_CreateTexture( @@ -27,10 +29,54 @@ EmuModule::EmuModule(const SDLCommon& sdl_common, const CLIArgs& cli_args, Confi this->sdl.screen.y = 0; this->sdl.sound_queue.init(this->sdl_common.SAMPLE_RATE); + + // ---------------------------- Movie Support ----------------------------- // + + if (this->config.cli.replay_fm2_path != "") { + bool did_load = this->fm2_replay.init(this->config.cli.replay_fm2_path.c_str()); + if (!did_load) + fprintf(stderr, "[Replay][fm2] Movie loading failed!\n"); + fprintf(stderr, "[Replay][fm2] Movie successfully loaded!\n"); + } + + if (this->config.cli.record_fm2_path != "") { + bool did_load = this->fm2_record.init(this->config.cli.record_fm2_path.c_str()); + if (!did_load) + fprintf(stderr, "[Record][fm2] Failed to setup Movie recording!\n"); + fprintf(stderr, "[Record][fm2] Movie recording is setup!\n"); + } + + // -------------------------- NES Initialization -------------------------- // + + // pass controllers to this->fm2_record + this->fm2_record.set_joy(0, FM2_Controller::SI_GAMEPAD, &this->joy_1); + this->fm2_record.set_joy(1, FM2_Controller::SI_GAMEPAD, &this->joy_2); + + // Check if there is fm2 to replay + if (this->fm2_replay.is_enabled()) { + // plug in fm2 controllers + this->nes.attach_joy(0, this->fm2_replay.get_joy(0)); + this->nes.attach_joy(1, this->fm2_replay.get_joy(1)); + } else { + // plug in physical nes controllers + this->nes.attach_joy(0, &this->joy_1); + this->nes.attach_joy(1, &this->zap_2); + } + + // Finally, flip some parameters (if needed) + if (this->config.cli.log_cpu) { this->params.log_cpu = true; } + if (this->config.cli.ppu_timing_hack) { this->params.ppu_timing_hack = true; } + this->nes.updated_params(); } EmuModule::~EmuModule() { + /*------------------------------ SDL Cleanup -----------------------------*/ + SDL_DestroyTexture(this->sdl.screen_texture); + + /*------------------------------ NES Cleanup -----------------------------*/ + this->unload_rom(this->cart); + delete this->cart; } void EmuModule::input(const SDL_Event& event) { @@ -265,7 +311,7 @@ int EmuModule::load_rom(const char* rompath) { // Try to load battery-backed save const Serializable::Chunk* sav = nullptr; - if (!this->cli_args.no_sav) { + if (!this->config.cli.no_sav) { u8* data = nullptr; uint len = 0; ANESE_fs::load::load_file((std::string(rompath) + ".sav").c_str(), data, len); @@ -293,7 +339,7 @@ int EmuModule::unload_rom(Cartridge* cart) { fprintf(stderr, "[UnLoad] Unloading cart...\n"); // Save Battey-Backed RAM - if (cart != nullptr && !this->cli_args.no_sav) { + if (cart != nullptr && !this->config.cli.no_sav) { const Serializable::Chunk* sav = cart->get_mapper()->getBatterySave(); if (sav) { const u8* data; diff --git a/src/ui/SDL2/gui_modules/emu.h b/src/ui/SDL2/gui_modules/emu.h index b57b841..4ed73d7 100644 --- a/src/ui/SDL2/gui_modules/emu.h +++ b/src/ui/SDL2/gui_modules/emu.h @@ -44,7 +44,7 @@ class EmuModule : public GUIModule { public: virtual ~EmuModule(); - EmuModule(const SDLCommon& sdl_common, const CLIArgs& cli_args, Config& config); + EmuModule(const SDLCommon& sdl_common, Config& config); void input(const SDL_Event&) override; void update() override; void output() override; diff --git a/src/ui/SDL2/gui_modules/menu.cc b/src/ui/SDL2/gui_modules/menu.cc index 832e0c5..27efbd8 100644 --- a/src/ui/SDL2/gui_modules/menu.cc +++ b/src/ui/SDL2/gui_modules/menu.cc @@ -6,77 +6,82 @@ #include #include -MenuModule::~MenuModule() { +#include "../fs/util.h" +MenuModule::~MenuModule() { + // Update config + ANESE_fs::util::get_abs_path(this->config.roms_dir, this->nav.directory, 260); } -MenuModule::MenuModule(const SDLCommon& sdl_common, const CLIArgs& cli_args, Config& config, EmuModule& emu_module) -: GUIModule(sdl_common, cli_args, config) -, emu_module(emu_module) +MenuModule::MenuModule(const SDLCommon& sdl_common, Config& config, EmuModule& emu) +: GUIModule(sdl_common, config) +, emu(emu) { - + // Update from config + strcpy(this->nav.directory, this->config.roms_dir); } void MenuModule::input(const SDL_Event& event) { if (event.type == SDL_KEYDOWN) { switch (event.key.keysym.sym) { - case SDLK_RETURN: this->menu.hit.enter = true; break; - case SDLK_DOWN: this->menu.hit.down = true; break; - case SDLK_UP: this->menu.hit.up = true; break; - case SDLK_LEFT: this->menu.hit.left = true; break; - case SDLK_RIGHT: this->menu.hit.right = true; break; + case SDLK_RETURN: this->hit.enter = true; break; + case SDLK_DOWN: this->hit.down = true; break; + case SDLK_UP: this->hit.up = true; break; + case SDLK_LEFT: this->hit.left = true; break; + case SDLK_RIGHT: this->hit.right = true; break; } // support for basic "fast skipping" though file-names const char* key_pressed = SDL_GetKeyName(event.key.keysym.sym); bool is_valid_char = isalnum(key_pressed[0]) || key_pressed[0] == '.'; if (is_valid_char && key_pressed[1] == '\0') - this->menu.hit.last_ascii = key_pressed[0]; + this->hit.last_ascii = key_pressed[0]; // Special case: space if (event.key.keysym.sym == SDLK_SPACE) - this->menu.hit.last_ascii = ' '; + this->hit.last_ascii = ' '; } - if (event.type == SDL_CONTROLLERBUTTONDOWN || event.type == SDL_CONTROLLERBUTTONUP) { + if (event.type == SDL_CONTROLLERBUTTONDOWN || + event.type == SDL_CONTROLLERBUTTONUP) { switch (event.cbutton.button) { - case SDL_CONTROLLER_BUTTON_A: this->menu.hit.enter = true; break; - case SDL_CONTROLLER_BUTTON_DPAD_UP: this->menu.hit.up = true; break; - case SDL_CONTROLLER_BUTTON_DPAD_DOWN: this->menu.hit.down = true; break; - case SDL_CONTROLLER_BUTTON_DPAD_LEFT: this->menu.hit.left = true; break; + case SDL_CONTROLLER_BUTTON_A: this->hit.enter = true; break; + case SDL_CONTROLLER_BUTTON_DPAD_UP: this->hit.up = true; break; + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: this->hit.down = true; break; + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: this->hit.left = true; break; } } } void MenuModule::update() { - std::vector& files = this->menu.files; // helpful alias + std::vector& files = this->nav.files; // helpful alias // First, check if the user wants to navigate / load a rom - if (this->menu.hit.enter || this->menu.hit.right) { - this->menu.hit.enter = false; - this->menu.hit.right = false; - const cf_file_t& file = files[this->menu.selected_i]; + if (this->hit.enter || this->hit.right) { + this->hit.enter = false; + this->hit.right = false; + const cf_file_t& file = files[this->nav.selected_i]; if (file.is_dir) { // Navigate into directory - strcpy(this->menu.directory, file.path); - this->menu.selected_i = 0; - this->menu.should_update_dir = true; + strcpy(this->nav.directory, file.path); + this->nav.selected_i = 0; + this->nav.should_update_dir = true; } else { // Load-up ROM (and close menu) fprintf(stderr, "[Menu] Selected '%s'\n", file.name); - this->emu_module.unload_rom(this->emu_module.cart); - this->emu_module.load_rom(file.path); + this->emu.unload_rom(this->emu.cart); + this->emu.load_rom(file.path); this->in_menu = false; } } // Potentially update directory listing - if (this->menu.should_update_dir) { - this->menu.should_update_dir = false; + if (this->nav.should_update_dir) { + this->nav.should_update_dir = false; files.clear(); // Get file-listing cf_dir_t dir; - cf_dir_open(&dir, this->menu.directory); + cf_dir_open(&dir, this->nav.directory); bool skip_first = true; while (dir.has_next) { cf_file_t file; @@ -106,48 +111,48 @@ void MenuModule::update() { // Handle navigation... - if (this->menu.hit.up) { - this->menu.hit.up = false; - this->menu.selected_i -= this->menu.selected_i ? 1 : 0; + if (this->hit.up) { + this->hit.up = false; + this->nav.selected_i -= this->nav.selected_i ? 1 : 0; } - if (this->menu.hit.down) { - this->menu.hit.down = false; - this->menu.selected_i += (this->menu.selected_i < (files.size() - 1)); + if (this->hit.down) { + this->hit.down = false; + this->nav.selected_i += (this->nav.selected_i < (files.size() - 1)); } - if (this->menu.hit.left) { - this->menu.hit.left = false; - strcpy(this->menu.directory, files[0].path); - this->menu.selected_i = 0; + if (this->hit.left) { + this->hit.left = false; + strcpy(this->nav.directory, files[0].path); + this->nav.selected_i = 0; } - if (this->menu.quicknav.timeout) { this->menu.quicknav.timeout--; } + if (this->nav.quicksel.timeout) { this->nav.quicksel.timeout--; } else { - this->menu.quicknav.i = 0; - memset(this->menu.quicknav.buf, '\0', 16); + this->nav.quicksel.i = 0; + memset(this->nav.quicksel.buf, '\0', 16); } - if (this->menu.hit.last_ascii) { + if (this->hit.last_ascii) { // clear buffer in ~1s from last keypress - this->menu.quicknav.timeout = 30; + this->nav.quicksel.timeout = 30; // buf[15] is always '\0' - this->menu.quicknav.buf[this->menu.quicknav.i++ % 15] = tolower(this->menu.hit.last_ascii); + this->nav.quicksel.buf[this->nav.quicksel.i++ % 15] = tolower(this->hit.last_ascii); uint new_selection = std::distance( files.begin(), std::find_if(files.begin(), files.end(), [=](const cf_file_t& f){ - std::string fname = std::string(f.name).substr(0, this->menu.quicknav.i); + std::string fname = std::string(f.name).substr(0, this->nav.quicksel.i); std::transform(fname.begin(), fname.end(), fname.begin(), tolower); - return strcmp(fname.c_str(), this->menu.quicknav.buf) == 0; + return strcmp(fname.c_str(), this->nav.quicksel.buf) == 0; }) ); if (new_selection < files.size()) - this->menu.selected_i = new_selection; + this->nav.selected_i = new_selection; - this->menu.hit.last_ascii = '\0'; + this->hit.last_ascii = '\0'; } } @@ -159,18 +164,18 @@ void MenuModule::output() { SDL_RenderFillRect(this->sdl_common.renderer, &this->bg); // Paint menu - for (uint i = 0; i < this->menu.files.size(); i++) { - const cf_file_t& file = this->menu.files[i]; + for (uint i = 0; i < this->nav.files.size(); i++) { + const cf_file_t& file = this->nav.files[i]; u32 color; - if (this->menu.selected_i == i) color = 0xff0000; // red - selected + if (this->nav.selected_i == i) color = 0xff0000; // red - selected else if (strcmp("nes", file.ext) == 0) color = 0x00ff00; // green - .nes else if (strcmp("zip", file.ext) == 0) color = 0x00ffff; // cyan - .zip else color = 0xffffff; // white - folder SDL2_inprint::incolor(color, /* unused */ 0); SDL2_inprint::inprint(this->sdl_common.renderer, file.name, - 10, this->bg.h / this->sdl_common.SCREEN_SCALE + (i - this->menu.selected_i) * 12 + 10, this->bg.h / this->sdl_common.SCREEN_SCALE + (i - this->nav.selected_i) * 12 ); } } diff --git a/src/ui/SDL2/gui_modules/menu.h b/src/ui/SDL2/gui_modules/menu.h index 6aaae64..38962e8 100644 --- a/src/ui/SDL2/gui_modules/menu.h +++ b/src/ui/SDL2/gui_modules/menu.h @@ -3,40 +3,40 @@ #include #include -#include "../config.h" +#include #include "module.h" #include "emu.h" -#include +#include "../config.h" class MenuModule : public GUIModule { private: SDL_Rect bg; - EmuModule& emu_module; + EmuModule& emu; public: bool in_menu = true; struct { std::vector files; - char directory [256] = "."; - bool should_update_dir = true; uint selected_i = 0; + char directory [260] = "."; + bool should_update_dir = true; struct { uint timeout = 0; char buf [16] = "\0"; uint i = 0; - } quicknav; + } quicksel; + } nav; - struct { - bool enter, up, down, left, right; - char last_ascii; - } hit = {0, 0, 0, 0, 0, 0}; - } menu; + struct { + bool enter, up, down, left, right; + char last_ascii; + } hit = {0, 0, 0, 0, 0, 0}; public: virtual ~MenuModule(); - MenuModule(const SDLCommon&, const CLIArgs&, Config&, EmuModule&); + MenuModule(const SDLCommon&, Config&, EmuModule&); void input(const SDL_Event&) override; void update() override; void output() override; diff --git a/src/ui/SDL2/gui_modules/module.h b/src/ui/SDL2/gui_modules/module.h index 75ef467..c9a602d 100644 --- a/src/ui/SDL2/gui_modules/module.h +++ b/src/ui/SDL2/gui_modules/module.h @@ -21,14 +21,11 @@ struct SDLCommon { class GUIModule { protected: const SDLCommon& sdl_common; - - const CLIArgs& cli_args; Config& config; public: virtual ~GUIModule() = default; - GUIModule(const SDLCommon& sdl_common, const CLIArgs& cli_args, Config& config) + GUIModule(const SDLCommon& sdl_common, Config& config) : sdl_common(sdl_common) - , cli_args(cli_args) , config(config) {}