diff --git a/rpcs3/Emu/FS/VFS.cpp b/rpcs3/Emu/FS/VFS.cpp index a44003e460..ceab7d7b19 100644 --- a/rpcs3/Emu/FS/VFS.cpp +++ b/rpcs3/Emu/FS/VFS.cpp @@ -5,6 +5,8 @@ #include "vfsDeviceLocalFile.h" #include "Ini.h" #include "Emu/System.h" +#include "Utilities/Log.h" +#include // To check whether directory exists #undef CreateFile @@ -429,7 +431,15 @@ void VFS::Init(const std::string& path) std::string mpath = entry.path; // TODO: This shouldn't use current dir - fmt::Replace(mpath, "$(EmulatorDir)", Emu.GetEmulatorPath()); + // If no value assigned to SysEmulationDirPath in INI, use the path that with executable. + if (Ini.SysEmulationDirPathEnable.GetValue()) + { + fmt::Replace(mpath, "$(EmulatorDir)", Ini.SysEmulationDirPath.GetValue()); + } + else + { + fmt::Replace(mpath, "$(EmulatorDir)", Emu.GetEmulatorPath()); + } fmt::Replace(mpath, "$(GameDir)", cwd); Mount(entry.mount, mpath, dev); } @@ -468,6 +478,34 @@ void VFS::SaveLoadDevices(std::vector& res, bool is_load) entries_count.SaveValue(count); } + // Custom EmulationDir. + // TODO:: should have a better log that would show results before loading a game? + if (Ini.SysEmulationDirPathEnable.GetValue()) + { + std::string EmulationDir = Ini.SysEmulationDirPath.GetValue(); + if (EmulationDir.empty()) + Ini.SysEmulationDirPath.SetValue(Emu.GetEmulatorPath()); + struct stat fstatinfo; + if ((stat(EmulationDir.c_str(), &fstatinfo))) + { + LOG_NOTICE(GENERAL, "Custom EmualtionDir: Tried %s but it doesn't exists. Maybe you add some not needed chars like '\"'?"); + Ini.SysEmulationDirPathEnable.SetValue(false); + } + else if (fstatinfo.st_mode & S_IFDIR) + LOG_NOTICE(GENERAL, "Custom EmualtionDir: On, Binded $(EmulatorDir) to %s.", EmulationDir); + else + { + // If that is not directory turn back to use original one. + LOG_NOTICE(GENERAL, "Custom EmulationDir: Cause path %s is not a valid directory.", EmulationDir); + Ini.SysEmulationDirPathEnable.SetValue(false); + } + } + // I left this to check again just to catch those failed in directory checks. + if (!Ini.SysEmulationDirPathEnable.GetValue()) + { + LOG_NOTICE(GENERAL, "Custom EmualtionDir: Off, Binded $(EmulatorDir) to %s.", Emu.GetEmulatorPath()); + } + for(int i=0; i entry_path; diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index dd0298777e..ae4ae0556a 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -436,6 +436,10 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) wxCheckBox* chbox_dbg_ap_systemcall = new wxCheckBox(p_hle, wxID_ANY, "Auto Pause at System Call"); wxCheckBox* chbox_dbg_ap_functioncall = new wxCheckBox(p_hle, wxID_ANY, "Auto Pause at Function Call"); + //Custom EmulationDir + wxCheckBox* chbox_emulationdir_enable = new wxCheckBox(p_system, wxID_ANY, "Use Path Below as EmulationDir ? (Need Restart)"); + wxTextCtrl* txt_emulationdir_path = new wxTextCtrl(p_system, wxID_ANY, Emu.GetEmulatorPath()); + cbox_cpu_decoder->Append("PPU Interpreter"); cbox_cpu_decoder->Append("PPU Interpreter 2"); cbox_cpu_decoder->Append("PPU JIT (LLVM)"); @@ -533,6 +537,10 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) chbox_dbg_ap_systemcall ->SetValue(Ini.DBGAutoPauseSystemCall.GetValue()); chbox_dbg_ap_functioncall->SetValue(Ini.DBGAutoPauseFunctionCall.GetValue()); + //Custom EmulationDir + chbox_emulationdir_enable->SetValue(Ini.SysEmulationDirPathEnable.GetValue()); + txt_emulationdir_path ->SetValue(Ini.SysEmulationDirPath.GetValue()); + cbox_cpu_decoder ->SetSelection(Ini.CPUDecoderMode.GetValue() ? Ini.CPUDecoderMode.GetValue() : 0); cbox_spu_decoder ->SetSelection(Ini.SPUDecoderMode.GetValue() ? Ini.SPUDecoderMode.GetValue() : 0); cbox_gs_render ->SetSelection(Ini.GSRenderMode.GetValue()); @@ -614,6 +622,10 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) // System s_subpanel_system->Add(s_round_sys_lang, wxSizerFlags().Border(wxALL, 5).Expand()); + + //Custom EmulationDir + s_subpanel_system->Add(chbox_emulationdir_enable, wxSizerFlags().Border(wxALL, 5).Expand()); + s_subpanel_system->Add(txt_emulationdir_path, wxSizerFlags().Border(wxALL, 5).Expand()); // Buttons wxBoxSizer* s_b_panel(new wxBoxSizer(wxHORIZONTAL)); @@ -667,6 +679,10 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) Ini.DBGAutoPauseFunctionCall.SetValue(chbox_dbg_ap_functioncall->GetValue()); Ini.DBGAutoPauseSystemCall.SetValue(chbox_dbg_ap_systemcall->GetValue()); + //Custom EmulationDir + Ini.SysEmulationDirPathEnable.SetValue(chbox_emulationdir_enable->GetValue()); + Ini.SysEmulationDirPath.SetValue(txt_emulationdir_path->GetValue().ToStdString()); + Ini.Save(); } diff --git a/rpcs3/Ini.h b/rpcs3/Ini.h index 08b0ea3b86..5f1155489d 100644 --- a/rpcs3/Ini.h +++ b/rpcs3/Ini.h @@ -163,6 +163,10 @@ public: IniEntry DBGAutoPauseSystemCall; IniEntry DBGAutoPauseFunctionCall; + //Customed EmulationDir + IniEntry SysEmulationDirPath; + IniEntry SysEmulationDirPathEnable; + // Language IniEntry SysLanguage; @@ -240,6 +244,10 @@ public: DBGAutoPauseFunctionCall.Init("DBG_AutoPauseFunctionCall", path); DBGAutoPauseSystemCall.Init("DBG_AutoPauseSystemCall", path); + // Customed EmulationDir + SysEmulationDirPath.Init("System_EmulationDir", path); + SysEmulationDirPathEnable.Init("System_EmulationDirEnable", path); + // Language SysLanguage.Init("Sytem_SysLanguage", path); } @@ -316,6 +324,9 @@ public: // Language SysLanguage.Load(1); + // Customed EmulationDir + SysEmulationDirPath.Load(""); + SysEmulationDirPathEnable.Load(false); } void Save() @@ -389,6 +400,10 @@ public: // Language SysLanguage.Save(); + + // Customed EmulationDir + SysEmulationDirPath.Save(); + SysEmulationDirPathEnable.Save(); } };