fs::get_config_dir, fs::get_executable_dir

This commit is contained in:
Nekotekina 2015-12-16 22:50:45 +03:00
parent 56ba5a765b
commit 321e6d3a86
21 changed files with 249 additions and 178 deletions

View File

@ -43,14 +43,14 @@ AutoPause::~AutoPause(void)
//This would be able to create in a GUI window. //This would be able to create in a GUI window.
void AutoPause::Reload(void) 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.clear();
m_pause_function.reserve(16); m_pause_function.reserve(16);
m_pause_syscall.clear(); m_pause_syscall.clear();
m_pause_syscall.reserve(16); 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. //System calls ID and Function calls ID are all u32 iirc.
u32 num; u32 num;
size_t fmax = list.size(); size_t fmax = list.size();

View File

@ -8,7 +8,7 @@
#define GET_API_ERROR static_cast<u64>(GetLastError()) #define GET_API_ERROR static_cast<u64>(GetLastError())
std::unique_ptr<wchar_t[]> to_wchar(const std::string& source) static std::unique_ptr<wchar_t[]> to_wchar(const std::string& source)
{ {
const auto length = source.size() + 1; // size + null terminator const auto length = source.size() + 1; // size + null terminator
@ -24,7 +24,7 @@ std::unique_ptr<wchar_t[]> to_wchar(const std::string& source)
return buffer; 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 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; 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; ULARGE_INTEGER v;
v.LowPart = ft.LowPart; v.LowPart = ft.LowPart;
v.HighPart = ft.HighPart; 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; ULARGE_INTEGER v;
v.LowPart = ft.dwLowDateTime; v.LowPart = ft.dwLowDateTime;
v.HighPart = ft.dwHighDateTime; 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 // open the file
const auto handle = CreateFileW(to_wchar(file).get(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 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 <unistd.h> #include <unistd.h>
#if defined(__APPLE__) || defined(__FreeBSD__) #if defined(__APPLE__) || defined(__FreeBSD__)
#include <copyfile.h> #include <copyfile.h>
#include <mach-o/dyld.h>
#else #else
#include <sys/sendfile.h> #include <sys/sendfile.h>
#endif #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_directory = (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
info.is_writable = (attrs.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0; info.is_writable = (attrs.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0;
info.size = (u64)attrs.nFileSizeLow | ((u64)attrs.nFileSizeHigh << 32); info.size = (u64)attrs.nFileSizeLow | ((u64)attrs.nFileSizeHigh << 32);
info.atime = to_time_t(attrs.ftLastAccessTime); info.atime = to_time(attrs.ftLastAccessTime);
info.mtime = to_time_t(attrs.ftLastWriteTime); info.mtime = to_time(attrs.ftLastWriteTime);
info.ctime = to_time_t(attrs.ftCreationTime); info.ctime = to_time(attrs.ftCreationTime);
#else #else
struct stat file_info; struct stat file_info;
if (stat(path.c_str(), &file_info) < 0) 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 #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 */ /* 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_directory = (basic_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
info.is_writable = (basic_info.FileAttributes & FILE_ATTRIBUTE_READONLY) == 0; info.is_writable = (basic_info.FileAttributes & FILE_ATTRIBUTE_READONLY) == 0;
info.size = this->size(); info.size = this->size();
info.atime = to_time_t(basic_info.LastAccessTime); info.atime = to_time(basic_info.LastAccessTime);
info.mtime = to_time_t(basic_info.ChangeTime); info.mtime = to_time(basic_info.ChangeTime);
info.ctime = to_time_t(basic_info.CreationTime); info.ctime = to_time(basic_info.CreationTime);
#else #else
struct stat file_info; struct stat file_info;
if (fstat(m_fd, &file_info) < 0) 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; g_tls_error = fse::ok;
// TODO (call ReadFile multiple times if count is too big)
const int size = count <= INT_MAX ? static_cast<int>(count) : throw EXCEPTION("Invalid count (0x%llx)", count); const int size = count <= INT_MAX ? static_cast<int>(count) : throw EXCEPTION("Invalid count (0x%llx)", count);
#ifdef _WIN32 #ifdef _WIN32
@ -584,6 +586,7 @@ u64 fs::file::write(const void* buffer, u64 count) const
{ {
g_tls_error = fse::ok; g_tls_error = fse::ok;
// TODO (call WriteFile multiple times if count is too big)
const int size = count <= INT_MAX ? static_cast<int>(count) : throw EXCEPTION("Invalid count (0x%llx)", count); const int size = count <= INT_MAX ? static_cast<int>(count) : throw EXCEPTION("Invalid count (0x%llx)", count);
#ifdef _WIN32 #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_directory = (found.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
info.is_writable = (found.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0; info.is_writable = (found.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0;
info.size = ((u64)found.nFileSizeHigh << 32) | (u64)found.nFileSizeLow; info.size = ((u64)found.nFileSizeHigh << 32) | (u64)found.nFileSizeLow;
info.atime = to_time_t(found.ftLastAccessTime); info.atime = to_time(found.ftLastAccessTime);
info.mtime = to_time_t(found.ftLastWriteTime); info.mtime = to_time(found.ftLastWriteTime);
info.ctime = to_time_t(found.ftCreationTime); info.ctime = to_time(found.ftCreationTime);
#else #else
const auto found = ::readdir((DIR*)m_dd); const auto found = ::readdir((DIR*)m_dd);
@ -793,3 +796,87 @@ bool fs::dir::read(std::string& name, stat_t& info)
return true; 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<std::size_t>(size) };
#endif
// Replace "\"
for (auto& c : dir)
{
if (c == '\\') c = '/';
}
// Leave only path
dir.resize(dir.rfind('/') + 1);
return dir;
}();
return s_dir;
}

View File

@ -149,6 +149,51 @@ namespace fs
CHECK_ASSERTION(write(str.data(), str.size()) == str.size()); CHECK_ASSERTION(write(str.data(), str.size()) == str.size());
return *this; return *this;
} }
// Write POD
template<typename T>
std::enable_if_t<std::is_pod<T>::value && !std::is_pointer<T>::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<typename T>
std::enable_if_t<std::is_pod<T>::value && !std::is_pointer<T>::value, const file&> operator <<(const std::vector<T>& 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<typename T>
std::enable_if_t<std::is_pod<T>::value && !std::is_pointer<T>::value, bool> read(T& data) const
{
return read(&data, sizeof(T)) == sizeof(T);
}
// Read POD std::vector
template<typename T>
std::enable_if_t<std::is_pod<T>::value && !std::is_pointer<T>::value, bool> read(std::vector<T>& 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 class file_ptr final
@ -245,4 +290,10 @@ namespace fs
// Get next directory entry (UTF-8 name and file stat) // Get next directory entry (UTF-8 name and file stat)
bool read(std::string& name, stat_t& info); bool read(std::string& name, stat_t& info);
}; };
// Get configuration directory
std::string get_config_dir();
// Get executable directory
std::string get_executable_dir();
} }

View File

@ -94,7 +94,7 @@ struct FileListener : LogListener
bool mPrependChannelName; bool mPrependChannelName;
FileListener(const std::string& name = _PRGNAME_, bool prependChannel = true) 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) , mPrependChannelName(prependChannel)
{ {
if (!mFile) if (!mFile)

View File

@ -163,3 +163,10 @@ std::string config_context_t::to_string() const
return result.str(); return result.str();
} }
void config_context_t::from_string(const std::string& str)
{
std::istringstream source(str);
deserialize(source);
}

View File

@ -159,4 +159,5 @@ public:
void set_defaults(); void set_defaults();
std::string to_string() const; std::string to_string() const;
void from_string(const std::string&);
}; };

View File

@ -40,29 +40,3 @@ void rImage::SaveFile(const std::string& name, rImageType type)
throw EXCEPTION("unsupported 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;
}

View File

@ -1,10 +1,5 @@
#pragma once #pragma once
struct rPlatform
{
static std::string getConfigDir();
};
/********************************************************************** /**********************************************************************
*********** RSX Debugger *********** RSX Debugger
************************************************************************/ ************************************************************************/

View File

@ -33,7 +33,7 @@ spu_recompiler::spu_recompiler()
LOG_SUCCESS(SPU, "SPU Recompiler (ASMJIT) created..."); 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) void spu_recompiler::compile(spu_function_t& f)
@ -218,7 +218,7 @@ void spu_recompiler::compile(spu_function_t& f)
log += "\n\n\n"; log += "\n\n\n";
// Append log file // 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 spu_recompiler::XmmLink spu_recompiler::XmmAlloc() // get empty xmm register

View File

@ -480,7 +480,6 @@ void VFS::Init(const std::string& path)
} }
std::string mpath = entry.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 no value assigned to SysEmulationDirPath in INI, use the path that with executable.
if (rpcs3::config.system.emulation_dir_path_enable.value()) if (rpcs3::config.system.emulation_dir_path_enable.value())
{ {
@ -488,7 +487,7 @@ void VFS::Init(const std::string& path)
} }
else else
{ {
fmt::Replace(mpath, "$(EmulatorDir)", Emu.GetEmulatorPath()); fmt::Replace(mpath, "$(EmulatorDir)", fs::get_executable_dir());
} }
fmt::Replace(mpath, "$(GameDir)", cwd); fmt::Replace(mpath, "$(GameDir)", cwd);
Mount(entry.mount, mpath, dev); Mount(entry.mount, mpath, dev);
@ -531,7 +530,7 @@ void VFS::SaveLoadDevices(std::vector<VFSManagerEntry>& res, bool is_load)
if (dir.empty()) 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)) if (!fs::is_dir(dir))

View File

@ -166,8 +166,7 @@ struct D3D12Traits
} }
} }
// TODO: This shouldn't use current dir fs::file(fs::get_config_dir() + "FragmentProgram" + std::to_string(ID) + ".hlsl", fom::rewrite) << shader;
fs::file("./FragmentProgram" + std::to_string(ID) + ".hlsl", fom::rewrite) << shader;
fragmentProgramData.id = (u32)ID; fragmentProgramData.id = (u32)ID;
} }
@ -178,8 +177,7 @@ struct D3D12Traits
std::string shaderCode = VS.Decompile(); std::string shaderCode = VS.Decompile();
vertexProgramData.Compile(shaderCode, Shader::SHADER_TYPE::SHADER_TYPE_VERTEX); vertexProgramData.Compile(shaderCode, Shader::SHADER_TYPE::SHADER_TYPE_VERTEX);
vertexProgramData.vertex_shader_inputs = VS.input_slots; vertexProgramData.vertex_shader_inputs = VS.input_slots;
// TODO: This shouldn't use current dir fs::file(fs::get_config_dir() + "VertexProgram" + std::to_string(ID) + ".hlsl", fom::rewrite) << shaderCode;
fs::file("./VertexProgram" + std::to_string(ID) + ".hlsl", fom::rewrite) << shaderCode;
vertexProgramData.id = (u32)ID; vertexProgramData.id = (u32)ID;
} }

View File

@ -466,7 +466,7 @@ void GLTexture::save(rsx::texture& tex, const std::string& name)
return; 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* data = new u8[texPixelCount * 3];
u8* alpha = new u8[texPixelCount]; 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& dir_path = "textures";
static const std::string& file_fmt = dir_path + "/" + "tex[%d].png"; 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; 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)); 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]; size_t vertex_arrays_offsets[rsx::limits::vertex_count];
#if DUMP_VERTEX_DATA #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(); Emu.Pause();
#endif #endif

View File

@ -18,8 +18,7 @@ struct GLTraits
fragmentProgramData.Compile(); fragmentProgramData.Compile();
//checkForGlError("m_fragment_prog.Compile"); //checkForGlError("m_fragment_prog.Compile");
// TODO: This shouldn't use current dir fs::file(fs::get_config_dir() + "FragmentProgram.txt", fom::rewrite) << fragmentProgramData.shader;
fs::file("./FragmentProgram.txt", fom::rewrite) << fragmentProgramData.shader;
} }
static static
@ -29,8 +28,7 @@ struct GLTraits
vertexProgramData.Compile(); vertexProgramData.Compile();
//checkForGlError("m_vertex_prog.Compile"); //checkForGlError("m_vertex_prog.Compile");
// TODO: This shouldn't use current dir fs::file(fs::get_config_dir() + "VertexProgram.txt", fom::rewrite) << vertexProgramData.shader;
fs::file("./VertexProgram.txt", fom::rewrite) << vertexProgramData.shader;
} }
static static

View File

@ -34,11 +34,32 @@
#include "Loader/ELF32.h" #include "Loader/ELF32.h"
#include "../Crypto/unself.h" #include "../Crypto/unself.h"
#include <fstream>
using namespace PPU_instr; using namespace PPU_instr;
static const std::string& BreakPointsDBName = "BreakPoints.dat"; static const std::string& BreakPointsDBName = "BreakPoints.dat";
static const u16 bpdb_version = 0x1000; static const u16 bpdb_version = 0x1000;
// Draft (not used)
struct bpdb_header_t
{
le_t<u32> magic;
le_t<u32> version;
le_t<u32> count;
le_t<u32> marked;
// POD
bpdb_header_t() = default;
bpdb_header_t(u32 count, u32 marked)
: magic(*reinterpret_cast<const u32*>("BPDB"))
, version(0x00010000)
, count(count)
, marked(marked)
{
}
};
extern std::atomic<u32> g_thread_count; extern std::atomic<u32> g_thread_count;
extern u64 get_system_time(); extern u64 get_system_time();
@ -88,7 +109,7 @@ void Emulator::SetTitle(const std::string& title)
void Emulator::CreateConfig(const std::string& name) 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"; const std::string& ini_file = path + "/settings.ini";
if (!fs::is_dir("data")) if (!fs::is_dir("data"))
@ -264,7 +285,7 @@ void Emulator::Load()
{ {
title_id = title_id.substr(0, 4) + "-" + title_id.substr(4, 5); title_id = title_id.substr(0, 4) + "-" + title_id.substr(4, 5);
CreateConfig(title_id); 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(); custom_config.load();
rpcs3::state.config = custom_config; rpcs3::state.config = custom_config;
} }
@ -300,7 +321,7 @@ void Emulator::Load()
return; return;
} }
LoadPoints(BreakPointsDBName); LoadPoints(fs::get_config_dir() + BreakPointsDBName);
GetGSManager().Init(); GetGSManager().Init();
GetCallbackManager().Init(); GetCallbackManager().Init();
@ -458,7 +479,7 @@ void Emulator::Stop()
// TODO: check finalization order // TODO: check finalization order
SavePoints(BreakPointsDBName); SavePoints(fs::get_config_dir() + BreakPointsDBName);
m_break_points.clear(); m_break_points.clear();
m_marked_points.clear(); m_marked_points.clear();
@ -482,84 +503,50 @@ void Emulator::Stop()
void Emulator::SavePoints(const std::string& path) void Emulator::SavePoints(const std::string& path)
{ {
std::ofstream f(path, std::ios::binary | std::ios::trunc); const u32 break_count = size32(m_break_points);
const u32 marked_count = size32(m_marked_points);
u32 break_count = (u32)m_break_points.size(); fs::file(path, fom::rewrite)
u32 marked_count = (u32)m_marked_points.size(); << bpdb_version
<< break_count
f.write((char*)(&bpdb_version), sizeof(bpdb_version)); << marked_count
f.write((char*)(&break_count), sizeof(break_count)); << m_break_points
f.write((char*)(&marked_count), sizeof(marked_count)); << m_marked_points;
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);
}
} }
bool Emulator::LoadPoints(const std::string& path) bool Emulator::LoadPoints(const std::string& path)
{ {
if (!fs::is_file(path)) return false; if (fs::file f{ path })
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)
{ {
LOG_ERROR(LOADER, u16 version;
"'%s' breakpoint db is broken (file is too short, length=0x%x)", u32 break_count;
path, length); u32 marked_count;
return false;
}
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) if (version != bpdb_version)
{ {
LOG_ERROR(LOADER, LOG_ERROR(LOADER, "BP file '%s' has unsupported version (version=0x%x)", path, version);
"'%s' breakpoint db version is unsupported (version=0x%x, length=0x%x)", return false;
path, version, length); }
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);
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 (break_count > 0)
{
m_break_points.resize(break_count); m_break_points.resize(break_count);
f.read((char*)(m_break_points.data()), sizeof(u64) * break_count); m_marked_points.resize(marked_count);
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;
}
return true;
} }
if (marked_count > 0) return false;
{
m_marked_points.resize(marked_count);
f.read((char*)(m_marked_points.data()), sizeof(u64) * marked_count);
}
return true;
} }
Emulator Emu; Emulator Emu;

View File

@ -102,7 +102,6 @@ class Emulator final
std::string m_path; std::string m_path;
std::string m_elf_path; std::string m_elf_path;
std::string m_emu_path;
std::string m_title_id; std::string m_title_id;
std::string m_title; std::string m_title;
@ -170,11 +169,6 @@ public:
return m_elf_path; return m_elf_path;
} }
const std::string& GetEmulatorPath() const
{
return m_emu_path;
}
const std::string& GetTitleID() const const std::string& GetTitleID() const
{ {
return m_title_id; return m_title_id;
@ -185,11 +179,6 @@ public:
return m_title; return m_title;
} }
void SetEmulatorPath(const std::string& path)
{
m_emu_path = path;
}
u64 GetPauseTime() u64 GetPauseTime()
{ {
return m_pause_amend_time; return m_pause_amend_time;

View File

@ -59,7 +59,7 @@ void AutoPauseManagerDialog::LoadEntries(void)
m_entries.clear(); m_entries.clear();
m_entries.reserve(16); m_entries.reserve(16);
fs::file list("pause.bin"); fs::file list(fs::get_config_dir() + "pause.bin");
if (list) if (list)
{ {
@ -84,7 +84,7 @@ void AutoPauseManagerDialog::LoadEntries(void)
//This would always use a 0xFFFFFFFF as end of the pause.bin //This would always use a 0xFFFFFFFF as end of the pause.bin
void AutoPauseManagerDialog::SaveEntries(void) 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. //System calls ID and Function calls ID are all u32 iirc.
u32 num = 0; u32 num = 0;
CHECK_ASSERTION(list.seek(0) != -1); CHECK_ASSERTION(list.seek(0) != -1);

View File

@ -2,7 +2,7 @@
#include "stdafx_gui.h" #include "stdafx_gui.h"
#include "Utilities/AutoPause.h" #include "Utilities/AutoPause.h"
#include "Utilities/Log.h" #include "Utilities/Log.h"
//#include "Utilities/File.h" #include "Utilities/File.h"
#include "Emu/Memory/Memory.h" #include "Emu/Memory/Memory.h"
#include "Emu/System.h" #include "Emu/System.h"
#include "Emu/FS/VFS.h" #include "Emu/FS/VFS.h"
@ -260,7 +260,7 @@ void GameViewer::ConfigureGame(wxCommandEvent& WXUNUSED(event))
if (i < 0) return; if (i < 0) return;
Emu.CreateConfig(m_game_data[i].serial); 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(); custom_config.load();
LOG_NOTICE(LOADER, "Configure: '%s'", custom_config.path().c_str()); LOG_NOTICE(LOADER, "Configure: '%s'", custom_config.path().c_str());
SettingsDialog(this, &custom_config); SettingsDialog(this, &custom_config);

View File

@ -571,7 +571,7 @@ void RSXDebugger::GetMemory()
dump += '\n'; 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++) for (u32 i = 0;i < frame_debug.draw_calls.size(); i++)
m_list_captured_draw_calls->InsertItem(i, frame_debug.draw_calls[i].name); m_list_captured_draw_calls->InsertItem(i, frame_debug.draw_calls[i].name);

View File

@ -6,6 +6,7 @@
#include "Emu/SysCalls/Modules/cellVideoOut.h" #include "Emu/SysCalls/Modules/cellVideoOut.h"
#include "SettingsDialog.h" #include "SettingsDialog.h"
#include "Utilities/Log.h" #include "Utilities/Log.h"
#include "Utilities/File.h"
#include <wx/radiobox.h> #include <wx/radiobox.h>
#ifdef _WIN32 #ifdef _WIN32
@ -212,7 +213,7 @@ SettingsDialog::SettingsDialog(wxWindow *parent, rpcs3::config_t* cfg)
//Custom EmulationDir //Custom EmulationDir
wxCheckBox* chbox_emulationdir_enable = new wxCheckBox(p_system, wxID_ANY, "Use path below as EmulationDir. (Restart required)"); 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; wxArrayString ppu_decoder_modes;

View File

@ -1,6 +1,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "config.h" #include "config.h"
#include <fstream>
#include "Utilities/File.h"
namespace rpcs3 namespace rpcs3
{ {
@ -32,23 +33,13 @@ namespace rpcs3
void config_t::load() void config_t::load()
{ {
if (!m_path.empty()) from_string(fs::file(m_path));
{
std::ifstream stream{ m_path };
if (stream)
deserialize(stream);
}
} }
void config_t::save() const void config_t::save() const
{ {
if (!m_path.empty()) fs::file(m_path, fom::rewrite) << to_string();
{
std::ofstream stream{ m_path };
if (stream)
serialize(stream);
}
} }
config_t config{ "rpcs3.new.ini" }; config_t config{ fs::get_config_dir() + "rpcs3.new.ini" };
} }

View File

@ -37,8 +37,6 @@
#include "Emu/RSX/D3D12/D3D12GSRender.h" #include "Emu/RSX/D3D12/D3D12GSRender.h"
#endif #endif
#include <wx/stdpaths.h>
#ifdef _WIN32 #ifdef _WIN32
#include <wx/msw/wrapwin.h> #include <wx/msw/wrapwin.h>
#endif #endif
@ -163,12 +161,7 @@ bool Rpcs3App::OnInit()
SetAppName(_PRGNAME_); SetAppName(_PRGNAME_);
wxInitAllImageHandlers(); 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.Init();
Emu.SetEmulatorPath(executablePath.ToStdString());
m_MainFrame = new MainFrame(); m_MainFrame = new MainFrame();
SetTopWindow(m_MainFrame); SetTopWindow(m_MainFrame);