mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-03 13:31:18 +12:00
Windows default to non-portable + Reworked MLC handling and related UI (#1252)
This commit is contained in:
parent
7522c8470e
commit
64232ffdbd
18 changed files with 515 additions and 651 deletions
|
@ -7,41 +7,47 @@
|
|||
#include "config/LaunchSettings.h"
|
||||
#include "util/helpers/helpers.h"
|
||||
|
||||
std::set<fs::path>
|
||||
ActiveSettings::LoadOnce(
|
||||
const fs::path& executablePath,
|
||||
const fs::path& userDataPath,
|
||||
const fs::path& configPath,
|
||||
const fs::path& cachePath,
|
||||
const fs::path& dataPath)
|
||||
void ActiveSettings::SetPaths(bool isPortableMode,
|
||||
const fs::path& executablePath,
|
||||
const fs::path& userDataPath,
|
||||
const fs::path& configPath,
|
||||
const fs::path& cachePath,
|
||||
const fs::path& dataPath,
|
||||
std::set<fs::path>& failedWriteAccess)
|
||||
{
|
||||
cemu_assert_debug(!s_setPathsCalled); // can only change paths before loading
|
||||
s_isPortableMode = isPortableMode;
|
||||
s_executable_path = executablePath;
|
||||
s_user_data_path = userDataPath;
|
||||
s_config_path = configPath;
|
||||
s_cache_path = cachePath;
|
||||
s_data_path = dataPath;
|
||||
std::set<fs::path> failed_write_access;
|
||||
failedWriteAccess.clear();
|
||||
for (auto&& path : {userDataPath, configPath, cachePath})
|
||||
{
|
||||
if (!fs::exists(path))
|
||||
{
|
||||
std::error_code ec;
|
||||
std::error_code ec;
|
||||
if (!fs::exists(path, ec))
|
||||
fs::create_directories(path, ec);
|
||||
}
|
||||
if (!TestWriteAccess(path))
|
||||
{
|
||||
cemuLog_log(LogType::Force, "Failed to write to {}", _pathToUtf8(path));
|
||||
failed_write_access.insert(path);
|
||||
failedWriteAccess.insert(path);
|
||||
}
|
||||
}
|
||||
|
||||
s_executable_filename = s_executable_path.filename();
|
||||
s_setPathsCalled = true;
|
||||
}
|
||||
|
||||
g_config.SetFilename(GetConfigPath("settings.xml").generic_wstring());
|
||||
g_config.Load();
|
||||
[[nodiscard]] bool ActiveSettings::IsPortableMode()
|
||||
{
|
||||
return s_isPortableMode;
|
||||
}
|
||||
|
||||
void ActiveSettings::Init()
|
||||
{
|
||||
cemu_assert_debug(s_setPathsCalled);
|
||||
std::string additionalErrorInfo;
|
||||
s_has_required_online_files = iosuCrypt_checkRequirementsForOnlineMode(additionalErrorInfo) == IOS_CRYPTO_ONLINE_REQ_OK;
|
||||
return failed_write_access;
|
||||
}
|
||||
|
||||
bool ActiveSettings::LoadSharedLibrariesEnabled()
|
||||
|
@ -229,6 +235,7 @@ bool ActiveSettings::ForceSamplerRoundToPrecision()
|
|||
|
||||
fs::path ActiveSettings::GetMlcPath()
|
||||
{
|
||||
cemu_assert_debug(s_setPathsCalled);
|
||||
if(const auto launch_mlc = LaunchSettings::GetMLCPath(); launch_mlc.has_value())
|
||||
return launch_mlc.value();
|
||||
|
||||
|
@ -238,6 +245,17 @@ fs::path ActiveSettings::GetMlcPath()
|
|||
return GetDefaultMLCPath();
|
||||
}
|
||||
|
||||
bool ActiveSettings::IsCustomMlcPath()
|
||||
{
|
||||
cemu_assert_debug(s_setPathsCalled);
|
||||
return !GetConfig().mlc_path.GetValue().empty();
|
||||
}
|
||||
|
||||
bool ActiveSettings::IsCommandLineMlcPath()
|
||||
{
|
||||
return LaunchSettings::GetMLCPath().has_value();
|
||||
}
|
||||
|
||||
fs::path ActiveSettings::GetDefaultMLCPath()
|
||||
{
|
||||
return GetUserDataPath("mlc01");
|
||||
|
|
|
@ -34,12 +34,16 @@ private:
|
|||
|
||||
public:
|
||||
// Set directories and return all directories that failed write access test
|
||||
static std::set<fs::path>
|
||||
LoadOnce(const fs::path& executablePath,
|
||||
const fs::path& userDataPath,
|
||||
const fs::path& configPath,
|
||||
const fs::path& cachePath,
|
||||
const fs::path& dataPath);
|
||||
static void
|
||||
SetPaths(bool isPortableMode,
|
||||
const fs::path& executablePath,
|
||||
const fs::path& userDataPath,
|
||||
const fs::path& configPath,
|
||||
const fs::path& cachePath,
|
||||
const fs::path& dataPath,
|
||||
std::set<fs::path>& failedWriteAccess);
|
||||
|
||||
static void Init();
|
||||
|
||||
[[nodiscard]] static fs::path GetExecutablePath() { return s_executable_path; }
|
||||
[[nodiscard]] static fs::path GetExecutableFilename() { return s_executable_filename; }
|
||||
|
@ -56,11 +60,14 @@ public:
|
|||
|
||||
template <typename ...TArgs>
|
||||
[[nodiscard]] static fs::path GetMlcPath(TArgs&&... args){ return GetPath(GetMlcPath(), std::forward<TArgs>(args)...); };
|
||||
static bool IsCustomMlcPath();
|
||||
static bool IsCommandLineMlcPath();
|
||||
|
||||
// get mlc path to default cemu root dir/mlc01
|
||||
[[nodiscard]] static fs::path GetDefaultMLCPath();
|
||||
|
||||
private:
|
||||
inline static bool s_isPortableMode{false};
|
||||
inline static fs::path s_executable_path;
|
||||
inline static fs::path s_user_data_path;
|
||||
inline static fs::path s_config_path;
|
||||
|
@ -70,6 +77,9 @@ private:
|
|||
inline static fs::path s_mlc_path;
|
||||
|
||||
public:
|
||||
// can be called before Init
|
||||
[[nodiscard]] static bool IsPortableMode();
|
||||
|
||||
// general
|
||||
[[nodiscard]] static bool LoadSharedLibrariesEnabled();
|
||||
[[nodiscard]] static bool DisplayDRCEnabled();
|
||||
|
@ -111,6 +121,7 @@ public:
|
|||
[[nodiscard]] static bool ForceSamplerRoundToPrecision();
|
||||
|
||||
private:
|
||||
inline static bool s_setPathsCalled = false;
|
||||
// dump options
|
||||
inline static bool s_dump_shaders = false;
|
||||
inline static bool s_dump_textures = false;
|
||||
|
|
|
@ -8,10 +8,6 @@ add_library(CemuConfig
|
|||
LaunchSettings.h
|
||||
NetworkSettings.cpp
|
||||
NetworkSettings.h
|
||||
PermanentConfig.cpp
|
||||
PermanentConfig.h
|
||||
PermanentStorage.cpp
|
||||
PermanentStorage.h
|
||||
XMLConfig.h
|
||||
)
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include <wx/language.h>
|
||||
|
||||
#include "PermanentConfig.h"
|
||||
#include "ActiveSettings.h"
|
||||
|
||||
XMLCemuConfig_t g_config(L"settings.xml");
|
||||
|
@ -15,23 +14,6 @@ void CemuConfig::SetMLCPath(fs::path path, bool save)
|
|||
mlc_path.SetValue(_pathToUtf8(path));
|
||||
if(save)
|
||||
g_config.Save();
|
||||
|
||||
// if custom mlc path has been selected, store it in permanent config
|
||||
if (path != ActiveSettings::GetDefaultMLCPath())
|
||||
{
|
||||
try
|
||||
{
|
||||
auto pconfig = PermanentConfig::Load();
|
||||
pconfig.custom_mlc_path = _pathToUtf8(path);
|
||||
pconfig.Store();
|
||||
}
|
||||
catch (const PSDisabledException&) {}
|
||||
catch (const std::exception& ex)
|
||||
{
|
||||
cemuLog_log(LogType::Force, "can't store custom mlc path in permanent storage: {}", ex.what());
|
||||
}
|
||||
}
|
||||
|
||||
Account::RefreshAccounts();
|
||||
}
|
||||
|
||||
|
|
|
@ -417,7 +417,7 @@ struct CemuConfig
|
|||
ConfigValue<bool> save_screenshot{true};
|
||||
|
||||
ConfigValue<bool> did_show_vulkan_warning{false};
|
||||
ConfigValue<bool> did_show_graphic_pack_download{false};
|
||||
ConfigValue<bool> did_show_graphic_pack_download{false}; // no longer used but we keep the config value around in case people downgrade Cemu. Despite the name this was used for the Getting Started dialog
|
||||
ConfigValue<bool> did_show_macos_disclaimer{false};
|
||||
|
||||
ConfigValue<bool> show_icon_column{ true };
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
#include "PermanentConfig.h"
|
||||
|
||||
#include "pugixml.hpp"
|
||||
|
||||
#include "PermanentStorage.h"
|
||||
|
||||
struct xml_string_writer : pugi::xml_writer
|
||||
{
|
||||
std::string result;
|
||||
|
||||
void write(const void* data, size_t size) override
|
||||
{
|
||||
result.append(static_cast<const char*>(data), size);
|
||||
}
|
||||
};
|
||||
|
||||
std::string PermanentConfig::ToXMLString() const noexcept
|
||||
{
|
||||
pugi::xml_document doc;
|
||||
doc.append_child(pugi::node_declaration).append_attribute("encoding") = "UTF-8";
|
||||
auto root = doc.append_child("config");
|
||||
root.append_child("MlcPath").text().set(this->custom_mlc_path.c_str());
|
||||
|
||||
xml_string_writer writer;
|
||||
doc.save(writer);
|
||||
return writer.result;
|
||||
}
|
||||
|
||||
PermanentConfig PermanentConfig::FromXMLString(std::string_view str) noexcept
|
||||
{
|
||||
PermanentConfig result{};
|
||||
|
||||
pugi::xml_document doc;
|
||||
if(doc.load_buffer(str.data(), str.size()))
|
||||
{
|
||||
result.custom_mlc_path = doc.select_node("/config/MlcPath").node().text().as_string();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
PermanentConfig PermanentConfig::Load()
|
||||
{
|
||||
PermanentStorage storage;
|
||||
|
||||
const auto str = storage.ReadFile(kFileName);
|
||||
if (!str.empty())
|
||||
return FromXMLString(str);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool PermanentConfig::Store() noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
PermanentStorage storage;
|
||||
storage.WriteStringToFile(kFileName, ToXMLString());
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "PermanentStorage.h"
|
||||
|
||||
struct PermanentConfig
|
||||
{
|
||||
static constexpr const char* kFileName = "perm_setting.xml";
|
||||
|
||||
std::string custom_mlc_path;
|
||||
|
||||
[[nodiscard]] std::string ToXMLString() const noexcept;
|
||||
static PermanentConfig FromXMLString(std::string_view str) noexcept;
|
||||
|
||||
// gets from permanent storage
|
||||
static PermanentConfig Load();
|
||||
// saves to permanent storage
|
||||
bool Store() noexcept;
|
||||
};
|
|
@ -1,76 +0,0 @@
|
|||
#include "PermanentStorage.h"
|
||||
#include "config/CemuConfig.h"
|
||||
#include "util/helpers/SystemException.h"
|
||||
|
||||
PermanentStorage::PermanentStorage()
|
||||
{
|
||||
if (!GetConfig().permanent_storage)
|
||||
throw PSDisabledException();
|
||||
|
||||
const char* appdata = std::getenv("LOCALAPPDATA");
|
||||
if (!appdata)
|
||||
throw std::runtime_error("can't get LOCALAPPDATA");
|
||||
m_storage_path = appdata;
|
||||
m_storage_path /= "Cemu";
|
||||
|
||||
fs::create_directories(m_storage_path);
|
||||
}
|
||||
|
||||
PermanentStorage::~PermanentStorage()
|
||||
{
|
||||
if (m_remove_storage)
|
||||
{
|
||||
std::error_code ec;
|
||||
fs::remove_all(m_storage_path, ec);
|
||||
if (ec)
|
||||
{
|
||||
SystemException ex(ec);
|
||||
cemuLog_log(LogType::Force, "can't remove permanent storage: {}", ex.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PermanentStorage::ClearAllFiles() const
|
||||
{
|
||||
fs::remove_all(m_storage_path);
|
||||
fs::create_directories(m_storage_path);
|
||||
}
|
||||
|
||||
void PermanentStorage::RemoveStorage()
|
||||
{
|
||||
m_remove_storage = true;
|
||||
}
|
||||
|
||||
void PermanentStorage::WriteStringToFile(std::string_view filename, std::string_view content)
|
||||
{
|
||||
const auto name = m_storage_path.append(filename.data(), filename.data() + filename.size());
|
||||
std::ofstream file(name.string());
|
||||
file.write(content.data(), (uint32_t)content.size());
|
||||
}
|
||||
|
||||
std::string PermanentStorage::ReadFile(std::string_view filename) noexcept
|
||||
{
|
||||
try
|
||||
{
|
||||
const auto name = m_storage_path.append(filename.data(), filename.data() + filename.size());
|
||||
std::ifstream file(name, std::ios::in | std::ios::ate);
|
||||
if (!file.is_open())
|
||||
return {};
|
||||
|
||||
const auto end = file.tellg();
|
||||
file.seekg(0, std::ios::beg);
|
||||
const auto file_size = end - file.tellg();
|
||||
if (file_size == 0)
|
||||
return {};
|
||||
|
||||
std::string result;
|
||||
result.resize(file_size);
|
||||
file.read(result.data(), file_size);
|
||||
return result;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
// disabled by config
|
||||
class PSDisabledException : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
PSDisabledException()
|
||||
: std::runtime_error("permanent storage is disabled by user") {}
|
||||
};
|
||||
|
||||
class PermanentStorage
|
||||
{
|
||||
public:
|
||||
PermanentStorage();
|
||||
~PermanentStorage();
|
||||
|
||||
void ClearAllFiles() const;
|
||||
// flags storage to be removed on destruction
|
||||
void RemoveStorage();
|
||||
|
||||
void WriteStringToFile(std::string_view filename, std::string_view content);
|
||||
std::string ReadFile(std::string_view filename) noexcept;
|
||||
|
||||
private:
|
||||
fs::path m_storage_path;
|
||||
bool m_remove_storage = false;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue