From 321e6d3a86bbcebd16a1b2ac6c7b2d183f7ad291 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 16 Dec 2015 22:50:45 +0300 Subject: [PATCH] fs::get_config_dir, fs::get_executable_dir --- Utilities/AutoPause.cpp | 4 +- Utilities/File.cpp | 123 +++++++++++++++++---- Utilities/File.h | 51 +++++++++ Utilities/Log.cpp | 2 +- Utilities/config_context.cpp | 7 ++ Utilities/config_context.h | 1 + Utilities/rPlatform.cpp | 26 ----- Utilities/rPlatform.h | 5 - rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp | 4 +- rpcs3/Emu/FS/VFS.cpp | 5 +- rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h | 6 +- rpcs3/Emu/RSX/GL/GLGSRender.cpp | 8 +- rpcs3/Emu/RSX/GL/GLProgramBuffer.h | 6 +- rpcs3/Emu/System.cpp | 129 ++++++++++------------- rpcs3/Emu/System.h | 11 -- rpcs3/Gui/AutoPauseManager.cpp | 4 +- rpcs3/Gui/GameViewer.cpp | 4 +- rpcs3/Gui/RSXDebugger.cpp | 2 +- rpcs3/Gui/SettingsDialog.cpp | 3 +- rpcs3/config.cpp | 19 +--- rpcs3/rpcs3.cpp | 7 -- 21 files changed, 249 insertions(+), 178 deletions(-) diff --git a/Utilities/AutoPause.cpp b/Utilities/AutoPause.cpp index f5766dd556bd..35608d33005b 100644 --- a/Utilities/AutoPause.cpp +++ b/Utilities/AutoPause.cpp @@ -43,14 +43,14 @@ AutoPause::~AutoPause(void) //This would be able to create in a GUI window. void AutoPause::Reload(void) { - if (fs::is_file("pause.bin")) + if (fs::is_file(fs::get_config_dir() + "pause.bin")) { m_pause_function.clear(); m_pause_function.reserve(16); m_pause_syscall.clear(); m_pause_syscall.reserve(16); - fs::file list("pause.bin"); + fs::file list(fs::get_config_dir() + "pause.bin"); //System calls ID and Function calls ID are all u32 iirc. u32 num; size_t fmax = list.size(); diff --git a/Utilities/File.cpp b/Utilities/File.cpp index 56824b18e026..250c5b03e890 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -8,7 +8,7 @@ #define GET_API_ERROR static_cast(GetLastError()) -std::unique_ptr to_wchar(const std::string& source) +static std::unique_ptr to_wchar(const std::string& source) { const auto length = source.size() + 1; // size + null terminator @@ -24,7 +24,7 @@ std::unique_ptr to_wchar(const std::string& source) return buffer; } -void to_utf8(std::string& result, const wchar_t* source) +static void to_utf8(std::string& result, const wchar_t* source) { const int length = lstrlenW(source); // source length @@ -48,30 +48,30 @@ void to_utf8(std::string& result, const wchar_t* source) } } -time_t to_time_t(const ULARGE_INTEGER& ft) +static time_t to_time(const ULARGE_INTEGER& ft) { return ft.QuadPart / 10000000ULL - 11644473600ULL; } -time_t to_time_t(const LARGE_INTEGER& ft) +static time_t to_time(const LARGE_INTEGER& ft) { ULARGE_INTEGER v; v.LowPart = ft.LowPart; v.HighPart = ft.HighPart; - return to_time_t(v); + return to_time(v); } -time_t to_time_t(const FILETIME& ft) +static time_t to_time(const FILETIME& ft) { ULARGE_INTEGER v; v.LowPart = ft.dwLowDateTime; v.HighPart = ft.dwHighDateTime; - return to_time_t(v); + return to_time(v); } -bool truncate_file(const std::string& file, u64 length) +static bool truncate_file(const std::string& file, u64 length) { // open the file const auto handle = CreateFileW(to_wchar(file).get(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); @@ -105,6 +105,7 @@ bool truncate_file(const std::string& file, u64 length) #include #if defined(__APPLE__) || defined(__FreeBSD__) #include +#include #else #include #endif @@ -130,9 +131,9 @@ bool fs::stat(const std::string& path, stat_t& info) info.is_directory = (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; info.is_writable = (attrs.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0; info.size = (u64)attrs.nFileSizeLow | ((u64)attrs.nFileSizeHigh << 32); - info.atime = to_time_t(attrs.ftLastAccessTime); - info.mtime = to_time_t(attrs.ftLastWriteTime); - info.ctime = to_time_t(attrs.ftCreationTime); + info.atime = to_time(attrs.ftLastAccessTime); + info.mtime = to_time(attrs.ftLastWriteTime); + info.ctime = to_time(attrs.ftCreationTime); #else struct stat file_info; if (stat(path.c_str(), &file_info) < 0) @@ -306,7 +307,7 @@ bool fs::rename(const std::string& from, const std::string& to) #ifndef _WIN32 -int OSCopyFile(const char* source, const char* destination, bool overwrite) +static int OSCopyFile(const char* source, const char* destination, bool overwrite) { /* Source: http://stackoverflow.com/questions/2180079/how-can-i-copy-a-file-on-unix-using-c */ @@ -521,9 +522,9 @@ bool fs::file::stat(stat_t& info) const info.is_directory = (basic_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; info.is_writable = (basic_info.FileAttributes & FILE_ATTRIBUTE_READONLY) == 0; info.size = this->size(); - info.atime = to_time_t(basic_info.LastAccessTime); - info.mtime = to_time_t(basic_info.ChangeTime); - info.ctime = to_time_t(basic_info.CreationTime); + info.atime = to_time(basic_info.LastAccessTime); + info.mtime = to_time(basic_info.ChangeTime); + info.ctime = to_time(basic_info.CreationTime); #else struct stat file_info; if (fstat(m_fd, &file_info) < 0) @@ -565,6 +566,7 @@ u64 fs::file::read(void* buffer, u64 count) const { g_tls_error = fse::ok; + // TODO (call ReadFile multiple times if count is too big) const int size = count <= INT_MAX ? static_cast(count) : throw EXCEPTION("Invalid count (0x%llx)", count); #ifdef _WIN32 @@ -584,6 +586,7 @@ u64 fs::file::write(const void* buffer, u64 count) const { g_tls_error = fse::ok; + // TODO (call WriteFile multiple times if count is too big) const int size = count <= INT_MAX ? static_cast(count) : throw EXCEPTION("Invalid count (0x%llx)", count); #ifdef _WIN32 @@ -769,9 +772,9 @@ bool fs::dir::read(std::string& name, stat_t& info) info.is_directory = (found.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; info.is_writable = (found.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0; info.size = ((u64)found.nFileSizeHigh << 32) | (u64)found.nFileSizeLow; - info.atime = to_time_t(found.ftLastAccessTime); - info.mtime = to_time_t(found.ftLastWriteTime); - info.ctime = to_time_t(found.ftCreationTime); + info.atime = to_time(found.ftLastAccessTime); + info.mtime = to_time(found.ftLastWriteTime); + info.ctime = to_time(found.ftCreationTime); #else const auto found = ::readdir((DIR*)m_dd); @@ -793,3 +796,87 @@ bool fs::dir::read(std::string& name, stat_t& info) return true; } + +std::string fs::get_config_dir() +{ + // Use magic static for dir initialization + static const std::string s_dir = [] + { +#ifdef _WIN32 + return get_executable_dir(); // ? +#else + std::string dir; + + if (const char* home = ::getenv("XDG_CONFIG_HOME")) + dir = home; + else if (const char* home = ::getenv("HOME")) + dir = home + "/.config"s; + else // Just in case + dir = "./config"; + + dir += "/rpcs3/"; + + if (::mkdir(dir.c_str(), 0777) == -1 && errno != EEXIST) + { + std::printf("Failed to create configuration directory '%s' (%d).\n", dir.c_str(), errno); + } + + return dir; +#endif + }(); + + return s_dir; +} + +std::string fs::get_executable_dir() +{ + // Use magic static for dir initialization + static const std::string s_dir = [] + { + std::string dir; + +#ifdef _WIN32 + wchar_t buf[2048]; + if (GetModuleFileName(NULL, buf, ::size32(buf)) - 1 >= ::size32(buf) - 1) + { + MessageBoxA(0, fmt::format("GetModuleFileName() failed: 0x%x.", GetLastError()).c_str(), "fs::get_config_dir()", MB_ICONERROR); + return dir; // empty + } + + to_utf8(dir, buf); // Convert to UTF-8 + +#elif __APPLE__ + char buf[4096]; + u32 size = sizeof(buf); + if (_NSGetExecutablePath(buf, &size)) + { + std::printf("_NSGetExecutablePath() failed (size=0x%x).\n", size); + return dir; // empty + } + + dir = buf; +#else + char buf[4096]; + const auto size = ::readlink("/proc/self/exe", buf, sizeof(buf)); + if (size <= 0 || size >= sizeof(buf)) + { + std::printf("readlink(/proc/self/exe) failed (%d).\n", errno); + return dir; // empty + } + + dir = { buf, static_cast(size) }; +#endif + + // Replace "\" + for (auto& c : dir) + { + if (c == '\\') c = '/'; + } + + // Leave only path + dir.resize(dir.rfind('/') + 1); + return dir; + }(); + + return s_dir; +} diff --git a/Utilities/File.h b/Utilities/File.h index 1678f2833a29..7398baab23af 100644 --- a/Utilities/File.h +++ b/Utilities/File.h @@ -149,6 +149,51 @@ namespace fs CHECK_ASSERTION(write(str.data(), str.size()) == str.size()); return *this; } + + // Write POD + template + std::enable_if_t::value && !std::is_pointer::value, const file&> operator <<(const T& data) const + { + CHECK_ASSERTION(write(std::addressof(data), sizeof(T)) == sizeof(T)); + return *this; + } + + // Write POD std::vector + template + std::enable_if_t::value && !std::is_pointer::value, const file&> operator <<(const std::vector& vec) const + { + CHECK_ASSERTION(write(vec.data(), vec.size() * sizeof(T)) == vec.size() * sizeof(T)); + return *this; + } + + // Read std::string + bool read(std::string& str) const + { + return read(&str[0], str.size()) == str.size(); + } + + // Read POD + template + std::enable_if_t::value && !std::is_pointer::value, bool> read(T& data) const + { + return read(&data, sizeof(T)) == sizeof(T); + } + + // Read POD std::vector + template + std::enable_if_t::value && !std::is_pointer::value, bool> read(std::vector& vec) const + { + return read(vec.data(), sizeof(T) * vec.size()) == sizeof(T) * vec.size(); + } + + // Convert to std::string + operator std::string() const + { + std::string result; + result.resize(size() - seek(0, fsm::cur)); + CHECK_ASSERTION(read(result)); + return result; + } }; class file_ptr final @@ -245,4 +290,10 @@ namespace fs // Get next directory entry (UTF-8 name and file stat) bool read(std::string& name, stat_t& info); }; + + // Get configuration directory + std::string get_config_dir(); + + // Get executable directory + std::string get_executable_dir(); } diff --git a/Utilities/Log.cpp b/Utilities/Log.cpp index 6fa770f0c115..da7c723ae0bc 100644 --- a/Utilities/Log.cpp +++ b/Utilities/Log.cpp @@ -94,7 +94,7 @@ struct FileListener : LogListener bool mPrependChannelName; FileListener(const std::string& name = _PRGNAME_, bool prependChannel = true) - : mFile(rPlatform::getConfigDir() + name + ".log", fom::rewrite) + : mFile(fs::get_config_dir() + name + ".log", fom::rewrite) , mPrependChannelName(prependChannel) { if (!mFile) diff --git a/Utilities/config_context.cpp b/Utilities/config_context.cpp index 5fed6c60b205..69b953d19d84 100644 --- a/Utilities/config_context.cpp +++ b/Utilities/config_context.cpp @@ -163,3 +163,10 @@ std::string config_context_t::to_string() const return result.str(); } + +void config_context_t::from_string(const std::string& str) +{ + std::istringstream source(str); + + deserialize(source); +} diff --git a/Utilities/config_context.h b/Utilities/config_context.h index 28eb2b34b016..dd328d1766c4 100644 --- a/Utilities/config_context.h +++ b/Utilities/config_context.h @@ -159,4 +159,5 @@ class config_context_t void set_defaults(); std::string to_string() const; + void from_string(const std::string&); }; diff --git a/Utilities/rPlatform.cpp b/Utilities/rPlatform.cpp index 1b21be5b6c5e..136b939b0af8 100644 --- a/Utilities/rPlatform.cpp +++ b/Utilities/rPlatform.cpp @@ -40,29 +40,3 @@ void rImage::SaveFile(const std::string& name, rImageType type) throw EXCEPTION("unsupported type"); } } - -std::string rPlatform::getConfigDir() -{ - static std::string dir = "."; - if (dir == ".") - { -#ifdef _WIN32 - dir = ""; - //mkdir(dir.c_str()); -#else - if (getenv("XDG_CONFIG_HOME") != NULL) - dir = getenv("XDG_CONFIG_HOME"); - else if (getenv("HOME") != NULL) - dir = getenv("HOME") + std::string("/.config"); - else // Just in case - dir = "./config"; - dir = dir + "/rpcs3/"; - - if (mkdir(dir.c_str(), 0777) == -1) - { - printf("An error occured during the creation of the configuration directory. (%d)", errno); - } -#endif - } - return dir; -} diff --git a/Utilities/rPlatform.h b/Utilities/rPlatform.h index ce88b70ecc31..09308edb5357 100644 --- a/Utilities/rPlatform.h +++ b/Utilities/rPlatform.h @@ -1,10 +1,5 @@ #pragma once -struct rPlatform -{ - static std::string getConfigDir(); -}; - /********************************************************************** *********** RSX Debugger ************************************************************************/ diff --git a/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp b/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp index b2a83a7f7279..bac5cae9076f 100644 --- a/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp @@ -33,7 +33,7 @@ spu_recompiler::spu_recompiler() LOG_SUCCESS(SPU, "SPU Recompiler (ASMJIT) created..."); - fs::file("SPUJIT.log", fom::rewrite) << fmt::format("SPU JIT initialization...\n\nTitle: %s\nTitle ID: %s\n\n", Emu.GetTitle().c_str(), Emu.GetTitleID().c_str()); + fs::file(fs::get_config_dir() + "SPUJIT.log", fom::rewrite) << fmt::format("SPU JIT initialization...\n\nTitle: %s\nTitle ID: %s\n\n", Emu.GetTitle().c_str(), Emu.GetTitleID().c_str()); } void spu_recompiler::compile(spu_function_t& f) @@ -218,7 +218,7 @@ void spu_recompiler::compile(spu_function_t& f) log += "\n\n\n"; // Append log file - fs::file("SPUJIT.log", fom::write | fom::append) << log; + fs::file(fs::get_config_dir() + "SPUJIT.log", fom::write | fom::append) << log; } spu_recompiler::XmmLink spu_recompiler::XmmAlloc() // get empty xmm register diff --git a/rpcs3/Emu/FS/VFS.cpp b/rpcs3/Emu/FS/VFS.cpp index 9eea52af0e8e..ef58afac7233 100644 --- a/rpcs3/Emu/FS/VFS.cpp +++ b/rpcs3/Emu/FS/VFS.cpp @@ -480,7 +480,6 @@ void VFS::Init(const std::string& path) } std::string mpath = entry.path; - // TODO: This shouldn't use current dir // If no value assigned to SysEmulationDirPath in INI, use the path that with executable. if (rpcs3::config.system.emulation_dir_path_enable.value()) { @@ -488,7 +487,7 @@ void VFS::Init(const std::string& path) } else { - fmt::Replace(mpath, "$(EmulatorDir)", Emu.GetEmulatorPath()); + fmt::Replace(mpath, "$(EmulatorDir)", fs::get_executable_dir()); } fmt::Replace(mpath, "$(GameDir)", cwd); Mount(entry.mount, mpath, dev); @@ -531,7 +530,7 @@ void VFS::SaveLoadDevices(std::vector& res, bool is_load) if (dir.empty()) { - rpcs3::config.system.emulation_dir_path = Emu.GetEmulatorPath(); + rpcs3::config.system.emulation_dir_path = fs::get_executable_dir(); } if (!fs::is_dir(dir)) diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h index 39c566398486..b6c229382f25 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h @@ -166,8 +166,7 @@ struct D3D12Traits } } - // TODO: This shouldn't use current dir - fs::file("./FragmentProgram" + std::to_string(ID) + ".hlsl", fom::rewrite) << shader; + fs::file(fs::get_config_dir() + "FragmentProgram" + std::to_string(ID) + ".hlsl", fom::rewrite) << shader; fragmentProgramData.id = (u32)ID; } @@ -178,8 +177,7 @@ struct D3D12Traits std::string shaderCode = VS.Decompile(); vertexProgramData.Compile(shaderCode, Shader::SHADER_TYPE::SHADER_TYPE_VERTEX); vertexProgramData.vertex_shader_inputs = VS.input_slots; - // TODO: This shouldn't use current dir - fs::file("./VertexProgram" + std::to_string(ID) + ".hlsl", fom::rewrite) << shaderCode; + fs::file(fs::get_config_dir() + "VertexProgram" + std::to_string(ID) + ".hlsl", fom::rewrite) << shaderCode; vertexProgramData.id = (u32)ID; } diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index df978c95d7a7..ba10d04aa05d 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -466,7 +466,7 @@ void GLTexture::save(rsx::texture& tex, const std::string& name) return; } - fs::file(name + ".raw", fom::rewrite).write(alldata, texPixelCount * 4); + fs::file(fs::get_config_dir() + name + ".raw", fom::rewrite).write(alldata, texPixelCount * 4); u8* data = new u8[texPixelCount * 3]; u8* alpha = new u8[texPixelCount]; @@ -496,10 +496,10 @@ void GLTexture::save(rsx::texture& tex) static const std::string& dir_path = "textures"; static const std::string& file_fmt = dir_path + "/" + "tex[%d].png"; - if (!fs::exists(dir_path)) fs::create_dir(dir_path); + if (!fs::is_dir(dir_path)) fs::create_dir(dir_path); u32 count = 0; - while (fs::exists(fmt::format(file_fmt.c_str(), count))) count++; + while (fs::is_file(fmt::format(file_fmt.c_str(), count))) count++; save(tex, fmt::format(file_fmt.c_str(), count)); } @@ -886,7 +886,7 @@ void GLGSRender::end() size_t vertex_arrays_offsets[rsx::limits::vertex_count]; #if DUMP_VERTEX_DATA - fs::file dump("VertexDataArray.dump", o_create | o_write); + fs::file dump(fs::get_config_dir() + "VertexDataArray.dump", fom::rewrite); Emu.Pause(); #endif diff --git a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h index 39df0b9fd684..5ee69f5e9a5d 100644 --- a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h +++ b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h @@ -18,8 +18,7 @@ struct GLTraits fragmentProgramData.Compile(); //checkForGlError("m_fragment_prog.Compile"); - // TODO: This shouldn't use current dir - fs::file("./FragmentProgram.txt", fom::rewrite) << fragmentProgramData.shader; + fs::file(fs::get_config_dir() + "FragmentProgram.txt", fom::rewrite) << fragmentProgramData.shader; } static @@ -29,8 +28,7 @@ struct GLTraits vertexProgramData.Compile(); //checkForGlError("m_vertex_prog.Compile"); - // TODO: This shouldn't use current dir - fs::file("./VertexProgram.txt", fom::rewrite) << vertexProgramData.shader; + fs::file(fs::get_config_dir() + "VertexProgram.txt", fom::rewrite) << vertexProgramData.shader; } static diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 25d063377eb1..7dc9d0960177 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -34,11 +34,32 @@ #include "Loader/ELF32.h" #include "../Crypto/unself.h" -#include + using namespace PPU_instr; static const std::string& BreakPointsDBName = "BreakPoints.dat"; static const u16 bpdb_version = 0x1000; + +// Draft (not used) +struct bpdb_header_t +{ + le_t magic; + le_t version; + le_t count; + le_t marked; + + // POD + bpdb_header_t() = default; + + bpdb_header_t(u32 count, u32 marked) + : magic(*reinterpret_cast("BPDB")) + , version(0x00010000) + , count(count) + , marked(marked) + { + } +}; + extern std::atomic g_thread_count; extern u64 get_system_time(); @@ -88,7 +109,7 @@ void Emulator::SetTitle(const std::string& title) void Emulator::CreateConfig(const std::string& name) { - const std::string& path = "data/" + name; + const std::string& path = fs::get_config_dir() + "data/" + name; const std::string& ini_file = path + "/settings.ini"; if (!fs::is_dir("data")) @@ -264,7 +285,7 @@ void Emulator::Load() { title_id = title_id.substr(0, 4) + "-" + title_id.substr(4, 5); CreateConfig(title_id); - rpcs3::config_t custom_config { "data/" + title_id + "/settings.ini" }; + rpcs3::config_t custom_config { fs::get_config_dir() + "data/" + title_id + "/settings.ini" }; custom_config.load(); rpcs3::state.config = custom_config; } @@ -300,7 +321,7 @@ void Emulator::Load() return; } - LoadPoints(BreakPointsDBName); + LoadPoints(fs::get_config_dir() + BreakPointsDBName); GetGSManager().Init(); GetCallbackManager().Init(); @@ -458,7 +479,7 @@ void Emulator::Stop() // TODO: check finalization order - SavePoints(BreakPointsDBName); + SavePoints(fs::get_config_dir() + BreakPointsDBName); m_break_points.clear(); m_marked_points.clear(); @@ -482,84 +503,50 @@ void Emulator::Stop() void Emulator::SavePoints(const std::string& path) { - std::ofstream f(path, std::ios::binary | std::ios::trunc); - - u32 break_count = (u32)m_break_points.size(); - u32 marked_count = (u32)m_marked_points.size(); - - f.write((char*)(&bpdb_version), sizeof(bpdb_version)); - f.write((char*)(&break_count), sizeof(break_count)); - f.write((char*)(&marked_count), sizeof(marked_count)); - - if (break_count) - { - f.write((char*)(m_break_points.data()), sizeof(u64) * break_count); - } - - if (marked_count) - { - f.write((char*)(m_marked_points.data()), sizeof(u64) * marked_count); - } + const u32 break_count = size32(m_break_points); + const u32 marked_count = size32(m_marked_points); + + fs::file(path, fom::rewrite) + << bpdb_version + << break_count + << marked_count + << m_break_points + << m_marked_points; } bool Emulator::LoadPoints(const std::string& path) { - if (!fs::is_file(path)) return false; - std::ifstream f(path, std::ios::binary); - if (!f.is_open()) - return false; - f.seekg(0, std::ios::end); - u64 length = (u64)f.tellg(); - f.seekg(0, std::ios::beg); - - u16 version; - u32 break_count, marked_count; - - u64 expected_length = sizeof(bpdb_version) + sizeof(break_count) + sizeof(marked_count); - - if (length < expected_length) + if (fs::file f{ path }) { - LOG_ERROR(LOADER, - "'%s' breakpoint db is broken (file is too short, length=0x%x)", - path, length); - return false; - } + u16 version; + u32 break_count; + u32 marked_count; - f.read((char*)(&version), sizeof(version)); + if (!f.read(version) || !f.read(break_count) || !f.read(marked_count)) + { + LOG_ERROR(LOADER, "BP file '%s' is broken (length=0x%llx)", path, f.size()); + return false; + } - if (version != bpdb_version) - { - LOG_ERROR(LOADER, - "'%s' breakpoint db version is unsupported (version=0x%x, length=0x%x)", - path, version, length); - return false; - } + if (version != bpdb_version) + { + LOG_ERROR(LOADER, "BP file '%s' has unsupported version (version=0x%x)", path, version); + return false; + } - f.read((char*)(&break_count), sizeof(break_count)); - f.read((char*)(&marked_count), sizeof(marked_count)); - expected_length += break_count * sizeof(u64) + marked_count * sizeof(u64); + m_break_points.resize(break_count); + m_marked_points.resize(marked_count); - if (expected_length != length) - { - LOG_ERROR(LOADER, - "'%s' breakpoint db format is incorrect " - "(version=0x%x, break_count=0x%x, marked_count=0x%x, length=0x%x)", - path, version, break_count, marked_count, length); - return false; - } + if (!f.read(m_break_points) || !f.read(m_marked_points)) + { + LOG_ERROR(LOADER, "'BP file %s' is broken (length=0x%llx, break_count=%u, marked_count=%u)", path, f.size(), break_count, marked_count); + return false; + } - if (break_count > 0) - { - m_break_points.resize(break_count); - f.read((char*)(m_break_points.data()), sizeof(u64) * break_count); + return true; } - if (marked_count > 0) - { - m_marked_points.resize(marked_count); - f.read((char*)(m_marked_points.data()), sizeof(u64) * marked_count); - } - return true; + return false; } Emulator Emu; diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index db5a1784bda1..ba95ccd5da94 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -102,7 +102,6 @@ class Emulator final std::string m_path; std::string m_elf_path; - std::string m_emu_path; std::string m_title_id; std::string m_title; @@ -170,11 +169,6 @@ class Emulator final return m_elf_path; } - const std::string& GetEmulatorPath() const - { - return m_emu_path; - } - const std::string& GetTitleID() const { return m_title_id; @@ -185,11 +179,6 @@ class Emulator final return m_title; } - void SetEmulatorPath(const std::string& path) - { - m_emu_path = path; - } - u64 GetPauseTime() { return m_pause_amend_time; diff --git a/rpcs3/Gui/AutoPauseManager.cpp b/rpcs3/Gui/AutoPauseManager.cpp index 0f20a6beec5c..091f272f123f 100644 --- a/rpcs3/Gui/AutoPauseManager.cpp +++ b/rpcs3/Gui/AutoPauseManager.cpp @@ -59,7 +59,7 @@ void AutoPauseManagerDialog::LoadEntries(void) m_entries.clear(); m_entries.reserve(16); - fs::file list("pause.bin"); + fs::file list(fs::get_config_dir() + "pause.bin"); if (list) { @@ -84,7 +84,7 @@ void AutoPauseManagerDialog::LoadEntries(void) //This would always use a 0xFFFFFFFF as end of the pause.bin void AutoPauseManagerDialog::SaveEntries(void) { - fs::file list("pause.bin", fom::rewrite); + fs::file list(fs::get_config_dir() + "pause.bin", fom::rewrite); //System calls ID and Function calls ID are all u32 iirc. u32 num = 0; CHECK_ASSERTION(list.seek(0) != -1); diff --git a/rpcs3/Gui/GameViewer.cpp b/rpcs3/Gui/GameViewer.cpp index 30101ab31b90..d13837a05607 100644 --- a/rpcs3/Gui/GameViewer.cpp +++ b/rpcs3/Gui/GameViewer.cpp @@ -2,7 +2,7 @@ #include "stdafx_gui.h" #include "Utilities/AutoPause.h" #include "Utilities/Log.h" -//#include "Utilities/File.h" +#include "Utilities/File.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/FS/VFS.h" @@ -260,7 +260,7 @@ void GameViewer::ConfigureGame(wxCommandEvent& WXUNUSED(event)) if (i < 0) return; Emu.CreateConfig(m_game_data[i].serial); - rpcs3::config_t custom_config { "data/" + m_game_data[i].serial + "/settings.ini" }; + rpcs3::config_t custom_config { fs::get_config_dir() + "data/" + m_game_data[i].serial + "/settings.ini" }; custom_config.load(); LOG_NOTICE(LOADER, "Configure: '%s'", custom_config.path().c_str()); SettingsDialog(this, &custom_config); diff --git a/rpcs3/Gui/RSXDebugger.cpp b/rpcs3/Gui/RSXDebugger.cpp index 622ba4eabc85..25a63c210ec4 100644 --- a/rpcs3/Gui/RSXDebugger.cpp +++ b/rpcs3/Gui/RSXDebugger.cpp @@ -571,7 +571,7 @@ void RSXDebugger::GetMemory() dump += '\n'; } - fs::file("command_dump.log", fom::rewrite) << dump; + fs::file(fs::get_config_dir() + "command_dump.log", fom::rewrite) << dump; for (u32 i = 0;i < frame_debug.draw_calls.size(); i++) m_list_captured_draw_calls->InsertItem(i, frame_debug.draw_calls[i].name); diff --git a/rpcs3/Gui/SettingsDialog.cpp b/rpcs3/Gui/SettingsDialog.cpp index 99ee6783a79f..1465a90c41d4 100644 --- a/rpcs3/Gui/SettingsDialog.cpp +++ b/rpcs3/Gui/SettingsDialog.cpp @@ -6,6 +6,7 @@ #include "Emu/SysCalls/Modules/cellVideoOut.h" #include "SettingsDialog.h" #include "Utilities/Log.h" +#include "Utilities/File.h" #include #ifdef _WIN32 @@ -212,7 +213,7 @@ SettingsDialog::SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg) //Custom EmulationDir wxCheckBox* chbox_emulationdir_enable = new wxCheckBox(p_system, wxID_ANY, "Use path below as EmulationDir. (Restart required)"); - wxTextCtrl* txt_emulationdir_path = new wxTextCtrl(p_system, wxID_ANY, Emu.GetEmulatorPath()); + wxTextCtrl* txt_emulationdir_path = new wxTextCtrl(p_system, wxID_ANY, fs::get_executable_dir()); wxArrayString ppu_decoder_modes; diff --git a/rpcs3/config.cpp b/rpcs3/config.cpp index 83307285a94d..62488558ebed 100644 --- a/rpcs3/config.cpp +++ b/rpcs3/config.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "config.h" -#include + +#include "Utilities/File.h" namespace rpcs3 { @@ -32,23 +33,13 @@ namespace rpcs3 void config_t::load() { - if (!m_path.empty()) - { - std::ifstream stream{ m_path }; - if (stream) - deserialize(stream); - } + from_string(fs::file(m_path)); } void config_t::save() const { - if (!m_path.empty()) - { - std::ofstream stream{ m_path }; - if (stream) - serialize(stream); - } + fs::file(m_path, fom::rewrite) << to_string(); } - config_t config{ "rpcs3.new.ini" }; + config_t config{ fs::get_config_dir() + "rpcs3.new.ini" }; } diff --git a/rpcs3/rpcs3.cpp b/rpcs3/rpcs3.cpp index 16133097eb77..10f2a54dff7f 100644 --- a/rpcs3/rpcs3.cpp +++ b/rpcs3/rpcs3.cpp @@ -37,8 +37,6 @@ #include "Emu/RSX/D3D12/D3D12GSRender.h" #endif -#include - #ifdef _WIN32 #include #endif @@ -163,12 +161,7 @@ bool Rpcs3App::OnInit() SetAppName(_PRGNAME_); wxInitAllImageHandlers(); - // RPCS3 assumes the current working directory is the folder where it is contained, so we make sure this is true - const wxString executablePath = wxPathOnly(wxStandardPaths::Get().GetExecutablePath()); - wxSetWorkingDirectory(executablePath); - Emu.Init(); - Emu.SetEmulatorPath(executablePath.ToStdString()); m_MainFrame = new MainFrame(); SetTopWindow(m_MainFrame);