diff --git a/extern/hqn/hqn_gui_controller.cpp b/extern/hqn/hqn_gui_controller.cpp index 3a73ce3..d323d62 100644 --- a/extern/hqn/hqn_gui_controller.cpp +++ b/extern/hqn/hqn_gui_controller.cpp @@ -68,10 +68,10 @@ GUIController::~GUIController() m_state.setListener(nullptr); } -GUIController *GUIController::create(HQNState &state) +GUIController *GUIController::create(HQNState &state, SDL_Window* window) { GUIController *self = new GUIController(state); - if (!self->init()) + if (!self->init(window)) { delete self; return nullptr; @@ -82,13 +82,9 @@ GUIController *GUIController::create(HQNState &state) } } -bool GUIController::init() +bool GUIController::init(SDL_Window* window) { - // create the window - if (!(m_window = SDL_CreateWindow(DEFAULT_WINDOW_TITLE, - SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, DEFAULT_WIDTH, - DEFAULT_HEIGHT, 0))) - return false; + m_window = window; if (!(m_renderer = SDL_CreateRenderer(m_window, -1, SDL_RENDERER_ACCELERATED))) return false; if (!(m_tex = SDL_CreateTexture(m_renderer, SDL_PIXELFORMAT_ARGB8888, diff --git a/extern/hqn/hqn_gui_controller.h b/extern/hqn/hqn_gui_controller.h index 8896f19..e312bc8 100644 --- a/extern/hqn/hqn_gui_controller.h +++ b/extern/hqn/hqn_gui_controller.h @@ -33,7 +33,7 @@ public: * Create a new GUI controller. Returns a GUI Controller or nullptr * if an error occured during initialization. */ - static GUIController *create(HQNState &state); + static GUIController *create(HQNState &state, SDL_Window* window); /** * Set the window title. @@ -112,7 +112,7 @@ protected: /** * Called in create(). If this fails the GUI cannot be created. */ - bool init(); + bool init(SDL_Window* window); private: /** diff --git a/source/playbackInstance.hpp b/source/playbackInstance.hpp index 9bf2305..dfe8536 100644 --- a/source/playbackInstance.hpp +++ b/source/playbackInstance.hpp @@ -41,35 +41,8 @@ class PlaybackInstance } // Initializes the playback module instance - PlaybackInstance(NESInstance *emu, const std::vector &sequence, const std::string &overlayPath = "") : _emu(emu) + PlaybackInstance(NESInstance *emu, const std::string &overlayPath = "") : _emu(emu) { - // Allocating video buffer - _video_buffer = (uint8_t *)malloc(image_width * image_height); - - // Setting video buffer - ((emulator_t*)_emu->getInternalEmulatorPointer())->set_pixels(_video_buffer, image_width + 8); - - // Enabling emulation rendering - _emu->enableRendering(); - - // Loading Emulator instance HQN - _hqnState.setEmulatorPointer(_emu->getInternalEmulatorPointer()); - static uint8_t video_buffer[image_width * image_height]; - _hqnState.m_emu->set_pixels(video_buffer, image_width + 8); - - // Building sequence information - for (const auto &input : sequence) - { - // Adding new step - addStep(input); - - // Advance state based on the input received - _emu->advanceState(input); - } - - // Adding last step with no input - addStep(""); - // Loading overlay, if provided if (overlayPath != "") { @@ -115,17 +88,42 @@ class PlaybackInstance _overlayButtonDownSurface = IMG_Load(imagePath.c_str()); if (_overlayButtonDownSurface == NULL) JAFFAR_THROW_LOGIC("[Error] Could not load image: %s, Reason: %s\n", imagePath.c_str(), SDL_GetError()); } + } - // Opening rendering window - SDL_SetMainReady(); + void initialize(const std::vector &sequence) + { + // Building sequence information + for (const auto &input : sequence) + { + // Adding new step + addStep(input); - // We can only call SDL_InitSubSystem once - if (!SDL_WasInit(SDL_INIT_VIDEO)) - if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) - JAFFAR_THROW_LOGIC("Failed to initialize video: %s", SDL_GetError()); + // Advance state based on the input received + _emu->advanceState(input); + } + + // Adding last step with no input + addStep(""); + } + + void enableRendering(SDL_Window* window) + { + // Allocating video buffer + _video_buffer = (uint8_t *)malloc(image_width * image_height); + + // Setting video buffer + ((emulator_t*)_emu->getInternalEmulatorPointer())->set_pixels(_video_buffer, image_width + 8); + + // Loading Emulator instance HQN + _hqnState.setEmulatorPointer(_emu->getInternalEmulatorPointer()); + static uint8_t video_buffer[image_width * image_height]; + _hqnState.m_emu->set_pixels(video_buffer, image_width + 8); + + // Enabling emulation rendering + _emu->enableRendering(); // Creating HQN GUI - _hqnGUI = hqn::GUIController::create(_hqnState); + _hqnGUI = hqn::GUIController::create(_hqnState, window); _hqnGUI->setScale(1); } diff --git a/source/player.cpp b/source/player.cpp index 76d2715..65d8a3d 100644 --- a/source/player.cpp +++ b/source/player.cpp @@ -8,6 +8,23 @@ #include "nesInstance.hpp" #include "playbackInstance.hpp" +SDL_Window *launchOutputWindow() +{ + // Opening rendering window + SDL_SetMainReady(); + + // We can only call SDL_InitSubSystem once + if (!SDL_WasInit(SDL_INIT_VIDEO)) + if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0) JAFFAR_THROW_LOGIC("Failed to initialize video: %s", SDL_GetError()); + + auto window = SDL_CreateWindow("JaffarPlus", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 100, 100, SDL_WINDOW_RESIZABLE); + if (window == nullptr) JAFFAR_THROW_LOGIC("Coult not open SDL window"); + + return window; +} + +void closeOutputWindow(SDL_Window *window) { SDL_DestroyWindow(window); } + int main(int argc, char *argv[]) { // Parsing command line arguments @@ -86,11 +103,11 @@ int main(int argc, char *argv[]) jaffarCommon::logger::initializeTerminal(); // Printing provided parameters - printw("[] Rom File Path: '%s'\n", romFilePath.c_str()); - printw("[] Sequence File Path: '%s'\n", sequenceFilePath.c_str()); - printw("[] Sequence Length: %lu\n", sequence.size()); - printw("[] State File Path: '%s'\n", stateFilePath.empty() ? "" : stateFilePath.c_str()); - printw("[] Generating Sequence...\n"); + jaffarCommon::logger::log("[] Rom File Path: '%s'\n", romFilePath.c_str()); + jaffarCommon::logger::log("[] Sequence File Path: '%s'\n", sequenceFilePath.c_str()); + jaffarCommon::logger::log("[] Sequence Length: %lu\n", sequence.size()); + jaffarCommon::logger::log("[] State File Path: '%s'\n", stateFilePath.empty() ? "" : stateFilePath.c_str()); + jaffarCommon::logger::log("[] Generating Sequence...\n"); jaffarCommon::logger::refreshTerminal(); @@ -116,7 +133,18 @@ int main(int argc, char *argv[]) } // Creating playback instance - auto p = PlaybackInstance(&e, sequence); + auto p = PlaybackInstance(&e); + + // If render is enabled then, create window now + SDL_Window* window = nullptr; + if (disableRender == false) + { + window = launchOutputWindow(); + p.enableRendering(window); + } + + // Initializing playback instance + p.initialize(sequence); // Getting state size auto stateSize = e.getFullStateSize(); @@ -151,13 +179,13 @@ int main(int argc, char *argv[]) { jaffarCommon::logger::clearTerminal(); - printw("[] ----------------------------------------------------------------\n"); - printw("[] Current Step #: %lu / %lu\n", currentStep + 1, sequenceLength); - printw("[] Input: %s\n", input.c_str()); - printw("[] State Hash: 0x%lX%lX\n", hash.first, hash.second); + jaffarCommon::logger::log("[] ----------------------------------------------------------------\n"); + jaffarCommon::logger::log("[] Current Step #: %lu / %lu\n", currentStep + 1, sequenceLength); + jaffarCommon::logger::log("[] Input: %s\n", input.c_str()); + jaffarCommon::logger::log("[] State Hash: 0x%lX%lX\n", hash.first, hash.second); // Only print commands if not in reproduce mode - if (isReproduce == false) printw("[] Commands: n: -1 m: +1 | h: -10 | j: +10 | y: -100 | u: +100 | k: -1000 | i: +1000 | s: quicksave | p: play | q: quit\n"); + if (isReproduce == false) jaffarCommon::logger::log("[] Commands: n: -1 m: +1 | h: -10 | j: +10 | y: -100 | u: +100 | k: -1000 | i: +1000 | s: quicksave | p: play | q: quit\n"); jaffarCommon::logger::refreshTerminal(); } @@ -192,7 +220,7 @@ int main(int argc, char *argv[]) saveData.resize(stateSize); memcpy(saveData.data(), stateData, stateSize); if (jaffarCommon::file::saveStringToFile(saveData, saveFileName.c_str()) == false) JAFFAR_THROW_LOGIC("[ERROR] Could not save state file: %s\n", saveFileName.c_str()); - printw("[] Saved state to %s\n", saveFileName.c_str()); + jaffarCommon::logger::log("[] Saved state to %s\n", saveFileName.c_str()); // Do no show frame info again after this action showFrameInfo = false; @@ -205,6 +233,9 @@ int main(int argc, char *argv[]) if (command == 'q') continueRunning = false; } + // If render is enabled then, close window now + if (disableRender == false) closeOutputWindow(window); + // Ending ncurses window jaffarCommon::logger::finalizeTerminal(); }