diff --git a/Utilities/File.cpp b/Utilities/File.cpp index 8ef949a65e..a640d43ff6 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -167,7 +167,8 @@ bool fs::is_file(const std::string& file) #ifdef _WIN32 DWORD attrs; - if ((attrs = GetFileAttributesW(to_wchar(file).get())) == INVALID_FILE_ATTRIBUTES) + const std::string path = fmt::replace_all(file, "/", "\\"); + if ((attrs = GetFileAttributesW(to_wchar(path).get())) == INVALID_FILE_ATTRIBUTES) { return false; } @@ -190,7 +191,8 @@ bool fs::is_dir(const std::string& dir) #ifdef _WIN32 DWORD attrs; - if ((attrs = GetFileAttributesW(to_wchar(dir).get())) == INVALID_FILE_ATTRIBUTES) + const std::string path = fmt::replace_all(dir, "/", "\\"); + if ((attrs = GetFileAttributesW(to_wchar(path).get())) == INVALID_FILE_ATTRIBUTES) { return false; } @@ -212,7 +214,8 @@ bool fs::create_dir(const std::string& dir) g_tls_error = fse::ok; #ifdef _WIN32 - if (!CreateDirectoryW(to_wchar(dir).get(), NULL)) + const std::string path = fmt::replace_all(dir, "/", "\\"); + if (!CreateDirectoryW(to_wchar(path).get(), NULL)) #else if (mkdir(dir.c_str(), 0777)) #endif diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index f0550c2e49..16d2cbba9c 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -86,6 +86,21 @@ void Emulator::SetTitle(const std::string& title) m_title = title; } +void Emulator::CreateConfig(const std::string& name) +{ + const std::string& path = "data/" + name; + const std::string& ini_file = path + "/" + name + ".ini"; + + if (!fs::is_dir("data")) + fs::create_dir("data"); + + if (!fs::is_dir(path)) + fs::create_dir(path); + + if (!fs::is_file(ini_file)) + rpcs3::config_t{ ini_file }.save(); +} + bool Emulator::BootGame(const std::string& path, bool direct) { static const char* elf_path[6] = @@ -173,12 +188,27 @@ void Emulator::Load() } } - //TODO: load custom config if exists + ResetInfo(); + GetVFS().Init(elf_dir); + + // load custom config as global + if (!Ini.UseDefaultIni.GetValue()) + { + std::string& name = PSFLoader{ vfsFile{ "/app_home/../PARAM.SFO" } }.GetString("TITLE_ID"); + if (name.size()) + { + name = name.substr(0, 4) + "-" + name.substr(4, 5); + CreateConfig(name); + rpcs3::config.path("data/" + name + "/" + name + ".ini"); + rpcs3::config.load(); + } + } + + // TODO: use state configuration instead of global config rpcs3::state.config = rpcs3::config; LOG_NOTICE(LOADER, "Loading '%s'...", m_path.c_str()); - ResetInfo(); - GetVFS().Init(elf_dir); + LOG_NOTICE(LOADER, "Used configuration: '%s'", rpcs3::config.path().c_str()); // /dev_bdvd/ mounting vfsFile f("/app_home/../dev_bdvd.path"); @@ -447,6 +477,8 @@ void Emulator::Stop() RSXIOMem.Clear(); vm::close(); + rpcs3::config.path("rpcs3.new.ini"); // fallback to default .ini + rpcs3::config.load(); SendDbgCommand(DID_STOPPED_EMU); } diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index 81e2799a4d..3fb8991dc5 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -147,6 +147,7 @@ public: void SetPath(const std::string& path, const std::string& elf_path = ""); void SetTitleID(const std::string& id); void SetTitle(const std::string& title); + void CreateConfig(const std::string& name); const std::string& GetPath() const { diff --git a/rpcs3/Gui/GameViewer.cpp b/rpcs3/Gui/GameViewer.cpp index f0bca30f3d..4e094673d1 100644 --- a/rpcs3/Gui/GameViewer.cpp +++ b/rpcs3/Gui/GameViewer.cpp @@ -9,6 +9,7 @@ #include "Emu/FS/vfsFile.h" #include "GameViewer.h" #include "Loader/PSF.h" +#include "SettingsDialog.h" #include static const std::string m_class_name = "GameViewer"; @@ -251,13 +252,46 @@ void GameViewer::DClick(wxListEvent& event) void GameViewer::RightClick(wxListEvent& event) { - m_popup->Destroy(m_popup->FindItemByPosition(0)); + m_popup->Destroy(0); + m_popup->Destroy(1); + m_popup->Destroy(2); - wxMenuItem *pMenuItemA = m_popup->Append(event.GetIndex(), _T("Remove Game")); - Bind(wxEVT_MENU, &GameViewer::RemoveGame, this, event.GetIndex()); + wxFont font = GetFont(); + font.SetWeight(wxFONTWEIGHT_BOLD); + wxMenuItem* boot_item = new wxMenuItem(m_popup, 0, _T("Boot")); + boot_item->SetFont(font); + + m_popup->Append(boot_item); + m_popup->Append(1, _T("Configure")); + m_popup->Append(2, _T("Remove Game")); + + Bind(wxEVT_MENU, &GameViewer::BootGame, this, 0); + Bind(wxEVT_MENU, &GameViewer::ConfigureGame, this, 1); + Bind(wxEVT_MENU, &GameViewer::RemoveGame, this, 2); + PopupMenu(m_popup, event.GetPoint()); } +void GameViewer::BootGame(wxCommandEvent& WXUNUSED(event)) +{ + wxListEvent unused_event; + DClick(unused_event); +} + +void GameViewer::ConfigureGame(wxCommandEvent& WXUNUSED(event)) +{ + long i = GetFirstSelected(); + if (i < 0) return; + + Emu.CreateConfig(m_game_data[i].serial); + rpcs3::config.path("data/" + m_game_data[i].serial + "/" + m_game_data[i].serial + ".ini"); + LOG_NOTICE(LOADER, "Configure: '%s'", rpcs3::config.path().c_str()); + rpcs3::config.load(); + SettingsDialog(this); + rpcs3::config.path("rpcs3.new.ini"); + rpcs3::config.load(); +} + void GameViewer::RemoveGame(wxCommandEvent& event) { Emu.GetVFS().Init("/"); diff --git a/rpcs3/Gui/GameViewer.h b/rpcs3/Gui/GameViewer.h index 71df489898..078dc00032 100644 --- a/rpcs3/Gui/GameViewer.h +++ b/rpcs3/Gui/GameViewer.h @@ -279,8 +279,9 @@ public: void LoadSettings(); void Refresh(); + void BootGame(wxCommandEvent& event); + void ConfigureGame(wxCommandEvent& event); void RemoveGame(wxCommandEvent& event); - bool RemoveFolder(std::string localPath); private: virtual void DClick(wxListEvent& event); diff --git a/rpcs3/Gui/SettingsDialog.cpp b/rpcs3/Gui/SettingsDialog.cpp index 1591c28f3c..f41f0036ac 100644 --- a/rpcs3/Gui/SettingsDialog.cpp +++ b/rpcs3/Gui/SettingsDialog.cpp @@ -196,6 +196,7 @@ SettingsDialog::SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg) wxCheckBox* chbox_hle_savetty = new wxCheckBox(p_misc, wxID_ANY, "Save TTY output to file"); wxCheckBox* chbox_hle_exitonstop = new wxCheckBox(p_misc, wxID_ANY, "Exit RPCS3 when process finishes"); wxCheckBox* chbox_hle_always_start = new wxCheckBox(p_misc, wxID_ANY, "Always start after boot"); + wxCheckBox* chbox_hle_use_default_ini = new wxCheckBox(p_misc, wxID_ANY, "Use default configuration"); wxTextCtrl* txt_dbg_range_min = new wxTextCtrl(p_core, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(55, 20)); wxTextCtrl* txt_dbg_range_max = new wxTextCtrl(p_core, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(55, 20)); @@ -335,6 +336,7 @@ SettingsDialog::SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg) chbox_hle_savetty->SetValue(Ini.HLESaveTTY.GetValue()); chbox_hle_exitonstop->SetValue(Ini.HLEExitOnStop.GetValue()); chbox_hle_always_start->SetValue(Ini.HLEAlwaysStart.GetValue()); + chbox_hle_use_default_ini->SetValue(Ini.UseDefaultIni.GetValue()); chbox_core_hook_stfunc->SetValue(Ini.HookStFunc.GetValue()); chbox_core_load_liblv2->SetValue(Ini.LoadLibLv2.GetValue()); @@ -449,6 +451,7 @@ SettingsDialog::SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg) s_subpanel_misc->Add(chbox_hle_savetty, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel_misc->Add(chbox_hle_exitonstop, wxSizerFlags().Border(wxALL, 5).Expand()); s_subpanel_misc->Add(chbox_hle_always_start, wxSizerFlags().Border(wxALL, 5).Expand()); + s_subpanel_misc->Add(chbox_hle_use_default_ini, wxSizerFlags().Border(wxALL, 5).Expand()); // Auto Pause s_subpanel_misc->Add(chbox_dbg_ap_systemcall, wxSizerFlags().Border(wxALL, 5).Expand()); @@ -528,6 +531,7 @@ SettingsDialog::SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg) Ini.NETInterface.SetValue(cbox_net_interface->GetSelection()); Ini.SysLanguage.SetValue(cbox_sys_lang->GetSelection()); Ini.HLEAlwaysStart.SetValue(chbox_hle_always_start->GetValue()); + Ini.UseDefaultIni.SetValue(chbox_hle_use_default_ini->GetValue()); //Auto Pause Ini.DBGAutoPauseFunctionCall.SetValue(chbox_dbg_ap_functioncall->GetValue()); diff --git a/rpcs3/Ini.h b/rpcs3/Ini.h index 139df08436..fbee6f27f0 100644 --- a/rpcs3/Ini.h +++ b/rpcs3/Ini.h @@ -161,6 +161,7 @@ public: IniEntry HLESaveTTY; IniEntry HLEExitOnStop; IniEntry HLEAlwaysStart; + IniEntry UseDefaultIni; // Auto Pause IniEntry DBGAutoPauseSystemCall; @@ -249,6 +250,7 @@ public: HLEExitOnStop.Init("HLE_HLEExitOnStop", path); HLELogLvl.Init("HLE_HLELogLvl", path); HLEAlwaysStart.Init("HLE_HLEAlwaysStart", path); + UseDefaultIni.Init("HLE_UseDefaultIni", path); // Auto Pause DBGAutoPauseFunctionCall.Init("DBG_AutoPauseFunctionCall", path); @@ -333,6 +335,7 @@ public: HLEExitOnStop.Load(false); HLELogLvl.Load(3); HLEAlwaysStart.Load(true); + UseDefaultIni.Load(false); //Auto Pause DBGAutoPauseFunctionCall.Load(false); @@ -417,6 +420,7 @@ public: HLEExitOnStop.Save(); HLELogLvl.Save(); HLEAlwaysStart.Save(); + UseDefaultIni.Save(); //Auto Pause DBGAutoPauseFunctionCall.Save();