From 3664989c2577d433ebc84b3d6397e1cbfa756531 Mon Sep 17 00:00:00 2001 From: Rosalie Wanders Date: Thu, 1 Oct 2020 19:40:55 +0200 Subject: [PATCH] savestates work, slot selection is still todo --- Source/3rdParty/CMakeLists.txt | 10 +-- Source/RMG/M64P/Wrapper/Config.cpp | 5 ++ Source/RMG/M64P/Wrapper/Config.hpp | 1 + Source/RMG/M64P/Wrapper/Core.cpp | 99 ++++++++++++++++++++++++- Source/RMG/M64P/Wrapper/Core.hpp | 10 +++ Source/RMG/UserInterface/MainWindow.cpp | 52 ++++++++++++- 6 files changed, 168 insertions(+), 9 deletions(-) diff --git a/Source/3rdParty/CMakeLists.txt b/Source/3rdParty/CMakeLists.txt index 6821abc7..7d18e269 100644 --- a/Source/3rdParty/CMakeLists.txt +++ b/Source/3rdParty/CMakeLists.txt @@ -34,20 +34,20 @@ ExternalProject_Add(mupen64plus-core set(APIDIR "${CMAKE_BINARY_DIR}/Source/3rdParty/mupen64plus-core/src/api") ExternalProject_Add(mupen64plus-audio-sdl - SOURCE_DIR mupen64plus-audio-sdl/ + SOURCE_DIR mupen64plus-audio-sdl2/ CONFIGURE_COMMAND "" INSTALL_COMMAND "" - GIT_REPOSITORY https://github.com/mupen64plus/mupen64plus-audio-sdl - GIT_TAG 39b8cb778c4690de98c8b9497578662cece356cc + GIT_REPOSITORY https://github.com/Rosalie241/mupen64plus-audio-sdl2 + GIT_TAG cc6aca5a13b0b8ca7a2f9f5fa472ed3bb7f817db BUILD_COMMAND make all APIDIR=${APIDIR} DEBUG=$ BUILD_IN_SOURCE False - BINARY_DIR ${THIRDPARTY_DIR}/mupen64plus-audio-sdl/projects/unix + BINARY_DIR ${THIRDPARTY_DIR}/mupen64plus-audio-sdl2/projects/unix - BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-audio-sdl/projects/unix/mupen64plus-audio-sdl.${SO_EXT} + BUILD_BYPRODUCTS ${THIRDPARTY_DIR}/mupen64plus-audio-sdl2/projects/unix/mupen64plus-audio-sdl2.${SO_EXT} DEPENDS mupen64plus-core ) diff --git a/Source/RMG/M64P/Wrapper/Config.cpp b/Source/RMG/M64P/Wrapper/Config.cpp index 5c3bdcab..441ef25d 100644 --- a/Source/RMG/M64P/Wrapper/Config.cpp +++ b/Source/RMG/M64P/Wrapper/Config.cpp @@ -65,6 +65,11 @@ bool Config::SetOption(QString section, QString key, char *value) this->value_Set(key, M64TYPE_STRING, (void *)value); } +bool Config::SetOption(QString section, QString key, const char* value) +{ + return this->SetOption(section, key, (char*)value); +} + bool Config::GetOption(QString section, QString key, int *value) { return this->section_Open(section) && diff --git a/Source/RMG/M64P/Wrapper/Config.hpp b/Source/RMG/M64P/Wrapper/Config.hpp index 3c5dbfe2..36158d83 100644 --- a/Source/RMG/M64P/Wrapper/Config.hpp +++ b/Source/RMG/M64P/Wrapper/Config.hpp @@ -31,6 +31,7 @@ namespace M64P bool SetOption(QString section, QString key, bool value); bool SetOption(QString section, QString key, QString value); bool SetOption(QString section, QString key, char* value); + bool SetOption(QString section, QString key, const char* value); bool GetOption(QString section, QString key, int* value); bool GetOption(QString section, QString key, float* value); diff --git a/Source/RMG/M64P/Wrapper/Core.cpp b/Source/RMG/M64P/Wrapper/Core.cpp index 51ac4faf..669f7634 100644 --- a/Source/RMG/M64P/Wrapper/Core.cpp +++ b/Source/RMG/M64P/Wrapper/Core.cpp @@ -65,7 +65,7 @@ bool Core::HasPluginConfig(PluginType type) bool Core::OpenPluginConfig(PluginType type) { bool ret, paused; - + paused = this->emulation_IsPaused(); if (!paused) @@ -75,7 +75,7 @@ bool Core::OpenPluginConfig(PluginType type) if (!paused) this->ResumeEmulation(); - + return ret; } @@ -360,6 +360,101 @@ bool Core::isEmulationPaused(void) return emulation_IsPaused(); } +bool Core::PressGameSharkButton(void) +{ + m64p_error ret; + int value = 1; + + ret = M64P::Core.DoCommand(M64CMD_CORE_STATE_SET, M64CORE_INPUT_GAMESHARK, &value); + if (ret != M64ERR_SUCCESS) + { + this->error_Message = "Core::PressGameSharkButton Failed: "; + this->error_Message += M64P::Core.ErrorMessage(ret); + return false; + } + + value = 0; + ret = M64P::Core.DoCommand(M64CMD_CORE_STATE_SET, M64CORE_INPUT_GAMESHARK, &value); + if (ret != M64ERR_SUCCESS) + { + this->error_Message = "Core::PressGameSharkButton Failed: "; + this->error_Message += M64P::Core.ErrorMessage(ret); + return false; + } + + return true; +} + +bool Core::SetSaveSlot(int slot) +{ + m64p_error ret; + + ret = M64P::Core.DoCommand(M64CMD_STATE_SET_SLOT, slot, NULL); + if (ret != M64ERR_SUCCESS) + { + this->error_Message = "Core::SetSaveSlot M64P::Core.DoCommand(M64CMD_STATE_SET_SLOT) Failed: "; + this->error_Message += M64P::Core.ErrorMessage(ret); + } + + return ret == M64ERR_SUCCESS; +} + +bool Core::SaveStateAsFile(QString file) +{ + m64p_error ret; + + ret = M64P::Core.DoCommand(M64CMD_STATE_SAVE, 1, (void*)file.toStdString().c_str()); + if (ret != M64ERR_SUCCESS) + { + this->error_Message = "Core::SaveStateAsFile: M64P::Core.DoCommand(M64CMD_STATE_SAVE) Failed: "; + this->error_Message += M64P::Core.ErrorMessage(ret); + } + + return ret == M64ERR_SUCCESS; +} + +bool Core::LoadStateFromFile(QString file) +{ + m64p_error ret; + + ret = M64P::Core.DoCommand(M64CMD_STATE_LOAD, 0, (void*)file.toStdString().c_str()); + if (ret != M64ERR_SUCCESS) + { + this->error_Message = "Core::SaveStateAsFile: M64P::Core.DoCommand(M64CMD_STATE_LOAD) Failed: "; + this->error_Message += M64P::Core.ErrorMessage(ret); + } + + return ret == M64ERR_SUCCESS; +} + +bool Core::SaveState(void) +{ + m64p_error ret; + + ret = M64P::Core.DoCommand(M64CMD_STATE_SAVE, 0, NULL); + if (ret != M64ERR_SUCCESS) + { + this->error_Message = "Core::SaveState: M64P::Core.DoCommand(M64CMD_STATE_SAVE) Failed: "; + this->error_Message += M64P::Core.ErrorMessage(ret); + } + + return ret == M64ERR_SUCCESS; +} + +bool Core::LoadState(void) +{ + m64p_error ret; + + ret = M64P::Core.DoCommand(M64CMD_STATE_LOAD, 0, NULL); + if (ret != M64ERR_SUCCESS) + { + this->error_Message = "Core::LoadState: M64P::Core.DoCommand(M64CMD_STATE_LOAD) Failed: "; + this->error_Message += M64P::Core.ErrorMessage(ret); + } + + return ret == M64ERR_SUCCESS; +} + bool Core::ResetEmulation(bool hard) { m64p_error ret; diff --git a/Source/RMG/M64P/Wrapper/Core.hpp b/Source/RMG/M64P/Wrapper/Core.hpp index 668a655e..21c62c93 100644 --- a/Source/RMG/M64P/Wrapper/Core.hpp +++ b/Source/RMG/M64P/Wrapper/Core.hpp @@ -50,6 +50,16 @@ namespace M64P bool EnableSpeedLimiter(void); bool DisableSpeedLimiter(void); + bool PressGameSharkButton(void); + + bool SetSaveSlot(int); + + bool SaveStateAsFile(QString); + bool LoadStateFromFile(QString); + + bool SaveState(void); + bool LoadState(void); + QString GetLastError(void); private: diff --git a/Source/RMG/UserInterface/MainWindow.cpp b/Source/RMG/UserInterface/MainWindow.cpp index 65080e51..24a657df 100644 --- a/Source/RMG/UserInterface/MainWindow.cpp +++ b/Source/RMG/UserInterface/MainWindow.cpp @@ -55,7 +55,10 @@ bool MainWindow::Init(void) g_MupenApi.Core.GetPlugins(M64P::Wrapper::PluginType::Audio); g_MupenApi.Core.GetPlugins(M64P::Wrapper::PluginType::Input); - // g_MupenApi.Config.SetOption("Core", "ScreenshotPath", "Screenshots"); + g_MupenApi.Config.SetOption("Core", "ScreenshotPath", "Screenshots"); + g_MupenApi.Config.SetOption("Core", "SaveStatePath", "Save/State"); + g_MupenApi.Config.SetOption("Core", "SaveSRAMPath", "Save/Game"); + g_MupenApi.Config.SetOption("Core", "SharedDataPath", "Data"); this->ui_Init(); this->ui_Setup(); @@ -407,6 +410,7 @@ void MainWindow::menuBar_Actions_Connect(void) connect(this->action_System_SaveState, &QAction::triggered, this, &MainWindow::on_Action_System_SaveState); connect(this->action_System_SaveAs, &QAction::triggered, this, &MainWindow::on_Action_System_SaveAs); connect(this->action_System_LoadState, &QAction::triggered, this, &MainWindow::on_Action_System_LoadState); + connect(this->action_System_Load, &QAction::triggered, this, &MainWindow::on_Action_System_Load); connect(this->action_System_Cheats, &QAction::triggered, this, &MainWindow::on_Action_System_Cheats); connect(this->action_System_GSButton, &QAction::triggered, this, &MainWindow::on_Action_System_GSButton); @@ -553,7 +557,7 @@ void MainWindow::on_Action_System_LimitFPS(void) if (!ret) { - this->ui_MessageBox("Error", "aaaa Failed:", g_MupenApi.Core.GetLastError()); + this->ui_MessageBox("Error", "aaaa Failed", g_MupenApi.Core.GetLastError()); } } @@ -563,18 +567,58 @@ void MainWindow::on_Action_System_SwapDisk(void) void MainWindow::on_Action_System_SaveState(void) { + if (!g_MupenApi.Core.SaveState()) + { + this->ui_MessageBox("Error", "Api::Core::SaveState Failed", g_MupenApi.Core.GetLastError()); + } } void MainWindow::on_Action_System_SaveAs(void) { + bool isPaused = g_MupenApi.Core.isEmulationPaused(); + + if (!isPaused) + this->on_Action_System_Pause(); + + QString fileName = QFileDialog::getSaveFileName(this, + tr("Save State"), "", + tr("SaveState (*.dat);;All Files (*)")); + + if (!g_MupenApi.Core.SaveStateAsFile(fileName)) + { + this->ui_MessageBox("Error", "Api::Core::SaveStateAsFile Failed", g_MupenApi.Core.GetLastError()); + } + + if (!isPaused) + this->on_Action_System_Pause(); } void MainWindow::on_Action_System_LoadState(void) { + if (!g_MupenApi.Core.LoadState()) + { + this->ui_MessageBox("Error", "Api::Core::LoadState Failed", g_MupenApi.Core.GetLastError()); + } } void MainWindow::on_Action_System_Load(void) { + bool isPaused = g_MupenApi.Core.isEmulationPaused(); + + if (!isPaused) + this->on_Action_System_Pause(); + + QString fileName = QFileDialog::getOpenFileName(this, + tr("Open Save State"), "", + tr("SaveState (*.dat);;All Files (*)")); + + if (!g_MupenApi.Core.LoadStateFromFile(fileName)) + { + this->ui_MessageBox("Error", "Api::Core::LoadStateFromFile Failed", g_MupenApi.Core.GetLastError()); + } + + if (!isPaused) + this->on_Action_System_Pause(); } void MainWindow::on_Action_System_CurrentSaveState(void) @@ -587,6 +631,10 @@ void MainWindow::on_Action_System_Cheats(void) void MainWindow::on_Action_System_GSButton(void) { + if (!g_MupenApi.Core.PressGameSharkButton()) + { + this->ui_MessageBox("Error", "Api::Core::PressGameSharkButton Failed", g_MupenApi.Core.GetLastError()); + } } void MainWindow::on_Action_Options_FullScreen(void)