mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-10 06:44:34 +00:00
fs::get_config_dir, fs::get_executable_dir
This commit is contained in:
parent
56ba5a765b
commit
321e6d3a86
@ -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();
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
}
|
||||||
|
@ -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&);
|
||||||
};
|
};
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
struct rPlatform
|
|
||||||
{
|
|
||||||
static std::string getConfigDir();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
*********** RSX Debugger
|
*********** RSX Debugger
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
@ -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
|
||||||
|
@ -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))
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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" };
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user