From b3e3c68f15335cda4a7e4173abaf9c3df396c37e Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 6 Jan 2016 02:52:48 +0300 Subject: [PATCH] File utility improved + minor fixes --- Utilities/File.cpp | 806 ++++++++++++-------- Utilities/File.h | 160 ++-- Utilities/Log.cpp | 24 +- Utilities/Thread.cpp | 58 +- Utilities/convert.h | 6 +- Utilities/rPlatform.cpp | 1 - rpcs3.sln | 8 - rpcs3/CMakeLists.txt | 1 + rpcs3/Crypto/unpkg.cpp | 2 +- rpcs3/Crypto/unself.cpp | 2 + rpcs3/D3D12GSRender.vcxproj | 61 +- rpcs3/Emu/Audio/AudioManager.cpp | 16 +- rpcs3/Emu/Audio/AudioManager.h | 20 +- rpcs3/Emu/Audio/XAudio2/XAudio2Thread.h | 4 +- rpcs3/Emu/Cell/PPUThread.h | 4 +- rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp | 4 +- rpcs3/Emu/FS/vfsFile.cpp | 8 +- rpcs3/Emu/FS/vfsFile.h | 4 +- rpcs3/Emu/FS/vfsFileBase.cpp | 5 +- rpcs3/Emu/FS/vfsFileBase.h | 2 +- rpcs3/Emu/FS/vfsLocalDir.cpp | 2 +- rpcs3/Emu/FS/vfsLocalFile.cpp | 11 +- rpcs3/Emu/FS/vfsLocalFile.h | 4 +- rpcs3/Emu/FS/vfsStream.h | 5 +- rpcs3/Emu/FS/vfsStreamMemory.h | 12 +- rpcs3/Emu/HDD/HDD.cpp | 14 +- rpcs3/Emu/HDD/HDD.h | 2 +- rpcs3/Emu/Memory/vm.cpp | 6 +- rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h | 4 +- rpcs3/Emu/RSX/GCM.h | 2 +- rpcs3/Emu/RSX/GL/GLProgramBuffer.h | 4 +- rpcs3/Emu/RSX/RSXThread.cpp | 4 +- rpcs3/Emu/SysCalls/Modules/cellFs.cpp | 18 +- rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp | 1 - rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp | 2 +- rpcs3/Emu/SysCalls/Modules/sys_net.cpp | 2 + rpcs3/Emu/SysCalls/lv2/sys_fs.cpp | 2 +- rpcs3/Emu/System.cpp | 88 +-- rpcs3/Emu/events.cpp | 2 +- rpcs3/Emu/state.h | 1 + rpcs3/GLGSRender.vcxproj | 49 -- rpcs3/Gui/CgDisasm.h | 4 +- rpcs3/Gui/ConLogFrame.cpp | 5 +- rpcs3/Gui/ConLogFrame.h | 3 +- rpcs3/Gui/Debugger.cpp | 1 - rpcs3/Gui/GLGSFrame.cpp | 2 +- rpcs3/Gui/GameViewer.cpp | 1 - rpcs3/Gui/GameViewer.h | 4 +- rpcs3/Gui/KernelExplorer.h | 2 - rpcs3/Gui/LLEModulesManager.h | 2 +- rpcs3/Gui/MainFrame.cpp | 8 +- rpcs3/Gui/MainFrame.h | 2 - rpcs3/Gui/MemoryStringSearcher.cpp | 2 - rpcs3/Gui/MemoryStringSearcher.h | 1 - rpcs3/Gui/MemoryViewer.h | 2 - rpcs3/Gui/RSXDebugger.cpp | 4 +- rpcs3/Gui/RSXDebugger.h | 2 - rpcs3/Gui/SettingsDialog.cpp | 1 - rpcs3/Gui/VHDDManager.cpp | 1 - rpcs3/Gui/VHDDManager.h | 2 +- rpcs3/Loader/TROPUSR.cpp | 8 +- rpcs3/Loader/TROPUSR.h | 2 +- rpcs3/Loader/TRP.cpp | 4 +- rpcs3/Loader/TRP.h | 2 +- rpcs3/OpenAL.vcxproj | 47 +- rpcs3/XAudio.vcxproj | 46 +- rpcs3/XAudio.vcxproj.filters | 6 +- rpcs3/config.cpp | 4 +- rpcs3/emucore.vcxproj | 75 +- rpcs3/emucore.vcxproj.filters | 9 + rpcs3/rpcs3.vcxproj | 45 +- rpcs3/stb_image.cpp | 9 + rpcs3/stdafx.h | 39 +- rpcs3/stdafx_gui.h | 18 + rpcs3_default.props | 9 +- 75 files changed, 839 insertions(+), 964 deletions(-) create mode 100644 rpcs3/stb_image.cpp diff --git a/Utilities/File.cpp b/Utilities/File.cpp index 1c0d19b2ee..e9cbc3a8af 100644 --- a/Utilities/File.cpp +++ b/Utilities/File.cpp @@ -1,25 +1,24 @@ #include "stdafx.h" -#include "Log.h" #include "File.h" #ifdef _WIN32 + +#include +#undef _WIN32_WINNT #define _WIN32_WINNT 0x0601 #include -#include - -#define GET_API_ERROR static_cast(GetLastError()) static std::unique_ptr to_wchar(const std::string& source) { - const auto length = source.size() + 1; // size + null terminator + const auto buf_size = source.size() + 1; // size + null terminator - const int size = source.size() < INT_MAX ? static_cast(length) : throw EXCEPTION("Invalid source length (0x%llx)", source.size()); + const int size = source.size() < INT_MAX ? static_cast(buf_size) : throw EXCEPTION("Invalid source length (0x%llx)", source.size()); - std::unique_ptr buffer(new wchar_t[length]); // allocate buffer assuming that length is the max possible size + std::unique_ptr buffer(new wchar_t[buf_size]); // allocate buffer assuming that length is the max possible size if (!MultiByteToWideChar(CP_UTF8, 0, source.c_str(), size, buffer.get(), size)) { - throw EXCEPTION("System error 0x%x", GetLastError()); + throw EXCEPTION("MultiByteToWideChar() failed (0x%x).", GetLastError()); } return buffer; @@ -27,25 +26,19 @@ static std::unique_ptr to_wchar(const std::string& source) static void to_utf8(std::string& result, const wchar_t* source) { - const int length = lstrlenW(source); // source length + const auto length = std::wcslen(source); - if (length == 0) + const int buf_size = length <= INT_MAX / 3 ? static_cast(length) * 3 + 1 : throw EXCEPTION("Invalid source length (0x%llx)", length); + + result.resize(buf_size); // set max possible length for utf-8 + null terminator + + if (const int nwritten = WideCharToMultiByte(CP_UTF8, 0, source, static_cast(length) + 1, &result.front(), buf_size, NULL, NULL)) { - return result.clear(); + result.resize(nwritten - 1); // fix the size, remove null terminator } - - const int size = WideCharToMultiByte(CP_UTF8, 0, source, length, NULL, 0, NULL, NULL); // output size - - if (size <= 0) + else { - throw EXCEPTION("System error 0x%x", GetLastError()); - } - - result.resize(size); - - if (!WideCharToMultiByte(CP_UTF8, 0, source, length, &result.front(), size, NULL, NULL)) - { - throw EXCEPTION("System error 0x%x", GetLastError()); + throw EXCEPTION("WideCharToMultiByte() failed (0x%x).", GetLastError()); } } @@ -72,32 +65,8 @@ static time_t to_time(const FILETIME& ft) return to_time(v); } -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); - - if (handle == INVALID_HANDLE_VALUE) - { - return false; - } - - LARGE_INTEGER distance; - distance.QuadPart = length; - - // seek and truncate - if (!SetFilePointerEx(handle, distance, NULL, FILE_BEGIN) || !SetEndOfFile(handle)) - { - const auto error = GetLastError(); - CloseHandle(handle); - SetLastError(error); - return false; - } - - return CloseHandle(handle); -} - #else + #include #include #include @@ -106,28 +75,81 @@ static bool truncate_file(const std::string& file, u64 length) #include #include #include + #if defined(__APPLE__) || defined(__FreeBSD__) #include #include #else #include #endif -#include - -#define GET_API_ERROR static_cast(errno) #endif -thread_local fse fs::g_tls_error = fse::ok; +std::string fs::get_parent_dir(const std::string& path) +{ + // Search upper bound (set to the last character, npos for empty string) + auto last = path.size() - 1; + +#ifdef _WIN32 + const auto& delim = "/\\"; +#else + const auto& delim = "/"; +#endif + + while (true) + { + const auto pos = path.find_last_of(delim, last, sizeof(delim) - 1); + + // Contiguous slashes are ignored at the end + if (std::exchange(last, pos - 1) != pos) + { + // Return empty string if the path doesn't contain at least 2 elements + return path.substr(0, pos != -1 && path.find_last_not_of(delim, pos, sizeof(delim) - 1) != -1 ? pos : 0); + } + } +} + +static const auto test_get_parent_dir = []() -> bool +{ + // Success: + CHECK_ASSERTION(fs::get_parent_dir("/x/y///") == "/x"); + CHECK_ASSERTION(fs::get_parent_dir("/x/y/") == "/x"); + CHECK_ASSERTION(fs::get_parent_dir("/x/y") == "/x"); + CHECK_ASSERTION(fs::get_parent_dir("x:/y") == "x:"); + CHECK_ASSERTION(fs::get_parent_dir("//x/y") == "//x"); + + // Failure: + CHECK_ASSERTION(fs::get_parent_dir("").empty()); + CHECK_ASSERTION(fs::get_parent_dir("x/").empty()); + CHECK_ASSERTION(fs::get_parent_dir("x").empty()); + CHECK_ASSERTION(fs::get_parent_dir("x///").empty()); + CHECK_ASSERTION(fs::get_parent_dir("/x/").empty()); + CHECK_ASSERTION(fs::get_parent_dir("/x").empty()); + CHECK_ASSERTION(fs::get_parent_dir("/").empty()); + CHECK_ASSERTION(fs::get_parent_dir("//").empty()); + CHECK_ASSERTION(fs::get_parent_dir("//x").empty()); + CHECK_ASSERTION(fs::get_parent_dir("//x/").empty()); + CHECK_ASSERTION(fs::get_parent_dir("///").empty()); + CHECK_ASSERTION(fs::get_parent_dir("///x").empty()); + CHECK_ASSERTION(fs::get_parent_dir("///x/").empty()); + + return false; +}(); bool fs::stat(const std::string& path, stat_t& info) { - g_tls_error = fse::ok; - #ifdef _WIN32 WIN32_FILE_ATTRIBUTE_DATA attrs; if (!GetFileAttributesExW(to_wchar(path).get(), GetFileExInfoStandard, &attrs)) { + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_FILE_NOT_FOUND: errno = ENOENT; break; + case ERROR_PATH_NOT_FOUND: errno = ENOENT; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x (%s).", error, path); + } + return false; } @@ -138,8 +160,8 @@ bool fs::stat(const std::string& path, stat_t& info) 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) + struct ::stat file_info; + if (::stat(path.c_str(), &file_info) != 0) { return false; } @@ -157,223 +179,300 @@ bool fs::stat(const std::string& path, stat_t& info) bool fs::exists(const std::string& path) { - g_tls_error = fse::ok; - #ifdef _WIN32 - return GetFileAttributesW(to_wchar(path).get()) != 0xFFFFFFFF; -#else - struct stat buffer; - return stat(path.c_str(), &buffer) == 0; -#endif -} - -bool fs::is_file(const std::string& file) -{ - g_tls_error = fse::ok; - -#ifdef _WIN32 - DWORD attrs; - if ((attrs = GetFileAttributesW(to_wchar(file).get())) == INVALID_FILE_ATTRIBUTES) + if (GetFileAttributesW(to_wchar(path).get()) == INVALID_FILE_ATTRIBUTES) { - return false; - } + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_FILE_NOT_FOUND: errno = ENOENT; break; + case ERROR_PATH_NOT_FOUND: errno = ENOENT; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x (%s).", error, path); + } - return (attrs & FILE_ATTRIBUTE_DIRECTORY) == 0; -#else - struct stat file_info; - if (stat(file.c_str(), &file_info) < 0) - { - return false; - } - - return !S_ISDIR(file_info.st_mode); -#endif -} - -bool fs::is_dir(const std::string& dir) -{ - g_tls_error = fse::ok; - -#ifdef _WIN32 - DWORD attrs; - if ((attrs = GetFileAttributesW(to_wchar(dir).get())) == INVALID_FILE_ATTRIBUTES) - { - return false; - } - - return (attrs & FILE_ATTRIBUTE_DIRECTORY) != 0; -#else - struct stat file_info; - if (stat(dir.c_str(), &file_info) < 0) - { - return false; - } - - return S_ISDIR(file_info.st_mode); -#endif -} - -bool fs::create_dir(const std::string& dir) -{ - g_tls_error = fse::ok; - -#ifdef _WIN32 - if (!CreateDirectoryW(to_wchar(dir).get(), NULL)) -#else - if (mkdir(dir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH)) -#endif - { - LOG_WARNING(GENERAL, "Error creating directory '%s': 0x%llx", dir, GET_API_ERROR); return false; } return true; +#else + struct ::stat file_info; + return !::stat(path.c_str(), &file_info); +#endif +} + +bool fs::is_file(const std::string& path) +{ +#ifdef _WIN32 + const DWORD attrs = GetFileAttributesW(to_wchar(path).get()); + if (attrs == INVALID_FILE_ATTRIBUTES) + { + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_FILE_NOT_FOUND: errno = ENOENT; break; + case ERROR_PATH_NOT_FOUND: errno = ENOENT; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x (%s).", error, path); + } + + return false; + } +#else + struct ::stat file_info; + if (::stat(path.c_str(), &file_info) != 0) + { + return false; + } +#endif + + // TODO: correct file type check +#ifdef _WIN32 + if ((attrs & FILE_ATTRIBUTE_DIRECTORY) != 0) +#else + if (S_ISDIR(file_info.st_mode)) +#endif + { + errno = EEXIST; + return false; + } + + return true; +} + +bool fs::is_dir(const std::string& path) +{ +#ifdef _WIN32 + const DWORD attrs = GetFileAttributesW(to_wchar(path).get()); + if (attrs == INVALID_FILE_ATTRIBUTES) + { + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_FILE_NOT_FOUND: errno = ENOENT; break; + case ERROR_PATH_NOT_FOUND: errno = ENOENT; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x (%s).", error, path); + } + + return false; + } +#else + struct ::stat file_info; + if (::stat(path.c_str(), &file_info) != 0) + { + return false; + } +#endif + +#ifdef _WIN32 + if ((attrs & FILE_ATTRIBUTE_DIRECTORY) == 0) +#else + if (!S_ISDIR(file_info.st_mode)) +#endif + { + errno = EEXIST; + return false; + } + + return true; +} + +bool fs::create_dir(const std::string& path) +{ +#ifdef _WIN32 + if (!CreateDirectoryW(to_wchar(path).get(), NULL)) + { + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_ALREADY_EXISTS: errno = EEXIST; break; + case ERROR_PATH_NOT_FOUND: errno = ENOENT; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x (%s).", error, path); + } + + return false; + } + + return true; +#else + return !::mkdir(path.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); +#endif } bool fs::create_path(const std::string& path) { - g_tls_error = fse::ok; + const auto& parent = get_parent_dir(path); - std::string parent; + if (!parent.empty() && !is_dir(parent) && !create_path(parent)) { -#ifdef _WIN32 - auto copy = to_wchar(path); - // PathRemoveFileSpecW only works on paths delimited by '\\' - std::replace(copy.get(), copy.get() + path.length(), '/', '\\'); - PathRemoveFileSpecW(copy.get()); - to_utf8(parent, copy.get()); -#else - std::unique_ptr copy{ strdup(path.c_str()), std::free }; - parent = dirname(copy.get()); -#endif - } - - if (!is_dir(parent) && !create_path(parent)) return false; + } return create_dir(path); } -bool fs::remove_dir(const std::string& dir) +bool fs::remove_dir(const std::string& path) { - g_tls_error = fse::ok; - #ifdef _WIN32 - if (!RemoveDirectoryW(to_wchar(dir).get())) -#else - if (rmdir(dir.c_str())) -#endif + if (!RemoveDirectoryW(to_wchar(path).get())) { - LOG_WARNING(GENERAL, "Error deleting directory '%s': 0x%llx", dir, GET_API_ERROR); + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_PATH_NOT_FOUND: errno = ENOENT; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x (%s).", error, path); + } + return false; } return true; +#else + return !::rmdir(path.c_str()); +#endif } bool fs::rename(const std::string& from, const std::string& to) { - g_tls_error = fse::ok; - #ifdef _WIN32 if (!MoveFileW(to_wchar(from).get(), to_wchar(to).get())) -#else - if (rename(from.c_str(), to.c_str())) -#endif { - LOG_WARNING(GENERAL, "Error renaming '%s' to '%s': 0x%llx", from, to, GET_API_ERROR); + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_PATH_NOT_FOUND: errno = ENOENT; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x.\nFrom: %s\nTo: %s", error, from, to); + } + return false; } return true; -} - -#ifndef _WIN32 - -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 */ - - const int input = open(source, O_RDONLY); - if (input == -1) - { - return -1; - } - - const int output = open(destination, O_WRONLY | O_CREAT | (overwrite ? O_TRUNC : O_EXCL), 0666); - if (output == -1) - { - close(input); - return -1; - } - - //Here we use kernel-space copying for performance reasons -#if defined(__APPLE__) || defined(__FreeBSD__) - //fcopyfile works on FreeBSD and OS X 10.5+ - const int result = fcopyfile(input, output, 0, COPYFILE_ALL); #else - //sendfile will work with non-socket output (i.e. regular file) on Linux 2.6.33+ - off_t bytesCopied = 0; - struct stat fileinfo = { 0 }; - const int result = fstat(input, &fileinfo) == -1 || sendfile(output, input, &bytesCopied, fileinfo.st_size) == -1 ? -1 : 0; + return !::rename(from.c_str(), to.c_str()); #endif - - close(input); - close(output); - - return result; } -#endif bool fs::copy_file(const std::string& from, const std::string& to, bool overwrite) { - g_tls_error = fse::ok; - #ifdef _WIN32 if (!CopyFileW(to_wchar(from).get(), to_wchar(to).get(), !overwrite)) -#else - if (OSCopyFile(from.c_str(), to.c_str(), overwrite)) -#endif { - LOG_WARNING(GENERAL, "Error copying '%s' to '%s': 0x%llx", from, to, GET_API_ERROR); + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_PATH_NOT_FOUND: errno = ENOENT; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x.\nFrom: %s\nTo: %s", error, from, to); + } + return false; } return true; +#else + /* Source: http://stackoverflow.com/questions/2180079/how-can-i-copy-a-file-on-unix-using-c */ + + const int input = ::open(from.c_str(), O_RDONLY); + if (input == -1) + { + return false; + } + + const int output = ::open(to.c_str(), O_WRONLY | O_CREAT | (overwrite ? O_TRUNC : O_EXCL), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if (output == -1) + { + const int err = errno; + + ::close(input); + errno = err; + return false; + } + + // Here we use kernel-space copying for performance reasons +#if defined(__APPLE__) || defined(__FreeBSD__) + // fcopyfile works on FreeBSD and OS X 10.5+ + if (::fcopyfile(input, output, 0, COPYFILE_ALL)) +#else + // sendfile will work with non-socket output (i.e. regular file) on Linux 2.6.33+ + off_t bytes_copied = 0; + struct ::stat fileinfo = { 0 }; + if (::fstat(input, &fileinfo) || ::sendfile(output, input, &bytes_copied, fileinfo.st_size)) +#endif + { + const int err = errno; + + ::close(input); + ::close(output); + errno = err; + return false; + } + + ::close(input); + ::close(output); + return true; +#endif } -bool fs::remove_file(const std::string& file) +bool fs::remove_file(const std::string& path) { - g_tls_error = fse::ok; - #ifdef _WIN32 - if (!DeleteFileW(to_wchar(file).get())) -#else - if (unlink(file.c_str())) -#endif + if (!DeleteFileW(to_wchar(path).get())) { - LOG_WARNING(GENERAL, "Error deleting file '%s': 0x%llx", file, GET_API_ERROR); + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_FILE_NOT_FOUND: errno = ENOENT; break; + case ERROR_PATH_NOT_FOUND: errno = ENOENT; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x (%s).", error, path); + } + return false; } return true; +#else + return !::unlink(path.c_str()); +#endif } -bool fs::truncate_file(const std::string& file, u64 length) +bool fs::truncate_file(const std::string& path, u64 length) { - g_tls_error = fse::ok; - #ifdef _WIN32 - if (!::truncate_file(file, length)) -#else - if (::truncate(file.c_str(), length)) -#endif + // Open the file + const auto handle = CreateFileW(to_wchar(path).get(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (handle == INVALID_HANDLE_VALUE) { - LOG_WARNING(GENERAL, "Error resizing file '%s' to 0x%llx: 0x%llx", file, length, GET_API_ERROR); + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_FILE_NOT_FOUND: errno = ENOENT; break; + case ERROR_PATH_NOT_FOUND: errno = ENOENT; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x (%s).", error, path); + } + return false; } + LARGE_INTEGER distance; + distance.QuadPart = length; + + // Seek and truncate + if (!SetFilePointerEx(handle, distance, NULL, FILE_BEGIN) || !SetEndOfFile(handle)) + { + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_NEGATIVE_SEEK: errno = EINVAL; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x (length=0x%llx).", error, length); + } + + CloseHandle(handle); + return false; + } + + CloseHandle(handle); return true; +#else + return !::truncate(path.c_str(), length); +#endif } fs::file::~file() @@ -388,12 +487,10 @@ fs::file::~file() } } -bool fs::file::open(const std::string& filename, u32 mode) +bool fs::file::open(const std::string& path, u32 mode) { this->close(); - g_tls_error = fse::ok; - #ifdef _WIN32 DWORD access = 0; switch (mode & (fom::read | fom::write | fom::append)) @@ -404,11 +501,6 @@ bool fs::file::open(const std::string& filename, u32 mode) case fom::write | fom::append: access |= FILE_APPEND_DATA; break; case fom::read | fom::write: access |= GENERIC_READ | GENERIC_WRITE; break; case fom::read | fom::write | fom::append: access |= GENERIC_READ | FILE_APPEND_DATA; break; - default: - { - LOG_ERROR(GENERAL, "fs::file::open('%s') failed: neither fom::read nor fom::write specified (0x%x)", filename, mode); - return false; - } } DWORD disp = 0; @@ -420,15 +512,28 @@ bool fs::file::open(const std::string& filename, u32 mode) case fom::create | fom::trunc: disp = CREATE_ALWAYS; break; case fom::create | fom::excl: disp = CREATE_NEW; break; case fom::create | fom::excl | fom::trunc: disp = CREATE_NEW; break; - } - - if (!disp || (mode & ~(fom::read | fom::write | fom::append | fom::create | fom::trunc | fom::excl))) - { - LOG_ERROR(GENERAL, "fs::file::open('%s') failed: unknown mode specified (0x%x)", filename, mode); + default: + errno = EINVAL; return false; } - m_fd = (std::intptr_t)CreateFileW(to_wchar(filename).get(), access, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL); + m_fd = (std::intptr_t)CreateFileW(to_wchar(path).get(), access, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL); + + if (m_fd == null) + { + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_FILE_NOT_FOUND: errno = ENOENT; break; + case ERROR_PATH_NOT_FOUND: errno = ENOENT; break; + case ERROR_FILE_EXISTS: errno = EEXIST; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x (%s).", error, path); + } + + return false; + } + + return true; #else int flags = 0; @@ -437,11 +542,6 @@ bool fs::file::open(const std::string& filename, u32 mode) case fom::read: flags |= O_RDONLY; break; case fom::write: flags |= O_WRONLY; break; case fom::read | fom::write: flags |= O_RDWR; break; - default: - { - LOG_ERROR(GENERAL, "fs::file::open('%s') failed: neither fom::read nor fom::write specified (0x%x)", filename, mode); - return false; - } } if (mode & fom::append) flags |= O_APPEND; @@ -449,42 +549,63 @@ bool fs::file::open(const std::string& filename, u32 mode) if (mode & fom::trunc) flags |= O_TRUNC; if (mode & fom::excl) flags |= O_EXCL; - if (((mode & fom::excl) && !(mode & fom::create)) || (mode & ~(fom::read | fom::write | fom::append | fom::create | fom::trunc | fom::excl))) - { - LOG_ERROR(GENERAL, "fs::file::open('%s') failed: unknown mode specified (0x%x)", filename, mode); - return false; - } + m_fd = ::open(path.c_str(), flags, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - m_fd = ::open(filename.c_str(), flags, 0666); + return m_fd != null; #endif - - if (m_fd == null) - { - LOG_WARNING(GENERAL, "fs::file::open('%s', 0x%x) failed: error 0x%llx", filename, mode, GET_API_ERROR); - return false; - } - - return true; } bool fs::file::trunc(u64 size) const { - g_tls_error = fse::ok; - #ifdef _WIN32 LARGE_INTEGER old, pos; pos.QuadPart = 0; - SetFilePointerEx((HANDLE)m_fd, pos, &old, FILE_CURRENT); // get old position + if (!SetFilePointerEx((HANDLE)m_fd, pos, &old, FILE_CURRENT)) // get old position + { + switch (DWORD error = GetLastError()) + { + case ERROR_INVALID_HANDLE: errno = EBADF; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x.", error); + } + + return false; + } pos.QuadPart = size; - SetFilePointerEx((HANDLE)m_fd, pos, NULL, FILE_BEGIN); // set new position + if (!SetFilePointerEx((HANDLE)m_fd, pos, NULL, FILE_BEGIN)) // set new position + { + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_NEGATIVE_SEEK: errno = EINVAL; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x.", error); + } - SetEndOfFile((HANDLE)m_fd); // change file size + return false; + } - SetFilePointerEx((HANDLE)m_fd, old, NULL, FILE_BEGIN); // restore position + const BOOL result = SetEndOfFile((HANDLE)m_fd); // change file size - return true; // TODO + if (!result) + { + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case 0: + default: throw EXCEPTION("Unknown Win32 error: 0x%x.", error); + } + } + + if (!SetFilePointerEx((HANDLE)m_fd, old, NULL, FILE_BEGIN) && result) // restore position + { + if (DWORD error = GetLastError()) + { + throw EXCEPTION("Unknown Win32 error: 0x%x.", error); + } + } + + return result != FALSE; #else return !::ftruncate(m_fd, size); #endif @@ -492,13 +613,17 @@ bool fs::file::trunc(u64 size) const bool fs::file::stat(stat_t& info) const { - g_tls_error = fse::ok; - #ifdef _WIN32 FILE_BASIC_INFO basic_info; - if (!GetFileInformationByHandleEx((HANDLE)m_fd, FileBasicInfo, &basic_info, sizeof(FILE_BASIC_INFO))) { + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_INVALID_HANDLE: errno = EBADF; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x.", error); + } + return false; } @@ -509,8 +634,8 @@ bool fs::file::stat(stat_t& info) const 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) + struct ::stat file_info; + if (::fstat(m_fd, &file_info) < 0) { return false; } @@ -526,29 +651,31 @@ bool fs::file::stat(stat_t& info) const return true; } -bool fs::file::close() +void fs::file::close() { - g_tls_error = fse::ok; - if (m_fd == null) { - return false; + return /*true*/; } - auto fd = m_fd; + const auto fd = m_fd; m_fd = null; #ifdef _WIN32 - return CloseHandle((HANDLE)fd); + if (!CloseHandle((HANDLE)fd)) + { + throw EXCEPTION("CloseHandle() failed (fd=0x%llx, 0x%x)", fd, GetLastError()); + } #else - return !::close(fd); + if (::close(fd) != 0) + { + throw EXCEPTION("close() failed (fd=0x%llx, errno=%d)", fd, errno); + } #endif } 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); @@ -556,6 +683,13 @@ u64 fs::file::read(void* buffer, u64 count) const DWORD nread; if (!ReadFile((HANDLE)m_fd, buffer, size, &nread, NULL)) { + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_INVALID_HANDLE: errno = EBADF; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x.", error); + } + return -1; } @@ -567,8 +701,6 @@ u64 fs::file::read(void* buffer, u64 count) const 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); @@ -576,6 +708,13 @@ u64 fs::file::write(const void* buffer, u64 count) const DWORD nwritten; if (!WriteFile((HANDLE)m_fd, buffer, size, &nwritten, NULL)) { + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_INVALID_HANDLE: errno = EBADF; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x.", error); + } + return -1; } @@ -585,52 +724,76 @@ u64 fs::file::write(const void* buffer, u64 count) const #endif } -u64 fs::file::seek(s64 offset, fsm seek_mode) const +u64 fs::file::seek(s64 offset, seek_mode whence) const { - g_tls_error = fse::ok; - #ifdef _WIN32 LARGE_INTEGER pos; pos.QuadPart = offset; - const DWORD mode = - seek_mode == fsm::begin ? FILE_BEGIN : - seek_mode == fsm::cur ? FILE_CURRENT : - seek_mode == fsm::end ? FILE_END : - throw EXCEPTION("Unknown seek_mode (0x%x)", seek_mode); + DWORD mode; + switch (whence) + { + case seek_set: mode = FILE_BEGIN; break; + case seek_cur: mode = FILE_CURRENT; break; + case seek_end: mode = FILE_END; break; + default: + { + errno = EINVAL; + return -1; + } + } if (!SetFilePointerEx((HANDLE)m_fd, pos, &pos, mode)) { + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_INVALID_HANDLE: errno = EBADF; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x.", error); + } + return -1; } return pos.QuadPart; #else - const int whence = - seek_mode == fsm::begin ? SEEK_SET : - seek_mode == fsm::cur ? SEEK_CUR : - seek_mode == fsm::end ? SEEK_END : - throw EXCEPTION("Unknown seek_mode (0x%x)", seek_mode); + int mode; + switch (whence) + { + case seek_set: mode = SEEK_SET; break; + case seek_cur: mode = SEEK_CUR; break; + case seek_end: mode = SEEK_END; break; + default: + { + errno = EINVAL; + return -1; + } + } - return ::lseek(m_fd, offset, whence); + return ::lseek(m_fd, offset, mode); #endif } u64 fs::file::size() const { - g_tls_error = fse::ok; - #ifdef _WIN32 LARGE_INTEGER size; if (!GetFileSizeEx((HANDLE)m_fd, &size)) { + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_INVALID_HANDLE: errno = EBADF; break; + default: throw EXCEPTION("Unknown Win32 error: 0x%x.", error); + } + return -1; } return size.QuadPart; #else - struct stat file_info; - if (::fstat(m_fd, &file_info) < 0) + struct ::stat file_info; + if (::fstat(m_fd, &file_info) != 0) { return -1; } @@ -651,7 +814,7 @@ fs::dir::~dir() } } -void fs::file_ptr::reset(const file& f) +void fs::file_read_map::reset(const file& f) { reset(); @@ -669,7 +832,7 @@ void fs::file_ptr::reset(const file& f) } } -void fs::file_ptr::reset() +void fs::file_read_map::reset() { if (m_ptr) { @@ -685,32 +848,34 @@ bool fs::dir::open(const std::string& dirname) { this->close(); - g_tls_error = fse::ok; - +#ifdef _WIN32 if (!is_dir(dirname)) { return false; } - m_path.reset(new char[dirname.size() + 1]); - std::memcpy(m_path.get(), dirname.c_str(), dirname.size() + 1); - -#ifdef _WIN32 m_dd = -1; #else - m_dd = (std::intptr_t)::opendir(m_path.get()); + const auto ptr = ::opendir(m_path.get()); + if (!ptr) + { + return false; + } + + m_dd = reinterpret_cast(ptr); #endif + m_path.reset(new char[dirname.size() + 1]); + std::memcpy(m_path.get(), dirname.c_str(), dirname.size() + 1); + return true; } -bool fs::dir::close() +void fs::dir::close() { - g_tls_error = fse::ok; - if (!m_path) { - return false; + return /*true*/; } m_path.reset(); @@ -720,33 +885,40 @@ bool fs::dir::close() #else CHECK_ASSERTION(!::closedir((DIR*)m_dd)); #endif - - return true; } bool fs::dir::read(std::string& name, stat_t& info) { - g_tls_error = fse::ok; - if (!m_path) { + errno = EINVAL; return false; } #ifdef _WIN32 + const bool is_first = m_dd == -1; + WIN32_FIND_DATAW found; - if (m_dd == -1) + if (is_first) { m_dd = (std::intptr_t)FindFirstFileW(to_wchar(m_path.get() + "/*"s).get(), &found); - - if (m_dd == -1) - { - return false; - } } - else if (!FindNextFileW((HANDLE)m_dd, &found)) + + if (is_first && m_dd == -1 || !is_first && !FindNextFileW((HANDLE)m_dd, &found)) { + // TODO: convert Win32 error code to errno + switch (DWORD error = GetLastError()) + { + case ERROR_NO_MORE_FILES: + { + name.clear(); + return true; + } + + default: throw EXCEPTION("Unknown Win32 error: 0x%x.", error); + } + return false; } @@ -760,9 +932,14 @@ bool fs::dir::read(std::string& name, stat_t& info) info.ctime = to_time(found.ftCreationTime); #else const auto found = ::readdir((DIR*)m_dd); + if (!found) + { + name.clear(); + return true; + } - struct stat file_info; - if (!found || ::fstatat(::dirfd((DIR*)m_dd), found->d_name, &file_info, 0) < 0) + struct ::stat file_info; + if (::fstatat(::dirfd((DIR*)m_dd), found->d_name, &file_info, 0) != 0) { return false; } @@ -798,7 +975,7 @@ bool fs::dir::first(std::string& name, stat_t& info) return read(name, info); } -std::string fs::get_config_dir() +const std::string& fs::get_config_dir() { // Use magic static for dir initialization static const std::string s_dir = [] @@ -820,6 +997,7 @@ std::string fs::get_config_dir() if (!is_dir(dir) && !create_path(dir)) { std::printf("Failed to create configuration directory '%s' (%d).\n", dir.c_str(), errno); + return get_executable_dir(); } return dir; @@ -829,7 +1007,7 @@ std::string fs::get_config_dir() return s_dir; } -std::string fs::get_executable_dir() +const std::string& fs::get_executable_dir() { // Use magic static for dir initialization static const std::string s_dir = [] @@ -846,6 +1024,8 @@ std::string fs::get_executable_dir() to_utf8(dir, buf); // Convert to UTF-8 + std::replace(dir.begin(), dir.end(), '\\', '/'); + #elif __APPLE__ char buf[4096]; u32 size = sizeof(buf); @@ -865,15 +1045,9 @@ std::string fs::get_executable_dir() return dir; // empty } - dir = { buf, static_cast(size) }; + dir.assign(buf, size); #endif - - // Replace "\" - for (auto& c : dir) - { - if (c == '\\') c = '/'; - } - + // Leave only path dir.resize(dir.rfind('/') + 1); return dir; diff --git a/Utilities/File.h b/Utilities/File.h index 0fcb3c30a7..38ed811955 100644 --- a/Utilities/File.h +++ b/Utilities/File.h @@ -1,15 +1,8 @@ #pragma once -enum class fsm : u32 // file seek mode -{ - begin, - cur, - end, -}; - namespace fom // file open mode { - enum : u32 + enum open_mode : u32 { read = 1 << 0, // enable reading write = 1 << 1, // enable writing @@ -18,19 +11,18 @@ namespace fom // file open mode trunc = 1 << 4, // clear opened file if it's not empty excl = 1 << 5, // failure if the file already exists (used with `create`) - rewrite = write | create | trunc, // write + create + trunc + rewrite = write | create | trunc, }; }; -enum class fse : u32 // filesystem (file or dir) error -{ - ok, // no error - invalid_arguments, -}; - namespace fs { - thread_local extern fse g_tls_error; + enum seek_mode : u32 // file seek mode + { + seek_set, + seek_cur, + seek_end, + }; struct stat_t { @@ -42,6 +34,9 @@ namespace fs s64 ctime; }; + // Get parent directory for the path (returns empty string on failure) + std::string get_parent_dir(const std::string& path); + // Get file information bool stat(const std::string& path, stat_t& info); @@ -49,16 +44,16 @@ namespace fs bool exists(const std::string& path); // Check whether the file exists and is NOT a directory - bool is_file(const std::string& file); + bool is_file(const std::string& path); // Check whether the directory exists and is NOT a file - bool is_dir(const std::string& dir); + bool is_dir(const std::string& path); // Delete empty directory - bool remove_dir(const std::string& dir); + bool remove_dir(const std::string& path); // Create directory - bool create_dir(const std::string& dir); + bool create_dir(const std::string& path); // Create directories bool create_path(const std::string& path); @@ -70,10 +65,10 @@ namespace fs bool copy_file(const std::string& from, const std::string& to, bool overwrite); // Delete file - bool remove_file(const std::string& file); + bool remove_file(const std::string& path); // Change file size (possibly appending zeros) - bool truncate_file(const std::string& file, u64 length); + bool truncate_file(const std::string& path, u64 length); class file final { @@ -83,14 +78,15 @@ namespace fs handle_type m_fd = null; - friend class file_ptr; + friend class file_read_map; + friend class file_write_map; public: file() = default; - explicit file(const std::string& filename, u32 mode = fom::read) + explicit file(const std::string& path, u32 mode = fom::read) { - open(filename, mode); + open(path, mode); } file(file&& other) @@ -120,7 +116,7 @@ namespace fs } // Open specified file with specified mode - bool open(const std::string& filename, u32 mode = fom::read); + bool open(const std::string& path, u32 mode = fom::read); // Change file size (possibly appending zero bytes) bool trunc(u64 size) const; @@ -129,7 +125,7 @@ namespace fs bool stat(stat_t& info) const; // Close the file explicitly (destructor automatically closes the file) - bool close(); + void close(); // Read the data from the file and return the amount of data written in buffer u64 read(void* buffer, u64 count) const; @@ -138,92 +134,102 @@ namespace fs u64 write(const void* buffer, u64 count) const; // Move file pointer - u64 seek(s64 offset, fsm seek_mode = fsm::begin) const; + u64 seek(s64 offset, seek_mode whence = seek_set) const; // Get file size u64 size() const; - // Write std::string - const file& operator <<(const std::string& str) const + // Write std::string unconditionally + const file& write(const std::string& str) const { CHECK_ASSERTION(write(str.data(), str.size()) == str.size()); return *this; } - // Write POD + // Write POD unconditionally template - std::enable_if_t::value && !std::is_pointer::value, const file&> operator <<(const T& data) const + std::enable_if_t::value && !std::is_pointer::value, const file&> write(const T& data) const { CHECK_ASSERTION(write(std::addressof(data), sizeof(T)) == sizeof(T)); return *this; } - // Write POD std::vector + // Write POD std::vector unconditionally template - std::enable_if_t::value && !std::is_pointer::value, const file&> operator <<(const std::vector& vec) const + std::enable_if_t::value && !std::is_pointer::value, const file&> write(const std::vector& vec) const { CHECK_ASSERTION(write(vec.data(), vec.size() * sizeof(T)) == vec.size() * sizeof(T)); return *this; } - // Read std::string + // Read std::string, size must be set by resize() method bool read(std::string& str) const { return read(&str[0], str.size()) == str.size(); } - // Read POD + // Read POD, sizeof(T) is used 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 + // Read POD std::vector, size must be set by resize() method 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 + // Read POD (experimental) + template + std::enable_if_t::value && !std::is_pointer::value, T> read() const + { + T result; + CHECK_ASSERTION(read(result)); + return result; + } + + // Read full file to std::string + std::string to_string() const { std::string result; - result.resize(size() - seek(0, fsm::cur)); - CHECK_ASSERTION(read(result)); + result.resize(size()); + CHECK_ASSERTION(seek(0) != -1 && read(result)); return result; } }; - class file_ptr final + // TODO + class file_read_map final { char* m_ptr = nullptr; u64 m_size; public: - file_ptr() = default; + file_read_map() = default; - file_ptr(file_ptr&& right) + file_read_map(file_read_map&& right) : m_ptr(right.m_ptr) , m_size(right.m_size) { right.m_ptr = 0; } - file_ptr& operator =(file_ptr&& right) + file_read_map& operator =(file_read_map&& right) { std::swap(m_ptr, right.m_ptr); std::swap(m_size, right.m_size); return *this; } - file_ptr(const file& f) + file_read_map(const file& f) { reset(f); } - ~file_ptr() + ~file_read_map() { reset(); } @@ -234,6 +240,52 @@ namespace fs // Close file mapping void reset(); + // Get pointer + operator const char*() const + { + return m_ptr; + } + }; + + // TODO + class file_write_map final + { + char* m_ptr = nullptr; + u64 m_size; + + public: + file_write_map() = default; + + file_write_map(file_write_map&& right) + : m_ptr(right.m_ptr) + , m_size(right.m_size) + { + right.m_ptr = 0; + } + + file_write_map& operator =(file_write_map&& right) + { + std::swap(m_ptr, right.m_ptr); + std::swap(m_size, right.m_size); + return *this; + } + + file_write_map(const file& f) + { + reset(f); + } + + ~file_write_map() + { + reset(); + } + + // Open file mapping + void reset(const file& f); + + // Close file mapping + void reset(); + // Get pointer operator char*() const { @@ -285,7 +337,7 @@ namespace fs bool open(const std::string& dirname); // Close the directory explicitly (destructor automatically closes the directory) - bool close(); + void close(); // Get next directory entry (UTF-8 name and file stat) bool read(std::string& name, stat_t& info); @@ -318,18 +370,16 @@ namespace fs return; } - bool is_ok; - if (mode_ == mode::from_first) { - is_ok = m_parent->first(m_entry.name, m_entry.info); + m_parent->first(m_entry.name, m_entry.info); } else { - is_ok = m_parent->read(m_entry.name, m_entry.info); + m_parent->read(m_entry.name, m_entry.info); } - if (!is_ok) + if (m_entry.name.empty()) { m_parent = nullptr; } @@ -364,8 +414,8 @@ namespace fs }; // Get configuration directory - std::string get_config_dir(); + const std::string& get_config_dir(); // Get executable directory - std::string get_executable_dir(); + const std::string& get_executable_dir(); } diff --git a/Utilities/Log.cpp b/Utilities/Log.cpp index d5794f7d69..162c8cfbfd 100644 --- a/Utilities/Log.cpp +++ b/Utilities/Log.cpp @@ -126,7 +126,7 @@ struct FileListener : LogListener } } - mFile << text; + mFile.write(text); } }; @@ -261,25 +261,5 @@ void log_message(Log::LogType type, Log::Severity sev, const char* text) void log_message(Log::LogType type, Log::Severity sev, std::string text) { - if (g_log_manager) - { - g_log_manager->log({ type, sev, std::move(text) }); - } - else - { - const auto severity = - sev == Severity::Notice ? "Notice" : - sev == Severity::Warning ? "Warning" : - sev == Severity::Success ? "Success" : - sev == Severity::Error ? "Error" : "Unknown"; - -#ifdef _WIN32 - MessageBoxA(0, text.c_str(), severity, - sev == Severity::Notice ? MB_ICONINFORMATION : - sev == Severity::Warning ? MB_ICONEXCLAMATION : - sev == Severity::Error ? MB_ICONERROR : MB_ICONINFORMATION); -#else - std::printf("[Log:%s] %s\n", severity, text.c_str()); -#endif - } + g_log_manager->log({ type, sev, std::move(text) }); } diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index 306ef4305b..d72b20a757 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -19,7 +19,7 @@ #include #endif -void report_fatal_error(const std::string& msg) +static void report_fatal_error(const std::string& msg) { #ifdef _WIN32 const auto& text = msg + "\n\nPlease report this error to the developers. Press (Ctrl+C) to copy this message."; @@ -1148,7 +1148,7 @@ void prepare_throw_access_violation(x64_context* context, const char* cause, u32 #ifdef _WIN32 -const auto g_exception_handler = AddVectoredExceptionHandler(1, [](PEXCEPTION_POINTERS pExp) -> LONG +static LONG exception_handler(PEXCEPTION_POINTERS pExp) { const u64 addr64 = pExp->ExceptionRecord->ExceptionInformation[1] - (u64)vm::base(0); const bool is_writing = pExp->ExceptionRecord->ExceptionInformation[0] != 0; @@ -1161,9 +1161,9 @@ const auto g_exception_handler = AddVectoredExceptionHandler(1, [](PEXCEPTION_PO { return EXCEPTION_CONTINUE_SEARCH; } -}); +} -const auto g_exception_filter = SetUnhandledExceptionFilter([](PEXCEPTION_POINTERS pExp) -> LONG +static LONG exception_filter(PEXCEPTION_POINTERS pExp) { std::string msg = fmt::format("Unhandled Win32 exception 0x%08X.\n", pExp->ExceptionRecord->ExceptionCode); @@ -1191,16 +1191,36 @@ const auto g_exception_filter = SetUnhandledExceptionFilter([](PEXCEPTION_POINTE } } + msg += fmt::format("Instruction address: %p.\n", pExp->ContextRecord->Rip); msg += fmt::format("Image base: %p.", GetModuleHandle(NULL)); + // TODO: print registers and the callstack + // Report fatal error report_fatal_error(msg); return EXCEPTION_CONTINUE_SEARCH; -}); +} + +const bool g_exception_handler_set = []() -> bool +{ + if (!AddVectoredExceptionHandler(1, (PVECTORED_EXCEPTION_HANDLER)exception_handler)) + { + report_fatal_error("AddVectoredExceptionHandler() failed."); + std::abort(); + } + + if (!SetUnhandledExceptionFilter((LPTOP_LEVEL_EXCEPTION_FILTER)exception_filter)) + { + report_fatal_error("SetUnhandledExceptionFilter() failed."); + std::abort(); + } + + return true; +}(); #else -void signal_handler(int sig, siginfo_t* info, void* uct) +static void signal_handler(int sig, siginfo_t* info, void* uct) { x64_context* context = (ucontext_t*)uct; @@ -1230,17 +1250,21 @@ void signal_handler(int sig, siginfo_t* info, void* uct) } } -int setup_signal_handler() +const bool g_exception_handler_set = []() -> bool { - struct sigaction sa; - + struct ::sigaction sa; sa.sa_flags = SA_SIGINFO; sigemptyset(&sa.sa_mask); sa.sa_sigaction = signal_handler; - return sigaction(SIGSEGV, &sa, NULL); -} -const int g_sigaction_result = setup_signal_handler(); + if (::sigaction(SIGSEGV, &sa, NULL) == -1) + { + std::printf("sigaction() failed (0x%x).", errno); + std::abort(); + } + + return true; +}(); #endif @@ -1253,16 +1277,6 @@ void thread_ctrl::initialize() { SetCurrentThreadDebugName(g_tls_this_thread->m_name().c_str()); -#ifdef _WIN32 - if (!g_exception_handler || !g_exception_filter) -#else - if (g_sigaction_result == -1) -#endif - { - report_fatal_error("Exception handler is not set correctly."); - std::abort(); - } - // TODO g_thread_count++; } diff --git a/Utilities/convert.h b/Utilities/convert.h index d8b10e54c5..b190737fcb 100644 --- a/Utilities/convert.h +++ b/Utilities/convert.h @@ -30,14 +30,14 @@ namespace convert { static bool func(const std::string& value) { - return value == "true" ? true : false; + return value == "true" ? true : value == "false" ? false : throw std::invalid_argument(__FUNCTION__); } }; template<> - struct to_impl_t + struct to_impl_t { - static std::string func(char value) + static std::string func(signed char value) { return std::to_string(value); } diff --git a/Utilities/rPlatform.cpp b/Utilities/rPlatform.cpp index 136b939b0a..53f7e783d7 100644 --- a/Utilities/rPlatform.cpp +++ b/Utilities/rPlatform.cpp @@ -10,7 +10,6 @@ #ifndef _WIN32 #include -#include #endif #include "rPlatform.h" diff --git a/rpcs3.sln b/rpcs3.sln index 5769fb4e35..fd0f9573bf 100644 --- a/rpcs3.sln +++ b/rpcs3.sln @@ -139,12 +139,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xrc", "wxWidgets\build\msw\ {24C45343-FD20-5C92-81C1-35A2AE841E79} = {24C45343-FD20-5C92-81C1-35A2AE841E79} EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "stblib", "stblib", "{9D839DFB-76E6-4F10-8EED-BA2AC7CC3FB6}" - ProjectSection(SolutionItems) = preProject - stblib\stb_image.c = stblib\stb_image.c - stblib\stb_image.h = stblib\stb_image.h - EndProjectSection -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ribbon", "wxWidgets\build\msw\wx_ribbon.vcxproj", "{87B42A9C-3F5C-53D7-9017-2B1CAE39457D}" ProjectSection(ProjectDependencies) = postProject {24C45343-FD20-5C92-81C1-35A2AE841E79} = {24C45343-FD20-5C92-81C1-35A2AE841E79} @@ -181,8 +175,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "_custom_build", "wxWidgets\ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "copy_setup_h", "rpcs3\copy_setup_h.vcxproj", "{00D36322-6188-4A66-B514-3B3F183E998D}" EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GSRender", "GSRender", "{1A43FD7A-C7DD-4D04-A4D6-FAA194AAD9D2}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "D3D12GSRender", "rpcs3\D3D12GSRender.vcxproj", "{FAC9B17B-F4B8-4B75-8AEB-C8C7CB92B078}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rpcs3-tests", "rpcs3-tests\rpcs3-tests.vcxproj", "{AB222E8A-00CA-4ACF-A87E-5251C16C0587}" diff --git a/rpcs3/CMakeLists.txt b/rpcs3/CMakeLists.txt index 616d99268d..7063834e8d 100644 --- a/rpcs3/CMakeLists.txt +++ b/rpcs3/CMakeLists.txt @@ -156,6 +156,7 @@ GLOB_RECURSE RPCS3_SRC "${RPCS3_SRC_DIR}/rpcs3.cpp" "${RPCS3_SRC_DIR}/config.cpp" +"${RPCS3_SRC_DIR}/stb_image.cpp" "${RPCS3_SRC_DIR}/../Utilities/GNU.cpp" "${RPCS3_SRC_DIR}/Emu/*" "${RPCS3_SRC_DIR}/Gui/*" diff --git a/rpcs3/Crypto/unpkg.cpp b/rpcs3/Crypto/unpkg.cpp index f4cda67604..568e5aaa63 100644 --- a/rpcs3/Crypto/unpkg.cpp +++ b/rpcs3/Crypto/unpkg.cpp @@ -62,7 +62,7 @@ bool pkg_install(const fs::file& pkg_f, const std::string& dir, volatile f64& pr const std::size_t BUF_SIZE = 8192 * 1024; // 8 MB // Save current file offset (probably zero) - const u64 start_offset = pkg_f.seek(0, fsm::cur); + const u64 start_offset = pkg_f.seek(0, fs::seek_cur); // Get basic PKG information PKGHeader header; diff --git a/rpcs3/Crypto/unself.cpp b/rpcs3/Crypto/unself.cpp index 6fe7ce0e07..d2f0edf254 100644 --- a/rpcs3/Crypto/unself.cpp +++ b/rpcs3/Crypto/unself.cpp @@ -1330,6 +1330,8 @@ bool CheckDebugSelf(const std::string& self, const std::string& elf) bool DecryptSelf(const std::string& elf, const std::string& self) { + LOG_NOTICE(GENERAL, "Decrypting %s", self); + // Check for a debug SELF first. if (!CheckDebugSelf(self, elf)) { diff --git a/rpcs3/D3D12GSRender.vcxproj b/rpcs3/D3D12GSRender.vcxproj index fd75eb3e7a..a610917e18 100644 --- a/rpcs3/D3D12GSRender.vcxproj +++ b/rpcs3/D3D12GSRender.vcxproj @@ -61,66 +61,7 @@ - - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - - - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - - - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - - - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - - - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - - - - true - - - true - - - - - true - - - - - true - - - - - true - - - true - - - - - true - - - true - - - - - true - - - + true diff --git a/rpcs3/Emu/Audio/AudioManager.cpp b/rpcs3/Emu/Audio/AudioManager.cpp index 615a518c06..9336a8fa3d 100644 --- a/rpcs3/Emu/Audio/AudioManager.cpp +++ b/rpcs3/Emu/Audio/AudioManager.cpp @@ -1,24 +1,10 @@ #include "stdafx.h" #include "Emu/System.h" #include "AudioManager.h" -#include "Emu/state.h" - -AudioManager::AudioManager() : m_audio_out(nullptr) -{ -} - -AudioManager::~AudioManager() -{ - Close(); -} void AudioManager::Init() { - if (m_audio_out) return; - - m_audio_info.Init(); - - m_audio_out = Emu.GetCallbacks().get_audio(); + if (!m_audio_out) m_audio_out = Emu.GetCallbacks().get_audio(); } void AudioManager::Close() diff --git a/rpcs3/Emu/Audio/AudioManager.h b/rpcs3/Emu/Audio/AudioManager.h index 149fa15ede..d5514f8e49 100644 --- a/rpcs3/Emu/Audio/AudioManager.h +++ b/rpcs3/Emu/Audio/AudioManager.h @@ -2,29 +2,13 @@ #include "AudioThread.h" -// it cannot be configured currently, and it must NOT use cellSysutil definitions -struct AudioInfo -{ - AudioInfo() - { - } - - void Init() - { - } -}; - class AudioManager { - AudioInfo m_audio_info; std::shared_ptr m_audio_out; -public: - AudioManager(); - ~AudioManager(); +public: void Init(); void Close(); - AudioThread& GetAudioOut() { assert(m_audio_out); return *m_audio_out; } - AudioInfo& GetInfo() { return m_audio_info; } + AudioThread& GetAudioOut() { return *m_audio_out; } }; diff --git a/rpcs3/Emu/Audio/XAudio2/XAudio2Thread.h b/rpcs3/Emu/Audio/XAudio2/XAudio2Thread.h index cf7141c792..5ef541754e 100644 --- a/rpcs3/Emu/Audio/XAudio2/XAudio2Thread.h +++ b/rpcs3/Emu/Audio/XAudio2/XAudio2Thread.h @@ -3,9 +3,11 @@ #include "Emu/Audio/AudioThread.h" +#pragma push_macro("_WIN32_WINNT") +#undef _WIN32_WINNT #define _WIN32_WINNT 0x0601 // This is to be sure that correct (2.7) header is included #include "minidx9/Include/XAudio2.h" // XAudio2 2.8 available only on Win8+, used XAudio2 2.7 from dxsdk -#undef _WIN32_WINNT +#pragma pop_macro("_WIN32_WINNT") class XAudio2Thread : public AudioThread { diff --git a/rpcs3/Emu/Cell/PPUThread.h b/rpcs3/Emu/Cell/PPUThread.h index 2c055ef1ee..897864d611 100644 --- a/rpcs3/Emu/Cell/PPUThread.h +++ b/rpcs3/Emu/Cell/PPUThread.h @@ -1017,6 +1017,8 @@ enum : u32 { MFF_FORCED_HLE = (1 << 0), // always call HLE function MFF_NO_RETURN = (1 << 1), // uses EIF_USE_BRANCH flag with LLE, ignored with MFF_FORCED_HLE + + MFF_PERFECT = /* 0 */ MFF_FORCED_HLE, // can be set for fully implemented functions with LLE compatibility }; // flags passed with index @@ -1026,5 +1028,5 @@ enum : u32 EIF_PERFORM_BLR = (1 << 24), // do BLR after calling HLE/LLE function EIF_USE_BRANCH = (1 << 23), // do only branch, LLE must be set, last_syscall must be zero - EIF_FLAGS = 0x3800000, // all flags + EIF_FLAGS = 0x3800000, // all flags }; diff --git a/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp b/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp index fc2e5aaf97..851a951e35 100644 --- a/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp +++ b/rpcs3/Emu/Cell/SPUASMJITRecompiler.cpp @@ -31,7 +31,7 @@ spu_recompiler::spu_recompiler() LOG_SUCCESS(SPU, "SPU Recompiler (ASMJIT) created..."); - 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()); + fs::file(fs::get_config_dir() + "SPUJIT.log", fom::rewrite).write(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) @@ -216,7 +216,7 @@ void spu_recompiler::compile(spu_function_t& f) log += "\n\n\n"; // Append log file - fs::file(fs::get_config_dir() + "SPUJIT.log", fom::write | fom::append) << log; + fs::file(fs::get_config_dir() + "SPUJIT.log", fom::write | fom::append).write(log); } spu_recompiler::XmmLink spu_recompiler::XmmAlloc() // get empty xmm register diff --git a/rpcs3/Emu/FS/vfsFile.cpp b/rpcs3/Emu/FS/vfsFile.cpp index 252ca4c21d..cded25282c 100644 --- a/rpcs3/Emu/FS/vfsFile.cpp +++ b/rpcs3/Emu/FS/vfsFile.cpp @@ -26,11 +26,9 @@ bool vfsFile::Open(const std::string& path, u32 mode) return m_stream && m_stream->IsOpened(); } -bool vfsFile::Close() +void vfsFile::Close() { m_stream.reset(); - - return true; } u64 vfsFile::GetSize() const @@ -48,9 +46,9 @@ u64 vfsFile::Read(void* dst, u64 size) return m_stream->Read(dst, size); } -u64 vfsFile::Seek(s64 offset, fsm mode) +u64 vfsFile::Seek(s64 offset, fs::seek_mode whence) { - return m_stream->Seek(offset, mode); + return m_stream->Seek(offset, whence); } u64 vfsFile::Tell() const diff --git a/rpcs3/Emu/FS/vfsFile.h b/rpcs3/Emu/FS/vfsFile.h index 11d1382905..74f538abc5 100644 --- a/rpcs3/Emu/FS/vfsFile.h +++ b/rpcs3/Emu/FS/vfsFile.h @@ -12,14 +12,14 @@ public: vfsFile(const std::string& path, u32 mode = fom::read); virtual bool Open(const std::string& path, u32 mode = fom::read) override; - virtual bool Close() override; + virtual void Close() override; virtual u64 GetSize() const override; virtual u64 Write(const void* src, u64 size) override; virtual u64 Read(void* dst, u64 size) override; - virtual u64 Seek(s64 offset, fsm seek_mode = fsm::begin) override; + virtual u64 Seek(s64 offset, fs::seek_mode whence = fs::seek_set) override; virtual u64 Tell() const override; virtual bool IsOpened() const override; diff --git a/rpcs3/Emu/FS/vfsFileBase.cpp b/rpcs3/Emu/FS/vfsFileBase.cpp index dc7aa6dd56..b3cc967246 100644 --- a/rpcs3/Emu/FS/vfsFileBase.cpp +++ b/rpcs3/Emu/FS/vfsFileBase.cpp @@ -20,11 +20,10 @@ bool vfsFileBase::Open(const std::string& path, u32 mode) return true; } -bool vfsFileBase::Close() +void vfsFileBase::Close() { m_path = ""; - - return vfsStream::Close(); + vfsStream::Close(); } std::string vfsFileBase::GetPath() const diff --git a/rpcs3/Emu/FS/vfsFileBase.h b/rpcs3/Emu/FS/vfsFileBase.h index bba47776d5..0b4f00b4b2 100644 --- a/rpcs3/Emu/FS/vfsFileBase.h +++ b/rpcs3/Emu/FS/vfsFileBase.h @@ -16,7 +16,7 @@ public: virtual ~vfsFileBase() override; virtual bool Open(const std::string& path, u32 mode); - virtual bool Close() override; + virtual void Close() override; virtual bool IsOpened() const override { return !m_path.empty(); } std::string GetPath() const; diff --git a/rpcs3/Emu/FS/vfsLocalDir.cpp b/rpcs3/Emu/FS/vfsLocalDir.cpp index 5048550061..95062193cb 100644 --- a/rpcs3/Emu/FS/vfsLocalDir.cpp +++ b/rpcs3/Emu/FS/vfsLocalDir.cpp @@ -20,7 +20,7 @@ bool vfsLocalDir::Open(const std::string& path) std::string name; fs::stat_t file_info; - while (m_dir.read(name, file_info)) + while (m_dir.read(name, file_info) && name.size()) { m_entries.emplace_back(); diff --git a/rpcs3/Emu/FS/vfsLocalFile.cpp b/rpcs3/Emu/FS/vfsLocalFile.cpp index efe713c8ba..573fc9db47 100644 --- a/rpcs3/Emu/FS/vfsLocalFile.cpp +++ b/rpcs3/Emu/FS/vfsLocalFile.cpp @@ -12,9 +12,10 @@ bool vfsLocalFile::Open(const std::string& path, u32 mode) return m_file.open(path, mode) && vfsFileBase::Open(path, mode); } -bool vfsLocalFile::Close() +void vfsLocalFile::Close() { - return m_file.close() && vfsFileBase::Close(); + m_file.close(); + vfsFileBase::Close(); } u64 vfsLocalFile::GetSize() const @@ -32,14 +33,14 @@ u64 vfsLocalFile::Read(void* dst, u64 size) return m_file.read(dst, size); } -u64 vfsLocalFile::Seek(s64 offset, fsm mode) +u64 vfsLocalFile::Seek(s64 offset, fs::seek_mode whence) { - return m_file.seek(offset, mode); + return m_file.seek(offset, whence); } u64 vfsLocalFile::Tell() const { - return m_file.seek(0, fsm::cur); + return m_file.seek(0, fs::seek_cur); } bool vfsLocalFile::IsOpened() const diff --git a/rpcs3/Emu/FS/vfsLocalFile.h b/rpcs3/Emu/FS/vfsLocalFile.h index c014903389..dc56074b71 100644 --- a/rpcs3/Emu/FS/vfsLocalFile.h +++ b/rpcs3/Emu/FS/vfsLocalFile.h @@ -11,14 +11,14 @@ public: vfsLocalFile(vfsDevice* device); virtual bool Open(const std::string& path, u32 mode = fom::read) override; - virtual bool Close() override; + virtual void Close() override; virtual u64 GetSize() const override; virtual u64 Write(const void* src, u64 size) override; virtual u64 Read(void* dst, u64 size) override; - virtual u64 Seek(s64 offset, fsm seek_mode = fsm::begin) override; + virtual u64 Seek(s64 offset, fs::seek_mode whence = fs::seek_set) override; virtual u64 Tell() const override; virtual bool IsOpened() const override; diff --git a/rpcs3/Emu/FS/vfsStream.h b/rpcs3/Emu/FS/vfsStream.h index 826e5acf77..e1d1976049 100644 --- a/rpcs3/Emu/FS/vfsStream.h +++ b/rpcs3/Emu/FS/vfsStream.h @@ -9,9 +9,8 @@ struct vfsStream Close(); } - virtual bool Close() + virtual void Close() { - return true; } virtual u64 GetSize() const = 0; @@ -30,7 +29,7 @@ struct vfsStream return Read(&data, count) == count; } - virtual u64 Seek(s64 offset, fsm seek_mode = fsm::begin) = 0; + virtual u64 Seek(s64 offset, fs::seek_mode whence = fs::seek_set) = 0; virtual u64 Tell() const = 0; diff --git a/rpcs3/Emu/FS/vfsStreamMemory.h b/rpcs3/Emu/FS/vfsStreamMemory.h index 6054bb1b0e..d5dd22c0db 100644 --- a/rpcs3/Emu/FS/vfsStreamMemory.h +++ b/rpcs3/Emu/FS/vfsStreamMemory.h @@ -31,16 +31,16 @@ public: virtual u64 Read(void* dst, u64 count) override; - virtual u64 Seek(s64 offset, fsm seek_mode = fsm::begin) override + virtual u64 Seek(s64 offset, fs::seek_mode whence) override { - switch (seek_mode) + switch (whence) { - case fsm::begin: return m_pos = offset; - case fsm::cur: return m_pos += offset; - case fsm::end: return m_pos = m_size + offset; + case fs::seek_set: return m_pos = offset; + case fs::seek_cur: return m_pos += offset; + case fs::seek_end: return m_pos = m_size + offset; } - throw EXCEPTION("Unknown seek_mode (0x%x)", seek_mode); + throw EXCEPTION("Unknown seek_mode (0x%x)", whence); } virtual u64 Tell() const override diff --git a/rpcs3/Emu/HDD/HDD.cpp b/rpcs3/Emu/HDD/HDD.cpp index aa5d293cc3..5c4cf61145 100644 --- a/rpcs3/Emu/HDD/HDD.cpp +++ b/rpcs3/Emu/HDD/HDD.cpp @@ -787,16 +787,16 @@ u64 vfsHDD::Read(void* dst, u64 size) return m_file.Read(dst, size); // ??? } -u64 vfsHDD::Seek(s64 offset, fsm seek_mode) +u64 vfsHDD::Seek(s64 offset, fs::seek_mode whence) { - switch (seek_mode) + switch (whence) { - case fsm::begin: return m_file.Seek(offset); - case fsm::cur: return m_file.Seek(Tell() + offset); - case fsm::end: return m_file.Seek(m_file.GetSize() + offset); + case fs::seek_set: return m_file.Seek(offset); + case fs::seek_cur: return m_file.Seek(Tell() + offset); + case fs::seek_end: return m_file.Seek(m_file.GetSize() + offset); } - throw EXCEPTION("Unknown seek_mode(0x%x)", seek_mode); + throw EXCEPTION("Unknown whence (0x%x)", whence); } u64 vfsHDD::Tell() const @@ -817,4 +817,4 @@ bool vfsHDD::IsOpened() const u64 vfsHDD::GetSize() const { return m_file.GetSize(); -} \ No newline at end of file +} diff --git a/rpcs3/Emu/HDD/HDD.h b/rpcs3/Emu/HDD/HDD.h index 9bbc651f23..a192de41e5 100644 --- a/rpcs3/Emu/HDD/HDD.h +++ b/rpcs3/Emu/HDD/HDD.h @@ -196,7 +196,7 @@ public: virtual u64 Read(void* dst, u64 count) override; - virtual u64 Seek(s64 offset, fsm seek_mode = fsm::begin) override; + virtual u64 Seek(s64 offset, fs::seek_mode whence = fs::seek_set) override; virtual u64 Tell() const override; diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index 1d8d2b61c4..e5bd00b22d 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -15,7 +15,6 @@ #include #include #include -#include /* OS X uses MAP_ANON instead of MAP_ANONYMOUS */ #ifndef MAP_ANONYMOUS @@ -239,13 +238,10 @@ namespace vm catch (...) { // capture any exception possibly thrown by predicate - pred = [exception = std::current_exception()] + pred = [exception = std::current_exception()]() -> bool { // new predicate will throw the captured exception from the original thread std::rethrow_exception(exception); - - // dummy return value, remove when std::rethrow_exception gains [[noreturn]] attribute in MSVC - return true; }; } diff --git a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h index ef4ba8db27..831146f246 100644 --- a/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h +++ b/rpcs3/Emu/RSX/D3D12/D3D12PipelineState.h @@ -166,7 +166,7 @@ struct D3D12Traits } } - fs::file(fs::get_config_dir() + "FragmentProgram" + std::to_string(ID) + ".hlsl", fom::rewrite) << shader; + fs::file(fs::get_config_dir() + "FragmentProgram" + std::to_string(ID) + ".hlsl", fom::rewrite).write(shader); fragmentProgramData.id = (u32)ID; } @@ -177,7 +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; - fs::file(fs::get_config_dir() + "VertexProgram" + std::to_string(ID) + ".hlsl", fom::rewrite) << shaderCode; + fs::file(fs::get_config_dir() + "VertexProgram" + std::to_string(ID) + ".hlsl", fom::rewrite).write(shaderCode); vertexProgramData.id = (u32)ID; } diff --git a/rpcs3/Emu/RSX/GCM.h b/rpcs3/Emu/RSX/GCM.h index 6a97a25e89..cd55822aca 100644 --- a/rpcs3/Emu/RSX/GCM.h +++ b/rpcs3/Emu/RSX/GCM.h @@ -979,7 +979,7 @@ namespace rsx template static size_t make_command(vm::ps3::ptr &dst, u32 start_register, T... values) { - for (u32 command : { (start_register << 2) | u32(sizeof...(values) << 18), u32(values)... }) + for (u32 command : { (start_register << 2) | u32(sizeof...(values) << 18), static_cast(values)... }) { *dst++ = command; } diff --git a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h index 823064a176..ccecef2037 100644 --- a/rpcs3/Emu/RSX/GL/GLProgramBuffer.h +++ b/rpcs3/Emu/RSX/GL/GLProgramBuffer.h @@ -17,7 +17,7 @@ struct GLTraits fragmentProgramData.Compile(); //checkForGlError("m_fragment_prog.Compile"); - fs::file(fs::get_config_dir() + "FragmentProgram.txt", fom::rewrite) << fragmentProgramData.shader; + fs::file(fs::get_config_dir() + "FragmentProgram.txt", fom::rewrite).write(fragmentProgramData.shader); } static @@ -27,7 +27,7 @@ struct GLTraits vertexProgramData.Compile(); //checkForGlError("m_vertex_prog.Compile"); - fs::file(fs::get_config_dir() + "VertexProgram.txt", fom::rewrite) << vertexProgramData.shader; + fs::file(fs::get_config_dir() + "VertexProgram.txt", fom::rewrite).write(vertexProgramData.shader); } static diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 0f485e156a..8984611e73 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -53,14 +53,14 @@ namespace rsx if (fmt::match(entry.name, "*.fs." + lang_name)) { fs::file file{ path + entry.name }; - decompiled_fragment_shaders.insert(hash, { (const std::string)file }); + decompiled_fragment_shaders.insert(hash, { file.to_string() }); continue; } if (fmt::match(entry.name, "*.vs." + lang_name)) { fs::file file{ path + entry.name }; - decompiled_vertex_shaders.insert(hash, { (const std::string)file }); + decompiled_vertex_shaders.insert(hash, { file.to_string() }); continue; } } diff --git a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp index f6d9cff989..4cfbcfd5ea 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp @@ -1058,24 +1058,24 @@ Module<> cellFs("cellFs", []() REG_FUNC(cellFs, cellFsOpen); REG_FUNC(cellFs, cellFsSdataOpen); REG_FUNC(cellFs, cellFsSdataOpenByFd); - REG_FUNC(cellFs, cellFsRead); - REG_FUNC(cellFs, cellFsWrite); - REG_FUNC(cellFs, cellFsClose); + REG_FUNC(cellFs, cellFsRead, MFF_PERFECT); + REG_FUNC(cellFs, cellFsWrite, MFF_PERFECT); + REG_FUNC(cellFs, cellFsClose, MFF_PERFECT); REG_FUNC(cellFs, cellFsOpendir); - REG_FUNC(cellFs, cellFsReaddir); - REG_FUNC(cellFs, cellFsClosedir); + REG_FUNC(cellFs, cellFsReaddir, MFF_PERFECT); + REG_FUNC(cellFs, cellFsClosedir, MFF_PERFECT); REG_FUNC(cellFs, cellFsStat); - REG_FUNC(cellFs, cellFsFstat); + REG_FUNC(cellFs, cellFsFstat, MFF_PERFECT); REG_FUNC(cellFs, cellFsMkdir); REG_FUNC(cellFs, cellFsRename); REG_FUNC(cellFs, cellFsChmod); REG_FUNC(cellFs, cellFsFsync); REG_FUNC(cellFs, cellFsRmdir); REG_FUNC(cellFs, cellFsUnlink); - REG_FUNC(cellFs, cellFsLseek); - REG_FUNC(cellFs, cellFsFtruncate); + REG_FUNC(cellFs, cellFsLseek, MFF_PERFECT); + REG_FUNC(cellFs, cellFsFtruncate, MFF_PERFECT); REG_FUNC(cellFs, cellFsTruncate); - REG_FUNC(cellFs, cellFsFGetBlockSize); + REG_FUNC(cellFs, cellFsFGetBlockSize, MFF_PERFECT); REG_FUNC(cellFs, cellFsAioInit); REG_FUNC(cellFs, cellFsAioFinish); REG_FUNC(cellFs, cellFsAioRead); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp index 22d901f69e..5179971803 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp @@ -7,7 +7,6 @@ extern "C" { #include "stblib/stb_image.h" -#include "stblib/stb_image.c" } #include "Emu/FS/VFS.h" diff --git a/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp b/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp index 2da10e5992..f23eaa48e7 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp @@ -593,7 +593,7 @@ never_inline s32 savedata_op(PPUThread& ppu, u32 operation, u32 version, vm::cpt fs::file file(local_path, fom::write | fom::create); file.seek(fileSet->fileOffset); fileGet->excSize = static_cast(file.write(fileSet->fileBuf.get_ptr(), std::min(fileSet->fileSize, fileSet->fileBufSize))); - file.trunc(file.seek(0, fsm::cur)); // truncate + file.trunc(file.seek(0, fs::seek_cur)); // truncate break; } diff --git a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp b/rpcs3/Emu/SysCalls/Modules/sys_net.cpp index 8fd4500e2a..238a53492b 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_net.cpp @@ -5,6 +5,8 @@ #include "sys_net.h" #ifdef _WIN32 +#undef _WIN32_WINNT +#define _WIN32_WINNT 0x0601 #include #include #else diff --git a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp index 3d6651480c..2576ebdf25 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp @@ -430,7 +430,7 @@ s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr pos) std::lock_guard lock(file->mutex); - *pos = file->file->Seek(offset, (fsm)whence); + *pos = file->file->Seek(offset, (fs::seek_mode)whence); return CELL_OK; } diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index b6b3859fd4..7a53f25d75 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -122,36 +122,31 @@ void Emulator::CreateConfig(const std::string& name) bool Emulator::BootGame(const std::string& path, bool direct) { - static const char* elf_path[6] = + static const char* boot_list[] = { "/PS3_GAME/USRDIR/BOOT.BIN", "/USRDIR/BOOT.BIN", "/BOOT.BIN", "/PS3_GAME/USRDIR/EBOOT.BIN", "/USRDIR/EBOOT.BIN", - "/EBOOT.BIN" + "/EBOOT.BIN", }; - auto curpath = path; - - if (direct) + if (direct && fs::is_file(path)) { - if (fs::is_file(curpath)) - { - SetPath(curpath); - Load(); + SetPath(path); + Load(); - return true; - } + return true; } - for (int i = 0; i < sizeof(elf_path) / sizeof(*elf_path); i++) + for (std::string elf : boot_list) { - curpath = path + elf_path[i]; - - if (fs::is_file(curpath)) + elf = path + elf; + + if (fs::is_file(elf)) { - SetPath(curpath); + SetPath(elf); Load(); return true; @@ -171,36 +166,28 @@ void Emulator::Load() return; } - const std::string elf_dir = m_path.substr(0, m_path.find_last_of("/\\", std::string::npos, 2) + 1); + const std::string& elf_dir = fs::get_parent_dir(m_path); if (IsSelf(m_path)) { - const std::string full_name = m_path.substr(elf_dir.length()); + const std::size_t elf_ext_pos = m_path.find_last_of('.'); + const std::string& elf_ext = fmt::toupper(m_path.substr(elf_ext_pos != -1 ? elf_ext_pos : m_path.size())); + const std::string& elf_name = m_path.substr(elf_dir.size()); - const std::string base_name = full_name.substr(0, full_name.find_last_of('.', std::string::npos)); - - const std::string ext = full_name.substr(base_name.length()); - - if (fmt::toupper(full_name) == "EBOOT.BIN") + if (elf_name.compare(elf_name.find_last_of("/\\", -1, 2) + 1, 9, "EBOOT.BIN", 9) == 0) { - m_path = elf_dir + "BOOT.BIN"; + m_path.erase(m_path.size() - 9, 1); // change EBOOT.BIN to BOOT.BIN } - else if (fmt::toupper(ext) == ".SELF") + else if (elf_ext == ".SELF" || elf_ext == ".SPRX") { - m_path = elf_dir + base_name + ".elf"; - } - else if (fmt::toupper(ext) == ".SPRX") - { - m_path = elf_dir + base_name + ".prx"; + m_path.erase(m_path.size() - 4, 1); // change *.self to *.elf, *.sprx to *.prx } else { - m_path = elf_dir + base_name + ".decrypted" + ext; + m_path += ".decrypted.elf"; } - LOG_NOTICE(LOADER, "Decrypting '%s%s'...", elf_dir, full_name); - - if (!DecryptSelf(m_path, elf_dir + full_name)) + if (!DecryptSelf(m_path, elf_dir + elf_name)) { m_status = Stopped; return; @@ -223,7 +210,7 @@ void Emulator::Load() Emu.GetVFS().Mount("/dev_bdvd/", bdvd, new vfsDeviceLocalFile()); } - else if (fs::is_file(elf_dir + "../../PS3_DISC.SFB")) // guess loading disc game + else if (fs::is_file(elf_dir + "/../../PS3_DISC.SFB")) // guess loading disc game { const auto dir_list = fmt::split(elf_dir, { "/", "\\" }); @@ -242,27 +229,6 @@ void Emulator::Load() LOG_NOTICE(LOADER, "%s -> %s", GetVFS().m_devices[i]->GetPs3Path().c_str(), GetVFS().m_devices[i]->GetLocalPath().c_str()); } - LOG_NOTICE(LOADER, ""); - - /*LOG_NOTICE(LOADER, "Settings:"); - LOG_NOTICE(LOADER, "CPU: %s", Ini.CPUIdToString(Ini.CPUDecoderMode.GetValue())); - LOG_NOTICE(LOADER, "SPU: %s", Ini.SPUIdToString(Ini.SPUDecoderMode.GetValue())); - LOG_NOTICE(LOADER, "Renderer: %s", Ini.RendererIdToString(Ini.GSRenderMode.GetValue())); - - if (Ini.GSRenderMode.GetValue() == 2) - { - LOG_NOTICE(LOADER, "D3D Adapter: %s", Ini.AdapterIdToString(Ini.GSD3DAdaptater.GetValue())); - } - - LOG_NOTICE(LOADER, "Resolution: %s", Ini.ResolutionIdToString(Ini.GSResolution.GetValue())); - LOG_NOTICE(LOADER, "Write Depth Buffer: %s", Ini.GSDumpDepthBuffer.GetValue() ? "Yes" : "No"); - LOG_NOTICE(LOADER, "Write Color Buffers: %s", Ini.GSDumpColorBuffers.GetValue() ? "Yes" : "No"); - LOG_NOTICE(LOADER, "Read Color Buffers: %s", Ini.GSReadColorBuffers.GetValue() ? "Yes" : "No"); - LOG_NOTICE(LOADER, "Read Depth Buffer: %s", Ini.GSReadDepthBuffer.GetValue() ? "Yes" : "No"); - LOG_NOTICE(LOADER, "Audio Out: %s", Ini.AudioOutIdToString(Ini.AudioOutMode.GetValue())); - LOG_NOTICE(LOADER, "Log Everything: %s", Ini.HLELogging.GetValue() ? "Yes" : "No"); - LOG_NOTICE(LOADER, "RSX Logging: %s", Ini.RSXLogging.GetValue() ? "Yes" : "No");*/ - LOG_NOTICE(LOADER, ""); f.Open("/app_home/../PARAM.SFO"); const PSFLoader psf(f); @@ -505,11 +471,11 @@ void Emulator::SavePoints(const std::string& path) 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; + .write(bpdb_version) + .write(break_count) + .write(marked_count) + .write(m_break_points) + .write(m_marked_points); } bool Emulator::LoadPoints(const std::string& path) diff --git a/rpcs3/Emu/events.cpp b/rpcs3/Emu/events.cpp index e02d4f56f4..333a065528 100644 --- a/rpcs3/Emu/events.cpp +++ b/rpcs3/Emu/events.cpp @@ -7,4 +7,4 @@ namespace rpcs3 event onstart; event onstop; event onpause; -} \ No newline at end of file +} diff --git a/rpcs3/Emu/state.h b/rpcs3/Emu/state.h index 08475ba818..fd7db03d03 100644 --- a/rpcs3/Emu/state.h +++ b/rpcs3/Emu/state.h @@ -1,4 +1,5 @@ #pragma once + #include "config.h" namespace rpcs3 diff --git a/rpcs3/GLGSRender.vcxproj b/rpcs3/GLGSRender.vcxproj index e47df409ab..45cd8a0696 100644 --- a/rpcs3/GLGSRender.vcxproj +++ b/rpcs3/GLGSRender.vcxproj @@ -61,55 +61,6 @@ - - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - - - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - - - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - - - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - - - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - - - - true - - - - - true - - - - - - - true - - - - - true - - - - - true - - - - {c4a10229-4712-4bd2-b63e-50d93c67a038} diff --git a/rpcs3/Gui/CgDisasm.h b/rpcs3/Gui/CgDisasm.h index ed5917f5ee..97569fffb1 100644 --- a/rpcs3/Gui/CgDisasm.h +++ b/rpcs3/Gui/CgDisasm.h @@ -1,7 +1,5 @@ #pragma once -#include - enum CgDisasmIds { id_open_file, @@ -22,4 +20,4 @@ public: virtual void OnSize(wxSizeEvent& event); void OnRightClick(wxMouseEvent& event); void OnContextMenu(wxCommandEvent& event); -}; \ No newline at end of file +}; diff --git a/rpcs3/Gui/ConLogFrame.cpp b/rpcs3/Gui/ConLogFrame.cpp index 5035af4c37..51d2f3f440 100644 --- a/rpcs3/Gui/ConLogFrame.cpp +++ b/rpcs3/Gui/ConLogFrame.cpp @@ -1,9 +1,6 @@ #include "stdafx.h" #include "stdafx_gui.h" -#include -#include - #include "Emu/state.h" #include "Gui/ConLogFrame.h" @@ -204,4 +201,4 @@ void LogFrame::OnContextMenu(wxCommandEvent& event) default: event.Skip(); } -} \ No newline at end of file +} diff --git a/rpcs3/Gui/ConLogFrame.h b/rpcs3/Gui/ConLogFrame.h index cecff5fcf0..e0d5a19231 100644 --- a/rpcs3/Gui/ConLogFrame.h +++ b/rpcs3/Gui/ConLogFrame.h @@ -1,5 +1,4 @@ #pragma once -#include namespace Log { @@ -31,4 +30,4 @@ private: void OnContextMenu(wxCommandEvent& event); //After select DECLARE_EVENT_TABLE(); -}; \ No newline at end of file +}; diff --git a/rpcs3/Gui/Debugger.cpp b/rpcs3/Gui/Debugger.cpp index 6465bb5334..4cf58bea0d 100644 --- a/rpcs3/Gui/Debugger.cpp +++ b/rpcs3/Gui/Debugger.cpp @@ -1,6 +1,5 @@ #include "stdafx.h" #include "stdafx_gui.h" -#include #include "Emu/Memory/Memory.h" #include "Emu/System.h" diff --git a/rpcs3/Gui/GLGSFrame.cpp b/rpcs3/Gui/GLGSFrame.cpp index cab168daae..908d454c36 100644 --- a/rpcs3/Gui/GLGSFrame.cpp +++ b/rpcs3/Gui/GLGSFrame.cpp @@ -41,4 +41,4 @@ void GLGSFrame::OnSize(wxSizeEvent& event) m_canvas->SetSize(GetClientSize()); event.Skip(); -} \ No newline at end of file +} diff --git a/rpcs3/Gui/GameViewer.cpp b/rpcs3/Gui/GameViewer.cpp index 43bbe23d3d..f7daacf769 100644 --- a/rpcs3/Gui/GameViewer.cpp +++ b/rpcs3/Gui/GameViewer.cpp @@ -9,7 +9,6 @@ #include "GameViewer.h" #include "Loader/PSF.h" #include "SettingsDialog.h" -#include static const std::string m_class_name = "GameViewer"; diff --git a/rpcs3/Gui/GameViewer.h b/rpcs3/Gui/GameViewer.h index e7cd287ed2..193ac2d418 100644 --- a/rpcs3/Gui/GameViewer.h +++ b/rpcs3/Gui/GameViewer.h @@ -1,7 +1,5 @@ #pragma once -#include -#include -#include + #include "Emu/GameInfo.h" #include "Emu/state.h" diff --git a/rpcs3/Gui/KernelExplorer.h b/rpcs3/Gui/KernelExplorer.h index 195fe52cdd..723b66c0a5 100644 --- a/rpcs3/Gui/KernelExplorer.h +++ b/rpcs3/Gui/KernelExplorer.h @@ -1,7 +1,5 @@ #pragma once -#include - class KernelExplorer : public wxDialog { wxTreeCtrl* m_tree; diff --git a/rpcs3/Gui/LLEModulesManager.h b/rpcs3/Gui/LLEModulesManager.h index c95516e393..22a1c1cea4 100644 --- a/rpcs3/Gui/LLEModulesManager.h +++ b/rpcs3/Gui/LLEModulesManager.h @@ -1,6 +1,6 @@ #pragma once + #include "Gui/FrameBase.h" -#include class LLEModulesManagerFrame : public wxDialog { diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 5f9be47e18..64bacd7257 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -24,8 +24,6 @@ #include "Gui/LLEModulesManager.h" #include "Gui/CgDisasm.h" #include "Crypto/unpkg.h" -#include -#include #ifndef _WIN32 #include "frame_icon.xpm" @@ -255,7 +253,7 @@ void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event)) fs::file pkg_f(ctrl.GetPath().ToStdString()); // Open file mapping (test) - fs::file_ptr pkg_ptr(pkg_f); + fs::file_read_map pkg_ptr(pkg_f); if (!pkg_f || !pkg_ptr) { @@ -265,7 +263,7 @@ void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event)) // Append title ID to the path local_path += '/'; - local_path += { pkg_ptr + 55, 9 }; + local_path.append(pkg_ptr + 55, 9); if (!fs::create_dir(local_path)) { @@ -289,7 +287,7 @@ void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event)) volatile f64 progress = 0.0; // Run PKG unpacking asynchronously - auto result = std::async(std::launch::async, WRAP_EXPR(pkg_install(pkg_f, local_path + "/", progress))); + auto result = std::async(std::launch::async, WRAP_EXPR(pkg_install(pkg_f, local_path + '/', progress))); // Wait for the completion while (result.wait_for(15ms) != std::future_status::ready) diff --git a/rpcs3/Gui/MainFrame.h b/rpcs3/Gui/MainFrame.h index 9477e082a2..cd9f68589d 100644 --- a/rpcs3/Gui/MainFrame.h +++ b/rpcs3/Gui/MainFrame.h @@ -4,8 +4,6 @@ #include "Gui/ConLogFrame.h" #include "Gui/FrameBase.h" -#include - class GameViewer; class MainFrame : public FrameBase diff --git a/rpcs3/Gui/MemoryStringSearcher.cpp b/rpcs3/Gui/MemoryStringSearcher.cpp index 184cce2c99..88f129f662 100644 --- a/rpcs3/Gui/MemoryStringSearcher.cpp +++ b/rpcs3/Gui/MemoryStringSearcher.cpp @@ -6,8 +6,6 @@ #include "MemoryStringSearcher.h" -#include - MemoryStringSearcher::MemoryStringSearcher(wxWindow* parent) : wxDialog(parent, wxID_ANY, "String Searcher", wxDefaultPosition, wxSize(545, 64)) , exit(false) diff --git a/rpcs3/Gui/MemoryStringSearcher.h b/rpcs3/Gui/MemoryStringSearcher.h index 109b4d761c..5edb7dc18d 100644 --- a/rpcs3/Gui/MemoryStringSearcher.h +++ b/rpcs3/Gui/MemoryStringSearcher.h @@ -1,5 +1,4 @@ #pragma once -#include class MemoryStringSearcher : public wxDialog { diff --git a/rpcs3/Gui/MemoryViewer.h b/rpcs3/Gui/MemoryViewer.h index 877dd7a3b6..e0637a3ad2 100644 --- a/rpcs3/Gui/MemoryViewer.h +++ b/rpcs3/Gui/MemoryViewer.h @@ -1,7 +1,5 @@ #pragma once -#include - class MemoryViewerPanel : public wxDialog { u32 m_addr; diff --git a/rpcs3/Gui/RSXDebugger.cpp b/rpcs3/Gui/RSXDebugger.cpp index 5eefb3752d..6f8602af62 100644 --- a/rpcs3/Gui/RSXDebugger.cpp +++ b/rpcs3/Gui/RSXDebugger.cpp @@ -15,8 +15,6 @@ #include "MemoryViewer.h" -#include - // TODO: Clear the object when restarting the emulator std::vector m_debug_programs; @@ -569,7 +567,7 @@ void RSXDebugger::GetMemory() dump += '\n'; } - fs::file(fs::get_config_dir() + "command_dump.log", fom::rewrite) << dump; + fs::file(fs::get_config_dir() + "command_dump.log", fom::rewrite).write(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/RSXDebugger.h b/rpcs3/Gui/RSXDebugger.h index c0baafe715..26074a6561 100644 --- a/rpcs3/Gui/RSXDebugger.h +++ b/rpcs3/Gui/RSXDebugger.h @@ -1,7 +1,5 @@ #pragma once -#include - class RSXDebugger : public wxDialog { u32 m_addr; diff --git a/rpcs3/Gui/SettingsDialog.cpp b/rpcs3/Gui/SettingsDialog.cpp index 4827f640d4..a8ca4a3cc6 100644 --- a/rpcs3/Gui/SettingsDialog.cpp +++ b/rpcs3/Gui/SettingsDialog.cpp @@ -5,7 +5,6 @@ #include "Emu/state.h" #include "Emu/SysCalls/Modules/cellVideoOut.h" #include "SettingsDialog.h" -#include #ifdef _WIN32 #include diff --git a/rpcs3/Gui/VHDDManager.cpp b/rpcs3/Gui/VHDDManager.cpp index 81ff563985..740d697f38 100644 --- a/rpcs3/Gui/VHDDManager.cpp +++ b/rpcs3/Gui/VHDDManager.cpp @@ -3,7 +3,6 @@ #include "VHDDManager.h" #include "TextInputDialog.h" #include "Emu/state.h" -#include VHDDListDropTarget::VHDDListDropTarget(wxListView* parent) : m_parent(parent) { diff --git a/rpcs3/Gui/VHDDManager.h b/rpcs3/Gui/VHDDManager.h index ee9f8d128f..6cd2614f13 100644 --- a/rpcs3/Gui/VHDDManager.h +++ b/rpcs3/Gui/VHDDManager.h @@ -1,5 +1,5 @@ #pragma once -#include + #include "Emu/HDD/HDD.h" class VHDDListDropTarget : public wxDropTarget diff --git a/rpcs3/Loader/TROPUSR.cpp b/rpcs3/Loader/TROPUSR.cpp index 3ae1e603cc..4867bbc313 100644 --- a/rpcs3/Loader/TROPUSR.cpp +++ b/rpcs3/Loader/TROPUSR.cpp @@ -239,14 +239,12 @@ bool TROPUSRLoader::UnlockTrophy(u32 id, u64 timestamp1, u64 timestamp2) return true; } -bool TROPUSRLoader::Close() +void TROPUSRLoader::Close() { - if (m_file && m_file->Close()) + if (m_file) { + m_file->Close(); delete m_file; m_file = nullptr; - return true; } - - return false; } diff --git a/rpcs3/Loader/TROPUSR.h b/rpcs3/Loader/TROPUSR.h index 75c7660192..e3d2921aae 100644 --- a/rpcs3/Loader/TROPUSR.h +++ b/rpcs3/Loader/TROPUSR.h @@ -74,7 +74,7 @@ public: virtual bool Load(const std::string& filepath, const std::string& configpath); virtual bool Save(const std::string& filepath); - virtual bool Close(); + virtual void Close(); virtual u32 GetTrophiesCount(); diff --git a/rpcs3/Loader/TRP.cpp b/rpcs3/Loader/TRP.cpp index fed01da031..2a8123cf55 100644 --- a/rpcs3/Loader/TRP.cpp +++ b/rpcs3/Loader/TRP.cpp @@ -124,7 +124,7 @@ void TRPLoader::RenameEntry(const char *oldname, const char *newname) } } -bool TRPLoader::Close() +void TRPLoader::Close() { - return trp_f.Close(); + trp_f.Close(); } diff --git a/rpcs3/Loader/TRP.h b/rpcs3/Loader/TRP.h index 006df5f18e..f2818ad525 100644 --- a/rpcs3/Loader/TRP.h +++ b/rpcs3/Loader/TRP.h @@ -39,5 +39,5 @@ public: virtual void RemoveEntry(const char *filename); virtual void RenameEntry(const char *oldname, const char *newname); - virtual bool Close(); + virtual void Close(); }; diff --git a/rpcs3/OpenAL.vcxproj b/rpcs3/OpenAL.vcxproj index e9cf287205..3989b340ff 100644 --- a/rpcs3/OpenAL.vcxproj +++ b/rpcs3/OpenAL.vcxproj @@ -62,54 +62,9 @@ - - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - - - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - - - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - - - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - - - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - - + .\OpenAL\include;%(AdditionalIncludeDirectories) - true - - - - - .\OpenAL\include;%(AdditionalIncludeDirectories) - true - - - - - .\OpenAL\include;%(AdditionalIncludeDirectories) - true - - - - - .\OpenAL\include;%(AdditionalIncludeDirectories) - true - - - - - .\OpenAL\include;%(AdditionalIncludeDirectories) - true diff --git a/rpcs3/XAudio.vcxproj b/rpcs3/XAudio.vcxproj index 3e2b6a28eb..93488ac8c0 100644 --- a/rpcs3/XAudio.vcxproj +++ b/rpcs3/XAudio.vcxproj @@ -61,55 +61,11 @@ - - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - - - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - - - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - - + ..\minidx9\Include;%(AdditionalIncludeDirectories) - - - ..\minidx9\Include;%(AdditionalIncludeDirectories) - - - - - ..\minidx9\Include;%(AdditionalIncludeDirectories) - - - - - ..\minidx9\Include;%(AdditionalIncludeDirectories) - - - - - ..\minidx9\Include;%(AdditionalIncludeDirectories) - - - - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - - - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - - - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - {c4a10229-4712-4bd2-b63e-50d93c67a038} diff --git a/rpcs3/XAudio.vcxproj.filters b/rpcs3/XAudio.vcxproj.filters index 6b96905421..793c486f62 100644 --- a/rpcs3/XAudio.vcxproj.filters +++ b/rpcs3/XAudio.vcxproj.filters @@ -1,19 +1,19 @@  - + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx - Fichiers sources + Source Files - Fichiers sources + Source Files \ No newline at end of file diff --git a/rpcs3/config.cpp b/rpcs3/config.cpp index 745509ba11..270ecc8567 100644 --- a/rpcs3/config.cpp +++ b/rpcs3/config.cpp @@ -34,12 +34,12 @@ namespace rpcs3 fs::file file(m_path, fom::create | fom::read); if (file) - from_string((const std::string)file); + from_string(file.to_string()); } void config_t::save() const { - fs::file(m_path, fom::rewrite) << to_string(); + fs::file(m_path, fom::rewrite).write(to_string()); } config_t config{ fs::get_config_dir() + "rpcs3.new.ini" }; diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 92f54a1b3b..6515b0beb8 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -58,47 +58,8 @@ - - - true - - - false - - - - - true - - - true - - - - - true - - - false - - - - - true - - - true - - - - - true - - - false - - + @@ -150,11 +111,7 @@ - NotUsing - NotUsing - NotUsing - NotUsing - NotUsing + NotUsing @@ -391,15 +348,13 @@ + - Create - Create - Create - Create - Create + Create + @@ -686,26 +641,6 @@ - - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - - - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - - - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - - - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - - - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - $(SolutionDir)lib\$(Configuration)-$(Platform)\ - diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 8ea7f0719f..61dc63dbf8 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -930,6 +930,9 @@ Emu\GPU\RSX + + Source Files + Source Files @@ -1788,5 +1791,11 @@ Emu\GPU\RSX + + Header Files + + + Source Files + \ No newline at end of file diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 9ea6039805..c6db0d280e 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -61,43 +61,26 @@ - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath);..\minidx12\Include $(SolutionDir)bin\ - $(SolutionDir)lib\$(Configuration)-$(Platform)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath) $(ProjectName)-dbg - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath);..\minidx12\Include $(SolutionDir)bin\ - $(SolutionDir)lib\$(Configuration)-$(Platform)\;$(SolutionDir)lib\Debug-$(Platform)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath);$(SolutionDir)lib\$(Configuration)-$(Platform)\ $(ProjectName)-dbg - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(UniversalCRT_IncludePath);$(IncludePath);..\minidx12\Include $(SolutionDir)bin\ - $(SolutionDir)lib\$(Configuration)-$(Platform)\;$(SolutionDir)lib\Debug-$(Platform)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath);$(SolutionDir)lib\$(Configuration)-$(Platform)\ $(ProjectName)-dbg - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - false - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath);..\minidx12\Include $(SolutionDir)bin\ - $(SolutionDir)lib\$(Configuration)-$(Platform)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath) false false - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ - false - .\;..\wxWidgets\include;..\SDL-1.3.0-5538\include;..\SDL_image-1.2.10;..\pthreads-2.8.0;..\;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;.\OpenAL\include;$(IncludePath);..\asmjit\src\asmjit;$(UniversalCRT_IncludePath);..\minidx12\Include $(SolutionDir)bin\ - $(SolutionDir)lib\$(Configuration)-$(Platform)\;$(SolutionDir)lib\Release-$(Platform)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath) false false - $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ @@ -108,34 +91,10 @@ false - ..\minidx9\Include;..\OpenAL\include;%(AdditionalIncludeDirectories) - - - ..\minidx9\Include;..\OpenAL\include;%(AdditionalIncludeDirectories) - - - ..\minidx9\Include;..\OpenAL\include;%(AdditionalIncludeDirectories) - - - ..\minidx9\Include;..\OpenAL\include;%(AdditionalIncludeDirectories) - - - ..\minidx9\Include;..\OpenAL\include;%(AdditionalIncludeDirectories) + ..\minidx9\Include;..\OpenAL\include;%(AdditionalIncludeDirectories) - ..\OpenAL\libs\Win64;%(AdditionalLibraryDirectories) - - - ..\OpenAL\libs\Win64;%(AdditionalLibraryDirectories) - - - ..\OpenAL\libs\Win64;%(AdditionalLibraryDirectories) - - - ..\OpenAL\libs\Win64;%(AdditionalLibraryDirectories) - - - ..\OpenAL\libs\Win64;%(AdditionalLibraryDirectories) + ..\OpenAL\libs\Win64;%(AdditionalLibraryDirectories) diff --git a/rpcs3/stb_image.cpp b/rpcs3/stb_image.cpp new file mode 100644 index 0000000000..144dbdd192 --- /dev/null +++ b/rpcs3/stb_image.cpp @@ -0,0 +1,9 @@ +#include "stdafx.h" + +extern "C" +{ +#pragma warning(push, 0) +#include "stblib/stb_image.h" +#include "stblib/stb_image.c" +#pragma warning(pop) +} diff --git a/rpcs3/stdafx.h b/rpcs3/stdafx.h index 088bc9fc2d..372a5d94c6 100644 --- a/rpcs3/stdafx.h +++ b/rpcs3/stdafx.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -78,7 +79,7 @@ public: { } - operator bool() const //template::value>> operator T() const + operator bool() const { return m_value != 0; } @@ -86,13 +87,15 @@ public: CHECK_SIZE_ALIGN(b8, 1, 1); -template::value>> inline T align(const T& value, u64 align) +template::value>> +inline T align(const T& value, u64 align) { return static_cast((value + (align - 1)) & ~(align - 1)); } // copy null-terminated string from std::string to char array with truncation -template inline void strcpy_trunc(char(&dst)[N], const std::string& src) +template +inline void strcpy_trunc(char(&dst)[N], const std::string& src) { const std::size_t count = src.size() >= N ? N - 1 : src.size(); std::memcpy(dst, src.c_str(), count); @@ -100,7 +103,8 @@ template inline void strcpy_trunc(char(&dst)[N], const std::strin } // copy null-terminated string from char array to char array with truncation -template inline void strcpy_trunc(char(&dst)[N], const char(&src)[N2]) +template +inline void strcpy_trunc(char(&dst)[N], const char(&src)[N2]) { const std::size_t count = N2 >= N ? N - 1 : N2; std::memcpy(dst, src, count); @@ -108,13 +112,15 @@ template inline void strcpy_trunc(char(&dst)[N], } // returns true if all array elements are unique and sorted in ascending order -template constexpr bool is_ascending(const T(&array)[N], std::size_t from = 0) +template +constexpr bool is_ascending(const T(&array)[N], std::size_t from = 0) { return from >= N - 1 ? true : array[from] < array[from + 1] ? is_ascending(array, from + 1) : false; } // get (first) array element equal to `value` or nullptr if not found -template constexpr const T* static_search(const T(&array)[N], const T2& value, std::size_t from = 0) +template +constexpr const T* static_search(const T(&array)[N], const T2& value, std::size_t from = 0) { return from >= N ? nullptr : array[from] == value ? array + from : static_search(array, value, from + 1); } @@ -135,7 +141,8 @@ struct explicit_bool_t } }; -template struct triplet_t +template +struct triplet_t { T1 first; T2 second; @@ -154,18 +161,28 @@ template struct triplet_t #define alignof32(type) static_cast(alignof(type)) // return 32 bit .size() for container -template inline auto size32(const T& container) -> decltype(static_cast(container.size())) +template +inline auto size32(const T& container) -> decltype(static_cast(container.size())) { const auto size = container.size(); return size >= 0 && size <= UINT32_MAX ? static_cast(size) : throw std::length_error(__FUNCTION__); } // return 32 bit size for an array -template constexpr u32 size32(const T(&)[Size]) +template +constexpr u32 size32(const T(&)[Size]) { return Size >= 0 && Size <= UINT32_MAX ? static_cast(Size) : throw std::length_error(__FUNCTION__); } +#define CONCATENATE_DETAIL(x, y) x ## y +#define CONCATENATE(x, y) CONCATENATE_DETAIL(x, y) + +#define SWITCH(expr) for (const auto& CONCATENATE(_switch_, __LINE__) = (expr);;) { const auto& _switch_ = CONCATENATE(_switch_, __LINE__); +#define CCASE(value) } constexpr std::remove_reference_t CONCATENATE(_value_, __LINE__) = value; if (_switch_ == CONCATENATE(_value_, __LINE__)) { +#define VCASE(value) } if (_switch_ == (value)) { +#define DEFAULT } /* must be the last one */ + #define WRAP_EXPR(expr) [&]{ return expr; } #define COPY_EXPR(expr) [=]{ return expr; } #define PURE_EXPR(expr) [] { return expr; } @@ -174,8 +191,8 @@ template constexpr u32 size32(const T(&)[Size]) #define IS_INTEGRAL(t) (std::is_integral::value || std::is_same, u128>::value) #define IS_INTEGER(t) (std::is_integral::value || std::is_enum::value || std::is_same, u128>::value) #define IS_BINARY_COMPARABLE(t1, t2) (IS_INTEGER(t1) && IS_INTEGER(t2) && sizeof(t1) == sizeof(t2)) -#define CHECK_ASSERTION(expr) if (expr) {} else throw EXCEPTION("Assertion failed: " #expr) -#define CHECK_SUCCESS(expr) if (s32 _r = (expr)) throw EXCEPTION(#expr " failed (0x%x)", _r) +#define CHECK_ASSERTION(expr) if (expr) {} else throw EXCEPTION("Assertion failed: %s", #expr) +#define CHECK_SUCCESS(expr) if (s32 _r = (expr)) throw EXCEPTION("Failure: %s -> 0x%x", #expr, _r) // Some forward declarations for the ID manager template struct id_traits; diff --git a/rpcs3/stdafx_gui.h b/rpcs3/stdafx_gui.h index c005be3999..158a599ba9 100644 --- a/rpcs3/stdafx_gui.h +++ b/rpcs3/stdafx_gui.h @@ -3,9 +3,13 @@ #include "restore_new.h" #ifndef QT_UI + #ifdef _MSC_VER #pragma warning(push, 0) +#else +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif +#include #include #include #include @@ -22,12 +26,26 @@ #include #include #include +#include #include #include #include #include +#include #include +#include +#include +#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include #ifdef _MSC_VER #pragma warning(pop) #endif diff --git a/rpcs3_default.props b/rpcs3_default.props index 1bad9556b8..4a097de958 100644 --- a/rpcs3_default.props +++ b/rpcs3_default.props @@ -2,8 +2,15 @@ - + + $(SolutionDir)lib\$(Configuration)-$(Platform)\ + $(SolutionDir)lib\$(Configuration)-$(Platform)\;$(UniversalCRT_LibraryPath_x64);$(LibraryPath) + $(SolutionDir)tmp\$(ProjectName)-$(Configuration)-$(Platform)\ + + + true + true .\;..\;..\asmjit\src\asmjit;..\wxWidgets\include\msvc;..\wxWidgets\include;..\ffmpeg\WindowsInclude;..\ffmpeg\Windows\x86_64\Include;$(VC_IncludePath);$(WindowsSDK_IncludePath);..\llvm\include;..\llvm_build\include;$(UniversalCRT_IncludePath);..\minidx12\Include;..\glm;..\GSL\include