1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2025-03-31 19:21:25 +00:00

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

@ -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();

@ -8,7 +8,7 @@
#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
@ -24,7 +24,7 @@ std::unique_ptr<wchar_t[]> 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 <unistd.h>
#if defined(__APPLE__) || defined(__FreeBSD__)
#include <copyfile.h>
#include <mach-o/dyld.h>
#else
#include <sys/sendfile.h>
#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<int>(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<int>(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<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;
}

@ -149,6 +149,51 @@ namespace fs
CHECK_ASSERTION(write(str.data(), str.size()) == str.size());
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
@ -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();
}

@ -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)

@ -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);
}

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

@ -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;
}

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

@ -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

@ -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<VFSManagerEntry>& 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))

@ -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;
}

@ -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

@ -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

@ -34,11 +34,32 @@
#include "Loader/ELF32.h"
#include "../Crypto/unself.h"
#include <fstream>
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<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 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);
const u32 break_count = size32(m_break_points);
const u32 marked_count = size32(m_marked_points);
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);
}
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);
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);
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)
{
m_marked_points.resize(marked_count);
f.read((char*)(m_marked_points.data()), sizeof(u64) * marked_count);
}
return true;
return false;
}
Emulator Emu;

@ -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 @@ public:
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 @@ public:
return m_title;
}
void SetEmulatorPath(const std::string& path)
{
m_emu_path = path;
}
u64 GetPauseTime()
{
return m_pause_amend_time;

@ -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);

@ -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);

@ -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);

@ -6,6 +6,7 @@
#include "Emu/SysCalls/Modules/cellVideoOut.h"
#include "SettingsDialog.h"
#include "Utilities/Log.h"
#include "Utilities/File.h"
#include <wx/radiobox.h>
#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;

@ -1,6 +1,7 @@
#include "stdafx.h"
#include "config.h"
#include <fstream>
#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" };
}

@ -37,8 +37,6 @@
#include "Emu/RSX/D3D12/D3D12GSRender.h"
#endif
#include <wx/stdpaths.h>
#ifdef _WIN32
#include <wx/msw/wrapwin.h>
#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);