mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2024-12-28 18:46:06 +00:00
Use fs::path::native whenever possible, avoid unnecessary fs->string conversions in GUI code (#1064)
* Use filesystem::path whenever possible, remove fs::path::string * My hatred for Windows grows with every passing day * More Qt stuff * custom u8string formatter for fmt library * Use u8string for imgui * Fix toml errors hopefully * Fix not printing issue * Oh and on SDL * I hate Windows even more today * fix toml reading utf-8 paths also small fix for fmt::UTF * Formatting * Fix QT path to run games * Fix path logging in save data * Fix trophy path handling * Update game_list_frame.cpp fixed snd0path * Update main_window.cpp fix snd0path * Update main_window.cpp * paths finally fixed * git info in WIP versions title --------- Co-authored-by: Vinicius Rangel <me@viniciusrangel.dev> Co-authored-by: georgemoralis <giorgosmrls@gmail.com>
This commit is contained in:
parent
54e2179337
commit
6295d6c416
|
@ -4,9 +4,25 @@
|
|||
#include <fstream>
|
||||
#include <string>
|
||||
#include <fmt/core.h>
|
||||
#include <fmt/xchar.h> // for wstring support
|
||||
#include <toml.hpp>
|
||||
#include "common/logging/formatter.h"
|
||||
#include "config.h"
|
||||
|
||||
namespace toml {
|
||||
template <typename TC, typename K>
|
||||
std::filesystem::path find_fs_path_or(const basic_value<TC>& v, const K& ky,
|
||||
std::filesystem::path opt) {
|
||||
try {
|
||||
auto str = find<std::string>(v, ky);
|
||||
std::u8string u8str{(char8_t*)&str.front(), (char8_t*)&str.back() + 1};
|
||||
return std::filesystem::path{u8str};
|
||||
} catch (...) {
|
||||
return opt;
|
||||
}
|
||||
}
|
||||
} // namespace toml
|
||||
|
||||
namespace Config {
|
||||
|
||||
static bool isNeo = false;
|
||||
|
@ -37,7 +53,7 @@ static bool vkMarkers = false;
|
|||
static bool vkCrashDiagnostic = false;
|
||||
|
||||
// Gui
|
||||
std::string settings_install_dir = "";
|
||||
std::filesystem::path settings_install_dir = {};
|
||||
u32 main_window_geometry_x = 400;
|
||||
u32 main_window_geometry_y = 400;
|
||||
u32 main_window_geometry_w = 1280;
|
||||
|
@ -267,7 +283,7 @@ void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h) {
|
|||
main_window_geometry_w = w;
|
||||
main_window_geometry_h = h;
|
||||
}
|
||||
void setGameInstallDir(const std::string& dir) {
|
||||
void setGameInstallDir(const std::filesystem::path& dir) {
|
||||
settings_install_dir = dir;
|
||||
}
|
||||
void setMainWindowTheme(u32 theme) {
|
||||
|
@ -323,7 +339,7 @@ u32 getMainWindowGeometryW() {
|
|||
u32 getMainWindowGeometryH() {
|
||||
return main_window_geometry_h;
|
||||
}
|
||||
std::string getGameInstallDir() {
|
||||
std::filesystem::path getGameInstallDir() {
|
||||
return settings_install_dir;
|
||||
}
|
||||
u32 getMainWindowTheme() {
|
||||
|
@ -378,7 +394,10 @@ void load(const std::filesystem::path& path) {
|
|||
toml::value data;
|
||||
|
||||
try {
|
||||
data = toml::parse(path);
|
||||
std::ifstream ifs;
|
||||
ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
ifs.open(path, std::ios_base::binary);
|
||||
data = toml::parse(ifs, std::string{fmt::UTF(path.filename().u8string()).data});
|
||||
} catch (std::exception& ex) {
|
||||
fmt::print("Got exception trying to load config file. Exception: {}\n", ex.what());
|
||||
return;
|
||||
|
@ -444,7 +463,7 @@ void load(const std::filesystem::path& path) {
|
|||
mw_themes = toml::find_or<int>(gui, "theme", 0);
|
||||
m_window_size_W = toml::find_or<int>(gui, "mw_width", 0);
|
||||
m_window_size_H = toml::find_or<int>(gui, "mw_height", 0);
|
||||
settings_install_dir = toml::find_or<std::string>(gui, "installDir", "");
|
||||
settings_install_dir = toml::find_fs_path_or(gui, "installDir", {});
|
||||
main_window_geometry_x = toml::find_or<int>(gui, "geometry_x", 0);
|
||||
main_window_geometry_y = toml::find_or<int>(gui, "geometry_y", 0);
|
||||
main_window_geometry_w = toml::find_or<int>(gui, "geometry_w", 0);
|
||||
|
@ -468,17 +487,19 @@ void save(const std::filesystem::path& path) {
|
|||
std::error_code error;
|
||||
if (std::filesystem::exists(path, error)) {
|
||||
try {
|
||||
data = toml::parse(path);
|
||||
std::ifstream ifs;
|
||||
ifs.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||
ifs.open(path, std::ios_base::binary);
|
||||
data = toml::parse(ifs, std::string{fmt::UTF(path.filename().u8string()).data});
|
||||
} catch (const std::exception& ex) {
|
||||
fmt::print("Exception trying to parse config file. Exception: {}\n", ex.what());
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if (error) {
|
||||
fmt::print("Filesystem error accessing {} (error: {})\n", path.string(),
|
||||
error.message().c_str());
|
||||
fmt::print("Filesystem error: {}\n", error.message());
|
||||
}
|
||||
fmt::print("Saving new configuration file {}\n", path.string());
|
||||
fmt::print("Saving new configuration file {}\n", fmt::UTF(path.u8string()));
|
||||
}
|
||||
|
||||
data["General"]["isPS4Pro"] = isNeo;
|
||||
|
@ -515,7 +536,7 @@ void save(const std::filesystem::path& path) {
|
|||
data["GUI"]["gameTableMode"] = m_table_mode;
|
||||
data["GUI"]["mw_width"] = m_window_size_W;
|
||||
data["GUI"]["mw_height"] = m_window_size_H;
|
||||
data["GUI"]["installDir"] = settings_install_dir;
|
||||
data["GUI"]["installDir"] = std::string{fmt::UTF(settings_install_dir.u8string()).data};
|
||||
data["GUI"]["geometry_x"] = main_window_geometry_x;
|
||||
data["GUI"]["geometry_y"] = main_window_geometry_y;
|
||||
data["GUI"]["geometry_w"] = main_window_geometry_w;
|
||||
|
|
|
@ -72,7 +72,7 @@ bool vkCrashDiagnosticEnabled();
|
|||
|
||||
// Gui
|
||||
void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h);
|
||||
void setGameInstallDir(const std::string& dir);
|
||||
void setGameInstallDir(const std::filesystem::path& dir);
|
||||
void setMainWindowTheme(u32 theme);
|
||||
void setIconSize(u32 size);
|
||||
void setIconSizeGrid(u32 size);
|
||||
|
@ -90,7 +90,7 @@ u32 getMainWindowGeometryX();
|
|||
u32 getMainWindowGeometryY();
|
||||
u32 getMainWindowGeometryW();
|
||||
u32 getMainWindowGeometryH();
|
||||
std::string getGameInstallDir();
|
||||
std::filesystem::path getGameInstallDir();
|
||||
u32 getMainWindowTheme();
|
||||
u32 getIconSize();
|
||||
u32 getIconSizeGrid();
|
||||
|
|
|
@ -19,3 +19,24 @@ struct fmt::formatter<T, std::enable_if_t<std::is_enum_v<T>, char>>
|
|||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
namespace fmt {
|
||||
template <typename T = std::string_view>
|
||||
struct UTF {
|
||||
T data;
|
||||
|
||||
explicit UTF(const std::u8string_view view) {
|
||||
data = T{(const char*)&view.front(), (const char*)&view.back() + 1};
|
||||
}
|
||||
|
||||
explicit UTF(const std::u8string& str) : UTF(std::u8string_view{str}) {}
|
||||
};
|
||||
} // namespace fmt
|
||||
|
||||
template <>
|
||||
struct fmt::formatter<fmt::UTF<std::string_view>, char> : formatter<std::string_view> {
|
||||
template <typename FormatContext>
|
||||
auto format(const UTF<std::string_view>& wrapper, FormatContext& ctx) const {
|
||||
return formatter<std::string_view>::format(wrapper.data, ctx);
|
||||
}
|
||||
};
|
|
@ -119,9 +119,9 @@ std::string convertValueToHex(const std::string type, const std::string valueStr
|
|||
void OnGameLoaded() {
|
||||
|
||||
if (!patchFile.empty()) {
|
||||
std::string patchDir = Common::FS::GetUserPath(Common::FS::PathType::PatchesDir).string();
|
||||
std::filesystem::path patchDir = Common::FS::GetUserPath(Common::FS::PathType::PatchesDir);
|
||||
|
||||
std::string filePath = patchDir + "/" + patchFile;
|
||||
auto filePath = (patchDir / patchFile).native();
|
||||
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result result = doc.load_file(filePath.c_str());
|
||||
|
@ -187,8 +187,8 @@ void OnGameLoaded() {
|
|||
|
||||
#ifdef ENABLE_QT_GUI
|
||||
// We use the QT headers for the xml and json parsing, this define is only true on QT builds
|
||||
QString patchDir =
|
||||
QString::fromStdString(Common::FS::GetUserPath(Common::FS::PathType::PatchesDir).string());
|
||||
QString patchDir;
|
||||
Common::FS::PathToQString(patchDir, Common::FS::GetUserPath(Common::FS::PathType::PatchesDir));
|
||||
QString repositories[] = {"GoldHEN", "shadPS4"};
|
||||
|
||||
for (const QString& repository : repositories) {
|
||||
|
|
|
@ -22,6 +22,10 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_QT_GUI
|
||||
#include <QString>
|
||||
#endif
|
||||
|
||||
namespace Common::FS {
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
@ -165,4 +169,22 @@ void SetUserPath(PathType shad_path, const fs::path& new_path) {
|
|||
UserPaths.insert_or_assign(shad_path, new_path);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_QT_GUI
|
||||
void PathToQString(QString& result, const std::filesystem::path& path) {
|
||||
#ifdef _WIN32
|
||||
result = QString::fromStdWString(path.wstring());
|
||||
#else
|
||||
result = QString::fromStdString(path.string());
|
||||
#endif
|
||||
}
|
||||
|
||||
std::filesystem::path PathFromQString(const QString& path) {
|
||||
#ifdef _WIN32
|
||||
return std::filesystem::path(path.toStdWString());
|
||||
#else
|
||||
return std::filesystem::path(path.toStdString());
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace Common::FS
|
|
@ -6,6 +6,10 @@
|
|||
#include <filesystem>
|
||||
#include <vector>
|
||||
|
||||
#ifdef ENABLE_QT_GUI
|
||||
class QString; // to avoid including <QString> in this header
|
||||
#endif
|
||||
|
||||
namespace Common::FS {
|
||||
|
||||
enum class PathType {
|
||||
|
@ -96,4 +100,23 @@ constexpr auto LOG_FILE = "shad_log.txt";
|
|||
*/
|
||||
void SetUserPath(PathType user_path, const std::filesystem::path& new_path);
|
||||
|
||||
#ifdef ENABLE_QT_GUI
|
||||
/**
|
||||
* Converts an std::filesystem::path to a QString.
|
||||
* The native underlying string of a path is wstring on Windows and string on POSIX.
|
||||
*
|
||||
* @param result The resulting QString
|
||||
* @param path The path to convert
|
||||
*/
|
||||
void PathToQString(QString& result, const std::filesystem::path& path);
|
||||
|
||||
/**
|
||||
* Converts a QString to an std::filesystem::path.
|
||||
* The native underlying string of a path is wstring on Windows and string on POSIX.
|
||||
*
|
||||
* @param path The path to convert
|
||||
*/
|
||||
[[nodiscard]] std::filesystem::path PathFromQString(const QString& path);
|
||||
#endif
|
||||
|
||||
} // namespace Common::FS
|
||||
|
|
|
@ -371,8 +371,7 @@ bool PKG::Extract(const std::filesystem::path& filepath, const std::filesystem::
|
|||
if (table.type == PFS_CURRENT_DIR) {
|
||||
current_dir = extractPaths[table.inode];
|
||||
}
|
||||
extractPaths[table.inode] =
|
||||
current_dir.string() / std::filesystem::path(table.name);
|
||||
extractPaths[table.inode] = current_dir / std::filesystem::path(table.name);
|
||||
|
||||
if (table.type == PFS_FILE || table.type == PFS_DIR) {
|
||||
if (table.type == PFS_DIR) { // Create dirs.
|
||||
|
@ -402,7 +401,7 @@ void PKG::ExtractFiles(const int index) {
|
|||
int bsize = iNodeBuf[inode_number].Size;
|
||||
|
||||
Common::FS::IOFile inflated;
|
||||
inflated.Open(extractPaths[inode_number].string(), Common::FS::FileAccessMode::Write);
|
||||
inflated.Open(extractPaths[inode_number], Common::FS::FileAccessMode::Write);
|
||||
|
||||
Common::FS::IOFile pkgFile; // Open the file for each iteration to avoid conflict.
|
||||
pkgFile.Open(pkgpath, Common::FS::FileAccessMode::Read);
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
#define STBI_NO_STDIO
|
||||
#include "externals/stb_image.h"
|
||||
|
||||
bool Splash::Open(const std::string& filepath) {
|
||||
ASSERT_MSG(filepath.ends_with(".png"), "Unexpected file format passed");
|
||||
bool Splash::Open(const std::filesystem::path& filepath) {
|
||||
ASSERT_MSG(filepath.stem().string() != "png", "Unexpected file format passed");
|
||||
|
||||
Common::FS::IOFile file(filepath, Common::FS::FileAccessMode::Read);
|
||||
if (!file.IsOpen()) {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "common/types.h"
|
||||
|
@ -22,7 +23,7 @@ public:
|
|||
Splash() = default;
|
||||
~Splash() = default;
|
||||
|
||||
bool Open(const std::string& filepath);
|
||||
bool Open(const std::filesystem::path& filepath);
|
||||
[[nodiscard]] bool IsLoaded() const {
|
||||
return img_data.size();
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ static void removePadding(std::vector<u8>& vec) {
|
|||
}
|
||||
|
||||
bool TRP::Extract(const std::filesystem::path& trophyPath) {
|
||||
std::string title = trophyPath.filename().string();
|
||||
std::filesystem::path title = trophyPath.filename();
|
||||
std::filesystem::path gameSysDir = trophyPath / "sce_sys/trophy/";
|
||||
if (!std::filesystem::exists(gameSysDir)) {
|
||||
return false;
|
||||
|
|
|
@ -557,10 +557,10 @@ s32 PS4_SYSV_ABI sceNpTrophyGetTrophyUnlockState(OrbisNpTrophyContext context,
|
|||
|
||||
const auto trophyDir =
|
||||
Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) / game_serial / "TrophyFiles";
|
||||
auto trophy_file = trophyDir / "trophy00" / "Xml" / "TROP.XML";
|
||||
|
||||
pugi::xml_document doc;
|
||||
pugi::xml_parse_result result =
|
||||
doc.load_file((trophyDir.string() + "/trophy00/Xml/TROP.XML").c_str());
|
||||
pugi::xml_parse_result result = doc.load_file(trophy_file.native().c_str());
|
||||
|
||||
int numTrophies = 0;
|
||||
|
||||
|
|
|
@ -107,14 +107,16 @@ static void BackupThreadBody() {
|
|||
}
|
||||
g_backup_status = WorkerStatus::Running;
|
||||
|
||||
LOG_INFO(Lib_SaveData, "Backing up the following directory: {}", req.save_path.string());
|
||||
LOG_INFO(Lib_SaveData, "Backing up the following directory: {}",
|
||||
fmt::UTF(req.save_path.u8string()));
|
||||
try {
|
||||
backup(req.save_path);
|
||||
} catch (const std::filesystem::filesystem_error& err) {
|
||||
LOG_ERROR(Lib_SaveData, "Failed to backup {}: {}", req.save_path.string(), err.what());
|
||||
LOG_ERROR(Lib_SaveData, "Failed to backup {}: {}", fmt::UTF(req.save_path.u8string()),
|
||||
err.what());
|
||||
}
|
||||
LOG_DEBUG(Lib_SaveData, "Backing up the following directory: {} finished",
|
||||
req.save_path.string());
|
||||
fmt::UTF(req.save_path.u8string()));
|
||||
{
|
||||
std::scoped_lock lk{g_backup_queue_mutex};
|
||||
g_backup_queue.front().done = true;
|
||||
|
@ -160,7 +162,7 @@ bool NewRequest(OrbisUserServiceUserId user_id, std::string_view title_id,
|
|||
|
||||
if (g_backup_status != WorkerStatus::Waiting && g_backup_status != WorkerStatus::Running) {
|
||||
LOG_ERROR(Lib_SaveData, "Called backup while status is {}. Backup request to {} ignored",
|
||||
magic_enum::enum_name(g_backup_status.load()), save_path.string());
|
||||
magic_enum::enum_name(g_backup_status.load()), fmt::UTF(save_path.u8string()));
|
||||
return false;
|
||||
}
|
||||
{
|
||||
|
@ -184,7 +186,7 @@ bool NewRequest(OrbisUserServiceUserId user_id, std::string_view title_id,
|
|||
}
|
||||
|
||||
bool Restore(const std::filesystem::path& save_path) {
|
||||
LOG_INFO(Lib_SaveData, "Restoring backup for {}", save_path.string());
|
||||
LOG_INFO(Lib_SaveData, "Restoring backup for {}", fmt::UTF(save_path.u8string()));
|
||||
std::unique_lock lk{g_backup_running_mutex};
|
||||
if (!fs::exists(save_path) || !fs::exists(save_path / backup_dir)) {
|
||||
return false;
|
||||
|
|
|
@ -77,7 +77,7 @@ static void SaveFileSafe(void* buf, size_t count, const std::filesystem::path& p
|
|||
g_saving_memory = true;
|
||||
std::scoped_lock lk{g_saving_memory_mutex};
|
||||
try {
|
||||
LOG_DEBUG(Lib_SaveData, "Saving save data memory {}", g_save_path.string());
|
||||
LOG_DEBUG(Lib_SaveData, "Saving save data memory {}", fmt::UTF(g_save_path.u8string()));
|
||||
|
||||
if (g_memory_dirty) {
|
||||
g_memory_dirty = false;
|
||||
|
@ -163,7 +163,8 @@ size_t CreateSaveMemory(size_t memory_size) {
|
|||
|
||||
bool ok = g_param_sfo.Open(g_param_sfo_path);
|
||||
if (!ok) {
|
||||
LOG_ERROR(Lib_SaveData, "Failed to open SFO at {}", g_param_sfo_path.string());
|
||||
LOG_ERROR(Lib_SaveData, "Failed to open SFO at {}",
|
||||
fmt::UTF(g_param_sfo_path.u8string()));
|
||||
throw std::filesystem::filesystem_error(
|
||||
"failed to open SFO", g_param_sfo_path,
|
||||
std::make_error_code(std::errc::illegal_byte_sequence));
|
||||
|
|
|
@ -607,7 +607,7 @@ Error PS4_SYSV_ABI sceSaveDataCheckBackupData(const OrbisSaveDataCheckBackupData
|
|||
if (check->param != nullptr) {
|
||||
PSF sfo;
|
||||
if (!sfo.Open(backup_path / "sce_sys" / "param.sfo")) {
|
||||
LOG_ERROR(Lib_SaveData, "Failed to read SFO at {}", backup_path.string());
|
||||
LOG_ERROR(Lib_SaveData, "Failed to read SFO at {}", fmt::UTF(backup_path.u8string()));
|
||||
return Error::INTERNAL;
|
||||
}
|
||||
check->param->FromSFO(sfo);
|
||||
|
@ -818,7 +818,7 @@ Error PS4_SYSV_ABI sceSaveDataDirNameSearch(const OrbisSaveDataDirNameSearchCond
|
|||
const auto sfo_path = SaveInstance::GetParamSFOPath(dir_path);
|
||||
PSF sfo;
|
||||
if (!sfo.Open(sfo_path)) {
|
||||
LOG_ERROR(Lib_SaveData, "Failed to read SFO: {}", sfo_path.string());
|
||||
LOG_ERROR(Lib_SaveData, "Failed to read SFO: {}", fmt::UTF(sfo_path.u8string()));
|
||||
ASSERT_MSG(false, "Failed to read SFO");
|
||||
}
|
||||
map_dir_sfo.emplace(dir_name, std::move(sfo));
|
||||
|
|
|
@ -139,7 +139,7 @@ void Emulator::Run(const std::filesystem::path& file) {
|
|||
if (splash->IsLoaded()) {
|
||||
continue;
|
||||
}
|
||||
if (!splash->Open(entry.path().string())) {
|
||||
if (!splash->Open(entry.path())) {
|
||||
LOG_ERROR(Loader, "Game splash: unable to open file");
|
||||
}
|
||||
}
|
||||
|
@ -189,7 +189,7 @@ void Emulator::Run(const std::filesystem::path& file) {
|
|||
if (!std::filesystem::exists(mount_captures_dir)) {
|
||||
std::filesystem::create_directory(mount_captures_dir);
|
||||
}
|
||||
VideoCore::SetOutputDir(mount_captures_dir.generic_string(), id);
|
||||
VideoCore::SetOutputDir(mount_captures_dir, id);
|
||||
|
||||
// Initialize kernel and library facilities.
|
||||
Libraries::Kernel::init_pthreads();
|
||||
|
@ -205,7 +205,7 @@ void Emulator::Run(const std::filesystem::path& file) {
|
|||
std::filesystem::path sce_module_folder = file.parent_path() / "sce_module";
|
||||
if (std::filesystem::is_directory(sce_module_folder)) {
|
||||
for (const auto& entry : std::filesystem::directory_iterator(sce_module_folder)) {
|
||||
LOG_INFO(Loader, "Loading {}", entry.path().string().c_str());
|
||||
LOG_INFO(Loader, "Loading {}", fmt::UTF(entry.path().u8string()));
|
||||
linker->LoadModule(entry.path());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,8 +51,16 @@ void Initialize(const ::Vulkan::Instance& instance, const Frontend::WindowSDL& w
|
|||
io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad;
|
||||
io.ConfigFlags |= ImGuiConfigFlags_DockingEnable;
|
||||
io.DisplaySize = ImVec2((float)window.getWidth(), (float)window.getHeight());
|
||||
io.IniFilename = SDL_strdup(config_path.string().c_str());
|
||||
io.LogFilename = SDL_strdup(log_path.string().c_str());
|
||||
|
||||
auto path = config_path.u8string();
|
||||
char* config_file_buf = new char[path.size() + 1]();
|
||||
std::memcpy(config_file_buf, path.c_str(), path.size());
|
||||
io.IniFilename = config_file_buf;
|
||||
|
||||
path = log_path.u8string();
|
||||
char* log_file_buf = new char[path.size() + 1]();
|
||||
std::memcpy(log_file_buf, path.c_str(), path.size());
|
||||
io.LogFilename = log_file_buf;
|
||||
|
||||
ImFontGlyphRangesBuilder rb{};
|
||||
rb.AddRanges(io.Fonts->GetGlyphRangesDefault());
|
||||
|
@ -114,8 +122,8 @@ void Shutdown(const vk::Device& device) {
|
|||
Sdl::Shutdown();
|
||||
DestroyContext();
|
||||
|
||||
SDL_free(ini_filename);
|
||||
SDL_free(log_filename);
|
||||
delete[] (char*)ini_filename;
|
||||
delete[] (char*)log_filename;
|
||||
}
|
||||
|
||||
bool ProcessEvent(SDL_Event* event) {
|
||||
|
|
|
@ -5,7 +5,15 @@
|
|||
#include "common/memory_patcher.h"
|
||||
#include "emulator.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
#ifdef _WIN32
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
#endif
|
||||
|
||||
if (argc == 1) {
|
||||
fmt::print("Usage: {} <elf or eboot.bin path>\n", argv[0]);
|
||||
return -1;
|
||||
|
|
|
@ -50,8 +50,9 @@ void CheatsPatches::setupUI() {
|
|||
defaultTextEdit = tr("defaultTextEdit_MSG");
|
||||
defaultTextEdit.replace("\\n", "\n");
|
||||
|
||||
QString CHEATS_DIR_QString =
|
||||
QString::fromStdString(Common::FS::GetUserPath(Common::FS::PathType::CheatsDir).string());
|
||||
QString CHEATS_DIR_QString;
|
||||
Common::FS::PathToQString(CHEATS_DIR_QString,
|
||||
Common::FS::GetUserPath(Common::FS::PathType::CheatsDir));
|
||||
QString NameCheatJson = m_gameSerial + "_" + m_gameVersion + ".json";
|
||||
m_cheatFilePath = CHEATS_DIR_QString + "/" + NameCheatJson;
|
||||
|
||||
|
@ -275,9 +276,9 @@ void CheatsPatches::onSaveButtonClicked() {
|
|||
int separatorIndex = selectedPatchName.indexOf(" | ");
|
||||
selectedPatchName = selectedPatchName.mid(separatorIndex + 3);
|
||||
|
||||
QString patchDir =
|
||||
QString::fromStdString(Common::FS::GetUserPath(Common::FS::PathType::PatchesDir).string()) +
|
||||
"/" + selectedPatchName;
|
||||
QString patchDir;
|
||||
Common::FS::PathToQString(patchDir, Common::FS::GetUserPath(Common::FS::PathType::PatchesDir));
|
||||
patchDir += "/" + selectedPatchName;
|
||||
|
||||
QString filesJsonPath = patchDir + "/files.json";
|
||||
QFile jsonFile(filesJsonPath);
|
||||
|
@ -555,10 +556,10 @@ void CheatsPatches::downloadCheats(const QString& source, const QString& gameSer
|
|||
if (dotIndex != -1) {
|
||||
baseFileName.insert(dotIndex, "_wolf2022");
|
||||
}
|
||||
QString filePath =
|
||||
QString::fromStdString(
|
||||
Common::FS::GetUserPath(Common::FS::PathType::CheatsDir).string()) +
|
||||
"/" + baseFileName;
|
||||
QString filePath;
|
||||
Common::FS::PathToQString(filePath,
|
||||
Common::FS::GetUserPath(Common::FS::PathType::CheatsDir));
|
||||
filePath += "/" + baseFileName;
|
||||
if (QFile::exists(filePath) && showMessageBox) {
|
||||
QMessageBox::StandardButton reply2;
|
||||
reply2 =
|
||||
|
@ -612,8 +613,9 @@ void CheatsPatches::populateFileListPatches() {
|
|||
}
|
||||
m_patchInfos.clear();
|
||||
|
||||
QString patchesDir =
|
||||
QString::fromStdString(Common::FS::GetUserPath(Common::FS::PathType::PatchesDir).string());
|
||||
QString patchesDir;
|
||||
Common::FS::PathToQString(patchesDir,
|
||||
Common::FS::GetUserPath(Common::FS::PathType::PatchesDir));
|
||||
QDir dir(patchesDir);
|
||||
|
||||
QStringList folders = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
|
@ -906,8 +908,8 @@ void CheatsPatches::addCheatsToLayout(const QJsonArray& modsArray, const QJsonAr
|
|||
}
|
||||
|
||||
void CheatsPatches::populateFileListCheats() {
|
||||
QString cheatsDir =
|
||||
QString::fromStdString(Common::FS::GetUserPath(Common::FS::PathType::CheatsDir).string());
|
||||
QString cheatsDir;
|
||||
Common::FS::PathToQString(cheatsDir, Common::FS::GetUserPath(Common::FS::PathType::CheatsDir));
|
||||
QString pattern = m_gameSerial + "_" + m_gameVersion + "*.json";
|
||||
|
||||
QDir dir(cheatsDir);
|
||||
|
@ -932,8 +934,9 @@ void CheatsPatches::populateFileListCheats() {
|
|||
if (!selectedIndexes.isEmpty()) {
|
||||
|
||||
QString selectedFileName = selectedIndexes.first().data().toString();
|
||||
QString cheatsDir = QString::fromStdString(
|
||||
Common::FS::GetUserPath(Common::FS::PathType::CheatsDir).string());
|
||||
QString cheatsDir;
|
||||
Common::FS::PathToQString(
|
||||
cheatsDir, Common::FS::GetUserPath(Common::FS::PathType::CheatsDir));
|
||||
|
||||
QFile file(cheatsDir + "/" + selectedFileName);
|
||||
if (file.open(QIODevice::ReadOnly)) {
|
||||
|
|
|
@ -44,7 +44,8 @@ void GameGridFrame::PlayBackgroundMusic(QTableWidgetItem* item) {
|
|||
BackgroundMusicPlayer::getInstance().stopMusic();
|
||||
return;
|
||||
}
|
||||
const auto snd0path = QString::fromStdString(m_game_info->m_games[item->row()].snd0_path);
|
||||
QString snd0path;
|
||||
Common::FS::PathToQString(snd0path, m_game_info->m_games[item->row()].snd0_path);
|
||||
BackgroundMusicPlayer::getInstance().playMusic(snd0path);
|
||||
}
|
||||
|
||||
|
@ -122,14 +123,12 @@ void GameGridFrame::SetGridBackgroundImage(int row, int column) {
|
|||
int itemID = (row * this->columnCount()) + column;
|
||||
QWidget* item = this->cellWidget(row, column);
|
||||
if (item) {
|
||||
QString pic1Path = QString::fromStdString((*m_games_shared)[itemID].pic_path);
|
||||
QString pic1Path;
|
||||
Common::FS::PathToQString(pic1Path, (*m_games_shared)[itemID].pic_path);
|
||||
const auto blurredPic1Path = Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) /
|
||||
(*m_games_shared)[itemID].serial / "pic1.png";
|
||||
#ifdef _WIN32
|
||||
const auto blurredPic1PathQt = QString::fromStdWString(blurredPic1Path.wstring());
|
||||
#else
|
||||
const auto blurredPic1PathQt = QString::fromStdString(blurredPic1Path.string());
|
||||
#endif
|
||||
QString blurredPic1PathQt;
|
||||
Common::FS::PathToQString(blurredPic1PathQt, blurredPic1Path);
|
||||
|
||||
backgroundImage = QImage(blurredPic1PathQt);
|
||||
if (backgroundImage.isNull()) {
|
||||
|
|
|
@ -3,13 +3,15 @@
|
|||
|
||||
#include <QProgressDialog>
|
||||
|
||||
#include "common/path_util.h"
|
||||
#include "game_info.h"
|
||||
|
||||
GameInfoClass::GameInfoClass() = default;
|
||||
GameInfoClass::~GameInfoClass() = default;
|
||||
|
||||
void GameInfoClass::GetGameInfo(QWidget* parent) {
|
||||
QString installDir = QString::fromStdString(Config::getGameInstallDir());
|
||||
QString installDir;
|
||||
Common::FS::PathToQString(installDir, Config::getGameInstallDir());
|
||||
QStringList filePaths;
|
||||
QDir parentFolder(installDir);
|
||||
QFileInfoList fileList = parentFolder.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
|
@ -19,7 +21,7 @@ void GameInfoClass::GetGameInfo(QWidget* parent) {
|
|||
}
|
||||
}
|
||||
m_games = QtConcurrent::mapped(filePaths, [&](const QString& path) {
|
||||
return readGameInfo(path.toStdString());
|
||||
return readGameInfo(Common::FS::PathFromQString(path));
|
||||
}).results();
|
||||
|
||||
// Progress bar, please be patient :)
|
||||
|
|
|
@ -22,17 +22,19 @@ public:
|
|||
return a.name < b.name;
|
||||
}
|
||||
|
||||
static GameInfo readGameInfo(const std::string& filePath) {
|
||||
static GameInfo readGameInfo(const std::filesystem::path& filePath) {
|
||||
GameInfo game;
|
||||
game.path = filePath;
|
||||
|
||||
PSF psf;
|
||||
if (psf.Open(std::filesystem::path(game.path) / "sce_sys" / "param.sfo")) {
|
||||
game.icon_path = game.path + "/sce_sys/icon0.png";
|
||||
QString iconpath = QString::fromStdString(game.icon_path);
|
||||
if (psf.Open(game.path / "sce_sys" / "param.sfo")) {
|
||||
game.icon_path = game.path / "sce_sys" / "icon0.png";
|
||||
QString iconpath;
|
||||
Common::FS::PathToQString(iconpath, game.icon_path);
|
||||
game.icon = QImage(iconpath);
|
||||
game.pic_path = game.path + "/sce_sys/pic1.png";
|
||||
game.snd0_path = game.path + "/sce_sys/snd0.at9";
|
||||
game.pic_path = game.path / "sce_sys" / "pic1.png";
|
||||
game.snd0_path = game.path / "sce_sys" / "snd0.at9";
|
||||
|
||||
if (const auto title = psf.GetString("TITLE"); title.has_value()) {
|
||||
game.name = *title;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,9 @@ QWidget* GameInstallDialog::SetupGamesDirectory() {
|
|||
|
||||
// Input.
|
||||
m_gamesDirectory = new QLineEdit();
|
||||
m_gamesDirectory->setText(QString::fromStdString(Config::getGameInstallDir()));
|
||||
QString install_dir;
|
||||
Common::FS::PathToQString(install_dir, Config::getGameInstallDir());
|
||||
m_gamesDirectory->setText(install_dir);
|
||||
m_gamesDirectory->setMinimumWidth(400);
|
||||
|
||||
layout->addWidget(m_gamesDirectory);
|
||||
|
@ -76,7 +78,7 @@ void GameInstallDialog::Save() {
|
|||
return;
|
||||
}
|
||||
|
||||
Config::setGameInstallDir(gamesDirectory.toStdString());
|
||||
Config::setGameInstallDir(Common::FS::PathFromQString(gamesDirectory));
|
||||
const auto config_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir);
|
||||
Config::save(config_dir / "config.toml");
|
||||
accept();
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/path_util.h"
|
||||
#include "common/string_util.h"
|
||||
#include "game_list_frame.h"
|
||||
|
||||
GameListFrame::GameListFrame(std::shared_ptr<GameInfoClass> game_info_get, QWidget* parent)
|
||||
|
@ -73,7 +74,8 @@ void GameListFrame::PlayBackgroundMusic(QTableWidgetItem* item) {
|
|||
BackgroundMusicPlayer::getInstance().stopMusic();
|
||||
return;
|
||||
}
|
||||
const auto snd0path = QString::fromStdString(m_game_info->m_games[item->row()].snd0_path);
|
||||
QString snd0path;
|
||||
Common::FS::PathToQString(snd0path, m_game_info->m_games[item->row()].snd0_path);
|
||||
BackgroundMusicPlayer::getInstance().playMusic(snd0path);
|
||||
}
|
||||
|
||||
|
@ -88,7 +90,9 @@ void GameListFrame::PopulateGameList() {
|
|||
SetTableItem(i, 4, QString::fromStdString(m_game_info->m_games[i].fw));
|
||||
SetTableItem(i, 5, QString::fromStdString(m_game_info->m_games[i].size));
|
||||
SetTableItem(i, 6, QString::fromStdString(m_game_info->m_games[i].version));
|
||||
SetTableItem(i, 7, QString::fromStdString(m_game_info->m_games[i].path));
|
||||
QString path;
|
||||
Common::FS::PathToQString(path, m_game_info->m_games[i].path);
|
||||
SetTableItem(i, 7, path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,14 +102,12 @@ void GameListFrame::SetListBackgroundImage(QTableWidgetItem* item) {
|
|||
return;
|
||||
}
|
||||
|
||||
QString pic1Path = QString::fromStdString(m_game_info->m_games[item->row()].pic_path);
|
||||
QString pic1Path;
|
||||
Common::FS::PathToQString(pic1Path, m_game_info->m_games[item->row()].pic_path);
|
||||
const auto blurredPic1Path = Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) /
|
||||
m_game_info->m_games[item->row()].serial / "pic1.png";
|
||||
#ifdef _WIN32
|
||||
const auto blurredPic1PathQt = QString::fromStdWString(blurredPic1Path.wstring());
|
||||
#else
|
||||
const auto blurredPic1PathQt = QString::fromStdString(blurredPic1Path.string());
|
||||
#endif
|
||||
QString blurredPic1PathQt;
|
||||
Common::FS::PathToQString(blurredPic1PathQt, blurredPic1Path);
|
||||
|
||||
backgroundImage = QImage(blurredPic1PathQt);
|
||||
if (backgroundImage.isNull()) {
|
||||
|
|
|
@ -3,11 +3,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "common/path_util.h"
|
||||
|
||||
struct GameInfo {
|
||||
std::string path; // root path of game directory (normally directory that contains eboot.bin)
|
||||
std::string icon_path; // path of icon0.png
|
||||
std::string pic_path; // path of pic1.png
|
||||
std::string snd0_path; // path of snd0.at9
|
||||
std::filesystem::path path; // root path of game directory
|
||||
// (normally directory that contains eboot.bin)
|
||||
std::filesystem::path icon_path; // path of icon0.png
|
||||
std::filesystem::path pic_path; // path of pic1.png
|
||||
std::filesystem::path snd0_path; // path of snd0.at9
|
||||
QImage icon;
|
||||
std::string size;
|
||||
// variables extracted from param.sfo
|
||||
|
@ -44,7 +47,9 @@ public:
|
|||
}
|
||||
|
||||
static void GetFolderSize(GameInfo& game) {
|
||||
QDir dir(QString::fromStdString(game.path));
|
||||
QString dirPath;
|
||||
Common::FS::PathToQString(dirPath, game.path);
|
||||
QDir dir(dirPath);
|
||||
QDirIterator it(dir.absolutePath(), QDirIterator::Subdirectories);
|
||||
qint64 total = 0;
|
||||
while (it.hasNext()) {
|
||||
|
|
|
@ -75,7 +75,8 @@ public:
|
|||
}
|
||||
|
||||
if (selected == &openFolder) {
|
||||
QString folderPath = QString::fromStdString(m_games[itemID].path);
|
||||
QString folderPath;
|
||||
Common::FS::PathToQString(folderPath, m_games[itemID].path);
|
||||
QDesktopServices::openUrl(QUrl::fromLocalFile(folderPath));
|
||||
}
|
||||
|
||||
|
@ -158,7 +159,9 @@ public:
|
|||
QString gameSerial = QString::fromStdString(m_games[itemID].serial);
|
||||
QString gameVersion = QString::fromStdString(m_games[itemID].version);
|
||||
QString gameSize = QString::fromStdString(m_games[itemID].size);
|
||||
QPixmap gameImage(QString::fromStdString(m_games[itemID].icon_path));
|
||||
QString iconPath;
|
||||
Common::FS::PathToQString(iconPath, m_games[itemID].icon_path);
|
||||
QPixmap gameImage(iconPath);
|
||||
CheatsPatches* cheatsPatches =
|
||||
new CheatsPatches(gameName, gameSerial, gameVersion, gameSize, gameImage);
|
||||
cheatsPatches->show();
|
||||
|
@ -167,8 +170,9 @@ public:
|
|||
}
|
||||
|
||||
if (selected == &openTrophyViewer) {
|
||||
QString trophyPath = QString::fromStdString(m_games[itemID].serial);
|
||||
QString gameTrpPath = QString::fromStdString(m_games[itemID].path);
|
||||
QString trophyPath, gameTrpPath;
|
||||
Common::FS::PathToQString(trophyPath, m_games[itemID].serial);
|
||||
Common::FS::PathToQString(gameTrpPath, m_games[itemID].path);
|
||||
TrophyViewer* trophyViewer = new TrophyViewer(trophyPath, gameTrpPath);
|
||||
trophyViewer->show();
|
||||
connect(widget->parent(), &QWidget::destroyed, trophyViewer,
|
||||
|
@ -176,11 +180,13 @@ public:
|
|||
}
|
||||
|
||||
if (selected == &createShortcut) {
|
||||
QString targetPath = QString::fromStdString(m_games[itemID].path);
|
||||
QString targetPath;
|
||||
Common::FS::PathToQString(targetPath, m_games[itemID].path);
|
||||
QString ebootPath = targetPath + "/eboot.bin";
|
||||
|
||||
// Get the full path to the icon
|
||||
QString iconPath = QString::fromStdString(m_games[itemID].icon_path);
|
||||
QString iconPath;
|
||||
Common::FS::PathToQString(iconPath, m_games[itemID].icon_path);
|
||||
QFileInfo iconFileInfo(iconPath);
|
||||
QString icoPath = iconFileInfo.absolutePath() + "/" + iconFileInfo.baseName() + ".ico";
|
||||
|
||||
|
|
|
@ -8,10 +8,18 @@
|
|||
#include "game_install_dialog.h"
|
||||
#include "main_window.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
// Custom message handler to ignore Qt logs
|
||||
void customMessageHandler(QtMsgType, const QMessageLogContext&, const QString&) {}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
#ifdef _WIN32
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
#endif
|
||||
|
||||
QApplication a(argc, argv);
|
||||
|
||||
// Load configurations and initialize Qt application
|
||||
|
@ -22,7 +30,7 @@ int main(int argc, char* argv[]) {
|
|||
bool has_command_line_argument = argc > 1;
|
||||
|
||||
// Check if the game install directory is set
|
||||
if (Config::getGameInstallDir() == "" && !has_command_line_argument) {
|
||||
if (Config::getGameInstallDir().empty() && !has_command_line_argument) {
|
||||
GameInstallDialog dlg;
|
||||
dlg.exec();
|
||||
}
|
||||
|
|
|
@ -4,10 +4,12 @@
|
|||
#include <QDockWidget>
|
||||
#include <QProgressDialog>
|
||||
|
||||
#include <common/scm_rev.h>
|
||||
#include "about_dialog.h"
|
||||
#include "cheats_patches.h"
|
||||
#include "check_update.h"
|
||||
#include "common/io_file.h"
|
||||
#include "common/path_util.h"
|
||||
#include "common/string_util.h"
|
||||
#include "common/version.h"
|
||||
#include "core/file_format/pkg.h"
|
||||
|
@ -43,7 +45,14 @@ bool MainWindow::Init() {
|
|||
GetPhysicalDevices();
|
||||
// show ui
|
||||
setMinimumSize(350, minimumSizeHint().height());
|
||||
setWindowTitle(QString::fromStdString("shadPS4 v" + std::string(Common::VERSION)));
|
||||
std::string window_title = "";
|
||||
if (Common::isRelease) {
|
||||
window_title = fmt::format("shadPS4 v{}", Common::VERSION);
|
||||
} else {
|
||||
window_title = fmt::format("shadPS4 v{} {} {}", Common::VERSION, Common::g_scm_branch,
|
||||
Common::g_scm_desc);
|
||||
}
|
||||
setWindowTitle(QString::fromStdString(window_title));
|
||||
this->show();
|
||||
// load game list
|
||||
LoadGameLists();
|
||||
|
@ -433,12 +442,14 @@ void MainWindow::CreateConnects() {
|
|||
.arg(" APP VERSION", -11)
|
||||
.arg(" Path");
|
||||
for (const GameInfo& game : m_game_info->m_games) {
|
||||
QString game_path;
|
||||
Common::FS::PathToQString(game_path, game.path);
|
||||
out << QString("%1 %2 %3 %4 %5\n")
|
||||
.arg(QString::fromStdString(game.name), -50)
|
||||
.arg(QString::fromStdString(game.serial), -10)
|
||||
.arg(QString::fromStdString(game.fw), -4)
|
||||
.arg(QString::fromStdString(game.version), -11)
|
||||
.arg(QString::fromStdString(game.path));
|
||||
.arg(game_path);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -517,7 +528,8 @@ void MainWindow::PlayBackgroundMusic() {
|
|||
: m_game_grid_frame->crtRow * m_game_grid_frame->columnCnt +
|
||||
m_game_grid_frame->crtColumn;
|
||||
|
||||
const auto snd0path = QString::fromStdString(m_game_info->m_games[itemID].snd0_path);
|
||||
QString snd0path;
|
||||
Common::FS::PathToQString(snd0path, m_game_info->m_games[itemID].snd0_path);
|
||||
BackgroundMusicPlayer::getInstance().playMusic(snd0path);
|
||||
}
|
||||
|
||||
|
@ -529,28 +541,29 @@ void MainWindow::StartGame() {
|
|||
if (table_mode == 0) {
|
||||
if (m_game_list_frame->currentItem()) {
|
||||
int itemID = m_game_list_frame->currentItem()->row();
|
||||
gamePath = QString::fromStdString(m_game_info->m_games[itemID].path + "/eboot.bin");
|
||||
Common::FS::PathToQString(gamePath, m_game_info->m_games[itemID].path / "eboot.bin");
|
||||
}
|
||||
} else if (table_mode == 1) {
|
||||
if (m_game_grid_frame->cellClicked) {
|
||||
int itemID = (m_game_grid_frame->crtRow * m_game_grid_frame->columnCnt) +
|
||||
m_game_grid_frame->crtColumn;
|
||||
gamePath = QString::fromStdString(m_game_info->m_games[itemID].path + "/eboot.bin");
|
||||
Common::FS::PathToQString(gamePath, m_game_info->m_games[itemID].path / "eboot.bin");
|
||||
}
|
||||
} else {
|
||||
if (m_elf_viewer->currentItem()) {
|
||||
int itemID = m_elf_viewer->currentItem()->row();
|
||||
gamePath = QString::fromStdString(m_elf_viewer->m_elf_list[itemID].toStdString());
|
||||
gamePath = m_elf_viewer->m_elf_list[itemID];
|
||||
}
|
||||
}
|
||||
if (gamePath != "") {
|
||||
AddRecentFiles(gamePath);
|
||||
Core::Emulator emulator;
|
||||
if (!std::filesystem::exists(gamePath.toUtf8().constData())) {
|
||||
const auto path = Common::FS::PathFromQString(gamePath);
|
||||
if (!std::filesystem::exists(path)) {
|
||||
QMessageBox::critical(nullptr, tr("Run Game"), QString(tr("Eboot.bin file not found")));
|
||||
return;
|
||||
}
|
||||
emulator.Run(gamePath.toUtf8().constData());
|
||||
emulator.Run(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -666,9 +679,11 @@ void MainWindow::InstallDragDropPkg(std::filesystem::path file, int pkgNum, int
|
|||
pkg = PKG();
|
||||
pkg.Open(file);
|
||||
std::string failreason;
|
||||
auto extract_path = std::filesystem::path(Config::getGameInstallDir()) / pkg.GetTitleID();
|
||||
auto extract_path = Config::getGameInstallDir() / pkg.GetTitleID();
|
||||
QString pkgType = QString::fromStdString(pkg.GetPkgFlags());
|
||||
QDir game_dir(QString::fromStdString(extract_path.string()));
|
||||
QString gameDirPath;
|
||||
Common::FS::PathToQString(gameDirPath, extract_path);
|
||||
QDir game_dir(gameDirPath);
|
||||
if (game_dir.exists()) {
|
||||
QMessageBox msgBox;
|
||||
msgBox.setWindowTitle(tr("PKG Extraction"));
|
||||
|
@ -690,7 +705,9 @@ void MainWindow::InstallDragDropPkg(std::filesystem::path file, int pkgNum, int
|
|||
|
||||
auto addon_extract_path = Common::FS::GetUserPath(Common::FS::PathType::AddonsDir) /
|
||||
pkg.GetTitleID() / entitlement_label;
|
||||
QDir addon_dir(QString::fromStdString(addon_extract_path.string()));
|
||||
QString addonDirPath;
|
||||
Common::FS::PathToQString(addonDirPath, addon_extract_path);
|
||||
QDir addon_dir(addonDirPath);
|
||||
auto category = psf.GetString("CATEGORY");
|
||||
|
||||
if (pkgType.contains("PATCH")) {
|
||||
|
@ -755,8 +772,7 @@ void MainWindow::InstallDragDropPkg(std::filesystem::path file, int pkgNum, int
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
msgBox.setText(QString(tr("DLC already installed:") + "\n" +
|
||||
QString::fromStdString(addon_extract_path.string()) +
|
||||
msgBox.setText(QString(tr("DLC already installed:") + "\n" + addonDirPath +
|
||||
"\n\n" + tr("Would you like to overwrite?")));
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msgBox.setDefaultButton(QMessageBox::No);
|
||||
|
@ -768,8 +784,7 @@ void MainWindow::InstallDragDropPkg(std::filesystem::path file, int pkgNum, int
|
|||
}
|
||||
}
|
||||
} else {
|
||||
msgBox.setText(QString(tr("Game already installed") + "\n" +
|
||||
QString::fromStdString(extract_path.string()) + "\n" +
|
||||
msgBox.setText(QString(tr("Game already installed") + "\n" + addonDirPath + "\n" +
|
||||
tr("Would you like to overwrite?")));
|
||||
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
|
||||
msgBox.setDefaultButton(QMessageBox::No);
|
||||
|
@ -812,7 +827,8 @@ void MainWindow::InstallDragDropPkg(std::filesystem::path file, int pkgNum, int
|
|||
QFutureWatcher<void> futureWatcher;
|
||||
connect(&futureWatcher, &QFutureWatcher<void>::finished, this, [=, this]() {
|
||||
if (pkgNum == nPkg) {
|
||||
QString path = QString::fromStdString(Config::getGameInstallDir());
|
||||
QString path;
|
||||
Common::FS::PathToQString(path, Config::getGameInstallDir());
|
||||
QMessageBox extractMsgBox(this);
|
||||
extractMsgBox.setWindowTitle(tr("Extraction Finished"));
|
||||
extractMsgBox.setText(
|
||||
|
@ -984,14 +1000,14 @@ void MainWindow::CreateRecentGameActions() {
|
|||
}
|
||||
|
||||
connect(m_recent_files_group, &QActionGroup::triggered, this, [this](QAction* action) {
|
||||
QString gamePath = action->text();
|
||||
AddRecentFiles(gamePath); // Update the list.
|
||||
auto gamePath = Common::FS::PathFromQString(action->text());
|
||||
AddRecentFiles(action->text()); // Update the list.
|
||||
Core::Emulator emulator;
|
||||
if (!std::filesystem::exists(gamePath.toUtf8().constData())) {
|
||||
if (!std::filesystem::exists(gamePath)) {
|
||||
QMessageBox::critical(nullptr, tr("Run Game"), QString(tr("Eboot.bin file not found")));
|
||||
return;
|
||||
}
|
||||
emulator.Run(gamePath.toUtf8().constData());
|
||||
emulator.Run(gamePath);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1025,4 +1041,4 @@ void MainWindow::OnLanguageChanged(const std::string& locale) {
|
|||
Config::setEmulatorLanguage(locale);
|
||||
|
||||
LoadTranslation();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,15 +21,10 @@ TrophyViewer::TrophyViewer(QString trophyPath, QString gameTrpPath) : QMainWindo
|
|||
}
|
||||
|
||||
void TrophyViewer::PopulateTrophyWidget(QString title) {
|
||||
#ifdef _WIN32
|
||||
const auto trophyDir = Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) /
|
||||
title.toStdWString() / "TrophyFiles";
|
||||
const auto trophyDirQt = QString::fromStdWString(trophyDir.wstring());
|
||||
#else
|
||||
const auto trophyDir = Common::FS::GetUserPath(Common::FS::PathType::MetaDataDir) /
|
||||
title.toStdString() / "TrophyFiles";
|
||||
const auto trophyDirQt = QString::fromStdString(trophyDir.string());
|
||||
#endif
|
||||
Common::FS::PathFromQString(title) / "TrophyFiles";
|
||||
QString trophyDirQt;
|
||||
Common::FS::PathToQString(trophyDirQt, trophyDir);
|
||||
|
||||
QDir dir(trophyDirQt);
|
||||
if (!dir.exists()) {
|
||||
|
|
|
@ -110,11 +110,11 @@ void TriggerCapture() {
|
|||
}
|
||||
}
|
||||
|
||||
void SetOutputDir(const std::string& path, const std::string& prefix) {
|
||||
void SetOutputDir(const std::filesystem::path& path, const std::string& prefix) {
|
||||
if (!rdoc_api) {
|
||||
return;
|
||||
}
|
||||
rdoc_api->SetCaptureFilePathTemplate((path + '\\' + prefix).c_str());
|
||||
rdoc_api->SetCaptureFilePathTemplate(fmt::UTF((path / prefix).u8string()).data.data());
|
||||
}
|
||||
|
||||
} // namespace VideoCore
|
||||
|
|
|
@ -20,6 +20,6 @@ void EndCapture();
|
|||
void TriggerCapture();
|
||||
|
||||
/// Sets output directory for captures
|
||||
void SetOutputDir(const std::string& path, const std::string& prefix);
|
||||
void SetOutputDir(const std::filesystem::path& path, const std::string& prefix);
|
||||
|
||||
} // namespace VideoCore
|
||||
|
|
Loading…
Reference in a new issue