diff --git a/Utilities/AutoPause.cpp b/Utilities/AutoPause.cpp index b1e4c3ed0a..8ef5af6627 100644 --- a/Utilities/AutoPause.cpp +++ b/Utilities/AutoPause.cpp @@ -2,7 +2,7 @@ #include "rpcs3/Ini.h" #include "AutoPause.h" #include "Utilities/Log.h" -#include "Utilities/rFile.h" +#include "Utilities/File.h" #include "Emu/System.h" using namespace Debug; @@ -44,23 +44,22 @@ AutoPause::~AutoPause(void) //This would be able to create in a GUI window. void AutoPause::Reload(void) { - if (rExists("pause.bin")) + if (fs::is_file("pause.bin")) { m_pause_function.clear(); m_pause_function.reserve(16); m_pause_syscall.clear(); m_pause_syscall.reserve(16); - rFile list; - list.Open("pause.bin", rFile::read); + fs::file list("pause.bin"); //System calls ID and Function calls ID are all u32 iirc. u32 num; - size_t fmax = list.Length(); + size_t fmax = list.size(); size_t fcur = 0; - list.Seek(0); + list.seek(0); while (fcur <= fmax - sizeof(u32)) { - list.Read(&num, sizeof(u32)); + list.read(&num, sizeof(u32)); fcur += sizeof(u32); if (num == 0xFFFFFFFF) break; @@ -77,12 +76,8 @@ void AutoPause::Reload(void) LOG_WARNING(HLE, "Auto Pause: Find Function Call ID 0x%x", num); } } - list.Close(); - } - else - { - LOG_WARNING(HLE, "No pause.bin found, Auto Pause will not work."); } + m_pause_syscall_enable = Ini.DBGAutoPauseSystemCall.GetValue(); m_pause_function_enable = Ini.DBGAutoPauseFunctionCall.GetValue(); initialized = true; @@ -125,4 +120,4 @@ void AutoPause::TryPause(u32 code) { } } } -} \ No newline at end of file +} diff --git a/Utilities/BEType.h b/Utilities/BEType.h index 96ef78f59d..ec2ba15605 100644 --- a/Utilities/BEType.h +++ b/Utilities/BEType.h @@ -879,90 +879,6 @@ template struct _se, T1, value> : pub #define se32(x) _se::value #define se64(x) _se::value -template __forceinline u8 Read8(T& f) -{ - u8 ret; - f.Read(&ret, sizeof(ret)); - return ret; -} - -template __forceinline u16 Read16(T& f) -{ - be_t ret; - f.Read(&ret, sizeof(ret)); - return ret; -} - -template __forceinline u32 Read32(T& f) -{ - be_t ret; - f.Read(&ret, sizeof(ret)); - return ret; -} - -template __forceinline u64 Read64(T& f) -{ - be_t ret; - f.Read(&ret, sizeof(ret)); - return ret; -} - -template __forceinline u16 Read16LE(T& f) -{ - u16 ret; - f.Read(&ret, sizeof(ret)); - return ret; -} - -template __forceinline u32 Read32LE(T& f) -{ - u32 ret; - f.Read(&ret, sizeof(ret)); - return ret; -} - -template __forceinline u64 Read64LE(T& f) -{ - u64 ret; - f.Read(&ret, sizeof(ret)); - return ret; -} - -template __forceinline void Write8(T& f, const u8 data) -{ - f.Write(&data, sizeof(data)); -} - -template __forceinline void Write16LE(T& f, const u16 data) -{ - f.Write(&data, sizeof(data)); -} - -template __forceinline void Write32LE(T& f, const u32 data) -{ - f.Write(&data, sizeof(data)); -} - -template __forceinline void Write64LE(T& f, const u64 data) -{ - f.Write(&data, sizeof(data)); -} - -template __forceinline void Write16(T& f, const u16 data) -{ - Write16LE(f, re16(data)); -} - -template __forceinline void Write32(T& f, const u32 data) -{ - Write32LE(f, re32(data)); -} - -template __forceinline void Write64(T& f, const u64 data) -{ - Write64LE(f, re64(data)); -} - template struct convert_le_be_t { diff --git a/Utilities/File.cpp b/Utilities/File.cpp new file mode 100644 index 0000000000..b96d00f187 --- /dev/null +++ b/Utilities/File.cpp @@ -0,0 +1,672 @@ +#include "stdafx.h" +#include "Log.h" +#pragma warning(push) +#pragma message("TODO: remove wx dependency: ") +#pragma warning(disable : 4996) +#include +#pragma warning(pop) +#include "File.h" + +#ifdef _WIN32 +#include + +#define GET_API_ERROR static_cast(GetLastError()) + +std::unique_ptr ConvertUTF8ToWChar(const std::string& source) +{ + const size_t length = source.size() + 1; // size + null terminator + + const int size = source.size() < INT_MAX ? static_cast(length) : throw std::length_error(__FUNCTION__); + + std::unique_ptr buffer(new wchar_t[length]); // allocate buffer assuming that length is the max possible size + + if (!MultiByteToWideChar(CP_UTF8, 0, source.c_str(), size, buffer.get(), size)) + { + LOG_ERROR(GENERAL, "ConvertUTF8ToWChar(source='%s') failed: 0x%llx", source, GET_API_ERROR); + } + + return buffer; +} + +time_t to_time_t(const ULARGE_INTEGER& ft) +{ + return ft.QuadPart / 10000000ULL - 11644473600ULL; +} + +time_t to_time_t(const LARGE_INTEGER& ft) +{ + ULARGE_INTEGER v; + v.LowPart = ft.LowPart; + v.HighPart = ft.HighPart; + + return to_time_t(v); +} + +time_t to_time_t(const FILETIME& ft) +{ + ULARGE_INTEGER v; + v.LowPart = ft.dwLowDateTime; + v.HighPart = ft.dwHighDateTime; + + return to_time_t(v); +} + +bool truncate_file(const std::string& file, uint64_t length) +{ + // open the file + const auto handle = CreateFileW(ConvertUTF8ToWChar(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 +#include +#if defined(__APPLE__) || defined(__FreeBSD__) +#include +#else +#include +#endif +#include "errno.h" + +#define GET_API_ERROR static_cast(errno) + +#endif + +bool fs::stat(const std::string& path, stat_t& info) +{ +#ifdef _WIN32 + WIN32_FILE_ATTRIBUTE_DATA attrs; + if (!GetFileAttributesExW(ConvertUTF8ToWChar(path).get(), GetFileExInfoStandard, &attrs)) + { + info = {}; + return false; + } + + info.exists = true; + info.is_directory = (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; + info.is_writable = (attrs.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0; + info.size = (uint64_t)attrs.nFileSizeLow | ((uint64_t)attrs.nFileSizeHigh << 32); + info.atime = to_time_t(attrs.ftLastAccessTime); + info.mtime = to_time_t(attrs.ftLastWriteTime); + info.ctime = to_time_t(attrs.ftCreationTime); +#else + struct stat64 file_info; + if (stat64(path.c_str(), &file_info) < 0) + { + info = {}; + return false; + } + + info.exists = true; + info.is_directory = S_ISDIR(file_info.st_mode); + info.is_writable = file_info.st_mode & 0200; // HACK: approximation + info.size = file_info.st_size; + info.atime = file_info.st_atime; + info.mtime = file_info.st_mtime; + info.ctime = file_info.st_ctime; +#endif + return true; +} + +bool fs::exists(const std::string& path) +{ +#ifdef _WIN32 + return GetFileAttributesW(ConvertUTF8ToWChar(path).get()) != 0xFFFFFFFF; +#else + struct stat buffer; + return stat(path.c_str(), &buffer) == 0; +#endif +} + +bool fs::is_file(const std::string& file) +{ +#ifdef _WIN32 + DWORD attrs; + if ((attrs = GetFileAttributesW(ConvertUTF8ToWChar(file).get())) == INVALID_FILE_ATTRIBUTES) + { + return false; + } + + return (attrs & FILE_ATTRIBUTE_DIRECTORY) == 0; +#else + struct stat64 file_info; + if (stat64(file.c_str(), &file_info) < 0) + { + return false; + } + + return !S_ISDIR(file_info.st_mode); +#endif +} + +bool fs::is_dir(const std::string& dir) +{ +#ifdef _WIN32 + DWORD attrs; + if ((attrs = GetFileAttributesW(ConvertUTF8ToWChar(dir).get())) == INVALID_FILE_ATTRIBUTES) + { + return false; + } + + return (attrs & FILE_ATTRIBUTE_DIRECTORY) != 0; +#else + struct stat64 file_info; + if (stat64(dir.c_str(), &file_info) < 0) + { + return false; + } + + return S_ISDIR(file_info.st_mode); +#endif +} + +bool fs::create_dir(const std::string& dir) +{ +#ifdef _WIN32 + if (!CreateDirectoryW(ConvertUTF8ToWChar(dir).get(), NULL)) +#else + if (mkdir(dir.c_str(), 0777)) +#endif + { + LOG_WARNING(GENERAL, "Error creating directory '%s': 0x%llx", dir, GET_API_ERROR); + return false; + } + + return true; +} + +bool fs::create_path(const std::string& path) +{ + size_t start = 0; + + while (true) + { + // maybe it could be more optimal if goes from the end recursively + size_t pos = path.find_first_of("/\\", start); + + if (pos == std::string::npos) + { + pos = path.length(); + } + + std::string dir = path.substr(0, pos); + + start = ++pos; + + if (dir.size() == 0) + { + continue; + } + + if (!is_dir(dir)) + { + // if doesn't exist or not a dir + if (!create_dir(dir)) + { + // if creating failed + return false; + } + } + + if (pos >= path.length()) + { + break; + } + } + + return true; +} + +bool fs::remove_dir(const std::string& dir) +{ +#ifdef _WIN32 + if (!RemoveDirectoryW(ConvertUTF8ToWChar(dir).get())) +#else + if (rmdir(dir.c_str())) +#endif + { + LOG_WARNING(GENERAL, "Error deleting directory '%s': 0x%llx", dir, GET_API_ERROR); + return false; + } + + return true; +} + +bool fs::rename(const std::string& from, const std::string& to) +{ + // TODO: Deal with case-sensitivity +#ifdef _WIN32 + if (!MoveFileW(ConvertUTF8ToWChar(from).get(), ConvertUTF8ToWChar(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); + return false; + } + + return true; +} + +#ifndef _WIN32 + +int OSCopyFile(const char* source, const char* destination, bool overwrite) +{ + /* This function was taken from http://stackoverflow.com/questions/2180079/how-can-i-copy-a-file-on-unix-using-c */ + + int input, output; + if ((input = open(source, O_RDONLY)) == -1) + { + return -1; + } + if ((output = open(destination, O_WRONLY | O_CREAT | (overwrite ? O_TRUNC : O_EXCL), 0666)) == -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+ + 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 }; + fstat(input, &fileinfo); + int result = sendfile(output, input, &bytesCopied, fileinfo.st_size) == -1 ? -1 : 0; +#endif + + close(input); + close(output); + + return result; +} +#endif + +bool fs::copy_file(const std::string& from, const std::string& to, bool overwrite) +{ +#ifdef _WIN32 + if (!CopyFileW(ConvertUTF8ToWChar(from).get(), ConvertUTF8ToWChar(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); + return false; + } + + return true; +} + +bool fs::remove_file(const std::string& file) +{ +#ifdef _WIN32 + if (!DeleteFileW(ConvertUTF8ToWChar(file).get())) +#else + if (unlink(file.c_str())) +#endif + { + LOG_WARNING(GENERAL, "Error deleting file '%s': 0x%llx", file, GET_API_ERROR); + return false; + } + + return true; +} + +bool fs::truncate_file(const std::string& file, uint64_t length) +{ +#ifdef _WIN32 + if (!::truncate_file(file, length)) +#else + if (truncate64(file.c_str(), length)) +#endif + { + LOG_WARNING(GENERAL, "Error resizing file '%s' to 0x%llx: 0x%llx", file, length, GET_API_ERROR); + return false; + } + + return true; +} + +fs::file::file() +#ifdef _WIN32 + : fd(INVALID_HANDLE_VALUE) +#else + : fd(-1) +#endif +{ +} + +fs::file::~file() +{ +#ifdef _WIN32 + if (fd != INVALID_HANDLE_VALUE) + { + CloseHandle(fd); + } +#else + if (fd != -1) + { + ::close(fd); + } +#endif +} + +fs::file::file(const std::string& filename, u32 mode) +#ifdef _WIN32 + : fd(INVALID_HANDLE_VALUE) +#else + : fd(-1) +#endif +{ + open(filename, mode); +} + +fs::file::operator bool() const +{ +#ifdef _WIN32 + return fd != INVALID_HANDLE_VALUE; +#else + return fd != -1; +#endif +} + +void fs::file::import(handle_type handle) +{ + this->~file(); + fd = handle; +} + +bool fs::file::open(const std::string& filename, u32 mode) +{ + this->~file(); + +#ifdef _WIN32 + DWORD access = 0; + switch (mode & (o_read | o_write | o_append)) + { + case o_read: access |= GENERIC_READ; break; + case o_read | o_append: access |= GENERIC_READ; break; + case o_write: access |= GENERIC_WRITE; break; + case o_write | o_append: access |= FILE_APPEND_DATA; break; + case o_read | o_write: access |= GENERIC_READ | GENERIC_WRITE; break; + case o_read | o_write | o_append: access |= GENERIC_READ | FILE_APPEND_DATA; break; + default: + { + LOG_ERROR(GENERAL, "fs::file::open('%s') failed: neither o_read nor o_write specified (0x%x)", filename, mode); + return false; + } + } + + DWORD disp = 0; + switch (mode & (o_create | o_trunc | o_excl)) + { + case 0: disp = OPEN_EXISTING; break; + case o_create: disp = OPEN_ALWAYS; break; + case o_trunc: disp = TRUNCATE_EXISTING; break; + case o_create | o_trunc: disp = CREATE_ALWAYS; break; + case o_create | o_excl: disp = CREATE_NEW; break; + case o_create | o_excl | o_trunc: disp = CREATE_NEW; break; + } + + if (!disp || (mode & ~(o_read | o_write | o_append | o_create | o_trunc | o_excl))) + { + LOG_ERROR(GENERAL, "fs::file::open('%s') failed: unknown mode specified (0x%x)", filename, mode); + return false; + } + + if ((fd = CreateFileW(ConvertUTF8ToWChar(filename).get(), access, FILE_SHARE_READ, NULL, disp, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE) +#else + int flags = 0; + + switch (mode & (o_read | o_write)) + { + case o_read: flags |= O_RDONLY; break; + case o_write: flags |= O_WRONLY; break; + case o_read | o_write: flags |= O_RDWR; break; + default: + { + LOG_ERROR(GENERAL, "fs::file::open('%s') failed: neither o_read nor o_write specified (0x%x)", filename, mode); + return false; + } + } + + if (mode & o_append) flags |= O_APPEND; + if (mode & o_create) flags |= O_CREAT; + if (mode & o_trunc) flags |= O_TRUNC; + if (mode & o_excl) flags |= O_EXCL; + + if (((mode & o_excl) && !(mode & o_create)) || (mode & ~(o_read | o_write | o_append | o_create | o_trunc | o_excl))) + { + LOG_ERROR(GENERAL, "fs::file::open('%s') failed: unknown mode specified (0x%x)", filename, mode); + return false; + } + + if ((fd = ::open(filename.c_str(), flags, 0666)) == -1) +#endif + { + 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::is_opened() const +{ + return *this; +} + +bool fs::file::trunc(u64 size) const +{ +#ifdef _WIN32 + LARGE_INTEGER old, pos; + + pos.QuadPart = 0; + SetFilePointerEx(fd, pos, &old, FILE_CURRENT); // get old position + + pos.QuadPart = size; + SetFilePointerEx(fd, pos, NULL, FILE_BEGIN); // set new position + + SetEndOfFile(fd); // change file size + + SetFilePointerEx(fd, old, NULL, FILE_BEGIN); // restore position + + return true; // TODO +#else + return !ftruncate64(fd, size); +#endif +} + +bool fs::file::stat(stat_t& info) const +{ +#ifdef _WIN32 + FILE_BASIC_INFO basic_info; + //FILE_NAME_INFO name_info; + + if (!GetFileInformationByHandleEx(fd, FileBasicInfo, &basic_info, sizeof(FILE_BASIC_INFO))) + { + info = {}; + return false; + } + + info.exists = true; + info.is_directory = (basic_info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; + info.is_writable = (basic_info.FileAttributes & FILE_ATTRIBUTE_READONLY) == 0; + info.size = this->size(); + info.atime = to_time_t(basic_info.LastAccessTime); + info.mtime = to_time_t(basic_info.ChangeTime); + info.ctime = to_time_t(basic_info.CreationTime); +#else + struct stat64 file_info; + if (fstat64(fd, &file_info) < 0) + { + info = {}; + return false; + } + + info.exists = true; + info.is_directory = S_ISDIR(file_info.st_mode); + info.is_writable = file_info.st_mode & 0200; // HACK: approximation + info.size = file_info.st_size; + info.atime = file_info.st_atime; + info.mtime = file_info.st_mtime; + info.ctime = file_info.st_ctime; +#endif + return true; +} + +bool fs::file::close() +{ +#ifdef _WIN32 + if (CloseHandle(fd)) + { + return true; + } + + fd = INVALID_HANDLE_VALUE; +#else + if (!::close(fd)) + { + return true; + } + + fd = -1; +#endif + + return false; +} + +u64 fs::file::read(void* buffer, u64 count) const +{ +#ifdef _WIN32 + DWORD nread; + if (!ReadFile(fd, buffer, count, &nread, NULL)) + { + return -1; + } + + return nread; +#else + return ::read(fd, buffer, count); +#endif +} + +u64 fs::file::write(const void* buffer, u64 count) const +{ +#ifdef _WIN32 + DWORD nwritten; + if (!WriteFile(fd, buffer, count, &nwritten, NULL)) + { + return -1; + } + + return nwritten; +#else + return ::write(fd, buffer, count); +#endif +} + +u64 fs::file::seek(u64 offset, u32 mode) const +{ + assert(mode < 3); + +#ifdef _WIN32 + LARGE_INTEGER pos; + pos.QuadPart = offset; + + if (!SetFilePointerEx(fd, pos, &pos, mode)) + { + return -1; + } + + return pos.QuadPart; +#else + return lseek64(fd, offset, mode); +#endif +} + +u64 fs::file::size() const +{ +#ifdef _WIN32 + LARGE_INTEGER size; + if (!GetFileSizeEx(fd, &size)) + { + return -1; + } + + return size.QuadPart; +#else + struct stat64 file_info; + if (fstat64(fd, &file_info) < 0) + { + return -1; + } + + return file_info.st_size; +#endif +} + +rDir::rDir() +{ + handle = reinterpret_cast(new wxDir()); +} + +rDir::~rDir() +{ + delete reinterpret_cast(handle); +} + +rDir::rDir(const std::string &path) +{ + handle = reinterpret_cast(new wxDir(fmt::FromUTF8(path))); +} + +bool rDir::Open(const std::string& path) +{ + return reinterpret_cast(handle)->Open(fmt::FromUTF8(path)); +} + +bool rDir::IsOpened() const +{ + return reinterpret_cast(handle)->IsOpened(); +} + +bool rDir::GetFirst(std::string *filename) const +{ + wxString str; + bool res; + res = reinterpret_cast(handle)->GetFirst(&str); + *filename = str.ToStdString(); + return res; +} + +bool rDir::GetNext(std::string *filename) const +{ + wxString str; + bool res; + res = reinterpret_cast(handle)->GetNext(&str); + *filename = str.ToStdString(); + return res; +} diff --git a/Utilities/File.h b/Utilities/File.h new file mode 100644 index 0000000000..166c0b14e1 --- /dev/null +++ b/Utilities/File.h @@ -0,0 +1,97 @@ +#pragma once + +enum file_seek_mode : u32 +{ + from_begin, + from_cur, + from_end, +}; + +enum file_open_mode : u32 +{ + o_read = 1 << 0, + o_write = 1 << 1, + o_append = 1 << 2, + o_create = 1 << 3, + o_trunc = 1 << 4, + o_excl = 1 << 5, +}; + +namespace fs +{ + struct stat_t + { + bool exists; + bool is_directory; + bool is_writable; + uint64_t size; + time_t atime; + time_t mtime; + time_t ctime; + }; + + bool stat(const std::string& path, stat_t& info); + bool exists(const std::string& path); + bool is_file(const std::string& file); + bool is_dir(const std::string& dir); + bool remove_dir(const std::string& dir); + bool create_dir(const std::string& dir); + bool create_path(const std::string& path); + bool rename(const std::string& from, const std::string& to); + bool copy_file(const std::string& from, const std::string& to, bool overwrite); + bool remove_file(const std::string& file); + bool truncate_file(const std::string& file, uint64_t length); + + struct file final + { +#ifdef _WIN32 + using handle_type = void*; +#else + using handle_type = intptr_t; +#endif + + private: + handle_type fd; + + public: + file(); + ~file(); + explicit file(const std::string& filename, u32 mode = o_read); + + file(const file&) = delete; + file(file&&) = delete; // possibly TODO + + file& operator =(const file&) = delete; + file& operator =(file&&) = delete; // possibly TODO + + operator bool() const; // check is_opened() + + void import(handle_type fd); // replace file handle + + bool open(const std::string& filename, u32 mode = o_read); + bool is_opened() const; // check whether the file is opened + bool trunc(u64 size) const; // change file size (possibly appending zero bytes) + bool stat(stat_t& info) const; // get file info + bool close(); + + u64 read(void* buffer, u64 count) const; + u64 write(const void* buffer, u64 count) const; + u64 seek(u64 offset, u32 mode = from_begin) const; + u64 size() const; + }; +} + +struct rDir +{ + rDir(); + ~rDir(); + rDir(const rDir& other) = delete; + rDir(const std::string &path); + bool Open(const std::string& path); + bool IsOpened() const; + static bool Exists(const std::string &path); + bool GetFirst(std::string *filename) const; + bool GetNext(std::string *filename) const; + + void *handle; +}; diff --git a/Utilities/Log.cpp b/Utilities/Log.cpp index 5aaf98579d..f4652da86f 100644 --- a/Utilities/Log.cpp +++ b/Utilities/Log.cpp @@ -5,11 +5,11 @@ #include #include #include "Thread.h" -#include "rFile.h" +#include "File.h" using namespace Log; -LogManager *gLogManager = nullptr; +std::unique_ptr g_log_manager; u32 LogMessage::size() const { @@ -90,14 +90,14 @@ struct CoutListener : LogListener struct FileListener : LogListener { - rFile mFile; + fs::file mFile; bool mPrependChannelName; FileListener(const std::string& name = _PRGNAME_, bool prependChannel = true) - : mFile(std::string(rPlatform::getConfigDir() + name + ".log").c_str(), rFile::write), - mPrependChannelName(prependChannel) + : mFile(rPlatform::getConfigDir() + name + ".log", o_write | o_create | o_trunc) + , mPrependChannelName(prependChannel) { - if (!mFile.IsOpened()) + if (!mFile) { rMessageBox("Can't create log file! (" + name + ".log)", "Error", rICON_ERROR); } @@ -119,7 +119,8 @@ struct FileListener : LogListener } } } - mFile.Write(text); + + mFile.write(text.c_str(), text.size()); } }; @@ -223,6 +224,7 @@ void LogManager::addListener(std::shared_ptr listener) channel.addListener(listener); } } + void LogManager::removeListener(std::shared_ptr listener) { for (auto& channel : mChannels) @@ -233,12 +235,14 @@ void LogManager::removeListener(std::shared_ptr listener) LogManager& LogManager::getInstance() { - if (!gLogManager) + if (!g_log_manager) { - gLogManager = new LogManager(); + g_log_manager.reset(new LogManager()); } - return *gLogManager; + + return *g_log_manager; } + LogChannel &LogManager::getChannel(LogType type) { return mChannels[static_cast(type)]; @@ -251,9 +255,22 @@ void log_message(Log::LogType type, Log::LogSeverity sev, const char* text) void log_message(Log::LogType type, Log::LogSeverity sev, std::string text) { - //another msvc bug makes this not work, uncomment this and delete everything else in this function when it's fixed - //Log::LogManager::getInstance().log({logType, severity, text}) - - Log::LogMessage msg{ type, sev, std::move(text) }; - Log::LogManager::getInstance().log(msg); + if (g_log_manager) + { + // another msvc bug makes this not work, uncomment this when it's fixed + //g_log_manager->log({logType, severity, text}); + Log::LogMessage msg{ type, sev, std::move(text) }; + g_log_manager->log(msg); + } + else + { + rMessageBox(text, + sev == Notice ? "Notice" : + sev == Warning ? "Warning" : + sev == Success ? "Success" : + sev == Error ? "Error" : "Unknown", + sev == Notice ? rICON_INFORMATION : + sev == Warning ? rICON_EXCLAMATION : + sev == Error ? rICON_ERROR : rICON_INFORMATION); + } } diff --git a/Utilities/StrFmt.cpp b/Utilities/StrFmt.cpp index b9eea87b95..86821274ad 100644 --- a/Utilities/StrFmt.cpp +++ b/Utilities/StrFmt.cpp @@ -1,5 +1,9 @@ #include "stdafx.h" +#pragma warning(push) +#pragma message("TODO: remove wx dependency: ") +#pragma warning(disable : 4996) #include +#pragma warning(pop) std::string u128::to_hex() const { @@ -218,7 +222,7 @@ std::string fmt::merge(std::vector source, const std::string& separ result += source[i] + separator; } - return result + source[source.size() - 1]; + return result + source.back(); } std::string fmt::merge(std::initializer_list> sources, const std::string& separator) diff --git a/Utilities/StrFmt.h b/Utilities/StrFmt.h index 623555f70e..365b60d005 100644 --- a/Utilities/StrFmt.h +++ b/Utilities/StrFmt.h @@ -48,47 +48,47 @@ namespace fmt // the stream `os`. Then write `arg` to to the stream. If there's no // `fmt::placeholder` after `pos` everything in `fmt` after pos is written // to `os`. Then `arg` is written to `os` after appending a space character - template - empty_t write(const std::string &fmt, std::ostream &os, std::string::size_type &pos, T &&arg) - { - std::string::size_type ins = fmt.find(placeholder, pos); + //template + //empty_t write(const std::string &fmt, std::ostream &os, std::string::size_type &pos, T &&arg) + //{ + // std::string::size_type ins = fmt.find(placeholder, pos); - if (ins == std::string::npos) - { - os.write(fmt.data() + pos, fmt.size() - pos); - os << ' ' << arg; + // if (ins == std::string::npos) + // { + // os.write(fmt.data() + pos, fmt.size() - pos); + // os << ' ' << arg; - pos = fmt.size(); - } - else - { - os.write(fmt.data() + pos, ins - pos); - os << arg; + // pos = fmt.size(); + // } + // else + // { + // os.write(fmt.data() + pos, ins - pos); + // os << arg; - pos = ins + placeholder.size(); - } - return{}; - } + // pos = ins + placeholder.size(); + // } + // return{}; + //} // typesafe version of a sprintf-like function. Returns the printed to // string. To mark positions where the arguments are supposed to be // inserted use `fmt::placeholder`. If there's not enough placeholders // the rest of the arguments are appended at the end, seperated by spaces - template - std::string SFormat(const std::string &fmt, Args&& ... parameters) - { - std::ostringstream os; - std::string::size_type pos = 0; - std::initializer_list { write(fmt, os, pos, parameters)... }; + //template + //std::string SFormat(const std::string &fmt, Args&& ... parameters) + //{ + // std::ostringstream os; + // std::string::size_type pos = 0; + // std::initializer_list { write(fmt, os, pos, parameters)... }; - if (!fmt.empty()) - { - os.write(fmt.data() + pos, fmt.size() - pos); - } + // if (!fmt.empty()) + // { + // os.write(fmt.data() + pos, fmt.size() - pos); + // } - std::string result = os.str(); - return result; - } + // std::string result = os.str(); + // return result; + //} //small wrapper used to deal with bitfields template diff --git a/Utilities/Thread.h b/Utilities/Thread.h index d41900a621..7de4c657cd 100644 --- a/Utilities/Thread.h +++ b/Utilities/Thread.h @@ -1,7 +1,5 @@ #pragma once -static std::thread::id main_thread; - class NamedThreadBase { std::string m_name; diff --git a/Utilities/rFile.cpp b/Utilities/rFile.cpp deleted file mode 100644 index ff41566927..0000000000 --- a/Utilities/rFile.cpp +++ /dev/null @@ -1,414 +0,0 @@ -#include "stdafx.h" -#include "Log.h" -#pragma warning(disable : 4996) -#include -#include -#include -#include "rFile.h" -#include "errno.h" - -#ifdef _WIN32 -#include - -// Maybe in StrFmt? -std::wstring ConvertUTF8ToWString(const std::string &source) { - int len = (int)source.size(); - int size = (int)MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, NULL, 0); - std::wstring str; - str.resize(size); - if (size > 0) { - MultiByteToWideChar(CP_UTF8, 0, source.c_str(), len, &str[0], size); - } - return str; -} -#endif - -#ifdef _WIN32 -#define GET_API_ERROR GetLastError() -#else -#define GET_API_ERROR errno -#endif - -bool getFileInfo(const char *path, FileInfo *fileInfo) { - // TODO: Expand relative paths? - fileInfo->fullName = path; - -#ifdef _WIN32 - WIN32_FILE_ATTRIBUTE_DATA attrs; - if (!GetFileAttributesExW(ConvertUTF8ToWString(path).c_str(), GetFileExInfoStandard, &attrs)) { - fileInfo->size = 0; - fileInfo->isDirectory = false; - fileInfo->exists = false; - return false; - } - fileInfo->size = (uint64_t)attrs.nFileSizeLow | ((uint64_t)attrs.nFileSizeHigh << 32); - fileInfo->isDirectory = (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; - fileInfo->isWritable = (attrs.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == 0; - fileInfo->exists = true; -#else - struct stat64 file_info; - int result = stat64(path, &file_info); - - if (result < 0) { - LOG_NOTICE(GENERAL, "IsDirectory: stat failed on %s", path); - fileInfo->exists = false; - return false; - } - - fileInfo->isDirectory = S_ISDIR(file_info.st_mode); - fileInfo->isWritable = false; - fileInfo->size = file_info.st_size; - fileInfo->exists = true; - // HACK: approximation - if (file_info.st_mode & 0200) - fileInfo->isWritable = true; -#endif - return true; -} - -bool rIsDir(const std::string &filename) { - FileInfo info; - getFileInfo(filename.c_str(), &info); - return info.isDirectory; -} - -bool rMkdir(const std::string &dir) -{ -#ifdef _WIN32 - return !_mkdir(dir.c_str()); -#else - return !mkdir(dir.c_str(), 0777); -#endif -} - -bool rMkpath(const std::string &path) -{ - size_t start=0, pos; - std::string dir; - bool ret; - - while (true) { - if ((pos = path.find_first_of("/\\", start)) == std::string::npos) - pos = path.length(); - - dir = path.substr(0,pos++); - start = pos; - if(dir.size() == 0) - continue; -#ifdef _WIN32 - if((ret = _mkdir(dir.c_str()) != 0) && errno != EEXIST){ -#else - if((ret = mkdir(dir.c_str(), 0777) != 0) && errno != EEXIST){ -#endif - return !ret; - } - if (pos >= path.length()) - return true; - } - return true; -} - -bool rRmdir(const std::string &dir) -{ -#ifdef _WIN32 - if (!RemoveDirectory(ConvertUTF8ToWString(dir).c_str())) -#else - if (rmdir(dir.c_str())) -#endif - { - LOG_ERROR(GENERAL, "Error deleting directory %s: 0x%llx", dir.c_str(), (u64)GET_API_ERROR); - return false; - } - return true; -} - -bool rRename(const std::string &from, const std::string &to) -{ - // TODO: Deal with case-sensitivity -#ifdef _WIN32 - if (!MoveFile(ConvertUTF8ToWString(from).c_str(), ConvertUTF8ToWString(to).c_str())) -#else - if (int err = rename(from.c_str(), to.c_str())) -#endif - { - LOG_ERROR(GENERAL, "Error renaming '%s' to '%s': 0x%llx", from.c_str(), to.c_str(), (u64)GET_API_ERROR); - return false; - } - return true; -} - -bool rExists(const std::string &file) -{ -#ifdef _WIN32 - std::wstring wstr = ConvertUTF8ToWString(file); - return GetFileAttributes(wstr.c_str()) != 0xFFFFFFFF; -#else - struct stat buffer; - return (stat (file.c_str(), &buffer) == 0); -#endif -} - -bool rRemoveFile(const std::string &file) -{ -#ifdef _WIN32 - if (!DeleteFile(ConvertUTF8ToWString(file).c_str())) -#else - if (unlink(file.c_str())) -#endif - { - LOG_ERROR(GENERAL, "Error deleting file %s: 0x%llx", file.c_str(), (u64)GET_API_ERROR); - return false; - } - return true; -} - -wxFile::OpenMode convertOpenMode(rFile::OpenMode open) -{ - wxFile::OpenMode mode; - switch (open) - { - case rFile::read: - mode = wxFile::read; - break; - case rFile::write: - mode = wxFile::write; - break; - case rFile::read_write: - mode = wxFile::read_write; - break; - case rFile::write_append: - mode = wxFile::write_append; - break; - case rFile::write_excl: - mode = wxFile::write_excl; - break; - } - return mode; -} - -rFile::OpenMode rConvertOpenMode(wxFile::OpenMode open) -{ - rFile::OpenMode mode; - switch (open) - { - case wxFile::read: - mode = rFile::read; - break; - case wxFile::write: - mode = rFile::write; - break; - case wxFile::read_write: - mode = rFile::read_write; - break; - case wxFile::write_append: - mode = rFile::write_append; - break; - case wxFile::write_excl: - mode = rFile::write_excl; - break; - } - return mode; -} - -wxSeekMode convertSeekMode(rSeekMode mode) -{ - wxSeekMode ret; - switch (mode) - { - case rFromStart: - ret = wxFromStart; - break; - case rFromCurrent: - ret = wxFromCurrent; - break; - case rFromEnd: - ret = wxFromEnd; - break; - } - return ret; -} - -rSeekMode rConvertSeekMode(wxSeekMode mode) -{ - rSeekMode ret; - switch (mode) - { - case wxFromStart: - ret = rFromStart; - break; - case wxFromCurrent: - ret = rFromCurrent; - break; - case wxFromEnd: - ret = rFromEnd; - break; - } - return ret; -} - - -rFile::rFile() -{ - handle = reinterpret_cast(new wxFile()); -} - -rFile::rFile(const std::string& filename, rFile::OpenMode open) -{ - - handle = reinterpret_cast(new wxFile(fmt::FromUTF8(filename), convertOpenMode(open))); -} - -rFile::rFile(int fd) -{ - handle = reinterpret_cast(new wxFile(fd)); -} - -rFile::~rFile() -{ - delete reinterpret_cast(handle); -} - -bool rFile::Access(const std::string &filename, rFile::OpenMode mode) -{ - return wxFile::Access(fmt::FromUTF8(filename), convertOpenMode(mode)); -} - -size_t rFile::Write(const void *buffer, size_t count) -{ - return reinterpret_cast(handle)->Write(buffer,count); -} - -bool rFile::Write(const std::string &text) -{ - return reinterpret_cast(handle)->Write(reinterpret_cast(text.c_str()),text.size()) != 0; -} - -bool rFile::Close() -{ - return reinterpret_cast(handle)->Close(); -} - -bool rFile::Create(const std::string &filename, bool overwrite, int access) -{ - return reinterpret_cast(handle)->Create(fmt::FromUTF8(filename), overwrite, access); -} - -bool rFile::Open(const std::string &filename, rFile::OpenMode mode, int access) -{ - return reinterpret_cast(handle)->Open(fmt::FromUTF8(filename), convertOpenMode(mode), access); -} - -bool rFile::IsOpened() const -{ - return reinterpret_cast(handle)->IsOpened(); -} - -size_t rFile::Length() const -{ - return reinterpret_cast(handle)->Length(); -} - -size_t rFile::Read(void *buffer, size_t count) -{ - return reinterpret_cast(handle)->Read(buffer,count); -} - -size_t rFile::Seek(size_t ofs, rSeekMode mode) -{ - return reinterpret_cast(handle)->Seek(ofs, convertSeekMode(mode)); -} - -size_t rFile::Tell() const -{ - return reinterpret_cast(handle)->Tell(); -} - -rDir::rDir() -{ - handle = reinterpret_cast(new wxDir()); -} - -rDir::~rDir() -{ - delete reinterpret_cast(handle); -} - -rDir::rDir(const std::string &path) -{ - handle = reinterpret_cast(new wxDir(fmt::FromUTF8(path))); -} - -bool rDir::Open(const std::string& path) -{ - return reinterpret_cast(handle)->Open(fmt::FromUTF8(path)); -} - -bool rDir::IsOpened() const -{ - return reinterpret_cast(handle)->IsOpened(); -} - -bool rDir::GetFirst(std::string *filename) const -{ - wxString str; - bool res; - res = reinterpret_cast(handle)->GetFirst(&str); - *filename = str.ToStdString(); - return res; -} - -bool rDir::GetNext(std::string *filename) const -{ - wxString str; - bool res; - res = reinterpret_cast(handle)->GetNext(&str); - *filename = str.ToStdString(); - return res; -} - -rFileName::rFileName() -{ - handle = reinterpret_cast(new wxFileName()); -} - -rFileName::~rFileName() -{ - delete reinterpret_cast(handle); -} - -rFileName::rFileName(const rFileName& filename) -{ - handle = reinterpret_cast(new wxFileName(*reinterpret_cast(filename.handle))); -} - - -rFileName::rFileName(const std::string& name) -{ - handle = reinterpret_cast(new wxFileName(fmt::FromUTF8(name))); -} - -std::string rFileName::GetFullPath() -{ - return fmt::ToUTF8(reinterpret_cast(handle)->GetFullPath()); -} - -std::string rFileName::GetPath() -{ - return fmt::ToUTF8(reinterpret_cast(handle)->GetPath()); -} - -std::string rFileName::GetName() -{ - return fmt::ToUTF8(reinterpret_cast(handle)->GetName()); -} - -std::string rFileName::GetFullName() -{ - return fmt::ToUTF8(reinterpret_cast(handle)->GetFullName()); -} - -bool rFileName::Normalize() -{ - return reinterpret_cast(handle)->Normalize(); -} - diff --git a/Utilities/rFile.h b/Utilities/rFile.h deleted file mode 100644 index 563b7475be..0000000000 --- a/Utilities/rFile.h +++ /dev/null @@ -1,87 +0,0 @@ -#pragma once - -struct FileInfo { - std::string name; - std::string fullName; - bool exists; - bool isDirectory; - bool isWritable; - uint64_t size; -}; - -bool getFileInfo(const char *path, FileInfo *fileInfo); -bool rIsDir(const std::string& filename); -bool rRmdir(const std::string& dir); -bool rMkdir(const std::string& dir); -bool rMkpath(const std::string& path); -bool rRename(const std::string &from, const std::string &to); -bool rExists(const std::string &path); -bool rRemoveFile(const std::string &path); - -enum rSeekMode -{ - rFromStart, - rFromCurrent, - rFromEnd -}; - -class rFile -{ -public: - enum OpenMode - { - read, - write, - read_write, - write_append, - write_excl - }; - rFile(); - rFile(const rFile& other) = delete; - ~rFile(); - rFile(const std::string& filename, rFile::OpenMode open = rFile::read); - rFile(int fd); - static bool Access(const std::string &filename, rFile::OpenMode mode); - size_t Write(const void *buffer, size_t count); - bool Write(const std::string &text); - bool Close(); - bool Create(const std::string &filename, bool overwrite = false, int access = 0666); - bool Open(const std::string &filename, rFile::OpenMode mode = rFile::read, int access = 0666); - static bool Exists(const std::string&); - bool IsOpened() const; - size_t Length() const; - size_t Read(void *buffer, size_t count); - size_t Seek(size_t ofs, rSeekMode mode = rFromStart); - size_t Tell() const; - - void *handle; -}; - -struct rDir -{ - rDir(); - ~rDir(); - rDir(const rDir& other) = delete; - rDir(const std::string &path); - bool Open(const std::string& path); - bool IsOpened() const; - static bool Exists(const std::string &path); - bool GetFirst(std::string *filename) const; - bool GetNext(std::string *filename) const; - - void *handle; -}; -struct rFileName -{ - rFileName(); - rFileName(const rFileName& other); - ~rFileName(); - rFileName(const std::string& name); - std::string GetFullPath(); - std::string GetPath(); - std::string GetName(); - std::string GetFullName(); - bool Normalize(); - - void *handle; -}; diff --git a/Utilities/rMsgBox.cpp b/Utilities/rMsgBox.cpp index cf4c027096..152ac74b94 100644 --- a/Utilities/rMsgBox.cpp +++ b/Utilities/rMsgBox.cpp @@ -1,7 +1,10 @@ #include "stdafx.h" #include "restore_new.h" +#pragma warning(push) +#pragma message("TODO: remove wx dependency: ") #pragma warning(disable : 4996) #include +#pragma warning(pop) #include "define_new_memleakdetect.h" #include "rMsgBox.h" diff --git a/Utilities/rPlatform.cpp b/Utilities/rPlatform.cpp index 57a32e1425..63eae5d141 100644 --- a/Utilities/rPlatform.cpp +++ b/Utilities/rPlatform.cpp @@ -1,7 +1,10 @@ #include "stdafx.h" #include "restore_new.h" +#pragma warning(push) +#pragma message("TODO: remove wx dependency: ") #pragma warning(disable : 4996) #include +#pragma warning(pop) #include "define_new_memleakdetect.h" #ifndef _WIN32 diff --git a/Utilities/rTime.cpp b/Utilities/rTime.cpp index 194394317c..58f607d1e3 100644 --- a/Utilities/rTime.cpp +++ b/Utilities/rTime.cpp @@ -1,7 +1,10 @@ #include "stdafx.h" #include "rTime.h" +#pragma warning(push) +#pragma message("TODO: remove wx dependency: ") #pragma warning(disable : 4996) #include +#pragma warning(pop) std::string rDefaultDateTimeFormat = "%c"; diff --git a/Utilities/rXml.cpp b/Utilities/rXml.cpp index 7d2ed9a533..30e0b457c2 100644 --- a/Utilities/rXml.cpp +++ b/Utilities/rXml.cpp @@ -1,6 +1,10 @@ #include "stdafx.h" #include "Utilities/rXml.h" +#pragma warning(push) +#pragma message("TODO: remove wx dependency: ") +#pragma warning(disable : 4996) #include +#pragma warning(pop) rXmlNode::rXmlNode() { diff --git a/rpcs3/Crypto/unedat.cpp b/rpcs3/Crypto/unedat.cpp index f4d57c49d0..9bfaa000e7 100644 --- a/rpcs3/Crypto/unedat.cpp +++ b/rpcs3/Crypto/unedat.cpp @@ -2,7 +2,7 @@ #include "key_vault.h" #include "unedat.h" #include "Utilities/Log.h" -#include "Utilities/rFile.h" +#include "Utilities/File.h" void generate_key(int crypto_mode, int version, unsigned char *key_final, unsigned char *iv_final, unsigned char *key, unsigned char *iv) { @@ -136,7 +136,7 @@ unsigned char* get_block_key(int block, NPD_HEADER *npd) } // EDAT/SDAT decryption. -int decrypt_data(rFile *in, rFile *out, EDAT_HEADER *edat, NPD_HEADER *npd, unsigned char* crypt_key, bool verbose) +int decrypt_data(const fs::file* in, const fs::file* out, EDAT_HEADER *edat, NPD_HEADER *npd, unsigned char* crypt_key, bool verbose) { // Get metadata info and setup buffers. int block_num = (int)((edat->file_size + edat->block_size - 1) / edat->block_size); @@ -170,11 +170,11 @@ int decrypt_data(rFile *in, rFile *out, EDAT_HEADER *edat, NPD_HEADER *npd, unsi if ((edat->flags & EDAT_COMPRESSED_FLAG) != 0) { metadata_sec_offset = metadata_offset + (unsigned long long) i * metadata_section_size; - in->Seek(metadata_sec_offset); + in->seek(metadata_sec_offset); unsigned char metadata[0x20]; memset(metadata, 0, 0x20); - in->Read(metadata, 0x20); + in->read(metadata, 0x20); // If the data is compressed, decrypt the metadata. // NOTE: For NPD version 1 the metadata is not encrypted. @@ -199,11 +199,11 @@ int decrypt_data(rFile *in, rFile *out, EDAT_HEADER *edat, NPD_HEADER *npd, unsi { // If FLAG 0x20, the metadata precedes each data block. metadata_sec_offset = metadata_offset + (unsigned long long) i * (metadata_section_size + length); - in->Seek(metadata_sec_offset); + in->seek(metadata_sec_offset); unsigned char metadata[0x20]; memset(metadata, 0, 0x20); - in->Read(metadata, 0x20); + in->read(metadata, 0x20); memcpy(hash_result, metadata, 0x14); // If FLAG 0x20 is set, apply custom xor. @@ -220,9 +220,9 @@ int decrypt_data(rFile *in, rFile *out, EDAT_HEADER *edat, NPD_HEADER *npd, unsi else { metadata_sec_offset = metadata_offset + (unsigned long long) i * metadata_section_size; - in->Seek(metadata_sec_offset); + in->seek(metadata_sec_offset); - in->Read(hash_result, 0x10); + in->read(hash_result, 0x10); offset = metadata_offset + (unsigned long long) i * edat->block_size + (unsigned long long) block_num * metadata_section_size; length = edat->block_size; @@ -242,8 +242,8 @@ int decrypt_data(rFile *in, rFile *out, EDAT_HEADER *edat, NPD_HEADER *npd, unsi memset(hash, 0, 0x10); memset(key_result, 0, 0x10); - in->Seek(offset); - in->Read(enc_data, length); + in->seek(offset); + in->read(enc_data, length); // Generate a key for the current block. b_key = get_block_key(i, npd); @@ -305,7 +305,7 @@ int decrypt_data(rFile *in, rFile *out, EDAT_HEADER *edat, NPD_HEADER *npd, unsi LOG_NOTICE(LOADER, "EDAT: Decompressing data..."); int res = decompress(decomp_data, dec_data, decomp_size); - out->Write(decomp_data, res); + out->write(decomp_data, res); if (verbose) { @@ -330,7 +330,7 @@ int decrypt_data(rFile *in, rFile *out, EDAT_HEADER *edat, NPD_HEADER *npd, unsi } else { - out->Write(dec_data, pad_length); + out->write(dec_data, pad_length); } delete[] enc_data; @@ -340,9 +340,9 @@ int decrypt_data(rFile *in, rFile *out, EDAT_HEADER *edat, NPD_HEADER *npd, unsi return 0; } -int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, rFile *f, bool verbose) +int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, const fs::file* f, bool verbose) { - f->Seek(0); + f->seek(0); unsigned char header[0xA0]; unsigned char empty_header[0xA0]; unsigned char header_hash[0x10]; @@ -384,12 +384,12 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, rFile *f, } // Read in the file header. - f->Read(header, 0xA0); + f->read(header, 0xA0); // Read in the header and metadata section hashes. - f->Seek(0x90); - f->Read(metadata_hash, 0x10); - f->Read(header_hash, 0x10); + f->seek(0x90); + f->read(metadata_hash, 0x10); + f->read(header_hash, 0x10); // Setup the hashing mode and the crypto mode used in the file. int crypto_mode = 0x1; @@ -443,10 +443,10 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, rFile *f, while (bytes_to_read > 0) { // Locate the metadata blocks. - f->Seek(metadata_section_offset); + f->seek(metadata_section_offset); // Read in the metadata. - f->Read(metadata + bytes_read, metadata_section_size); + f->read(metadata + bytes_read, metadata_section_size); // Adjust sizes. bytes_read += metadata_section_size; @@ -490,10 +490,10 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, rFile *f, // Read in the metadata and header signatures. - f->Seek(0xB0); - f->Read(metadata_signature, 0x28); - f->Seek(0xD8); - f->Read(header_signature, 0x28); + f->seek(0xB0); + f->read(metadata_signature, 0x28); + f->seek(0xD8); + f->read(header_signature, 0x28); // Checking metadata signature. // Setup signature r and s. @@ -508,8 +508,8 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, rFile *f, { int metadata_buf_size = block_num * 0x10; unsigned char *metadata_buf = new unsigned char[metadata_buf_size]; - f->Seek(metadata_offset); - f->Read(metadata_buf, metadata_buf_size); + f->seek(metadata_offset); + f->read(metadata_buf, metadata_buf_size); sha1(metadata_buf, metadata_buf_size, signature_hash); delete[] metadata_buf; } @@ -541,8 +541,8 @@ int check_data(unsigned char *key, EDAT_HEADER *edat, NPD_HEADER *npd, rFile *f, // Setup header signature hash. memset(signature_hash, 0, 20); unsigned char *header_buf = new unsigned char[0xD8]; - f->Seek(0x00); - f->Read(header_buf, 0xD8); + f->seek(0x00); + f->read(header_buf, 0xD8); sha1(header_buf, 0xD8, signature_hash ); delete[] header_buf; @@ -639,7 +639,7 @@ int validate_npd_hashes(const char* file_name, unsigned char *klicensee, NPD_HEA return (title_hash_result && dev_hash_result); } -bool extract_data(rFile *input, rFile *output, const char* input_file_name, unsigned char* devklic, unsigned char* rifkey, bool verbose) +bool extract_data(const fs::file* input, const fs::file* output, const char* input_file_name, unsigned char* devklic, unsigned char* rifkey, bool verbose) { // Setup NPD and EDAT/SDAT structs. NPD_HEADER *NPD = new NPD_HEADER(); @@ -648,8 +648,8 @@ bool extract_data(rFile *input, rFile *output, const char* input_file_name, unsi // Read in the NPD and EDAT/SDAT headers. char npd_header[0x80]; char edat_header[0x10]; - input->Read(npd_header, sizeof(npd_header)); - input->Read(edat_header, sizeof(edat_header)); + input->read(npd_header, sizeof(npd_header)); + input->read(edat_header, sizeof(edat_header)); memcpy(NPD->magic, npd_header, 4); NPD->version = swap32(*(int*)&npd_header[4]); @@ -812,9 +812,9 @@ bool extract_data(rFile *input, rFile *output, const char* input_file_name, unsi int DecryptEDAT(const std::string& input_file_name, const std::string& output_file_name, int mode, const std::string& rap_file_name, unsigned char *custom_klic, bool verbose) { // Prepare the files. - rFile input(input_file_name.c_str()); - rFile output(output_file_name.c_str(), rFile::write); - rFile rap(rap_file_name.c_str()); + fs::file input(input_file_name); + fs::file output(output_file_name, o_write | o_create | o_trunc); + fs::file rap(rap_file_name); // Set keys (RIF and DEVKLIC). unsigned char rifkey[0x10]; @@ -866,36 +866,30 @@ int DecryptEDAT(const std::string& input_file_name, const std::string& output_fi } // Check the input/output files. - if (!input.IsOpened() || !output.IsOpened()) + if (!input || !output) { LOG_ERROR(LOADER, "EDAT: Failed to open files!"); return -1; } // Read the RAP file, if provided. - if (rap.IsOpened()) + if (rap) { unsigned char rapkey[0x10]; memset(rapkey, 0, 0x10); - rap.Read(rapkey, 0x10); + rap.read(rapkey, 0x10); rap_to_rif(rapkey, rifkey); - - rap.Close(); } // Delete the bad output file if any errors arise. if (extract_data(&input, &output, input_file_name.c_str(), devklic, rifkey, verbose)) { - input.Close(); - output.Close(); - rRemoveFile(output_file_name); + output.close(); + fs::remove_file(output_file_name); return -1; } - // Cleanup. - input.Close(); - output.Close(); return 0; -} \ No newline at end of file +} diff --git a/rpcs3/Crypto/unedat.h b/rpcs3/Crypto/unedat.h index f1a9f81ab5..4513902e83 100644 --- a/rpcs3/Crypto/unedat.h +++ b/rpcs3/Crypto/unedat.h @@ -33,4 +33,4 @@ typedef struct unsigned long long file_size; } EDAT_HEADER; -int DecryptEDAT(const std::string& input_file_name, const std::string& output_file_name, int mode, const std::string& rap_file_name, unsigned char *custom_klic, bool verbose); \ No newline at end of file +int DecryptEDAT(const std::string& input_file_name, const std::string& output_file_name, int mode, const std::string& rap_file_name, unsigned char *custom_klic, bool verbose); diff --git a/rpcs3/Crypto/unpkg.cpp b/rpcs3/Crypto/unpkg.cpp index b4d18eb92d..fdc99b2e99 100644 --- a/rpcs3/Crypto/unpkg.cpp +++ b/rpcs3/Crypto/unpkg.cpp @@ -1,66 +1,77 @@ #include "stdafx.h" +#include "Utilities/Log.h" +#include "Utilities/File.h" #include "utils.h" #include "aes.h" #include "sha1.h" #include "key_vault.h" #include "unpkg.h" #include "restore_new.h" +#pragma warning(push) +#pragma message("TODO: remove wx dependency: ") #pragma warning(disable : 4996) #include +#pragma warning(pop) #include "define_new_memleakdetect.h" -#include "Utilities/Log.h" -#include "Utilities/rFile.h" - // Decryption. -bool CheckHeader(rFile& pkg_f, PKGHeader* m_header) +bool CheckHeader(const fs::file& pkg_f, PKGHeader* m_header) { - if (m_header->pkg_magic != 0x7F504B47) { + if (m_header->pkg_magic != 0x7F504B47) + { LOG_ERROR(LOADER, "PKG: Not a package file!"); return false; } - switch ((u32)m_header->pkg_type) + switch (const u16 type = m_header->pkg_type) { case PKG_RELEASE_TYPE_DEBUG: break; case PKG_RELEASE_TYPE_RELEASE: break; default: - LOG_ERROR(LOADER, "PKG: Unknown PKG type!"); + { + LOG_ERROR(LOADER, "PKG: Unknown PKG type (0x%x)", type); return false; } + } - switch ((u32)m_header->pkg_platform) + switch (const u16 platform = m_header->pkg_platform) { case PKG_PLATFORM_TYPE_PS3: break; case PKG_PLATFORM_TYPE_PSP: break; default: - LOG_ERROR(LOADER, "PKG: Unknown PKG type!"); + { + LOG_ERROR(LOADER, "PKG: Unknown PKG platform (0x%x)", platform); + return false; + } + } + + if (m_header->header_size != PKG_HEADER_SIZE) + { + LOG_ERROR(LOADER, "PKG: Wrong header size (0x%x)", m_header->header_size); return false; } - if (m_header->header_size != PKG_HEADER_SIZE) { - LOG_ERROR(LOADER, "PKG: Wrong header size!"); - return false; - } - - if (m_header->pkg_size != pkg_f.Length()) { - LOG_WARNING(LOADER, "PKG: File size mismatch."); + if (m_header->pkg_size != pkg_f.size()) + { + LOG_ERROR(LOADER, "PKG: File size mismatch (pkg_size=0x%x)", m_header->pkg_size); //return false; } - if (m_header->data_size + m_header->data_offset + 0x60 != pkg_f.Length()) { - LOG_WARNING(LOADER, "PKG: Data size mismatch."); + if (m_header->data_size + m_header->data_offset + 0x60 != pkg_f.size()) + { + LOG_ERROR(LOADER, "PKG: Data size mismatch (data_size=0x%x, offset=0x%x)", m_header->data_size, m_header->data_offset); //return false; } return true; } -bool LoadHeader(rFile& pkg_f, PKGHeader* m_header) +bool LoadHeader(const fs::file& pkg_f, PKGHeader* m_header) { - pkg_f.Seek(0); + pkg_f.seek(0); - if (pkg_f.Read(m_header, sizeof(PKGHeader)) != sizeof(PKGHeader)) { + if (pkg_f.read(m_header, sizeof(PKGHeader)) != sizeof(PKGHeader)) + { LOG_ERROR(LOADER, "PKG: Package file is too short!"); return false; } @@ -71,10 +82,12 @@ bool LoadHeader(rFile& pkg_f, PKGHeader* m_header) return true; } -int Decrypt(rFile& pkg_f, rFile& dec_pkg_f, PKGHeader* m_header) +int Decrypt(const fs::file& pkg_f, const fs::file& dec_pkg_f, PKGHeader* m_header) { if (!LoadHeader(pkg_f, m_header)) + { return -1; + } aes_context c; u8 iv[HASH_LEN]; @@ -89,7 +102,7 @@ int Decrypt(rFile& pkg_f, rFile& dec_pkg_f, PKGHeader* m_header) memcpy(key+0x10, &m_header->qa_digest[8], 8); // &data[0x68] memcpy(key+0x18, &m_header->qa_digest[8], 8); // &data[0x68] - pkg_f.Seek(m_header->data_offset); + pkg_f.seek(m_header->data_offset); u32 parts = (m_header->data_size + BUF_SIZE - 1) / BUF_SIZE; wxProgressDialog pdlg("PKG Decrypter / Installer", "Please wait, decrypting...", parts, 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL); @@ -100,7 +113,7 @@ int Decrypt(rFile& pkg_f, rFile& dec_pkg_f, PKGHeader* m_header) for (u32 i=0; ipkg_type == PKG_RELEASE_TYPE_DEBUG) @@ -136,7 +149,7 @@ int Decrypt(rFile& pkg_f, rFile& dec_pkg_f, PKGHeader* m_header) buf[j] ^= ctr[j]; } } - dec_pkg_f.Write(buf, length); + dec_pkg_f.write(buf, length); pdlg.Update(i); } pdlg.Update(parts); @@ -144,12 +157,13 @@ int Decrypt(rFile& pkg_f, rFile& dec_pkg_f, PKGHeader* m_header) } // Unpacking. -bool LoadEntries(rFile& dec_pkg_f, PKGHeader* m_header, PKGEntry *m_entries) +bool LoadEntries(const fs::file& dec_pkg_f, PKGHeader* m_header, PKGEntry* m_entries) { - dec_pkg_f.Seek(0); - dec_pkg_f.Read(m_entries, sizeof(PKGEntry) * m_header->file_count); + dec_pkg_f.seek(0); + dec_pkg_f.read(m_entries, sizeof(PKGEntry) * m_header->file_count); - if (m_entries->name_offset / sizeof(PKGEntry) != m_header->file_count) { + if (m_entries->name_offset / sizeof(PKGEntry) != m_header->file_count) + { LOG_ERROR(LOADER, "PKG: Entries are damaged!"); return false; } @@ -157,12 +171,12 @@ bool LoadEntries(rFile& dec_pkg_f, PKGHeader* m_header, PKGEntry *m_entries) return true; } -bool UnpackEntry(rFile& dec_pkg_f, const PKGEntry& entry, std::string dir) +bool UnpackEntry(const fs::file& dec_pkg_f, const PKGEntry& entry, std::string dir) { char buf[BUF_SIZE]; - dec_pkg_f.Seek(entry.name_offset); - dec_pkg_f.Read(buf, entry.name_size); + dec_pkg_f.seek(entry.name_offset); + dec_pkg_f.read(buf, entry.name_size); buf[entry.name_size] = 0; switch (entry.type.data() >> 24) @@ -172,40 +186,49 @@ bool UnpackEntry(rFile& dec_pkg_f, const PKGEntry& entry, std::string dir) case PKG_FILE_ENTRY_SDAT: case PKG_FILE_ENTRY_REGULAR: { - rFile out; - auto path = dir + std::string(buf, entry.name_size); - if (rExists(path)) + const std::string path = dir + std::string(buf, entry.name_size); + + if (fs::is_file(path)) { - LOG_WARNING(LOADER, "PKG Loader: File is overwritten: %s", path.c_str()); + LOG_WARNING(LOADER, "PKG Loader: '%s' is overwritten", path); } - if (out.Create(path, true /* overwriting */)) - { - dec_pkg_f.Seek(entry.file_offset); + fs::file out(path, o_write | o_create | o_trunc); + + if (out) + { + dec_pkg_f.seek(entry.file_offset); + + for (u64 size = 0; size < entry.file_size;) + { + size += dec_pkg_f.read(buf, BUF_SIZE); - for (u64 size = 0; size < entry.file_size;) { - size += dec_pkg_f.Read(buf, BUF_SIZE); if (size > entry.file_size) - out.Write(buf, BUF_SIZE - (size - entry.file_size)); + { + out.write(buf, BUF_SIZE - (size - entry.file_size)); + } else - out.Write(buf, BUF_SIZE); + { + out.write(buf, BUF_SIZE); + } } - out.Close(); + return true; } else { - LOG_ERROR(LOADER, "PKG Loader: Could not create file: %s", path.c_str()); + LOG_ERROR(LOADER, "PKG Loader: Could not create file '%s'", path); return false; } } case PKG_FILE_ENTRY_FOLDER: { - auto path = dir + std::string(buf, entry.name_size); - if (!rExists(path) && !rMkdir(path)) + const std::string path = dir + std::string(buf, entry.name_size); + + if (!fs::is_dir(path) && !fs::create_dir(path)) { - LOG_ERROR(LOADER, "PKG Loader: Could not create directory: %s", path.c_str()); + LOG_ERROR(LOADER, "PKG Loader: Could not create directory: %s", path); return false; } @@ -220,41 +243,44 @@ bool UnpackEntry(rFile& dec_pkg_f, const PKGEntry& entry, std::string dir) } } -int Unpack(rFile& pkg_f, std::string src, std::string dst) +int Unpack(const fs::file& pkg_f, std::string src, std::string dst) { PKGHeader* m_header = (PKGHeader*) malloc (sizeof(PKGHeader)); - rFile dec_pkg_f; // TODO: This shouldn't use current dir std::string decryptedFile = "./dev_hdd1/" + src + ".dec"; - dec_pkg_f.Create(decryptedFile, true); + fs::file dec_pkg_f(decryptedFile, o_read | o_write | o_create | o_trunc); if (Decrypt(pkg_f, dec_pkg_f, m_header) < 0) + { return -1; - - dec_pkg_f.Close(); + } - rFile n_dec_pkg_f(decryptedFile, rFile::read); + dec_pkg_f.seek(0); std::vector m_entries; m_entries.resize(m_header->file_count); - PKGEntry *m_entries_ptr = &m_entries[0]; - if (!LoadEntries(n_dec_pkg_f, m_header, m_entries_ptr)) + auto m_entries_ptr = m_entries.data(); + + if (!LoadEntries(dec_pkg_f, m_header, m_entries_ptr)) + { return -1; + } wxProgressDialog pdlg("PKG Decrypter / Installer", "Please wait, unpacking...", m_entries.size(), 0, wxPD_AUTO_HIDE | wxPD_APP_MODAL); - for (const PKGEntry& entry : m_entries) + for (const auto& entry : m_entries) { - UnpackEntry(n_dec_pkg_f, entry, dst + src + "/"); + UnpackEntry(dec_pkg_f, entry, dst + src + "/"); pdlg.Update(pdlg.GetValue() + 1); } + pdlg.Update(m_entries.size()); - n_dec_pkg_f.Close(); - wxRemoveFile(decryptedFile); + dec_pkg_f.close(); + fs::remove_file(decryptedFile); return 0; } diff --git a/rpcs3/Crypto/unpkg.h b/rpcs3/Crypto/unpkg.h index e47e061fbc..0f895a0fe6 100644 --- a/rpcs3/Crypto/unpkg.h +++ b/rpcs3/Crypto/unpkg.h @@ -1,21 +1,32 @@ #pragma once // Constants -#define PKG_HEADER_SIZE 0xC0 //sizeof(pkg_header) + sizeof(pkg_unk_checksum) -#define PKG_RELEASE_TYPE_RELEASE 0x8000 -#define PKG_RELEASE_TYPE_DEBUG 0x0000 -#define PKG_PLATFORM_TYPE_PS3 0x0001 -#define PKG_PLATFORM_TYPE_PSP 0x0002 +enum +{ + HASH_LEN = 16, + BUF_SIZE = 4096, + PKG_HEADER_SIZE = 0xC0, //sizeof(pkg_header) + sizeof(pkg_unk_checksum) +}; -#define PKG_FILE_ENTRY_NPDRM 0x0001 -#define PKG_FILE_ENTRY_NPDRMEDAT 0x0002 -#define PKG_FILE_ENTRY_REGULAR 0x0003 -#define PKG_FILE_ENTRY_FOLDER 0x0004 -#define PKG_FILE_ENTRY_SDAT 0x0009 -#define PKG_FILE_ENTRY_OVERWRITE 0x80000000 +enum : u16 +{ + PKG_RELEASE_TYPE_RELEASE = 0x8000, + PKG_RELEASE_TYPE_DEBUG = 0x0000, -#define HASH_LEN 16 -#define BUF_SIZE 4096 + PKG_PLATFORM_TYPE_PS3 = 0x0001, + PKG_PLATFORM_TYPE_PSP = 0x0002, +}; + +enum : u32 +{ + PKG_FILE_ENTRY_NPDRM = 1, + PKG_FILE_ENTRY_NPDRMEDAT = 2, + PKG_FILE_ENTRY_REGULAR = 3, + PKG_FILE_ENTRY_FOLDER = 4, + PKG_FILE_ENTRY_SDAT = 9, + + PKG_FILE_ENTRY_OVERWRITE = 0x80000000, +}; // Structs struct PKGHeader @@ -45,6 +56,6 @@ struct PKGEntry be_t pad; // Padding (zeros) }; -class rFile; +namespace fs { struct file; } -extern int Unpack(rFile& dec_pkg_f, std::string src, std::string dst); \ No newline at end of file +int Unpack(const fs::file& dec_pkg_f, std::string src, std::string dst); diff --git a/rpcs3/Crypto/unself.cpp b/rpcs3/Crypto/unself.cpp index 954f29eb22..1f6645bdd0 100644 --- a/rpcs3/Crypto/unself.cpp +++ b/rpcs3/Crypto/unself.cpp @@ -1,63 +1,187 @@ #include "stdafx.h" #include "Utilities/Log.h" -#include "Utilities/rFile.h" +#include "Utilities/File.h" #include "aes.h" #include "sha1.h" #include "utils.h" #include "Emu/FS/vfsLocalFile.h" #include "unself.h" +#pragma warning(push) +#pragma message("TODO: remove wx dependencies: ") #pragma warning(disable : 4996) #include #include +#pragma warning(pop) +__forceinline u8 Read8(vfsStream& f) +{ + u8 ret; + f.Read(&ret, sizeof(ret)); + return ret; +} -void WriteEhdr(rFile& f, Elf64_Ehdr& ehdr) +__forceinline u16 Read16(vfsStream& f) { -Write32(f, ehdr.e_magic); -Write8(f, ehdr.e_class); -Write8(f, ehdr.e_data); -Write8(f, ehdr.e_curver); -Write8(f, ehdr.e_os_abi); -Write64(f, ehdr.e_abi_ver); -Write16(f, ehdr.e_type); -Write16(f, ehdr.e_machine); -Write32(f, ehdr.e_version); -Write64(f, ehdr.e_entry); -Write64(f, ehdr.e_phoff); -Write64(f, ehdr.e_shoff); -Write32(f, ehdr.e_flags); -Write16(f, ehdr.e_ehsize); -Write16(f, ehdr.e_phentsize); -Write16(f, ehdr.e_phnum); -Write16(f, ehdr.e_shentsize); -Write16(f, ehdr.e_shnum); -Write16(f, ehdr.e_shstrndx); + be_t ret; + f.Read(&ret, sizeof(ret)); + return ret; } -void WritePhdr(rFile& f, Elf64_Phdr& phdr) + +__forceinline u32 Read32(vfsStream& f) { -Write32(f, phdr.p_type); -Write32(f, phdr.p_flags); -Write64(f, phdr.p_offset); -Write64(f, phdr.p_vaddr); -Write64(f, phdr.p_paddr); -Write64(f, phdr.p_filesz); -Write64(f, phdr.p_memsz); -Write64(f, phdr.p_align); + be_t ret; + f.Read(&ret, sizeof(ret)); + return ret; } -void WriteShdr(rFile& f, Elf64_Shdr& shdr) + +__forceinline u64 Read64(vfsStream& f) { -Write32(f, shdr.sh_name); -Write32(f, shdr.sh_type); -Write64(f, shdr.sh_flags); -Write64(f, shdr.sh_addr); -Write64(f, shdr.sh_offset); -Write64(f, shdr.sh_size); -Write32(f, shdr.sh_link); -Write32(f, shdr.sh_info); -Write64(f, shdr.sh_addralign); -Write64(f, shdr.sh_entsize); + be_t ret; + f.Read(&ret, sizeof(ret)); + return ret; } -void WriteEhdr(rFile& f, Elf32_Ehdr& ehdr) + +__forceinline u16 Read16LE(vfsStream& f) +{ + u16 ret; + f.Read(&ret, sizeof(ret)); + return ret; +} + +__forceinline u32 Read32LE(vfsStream& f) +{ + u32 ret; + f.Read(&ret, sizeof(ret)); + return ret; +} + +__forceinline u64 Read64LE(vfsStream& f) +{ + u64 ret; + f.Read(&ret, sizeof(ret)); + return ret; +} + +__forceinline void Write8(vfsStream& f, const u8 data) +{ + f.Write(&data, sizeof(data)); +} + +__forceinline void Write8(const fs::file& f, const u8 data) +{ + f.write(&data, sizeof(data)); +} + +__forceinline void Write16LE(vfsStream& f, const u16 data) +{ + f.Write(&data, sizeof(data)); +} + +__forceinline void Write16LE(const fs::file& f, const u16 data) +{ + f.write(&data, sizeof(data)); +} + +__forceinline void Write32LE(vfsStream& f, const u32 data) +{ + f.Write(&data, sizeof(data)); +} + +__forceinline void Write32LE(const fs::file& f, const u32 data) +{ + f.write(&data, sizeof(data)); +} + +__forceinline void Write64LE(vfsStream& f, const u64 data) +{ + f.Write(&data, sizeof(data)); +} + +__forceinline void Write64LE(const fs::file& f, const u64 data) +{ + f.write(&data, sizeof(data)); +} + +__forceinline void Write16(vfsStream& f, const u16 data) +{ + Write16LE(f, re16(data)); +} + +__forceinline void Write16(const fs::file& f, const u16 data) +{ + Write16LE(f, re16(data)); +} + +__forceinline void Write32(vfsStream& f, const u32 data) +{ + Write32LE(f, re32(data)); +} + +__forceinline void Write32(const fs::file& f, const u32 data) +{ + Write32LE(f, re32(data)); +} + +__forceinline void Write64(vfsStream& f, const u64 data) +{ + Write64LE(f, re64(data)); +} + +__forceinline void Write64(const fs::file& f, const u64 data) +{ + Write64LE(f, re64(data)); +} + +void WriteEhdr(const fs::file& f, Elf64_Ehdr& ehdr) +{ + Write32(f, ehdr.e_magic); + Write8(f, ehdr.e_class); + Write8(f, ehdr.e_data); + Write8(f, ehdr.e_curver); + Write8(f, ehdr.e_os_abi); + Write64(f, ehdr.e_abi_ver); + Write16(f, ehdr.e_type); + Write16(f, ehdr.e_machine); + Write32(f, ehdr.e_version); + Write64(f, ehdr.e_entry); + Write64(f, ehdr.e_phoff); + Write64(f, ehdr.e_shoff); + Write32(f, ehdr.e_flags); + Write16(f, ehdr.e_ehsize); + Write16(f, ehdr.e_phentsize); + Write16(f, ehdr.e_phnum); + Write16(f, ehdr.e_shentsize); + Write16(f, ehdr.e_shnum); + Write16(f, ehdr.e_shstrndx); +} + +void WritePhdr(const fs::file& f, Elf64_Phdr& phdr) +{ + Write32(f, phdr.p_type); + Write32(f, phdr.p_flags); + Write64(f, phdr.p_offset); + Write64(f, phdr.p_vaddr); + Write64(f, phdr.p_paddr); + Write64(f, phdr.p_filesz); + Write64(f, phdr.p_memsz); + Write64(f, phdr.p_align); +} + +void WriteShdr(const fs::file& f, Elf64_Shdr& shdr) +{ + Write32(f, shdr.sh_name); + Write32(f, shdr.sh_type); + Write64(f, shdr.sh_flags); + Write64(f, shdr.sh_addr); + Write64(f, shdr.sh_offset); + Write64(f, shdr.sh_size); + Write32(f, shdr.sh_link); + Write32(f, shdr.sh_info); + Write64(f, shdr.sh_addralign); + Write64(f, shdr.sh_entsize); +} + +void WriteEhdr(const fs::file& f, Elf32_Ehdr& ehdr) { Write32(f, ehdr.e_magic); Write8(f, ehdr.e_class); @@ -79,7 +203,8 @@ void WriteEhdr(rFile& f, Elf32_Ehdr& ehdr) Write16(f, ehdr.e_shnum); Write16(f, ehdr.e_shstrndx); } -void WritePhdr(rFile& f, Elf32_Phdr& phdr) + +void WritePhdr(const fs::file& f, Elf32_Phdr& phdr) { Write32(f, phdr.p_type); Write32(f, phdr.p_offset); @@ -90,7 +215,8 @@ void WritePhdr(rFile& f, Elf32_Phdr& phdr) Write32(f, phdr.p_flags); Write32(f, phdr.p_align); } -void WriteShdr(rFile& f, Elf32_Shdr& shdr) + +void WriteShdr(const fs::file& f, Elf32_Shdr& shdr) { Write32(f, shdr.sh_name); Write32(f, shdr.sh_type); @@ -408,8 +534,164 @@ void SelfSection::Load(vfsStream& f) offset = Read64(f); } +void Elf32_Ehdr::Load(vfsStream& f) +{ + e_magic = Read32(f); + e_class = Read8(f); + e_data = Read8(f); + e_curver = Read8(f); + e_os_abi = Read8(f); + + if (IsLittleEndian()) + { + e_abi_ver = Read64LE(f); + e_type = Read16LE(f); + e_machine = Read16LE(f); + e_version = Read32LE(f); + e_entry = Read32LE(f); + e_phoff = Read32LE(f); + e_shoff = Read32LE(f); + e_flags = Read32LE(f); + e_ehsize = Read16LE(f); + e_phentsize = Read16LE(f); + e_phnum = Read16LE(f); + e_shentsize = Read16LE(f); + e_shnum = Read16LE(f); + e_shstrndx = Read16LE(f); + } + else + { + e_abi_ver = Read64(f); + e_type = Read16(f); + e_machine = Read16(f); + e_version = Read32(f); + e_entry = Read32(f); + e_phoff = Read32(f); + e_shoff = Read32(f); + e_flags = Read32(f); + e_ehsize = Read16(f); + e_phentsize = Read16(f); + e_phnum = Read16(f); + e_shentsize = Read16(f); + e_shnum = Read16(f); + e_shstrndx = Read16(f); + } +} + +void Elf32_Shdr::Load(vfsStream& f) +{ + sh_name = Read32(f); + sh_type = Read32(f); + sh_flags = Read32(f); + sh_addr = Read32(f); + sh_offset = Read32(f); + sh_size = Read32(f); + sh_link = Read32(f); + sh_info = Read32(f); + sh_addralign = Read32(f); + sh_entsize = Read32(f); +} + +void Elf32_Shdr::LoadLE(vfsStream& f) +{ + f.Read(this, sizeof(*this)); +} + +void Elf32_Phdr::Load(vfsStream& f) +{ + p_type = Read32(f); + p_offset = Read32(f); + p_vaddr = Read32(f); + p_paddr = Read32(f); + p_filesz = Read32(f); + p_memsz = Read32(f); + p_flags = Read32(f); + p_align = Read32(f); +} + +void Elf32_Phdr::LoadLE(vfsStream& f) +{ + f.Read(this, sizeof(*this)); +} + +void Elf64_Ehdr::Load(vfsStream& f) +{ + e_magic = Read32(f); + e_class = Read8(f); + e_data = Read8(f); + e_curver = Read8(f); + e_os_abi = Read8(f); + e_abi_ver = Read64(f); + e_type = Read16(f); + e_machine = Read16(f); + e_version = Read32(f); + e_entry = Read64(f); + e_phoff = Read64(f); + e_shoff = Read64(f); + e_flags = Read32(f); + e_ehsize = Read16(f); + e_phentsize = Read16(f); + e_phnum = Read16(f); + e_shentsize = Read16(f); + e_shnum = Read16(f); + e_shstrndx = Read16(f); +} + +void Elf64_Shdr::Load(vfsStream& f) +{ + sh_name = Read32(f); + sh_type = Read32(f); + sh_flags = Read64(f); + sh_addr = Read64(f); + sh_offset = Read64(f); + sh_size = Read64(f); + sh_link = Read32(f); + sh_info = Read32(f); + sh_addralign = Read64(f); + sh_entsize = Read64(f); +} + +void Elf64_Phdr::Load(vfsStream& f) +{ + p_type = Read32(f); + p_flags = Read32(f); + p_offset = Read64(f); + p_vaddr = Read64(f); + p_paddr = Read64(f); + p_filesz = Read64(f); + p_memsz = Read64(f); + p_align = Read64(f); +} + +void SceHeader::Load(vfsStream& f) +{ + se_magic = Read32(f); + se_hver = Read32(f); + se_flags = Read16(f); + se_type = Read16(f); + se_meta = Read32(f); + se_hsize = Read64(f); + se_esize = Read64(f); +} + +void SelfHeader::Load(vfsStream& f) +{ + se_htype = Read64(f); + se_appinfooff = Read64(f); + se_elfoff = Read64(f); + se_phdroff = Read64(f); + se_shdroff = Read64(f); + se_secinfoff = Read64(f); + se_sceveroff = Read64(f); + se_controloff = Read64(f); + se_controlsize = Read64(f); + pad = Read64(f); +} + SELFDecrypter::SELFDecrypter(vfsStream& s) - : self_f(s), key_v(), data_buf_length(0) + : self_f(s) + , key_v() + , data_buf_length(0) { } @@ -794,8 +1076,8 @@ bool SELFDecrypter::DecryptData() bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32) { // Create a new ELF file. - rFile e(elf.c_str(), rFile::write); - if(!e.IsOpened()) + fs::file e(elf, o_write | o_create | o_trunc); + if(!e) { LOG_ERROR(LOADER, "Could not create ELF file! (%s)", elf.c_str()); return false; @@ -819,8 +1101,8 @@ bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32) if (meta_shdr[i].type == 2) { // Seek to the program header data offset and write the data. - e.Seek(phdr32_arr[meta_shdr[i].program_idx].p_offset); - e.Write(data_buf + data_buf_offset, meta_shdr[i].data_size); + e.seek(phdr32_arr[meta_shdr[i].program_idx].p_offset); + e.write(data_buf + data_buf_offset, meta_shdr[i].data_size); // Advance the data buffer offset by data size. data_buf_offset += meta_shdr[i].data_size; @@ -830,7 +1112,7 @@ bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32) // Write section headers. if(self_hdr.se_shdroff != 0) { - e.Seek(elf32_hdr.e_shoff); + e.seek(elf32_hdr.e_shoff); for(u32 i = 0; i < elf32_hdr.e_shnum; ++i) WriteShdr(e, shdr32_arr[i]); @@ -870,8 +1152,8 @@ bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32) decomp_stream_out.CopyTo(decomp_buf, phdr64_arr[meta_shdr[i].program_idx].p_filesz); // Seek to the program header data offset and write the data. - e.Seek(phdr64_arr[meta_shdr[i].program_idx].p_offset); - e.Write(decomp_buf, phdr64_arr[meta_shdr[i].program_idx].p_filesz); + e.seek(phdr64_arr[meta_shdr[i].program_idx].p_offset); + e.write(decomp_buf, phdr64_arr[meta_shdr[i].program_idx].p_filesz); // Release the decompression buffer. free(decomp_buf); @@ -879,8 +1161,8 @@ bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32) else { // Seek to the program header data offset and write the data. - e.Seek(phdr64_arr[meta_shdr[i].program_idx].p_offset); - e.Write(data_buf + data_buf_offset, meta_shdr[i].data_size); + e.seek(phdr64_arr[meta_shdr[i].program_idx].p_offset); + e.write(data_buf + data_buf_offset, meta_shdr[i].data_size); } // Advance the data buffer offset by data size. @@ -891,14 +1173,13 @@ bool SELFDecrypter::MakeElf(const std::string& elf, bool isElf32) // Write section headers. if(self_hdr.se_shdroff != 0) { - e.Seek(elf64_hdr.e_shoff); + e.seek(elf64_hdr.e_shoff); for(u32 i = 0; i < elf64_hdr.e_shnum; ++i) WriteShdr(e, shdr64_arr[i]); } } - e.Close(); return true; } @@ -914,24 +1195,23 @@ bool SELFDecrypter::GetKeyFromRap(u8 *content_id, u8 *npdrm_key) std::string rap_path("dev_hdd0/home/" + pf_str + "/exdata/" + ci_str + ".rap"); // Check if we have a valid RAP file. - if (!rExists(rap_path)) + if (!fs::is_file(rap_path)) { LOG_ERROR(LOADER, "This application requires a valid RAP file for decryption!"); return false; } // Open the RAP file and read the key. - rFile rap_file(rap_path, rFile::read); + fs::file rap_file(rap_path); - if (!rap_file.IsOpened()) + if (!rap_file) { LOG_ERROR(LOADER, "Failed to load RAP file!"); return false; } - LOG_NOTICE(LOADER, "Loading RAP file %s", (ci_str + ".rap").c_str()); - rap_file.Read(rap_key, 0x10); - rap_file.Close(); + LOG_NOTICE(LOADER, "Loading RAP file %s.rap", ci_str); + rap_file.read(rap_key, 0x10); // Convert the RAP key. rap_to_rif(rap_key, npdrm_key); @@ -975,18 +1255,18 @@ bool IsSelfElf32(const std::string& path) bool CheckDebugSelf(const std::string& self, const std::string& elf) { // Open the SELF file. - rFile s(self); + fs::file s(self); - if(!s.IsOpened()) + if(!s) { LOG_ERROR(LOADER, "Could not open SELF file! (%s)", self.c_str()); return false; } // Get the key version. - s.Seek(0x08); + s.seek(0x08); u16 key_version; - s.Read(&key_version, sizeof(key_version)); + s.read(&key_version, sizeof(key_version)); // Check for DEBUG version. if(swap16(key_version) == 0x8000) @@ -994,17 +1274,17 @@ bool CheckDebugSelf(const std::string& self, const std::string& elf) LOG_WARNING(LOADER, "Debug SELF detected! Removing fake header..."); // Get the real elf offset. - s.Seek(0x10); + s.seek(0x10); u64 elf_offset; - s.Read(&elf_offset, sizeof(elf_offset)); + s.read(&elf_offset, sizeof(elf_offset)); // Start at the real elf offset. elf_offset = swap64(elf_offset); - s.Seek(elf_offset); + s.seek(elf_offset); // Write the real ELF file back. - rFile e(elf, rFile::write); - if(!e.IsOpened()) + fs::file e(elf, o_write | o_create | o_trunc); + if(!e) { LOG_ERROR(LOADER, "Could not create ELF file! (%s)", elf.c_str()); return false; @@ -1012,18 +1292,14 @@ bool CheckDebugSelf(const std::string& self, const std::string& elf) // Copy the data. char buf[2048]; - while (ssize_t size = s.Read(buf, 2048)) - e.Write(buf, size); + while (ssize_t size = s.read(buf, 2048)) + e.write(buf, size); - e.Close(); return true; } - else - { - // Leave the file untouched. - s.Seek(0); - return false; - } + + // Leave the file untouched. + return false; } bool DecryptSelf(const std::string& elf, const std::string& self) diff --git a/rpcs3/Crypto/unself.h b/rpcs3/Crypto/unself.h index 787fc00c7b..337a933f4a 100644 --- a/rpcs3/Crypto/unself.h +++ b/rpcs3/Crypto/unself.h @@ -1,186 +1,187 @@ #pragma once - -#include "Loader/ELF64.h" -#include "Loader/ELF32.h" #include "key_vault.h" +struct vfsStream; + struct AppInfo { - u64 authid; - u32 vendor_id; - u32 self_type; - u64 version; - u64 padding; + u64 authid; + u32 vendor_id; + u32 self_type; + u64 version; + u64 padding; - void Load(vfsStream& f); - - void Show(); + void Load(vfsStream& f); + void Show(); }; struct SectionInfo { - u64 offset; - u64 size; - u32 compressed; - u32 unknown1; - u32 unknown2; - u32 encrypted; + u64 offset; + u64 size; + u32 compressed; + u32 unknown1; + u32 unknown2; + u32 encrypted; - void Load(vfsStream& f); - - void Show(); + void Load(vfsStream& f); + void Show(); }; struct SCEVersionInfo { - u32 subheader_type; - u32 present; - u32 size; - u32 unknown; + u32 subheader_type; + u32 present; + u32 size; + u32 unknown; - void Load(vfsStream& f); - - void Show(); + void Load(vfsStream& f); + void Show(); }; struct ControlInfo { - u32 type; - u32 size; - u64 next; + u32 type; + u32 size; + u64 next; - union { - // type 1 0x30 bytes - struct { - u32 ctrl_flag1; - u32 unknown1; - u32 unknown2; - u32 unknown3; - u32 unknown4; - u32 unknown5; - u32 unknown6; - u32 unknown7; - } control_flags; + union + { + // type 1 0x30 bytes + struct + { + u32 ctrl_flag1; + u32 unknown1; + u32 unknown2; + u32 unknown3; + u32 unknown4; + u32 unknown5; + u32 unknown6; + u32 unknown7; - // type 2 0x30 bytes - struct { - u8 digest[20]; - u64 unknown; - } file_digest_30; + } control_flags; - // type 2 0x40 bytes - struct { - u8 digest1[20]; - u8 digest2[20]; - u64 unknown; - } file_digest_40; + // type 2 0x30 bytes + struct + { + u8 digest[20]; + u64 unknown; - // type 3 0x90 bytes - struct { - u32 magic; - u32 unknown1; - u32 license; - u32 type; - u8 content_id[48]; - u8 digest[16]; - u8 invdigest[16]; - u8 xordigest[16]; - u64 unknown2; - u64 unknown3; - } npdrm; - }; + } file_digest_30; - void Load(vfsStream& f); + // type 2 0x40 bytes + struct + { + u8 digest1[20]; + u8 digest2[20]; + u64 unknown; - void Show(); + } file_digest_40; + + // type 3 0x90 bytes + struct + { + u32 magic; + u32 unknown1; + u32 license; + u32 type; + u8 content_id[48]; + u8 digest[16]; + u8 invdigest[16]; + u8 xordigest[16]; + u64 unknown2; + u64 unknown3; + + } npdrm; + }; + + void Load(vfsStream& f); + void Show(); }; struct MetadataInfo { - u8 key[0x10]; - u8 key_pad[0x10]; - u8 iv[0x10]; - u8 iv_pad[0x10]; + u8 key[0x10]; + u8 key_pad[0x10]; + u8 iv[0x10]; + u8 iv_pad[0x10]; - void Load(u8* in); - - void Show(); + void Load(u8* in); + void Show(); }; struct MetadataHeader { - u64 signature_input_length; - u32 unknown1; - u32 section_count; - u32 key_count; - u32 opt_header_size; - u32 unknown2; - u32 unknown3; + u64 signature_input_length; + u32 unknown1; + u32 section_count; + u32 key_count; + u32 opt_header_size; + u32 unknown2; + u32 unknown3; - void Load(u8* in); - - void Show(); + void Load(u8* in); + void Show(); }; struct MetadataSectionHeader { - u64 data_offset; - u64 data_size; - u32 type; - u32 program_idx; - u32 hashed; - u32 sha1_idx; - u32 encrypted; - u32 key_idx; - u32 iv_idx; - u32 compressed; + u64 data_offset; + u64 data_size; + u32 type; + u32 program_idx; + u32 hashed; + u32 sha1_idx; + u32 encrypted; + u32 key_idx; + u32 iv_idx; + u32 compressed; - void Load(u8* in); - - void Show(); + void Load(u8* in); + void Show(); }; struct SectionHash { - u8 sha1[20]; - u8 padding[12]; - u8 hmac_key[64]; + u8 sha1[20]; + u8 padding[12]; + u8 hmac_key[64]; - void Load(vfsStream& f); + void Load(vfsStream& f); }; struct CapabilitiesInfo { - u32 type; - u32 capabilities_size; - u32 next; - u32 unknown1; - u64 unknown2; - u64 unknown3; - u64 flags; - u32 unknown4; - u32 unknown5; + u32 type; + u32 capabilities_size; + u32 next; + u32 unknown1; + u64 unknown2; + u64 unknown3; + u64 flags; + u32 unknown4; + u32 unknown5; - void Load(vfsStream& f); + void Load(vfsStream& f); }; struct Signature { - u8 r[21]; - u8 s[21]; - u8 padding[6]; + u8 r[21]; + u8 s[21]; + u8 padding[6]; - void Load(vfsStream& f); + void Load(vfsStream& f); }; struct SelfSection { - u8 *data; - u64 size; - u64 offset; + u8 *data; + u64 size; + u64 offset; - void Load(vfsStream& f); + void Load(vfsStream& f); }; struct Elf32_Ehdr @@ -204,55 +205,10 @@ struct Elf32_Ehdr u16 e_shentsize; u16 e_shnum; u16 e_shstrndx; + + void Load(vfsStream& f); void Show() {} - bool IsLittleEndian() const - { - return e_data == 1; - } - - void Load(vfsStream& f) - { - e_magic = Read32(f); - e_class = Read8(f); - e_data = Read8(f); - e_curver = Read8(f); - e_os_abi = Read8(f); - - if (IsLittleEndian()) - { - e_abi_ver = Read64LE(f); - e_type = Read16LE(f); - e_machine = Read16LE(f); - e_version = Read32LE(f); - e_entry = Read32LE(f); - e_phoff = Read32LE(f); - e_shoff = Read32LE(f); - e_flags = Read32LE(f); - e_ehsize = Read16LE(f); - e_phentsize = Read16LE(f); - e_phnum = Read16LE(f); - e_shentsize = Read16LE(f); - e_shnum = Read16LE(f); - e_shstrndx = Read16LE(f); - } - else - { - e_abi_ver = Read64(f); - e_type = Read16(f); - e_machine = Read16(f); - e_version = Read32(f); - e_entry = Read32(f); - e_phoff = Read32(f); - e_shoff = Read32(f); - e_flags = Read32(f); - e_ehsize = Read16(f); - e_phentsize = Read16(f); - e_phnum = Read16(f); - e_shentsize = Read16(f); - e_shnum = Read16(f); - e_shstrndx = Read16(f); - } - } + bool IsLittleEndian() const { return e_data == 1; } bool CheckMagic() const { return e_magic == 0x7F454C46; } u32 GetEntry() const { return e_entry; } }; @@ -269,25 +225,12 @@ struct Elf32_Shdr u32 sh_info; u32 sh_addralign; u32 sh_entsize; - void Load(vfsStream& f) - { - sh_name = Read32(f); - sh_type = Read32(f); - sh_flags = Read32(f); - sh_addr = Read32(f); - sh_offset = Read32(f); - sh_size = Read32(f); - sh_link = Read32(f); - sh_info = Read32(f); - sh_addralign = Read32(f); - sh_entsize = Read32(f); - } - void LoadLE(vfsStream& f) - { - f.Read(this, sizeof(*this)); - } + + void Load(vfsStream& f); + void LoadLE(vfsStream& f); void Show() {} }; + struct Elf32_Phdr { u32 p_type; @@ -298,21 +241,9 @@ struct Elf32_Phdr u32 p_memsz; u32 p_flags; u32 p_align; - void Load(vfsStream& f) - { - p_type = Read32(f); - p_offset = Read32(f); - p_vaddr = Read32(f); - p_paddr = Read32(f); - p_filesz = Read32(f); - p_memsz = Read32(f); - p_flags = Read32(f); - p_align = Read32(f); - } - void LoadLE(vfsStream& f) - { - f.Read(this, sizeof(*this)); - } + + void Load(vfsStream& f); + void LoadLE(vfsStream& f); void Show() {} }; @@ -337,28 +268,8 @@ struct Elf64_Ehdr u16 e_shentsize; u16 e_shnum; u16 e_shstrndx; - void Load(vfsStream& f) - { - e_magic = Read32(f); - e_class = Read8(f); - e_data = Read8(f); - e_curver = Read8(f); - e_os_abi = Read8(f); - e_abi_ver = Read64(f); - e_type = Read16(f); - e_machine = Read16(f); - e_version = Read32(f); - e_entry = Read64(f); - e_phoff = Read64(f); - e_shoff = Read64(f); - e_flags = Read32(f); - e_ehsize = Read16(f); - e_phentsize = Read16(f); - e_phnum = Read16(f); - e_shentsize = Read16(f); - e_shnum = Read16(f); - e_shstrndx = Read16(f); - } + + void Load(vfsStream& f); void Show() {} bool CheckMagic() const { return e_magic == 0x7F454C46; } u64 GetEntry() const { return e_entry; } @@ -376,19 +287,8 @@ struct Elf64_Shdr u32 sh_info; u64 sh_addralign; u64 sh_entsize; - void Load(vfsStream& f) - { - sh_name = Read32(f); - sh_type = Read32(f); - sh_flags = Read64(f); - sh_addr = Read64(f); - sh_offset = Read64(f); - sh_size = Read64(f); - sh_link = Read32(f); - sh_info = Read32(f); - sh_addralign = Read64(f); - sh_entsize = Read64(f); - } + + void Load(vfsStream& f); void Show(){} }; @@ -402,17 +302,8 @@ struct Elf64_Phdr u64 p_filesz; u64 p_memsz; u64 p_align; - void Load(vfsStream& f) - { - p_type = Read32(f); - p_flags = Read32(f); - p_offset = Read64(f); - p_vaddr = Read64(f); - p_paddr = Read64(f); - p_filesz = Read64(f); - p_memsz = Read64(f); - p_align = Read64(f); - } + + void Load(vfsStream& f); void Show(){} }; @@ -425,16 +316,8 @@ struct SceHeader u32 se_meta; u64 se_hsize; u64 se_esize; - void Load(vfsStream& f) - { - se_magic = Read32(f); - se_hver = Read32(f); - se_flags = Read16(f); - se_type = Read16(f); - se_meta = Read32(f); - se_hsize = Read64(f); - se_esize = Read64(f); - } + + void Load(vfsStream& f); void Show(){} bool CheckMagic() const { return se_magic == 0x53434500; } }; @@ -451,23 +334,11 @@ struct SelfHeader u64 se_controloff; u64 se_controlsize; u64 pad; - void Load(vfsStream& f) - { - se_htype = Read64(f); - se_appinfooff = Read64(f); - se_elfoff = Read64(f); - se_phdroff = Read64(f); - se_shdroff = Read64(f); - se_secinfoff = Read64(f); - se_sceveroff = Read64(f); - se_controloff = Read64(f); - se_controlsize = Read64(f); - pad = Read64(f); - } + + void Load(vfsStream& f); void Show(){} }; - class SELFDecrypter { // Main SELF file stream. diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp b/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp index b619d5bb6b..42bdedb6d2 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLibKernel.cpp @@ -64,7 +64,7 @@ s32 sceKernelStartThread(s32 threadId, u32 argSize, vm::psv::ptr pAr { sceLibKernel.Warning("sceKernelStartThread(threadId=0x%x, argSize=0x%x, pArgBlock=*0x%x)", threadId, argSize, pArgBlock); - std::shared_ptr t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7); + const auto t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7); if (!t) { @@ -106,7 +106,7 @@ s32 sceKernelDeleteThread(s32 threadId) { sceLibKernel.Warning("sceKernelDeleteThread(threadId=0x%x)", threadId); - std::shared_ptr t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7); + const auto t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7); if (!t) { @@ -264,7 +264,7 @@ s32 sceKernelWaitThreadEnd(s32 threadId, vm::psv::ptr pExitStatus, vm::psv: { sceLibKernel.Warning("sceKernelWaitThreadEnd(threadId=0x%x, pExitStatus=*0x%x, pTimeout=*0x%x)", threadId, pExitStatus, pTimeout); - std::shared_ptr t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7); + const auto t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7); if (!t) { diff --git a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp index 85dba9cb20..d93e74af5f 100644 --- a/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp +++ b/rpcs3/Emu/ARMv7/Modules/sceLibc.cpp @@ -259,7 +259,7 @@ namespace sce_libc_func psv_log_base sceLibc("SceLibc", []() { - g_dso.set(0); + g_dso = vm::null; g_atexit.clear(); sceLibc.on_load = nullptr; diff --git a/rpcs3/Emu/ARMv7/PSVFuncList.h b/rpcs3/Emu/ARMv7/PSVFuncList.h index 811f33675a..170b6690e5 100644 --- a/rpcs3/Emu/ARMv7/PSVFuncList.h +++ b/rpcs3/Emu/ARMv7/PSVFuncList.h @@ -46,7 +46,7 @@ namespace psv_func_detail ARG_STACK, }; - static const auto FIXED_STACK_FRAME_SIZE = 0x100; // described in CB_FUNC.h + static const auto FIXED_STACK_FRAME_SIZE = 0x80; // described in CB_FUNC.h template struct bind_arg; diff --git a/rpcs3/Emu/Audio/AudioDumper.cpp b/rpcs3/Emu/Audio/AudioDumper.cpp index 1ccd7d24cc..7353a499a3 100644 --- a/rpcs3/Emu/Audio/AudioDumper.cpp +++ b/rpcs3/Emu/Audio/AudioDumper.cpp @@ -12,7 +12,7 @@ AudioDumper::~AudioDumper() bool AudioDumper::Init(u8 ch) { - if ((m_init = m_output.Open("audio.wav", rFile::write))) + if ((m_init = m_output.open("audio.wav", o_write | o_create | o_trunc))) { m_header = WAVHeader(ch); WriteHeader(); @@ -25,7 +25,7 @@ void AudioDumper::WriteHeader() { if (m_init) { - m_output.Write(&m_header, sizeof(m_header)); // write file header + m_output.write(&m_header, sizeof(m_header)); // write file header } } @@ -47,7 +47,7 @@ size_t AudioDumper::WriteData(const void* buffer, size_t size) if (m_init) #endif { - size_t ret = m_output.Write(buffer, size); + size_t ret = m_output.write(buffer, size); m_header.Size += (u32)ret; m_header.RIFF.Size += (u32)ret; return ret; @@ -60,8 +60,8 @@ void AudioDumper::Finalize() { if (m_init) { - m_output.Seek(0); - m_output.Write(&m_header, sizeof(m_header)); // write fixed file header - m_output.Close(); + m_output.seek(0); + m_output.write(&m_header, sizeof(m_header)); // write fixed file header + m_output.close(); } } \ No newline at end of file diff --git a/rpcs3/Emu/Audio/AudioDumper.h b/rpcs3/Emu/Audio/AudioDumper.h index 849adb851d..fa629b254d 100644 --- a/rpcs3/Emu/Audio/AudioDumper.h +++ b/rpcs3/Emu/Audio/AudioDumper.h @@ -1,6 +1,5 @@ #pragma once - -#include "Utilities/rFile.h" +#include "Utilities/File.h" struct WAVHeader { @@ -56,7 +55,7 @@ struct WAVHeader class AudioDumper { WAVHeader m_header; - rFile m_output; + fs::file m_output; bool m_init; public: diff --git a/rpcs3/Emu/CPU/CPUThread.h b/rpcs3/Emu/CPU/CPUThread.h index e81d79216e..d006ace661 100644 --- a/rpcs3/Emu/CPU/CPUThread.h +++ b/rpcs3/Emu/CPU/CPUThread.h @@ -77,7 +77,7 @@ public: std::string GetName() const { return NamedThreadBase::GetThreadName(); } std::string GetFName() const { - return fmt::format("%s[%d] Thread (%s)", GetTypeString(), m_id, GetName()); + return fmt::format("%s[0x%x] Thread (%s)", GetTypeString(), m_id, GetName()); } static std::string CPUThreadTypeToString(CPUThreadType type) diff --git a/rpcs3/Emu/CPU/CPUThreadManager.cpp b/rpcs3/Emu/CPU/CPUThreadManager.cpp index 027384f878..6e6953e9d4 100644 --- a/rpcs3/Emu/CPU/CPUThreadManager.cpp +++ b/rpcs3/Emu/CPU/CPUThreadManager.cpp @@ -112,26 +112,14 @@ void CPUThreadManager::RemoveThread(u32 id) std::shared_ptr CPUThreadManager::GetThread(u32 id) { - std::shared_ptr res; - - if (!id) return nullptr; - - if (!Emu.GetIdManager().GetIDData(id, res)) return nullptr; - - return res; + return Emu.GetIdManager().GetIDData(id); } std::shared_ptr CPUThreadManager::GetThread(u32 id, CPUThreadType type) { - std::shared_ptr res; + const auto res = GetThread(id); - if (!id) return nullptr; - - if (!Emu.GetIdManager().GetIDData(id, res)) return nullptr; - - if (res->GetType() != type) return nullptr; - - return res; + return res && res->GetType() == type ? res : nullptr; } std::shared_ptr CPUThreadManager::GetRawSPUThread(u32 index) diff --git a/rpcs3/Emu/CPU/CPUThreadManager.h b/rpcs3/Emu/CPU/CPUThreadManager.h index f335b871da..0bdcb05ce4 100644 --- a/rpcs3/Emu/CPU/CPUThreadManager.h +++ b/rpcs3/Emu/CPU/CPUThreadManager.h @@ -1,7 +1,6 @@ #pragma once class CPUThread; -class RawSPUThread; enum CPUThreadType : unsigned char; class CPUThreadManager diff --git a/rpcs3/Emu/Cell/PPULLVMRecompiler.h b/rpcs3/Emu/Cell/PPULLVMRecompiler.h index 81e28f66b6..5ab812e8b6 100644 --- a/rpcs3/Emu/Cell/PPULLVMRecompiler.h +++ b/rpcs3/Emu/Cell/PPULLVMRecompiler.h @@ -4,6 +4,7 @@ #ifdef LLVM_AVAILABLE #define PPU_LLVM_RECOMPILER 1 +#include #include "Emu/Cell/PPUDecoder.h" #include "Emu/Cell/PPUThread.h" #include "Emu/Cell/PPUInterpreter.h" diff --git a/rpcs3/Emu/Cell/PPUProgramCompiler.cpp b/rpcs3/Emu/Cell/PPUProgramCompiler.cpp index 532b26d36a..3ce377834d 100644 --- a/rpcs3/Emu/Cell/PPUProgramCompiler.cpp +++ b/rpcs3/Emu/Cell/PPUProgramCompiler.cpp @@ -1,6 +1,6 @@ #include "stdafx_gui.h" #include "PPUProgramCompiler.h" -#include "Utilities/rFile.h" +#include "Utilities/File.h" /* using namespace PPU_instr; diff --git a/rpcs3/Emu/Cell/PPUThread.cpp b/rpcs3/Emu/Cell/PPUThread.cpp index 393efddff1..d7945fd2f9 100644 --- a/rpcs3/Emu/Cell/PPUThread.cpp +++ b/rpcs3/Emu/Cell/PPUThread.cpp @@ -663,7 +663,7 @@ void PPUThread::FastCall2(u32 addr, u32 rtoc) { auto old_status = m_status; auto old_PC = PC; - auto old_stack = GPR[1]; // only saved and restored (may be wrong) + auto old_stack = GPR[1]; auto old_rtoc = GPR[2]; auto old_LR = LR; auto old_thread = GetCurrentNamedThread(); @@ -680,7 +680,13 @@ void PPUThread::FastCall2(u32 addr, u32 rtoc) m_status = old_status; PC = old_PC; - GPR[1] = old_stack; + + if (GPR[1] != old_stack && !Emu.IsStopped()) // GPR[1] shouldn't change + { + LOG_ERROR(PPU, "PPUThread::FastCall2(0x%x,0x%x): stack inconsistency (SP=0x%llx, old=0x%llx)", addr, rtoc, GPR[1], old_stack); + GPR[1] = old_stack; + } + GPR[2] = old_rtoc; LR = old_LR; SetCurrentNamedThread(old_thread); diff --git a/rpcs3/Emu/Cell/SPUInterpreter.cpp b/rpcs3/Emu/Cell/SPUInterpreter.cpp index b4cee8d155..40ae80fdde 100644 --- a/rpcs3/Emu/Cell/SPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/SPUInterpreter.cpp @@ -18,26 +18,6 @@ #define rotl32(x,r) (((u32)(x) << (r)) | ((u32)(x) >> (32 - (r)))) #endif -class spu_scale_table_t -{ - std::array<__m128, 155 + 174> m_data; - -public: - spu_scale_table_t() - { - for (s32 i = -155; i < 174; i++) - { - m_data[i + 155] = _mm_set1_ps(static_cast(exp2(i))); - } - } - - __forceinline __m128 operator [] (s32 scale) const - { - return m_data[scale + 155]; - } -} -const g_spu_scale_table; - void spu_interpreter::DEFAULT(SPUThread& CPU, spu_opcode_t op) { @@ -405,17 +385,17 @@ void spu_interpreter::GBB(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::FSM(SPUThread& CPU, spu_opcode_t op) { - CPU.GPR[op.rt].vi = g_imm_table.fsm_table[CPU.GPR[op.ra]._u32[3] & 0xf]; + CPU.GPR[op.rt] = g_spu_imm.fsm[CPU.GPR[op.ra]._u32[3] & 0xf]; } void spu_interpreter::FSMH(SPUThread& CPU, spu_opcode_t op) { - CPU.GPR[op.rt].vi = g_imm_table.fsmh_table[CPU.GPR[op.ra]._u32[3] & 0xff]; + CPU.GPR[op.rt] = g_spu_imm.fsmh[CPU.GPR[op.ra]._u32[3] & 0xff]; } void spu_interpreter::FSMB(SPUThread& CPU, spu_opcode_t op) { - CPU.GPR[op.rt].vi = g_imm_table.fsmb_table[CPU.GPR[op.ra]._u32[3] & 0xffff]; + CPU.GPR[op.rt] = g_spu_imm.fsmb[CPU.GPR[op.ra]._u32[3] & 0xffff]; } void spu_interpreter::FREST(SPUThread& CPU, spu_opcode_t op) @@ -436,17 +416,17 @@ void spu_interpreter::LQX(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::ROTQBYBI(SPUThread& CPU, spu_opcode_t op) { - CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_imm_table.rldq_pshufb[CPU.GPR[op.rb]._u32[3] >> 3 & 0xf]); + CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_spu_imm.rldq_pshufb[CPU.GPR[op.rb]._u32[3] >> 3 & 0xf].vi); } void spu_interpreter::ROTQMBYBI(SPUThread& CPU, spu_opcode_t op) { - CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_imm_table.srdq_pshufb[-(CPU.GPR[op.rb]._s32[3] >> 3) & 0x1f]); + CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_spu_imm.srdq_pshufb[-(CPU.GPR[op.rb]._s32[3] >> 3) & 0x1f].vi); } void spu_interpreter::SHLQBYBI(SPUThread& CPU, spu_opcode_t op) { - CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_imm_table.sldq_pshufb[CPU.GPR[op.rb]._u32[3] >> 3 & 0x1f]); + CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_spu_imm.sldq_pshufb[CPU.GPR[op.rb]._u32[3] >> 3 & 0x1f].vi); } void spu_interpreter::CBX(SPUThread& CPU, spu_opcode_t op) @@ -500,17 +480,17 @@ void spu_interpreter::SHLQBI(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::ROTQBY(SPUThread& CPU, spu_opcode_t op) { - CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_imm_table.rldq_pshufb[CPU.GPR[op.rb]._u32[3] & 0xf]); + CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_spu_imm.rldq_pshufb[CPU.GPR[op.rb]._u32[3] & 0xf].vi); } void spu_interpreter::ROTQMBY(SPUThread& CPU, spu_opcode_t op) { - CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_imm_table.srdq_pshufb[-CPU.GPR[op.rb]._s32[3] & 0x1f]); + CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_spu_imm.srdq_pshufb[-CPU.GPR[op.rb]._s32[3] & 0x1f].vi); } void spu_interpreter::SHLQBY(SPUThread& CPU, spu_opcode_t op) { - CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_imm_table.sldq_pshufb[CPU.GPR[op.rb]._u32[3] & 0x1f]); + CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_spu_imm.sldq_pshufb[CPU.GPR[op.rb]._u32[3] & 0x1f].vi); } void spu_interpreter::ORX(SPUThread& CPU, spu_opcode_t op) @@ -569,17 +549,17 @@ void spu_interpreter::SHLQBII(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::ROTQBYI(SPUThread& CPU, spu_opcode_t op) { - CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_imm_table.rldq_pshufb[op.i7 & 0xf]); + CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_spu_imm.rldq_pshufb[op.i7 & 0xf].vi); } void spu_interpreter::ROTQMBYI(SPUThread& CPU, spu_opcode_t op) { - CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_imm_table.srdq_pshufb[-op.si7 & 0x1f]); + CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_spu_imm.srdq_pshufb[-op.si7 & 0x1f].vi); } void spu_interpreter::SHLQBYI(SPUThread& CPU, spu_opcode_t op) { - CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_imm_table.sldq_pshufb[op.i7 & 0x1f]); + CPU.GPR[op.rt].vi = _mm_shuffle_epi8(CPU.GPR[op.ra].vi, g_spu_imm.sldq_pshufb[op.i7 & 0x1f].vi); } void spu_interpreter::NOP(SPUThread& CPU, spu_opcode_t op) @@ -770,9 +750,9 @@ void spu_interpreter::CEQ(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::MPYHHU(SPUThread& CPU, spu_opcode_t op) { - const auto a = _mm_srli_epi32(CPU.GPR[op.ra].vi, 16); - const auto b = _mm_srli_epi32(CPU.GPR[op.rb].vi, 16); - CPU.GPR[op.rt].vi = _mm_or_si128(_mm_slli_epi32(_mm_mulhi_epu16(a, b), 16), _mm_mullo_epi16(a, b)); + const auto a = CPU.GPR[op.ra].vi; + const auto b = CPU.GPR[op.rb].vi; + CPU.GPR[op.rt].vi = _mm_or_si128(_mm_srli_epi32(_mm_mullo_epi16(a, b), 16), _mm_and_si128(_mm_mulhi_epu16(a, b), _mm_set1_epi32(0xffff0000))); } void spu_interpreter::ADDX(SPUThread& CPU, spu_opcode_t op) @@ -810,9 +790,9 @@ void spu_interpreter::MPYHHA(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::MPYHHAU(SPUThread& CPU, spu_opcode_t op) { - const auto a = _mm_srli_epi32(CPU.GPR[op.ra].vi, 16); - const auto b = _mm_srli_epi32(CPU.GPR[op.rb].vi, 16); - CPU.GPR[op.rt].vi = _mm_add_epi32(CPU.GPR[op.rt].vi, _mm_or_si128(_mm_slli_epi32(_mm_mulhi_epu16(a, b), 16), _mm_mullo_epi16(a, b))); + const auto a = CPU.GPR[op.ra].vi; + const auto b = CPU.GPR[op.rb].vi; + CPU.GPR[op.rt].vi = _mm_add_epi32(CPU.GPR[op.rt].vi, _mm_or_si128(_mm_srli_epi32(_mm_mullo_epi16(a, b), 16), _mm_and_si128(_mm_mulhi_epu16(a, b), _mm_set1_epi32(0xffff0000)))); } void spu_interpreter::FSCRRD(SPUThread& CPU, spu_opcode_t op) @@ -890,9 +870,9 @@ void spu_interpreter::DFCMEQ(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::MPYU(SPUThread& CPU, spu_opcode_t op) { - const auto a = _mm_and_si128(CPU.GPR[op.ra].vi, _mm_set1_epi32(0xffff)); - const auto b = _mm_and_si128(CPU.GPR[op.rb].vi, _mm_set1_epi32(0xffff)); - CPU.GPR[op.rt].vi = _mm_or_si128(_mm_slli_epi32(_mm_mulhi_epu16(a, b), 16), _mm_mullo_epi16(a, b)); + const auto a = CPU.GPR[op.ra].vi; + const auto b = CPU.GPR[op.rb].vi; + CPU.GPR[op.rt].vi = _mm_or_si128(_mm_slli_epi32(_mm_mulhi_epu16(a, b), 16), _mm_and_si128(_mm_mullo_epi16(a, b), _mm_set1_epi32(0xffff))); } void spu_interpreter::CEQB(SPUThread& CPU, spu_opcode_t op) @@ -907,8 +887,8 @@ void spu_interpreter::FI(SPUThread& CPU, spu_opcode_t op) const auto mask_sf = _mm_set1_epi32(0x000003ff); // step fraction mask const auto mask_yf = _mm_set1_epi32(0x0007ffff); // Y fraction mask (bits 13..31) const auto base = _mm_or_ps(_mm_and_ps(CPU.GPR[op.rb].vf, mask_bf), _mm_castsi128_ps(_mm_set1_epi32(0x3f800000))); - const auto step = _mm_mul_ps(_mm_cvtepi32_ps(_mm_and_si128(CPU.GPR[op.rb].vi, mask_sf)), g_spu_scale_table[-13]); - const auto y = _mm_mul_ps(_mm_cvtepi32_ps(_mm_and_si128(CPU.GPR[op.ra].vi, mask_yf)), g_spu_scale_table[-19]); + const auto step = _mm_mul_ps(_mm_cvtepi32_ps(_mm_and_si128(CPU.GPR[op.rb].vi, mask_sf)), _mm_set1_ps(exp2f(-13))); + const auto y = _mm_mul_ps(_mm_cvtepi32_ps(_mm_and_si128(CPU.GPR[op.ra].vi, mask_yf)), _mm_set1_ps(exp2f(-19))); CPU.GPR[op.rt].vf = _mm_or_ps(_mm_and_ps(mask_se, CPU.GPR[op.rb].vf), _mm_andnot_ps(mask_se, _mm_sub_ps(base, _mm_mul_ps(step, y)))); } @@ -923,27 +903,27 @@ void spu_interpreter::HEQ(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::CFLTS(SPUThread& CPU, spu_opcode_t op) { - const auto scaled = _mm_mul_ps(CPU.GPR[op.ra].vf, g_spu_scale_table[173 - op.i8]); + const auto scaled = _mm_mul_ps(CPU.GPR[op.ra].vf, g_spu_imm.scale[173 - op.i8]); CPU.GPR[op.rt].vi = _mm_xor_si128(_mm_cvttps_epi32(scaled), _mm_castps_si128(_mm_cmpge_ps(scaled, _mm_set1_ps(0x80000000)))); } void spu_interpreter::CFLTU(SPUThread& CPU, spu_opcode_t op) { - const auto scaled1 = _mm_max_ps(_mm_mul_ps(CPU.GPR[op.ra].vf, g_spu_scale_table[173 - op.i8]), _mm_set1_ps(0.0f)); + const auto scaled1 = _mm_max_ps(_mm_mul_ps(CPU.GPR[op.ra].vf, g_spu_imm.scale[173 - op.i8]), _mm_set1_ps(0.0f)); const auto scaled2 = _mm_and_ps(_mm_sub_ps(scaled1, _mm_set1_ps(0x80000000)), _mm_cmpge_ps(scaled1, _mm_set1_ps(0x80000000))); CPU.GPR[op.rt].vi = _mm_or_si128(_mm_or_si128(_mm_cvttps_epi32(scaled1), _mm_cvttps_epi32(scaled2)), _mm_castps_si128(_mm_cmpge_ps(scaled1, _mm_set1_ps(0x100000000)))); } void spu_interpreter::CSFLT(SPUThread& CPU, spu_opcode_t op) { - CPU.GPR[op.rt].vf = _mm_mul_ps(_mm_cvtepi32_ps(CPU.GPR[op.ra].vi), g_spu_scale_table[op.i8 - 155]); + CPU.GPR[op.rt].vf = _mm_mul_ps(_mm_cvtepi32_ps(CPU.GPR[op.ra].vi), g_spu_imm.scale[op.i8 - 155]); } void spu_interpreter::CUFLT(SPUThread& CPU, spu_opcode_t op) { const auto a = CPU.GPR[op.ra].vi; const auto fix = _mm_and_ps(_mm_castsi128_ps(_mm_srai_epi32(a, 31)), _mm_set1_ps(0x80000000)); - CPU.GPR[op.rt].vf = _mm_mul_ps(_mm_add_ps(_mm_cvtepi32_ps(_mm_and_si128(a, _mm_set1_epi32(0x7fffffff))), fix), g_spu_scale_table[op.i8 - 155]); + CPU.GPR[op.rt].vf = _mm_mul_ps(_mm_add_ps(_mm_cvtepi32_ps(_mm_and_si128(a, _mm_set1_epi32(0x7fffffff))), fix), g_spu_imm.scale[op.i8 - 155]); } @@ -1013,7 +993,7 @@ void spu_interpreter::BR(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::FSMBI(SPUThread& CPU, spu_opcode_t op) { - CPU.GPR[op.rt].vi = g_imm_table.fsmb_table[op.i16]; + CPU.GPR[op.rt] = g_spu_imm.fsmb[op.i16]; } void spu_interpreter::BRSL(SPUThread& CPU, spu_opcode_t op) @@ -1177,7 +1157,7 @@ void spu_interpreter::MPYI(SPUThread& CPU, spu_opcode_t op) void spu_interpreter::MPYUI(SPUThread& CPU, spu_opcode_t op) { - const auto a = _mm_and_si128(CPU.GPR[op.ra].vi, _mm_set1_epi32(0xffff)); + const auto a = CPU.GPR[op.ra].vi; const auto i = _mm_set1_epi32(op.si10 & 0xffff); CPU.GPR[op.rt].vi = _mm_or_si128(_mm_slli_epi32(_mm_mulhi_epu16(a, i), 16), _mm_mullo_epi16(a, i)); } diff --git a/rpcs3/Emu/Cell/SPURecompiler.h b/rpcs3/Emu/Cell/SPURecompiler.h index 0391532151..1287970cff 100644 --- a/rpcs3/Emu/Cell/SPURecompiler.h +++ b/rpcs3/Emu/Cell/SPURecompiler.h @@ -28,14 +28,11 @@ public: u16 count; // count of instructions compiled from current point (and to be checked) u32 valid; // copy of valid opcode for validation void* pointer; // pointer to executable memory object -#ifdef _WIN32 - //_IMAGE_RUNTIME_FUNCTION_ENTRY info; -#endif }; SPURecEntry entry[0x10000]; - std::vector<__m128i> imm_table; + std::vector imm_table; SPURecompilerCore(SPUThread& cpu); @@ -50,25 +47,16 @@ public: #define c (*compiler) -#ifdef _WIN32 -#define cpu_xmm(x) oword_ptr(*cpu_var, (sizeof((*(SPUThread*)nullptr).x) == 16) ? (s32)offsetof(SPUThread, x) : throw "sizeof("#x") != 16") -#define cpu_qword(x) qword_ptr(*cpu_var, (sizeof((*(SPUThread*)nullptr).x) == 8) ? (s32)offsetof(SPUThread, x) : throw "sizeof("#x") != 8") -#define cpu_dword(x) dword_ptr(*cpu_var, (sizeof((*(SPUThread*)nullptr).x) == 4) ? (s32)offsetof(SPUThread, x) : throw "sizeof("#x") != 4") -#define cpu_word(x) word_ptr(*cpu_var, (sizeof((*(SPUThread*)nullptr).x) == 2) ? (s32)offsetof(SPUThread, x) : throw "sizeof("#x") != 2") -#define cpu_byte(x) byte_ptr(*cpu_var, (sizeof((*(SPUThread*)nullptr).x) == 1) ? (s32)offsetof(SPUThread, x) : throw "sizeof("#x") != 1") +#define cpu_offsetof(x) static_cast(reinterpret_cast(&(((SPUThread*)0)->x))) +#define cpu_xmm(x) oword_ptr(*cpu_var, cpu_offsetof(x)) +#define cpu_qword(x) qword_ptr(*cpu_var, cpu_offsetof(x)) +#define cpu_dword(x) dword_ptr(*cpu_var, cpu_offsetof(x)) +#define cpu_word(x) word_ptr(*cpu_var, cpu_offsetof(x)) +#define cpu_byte(x) byte_ptr(*cpu_var, cpu_offsetof(x)) -#define g_imm_xmm(x) oword_ptr(*g_imm_var, (s32)offsetof(g_imm_table_struct, x)) -#define g_imm2_xmm(x, y) oword_ptr(*g_imm_var, y, 0, (s32)offsetof(g_imm_table_struct, x)) -#else -#define cpu_xmm(x) oword_ptr(*cpu_var, reinterpret_cast(&(((SPUThread*)0)->x)) ) -#define cpu_qword(x) qword_ptr(*cpu_var, reinterpret_cast(&(((SPUThread*)0)->x)) ) -#define cpu_dword(x) dword_ptr(*cpu_var, reinterpret_cast(&(((SPUThread*)0)->x)) ) -#define cpu_word(x) word_ptr(*cpu_var, reinterpret_cast(&(((SPUThread*)0)->x)) ) -#define cpu_byte(x) byte_ptr(*cpu_var, reinterpret_cast(&(((SPUThread*)0)->x)) ) - -#define g_imm_xmm(x) oword_ptr(*g_imm_var, reinterpret_cast(&(((g_imm_table_struct*)0)->x))) -#define g_imm2_xmm(x, y) oword_ptr(*g_imm_var, y, 0, reinterpret_cast(&(((g_imm_table_struct*)0)->x))) -#endif +#define g_imm_offsetof(x) static_cast(reinterpret_cast(&(((g_spu_imm_table_t*)0)->x))) +#define g_imm_xmm(x) oword_ptr(*g_imm_var, g_imm_offsetof(x)) +#define g_imm2_xmm(x, y) oword_ptr(*g_imm_var, y, 0, g_imm_offsetof(x)) #define LOG_OPCODE(...) //ConLog.Write("Compiled "__FUNCTION__"(): "__VA_ARGS__) @@ -217,8 +205,8 @@ public: { if (xmm_var[i].reg == reg) { - assert(!xmm_var[i].got); - if (xmm_var[i].got) throw "XmmRead(): wrong reuse"; + //assert(!xmm_var[i].got); + //if (xmm_var[i].got) throw "XmmRead(): wrong reuse"; LOG4_OPCODE("GPR[%d] has been read (i=%d)", reg, i); xmm_var[i].access++; return &xmm_var[i]; @@ -352,23 +340,20 @@ public: } } - Mem XmmConst(const __m128i& data) + Mem XmmConst(u128 data) { - for (u32 i = 0; i < rec.imm_table.size(); i++) + s32 shift = 0; + + for (; shift < rec.imm_table.size(); shift++) { - if (mmToU64Ptr(rec.imm_table[i])[0] == mmToU64Ptr(data)[0] && mmToU64Ptr(rec.imm_table[i])[1] == mmToU64Ptr(data)[1]) + if (rec.imm_table[shift] == data) { - return oword_ptr(*imm_var, i * sizeof(__m128i)); + return oword_ptr(*imm_var, shift * sizeof(u128)); } } - const size_t shift = rec.imm_table.size() * sizeof(__m128i); - rec.imm_table.push_back(data); - return oword_ptr(*imm_var, (s32)shift); - } - Mem XmmConst(const __m128& data) - { - return XmmConst((__m128i&)data); + rec.imm_table.push_back(data); + return oword_ptr(*imm_var, shift * sizeof(u128)); } private: @@ -432,111 +417,67 @@ private: } void SF(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + // sub from + const XmmLink& vb = XmmGet(rb, rt); + if (const XmmLink* va = XmmRead(ra)) { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); + c.psubd(vb.get(), va->read()); } else { - // sub from - const XmmLink& vb = XmmGet(rb, rt); - if (const XmmLink* va = XmmRead(ra)) - { - c.psubd(vb.get(), va->read()); - } - else - { - c.psubd(vb.get(), cpu_xmm(GPR[ra])); - } - XmmFinalize(vb, rt); + c.psubd(vb.get(), cpu_xmm(GPR[ra])); } + XmmFinalize(vb, rt); LOG_OPCODE(); } void OR(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + const XmmLink& vb = XmmGet(rb, rt); + if (const XmmLink* va = XmmRead(ra)) { - // mov - if (ra != rt) - { - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop + c.por(vb.get(), va->read()); } else { - // or - const XmmLink& vb = XmmGet(rb, rt); - if (const XmmLink* va = XmmRead(ra)) - { - c.por(vb.get(), va->read()); - } - else - { - c.por(vb.get(), cpu_xmm(GPR[ra])); - } - XmmFinalize(vb, rt); + c.por(vb.get(), cpu_xmm(GPR[ra])); } + XmmFinalize(vb, rt); LOG_OPCODE(); } void BG(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + // compare if-greater-than + const XmmLink& va = XmmGet(ra, rt); + const XmmLink& vi = XmmAlloc(); + c.movdqa(vi.get(), XmmConst(u128::from32p(0x80000000))); + c.pxor(va.get(), vi.get()); + if (const XmmLink* vb = XmmRead(rb)) { - const XmmLink& v1 = XmmAlloc(rt); - c.movdqa(v1.get(), XmmConst(_mm_set1_epi32(1))); - XmmFinalize(v1, rt); + c.pxor(vi.get(), vb->read()); } else { - // compare if-greater-than - const XmmLink& va = XmmGet(ra, rt); - const XmmLink& vb = XmmGet(rb); - c.psubd(va.get(), XmmConst(_mm_set1_epi32(0x80000000))); - c.psubd(vb.get(), XmmConst(_mm_set1_epi32(0x80000000))); - c.pcmpgtd(va.get(), vb.get()); - c.paddd(va.get(), XmmConst(_mm_set1_epi32(1))); - XmmFinalize(va, rt); - XmmFinalize(vb); - // sign bits: - // a b (b-a) -> (result of BG) - // 0 0 0 -> 1 - // 0 0 1 -> 0 - // 0 1 0 -> 1 - // 0 1 1 -> 1 - // 1 0 0 -> 0 - // 1 0 1 -> 0 - // 1 1 0 -> 0 - // 1 1 1 -> 1 + c.pxor(vi.get(), cpu_xmm(GPR[rb])); } + c.pcmpgtd(va.get(), vi.get()); + c.paddd(va.get(), XmmConst(u128::from32p(1))); + XmmFinalize(va, rt); + XmmFinalize(vi); LOG_OPCODE(); } void SFH(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + // sub from (halfword) + const XmmLink& vb = XmmGet(rb, rt); + if (const XmmLink* va = XmmRead(ra)) { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); + c.psubw(vb.get(), va->read()); } else { - const XmmLink& vb = XmmGet(rb, rt); - if (const XmmLink* va = XmmRead(ra)) - { - c.psubw(vb.get(), va->read()); - } - else - { - c.psubw(vb.get(), cpu_xmm(GPR[ra])); - } - XmmFinalize(vb, rt); + c.psubw(vb.get(), cpu_xmm(GPR[ra])); } + XmmFinalize(vb, rt); LOG_OPCODE(); } void NOR(u32 rt, u32 ra, u32 rb) @@ -553,31 +494,21 @@ private: c.por(va.get(), cpu_xmm(GPR[rb])); } } - c.pxor(va.get(), XmmConst(_mm_set1_epi32(-1))); + c.pxor(va.get(), XmmConst(u128::from32p(0xffffffff))); XmmFinalize(va, rt); LOG_OPCODE(); } void ABSDB(u32 rt, u32 ra, u32 rb) { - if (ra == rb) - { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); - } - else - { - const XmmLink& va = XmmGet(ra, rt); - const XmmLink& vb = XmmGet(rb); - const XmmLink& vm = XmmCopy(va); - c.pmaxub(va.get(), vb.get()); - c.pminub(vb.get(), vm.get()); - c.psubb(va.get(), vb.get()); - XmmFinalize(va, rt); - XmmFinalize(vb); - XmmFinalize(vm); - } + const XmmLink& va = XmmGet(ra, rt); + const XmmLink& vb = XmmGet(rb); + const XmmLink& vm = XmmCopy(va); + c.pmaxub(va.get(), vb.get()); + c.pminub(vb.get(), vm.get()); + c.psubb(va.get(), vb.get()); + XmmFinalize(va, rt); + XmmFinalize(vb); + XmmFinalize(vm); LOG_OPCODE(); } void ROT(u32 rt, u32 ra, u32 rb) @@ -682,334 +613,157 @@ private: } void ROTI(u32 rt, u32 ra, s32 i7) { + // rotate left const int s = i7 & 0x1f; - if (s == 0) - { - // mov - if (ra != rt) - { - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else - { - const XmmLink& va = XmmGet(ra, rt); - const XmmLink& v1 = XmmCopy(va); - c.pslld(va.get(), s); - c.psrld(v1.get(), 32 - s); - c.por(va.get(), v1.get()); - XmmFinalize(va, rt); - XmmFinalize(v1); - } + const XmmLink& va = XmmGet(ra, rt); + const XmmLink& v1 = XmmCopy(va); + c.pslld(va.get(), s); + c.psrld(v1.get(), 32 - s); + c.por(va.get(), v1.get()); + XmmFinalize(va, rt); + XmmFinalize(v1); LOG_OPCODE(); } void ROTMI(u32 rt, u32 ra, s32 i7) { + // shift right logical const int s = (0 - i7) & 0x3f; - if (s > 31) - { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); - } - else if (s == 0) - { - // mov - if (ra != rt) - { - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else - { - // shift right logical - const XmmLink& va = XmmGet(ra, rt); - c.psrld(va.get(), s); - XmmFinalize(va, rt); - } + const XmmLink& va = XmmGet(ra, rt); + c.psrld(va.get(), s); + XmmFinalize(va, rt); LOG_OPCODE(); } void ROTMAI(u32 rt, u32 ra, s32 i7) { + // shift right arithmetical const int s = (0 - i7) & 0x3f; - if (s == 0) - { - // mov - if (ra != rt) - { - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else - { - // shift right arithmetical - const XmmLink& va = XmmGet(ra, rt); - c.psrad(va.get(), s); - XmmFinalize(va, rt); - } + const XmmLink& va = XmmGet(ra, rt); + c.psrad(va.get(), s); + XmmFinalize(va, rt); LOG_OPCODE(); } void SHLI(u32 rt, u32 ra, s32 i7) { + // shift left const int s = i7 & 0x3f; - if (s > 31) - { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); - } - else if (s == 0) - { - // mov - if (ra != rt) - { - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else - { - // shift left - const XmmLink& va = XmmGet(ra, rt); - c.pslld(va.get(), s); - XmmFinalize(va, rt); - } + const XmmLink& va = XmmGet(ra, rt); + c.pslld(va.get(), s); + XmmFinalize(va, rt); LOG_OPCODE(); } void ROTHI(u32 rt, u32 ra, s32 i7) { + // rotate left (halfword) const int s = i7 & 0xf; - if (s == 0) - { - // mov - if (ra != rt) - { - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else - { - const XmmLink& va = XmmGet(ra, rt); - const XmmLink& v1 = XmmCopy(va); - c.psllw(va.get(), s); - c.psrlw(v1.get(), 16 - s); - c.por(va.get(), v1.get()); - XmmFinalize(va, rt); - XmmFinalize(v1); - } + const XmmLink& va = XmmGet(ra, rt); + const XmmLink& v1 = XmmCopy(va); + c.psllw(va.get(), s); + c.psrlw(v1.get(), 16 - s); + c.por(va.get(), v1.get()); + XmmFinalize(va, rt); + XmmFinalize(v1); LOG_OPCODE(); } void ROTHMI(u32 rt, u32 ra, s32 i7) { + // shift right logical const int s = (0 - i7) & 0x1f; - if (s > 15) - { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); - } - else if (s == 0) - { - // mov - if (ra != rt) - { - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else - { - // shift right logical - const XmmLink& va = XmmGet(ra, rt); - c.psrlw(va.get(), s); - XmmFinalize(va, rt); - } + const XmmLink& va = XmmGet(ra, rt); + c.psrlw(va.get(), s); + XmmFinalize(va, rt); LOG_OPCODE(); } void ROTMAHI(u32 rt, u32 ra, s32 i7) { + // shift right arithmetical (halfword) const int s = (0 - i7) & 0x1f; - if (s == 0) - { - // mov - if (ra != rt) - { - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else - { - // shift right arithmetical - const XmmLink& va = XmmGet(ra, rt); - c.psraw(va.get(), s); - XmmFinalize(va, rt); - } + const XmmLink& va = XmmGet(ra, rt); + c.psraw(va.get(), s); + XmmFinalize(va, rt); LOG_OPCODE(); } void SHLHI(u32 rt, u32 ra, s32 i7) { + // shift left (halfword) const int s = i7 & 0x1f; - if (s > 15) - { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); - } - else if (s == 0) - { - // mov - if (ra != rt) - { - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else - { - // shift left - const XmmLink& va = XmmGet(ra, rt); - c.psllw(va.get(), s); - XmmFinalize(va, rt); - } + const XmmLink& va = XmmGet(ra, rt); + c.psllw(va.get(), s); + XmmFinalize(va, rt); LOG_OPCODE(); } void A(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + const XmmLink& vb = XmmGet(rb, rt); + if (const XmmLink* va = XmmRead(ra)) { - const XmmLink& vb = XmmGet(rb, rt); - c.paddd(vb.get(), vb.get()); - XmmFinalize(vb, rt); + c.paddd(vb.get(), va->read()); } else { - const XmmLink& vb = XmmGet(rb, rt); - if (const XmmLink* va = XmmRead(ra)) - { - c.paddd(vb.get(), va->read()); - } - else - { - c.paddd(vb.get(), cpu_xmm(GPR[ra])); - } - XmmFinalize(vb, rt); + c.paddd(vb.get(), cpu_xmm(GPR[ra])); } + XmmFinalize(vb, rt); LOG_OPCODE(); } void AND(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + // and + const XmmLink& vb = XmmGet(rb, rt); + if (const XmmLink* va = XmmRead(ra)) { - if (rt != ra) - { - // mov - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop + c.pand(vb.get(), va->read()); } else { - // and - const XmmLink& vb = XmmGet(rb, rt); - if (const XmmLink* va = XmmRead(ra)) - { - c.pand(vb.get(), va->read()); - } - else - { - c.pand(vb.get(), cpu_xmm(GPR[ra])); - } - XmmFinalize(vb, rt); + c.pand(vb.get(), cpu_xmm(GPR[ra])); } + XmmFinalize(vb, rt); LOG_OPCODE(); } void CG(u32 rt, u32 ra, u32 rb) { - if (ra == rb) - { - const XmmLink& va = XmmGet(ra, rt); - c.psrld(va.get(), 31); - XmmFinalize(va, rt); - } - else - { - const XmmLink& va = XmmGet(ra, rt); - const XmmLink& vb = XmmGet(rb); - c.paddd(vb.get(), va.get()); - c.psubd(va.get(), XmmConst(_mm_set1_epi32(0x80000000))); - c.psubd(vb.get(), XmmConst(_mm_set1_epi32(0x80000000))); - c.pcmpgtd(va.get(), vb.get()); - c.psrld(va.get(), 31); - XmmFinalize(va, rt); - XmmFinalize(vb); - } + const XmmLink& va = XmmGet(ra, rt); + const XmmLink& vb = XmmGet(rb); + const XmmLink& vi = XmmAlloc(); + c.movdqa(vi.get(), XmmConst(u128::from32p(0x80000000))); + c.paddd(vb.get(), va.get()); + c.pxor(va.get(), vi.get()); + c.pxor(vb.get(), vi.get()); + c.pcmpgtd(va.get(), vb.get()); + c.psrld(va.get(), 31); + XmmFinalize(va, rt); + XmmFinalize(vb); + XmmFinalize(vi); LOG_OPCODE(); } void AH(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + const XmmLink& va = XmmGet(ra, rt); + if (const XmmLink* vb = XmmRead(rb)) { - const XmmLink& va = XmmGet(ra, rt); - c.paddw(va.get(), va.get()); - XmmFinalize(va, rt); + c.paddw(va.get(), vb->read()); } else { - const XmmLink& va = XmmGet(ra, rt); - if (const XmmLink* vb = XmmRead(rb)) - { - c.paddw(va.get(), vb->read()); - } - else - { - c.paddw(va.get(), cpu_xmm(GPR[rb])); - } - XmmFinalize(va, rt); + c.paddw(va.get(), cpu_xmm(GPR[rb])); } + XmmFinalize(va, rt); LOG_OPCODE(); } void NAND(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + // nand + const XmmLink& va = XmmGet(ra, rt); + if (const XmmLink* vb = XmmRead(rb)) { - // not - const XmmLink& va = XmmGet(ra, rt); - c.pxor(va.get(), XmmConst(_mm_set1_epi32(-1))); - XmmFinalize(va, rt); + c.pand(va.get(), vb->read()); } else { - // nand - const XmmLink& va = XmmGet(ra, rt); - if (const XmmLink* vb = XmmRead(rb)) - { - c.pand(va.get(), vb->read()); - } - else - { - c.pand(va.get(), cpu_xmm(GPR[rb])); - } - c.pxor(va.get(), XmmConst(_mm_set1_epi32(-1))); - XmmFinalize(va, rt); + c.pand(va.get(), cpu_xmm(GPR[rb])); } + c.pxor(va.get(), XmmConst(u128::from32p(0xffffffff))); + XmmFinalize(va, rt); LOG_OPCODE(); } void AVGB(u32 rt, u32 ra, u32 rb) @@ -1027,7 +781,6 @@ private: } void MTSPR(u32 rt, u32 sa) { - UNIMPLEMENTED(); } void WRCH(u32 ra, u32 rt) { @@ -1232,31 +985,29 @@ private: void GB(u32 rt, u32 ra) { const XmmLink& va = XmmGet(ra, rt); - c.pand(va.get(), XmmConst(_mm_set1_epi32(1))); - c.pmullw(va.get(), XmmConst(_mm_set_epi32(8, 4, 2, 1))); - c.phaddd(va.get(), va.get()); - c.phaddd(va.get(), va.get()); - c.pand(va.get(), XmmConst(_mm_set_epi32(0xffffffff, 0, 0, 0))); + c.pshufb(va.get(), XmmConst(u128::fromV(_mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, 8, 4, 0)))); + c.psllq(va.get(), 7); + c.pmovmskb(*addr, va.get()); + c.pxor(va.get(), va.get()); + c.pinsrw(va.get(), *addr, 6); XmmFinalize(va, rt); LOG_OPCODE(); } void GBH(u32 rt, u32 ra) { const XmmLink& va = XmmGet(ra, rt); - c.pand(va.get(), XmmConst(_mm_set1_epi16(1))); - c.pmullw(va.get(), XmmConst(_mm_set_epi16(128, 64, 32, 16, 8, 4, 2, 1))); - c.phaddw(va.get(), va.get()); - c.phaddw(va.get(), va.get()); - c.phaddw(va.get(), va.get()); - c.pand(va.get(), XmmConst(_mm_set_epi32(0xffff, 0, 0, 0))); + c.pshufb(va.get(), XmmConst(u128::fromV(_mm_set_epi8(-1, -1, -1, -1, -1, -1, -1, -1, 14, 12, 10, 8, 6, 4, 2, 0)))); + c.psllq(va.get(), 7); + c.pmovmskb(*addr, va.get()); + c.pxor(va.get(), va.get()); + c.pinsrw(va.get(), *addr, 6); XmmFinalize(va, rt); LOG_OPCODE(); } void GBB(u32 rt, u32 ra) { const XmmLink& va = XmmGet(ra, rt); - //c.pand(va.get(), XmmConst(_mm_set1_epi8(1))); // ??? - c.pslld(va.get(), 7); + c.psllq(va.get(), 7); c.pmovmskb(*addr, va.get()); c.pxor(va.get(), va.get()); c.pinsrw(va.get(), *addr, 6); @@ -1269,7 +1020,7 @@ private: c.mov(*addr, cpu_dword(GPR[ra]._u32[3])); c.and_(*addr, 0xf); c.shl(*addr, 4); - c.movdqa(vr.get(), g_imm2_xmm(fsm_table[0], *addr)); + c.movdqa(vr.get(), g_imm2_xmm(fsm[0], *addr)); XmmFinalize(vr, rt); LOG_OPCODE(); } @@ -1279,7 +1030,7 @@ private: c.mov(*addr, cpu_dword(GPR[ra]._u32[3])); c.and_(*addr, 0xff); c.shl(*addr, 4); - c.movdqa(vr.get(), g_imm2_xmm(fsmh_table[0], *addr)); + c.movdqa(vr.get(), g_imm2_xmm(fsmh[0], *addr)); XmmFinalize(vr, rt); LOG_OPCODE(); } @@ -1289,7 +1040,7 @@ private: c.mov(*addr, cpu_dword(GPR[ra]._u32[3])); c.and_(*addr, 0xffff); c.shl(*addr, 4); - c.movdqa(vr.get(), g_imm2_xmm(fsmb_table[0], *addr)); + c.movdqa(vr.get(), g_imm2_xmm(fsmb[0], *addr)); XmmFinalize(vr, rt); LOG_OPCODE(); } @@ -1303,7 +1054,7 @@ private: void FRSQEST(u32 rt, u32 ra) { const XmmLink& va = XmmGet(ra, rt); - c.andps(va.get(), XmmConst(_mm_set1_epi32(0x7fffffff))); // abs + c.andps(va.get(), XmmConst(u128::from32p(0x7fffffff))); // abs c.rsqrtps(va.get(), va.get()); XmmFinalize(va, rt); LOG_OPCODE(); @@ -1387,7 +1138,7 @@ private: c.not_(*addr); c.and_(*addr, 0xf); const XmmLink& vr = XmmAlloc(rt); - c.movdqa(vr.get(), XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f))); + c.movdqa(vr.get(), XmmConst(u128::fromV(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)))); XmmFinalize(vr, rt); XmmInvalidate(rt); c.mov(byte_ptr(*cpu_var, *addr, 0, (s32)offsetof(SPUThread, GPR[rt]._u8[0])), 0x03); @@ -1411,7 +1162,7 @@ private: c.not_(*addr); c.and_(*addr, 0xe); const XmmLink& vr = XmmAlloc(rt); - c.movdqa(vr.get(), XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f))); + c.movdqa(vr.get(), XmmConst(u128::fromV(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)))); XmmFinalize(vr, rt); XmmInvalidate(rt); c.mov(word_ptr(*cpu_var, *addr, 0, (s32)offsetof(SPUThread, GPR[rt]._u16[0])), 0x0203); @@ -1435,7 +1186,7 @@ private: c.not_(*addr); c.and_(*addr, 0xc); const XmmLink& vr = XmmAlloc(rt); - c.movdqa(vr.get(), XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f))); + c.movdqa(vr.get(), XmmConst(u128::fromV(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)))); XmmFinalize(vr, rt); XmmInvalidate(rt); c.mov(dword_ptr(*cpu_var, *addr, 0, (s32)offsetof(SPUThread, GPR[rt]._u32[0])), 0x00010203); @@ -1459,7 +1210,7 @@ private: c.not_(*addr); c.and_(*addr, 0x8); const XmmLink& vr = XmmAlloc(rt); - c.movdqa(vr.get(), XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f))); + c.movdqa(vr.get(), XmmConst(u128::fromV(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)))); XmmFinalize(vr, rt); XmmInvalidate(rt); c.mov(dword_ptr(*cpu_var, *addr, 0, (s32)offsetof(SPUThread, GPR[rt]._u32[0])), 0x04050607); @@ -1560,7 +1311,7 @@ private: const XmmLink& vr = XmmAlloc(rt); u128 value = u128::fromV(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)); value.u8r[i7 & 0xf] = 0x03; - c.movdqa(vr.get(), XmmConst(value.vi)); + c.movdqa(vr.get(), XmmConst(value)); XmmFinalize(vr, rt); } else @@ -1570,7 +1321,7 @@ private: c.not_(*addr); c.and_(*addr, 0xf); const XmmLink& vr = XmmAlloc(rt); - c.movdqa(vr.get(), XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f))); + c.movdqa(vr.get(), XmmConst(u128::fromV(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)))); XmmFinalize(vr, rt); XmmInvalidate(rt); c.mov(byte_ptr(*cpu_var, *addr, 0, (s32)offsetof(SPUThread, GPR[rt]._u8[0])), 0x03); @@ -1585,7 +1336,7 @@ private: const XmmLink& vr = XmmAlloc(rt); u128 value = u128::fromV(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)); value.u16r[(i7 >> 1) & 0x7] = 0x0203; - c.movdqa(vr.get(), XmmConst(value.vi)); + c.movdqa(vr.get(), XmmConst(value)); XmmFinalize(vr, rt); } else @@ -1595,7 +1346,7 @@ private: c.not_(*addr); c.and_(*addr, 0xe); const XmmLink& vr = XmmAlloc(rt); - c.movdqa(vr.get(), XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f))); + c.movdqa(vr.get(), XmmConst(u128::fromV(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)))); XmmFinalize(vr, rt); XmmInvalidate(rt); c.mov(word_ptr(*cpu_var, *addr, 0, (s32)offsetof(SPUThread, GPR[rt]._u16[0])), 0x0203); @@ -1610,7 +1361,7 @@ private: const XmmLink& vr = XmmAlloc(rt); u128 value = u128::fromV(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)); value.u32r[(i7 >> 2) & 0x3] = 0x00010203; - c.movdqa(vr.get(), XmmConst(value.vi)); + c.movdqa(vr.get(), XmmConst(value)); XmmFinalize(vr, rt); } else @@ -1620,7 +1371,7 @@ private: c.not_(*addr); c.and_(*addr, 0xc); const XmmLink& vr = XmmAlloc(rt); - c.movdqa(vr.get(), XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f))); + c.movdqa(vr.get(), XmmConst(u128::fromV(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)))); XmmFinalize(vr, rt); XmmInvalidate(rt); c.mov(dword_ptr(*cpu_var, *addr, 0, (s32)offsetof(SPUThread, GPR[rt]._u32[0])), 0x00010203); @@ -1635,7 +1386,7 @@ private: const XmmLink& vr = XmmAlloc(rt); u128 value = u128::fromV(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)); value.u64r[(i7 >> 3) & 0x1] = 0x0001020304050607ull; - c.movdqa(vr.get(), XmmConst(value.vi)); + c.movdqa(vr.get(), XmmConst(value)); XmmFinalize(vr, rt); } else @@ -1645,7 +1396,7 @@ private: c.not_(*addr); c.and_(*addr, 0x8); const XmmLink& vr = XmmAlloc(rt); - c.movdqa(vr.get(), XmmConst(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f))); + c.movdqa(vr.get(), XmmConst(u128::fromV(_mm_set_epi32(0x10111213, 0x14151617, 0x18191a1b, 0x1c1d1e1f)))); XmmFinalize(vr, rt); XmmInvalidate(rt); c.mov(dword_ptr(*cpu_var, *addr, 0, (s32)offsetof(SPUThread, GPR[rt]._u32[0])), 0x04050607); @@ -1690,81 +1441,25 @@ private: void ROTQBYI(u32 rt, u32 ra, s32 i7) { const int s = i7 & 0xf; - if (s == 0) - { - // mov - if (ra != rt) - { - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else - { - // rotate left - const XmmLink& va = XmmGet(ra, rt); - c.palignr(va.get(), va.get(), 16 - s); - XmmFinalize(va, rt); - } + const XmmLink& va = XmmGet(ra, rt); + c.palignr(va.get(), va.get(), 16 - s); + XmmFinalize(va, rt); LOG_OPCODE(); } void ROTQMBYI(u32 rt, u32 ra, s32 i7) { const int s = (0 - i7) & 0x1f; - if (s == 0) - { - if (ra != rt) - { - // mov - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else if (s > 15) - { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); - } - else - { - // shift right - const XmmLink& va = XmmGet(ra, rt); - c.psrldq(va.get(), s); - XmmFinalize(va, rt); - } + const XmmLink& va = XmmGet(ra, rt); + c.psrldq(va.get(), s); + XmmFinalize(va, rt); LOG_OPCODE(); } void SHLQBYI(u32 rt, u32 ra, s32 i7) - { + { const int s = i7 & 0x1f; - if (s == 0) - { - if (ra != rt) - { - // mov - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else if (s > 15) - { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); - } - else - { - // shift left - const XmmLink& va = XmmGet(ra, rt); - c.pslldq(va.get(), s); - XmmFinalize(va, rt); - } + const XmmLink& va = XmmGet(ra, rt); + c.pslldq(va.get(), s); + XmmFinalize(va, rt); LOG_OPCODE(); } void NOP(u32 rt) @@ -1773,174 +1468,89 @@ private: } void CGT(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + const XmmLink& va = XmmGet(ra, rt); + if (const XmmLink* vb = XmmRead(rb)) { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); + c.pcmpgtd(va.get(), vb->read()); } else { - const XmmLink& va = XmmGet(ra, rt); - if (const XmmLink* vb = XmmRead(rb)) - { - c.pcmpgtd(va.get(), vb->read()); - } - else - { - c.pcmpgtd(va.get(), cpu_xmm(GPR[rb])); - } - XmmFinalize(va, rt); + c.pcmpgtd(va.get(), cpu_xmm(GPR[rb])); } + XmmFinalize(va, rt); LOG_OPCODE(); } void XOR(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + // xor + const XmmLink& va = XmmGet(ra, rt); + if (const XmmLink* vb = XmmRead(rb)) { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); + c.pxor(va.get(), vb->read()); } else { - // xor - const XmmLink& va = XmmGet(ra, rt); - if (const XmmLink* vb = XmmRead(rb)) - { - c.pxor(va.get(), vb->read()); - } - else - { - c.pxor(va.get(), cpu_xmm(GPR[rb])); - } - XmmFinalize(va, rt); + c.pxor(va.get(), cpu_xmm(GPR[rb])); } + XmmFinalize(va, rt); LOG_OPCODE(); } void CGTH(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + const XmmLink& va = XmmGet(ra, rt); + if (const XmmLink* vb = XmmRead(rb)) { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); + c.pcmpgtw(va.get(), vb->read()); } else { - const XmmLink& va = XmmGet(ra, rt); - if (const XmmLink* vb = XmmRead(rb)) - { - c.pcmpgtw(va.get(), vb->read()); - } - else - { - c.pcmpgtw(va.get(), cpu_xmm(GPR[rb])); - } - XmmFinalize(va, rt); + c.pcmpgtw(va.get(), cpu_xmm(GPR[rb])); } + XmmFinalize(va, rt); LOG_OPCODE(); } void EQV(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + const XmmLink& vb = XmmGet(rb, rt); + c.pxor(vb.get(), XmmConst(u128::from32p(0xffffffff))); + if (const XmmLink* va = XmmRead(ra)) { - const XmmLink& v1 = XmmAlloc(rt); - c.pcmpeqd(v1.get(), v1.get()); - XmmFinalize(v1, rt); + c.pxor(vb.get(), va->read()); } else { - const XmmLink& vb = XmmGet(rb, rt); - c.pxor(vb.get(), XmmConst(_mm_set1_epi32(-1))); - if (const XmmLink* va = XmmRead(ra)) - { - c.pxor(vb.get(), va->read()); - } - else - { - c.pxor(vb.get(), cpu_xmm(GPR[ra])); - } - XmmFinalize(vb, rt); + c.pxor(vb.get(), cpu_xmm(GPR[ra])); } + XmmFinalize(vb, rt); LOG_OPCODE(); } void CGTB(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + const XmmLink& va = XmmGet(ra, rt); + if (const XmmLink* vb = XmmRead(rb)) { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); + c.pcmpgtb(va.get(), vb->read()); } else { - const XmmLink& va = XmmGet(ra, rt); - if (const XmmLink* vb = XmmRead(rb)) - { - c.pcmpgtb(va.get(), vb->read()); - } - else - { - c.pcmpgtb(va.get(), cpu_xmm(GPR[rb])); - } - XmmFinalize(va, rt); + c.pcmpgtb(va.get(), cpu_xmm(GPR[rb])); } + XmmFinalize(va, rt); LOG_OPCODE(); } void SUMB(u32 rt, u32 ra, u32 rb) { - /*WRAPPER_BEGIN(rt, ra, rb, zz); - const SPU_GPR_hdr _a = CPU.GPR[ra]; - const SPU_GPR_hdr _b = CPU.GPR[rb]; - for (int w = 0; w < 4; w++) - { - CPU.GPR[rt]._u16[w*2] = _a._u8[w*4] + _a._u8[w*4 + 1] + _a._u8[w*4 + 2] + _a._u8[w*4 + 3]; - CPU.GPR[rt]._u16[w*2 + 1] = _b._u8[w*4] + _b._u8[w*4 + 1] + _b._u8[w*4 + 2] + _b._u8[w*4 + 3]; - } - WRAPPER_END(rt, ra, rb, 0);*/ - - const XmmLink& va = XmmGet(ra); + const XmmLink& va = XmmGet(ra, rt); const XmmLink& vb = (ra == rb) ? XmmCopy(va) : XmmGet(rb); - const XmmLink& v1 = XmmCopy(vb, rt); - const XmmLink& v2 = XmmCopy(vb); - const XmmLink& vFF = XmmAlloc(); - c.movdqa(vFF.get(), XmmConst(_mm_set1_epi32(0xff))); - c.pand(v1.get(), vFF.get()); - c.psrld(v2.get(), 8); - c.pand(v2.get(), vFF.get()); - c.paddd(v1.get(), v2.get()); - c.movdqa(v2.get(), vb.get()); - c.psrld(v2.get(), 16); - c.pand(v2.get(), vFF.get()); - c.paddd(v1.get(), v2.get()); - c.movdqa(v2.get(), vb.get()); - c.psrld(v2.get(), 24); - c.paddd(v1.get(), v2.get()); - c.pslld(v1.get(), 16); - c.movdqa(v2.get(), va.get()); - c.pand(v2.get(), vFF.get()); - c.por(v1.get(), v2.get()); - c.movdqa(v2.get(), va.get()); - c.psrld(v2.get(), 8); - c.pand(v2.get(), vFF.get()); - c.paddd(v1.get(), v2.get()); - c.movdqa(v2.get(), va.get()); - c.psrld(v2.get(), 16); - c.pand(v2.get(), vFF.get()); - c.paddd(v1.get(), v2.get()); - c.movdqa(v2.get(), va.get()); - c.psrld(v2.get(), 24); - c.paddd(v1.get(), v2.get()); + const XmmLink& vi = XmmAlloc(); + c.movdqa(vi.get(), XmmConst(u128::from8p(1))); + c.pmaddubsw(va.get(), vi.get()); + c.pmaddubsw(vb.get(), vi.get()); + c.phaddw(va.get(), vb.get()); + c.pshufb(va.get(), XmmConst(u128::fromV(_mm_set_epi8(15, 14, 7, 6, 13, 12, 5, 4, 11, 10, 3, 2, 9, 8, 1, 0)))); + XmmFinalize(va, rt); XmmFinalize(vb); - XmmFinalize(va); - XmmFinalize(v1, rt); - XmmFinalize(v2); - XmmFinalize(vFF); + XmmFinalize(vi); LOG_OPCODE(); } //HGT uses signed values. HLGT uses unsigned values @@ -1987,22 +1597,16 @@ private: } void CNTB(u32 rt, u32 ra) { - /*XmmInvalidate(rt); - for (u32 i = 0; i < 8; i++) - { - c.movzx(*addr, cpu_word(GPR[ra]._u16[i])); - c.movzx(*addr, word_ptr(*g_imm_var, *addr, 1, (s32)offsetof(g_imm_table_struct, cntb_table[0]))); - c.mov(cpu_word(GPR[rt]._u16[i]), addr->r16()); - }*/ const XmmLink& va = XmmGet(ra, rt); const XmmLink& v1 = XmmCopy(va); const XmmLink& vm = XmmAlloc(); - c.psrlw(v1.get(), 4); - c.pand(va.get(), XmmConst(_mm_set1_epi8(0xf))); - c.pand(v1.get(), XmmConst(_mm_set1_epi8(0xf))); - c.movdqa(vm.get(), XmmConst(_mm_set_epi8(4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0))); + c.psrlq(v1.get(), 4); + c.movdqa(vm.get(), XmmConst(u128::from8p(0xf))); + c.pand(va.get(), vm.get()); + c.pand(v1.get(), vm.get()); + c.movdqa(vm.get(), XmmConst(u128::fromV(_mm_set_epi8(4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0)))); c.pshufb(vm.get(), va.get()); - c.movdqa(va.get(), XmmConst(_mm_set_epi8(4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0))); + c.movdqa(va.get(), XmmConst(u128::fromV(_mm_set_epi8(4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0)))); c.pshufb(va.get(), v1.get()); c.paddb(va.get(), vm.get()); XmmFinalize(va, rt); @@ -2020,49 +1624,37 @@ private: } void CLGT(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + // compare if-greater-than + const XmmLink& va = XmmGet(ra, rt); + const XmmLink& vi = XmmAlloc(); + c.movdqa(vi.get(), XmmConst(u128::from32p(0x80000000))); + c.pxor(va.get(), vi.get()); + if (const XmmLink* vb = XmmRead(rb)) { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); + c.pxor(vi.get(), vb->read()); } else { - // compare if-greater-than - const XmmLink& va = XmmGet(ra, rt); - const XmmLink& vb = XmmGet(rb); - c.psubd(va.get(), XmmConst(_mm_set1_epi32(0x80000000))); - c.psubd(vb.get(), XmmConst(_mm_set1_epi32(0x80000000))); - c.pcmpgtd(va.get(), vb.get()); - XmmFinalize(va, rt); - XmmFinalize(vb); + c.pxor(vi.get(), cpu_xmm(GPR[rb])); } + c.pcmpgtd(va.get(), vi.get()); + XmmFinalize(va, rt); + XmmFinalize(vi); LOG_OPCODE(); } void ANDC(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + // and not + const XmmLink& vb = XmmGet(rb, rt); + if (const XmmLink* va = XmmRead(ra)) { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); + c.pandn(vb.get(), va->read()); } else { - // and not - const XmmLink& vb = XmmGet(rb, rt); - if (const XmmLink* va = XmmRead(ra)) - { - c.pandn(vb.get(), va->read()); - } - else - { - c.pandn(vb.get(), cpu_xmm(GPR[ra])); - } - XmmFinalize(vb, rt); + c.pandn(vb.get(), cpu_xmm(GPR[ra])); } + XmmFinalize(vb, rt); LOG_OPCODE(); } void FCGT(u32 rt, u32 ra, u32 rb) @@ -2087,127 +1679,98 @@ private: void FA(u32 rt, u32 ra, u32 rb) { const XmmLink& va = XmmGet(ra, rt); - if (ra == rb) + if (const XmmLink* vb = XmmRead(rb)) { - c.addps(va.get(), va.get()); + c.addps(va.get(), vb->read()); } else { - if (const XmmLink* vb = XmmRead(rb)) - { - c.addps(va.get(), vb->read()); - } - else - { - c.addps(va.get(), cpu_xmm(GPR[rb])); - } + c.addps(va.get(), cpu_xmm(GPR[rb])); } XmmFinalize(va, rt); LOG_OPCODE(); } void FS(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + const XmmLink& va = XmmGet(ra, rt); + if (const XmmLink* vb = XmmRead(rb)) { - // zero (?) - const XmmLink& v0 = XmmAlloc(rt); - c.subps(v0.get(), v0.get()); - XmmFinalize(v0, rt); + c.subps(va.get(), vb->read()); } else { - const XmmLink& va = XmmGet(ra, rt); - if (const XmmLink* vb = XmmRead(rb)) - { - c.subps(va.get(), vb->read()); - } - else - { - c.subps(va.get(), cpu_xmm(GPR[rb])); - } - XmmFinalize(va, rt); + c.subps(va.get(), cpu_xmm(GPR[rb])); } + XmmFinalize(va, rt); LOG_OPCODE(); } void FM(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + const XmmLink& va = XmmGet(ra, rt); + if (const XmmLink* vb = XmmRead(rb)) { - const XmmLink& va = XmmGet(ra, rt); - c.mulps(va.get(), va.get()); - XmmFinalize(va, rt); + c.mulps(va.get(), vb->read()); } else { - const XmmLink& va = XmmGet(ra, rt); - if (const XmmLink* vb = XmmRead(rb)) - { - c.mulps(va.get(), vb->read()); - } - else - { - c.mulps(va.get(), cpu_xmm(GPR[rb])); - } - XmmFinalize(va, rt); + c.mulps(va.get(), cpu_xmm(GPR[rb])); } + XmmFinalize(va, rt); LOG_OPCODE(); } void CLGTH(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + // compare if-greater-than + const XmmLink& va = XmmGet(ra, rt); + const XmmLink& vi = XmmAlloc(); + c.movdqa(vi.get(), XmmConst(u128::from16p(0x8000))); + c.pxor(va.get(), vi.get()); + if (const XmmLink* vb = XmmRead(rb)) { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); + c.pxor(vi.get(), vb->read()); } else { - // compare if-greater-than - const XmmLink& va = XmmGet(ra, rt); - const XmmLink& vb = XmmGet(rb); - c.psubw(va.get(), XmmConst(_mm_set1_epi32(0x80008000))); - c.psubw(vb.get(), XmmConst(_mm_set1_epi32(0x80008000))); - c.pcmpgtw(va.get(), vb.get()); - XmmFinalize(va, rt); - XmmFinalize(vb); + c.pxor(vi.get(), cpu_xmm(GPR[rb])); } + c.pcmpgtw(va.get(), vi.get()); + XmmFinalize(va, rt); + XmmFinalize(vi); LOG_OPCODE(); } void ORC(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + const XmmLink& vb = XmmGet(rb, rt); + c.pxor(vb.get(), XmmConst(u128::from32p(0xffffffff))); + if (const XmmLink* va = XmmRead(ra)) { - const XmmLink& v1 = XmmAlloc(rt); - c.pcmpeqd(v1.get(), v1.get()); - XmmFinalize(v1, rt); + c.por(vb.get(), va->read()); } else { - const XmmLink& vb = XmmGet(rb, rt); - c.pxor(vb.get(), XmmConst(_mm_set1_epi32(-1))); - if (const XmmLink* va = XmmRead(ra)) - { - c.por(vb.get(), va->read()); - } - else - { - c.por(vb.get(), cpu_xmm(GPR[ra])); - } - XmmFinalize(vb, rt); + c.por(vb.get(), cpu_xmm(GPR[ra])); } + XmmFinalize(vb, rt); LOG_OPCODE(); } void FCMGT(u32 rt, u32 ra, u32 rb) { // reverted less-than const XmmLink& vb = XmmGet(rb, rt); - const XmmLink& va = XmmGet(ra); - c.andps(vb.get(), XmmConst(_mm_set1_epi32(0x7fffffff))); // abs - c.andps(va.get(), XmmConst(_mm_set1_epi32(0x7fffffff))); // abs - c.cmpps(vb.get(), va.get(), 1); + const XmmLink& vi = XmmAlloc(); + c.movaps(vi.get(), XmmConst(u128::from32p(0x7fffffff))); + c.andps(vb.get(), vi.get()); // abs + if (const XmmLink* va = XmmRead(ra)) + { + c.andps(vi.get(), va->read()); + } + else + { + c.andps(vi.get(), cpu_xmm(GPR[ra])); + } + c.cmpps(vb.get(), vi.get(), 1); XmmFinalize(vb, rt); - XmmFinalize(va); + XmmFinalize(vi); LOG_OPCODE(); } void DFCMGT(u32 rt, u32 ra, u32 rb) @@ -2217,91 +1780,63 @@ private: void DFA(u32 rt, u32 ra, u32 rb) { const XmmLink& va = XmmGet(ra, rt); - if (ra == rb) + if (const XmmLink* vb = XmmRead(rb)) { - c.addpd(va.get(), va.get()); + c.addpd(va.get(), vb->read()); } else { - if (const XmmLink* vb = XmmRead(rb)) - { - c.addpd(va.get(), vb->read()); - } - else - { - c.addpd(va.get(), cpu_xmm(GPR[rb])); - } + c.addpd(va.get(), cpu_xmm(GPR[rb])); } XmmFinalize(va, rt); LOG_OPCODE(); } void DFS(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + const XmmLink& va = XmmGet(ra, rt); + if (const XmmLink* vb = XmmRead(rb)) { - // zero (?) - const XmmLink& v0 = XmmAlloc(rt); - c.subpd(v0.get(), v0.get()); - XmmFinalize(v0, rt); + c.subpd(va.get(), vb->read()); } else { - const XmmLink& va = XmmGet(ra, rt); - if (const XmmLink* vb = XmmRead(rb)) - { - c.subpd(va.get(), vb->read()); - } - else - { - c.subpd(va.get(), cpu_xmm(GPR[rb])); - } - XmmFinalize(va, rt); + c.subpd(va.get(), cpu_xmm(GPR[rb])); } + XmmFinalize(va, rt); LOG_OPCODE(); } void DFM(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + const XmmLink& va = XmmGet(ra, rt); + if (const XmmLink* vb = XmmRead(rb)) { - const XmmLink& va = XmmGet(ra, rt); - c.mulpd(va.get(), va.get()); - XmmFinalize(va, rt); + c.mulpd(va.get(), vb->read()); } else { - const XmmLink& va = XmmGet(ra, rt); - if (const XmmLink* vb = XmmRead(rb)) - { - c.mulpd(va.get(), vb->read()); - } - else - { - c.mulpd(va.get(), cpu_xmm(GPR[rb])); - } - XmmFinalize(va, rt); + c.mulpd(va.get(), cpu_xmm(GPR[rb])); } + XmmFinalize(va, rt); LOG_OPCODE(); } void CLGTB(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + // compare if-greater-than + const XmmLink& va = XmmGet(ra, rt); + const XmmLink& vi = XmmAlloc(); + c.movdqa(vi.get(), XmmConst(u128::from8p(0x80))); + c.pxor(va.get(), vi.get()); + if (const XmmLink* vb = XmmRead(rb)) { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); + c.pxor(vi.get(), vb->read()); } else { - // compare if-greater-than - const XmmLink& va = XmmGet(ra, rt); - const XmmLink& vb = XmmGet(rb); - c.psubb(va.get(), XmmConst(_mm_set1_epi32(0x80808080))); - c.psubb(vb.get(), XmmConst(_mm_set1_epi32(0x80808080))); - c.pcmpgtb(va.get(), vb.get()); - XmmFinalize(va, rt); - XmmFinalize(vb); + c.pxor(vi.get(), cpu_xmm(GPR[rb])); } + c.pcmpgtb(va.get(), vi.get()); + XmmFinalize(va, rt); + XmmFinalize(vi); LOG_OPCODE(); } void HLGT(u32 rt, u32 ra, u32 rb) @@ -2327,13 +1862,12 @@ private: } void DFMS(u32 rt, u32 ra, u32 rb) { - const XmmLink& vr = XmmGet(rt, rt); - const XmmLink& va = XmmGet(ra); + const XmmLink& va = XmmGet(ra, rt); + const XmmLink& vt = (ra == rt) ? XmmCopy(va) : XmmGet(rt); c.mulpd(va.get(), cpu_xmm(GPR[rb])); - c.xorpd(vr.get(), XmmConst(_mm_set_epi32(0x80000000, 0, 0x80000000, 0))); // neg - c.addpd(vr.get(), va.get()); - XmmFinalize(vr, rt); - XmmFinalize(va); + c.subpd(va.get(), vt.get()); + XmmFinalize(va, rt); + XmmFinalize(vt); LOG_OPCODE(); } void DFNMS(u32 rt, u32 ra, u32 rb) @@ -2348,53 +1882,49 @@ private: } void DFNMA(u32 rt, u32 ra, u32 rb) { - const XmmLink& vr = XmmGet(rt, rt); - const XmmLink& va = XmmGet(ra); + const XmmLink& va = XmmGet(ra, rt); + const XmmLink& vt = (ra == rt) ? XmmCopy(va) : XmmGet(rt); c.mulpd(va.get(), cpu_xmm(GPR[rb])); - c.addpd(vr.get(), va.get()); - c.xorpd(vr.get(), XmmConst(_mm_set_epi32(0x80000000, 0, 0x80000000, 0))); // neg - XmmFinalize(vr, rt); - XmmFinalize(va); + c.addpd(vt.get(), va.get()); + c.xorpd(va.get(), va.get()); + c.subpd(va.get(), vt.get()); + XmmFinalize(va, rt); + XmmFinalize(vt); LOG_OPCODE(); } void CEQ(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + const XmmLink& va = XmmGet(ra, rt); + if (const XmmLink* vb = XmmRead(rb)) { - const XmmLink& v1 = XmmAlloc(rt); - c.pcmpeqd(v1.get(), v1.get()); - XmmFinalize(v1, rt); + c.pcmpeqd(va.get(), vb->read()); } else { - const XmmLink& va = XmmGet(ra, rt); - if (const XmmLink* vb = XmmRead(rb)) - { - c.pcmpeqd(va.get(), vb->read()); - } - else - { - c.pcmpeqd(va.get(), cpu_xmm(GPR[rb])); - } - XmmFinalize(va, rt); + c.pcmpeqd(va.get(), cpu_xmm(GPR[rb])); } + XmmFinalize(va, rt); LOG_OPCODE(); } void MPYHHU(u32 rt, u32 ra, u32 rb) { const XmmLink& va = XmmGet(ra, rt); const XmmLink& vb = (ra == rb) ? XmmCopy(va) : XmmGet(rb); - c.psrld(va.get(), 16); - c.psrld(vb.get(), 16); - c.pmulld(va.get(), vb.get()); + const XmmLink& va2 = XmmCopy(va); + c.pmulhuw(va.get(), vb.get()); + c.pmullw(va2.get(), vb.get()); + c.pand(va.get(), XmmConst(u128::from32p(0xffff0000))); + c.psrld(va2.get(), 16); + c.por(va.get(), va2.get()); XmmFinalize(va, rt); XmmFinalize(vb); + XmmFinalize(va2); LOG_OPCODE(); } void ADDX(u32 rt, u32 ra, u32 rb) { const XmmLink& vt = XmmGet(rt); - c.pand(vt.get(), XmmConst(_mm_set1_epi32(1))); + c.pand(vt.get(), XmmConst(u128::from32p(1))); c.paddd(vt.get(), cpu_xmm(GPR[ra])); c.paddd(vt.get(), cpu_xmm(GPR[rb])); XmmFinalize(vt, rt); @@ -2403,24 +1933,11 @@ private: void SFX(u32 rt, u32 ra, u32 rb) { const XmmLink& vt = XmmGet(rt); - if (ra == rb) - { - // load zero - const XmmLink& v0 = XmmAlloc(rt); - c.pandn(vt.get(), XmmConst(_mm_set1_epi32(1))); - c.pxor(v0.get(), v0.get()); - c.psubd(v0.get(), vt.get()); - XmmFinalize(v0, rt); - } - else - { - // sub - const XmmLink& vb = XmmGet(rb, rt); - c.pandn(vt.get(), XmmConst(_mm_set1_epi32(1))); - c.psubd(vb.get(), cpu_xmm(GPR[ra])); - c.psubd(vb.get(), vt.get()); - XmmFinalize(vb, rt); - } + const XmmLink& vb = XmmGet(rb, rt); + c.pandn(vt.get(), XmmConst(u128::from32p(1))); + c.psubd(vb.get(), cpu_xmm(GPR[ra])); + c.psubd(vb.get(), vt.get()); + XmmFinalize(vb, rt); XmmFinalize(vt); LOG_OPCODE(); } @@ -2448,9 +1965,9 @@ private: const XmmLink& vt = XmmGet(rt, rt); const XmmLink& va = XmmGet(ra); const XmmLink& vb = (ra == rb) ? XmmCopy(va) : XmmGet(rb); - c.psrad(va.get(), 16); - c.psrad(vb.get(), 16); - c.pmulld(va.get(), vb.get()); + c.psrld(va.get(), 16); + c.psrld(vb.get(), 16); + c.pmaddwd(va.get(), vb.get()); c.paddd(vt.get(), va.get()); XmmFinalize(vt, rt); XmmFinalize(va); @@ -2462,13 +1979,17 @@ private: const XmmLink& vt = XmmGet(rt, rt); const XmmLink& va = XmmGet(ra); const XmmLink& vb = (ra == rb) ? XmmCopy(va) : XmmGet(rb); - c.psrld(va.get(), 16); - c.psrld(vb.get(), 16); - c.pmulld(va.get(), vb.get()); + const XmmLink& va2 = XmmCopy(va); + c.pmulhuw(va.get(), vb.get()); + c.pmullw(va2.get(), vb.get()); + c.pand(va.get(), XmmConst(u128::from32p(0xffff0000))); + c.psrld(va2.get(), 16); c.paddd(vt.get(), va.get()); + c.paddd(vt.get(), va2.get()); XmmFinalize(vt, rt); XmmFinalize(va); XmmFinalize(vb); + XmmFinalize(va2); LOG_OPCODE(); } void FSCRRD(u32 rt) @@ -2527,13 +2048,14 @@ private: { const XmmLink& va = XmmGet(ra, rt); const XmmLink& vb = (ra == rb) ? XmmCopy(va) : XmmGet(rb); - c.pslld(va.get(), 16); - c.pslld(vb.get(), 16); - c.psrad(va.get(), 16); - c.psrad(vb.get(), 16); - c.pmulld(va.get(), vb.get()); + const XmmLink& vi = XmmAlloc(); + c.movdqa(vi.get(), XmmConst(u128::from32p(0xffff))); + c.pand(va.get(), vi.get()); + c.pand(vb.get(), vi.get()); + c.pmaddwd(va.get(), vb.get()); XmmFinalize(va, rt); XmmFinalize(vb); + XmmFinalize(vi); LOG_OPCODE(); } void MPYH(u32 rt, u32 ra, u32 rb) @@ -2551,9 +2073,9 @@ private: { const XmmLink& va = XmmGet(ra, rt); const XmmLink& vb = (ra == rb) ? XmmCopy(va) : XmmGet(rb); - c.psrad(va.get(), 16); - c.psrad(vb.get(), 16); - c.pmulld(va.get(), vb.get()); + c.psrld(va.get(), 16); + c.psrld(vb.get(), 16); + c.pmaddwd(va.get(), vb.get()); XmmFinalize(va, rt); XmmFinalize(vb); LOG_OPCODE(); @@ -2571,36 +2093,35 @@ private: } void CEQH(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + const XmmLink& va = XmmGet(ra, rt); + if (const XmmLink* vb = XmmRead(rb)) { - const XmmLink& v1 = XmmAlloc(rt); - c.pcmpeqw(v1.get(), v1.get()); - XmmFinalize(v1, rt); + c.pcmpeqw(va.get(), vb->read()); } else { - const XmmLink& va = XmmGet(ra, rt); - if (const XmmLink* vb = XmmRead(rb)) - { - c.pcmpeqw(va.get(), vb->read()); - } - else - { - c.pcmpeqw(va.get(), cpu_xmm(GPR[rb])); - } - XmmFinalize(va, rt); + c.pcmpeqw(va.get(), cpu_xmm(GPR[rb])); } + XmmFinalize(va, rt); LOG_OPCODE(); } void FCMEQ(u32 rt, u32 ra, u32 rb) { const XmmLink& vb = XmmGet(rb, rt); - const XmmLink& va = XmmGet(ra); - c.andps(vb.get(), XmmConst(_mm_set1_epi32(0x7fffffff))); // abs - c.andps(va.get(), XmmConst(_mm_set1_epi32(0x7fffffff))); // abs - c.cmpps(vb.get(), va.get(), 0); // == + const XmmLink& vi = XmmAlloc(); + c.movaps(vi.get(), XmmConst(u128::from32p(0x7fffffff))); + c.andps(vb.get(), vi.get()); // abs + if (const XmmLink* va = XmmRead(ra)) + { + c.andps(vi.get(), va->read()); + } + else + { + c.andps(vi.get(), cpu_xmm(GPR[ra])); + } + c.cmpps(vb.get(), vi.get(), 0); // == XmmFinalize(vb, rt); - XmmFinalize(va); + XmmFinalize(vi); LOG_OPCODE(); } void DFCMEQ(u32 rt, u32 ra, u32 rb) @@ -2610,45 +2131,30 @@ private: void MPYU(u32 rt, u32 ra, u32 rb) { const XmmLink& va = XmmGet(ra, rt); - if (ra == rb) - { - c.pslld(va.get(), 16); - c.psrld(va.get(), 16); - c.pmulld(va.get(), va.get()); - } - else - { - const XmmLink& v1 = XmmAlloc(); - c.movdqa(v1.get(), XmmConst(_mm_set1_epi32(0xffff))); // load mask - c.pand(va.get(), v1.get()); // clear high words of each dword - c.pand(v1.get(), cpu_xmm(GPR[rb])); - c.pmulld(va.get(), v1.get()); - XmmFinalize(v1); - } + const XmmLink& vb = (ra == rb) ? XmmCopy(va) : XmmGet(rb); + const XmmLink& va2 = XmmCopy(va); + c.pmulhuw(va.get(), vb.get()); + c.pmullw(va2.get(), vb.get()); + c.pslld(va.get(), 16); + c.pand(va2.get(), XmmConst(u128::from32p(0xffff))); + c.por(va.get(), va2.get()); XmmFinalize(va, rt); + XmmFinalize(vb); + XmmFinalize(va2); LOG_OPCODE(); } void CEQB(u32 rt, u32 ra, u32 rb) { - if (ra == rb) + const XmmLink& va = XmmGet(ra, rt); + if (const XmmLink* vb = XmmRead(rb)) { - const XmmLink& v1 = XmmAlloc(rt); - c.pcmpeqb(v1.get(), v1.get()); - XmmFinalize(v1, rt); + c.pcmpeqb(va.get(), vb->read()); } else { - const XmmLink& va = XmmGet(ra, rt); - if (const XmmLink* vb = XmmRead(rb)) - { - c.pcmpeqb(va.get(), vb->read()); - } - else - { - c.pcmpeqb(va.get(), cpu_xmm(GPR[rb])); - } - XmmFinalize(va, rt); + c.pcmpeqb(va.get(), cpu_xmm(GPR[rb])); } + XmmFinalize(va, rt); LOG_OPCODE(); } void FI(u32 rt, u32 ra, u32 rb) @@ -2675,12 +2181,15 @@ private: const XmmLink& va = XmmGet(ra, rt); if (i8 != 173) { - c.mulps(va.get(), XmmConst(_mm_set1_ps((float)pow(2, 173 - (i8 & 0xff))))); // scale + c.mulps(va.get(), XmmConst(u128::fromF(_mm_set1_ps(exp2f(static_cast(173 - (i8 & 0xff))))))); // scale } - c.maxps(va.get(), XmmConst(_mm_set1_ps((float)-pow(2, 31)))); // saturate - c.minps(va.get(), XmmConst(_mm_set1_ps((float)0x7fffffff))); + const XmmLink& vi = XmmAlloc(); + c.movaps(vi.get(), XmmConst(u128::fromF(_mm_set1_ps(exp2f(31))))); + c.cmpps(vi.get(), va.get(), 2); c.cvttps2dq(va.get(), va.get()); // convert to ints with truncation + c.pxor(va.get(), vi.get()); // fix result saturation (0x80000000 -> 0x7fffffff) XmmFinalize(va, rt); + XmmFinalize(vi); LOG_OPCODE(); } void CFLTU(u32 rt, u32 ra, s32 i8) @@ -2688,17 +2197,25 @@ private: const XmmLink& va = XmmGet(ra, rt); if (i8 != 173) { - c.mulps(va.get(), XmmConst(_mm_set1_ps((float)pow(2, 173 - (i8 & 0xff))))); // scale + c.mulps(va.get(), XmmConst(u128::fromF(_mm_set1_ps(exp2f(static_cast(173 - (i8 & 0xff))))))); // scale } - c.maxps(va.get(), XmmConst(_mm_set1_ps(0.0f))); // saturate - c.minps(va.get(), XmmConst(_mm_set1_ps((float)0xffffffff))); - const XmmLink& v1 = XmmCopy(va); - c.cmpps(v1.get(), XmmConst(_mm_set1_ps((float)pow(2, 31))), 5); // generate mask of big values - c.andps(v1.get(), XmmConst(_mm_set1_ps((float)pow(2, 32)))); // generate correction component - c.subps(va.get(), v1.get()); // subtract correction component - c.cvttps2dq(va.get(), va.get()); // convert to ints with truncation + c.maxps(va.get(), XmmConst({})); // saturate + const XmmLink& vs = XmmCopy(va); // copy scaled value + const XmmLink& vs2 = XmmCopy(va); + const XmmLink& vs3 = XmmAlloc(); + c.movaps(vs3.get(), XmmConst(u128::fromF(_mm_set1_ps(exp2f(31))))); + c.subps(vs2.get(), vs3.get()); + c.cmpps(vs3.get(), vs.get(), 2); + c.andps(vs2.get(), vs3.get()); + c.cvttps2dq(va.get(), va.get()); + c.cmpps(vs.get(), XmmConst(u128::fromF(_mm_set1_ps(exp2f(32)))), 5); + c.cvttps2dq(vs2.get(), vs2.get()); + c.por(va.get(), vs.get()); + c.por(va.get(), vs2.get()); XmmFinalize(va, rt); - XmmFinalize(v1); + XmmFinalize(vs); + XmmFinalize(vs2); + XmmFinalize(vs3); LOG_OPCODE(); } void CSFLT(u32 rt, u32 ra, s32 i8) @@ -2707,7 +2224,7 @@ private: c.cvtdq2ps(va.get(), va.get()); // convert to floats if (i8 != 155) { - c.mulps(va.get(), XmmConst(_mm_set1_ps((float)pow(2, (i8 & 0xff) - 155)))); // scale + c.mulps(va.get(), XmmConst(u128::fromF(_mm_set1_ps(exp2f(static_cast((i8 & 0xff) - 155)))))); // scale } XmmFinalize(va, rt); LOG_OPCODE(); @@ -2716,13 +2233,14 @@ private: { const XmmLink& va = XmmGet(ra, rt); const XmmLink& v1 = XmmCopy(va); + c.pand(va.get(), XmmConst(u128::from32p(0x7fffffff))); c.cvtdq2ps(va.get(), va.get()); // convert to floats - c.psrad(v1.get(), 32); // generate mask from sign bit - c.andps(v1.get(), XmmConst(_mm_set1_ps((float)pow(2, 32)))); // generate correction component + c.psrad(v1.get(), 31); // generate mask from sign bit + c.andps(v1.get(), XmmConst(u128::fromF(_mm_set1_ps(exp2f(31))))); // generate correction component c.addps(va.get(), v1.get()); // add correction component if (i8 != 155) { - c.mulps(va.get(), XmmConst(_mm_set1_ps((float)pow(2, (i8 & 0xff) - 155)))); // scale + c.mulps(va.get(), XmmConst(u128::fromF(_mm_set1_ps(exp2f(static_cast((i8 & 0xff) - 155)))))); // scale } XmmFinalize(va, rt); XmmFinalize(v1); @@ -2873,7 +2391,7 @@ private: else { const XmmLink& vr = XmmAlloc(rt); - c.movdqa(vr.get(), g_imm_xmm(fsmb_table[i16 & 0xffff])); + c.movdqa(vr.get(), g_imm_xmm(fsmb[i16 & 0xffff])); XmmFinalize(vr, rt); } LOG_OPCODE(); @@ -2926,7 +2444,7 @@ private: } else { - c.movdqa(vr.get(), XmmConst(_mm_set1_epi32(i16))); + c.movdqa(vr.get(), XmmConst(u128::from32p(i16))); } XmmFinalize(vr, rt); LOG_OPCODE(); @@ -2934,43 +2452,22 @@ private: void ILHU(u32 rt, s32 i16) { const XmmLink& vr = XmmAlloc(rt); - if (i16 == 0) - { - c.pxor(vr.get(), vr.get()); - } - else - { - c.movdqa(vr.get(), XmmConst(_mm_set1_epi32(i16 << 16))); - } + c.movdqa(vr.get(), XmmConst(u128::from32p(i16 << 16))); XmmFinalize(vr, rt); LOG_OPCODE(); } void ILH(u32 rt, s32 i16) { const XmmLink& vr = XmmAlloc(rt); - if (i16 == 0) - { - c.pxor(vr.get(), vr.get()); - } - else - { - c.movdqa(vr.get(), XmmConst(_mm_set1_epi16(i16))); - } + c.movdqa(vr.get(), XmmConst(u128::from32p(i16))); XmmFinalize(vr, rt); LOG_OPCODE(); } void IOHL(u32 rt, s32 i16) { - if (i16 == 0) - { - // nop - } - else - { - const XmmLink& vt = XmmGet(rt, rt); - c.por(vt.get(), XmmConst(_mm_set1_epi32(i16 & 0xffff))); - XmmFinalize(vt, rt); - } + const XmmLink& vt = XmmGet(rt, rt); + c.por(vt.get(), XmmConst(u128::from32p(i16 & 0xffff))); + XmmFinalize(vt, rt); LOG_OPCODE(); } @@ -2998,63 +2495,23 @@ private: else { const XmmLink& va = XmmGet(ra, rt); - c.por(va.get(), XmmConst(_mm_set1_epi32(i10))); + c.por(va.get(), XmmConst(u128::from32p(i10))); XmmFinalize(va, rt); } LOG_OPCODE(); } void ORHI(u32 rt, u32 ra, s32 i10) { - if (i10 == -1) - { - // fill with 1 - const XmmLink& v1 = XmmAlloc(rt); - c.pcmpeqd(v1.get(), v1.get()); - XmmFinalize(v1, rt); - } - else if (i10 == 0) - { - if (rt != ra) - { - // mov - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else - { - const XmmLink& va = XmmGet(ra, rt); - c.por(va.get(), XmmConst(_mm_set1_epi16(i10))); - XmmFinalize(va, rt); - } + const XmmLink& va = XmmGet(ra, rt); + c.por(va.get(), XmmConst(u128::from16p(i10))); + XmmFinalize(va, rt); LOG_OPCODE(); } void ORBI(u32 rt, u32 ra, s32 i10) { - if (i10 == -1) - { - // fill with 1 - const XmmLink& v1 = XmmAlloc(rt); - c.pcmpeqd(v1.get(), v1.get()); - XmmFinalize(v1, rt); - } - else if (i10 == 0) - { - if (rt != ra) - { - // mov - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else - { - const XmmLink& va = XmmGet(ra, rt); - c.por(va.get(), XmmConst(_mm_set1_epi8(i10))); - XmmFinalize(va, rt); - } + const XmmLink& va = XmmGet(ra, rt); + c.por(va.get(), XmmConst(u128::from8p(i10))); + XmmFinalize(va, rt); LOG_OPCODE(); } void SFI(u32 rt, u32 ra, s32 i10) @@ -3078,7 +2535,7 @@ private: else { const XmmLink& vr = XmmAlloc(rt); - c.movdqa(vr.get(), XmmConst(_mm_set1_epi32(i10))); + c.movdqa(vr.get(), XmmConst(u128::from32p(i10))); c.psubd(vr.get(), cpu_xmm(GPR[ra])); XmmFinalize(vr, rt); } @@ -3105,7 +2562,7 @@ private: else { const XmmLink& vr = XmmAlloc(rt); - c.movdqa(vr.get(), XmmConst(_mm_set1_epi16(i10))); + c.movdqa(vr.get(), XmmConst(u128::from16p(i10))); c.psubw(vr.get(), cpu_xmm(GPR[ra])); XmmFinalize(vr, rt); } @@ -3113,125 +2570,39 @@ private: } void ANDI(u32 rt, u32 ra, s32 i10) { - if (i10 == 0) - { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); - } - else if (i10 == -1) - { - // mov - if (ra != rt) - { - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else - { - const XmmLink& va = XmmGet(ra, rt); - c.pand(va.get(), XmmConst(_mm_set1_epi32(i10))); - XmmFinalize(va, rt); - } + const XmmLink& va = XmmGet(ra, rt); + c.pand(va.get(), XmmConst(u128::from32p(i10))); + XmmFinalize(va, rt); LOG_OPCODE(); } void ANDHI(u32 rt, u32 ra, s32 i10) { - if (i10 == 0) - { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); - } - else if (i10 == -1) - { - // mov - if (ra != rt) - { - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else - { - const XmmLink& va = XmmGet(ra, rt); - c.pand(va.get(), XmmConst(_mm_set1_epi16(i10))); - XmmFinalize(va, rt); - } + const XmmLink& va = XmmGet(ra, rt); + c.pand(va.get(), XmmConst(u128::from16p(i10))); + XmmFinalize(va, rt); LOG_OPCODE(); } void ANDBI(u32 rt, u32 ra, s32 i10) { - if (i10 == 0) - { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); - } - else if (i10 == -1) - { - // mov - if (ra != rt) - { - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else - { - const XmmLink& va = XmmGet(ra, rt); - c.pand(va.get(), XmmConst(_mm_set1_epi8(i10))); - XmmFinalize(va, rt); - } + const XmmLink& va = XmmGet(ra, rt); + c.pand(va.get(), XmmConst(u128::from8p(i10))); + XmmFinalize(va, rt); LOG_OPCODE(); } void AI(u32 rt, u32 ra, s32 i10) { - if (i10 == 0) - { - if (rt != ra) - { - // mov - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else - { - // add - const XmmLink& va = XmmGet(ra, rt); - c.paddd(va.get(), XmmConst(_mm_set1_epi32(i10))); - XmmFinalize(va, rt); - } + // add + const XmmLink& va = XmmGet(ra, rt); + c.paddd(va.get(), XmmConst(u128::from32p(i10))); + XmmFinalize(va, rt); LOG_OPCODE(); } void AHI(u32 rt, u32 ra, s32 i10) { - if (i10 == 0) - { - if (rt != ra) - { - // mov - const XmmLink& va = XmmGet(ra, rt); - XmmFinalize(va, rt); - } - // else nop - } - else - { - // add - const XmmLink& va = XmmGet(ra, rt); - c.paddw(va.get(), XmmConst(_mm_set1_epi16(i10))); - XmmFinalize(va, rt); - } + // add + const XmmLink& va = XmmGet(ra, rt); + c.paddw(va.get(), XmmConst(u128::from16p(i10))); + XmmFinalize(va, rt); LOG_OPCODE(); } void STQD(u32 rt, s32 i10, u32 ra) // i10 is shifted left by 4 while decoding @@ -3279,42 +2650,42 @@ private: void XORI(u32 rt, u32 ra, s32 i10) { const XmmLink& va = XmmGet(ra); - c.pxor(va.get(), XmmConst(_mm_set1_epi32(i10))); + c.pxor(va.get(), XmmConst(u128::from32p(i10))); XmmFinalize(va, rt); LOG_OPCODE(); } void XORHI(u32 rt, u32 ra, s32 i10) { const XmmLink& va = XmmGet(ra); - c.pxor(va.get(), XmmConst(_mm_set1_epi16(i10))); + c.pxor(va.get(), XmmConst(u128::from16p(i10))); XmmFinalize(va, rt); LOG_OPCODE(); } void XORBI(u32 rt, u32 ra, s32 i10) { const XmmLink& va = XmmGet(ra); - c.pxor(va.get(), XmmConst(_mm_set1_epi8(i10))); + c.pxor(va.get(), XmmConst(u128::from8p(i10))); XmmFinalize(va, rt); LOG_OPCODE(); } void CGTI(u32 rt, u32 ra, s32 i10) { const XmmLink& va = XmmGet(ra); - c.pcmpgtd(va.get(), XmmConst(_mm_set1_epi32(i10))); + c.pcmpgtd(va.get(), XmmConst(u128::from32p(i10))); XmmFinalize(va, rt); LOG_OPCODE(); } void CGTHI(u32 rt, u32 ra, s32 i10) { const XmmLink& va = XmmGet(ra); - c.pcmpgtw(va.get(), XmmConst(_mm_set1_epi16(i10))); + c.pcmpgtw(va.get(), XmmConst(u128::from16p(i10))); XmmFinalize(va, rt); LOG_OPCODE(); } void CGTBI(u32 rt, u32 ra, s32 i10) { const XmmLink& va = XmmGet(ra); - c.pcmpgtb(va.get(), XmmConst(_mm_set1_epi8(i10))); + c.pcmpgtb(va.get(), XmmConst(u128::from8p(i10))); XmmFinalize(va, rt); LOG_OPCODE(); } @@ -3331,56 +2702,26 @@ private: } void CLGTI(u32 rt, u32 ra, s32 i10) { - if (i10 == -1) - { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); - } - else - { - const XmmLink& va = XmmGet(ra); - c.psubd(va.get(), XmmConst(_mm_set1_epi32(0x80000000))); - c.pcmpgtd(va.get(), XmmConst(_mm_set1_epi32((u32)i10 - 0x80000000))); - XmmFinalize(va, rt); - } + const XmmLink& va = XmmGet(ra); + c.pxor(va.get(), XmmConst(u128::from32p(0x80000000))); + c.pcmpgtd(va.get(), XmmConst(u128::from32p((u32)i10 - 0x80000000))); + XmmFinalize(va, rt); LOG_OPCODE(); } void CLGTHI(u32 rt, u32 ra, s32 i10) { - if (i10 == -1) - { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); - } - else - { - const XmmLink& va = XmmGet(ra); - c.psubw(va.get(), XmmConst(_mm_set1_epi16((u16)0x8000))); - c.pcmpgtw(va.get(), XmmConst(_mm_set1_epi16((u16)i10 - 0x8000))); - XmmFinalize(va, rt); - } + const XmmLink& va = XmmGet(ra); + c.pxor(va.get(), XmmConst(u128::from16p(0x8000))); + c.pcmpgtw(va.get(), XmmConst(u128::from16p((u16)i10 - 0x8000))); + XmmFinalize(va, rt); LOG_OPCODE(); } void CLGTBI(u32 rt, u32 ra, s32 i10) { - if (i10 == -1) - { - // zero - const XmmLink& v0 = XmmAlloc(rt); - c.pxor(v0.get(), v0.get()); - XmmFinalize(v0, rt); - } - else - { - const XmmLink& va = XmmGet(ra); - c.psubb(va.get(), XmmConst(_mm_set1_epi8((s8)0x80))); - c.pcmpgtb(va.get(), XmmConst(_mm_set1_epi8((s8)i10 - 0x80))); - XmmFinalize(va, rt); - } + const XmmLink& va = XmmGet(ra); + c.psubb(va.get(), XmmConst(u128::from8p(0x80))); + c.pcmpgtb(va.get(), XmmConst(u128::from8p((s8)i10 - 0x80))); + XmmFinalize(va, rt); LOG_OPCODE(); } void HLGTI(u32 rt, u32 ra, s32 i10) @@ -3397,39 +2738,43 @@ private: void MPYI(u32 rt, u32 ra, s32 i10) { const XmmLink& va = XmmGet(ra, rt); - c.pslld(va.get(), 16); - c.psrad(va.get(), 16); - c.pmulld(va.get(), XmmConst(_mm_set1_epi32(i10))); + c.pmaddwd(va.get(), XmmConst(u128::from32p(i10 & 0xffff))); XmmFinalize(va, rt); LOG_OPCODE(); } void MPYUI(u32 rt, u32 ra, s32 i10) { const XmmLink& va = XmmGet(ra, rt); + const XmmLink& vi = XmmAlloc(); + const XmmLink& va2 = XmmCopy(va); + c.movdqa(vi.get(), XmmConst(u128::from32p(i10 & 0xffff))); + c.pmulhuw(va.get(), vi.get()); + c.pmullw(va2.get(), vi.get()); c.pslld(va.get(), 16); - c.psrld(va.get(), 16); - c.pmulld(va.get(), XmmConst(_mm_set1_epi32(i10 & 0xffff))); + c.por(va.get(), va2.get()); XmmFinalize(va, rt); + XmmFinalize(vi); + XmmFinalize(va2); LOG_OPCODE(); } void CEQI(u32 rt, u32 ra, s32 i10) { const XmmLink& va = XmmGet(ra); - c.pcmpeqd(va.get(), XmmConst(_mm_set1_epi32(i10))); + c.pcmpeqd(va.get(), XmmConst(u128::from32p(i10))); XmmFinalize(va, rt); LOG_OPCODE(); } void CEQHI(u32 rt, u32 ra, s32 i10) { const XmmLink& va = XmmGet(ra); - c.pcmpeqw(va.get(), XmmConst(_mm_set1_epi16((s16)i10))); + c.pcmpeqw(va.get(), XmmConst(u128::from16p(i10))); XmmFinalize(va, rt); LOG_OPCODE(); } void CEQBI(u32 rt, u32 ra, s32 i10) { const XmmLink& va = XmmGet(ra); - c.pcmpeqb(va.get(), XmmConst(_mm_set1_epi8((s8)i10))); + c.pcmpeqb(va.get(), XmmConst(u128::from8p(i10))); XmmFinalize(va, rt); LOG_OPCODE(); } @@ -3464,7 +2809,7 @@ private: } else { - c.movdqa(vr.get(), XmmConst(_mm_set1_epi32(i18 & 0x3ffff))); + c.movdqa(vr.get(), XmmConst(u128::from32p(i18 & 0x3ffff))); } XmmFinalize(vr, rt); LOG_OPCODE(); @@ -3484,44 +2829,6 @@ private: } void SHUFB(u32 rt, u32 ra, u32 rb, u32 rc) { - /*WRAPPER_BEGIN(rc, rt, ra, rb); - const SPU_GPR_hdr _a = CPU.GPR[ra]; - const SPU_GPR_hdr _b = CPU.GPR[rb]; - for (int i = 0; i < 16; i++) - { - u8 b = CPU.GPR[rc]._u8[i]; - if (b & 0x80) - { - if (b & 0x40) - { - if (b & 0x20) - CPU.GPR[rt]._u8[i] = 0x80; - else - CPU.GPR[rt]._u8[i] = 0xFF; - } - else - CPU.GPR[rt]._u8[i] = 0x00; - } - else - { - if (b & 0x10) - CPU.GPR[rt]._u8[i] = _b._u8[15 - (b & 0x0F)]; - else - CPU.GPR[rt]._u8[i] = _a._u8[15 - (b & 0x0F)]; - } - } - WRAPPER_END(rc, rt, ra, rb);*/ - - // hypothetical AVX-512 implementation: - // VPXORD mask, rc, [byte:0x0f] // 15 - rc (only for index bits) - // VPSHUFB res {k0}, ra, mask - // VPTESTMB k1 {k0}, rc, [byte:0x10] - // VPSHUFB res {k1}, rb, mask - // VPCMPNLTUB k1 {k0}, mask, [byte:0xc0] - // VPADDB res {k1}, res, [byte:0xff] - // VPCMPNLTUB k1 {k1}, mask, [byte:0xe0] - // VPSUBB res {k1}, res, [byte:0x7f] - const XmmLink& v0 = XmmGet(rc); // v0 = mask const XmmLink& v1 = XmmAlloc(); const XmmLink& v2 = XmmCopy(v0); // v2 = mask @@ -3529,11 +2836,11 @@ private: const XmmLink& v4 = XmmAlloc(); const XmmLink& vFF = XmmAlloc(rt); // generate specific values: - c.movdqa(v1.get(), XmmConst(_mm_set1_epi32(0xe0e0e0e0))); // v1 = 11100000 - c.movdqa(v3.get(), XmmConst(_mm_set1_epi32(0x80808080))); // v3 = 10000000 + c.movdqa(v1.get(), XmmConst(u128::from8p(0xe0))); // v1 = 11100000 + c.movdqa(v3.get(), XmmConst(u128::from8p(0x80))); // v3 = 10000000 c.pand(v2.get(), v1.get()); // filter mask v2 = mask & 11100000 c.movdqa(vFF.get(), v2.get()); // and copy vFF = mask & 11100000 - c.movdqa(v4.get(), XmmConst(_mm_set1_epi32(0xc0c0c0c0))); // v4 = 11000000 + c.movdqa(v4.get(), XmmConst(u128::from8p(0xc0))); // v4 = 11000000 c.pcmpeqb(vFF.get(), v4.get()); // gen 0xff vFF = (mask & 11100000 == 11000000) ? 0xff : 0 c.movdqa(v4.get(), v2.get()); // copy again v4 = mask & 11100000 c.pand(v4.get(), v3.get()); // filter mask v4 = mask & 10000000 @@ -3543,13 +2850,13 @@ private: c.por(vFF.get(), v2.get()); // merge 0xff, 0x80 vFF = (mask & 11100000 == 11000000) ? 0xff : (mask & 11100000 == 11100000) ? 0x80 : 0 c.pandn(v1.get(), v0.get()); // filter mask v1 = mask & 00011111 // select bytes from [rb]: - c.movdqa(v2.get(), XmmConst(_mm_set1_epi8(15))); // v2 = 00001111 - c.pxor(v1.get(), XmmConst(_mm_set1_epi8(0x10))); // v1 = (mask & 00011111) ^ 00010000 + c.movdqa(v2.get(), XmmConst(u128::from8p(0x0f))); // v2 = 00001111 + c.pxor(v1.get(), XmmConst(u128::from8p(0x10))); // v1 = (mask & 00011111) ^ 00010000 c.psubb(v2.get(), v1.get()); // v2 = 00001111 - ((mask & 00011111) ^ 00010000) c.movdqa(v1.get(), cpu_xmm(GPR[rb])); // v1 = rb c.pshufb(v1.get(), v2.get()); // v1 = select(rb, 00001111 - ((mask & 00011111) ^ 00010000)) // select bytes from [ra]: - c.pxor(v2.get(), XmmConst(_mm_set1_epi32(0xf0f0f0f0))); // v2 = (00001111 - ((mask & 00011111) ^ 00010000)) ^ 11110000 + c.pxor(v2.get(), XmmConst(u128::from8p(0xf0))); // v2 = (00001111 - ((mask & 00011111) ^ 00010000)) ^ 11110000 c.movdqa(v3.get(), cpu_xmm(GPR[ra])); // v3 = ra c.pshufb(v3.get(), v2.get()); // v3 = select(ra, (00001111 - ((mask & 00011111) ^ 00010000)) ^ 11110000) c.por(v1.get(), v3.get()); // v1 = select(rb, 00001111 - ((mask & 00011111) ^ 00010000)) | (v3) @@ -3567,14 +2874,15 @@ private: { const XmmLink& va = XmmGet(ra, rt); const XmmLink& vb = XmmGet(rb); - c.pslld(va.get(), 16); - c.pslld(vb.get(), 16); - c.psrad(va.get(), 16); - c.psrad(vb.get(), 16); - c.pmulld(va.get(), vb.get()); + const XmmLink& vi = XmmAlloc(); + c.movdqa(vi.get(), XmmConst(u128::from32p(0xffff))); + c.pand(va.get(), vi.get()); + c.pand(vb.get(), vi.get()); + c.pmaddwd(va.get(), vb.get()); c.paddd(va.get(), cpu_xmm(GPR[rc])); XmmFinalize(va, rt); XmmFinalize(vb); + XmmFinalize(vi); LOG_OPCODE(); } void FNMS(u32 rt, u32 ra, u32 rb, u32 rc) @@ -3687,7 +2995,7 @@ private: } else { - throw (std::string(__FUNCTION__) + std::string("(): invalid case")).c_str(); + throw "FMA: invalid case"; // should never happen } LOG_OPCODE(); } @@ -3772,7 +3080,7 @@ private: } else { - throw (std::string(__FUNCTION__) + std::string("(): invalid case")).c_str(); + throw "FMS: invalid case"; // should never happen } LOG_OPCODE(); } diff --git a/rpcs3/Emu/Cell/SPURecompilerCore.cpp b/rpcs3/Emu/Cell/SPURecompilerCore.cpp index e476f80eb3..10329f727f 100644 --- a/rpcs3/Emu/Cell/SPURecompilerCore.cpp +++ b/rpcs3/Emu/Cell/SPURecompilerCore.cpp @@ -2,7 +2,7 @@ #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" -#include "Utilities/rFile.h" +#include "Utilities/File.h" #include "Emu/SysCalls/lv2/sys_time.h" @@ -13,8 +13,6 @@ #include "SPUInterpreter.h" #include "SPURecompiler.h" -const g_imm_table_struct g_imm_table; - SPURecompilerCore::SPURecompilerCore(SPUThread& cpu) : m_enc(new SPURecompiler(cpu, *this)) , inter(new SPUInterpreter(cpu)) @@ -25,11 +23,6 @@ SPURecompilerCore::SPURecompilerCore(SPUThread& cpu) memset(entry, 0, sizeof(entry)); X86CpuInfo inf; X86CpuUtil::detect(&inf); - if (!inf.hasFeature(kX86CpuFeatureSSE4_1)) - { - LOG_ERROR(SPU, "SPU JIT requires SSE4.1 instruction set support"); - Emu.Pause(); - } } SPURecompilerCore::~SPURecompilerCore() @@ -45,22 +38,22 @@ void SPURecompilerCore::Decode(const u32 code) // decode instruction and run wit void SPURecompilerCore::Compile(u16 pos) { - const u64 stamp0 = get_system_time(); - u64 time0 = 0; + //const u64 stamp0 = get_system_time(); + //u64 time0 = 0; - SPUDisAsm dis_asm(CPUDisAsm_InterpreterMode); - dis_asm.offset = vm::get_ptr(CPU.offset); + //SPUDisAsm dis_asm(CPUDisAsm_InterpreterMode); + //dis_asm.offset = vm::get_ptr(CPU.offset); - StringLogger stringLogger; - stringLogger.setOption(kLoggerOptionBinaryForm, true); + //StringLogger stringLogger; + //stringLogger.setOption(kLoggerOptionBinaryForm, true); X86Compiler compiler(&runtime); m_enc->compiler = &compiler; - compiler.setLogger(&stringLogger); + //compiler.setLogger(&stringLogger); compiler.addFunc(kFuncConvHost, FuncBuilder4()); const u16 start = pos; - u32 excess = 0; + //u32 excess = 0; entry[start].count = 0; X86GpVar cpu_var(compiler, kVarTypeIntPtr, "cpu"); @@ -107,11 +100,11 @@ void SPURecompilerCore::Compile(u16 pos) m_enc->do_finalize = false; if (opcode) { - const u64 stamp1 = get_system_time(); + //const u64 stamp1 = get_system_time(); // disasm for logging: - dis_asm.dump_pc = pos * 4; - (*SPU_instr::rrr_list)(&dis_asm, opcode); - compiler.addComment(fmt::Format("SPU data: PC=0x%05x %s", pos * 4, dis_asm.last_opcode.c_str()).c_str()); + //dis_asm.dump_pc = pos * 4; + //(*SPU_instr::rrr_list)(&dis_asm, opcode); + //compiler.addComment(fmt::Format("SPU data: PC=0x%05x %s", pos * 4, dis_asm.last_opcode.c_str()).c_str()); // compile single opcode: (*SPU_instr::rrr_list)(m_enc, opcode); // force finalization between every slice using absolute alignment @@ -121,17 +114,17 @@ void SPURecompilerCore::Compile(u16 pos) m_enc->do_finalize = true; }*/ entry[start].count++; - time0 += get_system_time() - stamp1; + //time0 += get_system_time() - stamp1; } else { m_enc->do_finalize = true; } bool fin = m_enc->do_finalize; - if (entry[pos].valid == re32(opcode)) - { - excess++; - } + //if (entry[pos].valid == re32(opcode)) + //{ + // excess++; + //} entry[pos].valid = re32(opcode); if (fin) break; @@ -148,34 +141,28 @@ void SPURecompilerCore::Compile(u16 pos) m_enc->xmm_var[i].data = nullptr; } - const u64 stamp1 = get_system_time(); + //const u64 stamp1 = get_system_time(); compiler.ret(pos_var); compiler.endFunc(); entry[start].pointer = compiler.make(); compiler.setLogger(nullptr); // crashes without it - rFile log; - log.Open(fmt::Format("SPUjit_%d.log", GetCurrentSPUThread().GetId()), first ? rFile::write : rFile::write_append); - log.Write(fmt::Format("========== START POSITION 0x%x ==========\n\n", start * 4)); - log.Write(std::string(stringLogger.getString())); - if (!entry[start].pointer) - { - LOG_ERROR(Log::SPU, "SPURecompilerCore::Compile(pos=0x%x) failed", start * sizeof(u32)); - log.Write("========== FAILED ============\n\n"); - Emu.Pause(); - } - else - { - log.Write(fmt::Format("========== COMPILED %d (excess %d), time: [start=%lld (decoding=%lld), finalize=%lld]\n\n", - entry[start].count, excess, stamp1 - stamp0, time0, get_system_time() - stamp1)); -#ifdef _WIN32 - //if (!RtlAddFunctionTable(&info, 1, (u64)entry[start].pointer)) - //{ - // LOG_ERROR(Log::SPU, "RtlAddFunctionTable() failed"); - //} -#endif - } - log.Close(); + //std::string log = fmt::format("========== START POSITION 0x%x ==========\n\n", start * 4); + //log += stringLogger.getString(); + //if (!entry[start].pointer) + //{ + // LOG_ERROR(Log::SPU, "SPURecompilerCore::Compile(pos=0x%x) failed", start * sizeof(u32)); + // log += "========== FAILED ============\n\n"; + // Emu.Pause(); + //} + //else + //{ + // log += fmt::format("========== COMPILED %d (excess %d), time: [start=%lld (decoding=%lld), finalize=%lld]\n\n", + // entry[start].count, excess, stamp1 - stamp0, time0, get_system_time() - stamp1); + //} + + //fs::file(fmt::Format("SPUjit_%d.log", this->CPU.GetId()), o_write | o_create | (first ? o_trunc : o_append)).write(log.c_str(), log.size()); + m_enc->compiler = nullptr; first = false; } @@ -217,9 +204,6 @@ u32 SPURecompilerCore::DecodeMemory(const u32 address) i < (u32)pos + (u32)entry[pos].count) { runtime.release(entry[i].pointer); -#ifdef _WIN32 - //RtlDeleteFunctionTable(&entry[i].info); -#endif entry[i].pointer = nullptr; for (u32 j = i; j < i + (u32)entry[i].count; j++) { @@ -264,7 +248,7 @@ u32 SPURecompilerCore::DecodeMemory(const u32 address) } u32 res = pos; - res = func(cpu, vm::get_ptr(m_offset), imm_table.data(), &g_imm_table); + res = func(cpu, vm::get_ptr(m_offset), imm_table.data(), &g_spu_imm); if (res & 0x1000000) { diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index c7909bee55..8548dea2d8 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -22,6 +22,8 @@ #include +const g_spu_imm_table_t g_spu_imm; + class spu_inter_func_list_t { std::array funcs; @@ -235,14 +237,14 @@ void SPUThread::FastCall(u32 ls_addr) m_status = Running; PC = ls_addr; GPR[0]._u32[3] = 0x0; - m_custom_task.swap(m_custom_task); + m_custom_task.swap(old_task); SPUThread::Task(); PC = old_PC; GPR[0]._u32[3] = old_LR; GPR[1]._u32[3] = old_stack; - m_custom_task.swap(m_custom_task); + m_custom_task.swap(old_task); } void SPUThread::FastStop() @@ -271,12 +273,11 @@ void SPUThread::do_dma_transfer(u32 cmd, spu_mfc_arg_t args) const u32 index = (eal - SYS_SPU_THREAD_BASE_LOW) / SYS_SPU_THREAD_OFFSET; // thread number in group const u32 offset = (eal - SYS_SPU_THREAD_BASE_LOW) % SYS_SPU_THREAD_OFFSET; // LS offset or MMIO register - std::shared_ptr group = tg.lock(); - std::shared_ptr t; + const auto group = tg.lock(); - if (group && index < group->num && (t = group->threads[index])) + if (group && index < group->num && group->threads[index]) { - auto& spu = static_cast(*t); + auto& spu = static_cast(*group->threads[index]); if (offset + args.size - 1 < 0x40000) // LS access { @@ -487,6 +488,7 @@ u32 SPUThread::get_ch_count(u32 ch) switch (ch) { + //case MFC_Cmd: return 16; //case SPU_WrSRR0: return 1; break; //case SPU_RdSRR0: return 1; break; case SPU_WrOutMbox: return ch_out_mbox.get_count() ^ 1; break; @@ -671,7 +673,7 @@ void SPUThread::set_ch_value(u32 ch, u32 value) LV2_LOCK; - std::shared_ptr queue = this->spup[spup].lock(); + const auto queue = this->spup[spup].lock(); if (!queue) { @@ -684,7 +686,7 @@ void SPUThread::set_ch_value(u32 ch, u32 value) return ch_in_mbox.push_uncond(CELL_EBUSY); } - queue->push(SYS_SPU_THREAD_EVENT_USER_KEY, GetId(), ((u64)spup << 32) | (value & 0x00ffffff), data); + queue->push(lv2_lock, SYS_SPU_THREAD_EVENT_USER_KEY, GetId(), ((u64)spup << 32) | (value & 0x00ffffff), data); return ch_in_mbox.push_uncond(CELL_OK); } @@ -708,7 +710,7 @@ void SPUThread::set_ch_value(u32 ch, u32 value) LV2_LOCK; - std::shared_ptr queue = this->spup[spup].lock(); + const auto queue = this->spup[spup].lock(); if (!queue) { @@ -723,7 +725,7 @@ void SPUThread::set_ch_value(u32 ch, u32 value) return; } - queue->push(SYS_SPU_THREAD_EVENT_USER_KEY, GetId(), ((u64)spup << 32) | (value & 0x00ffffff), data); + queue->push(lv2_lock, SYS_SPU_THREAD_EVENT_USER_KEY, GetId(), ((u64)spup << 32) | (value & 0x00ffffff), data); return; } else if (code == 128) @@ -751,9 +753,9 @@ void SPUThread::set_ch_value(u32 ch, u32 value) LV2_LOCK; - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(data); - if (!Emu.GetIdManager().GetIDData(data, ef)) + if (!ef) { return ch_in_mbox.push_uncond(CELL_ESRCH); } @@ -797,9 +799,9 @@ void SPUThread::set_ch_value(u32 ch, u32 value) LV2_LOCK; - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(data); - if (!Emu.GetIdManager().GetIDData(data, ef)) + if (!ef) { return; } @@ -1119,7 +1121,7 @@ void SPUThread::stop_and_signal(u32 code) LV2_LOCK; - std::shared_ptr group = tg.lock(); + const auto group = tg.lock(); if (!group) { diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index 95706fe60c..0156139f09 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -315,51 +315,89 @@ public: } }; -#define mmToU64Ptr(x) ((u64*)(&x)) -#define mmToU32Ptr(x) ((u32*)(&x)) -#define mmToU16Ptr(x) ((u16*)(&x)) -#define mmToU8Ptr(x) ((u8*)(&x)) - -struct g_imm_table_struct +struct g_spu_imm_table_t { - __m128i fsmb_table[65536]; - __m128i fsmh_table[256]; - __m128i fsm_table[16]; + u128 fsmb[65536]; // table for FSMB, FSMBI instructions + u128 fsmh[256]; // table for FSMH instruction + u128 fsm[16]; // table for FSM instruction - __m128i sldq_pshufb[32]; - __m128i srdq_pshufb[32]; - __m128i rldq_pshufb[16]; + u128 sldq_pshufb[32]; // table for SHLQBYBI, SHLQBY, SHLQBYI instructions + u128 srdq_pshufb[32]; // table for ROTQMBYBI, ROTQMBY, ROTQMBYI instructions + u128 rldq_pshufb[16]; // table for ROTQBYBI, ROTQBY, ROTQBYI instructions - g_imm_table_struct() + class scale_table_t { - for (u32 i = 0; i < sizeof(fsm_table) / sizeof(fsm_table[0]); i++) + std::array<__m128, 155 + 174> m_data; + + public: + scale_table_t() { - for (u32 j = 0; j < 4; j++) mmToU32Ptr(fsm_table[i])[j] = (i & (1 << j)) ? ~0 : 0; + for (s32 i = -155; i < 174; i++) + { + m_data[i + 155] = _mm_set1_ps(static_cast(exp2(i))); + } } - for (u32 i = 0; i < sizeof(fsmh_table) / sizeof(fsmh_table[0]); i++) + + __forceinline __m128 operator [] (s32 scale) const { - for (u32 j = 0; j < 8; j++) mmToU16Ptr(fsmh_table[i])[j] = (i & (1 << j)) ? ~0 : 0; + return m_data[scale + 155]; } - for (u32 i = 0; i < sizeof(fsmb_table) / sizeof(fsmb_table[0]); i++) + } + const scale; + + g_spu_imm_table_t() + { + for (u32 i = 0; i < sizeof(fsm) / sizeof(fsm[0]); i++) { - for (u32 j = 0; j < 16; j++) mmToU8Ptr(fsmb_table[i])[j] = (i & (1 << j)) ? ~0 : 0; + for (u32 j = 0; j < 4; j++) + { + fsm[i]._u32[j] = (i & (1 << j)) ? 0xffffffff : 0; + } } + + for (u32 i = 0; i < sizeof(fsmh) / sizeof(fsmh[0]); i++) + { + for (u32 j = 0; j < 8; j++) + { + fsmh[i]._u16[j] = (i & (1 << j)) ? 0xffff : 0; + } + } + + for (u32 i = 0; i < sizeof(fsmb) / sizeof(fsmb[0]); i++) + { + for (u32 j = 0; j < 16; j++) + { + fsmb[i]._u8[j] = (i & (1 << j)) ? 0xff : 0; + } + } + for (u32 i = 0; i < sizeof(sldq_pshufb) / sizeof(sldq_pshufb[0]); i++) { - for (u32 j = 0; j < 16; j++) mmToU8Ptr(sldq_pshufb[i])[j] = (u8)(j - i); + for (u32 j = 0; j < 16; j++) + { + sldq_pshufb[i]._u8[j] = static_cast(j - i); + } } + for (u32 i = 0; i < sizeof(srdq_pshufb) / sizeof(srdq_pshufb[0]); i++) { - for (u32 j = 0; j < 16; j++) mmToU8Ptr(srdq_pshufb[i])[j] = (j + i > 15) ? 0xff : (u8)(j + i); + for (u32 j = 0; j < 16; j++) + { + srdq_pshufb[i]._u8[j] = (j + i > 15) ? 0xff : static_cast(j + i); + } } + for (u32 i = 0; i < sizeof(rldq_pshufb) / sizeof(rldq_pshufb[0]); i++) { - for (u32 j = 0; j < 16; j++) mmToU8Ptr(rldq_pshufb[i])[j] = (u8)(j - i) & 0xf; + for (u32 j = 0; j < 16; j++) + { + rldq_pshufb[i]._u8[j] = static_cast((j - i) & 0xf); + } } } }; -extern const g_imm_table_struct g_imm_table; +extern const g_spu_imm_table_t g_spu_imm; enum FPSCR_EX { diff --git a/rpcs3/Emu/Event.cpp b/rpcs3/Emu/Event.cpp index 4297aa2cad..29df4196fa 100644 --- a/rpcs3/Emu/Event.cpp +++ b/rpcs3/Emu/Event.cpp @@ -1,5 +1,6 @@ #include "stdafx.h" #include "Emu/Memory/Memory.h" +#include "Emu/System.h" #include "Emu/SysCalls/lv2/sleep_queue.h" #include "Emu/SysCalls/lv2/sys_event.h" diff --git a/rpcs3/Emu/FS/VFS.cpp b/rpcs3/Emu/FS/VFS.cpp index ceab7d7b19..27c0eedfea 100644 --- a/rpcs3/Emu/FS/VFS.cpp +++ b/rpcs3/Emu/FS/VFS.cpp @@ -6,22 +6,20 @@ #include "Ini.h" #include "Emu/System.h" #include "Utilities/Log.h" -#include // To check whether directory exists - -#undef CreateFile std::vector simplify_path_blocks(const std::string& path) { // fmt::tolower() removed std::vector path_blocks = std::move(fmt::split(path, { "/", "\\" })); - for (size_t i = 0; i < path_blocks.size(); ++i) + for (s32 i = 0; i < path_blocks.size(); ++i) { - if (path_blocks[i] == ".") + if (path_blocks[i] == "." || (i > 0 && path_blocks[i].empty())) { - path_blocks.erase(path_blocks.begin() + i--); + path_blocks.erase(path_blocks.begin() + i); + i--; } - else if (i && path_blocks[i] == "..") + else if (i > 0 && path_blocks[i] == "..") { path_blocks.erase(path_blocks.begin() + (i - 1), path_blocks.begin() + (i + 1)); i--; @@ -132,9 +130,10 @@ void VFS::UnMountAll() m_devices.clear(); } -vfsFileBase* VFS::OpenFile(const std::string& ps3_path, vfsOpenMode mode) const +vfsFileBase* VFS::OpenFile(const std::string& ps3_path, u32 mode) const { std::string path; + if (vfsDevice* dev = GetDevice(ps3_path, path)) { if (vfsFileBase* res = dev->GetNewFileStream()) @@ -163,28 +162,13 @@ vfsDirBase* VFS::OpenDir(const std::string& ps3_path) const return nullptr; } -bool VFS::CreateFile(const std::string& ps3_path, bool overwrite) const -{ - std::string path; - if (vfsDevice* dev = GetDevice(ps3_path, path)) - { - std::shared_ptr res(dev->GetNewFileStream()); - - if (res) - { - return res->Create(path, overwrite); - } - } - - return false; -} - bool VFS::CreateDir(const std::string& ps3_path) const { std::string path; + if (vfsDevice* dev = GetDevice(ps3_path, path)) { - std::shared_ptr res(dev->GetNewDirStream()); + std::unique_ptr res(dev->GetNewDirStream()); if (res) { @@ -195,12 +179,25 @@ bool VFS::CreateDir(const std::string& ps3_path) const return false; } +bool VFS::CreatePath(const std::string& ps3_path) const +{ + std::string path; + + if (vfsDevice* dev = GetDevice(ps3_path, path)) + { + return fs::create_path(path); + } + + return false; +} + bool VFS::RemoveFile(const std::string& ps3_path) const { std::string path; + if (vfsDevice* dev = GetDevice(ps3_path, path)) { - std::shared_ptr res(dev->GetNewFileStream()); + std::unique_ptr res(dev->GetNewFileStream()); if (res) { @@ -214,9 +211,10 @@ bool VFS::RemoveFile(const std::string& ps3_path) const bool VFS::RemoveDir(const std::string& ps3_path) const { std::string path; + if (vfsDevice* dev = GetDevice(ps3_path, path)) { - std::shared_ptr res(dev->GetNewDirStream()); + std::unique_ptr res(dev->GetNewDirStream()); if (res) { @@ -230,9 +228,10 @@ bool VFS::RemoveDir(const std::string& ps3_path) const bool VFS::ExistsFile(const std::string& ps3_path) const { std::string path; + if (vfsDevice* dev = GetDevice(ps3_path, path)) { - std::shared_ptr res(dev->GetNewFileStream()); + std::unique_ptr res(dev->GetNewFileStream()); if (res) { @@ -246,9 +245,10 @@ bool VFS::ExistsFile(const std::string& ps3_path) const bool VFS::ExistsDir(const std::string& ps3_path) const { std::string path; + if (vfsDevice* dev = GetDevice(ps3_path, path)) { - std::shared_ptr res(dev->GetNewDirStream()); + std::unique_ptr res(dev->GetNewDirStream()); if (res) { @@ -267,7 +267,7 @@ bool VFS::RenameFile(const std::string& ps3_path_from, const std::string& ps3_pa { if (vfsDevice* dev_ = GetDevice(ps3_path_to, path_to)) { - std::shared_ptr res(dev->GetNewFileStream()); + std::unique_ptr res(dev->GetNewFileStream()); if (res) { @@ -287,7 +287,7 @@ bool VFS::RenameDir(const std::string& ps3_path_from, const std::string& ps3_pat { if (vfsDevice* dev_ = GetDevice(ps3_path_to, path_to)) { - std::shared_ptr res(dev->GetNewDirStream()); + std::unique_ptr res(dev->GetNewDirStream()); if (res) { @@ -299,6 +299,33 @@ bool VFS::RenameDir(const std::string& ps3_path_from, const std::string& ps3_pat return false; } +bool VFS::CopyFile(const std::string& ps3_path_from, const std::string& ps3_path_to, bool overwrite) const +{ + std::string path_from, path_to; + + if (vfsDevice* dev = GetDevice(ps3_path_from, path_from)) + { + if (vfsDevice* dev_ = GetDevice(ps3_path_to, path_to)) + { + return fs::copy_file(path_from, path_to, overwrite); + } + } + + return false; +} + +bool VFS::TruncateFile(const std::string& ps3_path, u64 length) const +{ + std::string path; + + if (vfsDevice* dev = GetDevice(ps3_path, path)) + { + return fs::truncate_file(path, length); + } + + return false; +} + vfsDevice* VFS::GetDevice(const std::string& ps3_path, std::string& path) const { auto try_get_device = [this, &path](const std::string& ps3_path) -> vfsDevice* @@ -464,7 +491,6 @@ void VFS::SaveLoadDevices(std::vector& res, bool is_load) res.emplace_back(vfsDevice_LocalFile, "$(EmulatorDir)/dev_flash/", "/dev_flash/"); res.emplace_back(vfsDevice_LocalFile, "$(EmulatorDir)/dev_usb000/", "/dev_usb000/"); res.emplace_back(vfsDevice_LocalFile, "$(EmulatorDir)/dev_usb000/", "/dev_usb/"); - res.emplace_back(vfsDevice_LocalFile, "$(GameDir)/../../", "/dev_bdvd/"); res.emplace_back(vfsDevice_LocalFile, "", "/host_root/"); return; @@ -478,33 +504,25 @@ void VFS::SaveLoadDevices(std::vector& res, bool is_load) entries_count.SaveValue(count); } - // Custom EmulationDir. - // TODO:: should have a better log that would show results before loading a game? + // Custom EmulationDir if (Ini.SysEmulationDirPathEnable.GetValue()) { - std::string EmulationDir = Ini.SysEmulationDirPath.GetValue(); - if (EmulationDir.empty()) - Ini.SysEmulationDirPath.SetValue(Emu.GetEmulatorPath()); - struct stat fstatinfo; - if ((stat(EmulationDir.c_str(), &fstatinfo))) + std::string dir = Ini.SysEmulationDirPath.GetValue(); + + if (dir.empty()) { - LOG_NOTICE(GENERAL, "Custom EmualtionDir: Tried %s but it doesn't exists. Maybe you add some not needed chars like '\"'?"); - Ini.SysEmulationDirPathEnable.SetValue(false); + Ini.SysEmulationDirPath.SetValue(Emu.GetEmulatorPath()); + } + + if (!fs::is_dir(dir)) + { + LOG_ERROR(GENERAL, "Custom EmulationDir: directory '%s' not found", dir); } - else if (fstatinfo.st_mode & S_IFDIR) - LOG_NOTICE(GENERAL, "Custom EmualtionDir: On, Binded $(EmulatorDir) to %s.", EmulationDir); else { - // If that is not directory turn back to use original one. - LOG_NOTICE(GENERAL, "Custom EmulationDir: Cause path %s is not a valid directory.", EmulationDir); - Ini.SysEmulationDirPathEnable.SetValue(false); + LOG_NOTICE(GENERAL, "Custom EmulationDir: $(EmulatorDir) bound to '%s'", dir); } } - // I left this to check again just to catch those failed in directory checks. - if (!Ini.SysEmulationDirPathEnable.GetValue()) - { - LOG_NOTICE(GENERAL, "Custom EmualtionDir: Off, Binded $(EmulatorDir) to %s.", Emu.GetEmulatorPath()); - } for(int i=0; i arr0 = fmt::rSplit(path0.GetFullPath(), DL); + std::vector arr0 = fmt::rSplit(m_local_path, DL); std::vector arr1 = fmt::rSplit(local_path, DL); const u32 lim = (u32)std::min(arr0.size(), arr1.size()); @@ -188,9 +184,7 @@ std::string vfsDevice::GetWinPath(const std::string& p, bool is_dir) if(is_dir && ret[ret.length() - 1] != '/' && ret[ret.length() - 1] != '\\') ret += '/'; // ??? - rFileName res(ret); - res.Normalize(); - return res.GetFullPath(); + return ret; } std::string vfsDevice::GetWinPath(const std::string& l, const std::string& r) @@ -252,4 +246,4 @@ void vfsDevice::Unlock() const bool vfsDevice::TryLock() const { return m_mtx_lock.try_lock(); -} \ No newline at end of file +} diff --git a/rpcs3/Emu/FS/vfsDirBase.cpp b/rpcs3/Emu/FS/vfsDirBase.cpp index 2d54b48e42..4a001e43fe 100644 --- a/rpcs3/Emu/FS/vfsDirBase.cpp +++ b/rpcs3/Emu/FS/vfsDirBase.cpp @@ -1,5 +1,5 @@ #include "stdafx.h" -#include "Utilities/rFile.h" +#include "Utilities/File.h" #include "vfsDirBase.h" vfsDirBase::vfsDirBase(vfsDevice* device) @@ -63,4 +63,4 @@ const DirEntryInfo* vfsDirBase::First() { m_pos = 0; return Read(); -} \ No newline at end of file +} diff --git a/rpcs3/Emu/FS/vfsDirBase.h b/rpcs3/Emu/FS/vfsDirBase.h index 654cc72d01..4bb707a941 100644 --- a/rpcs3/Emu/FS/vfsDirBase.h +++ b/rpcs3/Emu/FS/vfsDirBase.h @@ -16,12 +16,14 @@ struct DirEntryInfo { std::string name; u32 flags; + u64 size; time_t create_time; time_t access_time; time_t modify_time; DirEntryInfo() : flags(0) + , size(0) , create_time(0) , access_time(0) , modify_time(0) diff --git a/rpcs3/Emu/FS/vfsFile.cpp b/rpcs3/Emu/FS/vfsFile.cpp index 6f990c31e2..649a03fcda 100644 --- a/rpcs3/Emu/FS/vfsFile.cpp +++ b/rpcs3/Emu/FS/vfsFile.cpp @@ -10,14 +10,14 @@ vfsFile::vfsFile() { } -vfsFile::vfsFile(const std::string& path, vfsOpenMode mode) +vfsFile::vfsFile(const std::string& path, u32 mode) : vfsFileBase(nullptr) , m_stream(nullptr) { Open(path, mode); } -bool vfsFile::Open(const std::string& path, vfsOpenMode mode) +bool vfsFile::Open(const std::string& path, u32 mode) { Close(); @@ -26,11 +26,6 @@ bool vfsFile::Open(const std::string& path, vfsOpenMode mode) return m_stream && m_stream->IsOpened(); } -bool vfsFile::Create(const std::string& path, bool overwrite) -{ - return m_stream->Create(path, overwrite); -} - bool vfsFile::Exists(const std::string& path) { return m_stream->Exists(path); @@ -49,10 +44,11 @@ bool vfsFile::Remove(const std::string& path) bool vfsFile::Close() { m_stream.reset(); - return vfsFileBase::Close(); + + return true; } -u64 vfsFile::GetSize() +u64 vfsFile::GetSize() const { return m_stream->GetSize(); } @@ -67,7 +63,7 @@ u64 vfsFile::Read(void* dst, u64 size) return m_stream->Read(dst, size); } -u64 vfsFile::Seek(s64 offset, vfsSeekMode mode) +u64 vfsFile::Seek(s64 offset, u32 mode) { return m_stream->Seek(offset, mode); } @@ -79,5 +75,5 @@ u64 vfsFile::Tell() const bool vfsFile::IsOpened() const { - return m_stream && m_stream->IsOpened() && vfsFileBase::IsOpened(); + return m_stream && m_stream->IsOpened(); } diff --git a/rpcs3/Emu/FS/vfsFile.h b/rpcs3/Emu/FS/vfsFile.h index a5ed8cf138..dfb211cbd4 100644 --- a/rpcs3/Emu/FS/vfsFile.h +++ b/rpcs3/Emu/FS/vfsFile.h @@ -8,22 +8,21 @@ private: public: vfsFile(); - vfsFile(const std::string& path, vfsOpenMode mode = vfsRead); + vfsFile(const std::string& path, u32 mode = vfsRead); - virtual bool Open(const std::string& path, vfsOpenMode mode = vfsRead) override; - virtual bool Create(const std::string& path, bool overwrite = false) override; + virtual bool Open(const std::string& path, u32 mode = vfsRead) override; virtual bool Exists(const std::string& path) override; virtual bool Rename(const std::string& from, const std::string& to) override; virtual bool Remove(const std::string& path) override; virtual bool Close() override; - virtual u64 GetSize() 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, vfsSeekMode mode = vfsSeekSet) override; + virtual u64 Seek(s64 offset, u32 mode = from_begin) override; virtual u64 Tell() const override; virtual bool IsOpened() const override; -}; \ No newline at end of file +}; diff --git a/rpcs3/Emu/FS/vfsFileBase.cpp b/rpcs3/Emu/FS/vfsFileBase.cpp index 1cbed18a2c..dc7aa6dd56 100644 --- a/rpcs3/Emu/FS/vfsFileBase.cpp +++ b/rpcs3/Emu/FS/vfsFileBase.cpp @@ -12,18 +12,11 @@ vfsFileBase::~vfsFileBase() Close(); } -bool Access(const std::string& path, vfsOpenMode mode) -{ - return false; -} - -bool vfsFileBase::Open(const std::string& path, vfsOpenMode mode) +bool vfsFileBase::Open(const std::string& path, u32 mode) { m_path = path; m_mode = mode; - vfsStream::Reset(); - return true; } @@ -39,7 +32,7 @@ std::string vfsFileBase::GetPath() const return m_path; } -vfsOpenMode vfsFileBase::GetOpenMode() const +u32 vfsFileBase::GetOpenMode() const { return m_mode; } diff --git a/rpcs3/Emu/FS/vfsFileBase.h b/rpcs3/Emu/FS/vfsFileBase.h index 700f397a2a..9639d76992 100644 --- a/rpcs3/Emu/FS/vfsFileBase.h +++ b/rpcs3/Emu/FS/vfsFileBase.h @@ -1,15 +1,12 @@ #pragma once #include "vfsStream.h" -enum vfsOpenMode : u8 +enum vfsOpenMode : u32 { - vfsRead = 0x1, - vfsWrite = 0x2, - vfsExcl = 0x4, - vfsAppend = 0x8, - vfsReadWrite = vfsRead | vfsWrite, - vfsWriteExcl = vfsWrite | vfsExcl, - vfsWriteAppend = vfsWrite | vfsAppend, + vfsRead = o_read, + vfsReadWrite = o_read | o_write, + vfsWriteNew = o_write | o_create | o_trunc, + vfsWriteExcl = o_write | o_create | o_excl, }; class vfsDevice; @@ -18,20 +15,20 @@ struct vfsFileBase : public vfsStream { protected: std::string m_path; - vfsOpenMode m_mode; + u32 m_mode; vfsDevice* m_device; public: vfsFileBase(vfsDevice* device); - virtual ~vfsFileBase(); + virtual ~vfsFileBase() override; - virtual bool Open(const std::string& path, vfsOpenMode mode); + virtual bool Open(const std::string& path, u32 mode); virtual bool Close() override; - virtual bool Create(const std::string& path, bool overwrite = false) { return false; } virtual bool Exists(const std::string& path) { return false; } virtual bool Rename(const std::string& from, const std::string& to) { return false; } virtual bool Remove(const std::string& path) { return false; } + virtual bool IsOpened() const override { return !m_path.empty(); } std::string GetPath() const; - vfsOpenMode GetOpenMode() const; + u32 GetOpenMode() const; }; diff --git a/rpcs3/Emu/FS/vfsLocalDir.cpp b/rpcs3/Emu/FS/vfsLocalDir.cpp index cad28f5a64..822fe4f051 100644 --- a/rpcs3/Emu/FS/vfsLocalDir.cpp +++ b/rpcs3/Emu/FS/vfsLocalDir.cpp @@ -12,30 +12,29 @@ vfsLocalDir::~vfsLocalDir() bool vfsLocalDir::Open(const std::string& path) { - if(!vfsDirBase::Open(path)) - return false; - - if(!dir.Open(path)) + if (!vfsDirBase::Open(path) || !dir.Open(path)) + { return false; + } std::string name; - for(bool is_ok = dir.GetFirst(&name); is_ok; is_ok = dir.GetNext(&name)) + + for (bool is_ok = dir.GetFirst(&name); is_ok; is_ok = dir.GetNext(&name)) { - std::string dir_path = path + "/" + name; + fs::stat_t file_info; + fs::stat(path + "/" + name, file_info); m_entries.emplace_back(); - // TODO: Use same info structure as fileinfo? + DirEntryInfo& info = m_entries.back(); + info.name = name; - - FileInfo fileinfo; - getFileInfo(dir_path.c_str(), &fileinfo); - - // Not sure of purpose for below. I hope these don't need to be correct - info.flags |= rIsDir(dir_path) ? DirEntry_TypeDir : DirEntry_TypeFile; - if(fileinfo.isWritable) info.flags |= DirEntry_PermWritable; - info.flags |= DirEntry_PermReadable; // Always? - info.flags |= DirEntry_PermExecutable; // Always? + info.flags |= file_info.is_directory ? DirEntry_TypeDir | DirEntry_PermExecutable : DirEntry_TypeFile; + info.flags |= file_info.is_writable ? DirEntry_PermWritable | DirEntry_PermReadable : DirEntry_PermReadable; + info.size = file_info.size; + info.access_time = file_info.atime; + info.modify_time = file_info.mtime; + info.create_time = file_info.ctime; } return true; @@ -43,22 +42,22 @@ bool vfsLocalDir::Open(const std::string& path) bool vfsLocalDir::Create(const std::string& path) { - return rMkdir(path); + return fs::create_dir(path); } bool vfsLocalDir::IsExists(const std::string& path) const { - return rIsDir(path); + return fs::is_dir(path); } bool vfsLocalDir::Rename(const std::string& from, const std::string& to) { - return rRename(from, to); + return fs::rename(from, to); } bool vfsLocalDir::Remove(const std::string& path) { - return rRmdir(path); + return fs::remove_dir(path); } bool vfsLocalDir::IsOpened() const diff --git a/rpcs3/Emu/FS/vfsLocalDir.h b/rpcs3/Emu/FS/vfsLocalDir.h index c2174f3658..1c6e5ee6ae 100644 --- a/rpcs3/Emu/FS/vfsLocalDir.h +++ b/rpcs3/Emu/FS/vfsLocalDir.h @@ -1,6 +1,6 @@ #pragma once #include "vfsDirBase.h" -#include "Utilities/rFile.h" +#include "Utilities/File.h" class vfsLocalDir : public vfsDirBase { diff --git a/rpcs3/Emu/FS/vfsLocalFile.cpp b/rpcs3/Emu/FS/vfsLocalFile.cpp index 1542a49be5..c0a1d57935 100644 --- a/rpcs3/Emu/FS/vfsLocalFile.cpp +++ b/rpcs3/Emu/FS/vfsLocalFile.cpp @@ -2,136 +2,63 @@ #include "Utilities/Log.h" #include "vfsLocalFile.h" -static const rFile::OpenMode vfs2wx_mode(vfsOpenMode mode) -{ - switch(mode) - { - case vfsRead: return rFile::read; - case vfsWrite: return rFile::write; - case vfsReadWrite: return rFile::read_write; - case vfsWriteExcl: return rFile::write_excl; - case vfsWriteAppend: return rFile::write_append; - } - - return rFile::read; -} - -static const rSeekMode vfs2wx_seek(vfsSeekMode mode) -{ - switch(mode) - { - case vfsSeekSet: return rFromStart; - case vfsSeekCur: return rFromCurrent; - case vfsSeekEnd: return rFromEnd; - } - - return rFromStart; -} - vfsLocalFile::vfsLocalFile(vfsDevice* device) : vfsFileBase(device) { } -bool vfsLocalFile::Open(const std::string& path, vfsOpenMode mode) +bool vfsLocalFile::Open(const std::string& path, u32 mode) { Close(); - // if(m_device) - // { - // if(!m_file.Access(fmt::FromUTF8(vfsDevice::GetWinPath(m_device->GetLocalPath(), path)), vfs2wx_mode(mode))) return false; - - // return m_file.Open(fmt::FromUTF8(vfsDevice::GetWinPath(m_device->GetLocalPath(), path)), vfs2wx_mode(mode)) && - // vfsFileBase::Open(fmt::FromUTF8(vfsDevice::GetPs3Path(m_device->GetPs3Path(), path)), mode); - // } - // else - // { - if(!m_file.Access(path, vfs2wx_mode(mode))) return false; - - return m_file.Open(path, vfs2wx_mode(mode)) && vfsFileBase::Open(path, mode); - // } -} - -bool vfsLocalFile::Create(const std::string& path, bool overwrite) -{ - LOG_WARNING(HLE, "vfsLocalFile::Create('%s', overwrite=%d)", path.c_str(), overwrite); - for(uint p=1; p < path.length() && path[p] != '\0' ; p++) - { - for(; p < path.length() && path[p] != '\0'; p++) - if(path[p] == '/' || path[p] == '\\') break; // ??? - - if(p == path.length() || path[p] == '\0') - break; - - const std::string& dir = path.substr(0, p); - if(!rExists(dir)) - { - LOG_NOTICE(HLE, "create dir: %s", dir.c_str()); - rMkdir(dir); - } - } - - //create file - const char m = path[path.length() - 1]; - if(m != '/' && m != '\\' && !rExists(path)) // ??? - { - rFile f; - if (!f.Create(path, overwrite)) { - if (overwrite) LOG_NOTICE(HLE, "vfsLocalFile::Create: couldn't create file"); - return false; - } - else - return true; - } - - return true; + return m_file.open(path, mode) && vfsFileBase::Open(path, mode); } bool vfsLocalFile::Close() { - return m_file.Close() && vfsFileBase::Close(); + return m_file.close() && vfsFileBase::Close(); } -u64 vfsLocalFile::GetSize() +u64 vfsLocalFile::GetSize() const { - return m_file.Length(); + return m_file.size(); } u64 vfsLocalFile::Write(const void* src, u64 size) { - return m_file.Write(src, size); + return m_file.write(src, size); } u64 vfsLocalFile::Read(void* dst, u64 size) { - return m_file.Read(dst, size); + return m_file.read(dst, size); } -u64 vfsLocalFile::Seek(s64 offset, vfsSeekMode mode) +u64 vfsLocalFile::Seek(s64 offset, u32 mode) { - return m_file.Seek(offset, vfs2wx_seek(mode)); + return m_file.seek(offset, mode); } u64 vfsLocalFile::Tell() const { - return m_file.Tell(); + return m_file.seek(0, from_cur); } bool vfsLocalFile::IsOpened() const { - return m_file.IsOpened() && vfsFileBase::IsOpened(); + return m_file && vfsFileBase::IsOpened(); } bool vfsLocalFile::Exists(const std::string& path) { - return rExists(path); + return fs::is_file(path); } bool vfsLocalFile::Rename(const std::string& from, const std::string& to) { - return rRename(from, to); + return fs::rename(from, to); } bool vfsLocalFile::Remove(const std::string& path) { - return rRemoveFile(path); + return fs::remove_file(path); } diff --git a/rpcs3/Emu/FS/vfsLocalFile.h b/rpcs3/Emu/FS/vfsLocalFile.h index 42eb7a90bc..d6e0b5c493 100644 --- a/rpcs3/Emu/FS/vfsLocalFile.h +++ b/rpcs3/Emu/FS/vfsLocalFile.h @@ -1,29 +1,29 @@ #pragma once #include "vfsFileBase.h" -#include "Utilities/rFile.h" class vfsLocalFile : public vfsFileBase { private: - rFile m_file; + fs::file m_file; public: vfsLocalFile(vfsDevice* device); - virtual bool Open(const std::string& path, vfsOpenMode mode = vfsRead) override; - virtual bool Create(const std::string& path, bool overwrite = false) override; + virtual bool Open(const std::string& path, u32 mode = vfsRead) override; virtual bool Close() override; virtual bool Exists(const std::string& path) override; virtual bool Rename(const std::string& from, const std::string& to) override; virtual bool Remove(const std::string& path) override; - virtual u64 GetSize() 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, vfsSeekMode mode = vfsSeekSet) override; + virtual u64 Seek(s64 offset, u32 mode = from_begin) override; virtual u64 Tell() const override; virtual bool IsOpened() const override; -}; \ No newline at end of file + + virtual const fs::file& GetFile() const { return m_file; } +}; diff --git a/rpcs3/Emu/FS/vfsStream.cpp b/rpcs3/Emu/FS/vfsStream.cpp index eb15ad0837..a1fe0ffc0e 100644 --- a/rpcs3/Emu/FS/vfsStream.cpp +++ b/rpcs3/Emu/FS/vfsStream.cpp @@ -1,80 +1,2 @@ #include "stdafx.h" #include "vfsStream.h" - -vfsStream::vfsStream() -{ -} - -vfsStream::~vfsStream() -{ - Close(); -} - -void vfsStream::Reset() -{ - m_pos = 0; -} - -bool vfsStream::Close() -{ - Reset(); - - return true; -} - -u64 vfsStream::GetSize() -{ - u64 last_pos = Tell(); - Seek(0, vfsSeekEnd); - u64 size = Tell(); - Seek(last_pos, vfsSeekSet); - - return size; -} - -u64 vfsStream::Write(const void* src, u64 size) -{ - m_pos += size; - - return size; -} - -u64 vfsStream::Read(void* dst, u64 size) -{ - m_pos += size; - - return size; -} - -u64 vfsStream::Seek(s64 offset, vfsSeekMode mode) -{ - switch(mode) - { - case vfsSeekSet: - m_pos = offset; - break; - case vfsSeekCur: - m_pos += offset; - break; - case vfsSeekEnd: - m_pos = GetSize() + offset; - break; - } - - return m_pos; -} - -u64 vfsStream::Tell() const -{ - return m_pos; -} - -bool vfsStream::Eof() -{ - return Tell() >= GetSize(); -} - -bool vfsStream::IsOpened() const -{ - return true; -} \ No newline at end of file diff --git a/rpcs3/Emu/FS/vfsStream.h b/rpcs3/Emu/FS/vfsStream.h index cceb80b2ed..28e775c2cd 100644 --- a/rpcs3/Emu/FS/vfsStream.h +++ b/rpcs3/Emu/FS/vfsStream.h @@ -1,33 +1,44 @@ #pragma once - -enum vfsSeekMode -{ - vfsSeekSet, - vfsSeekCur, - vfsSeekEnd, -}; +#include "Utilities/File.h" struct vfsStream { -protected: - u64 m_pos; + vfsStream() = default; -public: - vfsStream(); + virtual ~vfsStream() + { + Close(); + } - virtual ~vfsStream(); + virtual bool Close() + { + return true; + } - virtual void Reset(); - virtual bool Close(); + virtual u64 GetSize() const = 0; - virtual u64 GetSize(); + virtual u64 Write(const void* src, u64 count) = 0; - virtual u64 Write(const void* src, u64 size); - virtual u64 Read(void* dst, u64 size); + template __forceinline bool SWrite(const T& data, u64 count = sizeof(T)) + { + return Write(&data, count) == count; + } - virtual u64 Seek(s64 offset, vfsSeekMode mode = vfsSeekSet); - virtual u64 Tell() const; - virtual bool Eof(); + virtual u64 Read(void* dst, u64 count) = 0; - virtual bool IsOpened() const; -}; \ No newline at end of file + template __forceinline bool SRead(T& data, u64 count = sizeof(T)) + { + return Read(&data, count) == count; + } + + virtual u64 Seek(s64 offset, u32 mode = from_begin) = 0; + + virtual u64 Tell() const = 0; + + virtual bool Eof() const + { + return Tell() >= GetSize(); + } + + virtual bool IsOpened() const = 0; +}; diff --git a/rpcs3/Emu/FS/vfsStreamMemory.cpp b/rpcs3/Emu/FS/vfsStreamMemory.cpp index 5ce30c3a7c..67134f8d3c 100644 --- a/rpcs3/Emu/FS/vfsStreamMemory.cpp +++ b/rpcs3/Emu/FS/vfsStreamMemory.cpp @@ -2,48 +2,28 @@ #include "Emu/Memory/Memory.h" #include "vfsStreamMemory.h" -vfsStreamMemory::vfsStreamMemory() : vfsStream() +u64 vfsStreamMemory::Write(const void* src, u64 count) { -} - -vfsStreamMemory::vfsStreamMemory(u32 addr, u32 size) : vfsStream() -{ - Open(addr, size); -} - -void vfsStreamMemory::Open(u32 addr, u32 size) -{ - m_addr = addr; - m_size = size ? size : 0x100000000ull - addr; // determine max possible size - - vfsStream::Reset(); -} - -u64 vfsStreamMemory::GetSize() -{ - return m_size; -} - -u64 vfsStreamMemory::Write(const void* src, u64 size) -{ - assert(Tell() < m_size); - if (Tell() + size > m_size) + assert(m_pos < m_size); + if (m_pos + count > m_size) { - size = m_size - Tell(); + count = m_size - m_pos; } - memcpy(vm::get_ptr(vm::cast(m_addr + Tell())), src, size); - return vfsStream::Write(src, size); + memcpy(vm::get_ptr(vm::cast(m_addr + m_pos)), src, count); + m_pos += count; + return count; } -u64 vfsStreamMemory::Read(void* dst, u64 size) +u64 vfsStreamMemory::Read(void* dst, u64 count) { - assert(Tell() < GetSize()); - if (Tell() + size > GetSize()) + assert(m_pos < m_size); + if (m_pos + count > m_size) { - size = GetSize() - Tell(); + count = m_size - m_pos; } - memcpy(dst, vm::get_ptr(vm::cast(m_addr + Tell())), size); - return vfsStream::Read(dst, size); + memcpy(dst, vm::get_ptr(vm::cast(m_addr + m_pos)), count); + m_pos += count; + return count; } diff --git a/rpcs3/Emu/FS/vfsStreamMemory.h b/rpcs3/Emu/FS/vfsStreamMemory.h index 1e3e06a73b..e6d7f48482 100644 --- a/rpcs3/Emu/FS/vfsStreamMemory.h +++ b/rpcs3/Emu/FS/vfsStreamMemory.h @@ -1,19 +1,57 @@ #pragma once #include "vfsStream.h" -struct vfsStreamMemory : public vfsStream +class vfsStreamMemory : public vfsStream { - u32 m_addr; - u64 m_size; + u64 m_pos = 0; + u32 m_addr = 0; + u64 m_size = 0; public: - vfsStreamMemory(); - vfsStreamMemory(u32 addr, u32 size = 0); + vfsStreamMemory() = default; - void Open(u32 addr, u32 size = 0); + vfsStreamMemory(u32 addr, u32 size = 0) + { + Open(addr, size); + } - virtual u64 GetSize() override; + void Open(u32 addr, u32 size = 0) + { + m_pos = 0; + m_addr = addr; + m_size = size ? size : 0x100000000ull - addr; // determine max possible size + } - virtual u64 Write(const void* src, u64 size) override; - virtual u64 Read(void* dst, u64 size) override; -}; \ No newline at end of file + virtual u64 GetSize() const override + { + return m_size; + } + + virtual u64 Write(const void* src, u64 count) override; + + virtual u64 Read(void* dst, u64 count) override; + + virtual u64 Seek(s64 offset, u32 mode = from_begin) override + { + assert(mode < 3); + + switch (mode) + { + case from_begin: return m_pos = offset; + case from_cur: return m_pos += offset; + case from_end: return m_pos = m_size + offset; + } + + return m_pos; + } + + virtual u64 Tell() const override + { + return m_pos; + } + + virtual bool IsOpened() const override + { + return true; + } +}; diff --git a/rpcs3/Emu/HDD/HDD.cpp b/rpcs3/Emu/HDD/HDD.cpp index 80eda63429..c16127fb75 100644 --- a/rpcs3/Emu/HDD/HDD.cpp +++ b/rpcs3/Emu/HDD/HDD.cpp @@ -21,7 +21,7 @@ void vfsHDDManager::CreateEntry(vfsHDD_Entry& entry) void vfsHDDManager::CreateHDD(const std::string& path, u64 size, u64 block_size) { - rFile f(path, rFile::write); + fs::file f(path, o_write | o_create | o_trunc); static const u64 cur_dir_block = 1; @@ -32,7 +32,7 @@ void vfsHDDManager::CreateHDD(const std::string& path, u64 size, u64 block_size) hdr.version = g_hdd_version; hdr.block_count = (size + block_size) / block_size; hdr.block_size = block_size; - f.Write(&hdr, sizeof(vfsHDD_Hdr)); + f.write(&hdr, sizeof(vfsHDD_Hdr)); { vfsHDD_Entry entry; @@ -41,14 +41,14 @@ void vfsHDDManager::CreateHDD(const std::string& path, u64 size, u64 block_size) entry.data_block = hdr.next_block; entry.next_block = 0; - f.Seek(cur_dir_block * hdr.block_size); - f.Write(&entry, sizeof(vfsHDD_Entry)); - f.Write("."); + f.seek(cur_dir_block * hdr.block_size); + f.write(&entry, sizeof(vfsHDD_Entry)); + f.write(".", 1); } u8 null = 0; - f.Seek(hdr.block_count * hdr.block_size - sizeof(null)); - f.Write(&null, sizeof(null)); + f.seek(hdr.block_count * hdr.block_size - sizeof(null)); + f.write(&null, sizeof(null)); } void vfsHDDManager::Format() @@ -599,7 +599,7 @@ bool vfsHDD::GetNextEntry(u64& block, vfsHDD_Entry& entry, std::string& name) return true; } -bool vfsHDD::Open(const std::string& path, vfsOpenMode mode) +bool vfsHDD::Open(const std::string& path, u32 mode) { const char* s = path.c_str(); u64 from = 0; @@ -737,47 +737,44 @@ bool vfsHDD::RemoveEntry(const std::string& name) return true; } -bool vfsHDD::Create(const std::string& path) +u64 vfsHDD::Write(const void* src, u64 size) { - return false; + return m_file.Write(src, size); // ??? } -u32 vfsHDD::Write(const void* src, u32 size) +u64 vfsHDD::Read(void* dst, u64 size) { - return vfsFileBase::Write(src, m_file.Write(src, size)); + return m_file.Read(dst, size); // ??? } -u32 vfsHDD::Read(void* dst, u32 size) -{ - return vfsFileBase::Read(dst, m_file.Read(dst, size)); -} - -u64 vfsHDD::Seek(s64 offset, vfsSeekMode mode) +u64 vfsHDD::Seek(s64 offset, u32 mode) { switch (mode) { - case vfsSeekCur: - m_file.Seek(Tell() + offset); - break; - - case vfsSeekSet: - m_file.Seek(offset); - break; - - case vfsSeekEnd: - m_file.Seek(m_file.GetSize() + offset); - break; + case from_begin: return m_file.Seek(offset); + case from_cur: return m_file.Seek(Tell() + offset); + case from_end: return m_file.Seek(m_file.GetSize() + offset); } - return vfsFileBase::Seek(offset, mode); + return m_file.Tell(); // ??? } -bool vfsHDD::Eof() +u64 vfsHDD::Tell() const +{ + return m_file.Tell(); // ??? +} + +bool vfsHDD::Eof() const { return m_file.Eof(); } -u64 vfsHDD::GetSize() +bool vfsHDD::IsOpened() const +{ + return true; // ??? +} + +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 f71fa77f35..22668d9474 100644 --- a/rpcs3/Emu/HDD/HDD.h +++ b/rpcs3/Emu/HDD/HDD.h @@ -32,7 +32,7 @@ enum vfsHDD_EntryType : u8 struct vfsHDD_Entry : public vfsHDD_Block { u64 data_block; - vfsOpenMode access; + u32 access; vfsHDD_EntryType type; u64 size; u64 ctime; @@ -109,6 +109,11 @@ public: bool Seek(u64 pos); + u64 Tell() const + { + return m_cur_block * m_hdd_info.block_size + m_position; // ??? + } + void SaveInfo(); u64 Read(void* dst, u64 size); @@ -177,7 +182,7 @@ public: bool GetNextEntry(u64& block, vfsHDD_Entry& entry, std::string& name); - virtual bool Open(const std::string& path, vfsOpenMode mode = vfsRead); + virtual bool Open(const std::string& path, u32 mode = vfsRead); bool HasEntry(const std::string& name); @@ -187,15 +192,17 @@ public: bool RemoveEntry(const std::string& name); - virtual bool Create(const std::string& path); + virtual u64 Write(const void* src, u64 count) override; - virtual u32 Write(const void* src, u32 size); + virtual u64 Read(void* dst, u64 count) override; - virtual u32 Read(void* dst, u32 size); + virtual u64 Seek(s64 offset, u32 mode = from_begin) override; - virtual u64 Seek(s64 offset, vfsSeekMode mode = vfsSeekSet); + virtual u64 Tell() const override; - virtual bool Eof(); + virtual bool Eof() const override; - virtual u64 GetSize(); + virtual bool IsOpened() const override; + + virtual u64 GetSize() const; }; diff --git a/rpcs3/Emu/IdManager.h b/rpcs3/Emu/IdManager.h index 2d1966c198..3921327ca6 100644 --- a/rpcs3/Emu/IdManager.h +++ b/rpcs3/Emu/IdManager.h @@ -122,22 +122,6 @@ public: return m_cur_id++; } - template bool GetIDData(const u32 id, std::shared_ptr& result) - { - std::lock_guard lock(m_mutex); - - auto f = m_id_map.find(id); - - if (f == m_id_map.end() || f->second.GetInfo() != typeid(T)) - { - return false; - } - - result = f->second.GetData(); - - return true; - } - template std::shared_ptr GetIDData(const u32 id) { std::lock_guard lock(m_mutex); diff --git a/rpcs3/Emu/Memory/vm.cpp b/rpcs3/Emu/Memory/vm.cpp index dc32c017ac..ff2da7e06b 100644 --- a/rpcs3/Emu/Memory/vm.cpp +++ b/rpcs3/Emu/Memory/vm.cpp @@ -628,27 +628,25 @@ namespace vm u32 stack_push(CPUThread& CPU, u32 size, u32 align_v, u32& old_pos) { - assert(align_v); - switch (CPU.GetType()) { case CPU_THREAD_PPU: { - PPUThread& PPU = static_cast(CPU); + PPUThread& context = static_cast(CPU); - old_pos = vm::cast(PPU.GPR[1], "SP"); - PPU.GPR[1] -= align(size, 8); // room minimal possible size - PPU.GPR[1] &= ~(align_v - 1); // fix stack alignment + old_pos = vm::cast(context.GPR[1], "SP"); + context.GPR[1] -= align(size, 8); // room minimal possible size + context.GPR[1] &= ~(align_v - 1); // fix stack alignment - if (PPU.GPR[1] < CPU.GetStackAddr()) + if (context.GPR[1] < CPU.GetStackAddr()) { - // stack overflow - PPU.GPR[1] = old_pos; + LOG_ERROR(PPU, "vm::stack_push(0x%x,%d): stack overflow (SP=0x%llx, stack=*0x%x)", size, align_v, context.GPR[1], CPU.GetStackAddr()); + context.GPR[1] = old_pos; return 0; } else { - return (u32)PPU.GPR[1]; + return static_cast(context.GPR[1]); } } @@ -669,7 +667,7 @@ namespace vm if (context.SP < CPU.GetStackAddr()) { - // stack overflow + LOG_ERROR(ARMv7, "vm::stack_push(0x%x,%d): stack overflow (SP=0x%x, stack=*0x%x)", size, align_v, context.SP, CPU.GetStackAddr()); context.SP = old_pos; return 0; } @@ -693,10 +691,14 @@ namespace vm { case CPU_THREAD_PPU: { - PPUThread& PPU = static_cast(CPU); + PPUThread& context = static_cast(CPU); - assert(PPU.GPR[1] == addr); - PPU.GPR[1] = old_pos; + if (context.GPR[1] != addr && !Emu.IsStopped()) + { + LOG_ERROR(PPU, "vm::stack_pop(*0x%x,*0x%x): stack inconsistency (SP=0x%llx)", addr, old_pos, context.GPR[1]); + } + + context.GPR[1] = old_pos; return; } @@ -711,7 +713,11 @@ namespace vm { ARMv7Context& context = static_cast(CPU).context; - assert(context.SP == addr); + if (context.SP != addr && !Emu.IsStopped()) + { + LOG_ERROR(ARMv7, "vm::stack_pop(*0x%x,*0x%x): stack inconsistency (SP=0x%x)", addr, old_pos, context.SP); + } + context.SP = old_pos; return; } diff --git a/rpcs3/Emu/Memory/vm.h b/rpcs3/Emu/Memory/vm.h index 73ae618404..41f0f825b8 100644 --- a/rpcs3/Emu/Memory/vm.h +++ b/rpcs3/Emu/Memory/vm.h @@ -65,7 +65,7 @@ namespace vm void dealloc(u32 addr, memory_location location = user_space); template - T* const get_ptr(u32 addr) + T* get_ptr(u32 addr) { return reinterpret_cast(static_cast(g_base_addr) + addr); } @@ -77,7 +77,7 @@ namespace vm } template - T* const priv_ptr(u32 addr) + T* priv_ptr(u32 addr) { return reinterpret_cast(static_cast(g_priv_addr) + addr); } @@ -107,15 +107,11 @@ namespace vm template<> struct cast_ptr { + static_assert(sizeof(unsigned long) == 8, "Unexpected size of unsigned long"); + __forceinline static u32 cast(const unsigned long addr, const char* func) { - const u32 res = static_cast(addr); - if (res != addr) - { - vm::error(addr, func); - } - - return res; + return cast_ptr::cast(addr, func); } }; #endif diff --git a/rpcs3/Emu/Memory/vm_ptr.h b/rpcs3/Emu/Memory/vm_ptr.h index 79fca811d9..d1eef9fe21 100644 --- a/rpcs3/Emu/Memory/vm_ptr.h +++ b/rpcs3/Emu/Memory/vm_ptr.h @@ -1,6 +1,6 @@ #pragma once -class CPUThread; +class PPUThread; struct ARMv7Context; namespace vm @@ -354,7 +354,7 @@ namespace vm public: typedef RT(type)(T...); - RT operator()(CPUThread& CPU, T... args) const; // defined in CB_FUNC.h, call using specified PPU thread context + RT operator()(PPUThread& CPU, T... args) const; // defined in CB_FUNC.h, call using specified PPU thread context RT operator()(ARMv7Context& context, T... args) const; // defined in ARMv7Callback.h, passing context is mandatory @@ -410,35 +410,47 @@ namespace vm static_assert(!sizeof(AT), "vm::_ptr_base<> error: use RT(T...) format for functions instead of RT(*)(T...)"); }; - //BE pointer to LE data + // BE pointer to LE data template using bptrl = _ptr_base::type>; - //BE pointer to BE data + // BE pointer to BE data template using bptrb = _ptr_base::type, lvl, typename to_be_t::type>; - //LE pointer to BE data + // LE pointer to BE data template using lptrb = _ptr_base::type, lvl, AT>; - //LE pointer to LE data + // LE pointer to LE data template using lptrl = _ptr_base; namespace ps3 { - //default pointer for HLE functions (LE pointer to BE data) + // default pointer for HLE functions (LE pointer to BE data) template using ptr = lptrb; - //default pointer for HLE structures (BE pointer to BE data) + // default pointer for HLE structures (BE pointer to BE data) template using bptr = bptrb; } namespace psv { - //default pointer for HLE functions & structures (LE pointer to LE data) + // default pointer for HLE functions & structures (LE pointer to LE data) template using ptr = lptrl; } - //PS3 emulation is main now, so lets it be as default + // PS3 emulation is main now, so lets it be as default using namespace ps3; + + struct null_t + { + template operator _ptr_base() const + { + const std::array value = {}; + return _ptr_base::make(value[0]); + } + }; + + // vm::null is convertible to any vm::ptr type as null pointer in virtual memory + static null_t null; } namespace fmt diff --git a/rpcs3/Emu/RSX/CgBinaryProgram.h b/rpcs3/Emu/RSX/CgBinaryProgram.h index e8084a541d..ff64e96e94 100644 --- a/rpcs3/Emu/RSX/CgBinaryProgram.h +++ b/rpcs3/Emu/RSX/CgBinaryProgram.h @@ -1,7 +1,6 @@ #pragma once - #include -#include "Utilities/rFile.h" +#include "Utilities/File.h" #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/RSX/GL/GLVertexProgram.h" @@ -182,14 +181,12 @@ public: , m_arb_shader("") , m_dst_reg_name("") { - rFile f(path); - if (!f.IsOpened()) - return; + fs::file f(path); + if (!f) return; - m_buffer_size = f.Length(); + m_buffer_size = f.size(); m_buffer = new u8[m_buffer_size]; - f.Read(m_buffer, m_buffer_size); - f.Close(); + f.read(m_buffer, m_buffer_size); m_arb_shader += fmt::format("Loading... [%s]\n", path.c_str()); } @@ -315,16 +312,13 @@ public: { u32 ptr; { - rFile f(m_path); + fs::file f(m_path); + if (!f) return; - if (!f.IsOpened()) - return; - - size_t size = f.Length(); + size_t size = f.size(); vm::ps3::init(); ptr = vm::alloc(size); - f.Read(vm::get_ptr(ptr), size); - f.Close(); + f.read(vm::get_ptr(ptr), size); } auto& vmprog = vm::get_ref(ptr); diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 5a47ec8a62..317613183a 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -1,7 +1,7 @@ #include "stdafx.h" #include "rpcs3/Ini.h" #include "Utilities/rPlatform.h" // only for rImage -#include "Utilities/rFile.h" +#include "Utilities/File.h" #include "Utilities/Log.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" @@ -580,10 +580,8 @@ void GLTexture::Save(RSXTexture& tex, const std::string& name) return; } - { - rFile f(name + ".raw", rFile::write); - f.Write(alldata, texPixelCount * 4); - } + fs::file(name + ".raw", o_write | o_create | o_trunc).write(alldata, texPixelCount * 4); + u8* data = new u8[texPixelCount * 3]; u8* alpha = new u8[texPixelCount]; @@ -612,10 +610,10 @@ void GLTexture::Save(RSXTexture& tex) static const std::string& dir_path = "textures"; static const std::string& file_fmt = dir_path + "/" + "tex[%d].png"; - if (!rExists(dir_path)) rMkdir(dir_path); + if (!fs::exists(dir_path)) fs::create_dir(dir_path); u32 count = 0; - while (rExists(fmt::Format(file_fmt.c_str(), count))) count++; + while (fs::exists(fmt::Format(file_fmt.c_str(), count))) count++; Save(tex, fmt::Format(file_fmt.c_str(), count)); } @@ -1136,8 +1134,7 @@ bool GLGSRender::LoadProgram() checkForGlError("m_fragment_prog.Compile"); // TODO: This shouldn't use current dir - rFile f("./FragmentProgram.txt", rFile::write); - f.Write(m_fragment_prog.shader); + fs::file("./FragmentProgram.txt", o_write | o_create | o_trunc).write(m_fragment_prog.shader.c_str(), m_fragment_prog.shader.size()); } if (m_vp_buf_num == -1) @@ -1148,8 +1145,7 @@ bool GLGSRender::LoadProgram() checkForGlError("m_vertex_prog.Compile"); // TODO: This shouldn't use current dir - rFile f("./VertexProgram.txt", rFile::write); - f.Write(m_vertex_prog.shader); + fs::file("./VertexProgram.txt", o_write | o_create | o_trunc).write(m_vertex_prog.shader.c_str(), m_vertex_prog.shader.size()); } if (m_fp_buf_num != -1 && m_vp_buf_num != -1) diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 6bc9344ca0..db7e9e5007 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -2484,18 +2484,19 @@ void RSXThread::Task() if (get_system_time() - start_time > m_vblank_count * 1000000 / 60) { m_vblank_count++; - if (m_vblank_handler) + + if (auto cb = m_vblank_handler) { - auto cb = m_vblank_handler; - Emu.GetCallbackManager().Async([cb](PPUThread& CPU) + Emu.GetCallbackManager().Async([=](PPUThread& CPU) { cb(CPU, 1); }); } - continue; } - - std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + else + { + std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack + } } }); diff --git a/rpcs3/Emu/SysCalls/CB_FUNC.h b/rpcs3/Emu/SysCalls/CB_FUNC.h index 160eab9559..92b8c13847 100644 --- a/rpcs3/Emu/SysCalls/CB_FUNC.h +++ b/rpcs3/Emu/SysCalls/CB_FUNC.h @@ -14,7 +14,7 @@ namespace cb_detail // Current implementation can handle only fixed amount of stack arguments. // This constant can be increased if necessary. // It's possible to calculate suitable stack frame size in template, but too complicated. - static const auto FIXED_STACK_FRAME_SIZE = 0x100; + static const auto FIXED_STACK_FRAME_SIZE = 0x90; template struct _func_arg; @@ -61,7 +61,7 @@ namespace cb_detail __forceinline static void set_value(PPUThread& CPU, const T& arg) { - const int stack_pos = 0x70 + (g_count - 9) * 8 - FIXED_STACK_FRAME_SIZE; + const int stack_pos = (g_count - 9) * 8 - FIXED_STACK_FRAME_SIZE; static_assert(stack_pos < 0, "TODO: Increase fixed stack frame size (arg count limit broken)"); vm::write64(CPU.GPR[1] + stack_pos, cast_to_ppu_gpr(arg)); } @@ -132,10 +132,7 @@ namespace cb_detail { __forceinline static RT call(PPUThread& CPU, u32 pc, u32 rtoc, T... args) { - const bool stack = _bind_func_args<0, 0, 0, T...>(CPU, args...); - if (stack) CPU.GPR[1] -= FIXED_STACK_FRAME_SIZE; - CPU.FastCall2(pc, rtoc); - if (stack) CPU.GPR[1] += FIXED_STACK_FRAME_SIZE; + _func_caller::call(CPU, pc, rtoc, args...); static_assert(!std::is_pointer::value, "Invalid callback result type (pointer)"); static_assert(!std::is_reference::value, "Invalid callback result type (reference)"); @@ -154,7 +151,9 @@ namespace cb_detail { const bool stack = _bind_func_args<0, 0, 0, T...>(CPU, args...); if (stack) CPU.GPR[1] -= FIXED_STACK_FRAME_SIZE; + CPU.GPR[1] -= 0x70; // create reserved area CPU.FastCall2(pc, rtoc); + CPU.GPR[1] += 0x70; if (stack) CPU.GPR[1] += FIXED_STACK_FRAME_SIZE; } }; @@ -163,14 +162,13 @@ namespace cb_detail namespace vm { template - __forceinline RT _ptr_base::operator()(CPUThread& CPU, T... args) const + __forceinline RT _ptr_base::operator()(PPUThread& CPU, T... args) const { - auto data = vm::get_ptr>(vm::cast(m_addr)); + const auto data = vm::get_ptr>(vm::cast(m_addr)); const u32 pc = data[0]; const u32 rtoc = data[1]; - assert(CPU.GetType() == CPU_THREAD_PPU); - return cb_detail::_func_caller::call(static_cast(CPU), pc, rtoc, args...); + return cb_detail::_func_caller::call(CPU, pc, rtoc, args...); } template diff --git a/rpcs3/Emu/SysCalls/FuncList.cpp b/rpcs3/Emu/SysCalls/FuncList.cpp index f6a5eae46d..b240a0d6ed 100644 --- a/rpcs3/Emu/SysCalls/FuncList.cpp +++ b/rpcs3/Emu/SysCalls/FuncList.cpp @@ -5,7 +5,7 @@ std::string SysCalls::GetFuncName(const u64 fid) { // check syscalls - switch (fid) + switch (~fid) { case 1: return "sys_process_getpid"; case 2: return "sys_process_wait_for_child"; @@ -26,7 +26,7 @@ std::string SysCalls::GetFuncName(const u64 fid) case 29: return "sys_process_get_id"; case 30: return "_sys_process_get_paramsfo"; case 31: return "sys_process_get_ppu_guid"; - case 41: return "sys_internal_ppu_thread_exit"; + case 41: return "_sys_ppu_thread_exit"; case 43: return "sys_ppu_thread_yield"; case 44: return "sys_ppu_thread_join"; case 45: return "sys_ppu_thread_detach"; @@ -36,7 +36,7 @@ std::string SysCalls::GetFuncName(const u64 fid) case 49: return "sys_ppu_thread_get_stack_information"; case 50: return "sys_ppu_thread_stop"; case 51: return "sys_ppu_thread_restart"; - case 52: return "sys_ppu_thread_create"; + case 52: return "_sys_ppu_thread_create"; case 53: return "sys_ppu_thread_start"; case 56: return "sys_ppu_thread_rename"; case 57: return "sys_ppu_thread_recover_page_fault"; @@ -4414,5 +4414,5 @@ std::string SysCalls::GetFuncName(const u64 fid) } } - return fmt::format("0x%08llX", fid); + return ~fid < 1024 ? fmt::format("syscall_%lld", ~fid) : fmt::format("0x%08llX", fid); } diff --git a/rpcs3/Emu/SysCalls/Modules.cpp b/rpcs3/Emu/SysCalls/Modules.cpp index c2cb8f2e0d..0e9f3561f9 100644 --- a/rpcs3/Emu/SysCalls/Modules.cpp +++ b/rpcs3/Emu/SysCalls/Modules.cpp @@ -106,12 +106,16 @@ void execute_ppu_func_by_index(PPUThread& CPU, u32 index) { // call LLE function if available + const auto data = vm::get_ptr>(func->lle_func.addr()); + const u32 pc = data[0]; + const u32 rtoc = data[1]; + if (Ini.HLELogging.GetValue()) { LOG_NOTICE(HLE, "LLE function called: %s", SysCalls::GetFuncName(func->id)); } - - func->lle_func(CPU); + + CPU.FastCall2(pc, rtoc); if (Ini.HLELogging.GetValue()) { diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index 49d7b51322..bc1ffe66d4 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -33,7 +33,7 @@ struct ModuleFunc { } - ModuleFunc(u32 id, u32 flags, Module* module, const char* name, ppu_func_caller func, vm::ptr lle_func = vm::ptr::make(0)) + ModuleFunc(u32 id, u32 flags, Module* module, const char* name, ppu_func_caller func, vm::ptr lle_func = vm::null) : id(id) , flags(flags) , module(module) diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp index 5cad2c2a63..bca545f960 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp @@ -226,7 +226,7 @@ u32 adecOpen(AudioDecoder* adec_ptr) adec.id = adec_id; adec.adecCb = static_cast(Emu.GetCPU().AddThread(CPU_THREAD_PPU).get()); - adec.adecCb->SetName(fmt::format("AudioDecoder[%d] Callback", adec_id)); + adec.adecCb->SetName(fmt::format("AudioDecoder[0x%x] Callback", adec_id)); adec.adecCb->SetEntry(0); adec.adecCb->SetPrio(1001); adec.adecCb->SetStackSize(0x10000); @@ -234,7 +234,7 @@ u32 adecOpen(AudioDecoder* adec_ptr) adec.adecCb->InitRegs(); adec.adecCb->DoRun(); - thread_t t(fmt::format("AudioDecoder[%d] Thread", adec_id), [adec_ptr, sptr]() + thread_t t(fmt::format("AudioDecoder[0x%x] Thread", adec_id), [adec_ptr, sptr]() { AudioDecoder& adec = *adec_ptr; AdecTask& task = adec.task; @@ -510,11 +510,14 @@ bool adecCheckType(AudioCodecType type) return true; } -int cellAdecQueryAttr(vm::ptr type, vm::ptr attr) +s32 cellAdecQueryAttr(vm::ptr type, vm::ptr attr) { - cellAdec.Warning("cellAdecQueryAttr(type_addr=0x%x, attr_addr=0x%x)", type.addr(), attr.addr()); + cellAdec.Warning("cellAdecQueryAttr(type=*0x%x, attr=*0x%x)", type, attr); - if (!adecCheckType(type->audioCodecType)) return CELL_ADEC_ERROR_ARG; + if (!adecCheckType(type->audioCodecType)) + { + return CELL_ADEC_ERROR_ARG; + } // TODO: check values attr->adecVerLower = 0x280000; // from dmux @@ -524,36 +527,46 @@ int cellAdecQueryAttr(vm::ptr type, vm::ptr attr) return CELL_OK; } -int cellAdecOpen(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle) +s32 cellAdecOpen(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle) { - cellAdec.Warning("cellAdecOpen(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)", - type.addr(), res.addr(), cb.addr(), handle.addr()); + cellAdec.Warning("cellAdecOpen(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle); - if (!adecCheckType(type->audioCodecType)) return CELL_ADEC_ERROR_ARG; + if (!adecCheckType(type->audioCodecType)) + { + return CELL_ADEC_ERROR_ARG; + } *handle = adecOpen(new AudioDecoder(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg)); return CELL_OK; } -int cellAdecOpenEx(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle) +s32 cellAdecOpenEx(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle) { - cellAdec.Warning("cellAdecOpenEx(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)", - type.addr(), res.addr(), cb.addr(), handle.addr()); + cellAdec.Warning("cellAdecOpenEx(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle); - if (!adecCheckType(type->audioCodecType)) return CELL_ADEC_ERROR_ARG; + if (!adecCheckType(type->audioCodecType)) + { + return CELL_ADEC_ERROR_ARG; + } *handle = adecOpen(new AudioDecoder(type->audioCodecType, res->startAddr, res->totalMemSize, cb->cbFunc, cb->cbArg)); return CELL_OK; } -int cellAdecClose(u32 handle) +s32 _nid_df982d2c(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle) { - cellAdec.Warning("cellAdecClose(handle=%d)", handle); + return cellAdecOpenEx(type, res, cb, handle); +} - std::shared_ptr adec; - if (!Emu.GetIdManager().GetIDData(handle, adec)) +s32 cellAdecClose(u32 handle) +{ + cellAdec.Warning("cellAdecClose(handle=0x%x)", handle); + + const auto adec = Emu.GetIdManager().GetIDData(handle); + + if (!adec) { return CELL_ADEC_ERROR_ARG; } @@ -576,12 +589,13 @@ int cellAdecClose(u32 handle) return CELL_OK; } -int cellAdecStartSeq(u32 handle, u32 param_addr) +s32 cellAdecStartSeq(u32 handle, u32 param) { - cellAdec.Warning("cellAdecStartSeq(handle=%d, param_addr=0x%x)", handle, param_addr); + cellAdec.Warning("cellAdecStartSeq(handle=0x%x, param=*0x%x)", handle, param); - std::shared_ptr adec; - if (!Emu.GetIdManager().GetIDData(handle, adec)) + const auto adec = Emu.GetIdManager().GetIDData(handle); + + if (!adec) { return CELL_ADEC_ERROR_ARG; } @@ -595,25 +609,25 @@ int cellAdecStartSeq(u32 handle, u32 param_addr) case CELL_ADEC_TYPE_ATRACX_6CH: case CELL_ADEC_TYPE_ATRACX_8CH: { - auto param = vm::ptr::make(param_addr); + const auto atx = vm::ptr::make(param); - task.at3p.sample_rate = param->sampling_freq; - task.at3p.channel_config = param->ch_config_idx; - task.at3p.channels = param->nch_out; - task.at3p.frame_size = param->nbytes; - task.at3p.extra_config = param->extra_config_data; - task.at3p.output = param->bw_pcm; - task.at3p.downmix = param->downmix_flag; - task.at3p.ats_header = param->au_includes_ats_hdr_flg; + task.at3p.sample_rate = atx->sampling_freq; + task.at3p.channel_config = atx->ch_config_idx; + task.at3p.channels = atx->nch_out; + task.at3p.frame_size = atx->nbytes; + task.at3p.extra_config = atx->extra_config_data; + task.at3p.output = atx->bw_pcm; + task.at3p.downmix = atx->downmix_flag; + task.at3p.ats_header = atx->au_includes_ats_hdr_flg; cellAdec.Todo("*** CellAdecParamAtracX: sr=%d, ch_cfg=%d(%d), frame_size=0x%x, extra=0x%x, output=%d, downmix=%d, ats_header=%d", task.at3p.sample_rate, task.at3p.channel_config, task.at3p.channels, task.at3p.frame_size, (u32&)task.at3p.extra_config, task.at3p.output, task.at3p.downmix, task.at3p.ats_header); break; } case CELL_ADEC_TYPE_MP3: { - auto param = vm::ptr::make(param_addr); + const auto mp3 = vm::ptr::make(param); - cellAdec.Todo("*** CellAdecParamMP3: bw_pcm=%d", param->bw_pcm); + cellAdec.Todo("*** CellAdecParamMP3: bw_pcm=%d", mp3->bw_pcm); break; } default: @@ -628,12 +642,13 @@ int cellAdecStartSeq(u32 handle, u32 param_addr) return CELL_OK; } -int cellAdecEndSeq(u32 handle) +s32 cellAdecEndSeq(u32 handle) { - cellAdec.Warning("cellAdecEndSeq(handle=%d)", handle); + cellAdec.Warning("cellAdecEndSeq(handle=0x%x)", handle); - std::shared_ptr adec; - if (!Emu.GetIdManager().GetIDData(handle, adec)) + const auto adec = Emu.GetIdManager().GetIDData(handle); + + if (!adec) { return CELL_ADEC_ERROR_ARG; } @@ -642,12 +657,13 @@ int cellAdecEndSeq(u32 handle) return CELL_OK; } -int cellAdecDecodeAu(u32 handle, vm::ptr auInfo) +s32 cellAdecDecodeAu(u32 handle, vm::ptr auInfo) { - cellAdec.Log("cellAdecDecodeAu(handle=%d, auInfo_addr=0x%x)", handle, auInfo.addr()); + cellAdec.Log("cellAdecDecodeAu(handle=0x%x, auInfo=*0x%x)", handle, auInfo); - std::shared_ptr adec; - if (!Emu.GetIdManager().GetIDData(handle, adec)) + const auto adec = Emu.GetIdManager().GetIDData(handle); + + if (!adec) { return CELL_ADEC_ERROR_ARG; } @@ -664,12 +680,13 @@ int cellAdecDecodeAu(u32 handle, vm::ptr auInfo) return CELL_OK; } -int cellAdecGetPcm(u32 handle, vm::ptr outBuffer) +s32 cellAdecGetPcm(u32 handle, vm::ptr outBuffer) { - cellAdec.Log("cellAdecGetPcm(handle=%d, outBuffer_addr=0x%x)", handle, outBuffer.addr()); + cellAdec.Log("cellAdecGetPcm(handle=0x%x, outBuffer=*0x%x)", handle, outBuffer); - std::shared_ptr adec; - if (!Emu.GetIdManager().GetIDData(handle, adec)) + const auto adec = Emu.GetIdManager().GetIDData(handle); + + if (!adec) { return CELL_ADEC_ERROR_ARG; } @@ -779,12 +796,13 @@ int cellAdecGetPcm(u32 handle, vm::ptr outBuffer) return CELL_OK; } -int cellAdecGetPcmItem(u32 handle, vm::ptr pcmItem_ptr) +s32 cellAdecGetPcmItem(u32 handle, vm::ptr> pcmItem) { - cellAdec.Log("cellAdecGetPcmItem(handle=%d, pcmItem_ptr_addr=0x%x)", handle, pcmItem_ptr.addr()); + cellAdec.Log("cellAdecGetPcmItem(handle=0x%x, pcmItem=**0x%x)", handle, pcmItem); - std::shared_ptr adec; - if (!Emu.GetIdManager().GetIDData(handle, adec)) + const auto adec = Emu.GetIdManager().GetIDData(handle); + + if (!adec) { return CELL_ADEC_ERROR_ARG; } @@ -798,7 +816,7 @@ int cellAdecGetPcmItem(u32 handle, vm::ptr pcmItem_ptr) AVFrame* frame = af.data; - auto pcm = vm::ptr::make(adec->memAddr + adec->memBias); + const auto pcm = vm::ptr::make(adec->memAddr + adec->memBias); adec->memBias += 512; if (adec->memBias + 512 > adec->memSize) @@ -853,7 +871,7 @@ int cellAdecGetPcmItem(u32 handle, vm::ptr pcmItem_ptr) memset(mp3.get_ptr(), 0, sizeof(CellAdecMP3Info)); } - *pcmItem_ptr = pcm.addr(); + *pcmItem = pcm; return CELL_OK; } @@ -862,6 +880,7 @@ Module cellAdec("cellAdec", []() REG_FUNC(cellAdec, cellAdecQueryAttr); REG_FUNC(cellAdec, cellAdecOpen); REG_FUNC(cellAdec, cellAdecOpenEx); + REG_UNNAMED(cellAdec, df982d2c); REG_FUNC(cellAdec, cellAdecClose); REG_FUNC(cellAdec, cellAdecStartSeq); REG_FUNC(cellAdec, cellAdecEndSeq); diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 67fd473b3a..39cf506454 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -96,10 +96,10 @@ s32 cellAudioInit() u16 buf_u16[out_buffer_size]; for (size_t i = 0; i < out_buffer_size; i += 8) { - static const __m128 float2u16 = { 0x8000, 0x8000, 0x8000, 0x8000 }; + const auto scale = _mm_set1_ps(0x8000); (__m128i&)(buf_u16[i]) = _mm_packs_epi32( - _mm_cvtps_epi32(_mm_mul_ps((__m128&)(buffer[i]), float2u16)), - _mm_cvtps_epi32(_mm_mul_ps((__m128&)(buffer[i + 4]), float2u16))); + _mm_cvtps_epi32(_mm_mul_ps(_mm_load_ps(buffer + i), scale)), + _mm_cvtps_epi32(_mm_mul_ps(_mm_load_ps(buffer + i + 4), scale))); } if (!opened) @@ -206,25 +206,17 @@ s32 cellAudioInit() auto step_volume = [](AudioPortConfig& port) // part of cellAudioSetPortLevel functionality { - if (port.level_inc) - { - port.level += port.level_inc; + const auto param = port.level_set.read_sync(); - if (port.level_inc > 0.0f) + if (param.inc != 0.0f) + { + port.level += param.inc; + const bool dec = param.inc < 0.0f; + + if ((!dec && param.value - port.level <= 0.0f) || (dec && param.value - port.level >= 0.0f)) { - if (port.level_set - port.level <= 0.0f) - { - port.level = port.level_set; - port.level_inc = 0.0f; - } - } - else - { - if (port.level_set - port.level >= 0.0f) - { - port.level = port.level_set; - port.level_inc = 0.0f; - } + port.level = param.value; + port.level_set.compare_and_swap(param, { param.value, 0.0f }); } } }; @@ -397,9 +389,9 @@ s32 cellAudioInit() for (auto key : g_audio.keys) { - if (std::shared_ptr queue = Emu.GetEventManager().GetEventQueue(key)) + if (const auto queue = Emu.GetEventManager().GetEventQueue(key)) { - queue->push(0, 0, 0, 0); // TODO: check arguments + queue->push(lv2_lock, 0, 0, 0, 0); // TODO: check arguments } } } @@ -547,8 +539,7 @@ s32 cellAudioPortOpen(vm::ptr audioParam, vm::ptr portN port.level = 1.0f; } - port.level_set = port.level; - port.level_inc = 0.0f; + port.level_set.data = { port.level, 0.0f }; *portNum = port_index; cellAudio.Warning("*** audio port opened(nChannel=%d, nBlock=%d, attr=0x%llx, level=%f): port = %d", channel, block, attr, port.level, port_index); @@ -754,10 +745,7 @@ s32 cellAudioSetPortLevel(u32 portNum, float level) if (level >= 0.0f) { - std::lock_guard lock(g_audio.mutex); - - port.level_set = level; - port.level_inc = (port.level - level) / 624.0f; + port.level_set.exchange({ level, (port.level - level) / 624.0f }); } else { diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.h b/rpcs3/Emu/SysCalls/Modules/cellAudio.h index ca165476c1..84b6bd65b4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.h +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.h @@ -108,9 +108,15 @@ struct AudioPortConfig u32 addr; u32 read_index_addr; u32 size; - float level; - float level_set; - float level_inc; + + struct level_set_t + { + float value; + float inc; + }; + + float level; + atomic_le_t level_set; }; struct AudioConfig //custom structure diff --git a/rpcs3/Emu/SysCalls/Modules/cellAvconfExt.cpp b/rpcs3/Emu/SysCalls/Modules/cellAvconfExt.cpp index 3cf9114e6a..4e51060ee0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAvconfExt.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAvconfExt.cpp @@ -6,15 +6,15 @@ extern Module cellAvconfExt; -int cellVideoOutConvertCursorColor() +s32 cellVideoOutConvertCursorColor() { UNIMPLEMENTED_FUNC(cellAvconfExt); return CELL_OK; } -int cellVideoOutGetScreenSize(u32 videoOut, vm::ptr screenSize) +s32 cellVideoOutGetScreenSize(u32 videoOut, vm::ptr screenSize) { - cellAvconfExt.Warning("cellVideoOutGetScreenSize(videoOut=%d, screenSize_addr=0x%x)", videoOut, screenSize.addr()); + cellAvconfExt.Warning("cellVideoOutGetScreenSize(videoOut=%d, screenSize=*0x%x)", videoOut, screenSize); if (videoOut != CELL_VIDEO_OUT_PRIMARY) { @@ -23,8 +23,8 @@ int cellVideoOutGetScreenSize(u32 videoOut, vm::ptr screenSize) //TODO: Use virtual screen size #ifdef _WIN32 - HDC screen = GetDC(NULL); - float diagonal = roundf(sqrtf((powf(float(GetDeviceCaps(screen, HORZSIZE)), 2) + powf(float(GetDeviceCaps(screen, VERTSIZE)), 2))) * 0.0393f); + //HDC screen = GetDC(NULL); + //float diagonal = roundf(sqrtf((powf(float(GetDeviceCaps(screen, HORZSIZE)), 2) + powf(float(GetDeviceCaps(screen, VERTSIZE)), 2))) * 0.0393f); #else // TODO: Linux implementation, without using wx // float diagonal = roundf(sqrtf((powf(wxGetDisplaySizeMM().GetWidth(), 2) + powf(wxGetDisplaySizeMM().GetHeight(), 2))) * 0.0393f); @@ -32,22 +32,20 @@ int cellVideoOutGetScreenSize(u32 videoOut, vm::ptr screenSize) if (Ini.GS3DTV.GetValue()) { -#ifdef _WIN32 - *screenSize = diagonal; -#endif + *screenSize = 24.0f; return CELL_OK; } return CELL_VIDEO_OUT_ERROR_VALUE_IS_NOT_SET; } -int cellVideoOutGetGamma() +s32 cellVideoOutGetGamma() { UNIMPLEMENTED_FUNC(cellAvconfExt); return CELL_OK; } -int cellVideoOutSetGamma() +s32 cellVideoOutSetGamma() { UNIMPLEMENTED_FUNC(cellAvconfExt); return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index 393e2cc541..0e9866667e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -284,16 +284,18 @@ void dmuxQueryAttr(u32 info_addr /* may be 0 */, vm::ptr attr) attr->memSize = 0x10000; // 0x3e8e6 from ps3 } -void dmuxQueryEsAttr(u32 info_addr /* may be 0 */, vm::ptr esFilterId, - const u32 esSpecificInfo_addr, vm::ptr attr) +void dmuxQueryEsAttr(u32 info /* may be 0 */, vm::ptr esFilterId, u32 esSpecificInfo, vm::ptr attr) { if (esFilterId->filterIdMajor >= 0xe0) + { attr->memSize = 0x500000; // 0x45fa49 from ps3 + } else + { attr->memSize = 0x7000; // 0x73d9 from ps3 + } - cellDmux.Warning("*** filter(0x%x, 0x%x, 0x%x, 0x%x)", (u32)esFilterId->filterIdMajor, (u32)esFilterId->filterIdMinor, - (u32)esFilterId->supplementalInfo1, (u32)esFilterId->supplementalInfo2); + cellDmux.Warning("*** filter(0x%x, 0x%x, 0x%x, 0x%x)", esFilterId->filterIdMajor, esFilterId->filterIdMinor, esFilterId->supplementalInfo1, esFilterId->supplementalInfo2); } u32 dmuxOpen(Demuxer* dmux_ptr) @@ -306,7 +308,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr) dmux.id = dmux_id; dmux.dmuxCb = static_cast(Emu.GetCPU().AddThread(CPU_THREAD_PPU).get()); - dmux.dmuxCb->SetName(fmt::format("Demuxer[%d] Callback", dmux_id)); + dmux.dmuxCb->SetName(fmt::format("Demuxer[0x%x] Callback", dmux_id)); dmux.dmuxCb->SetEntry(0); dmux.dmuxCb->SetPrio(1001); dmux.dmuxCb->SetStackSize(0x10000); @@ -314,7 +316,7 @@ u32 dmuxOpen(Demuxer* dmux_ptr) dmux.dmuxCb->InitRegs(); dmux.dmuxCb->DoRun(); - thread_t t(fmt::format("Demuxer[%d] Thread", dmux_id), [dmux_ptr, sptr]() + thread_t t(fmt::format("Demuxer[0x%x] Thread", dmux_id), [dmux_ptr, sptr]() { Demuxer& dmux = *dmux_ptr; @@ -774,92 +776,92 @@ u32 dmuxOpen(Demuxer* dmux_ptr) return dmux_id; } -int cellDmuxQueryAttr(vm::ptr demuxerType, vm::ptr demuxerAttr) +s32 cellDmuxQueryAttr(vm::ptr type, vm::ptr attr) { - cellDmux.Warning("cellDmuxQueryAttr(demuxerType_addr=0x%x, demuxerAttr_addr=0x%x)", demuxerType.addr(), demuxerAttr.addr()); + cellDmux.Warning("cellDmuxQueryAttr(type=*0x%x, attr=*0x%x)", type, attr); - if (demuxerType->streamType != CELL_DMUX_STREAM_TYPE_PAMF) + if (type->streamType != CELL_DMUX_STREAM_TYPE_PAMF) { return CELL_DMUX_ERROR_ARG; } - dmuxQueryAttr(0, demuxerAttr); + dmuxQueryAttr(0, attr); return CELL_OK; } -int cellDmuxQueryAttr2(vm::ptr demuxerType2, vm::ptr demuxerAttr) +s32 cellDmuxQueryAttr2(vm::ptr type2, vm::ptr attr) { - cellDmux.Warning("cellDmuxQueryAttr2(demuxerType2_addr=0x%x, demuxerAttr_addr=0x%x)", demuxerType2.addr(), demuxerAttr.addr()); + cellDmux.Warning("cellDmuxQueryAttr2(demuxerType2=*0x%x, demuxerAttr=*0x%x)", type2, attr); - if (demuxerType2->streamType != CELL_DMUX_STREAM_TYPE_PAMF) + if (type2->streamType != CELL_DMUX_STREAM_TYPE_PAMF) { return CELL_DMUX_ERROR_ARG; } - dmuxQueryAttr(demuxerType2->streamSpecificInfo_addr, demuxerAttr); + dmuxQueryAttr(type2->streamSpecificInfo, attr); return CELL_OK; } -int cellDmuxOpen(vm::ptr demuxerType, vm::ptr demuxerResource, - vm::ptr demuxerCb, vm::ptr demuxerHandle) +s32 cellDmuxOpen(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle) { - cellDmux.Warning("cellDmuxOpen(demuxerType_addr=0x%x, demuxerResource_addr=0x%x, demuxerCb_addr=0x%x, demuxerHandle_addr=0x%x)", - demuxerType.addr(), demuxerResource.addr(), demuxerCb.addr(), demuxerHandle.addr()); + cellDmux.Warning("cellDmuxOpen(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle); - if (demuxerType->streamType != CELL_DMUX_STREAM_TYPE_PAMF) + if (type->streamType != CELL_DMUX_STREAM_TYPE_PAMF) { return CELL_DMUX_ERROR_ARG; } // TODO: check demuxerResource and demuxerCb arguments - *demuxerHandle = dmuxOpen(new Demuxer(demuxerResource->memAddr, demuxerResource->memSize, demuxerCb->cbMsgFunc, demuxerCb->cbArg)); + *handle = dmuxOpen(new Demuxer(res->memAddr, res->memSize, cb->cbMsgFunc, cb->cbArg)); return CELL_OK; } -int cellDmuxOpenEx(vm::ptr demuxerType, vm::ptr demuxerResourceEx, - vm::ptr demuxerCb, vm::ptr demuxerHandle) +s32 cellDmuxOpenEx(vm::ptr type, vm::ptr resEx, vm::ptr cb, vm::ptr handle) { - cellDmux.Warning("cellDmuxOpenEx(demuxerType_addr=0x%x, demuxerResourceEx_addr=0x%x, demuxerCb_addr=0x%x, demuxerHandle_addr=0x%x)", - demuxerType.addr(), demuxerResourceEx.addr(), demuxerCb.addr(), demuxerHandle.addr()); + cellDmux.Warning("cellDmuxOpenEx(type=*0x%x, resEx=*0x%x, cb=*0x%x, handle=*0x%x)", type, resEx, cb, handle); - if (demuxerType->streamType != CELL_DMUX_STREAM_TYPE_PAMF) + if (type->streamType != CELL_DMUX_STREAM_TYPE_PAMF) { return CELL_DMUX_ERROR_ARG; } // TODO: check demuxerResourceEx and demuxerCb arguments - *demuxerHandle = dmuxOpen(new Demuxer(demuxerResourceEx->memAddr, demuxerResourceEx->memSize, demuxerCb->cbMsgFunc, demuxerCb->cbArg)); + *handle = dmuxOpen(new Demuxer(resEx->memAddr, resEx->memSize, cb->cbMsgFunc, cb->cbArg)); return CELL_OK; } -int cellDmuxOpen2(vm::ptr demuxerType2, vm::ptr demuxerResource2, - vm::ptr demuxerCb, vm::ptr demuxerHandle) +s32 _nid_e075fabc(vm::ptr type, vm::ptr resEx, vm::ptr cb, vm::ptr handle) { - cellDmux.Warning("cellDmuxOpen2(demuxerType2_addr=0x%x, demuxerResource2_addr=0x%x, demuxerCb_addr=0x%x, demuxerHandle_addr=0x%x)", - demuxerType2.addr(), demuxerResource2.addr(), demuxerCb.addr(), demuxerHandle.addr()); + return cellDmuxOpenEx(type, resEx, cb, handle); +} - if (demuxerType2->streamType != CELL_DMUX_STREAM_TYPE_PAMF) +s32 cellDmuxOpen2(vm::ptr type2, vm::ptr res2, vm::ptr cb, vm::ptr handle) +{ + cellDmux.Warning("cellDmuxOpen2(type2=*0x%x, res2=*0x%x, cb=*0x%x, handle=*0x%x)", type2, res2, cb, handle); + + if (type2->streamType != CELL_DMUX_STREAM_TYPE_PAMF) { return CELL_DMUX_ERROR_ARG; } // TODO: check demuxerType2, demuxerResource2 and demuxerCb arguments - *demuxerHandle = dmuxOpen(new Demuxer(demuxerResource2->memAddr, demuxerResource2->memSize, demuxerCb->cbMsgFunc, demuxerCb->cbArg)); + *handle = dmuxOpen(new Demuxer(res2->memAddr, res2->memSize, cb->cbMsgFunc, cb->cbArg)); return CELL_OK; } -int cellDmuxClose(u32 demuxerHandle) +s32 cellDmuxClose(u32 handle) { - cellDmux.Warning("cellDmuxClose(demuxerHandle=%d)", demuxerHandle); + cellDmux.Warning("cellDmuxClose(handle=0x%x)", handle); - std::shared_ptr dmux; - if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux)) + const auto dmux = Emu.GetIdManager().GetIDData(handle); + + if (!dmux) { return CELL_DMUX_ERROR_ARG; } @@ -871,7 +873,7 @@ int cellDmuxClose(u32 demuxerHandle) { if (Emu.IsStopped()) { - cellDmux.Warning("cellDmuxClose(%d) aborted", demuxerHandle); + cellDmux.Warning("cellDmuxClose(%d) aborted", handle); return CELL_OK; } @@ -879,17 +881,17 @@ int cellDmuxClose(u32 demuxerHandle) } if (dmux->dmuxCb) Emu.GetCPU().RemoveThread(dmux->dmuxCb->GetId()); - Emu.GetIdManager().RemoveID(demuxerHandle); + Emu.GetIdManager().RemoveID(handle); return CELL_OK; } -int cellDmuxSetStream(u32 demuxerHandle, const u32 streamAddress, u32 streamSize, bool discontinuity, u64 userData) +s32 cellDmuxSetStream(u32 handle, u32 streamAddress, u32 streamSize, bool discontinuity, u64 userData) { - cellDmux.Log("cellDmuxSetStream(demuxerHandle=%d, streamAddress=0x%x, streamSize=%d, discontinuity=%d, userData=0x%llx", - demuxerHandle, streamAddress, streamSize, discontinuity, userData); + cellDmux.Log("cellDmuxSetStream(handle=0x%x, streamAddress=0x%x, streamSize=%d, discontinuity=%d, userData=0x%llx)", handle, streamAddress, streamSize, discontinuity, userData); - std::shared_ptr dmux; - if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux)) + const auto dmux = Emu.GetIdManager().GetIDData(handle); + + if (!dmux) { return CELL_DMUX_ERROR_ARG; } @@ -911,12 +913,13 @@ int cellDmuxSetStream(u32 demuxerHandle, const u32 streamAddress, u32 streamSize return CELL_OK; } -int cellDmuxResetStream(u32 demuxerHandle) +s32 cellDmuxResetStream(u32 handle) { - cellDmux.Warning("cellDmuxResetStream(demuxerHandle=%d)", demuxerHandle); + cellDmux.Warning("cellDmuxResetStream(handle=0x%x)", handle); - std::shared_ptr dmux; - if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux)) + const auto dmux = Emu.GetIdManager().GetIDData(handle); + + if (!dmux) { return CELL_DMUX_ERROR_ARG; } @@ -925,12 +928,13 @@ int cellDmuxResetStream(u32 demuxerHandle) return CELL_OK; } -int cellDmuxResetStreamAndWaitDone(u32 demuxerHandle) +s32 cellDmuxResetStreamAndWaitDone(u32 handle) { - cellDmux.Warning("cellDmuxResetStreamAndWaitDone(demuxerHandle=%d)", demuxerHandle); + cellDmux.Warning("cellDmuxResetStreamAndWaitDone(handle=0x%x)", handle); - std::shared_ptr dmux; - if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux)) + const auto dmux = Emu.GetIdManager().GetIDData(handle); + + if (!dmux) { return CELL_DMUX_ERROR_ARG; } @@ -948,7 +952,7 @@ int cellDmuxResetStreamAndWaitDone(u32 demuxerHandle) { if (Emu.IsStopped()) { - cellDmux.Warning("cellDmuxResetStreamAndWaitDone(%d) aborted", demuxerHandle); + cellDmux.Warning("cellDmuxResetStreamAndWaitDone(%d) aborted", handle); return CELL_OK; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack @@ -957,48 +961,41 @@ int cellDmuxResetStreamAndWaitDone(u32 demuxerHandle) return CELL_OK; } -int cellDmuxQueryEsAttr(vm::ptr demuxerType, vm::ptr esFilterId, - const u32 esSpecificInfo_addr, vm::ptr esAttr) +s32 cellDmuxQueryEsAttr(vm::ptr type, vm::ptr esFilterId, u32 esSpecificInfo, vm::ptr esAttr) { - cellDmux.Warning("cellDmuxQueryEsAttr(demuxerType_addr=0x%x, esFilterId_addr=0x%x, esSpecificInfo_addr=0x%x, esAttr_addr=0x%x)", - demuxerType.addr(), esFilterId.addr(), esSpecificInfo_addr, esAttr.addr()); + cellDmux.Warning("cellDmuxQueryEsAttr(demuxerType=*0x%x, esFilterId=*0x%x, esSpecificInfo=*0x%x, esAttr=*0x%x)", type, esFilterId, esSpecificInfo, esAttr); - if (demuxerType->streamType != CELL_DMUX_STREAM_TYPE_PAMF) + if (type->streamType != CELL_DMUX_STREAM_TYPE_PAMF) { return CELL_DMUX_ERROR_ARG; } // TODO: check esFilterId and esSpecificInfo correctly - dmuxQueryEsAttr(0, esFilterId, esSpecificInfo_addr, esAttr); + dmuxQueryEsAttr(0, esFilterId, esSpecificInfo, esAttr); return CELL_OK; } -int cellDmuxQueryEsAttr2(vm::ptr demuxerType2, vm::ptr esFilterId, - const u32 esSpecificInfo_addr, vm::ptr esAttr) +s32 cellDmuxQueryEsAttr2(vm::ptr type2, vm::ptr esFilterId, u32 esSpecificInfo, vm::ptr esAttr) { - cellDmux.Warning("cellDmuxQueryEsAttr2(demuxerType2_addr=0x%x, esFilterId_addr=0x%x, esSpecificInfo_addr=0x%x, esAttr_addr=0x%x)", - demuxerType2.addr(), esFilterId.addr(), esSpecificInfo_addr, esAttr.addr()); + cellDmux.Warning("cellDmuxQueryEsAttr2(type2=*0x%x, esFilterId=*0x%x, esSpecificInfo=*0x%x, esAttr=*0x%x)", type2, esFilterId, esSpecificInfo, esAttr); - if (demuxerType2->streamType != CELL_DMUX_STREAM_TYPE_PAMF) + if (type2->streamType != CELL_DMUX_STREAM_TYPE_PAMF) { return CELL_DMUX_ERROR_ARG; } // TODO: check demuxerType2, esFilterId and esSpecificInfo correctly - dmuxQueryEsAttr(demuxerType2->streamSpecificInfo_addr, esFilterId, esSpecificInfo_addr, esAttr); + dmuxQueryEsAttr(type2->streamSpecificInfo, esFilterId, esSpecificInfo, esAttr); return CELL_OK; } -int cellDmuxEnableEs(u32 demuxerHandle, vm::ptr esFilterId, - vm::ptr esResourceInfo, vm::ptr esCb, - const u32 esSpecificInfo_addr, vm::ptr esHandle) +s32 cellDmuxEnableEs(u32 handle, vm::ptr esFilterId, vm::ptr esResourceInfo, vm::ptr esCb, u32 esSpecificInfo, vm::ptr esHandle) { - cellDmux.Warning("cellDmuxEnableEs(demuxerHandle=%d, esFilterId_addr=0x%x, esResourceInfo_addr=0x%x, esCb_addr=0x%x, " - "esSpecificInfo_addr=0x%x, esHandle_addr=0x%x)", demuxerHandle, esFilterId.addr(), esResourceInfo.addr(), - esCb.addr(), esSpecificInfo_addr, esHandle.addr()); + cellDmux.Warning("cellDmuxEnableEs(handle=0x%x, esFilterId=*0x%x, esResourceInfo=*0x%x, esCb=*0x%x, esSpecificInfo=*0x%x, esHandle=*0x%x)", handle, esFilterId, esResourceInfo, esCb, esSpecificInfo, esHandle); - std::shared_ptr dmux; - if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux)) + const auto dmux = Emu.GetIdManager().GetIDData(handle); + + if (!dmux) { return CELL_DMUX_ERROR_ARG; } @@ -1007,14 +1004,14 @@ int cellDmuxEnableEs(u32 demuxerHandle, vm::ptr esFil std::shared_ptr es(new ElementaryStream(dmux.get(), esResourceInfo->memAddr, esResourceInfo->memSize, esFilterId->filterIdMajor, esFilterId->filterIdMinor, esFilterId->supplementalInfo1, esFilterId->supplementalInfo2, - esCb->cbEsMsgFunc, esCb->cbArg, esSpecificInfo_addr)); + esCb->cbEsMsgFunc, esCb->cbArg, esSpecificInfo)); u32 id = Emu.GetIdManager().GetNewID(es); es->id = id; *esHandle = id; - cellDmux.Warning("*** New ES(dmux=%d, addr=0x%x, size=0x%x, filter(0x%x, 0x%x, 0x%x, 0x%x), cb=0x%x(arg=0x%x), spec=0x%x): id = %d", - demuxerHandle, es->memAddr, es->memSize, es->fidMajor, es->fidMinor, es->sup1, es->sup2, es->cbFunc, es->cbArg, es->spec, id); + cellDmux.Warning("*** New ES(dmux=0x%x, addr=0x%x, size=0x%x, filter={0x%x, 0x%x, 0x%x, 0x%x}, cb=0x%x, arg=0x%x, spec=0x%x): id = %d", + handle, es->memAddr, es->memSize, es->fidMajor, es->fidMinor, es->sup1, es->sup2, es->cbFunc, es->cbArg, es->spec, id); DemuxerTask task(dmuxEnableEs); task.es.es = id; @@ -1024,12 +1021,13 @@ int cellDmuxEnableEs(u32 demuxerHandle, vm::ptr esFil return CELL_OK; } -int cellDmuxDisableEs(u32 esHandle) +s32 cellDmuxDisableEs(u32 esHandle) { cellDmux.Warning("cellDmuxDisableEs(esHandle=0x%x)", esHandle); - std::shared_ptr es; - if (!Emu.GetIdManager().GetIDData(esHandle, es)) + const auto es = Emu.GetIdManager().GetIDData(esHandle); + + if (!es) { return CELL_DMUX_ERROR_ARG; } @@ -1042,12 +1040,13 @@ int cellDmuxDisableEs(u32 esHandle) return CELL_OK; } -int cellDmuxResetEs(u32 esHandle) +s32 cellDmuxResetEs(u32 esHandle) { cellDmux.Log("cellDmuxResetEs(esHandle=0x%x)", esHandle); - std::shared_ptr es; - if (!Emu.GetIdManager().GetIDData(esHandle, es)) + const auto es = Emu.GetIdManager().GetIDData(esHandle); + + if (!es) { return CELL_DMUX_ERROR_ARG; } @@ -1060,13 +1059,13 @@ int cellDmuxResetEs(u32 esHandle) return CELL_OK; } -int cellDmuxGetAu(u32 esHandle, vm::ptr auInfo_ptr, vm::ptr auSpecificInfo_ptr) +s32 cellDmuxGetAu(u32 esHandle, vm::ptr auInfo, vm::ptr auSpecificInfo) { - cellDmux.Log("cellDmuxGetAu(esHandle=0x%x, auInfo_ptr_addr=0x%x, auSpecificInfo_ptr_addr=0x%x)", - esHandle, auInfo_ptr.addr(), auSpecificInfo_ptr.addr()); + cellDmux.Log("cellDmuxGetAu(esHandle=0x%x, auInfo=**0x%x, auSpecificInfo=**0x%x)", esHandle, auInfo, auSpecificInfo); - std::shared_ptr es; - if (!Emu.GetIdManager().GetIDData(esHandle, es)) + const auto es = Emu.GetIdManager().GetIDData(esHandle); + + if (!es) { return CELL_DMUX_ERROR_ARG; } @@ -1078,18 +1077,18 @@ int cellDmuxGetAu(u32 esHandle, vm::ptr auInfo_ptr, vm::ptr auSpecific return CELL_DMUX_ERROR_EMPTY; } - *auInfo_ptr = info; - *auSpecificInfo_ptr = spec; + *auInfo = info; + *auSpecificInfo = spec; return CELL_OK; } -int cellDmuxPeekAu(u32 esHandle, vm::ptr auInfo_ptr, vm::ptr auSpecificInfo_ptr) +s32 cellDmuxPeekAu(u32 esHandle, vm::ptr auInfo, vm::ptr auSpecificInfo) { - cellDmux.Log("cellDmuxPeekAu(esHandle=0x%x, auInfo_ptr_addr=0x%x, auSpecificInfo_ptr_addr=0x%x)", - esHandle, auInfo_ptr.addr(), auSpecificInfo_ptr.addr()); + cellDmux.Log("cellDmuxPeekAu(esHandle=0x%x, auInfo=**0x%x, auSpecificInfo=**0x%x)", esHandle, auInfo, auSpecificInfo); - std::shared_ptr es; - if (!Emu.GetIdManager().GetIDData(esHandle, es)) + const auto es = Emu.GetIdManager().GetIDData(esHandle); + + if (!es) { return CELL_DMUX_ERROR_ARG; } @@ -1101,18 +1100,18 @@ int cellDmuxPeekAu(u32 esHandle, vm::ptr auInfo_ptr, vm::ptr auSpecifi return CELL_DMUX_ERROR_EMPTY; } - *auInfo_ptr = info; - *auSpecificInfo_ptr = spec; + *auInfo = info; + *auSpecificInfo = spec; return CELL_OK; } -int cellDmuxGetAuEx(u32 esHandle, vm::ptr auInfoEx_ptr, vm::ptr auSpecificInfo_ptr) +s32 cellDmuxGetAuEx(u32 esHandle, vm::ptr auInfoEx, vm::ptr auSpecificInfo) { - cellDmux.Log("cellDmuxGetAuEx(esHandle=0x%x, auInfoEx_ptr_addr=0x%x, auSpecificInfo_ptr_addr=0x%x)", - esHandle, auInfoEx_ptr.addr(), auSpecificInfo_ptr.addr()); + cellDmux.Log("cellDmuxGetAuEx(esHandle=0x%x, auInfoEx=**0x%x, auSpecificInfo=**0x%x)", esHandle, auInfoEx, auSpecificInfo); - std::shared_ptr es; - if (!Emu.GetIdManager().GetIDData(esHandle, es)) + const auto es = Emu.GetIdManager().GetIDData(esHandle); + + if (!es) { return CELL_DMUX_ERROR_ARG; } @@ -1124,18 +1123,18 @@ int cellDmuxGetAuEx(u32 esHandle, vm::ptr auInfoEx_ptr, vm::ptr auSpec return CELL_DMUX_ERROR_EMPTY; } - *auInfoEx_ptr = info; - *auSpecificInfo_ptr = spec; + *auInfoEx = info; + *auSpecificInfo = spec; return CELL_OK; } -int cellDmuxPeekAuEx(u32 esHandle, vm::ptr auInfoEx_ptr, vm::ptr auSpecificInfo_ptr) +s32 cellDmuxPeekAuEx(u32 esHandle, vm::ptr auInfoEx, vm::ptr auSpecificInfo) { - cellDmux.Log("cellDmuxPeekAuEx(esHandle=0x%x, auInfoEx_ptr_addr=0x%x, auSpecificInfo_ptr_addr=0x%x)", - esHandle, auInfoEx_ptr.addr(), auSpecificInfo_ptr.addr()); + cellDmux.Log("cellDmuxPeekAuEx(esHandle=0x%x, auInfoEx=**0x%x, auSpecificInfo=**0x%x)", esHandle, auInfoEx, auSpecificInfo); - std::shared_ptr es; - if (!Emu.GetIdManager().GetIDData(esHandle, es)) + const auto es = Emu.GetIdManager().GetIDData(esHandle); + + if (!es) { return CELL_DMUX_ERROR_ARG; } @@ -1147,17 +1146,18 @@ int cellDmuxPeekAuEx(u32 esHandle, vm::ptr auInfoEx_ptr, vm::ptr auSpe return CELL_DMUX_ERROR_EMPTY; } - *auInfoEx_ptr = info; - *auSpecificInfo_ptr = spec; + *auInfoEx = info; + *auSpecificInfo = spec; return CELL_OK; } -int cellDmuxReleaseAu(u32 esHandle) +s32 cellDmuxReleaseAu(u32 esHandle) { cellDmux.Log("cellDmuxReleaseAu(esHandle=0x%x)", esHandle); - std::shared_ptr es; - if (!Emu.GetIdManager().GetIDData(esHandle, es)) + const auto es = Emu.GetIdManager().GetIDData(esHandle); + + if (!es) { return CELL_DMUX_ERROR_ARG; } @@ -1169,12 +1169,13 @@ int cellDmuxReleaseAu(u32 esHandle) return CELL_OK; } -int cellDmuxFlushEs(u32 esHandle) +s32 cellDmuxFlushEs(u32 esHandle) { cellDmux.Warning("cellDmuxFlushEs(esHandle=0x%x)", esHandle); - std::shared_ptr es; - if (!Emu.GetIdManager().GetIDData(esHandle, es)) + const auto es = Emu.GetIdManager().GetIDData(esHandle); + + if (!es) { return CELL_DMUX_ERROR_ARG; } @@ -1193,6 +1194,7 @@ Module cellDmux("cellDmux", []() REG_FUNC(cellDmux, cellDmuxQueryAttr2); REG_FUNC(cellDmux, cellDmuxOpen); REG_FUNC(cellDmux, cellDmuxOpenEx); + REG_UNNAMED(cellDmux, e075fabc); REG_FUNC(cellDmux, cellDmuxOpen2); REG_FUNC(cellDmux, cellDmuxClose); REG_FUNC(cellDmux, cellDmuxSetStream); diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.h b/rpcs3/Emu/SysCalls/Modules/cellDmux.h index 5456db607f..69ca3645d0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.h +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.h @@ -169,7 +169,7 @@ struct CellDmuxPamfSpecificInfo struct CellDmuxType2 { be_t streamType; - be_t streamSpecificInfo_addr; + be_t streamSpecificInfo; }; struct CellDmuxResource diff --git a/rpcs3/Emu/SysCalls/Modules/cellFiber.cpp b/rpcs3/Emu/SysCalls/Modules/cellFiber.cpp index 632f4b56aa..5b51c39312 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFiber.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFiber.cpp @@ -84,7 +84,7 @@ vm::ptr cellFiberPpuSelf() cellFiber.Log("cellFiberPpuSelf() -> nullptr"); // TODO // returns fiber structure (zero for simple PPU thread) - return vm::ptr::make(0); + return vm::null; } int cellFiberPpuSendSignal() diff --git a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp index d24a129d62..1c628b03d6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellFs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellFs.cpp @@ -210,38 +210,42 @@ s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr entries, u32 { cellFs.Warning("cellFsGetDirectoryEntries(fd=0x%x, entries=*0x%x, entries_size=0x%x, data_count=*0x%x)", fd, entries, entries_size, data_count); - std::shared_ptr directory; + const auto directory = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, directory)) + if (!directory) { return CELL_FS_EBADF; } - const DirEntryInfo* info = directory->Read(); - if (info) - { - entries->attribute.mode = - CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR | - CELL_FS_S_IRGRP | CELL_FS_S_IWGRP | CELL_FS_S_IXGRP | - CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH; + u32 count = 0; - entries->attribute.uid = 0; - entries->attribute.gid = 0; - entries->attribute.atime = 0; //TODO - entries->attribute.mtime = 0; //TODO - entries->attribute.ctime = 0; //TODO - entries->attribute.blksize = 4096; + entries_size /= sizeof(CellFsDirectoryEntry); - entries->entry_name.d_type = (info->flags & DirEntry_TypeFile) ? CELL_FS_TYPE_REGULAR : CELL_FS_TYPE_DIRECTORY; - entries->entry_name.d_namlen = u8(std::min(info->name.length(), CELL_FS_MAX_FS_FILE_NAME_LENGTH)); - strcpy_trunc(entries->entry_name.d_name, info->name); - *data_count = 1; - } - else + for (; count < entries_size; count++) { - *data_count = 0; + if (const auto info = directory->Read()) + { + entries[count].attribute.mode = info->flags & DirEntry_TypeDir ? CELL_FS_S_IFDIR | 0777 : CELL_FS_S_IFREG | 0666; + entries[count].attribute.uid = 1; // ??? + entries[count].attribute.gid = 1; // ??? + entries[count].attribute.atime = info->access_time; + entries[count].attribute.mtime = info->modify_time; + entries[count].attribute.ctime = info->create_time; + entries[count].attribute.size = info->size; + entries[count].attribute.blksize = 4096; // ??? + + entries[count].entry_name.d_type = info->flags & DirEntry_TypeFile ? CELL_FS_TYPE_REGULAR : CELL_FS_TYPE_DIRECTORY; + entries[count].entry_name.d_namlen = u8(std::min(info->name.length(), CELL_FS_MAX_FS_FILE_NAME_LENGTH)); + strcpy_trunc(entries[count].entry_name.d_name, info->name); + } + else + { + break; + } } + *data_count = count; + return CELL_OK; } @@ -251,9 +255,9 @@ s32 cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 buffer_size, // TODO: use single sys_fs_fcntl syscall - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file) || file->flags & CELL_FS_O_WRONLY) + if (!file || file->flags & CELL_FS_O_WRONLY) { return CELL_FS_EBADF; } @@ -282,9 +286,9 @@ s32 cellFsWriteWithOffset(u32 fd, u64 offset, vm::ptr buf, u64 data_ // TODO: use single sys_fs_fcntl syscall - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file) || !(file->flags & CELL_FS_O_ACCMODE)) + if (!file || !(file->flags & CELL_FS_O_ACCMODE)) { return CELL_FS_EBADF; } @@ -326,9 +330,9 @@ s32 cellFsStReadInit(u32 fd, vm::ptr ringbuf) return CELL_FS_EINVAL; } - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; } @@ -364,9 +368,9 @@ s32 cellFsStReadFinish(u32 fd) { cellFs.Warning("cellFsStReadFinish(fd=0x%x)", fd); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; // ??? } @@ -387,9 +391,9 @@ s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr ringbuf) { cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, ringbuf=*0x%x)", fd, ringbuf); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; } @@ -411,9 +415,9 @@ s32 cellFsStReadGetStatus(u32 fd, vm::ptr status) { cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, status=*0x%x)", fd, status); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; } @@ -445,9 +449,9 @@ s32 cellFsStReadGetRegid(u32 fd, vm::ptr regid) { cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, regid=*0x%x)", fd, regid); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; } @@ -466,9 +470,9 @@ s32 cellFsStReadStart(u32 fd, u64 offset, u64 size) { cellFs.Warning("cellFsStReadStart(fd=0x%x, offset=0x%llx, size=0x%llx)", fd, offset, size); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; } @@ -548,9 +552,9 @@ s32 cellFsStReadStop(u32 fd) { cellFs.Warning("cellFsStReadStop(fd=0x%x)", fd); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; } @@ -579,9 +583,9 @@ s32 cellFsStRead(u32 fd, vm::ptr buf, u64 size, vm::ptr rsize) { cellFs.Warning("cellFsStRead(fd=0x%x, buf=*0x%x, size=0x%llx, rsize=*0x%x)", fd, buf, size, rsize); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; } @@ -613,9 +617,9 @@ s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr addr, vm::ptr size) { cellFs.Warning("cellFsStReadGetCurrentAddr(fd=0x%x, addr=*0x%x, size=*0x%x)", fd, addr, size); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; } @@ -646,9 +650,9 @@ s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr addr, u64 size) { cellFs.Warning("cellFsStReadPutCurrentAddr(fd=0x%x, addr=*0x%x, size=0x%llx)", fd, addr, size); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; } @@ -673,9 +677,9 @@ s32 cellFsStReadWait(u32 fd, u64 size) { cellFs.Warning("cellFsStReadWait(fd=0x%x, size=0x%llx)", fd, size); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; } @@ -707,9 +711,9 @@ s32 cellFsStReadWaitCallback(u32 fd, u64 size, fs_st_cb_t func) { cellFs.Warning("cellFsStReadWaitCallback(fd=0x%x, size=0x%llx, func=*0x%x)", fd, size, func); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; } @@ -756,17 +760,17 @@ bool sdata_check(u32 version, u32 flags, u64 filesizeInput, u64 filesizeTmp) int sdata_unpack(const std::string& packed_file, const std::string& unpacked_file) { std::shared_ptr packed_stream(Emu.GetVFS().OpenFile(packed_file, vfsRead)); - std::shared_ptr unpacked_stream(Emu.GetVFS().OpenFile(unpacked_file, vfsWrite)); + std::shared_ptr unpacked_stream(Emu.GetVFS().OpenFile(unpacked_file, vfsWriteNew)); if (!packed_stream || !packed_stream->IsOpened()) { - cellFs.Error("'%s' not found! flags: 0x%02x", packed_file.c_str(), vfsRead); + cellFs.Error("File '%s' not found!", packed_file.c_str()); return CELL_ENOENT; } if (!unpacked_stream || !unpacked_stream->IsOpened()) { - cellFs.Error("'%s' couldn't be created! flags: 0x%02x", unpacked_file.c_str(), vfsWrite); + cellFs.Error("File '%s' couldn't be created!", unpacked_file.c_str()); return CELL_ENOENT; } @@ -875,9 +879,9 @@ void fsAio(vm::ptr aio, bool write, s32 xid, fs_aio_cb_t func) s32 error = CELL_OK; u64 result = 0; - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(aio->fd); - if (!Emu.GetIdManager().GetIDData(aio->fd, file) || (!write && file->flags & CELL_FS_O_WRONLY) || (write && !(file->flags & CELL_FS_O_ACCMODE))) + if (!file || (!write && file->flags & CELL_FS_O_WRONLY) || (write && !(file->flags & CELL_FS_O_ACCMODE))) { error = CELL_FS_EBADF; } @@ -970,20 +974,20 @@ s32 cellFsAioCancel(s32 id) s32 cellFsSetDefaultContainer(u32 id, u32 total_limit) { - cellFs.Todo("cellFsSetDefaultContainer(id=%d, total_limit=%d)", id, total_limit); + cellFs.Todo("cellFsSetDefaultContainer(id=0x%x, total_limit=%d)", id, total_limit); return CELL_OK; } s32 cellFsSetIoBufferFromDefaultContainer(u32 fd, u32 buffer_size, u32 page_type) { - cellFs.Todo("cellFsSetIoBufferFromDefaultContainer(fd=%d, buffer_size=%d, page_type=%d)", fd, buffer_size, page_type); + cellFs.Todo("cellFsSetIoBufferFromDefaultContainer(fd=0x%x, buffer_size=%d, page_type=%d)", fd, buffer_size, page_type); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { - CELL_FS_EBADF; + return CELL_FS_EBADF; } return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp index 76531de0cc..bf67d13c96 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.cpp @@ -8,18 +8,91 @@ #include "Emu/FS/VFS.h" #include "Emu/FS/vfsFile.h" #include "Loader/PSF.h" +#include "cellSysutil.h" #include "cellGame.h" extern Module cellGame; -std::string contentInfo = ""; -std::string usrdir = ""; +std::string contentInfo; +std::string usrdir; bool path_set = false; -int cellGameBootCheck(vm::ptr type, vm::ptr attributes, vm::ptr size, vm::ptr dirName) +s32 cellHddGameCheck(PPUThread& CPU, u32 version, vm::ptr dirName, u32 errDialog, vm::ptr funcStat, u32 container) { - cellGame.Warning("cellGameBootCheck(type_addr=0x%x, attributes_addr=0x%x, size_addr=0x%x, dirName_addr=0x%x)", - type.addr(), attributes.addr(), size.addr(), dirName.addr()); + cellGame.Warning("cellHddGameCheck(version=%d, dirName=*0x%x, errDialog=%d, funcStat=*0x%x, container=%d)", version, dirName, errDialog, funcStat, container); + + std::string dir = dirName.get_ptr(); + + if (dir.size() != 9) + { + return CELL_HDDGAME_ERROR_PARAM; + } + + vm::var param; + vm::var result; + vm::var get; + vm::var set; + + get->hddFreeSizeKB = 40 * 1024 * 1024; // 40 GB, TODO: Use the free space of the computer's HDD where RPCS3 is being run. + get->isNewData = CELL_HDDGAME_ISNEWDATA_EXIST; + get->sysSizeKB = 0; // TODO + get->atime = 0; // TODO + get->ctime = 0; // TODO + get->mtime = 0; // TODO + get->sizeKB = CELL_HDDGAME_SIZEKB_NOTCALC; + strcpy_trunc(get->contentInfoPath, "/dev_hdd0/game/" + dir); + strcpy_trunc(get->hddGamePath, "/dev_hdd0/game/" + dir + "/USRDIR"); + + if (!Emu.GetVFS().ExistsDir("/dev_hdd0/game/" + dir)) + { + get->isNewData = CELL_HDDGAME_ISNEWDATA_NODIR; + } + else + { + // TODO: Is cellHddGameCheck really responsible for writing the information in get->getParam ? (If not, delete this else) + vfsFile f("/dev_hdd0/game/" + dir + "/PARAM.SFO"); + const PSFLoader psf(f); + if (!psf) + { + return CELL_HDDGAME_ERROR_BROKEN; + } + + get->getParam.parentalLevel = psf.GetInteger("PARENTAL_LEVEL"); + get->getParam.attribute = psf.GetInteger("ATTRIBUTE"); + get->getParam.resolution = psf.GetInteger("RESOLUTION"); + get->getParam.soundFormat = psf.GetInteger("SOUND_FORMAT"); + std::string title = psf.GetString("TITLE"); + strcpy_trunc(get->getParam.title, title); + std::string app_ver = psf.GetString("APP_VER"); + strcpy_trunc(get->getParam.dataVersion, app_ver); + strcpy_trunc(get->getParam.titleId, dir); + + for (u32 i = 0; i < CELL_HDDGAME_SYSP_LANGUAGE_NUM; i++) + { + char key[16]; + sprintf(key, "TITLE_%02d", i); + title = psf.GetString(key); + strcpy_trunc(get->getParam.titleLang[i], title); + } + } + + // TODO ? + + //funcStat(result, get, set); + + //if (result->result != CELL_HDDGAME_CBRESULT_OK && result->result != CELL_HDDGAME_CBRESULT_OK_CANCEL) + //{ + // return CELL_HDDGAME_ERROR_CBRESULT; + //} + + // TODO ? + + return CELL_OK; +} + +s32 cellGameBootCheck(vm::ptr type, vm::ptr attributes, vm::ptr size, vm::ptr dirName) +{ + cellGame.Warning("cellGameBootCheck(type=*0x%x, attributes=*0x%x, size=*0x%x, dirName=*0x%x)", type, attributes, size, dirName); if (size) { @@ -32,14 +105,8 @@ int cellGameBootCheck(vm::ptr type, vm::ptr attributes, vm::ptr type, vm::ptr attributes, vm::ptr size, u32 reserved_addr) +s32 cellGamePatchCheck(vm::ptr size, vm::ptr reserved) { - cellGame.Warning("cellGamePatchCheck(size_addr=0x%x, reserved_addr=0x%x)", size.addr(), reserved_addr); - - if (reserved_addr != 0) - { - cellGame.Error("cellGamePatchCheck(): CELL_GAME_ERROR_PARAM"); - return CELL_GAME_ERROR_PARAM; - } + cellGame.Warning("cellGamePatchCheck(size=*0x%x, reserved=*0x%x)", size, reserved); if (size) { @@ -105,14 +166,8 @@ int cellGamePatchCheck(vm::ptr size, u32 reserved_addr) } vfsFile f("/app_home/../PARAM.SFO"); - if (!f.IsOpened()) - { - cellGame.Error("cellGamePatchCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot open PARAM.SFO)"); - return CELL_GAME_ERROR_ACCESS_ERROR; - } - - PSFLoader psf(f); - if (!psf.Load(false)) + const PSFLoader psf(f); + if (!psf) { cellGame.Error("cellGamePatchCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot read PARAM.SFO)"); return CELL_GAME_ERROR_ACCESS_ERROR; @@ -133,9 +188,9 @@ int cellGamePatchCheck(vm::ptr size, u32 reserved_addr) return CELL_GAME_RET_OK; } -int cellGameDataCheck(u32 type, vm::ptr dirName, vm::ptr size) +s32 cellGameDataCheck(u32 type, vm::ptr dirName, vm::ptr size) { - cellGame.Warning("cellGameDataCheck(type=0x%x, dirName_addr=0x%x, size_addr=0x%x)", type, dirName.addr(), size.addr()); + cellGame.Warning("cellGameDataCheck(type=%d, dirName=*0x%x, size=*0x%x)", type, dirName, size); if ((type - 1) >= 3) { @@ -191,21 +246,33 @@ int cellGameDataCheck(u32 type, vm::ptr dirName, vm::ptr contentInfoPath, vm::ptr usrdirPath) +s32 cellGameContentPermit(vm::ptr contentInfoPath, vm::ptr usrdirPath) { - cellGame.Warning("cellGameContentPermit(contentInfoPath_addr=0x%x, usrdirPath_addr=0x%x)", - contentInfoPath.addr(), usrdirPath.addr()); + cellGame.Warning("cellGameContentPermit(contentInfoPath=*0x%x, usrdirPath=*0x%x)", contentInfoPath, usrdirPath); - if (!contentInfoPath || !usrdirPath) + if (!contentInfoPath && !usrdirPath) { return CELL_GAME_ERROR_PARAM; } + + cellGame.Warning("cellGameContentPermit(): path_set=%d, contentInfo='%s', usrdir='%s'", path_set, contentInfo, usrdir); if (!path_set) { return CELL_GAME_ERROR_FAILURE; } + if (contentInfo.size() == 9 && usrdir.empty()) + { + if (Emu.GetVFS().RenameDir("/dev_hdd0/game/TMP_" + contentInfo, "/dev_hdd0/game/" + contentInfo)) + { + cellGame.Success("cellGameContentPermit(): gamedata directory created ('/dev_hdd0/game/%s')", contentInfo); + } + + contentInfo = "/dev_hdd0/game/" + contentInfo; + usrdir = contentInfo + "/USRDIR"; + } + strcpy_trunc(*contentInfoPath, contentInfo); strcpy_trunc(*usrdirPath, usrdir); @@ -216,15 +283,13 @@ int cellGameContentPermit(vm::ptr contentInfoPath, vm: return CELL_GAME_RET_OK; } -int cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr dirName, u32 errDialog, - vm::ptr cbResult, vm::ptr get, vm::ptr set)> funcStat, u32 container) +s32 cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr dirName, u32 errDialog, vm::ptr funcStat, u32 container) { - cellGame.Warning("cellGameDataCheckCreate(2)(version=0x%x, dirName_addr=0x%x, errDialog=0x%x, funcStat_addr=0x%x, container=%d)", - version, dirName.addr(), errDialog, funcStat.addr(), container); + cellGame.Warning("cellGameDataCheckCreate2(version=0x%x, dirName=*0x%x, errDialog=0x%x, funcStat=*0x%x, container=%d)", version, dirName, errDialog, funcStat, container); if (version != CELL_GAMEDATA_VERSION_CURRENT || errDialog > 1) { - cellGame.Error("cellGameDataCheckCreate(2)(): CELL_GAMEDATA_ERROR_PARAM"); + cellGame.Error("cellGameDataCheckCreate2(): CELL_GAMEDATA_ERROR_PARAM"); return CELL_GAMEDATA_ERROR_PARAM; } @@ -234,22 +299,16 @@ int cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr di if (!Emu.GetVFS().ExistsDir(dir)) { - cellGame.Todo("cellGameDataCheckCreate(2)(): creating directory '%s'", dir.c_str()); + cellGame.Todo("cellGameDataCheckCreate2(): creating directory '%s'", dir.c_str()); // TODO: create data return CELL_GAMEDATA_RET_OK; } - vfsFile f(dir + "/PARAM.SFO"); - if (!f.IsOpened()) + vfsFile f("/app_home/../PARAM.SFO"); + const PSFLoader psf(f); + if (!psf) { - cellGame.Error("cellGameDataCheckCreate(2)(): CELL_GAMEDATA_ERROR_BROKEN (cannot open PARAM.SFO)"); - return CELL_GAMEDATA_ERROR_BROKEN; - } - - PSFLoader psf(f); - if (!psf.Load(false)) - { - cellGame.Error("cellGameDataCheckCreate(2)(): CELL_GAMEDATA_ERROR_BROKEN (cannot read PARAM.SFO)"); + cellGame.Error("cellGameDataCheckCreate2(): CELL_GAMEDATA_ERROR_BROKEN (cannot read PARAM.SFO)"); return CELL_GAMEDATA_ERROR_BROKEN; } @@ -287,72 +346,100 @@ int cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr di if (cbSet->setParam) { // TODO: write PARAM.SFO from cbSet - cellGame.Todo("cellGameDataCheckCreate(2)(): writing PARAM.SFO parameters (addr=0x%x)", cbSet->setParam); + cellGame.Todo("cellGameDataCheckCreate2(): writing PARAM.SFO parameters (addr=0x%x)", cbSet->setParam); } switch ((s32)cbResult->result) { case CELL_GAMEDATA_CBRESULT_OK_CANCEL: // TODO: do not process game data - cellGame.Warning("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_OK_CANCEL"); + cellGame.Warning("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_OK_CANCEL"); case CELL_GAMEDATA_CBRESULT_OK: return CELL_GAMEDATA_RET_OK; case CELL_GAMEDATA_CBRESULT_ERR_NOSPACE: // TODO: process errors, error message and needSizeKB result - cellGame.Error("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NOSPACE"); + cellGame.Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NOSPACE"); return CELL_GAMEDATA_ERROR_CBRESULT; case CELL_GAMEDATA_CBRESULT_ERR_BROKEN: - cellGame.Error("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_ERR_BROKEN"); + cellGame.Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_BROKEN"); return CELL_GAMEDATA_ERROR_CBRESULT; case CELL_GAMEDATA_CBRESULT_ERR_NODATA: - cellGame.Error("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NODATA"); + cellGame.Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_NODATA"); return CELL_GAMEDATA_ERROR_CBRESULT; case CELL_GAMEDATA_CBRESULT_ERR_INVALID: - cellGame.Error("cellGameDataCheckCreate(2)(): callback returned CELL_GAMEDATA_CBRESULT_ERR_INVALID"); + cellGame.Error("cellGameDataCheckCreate2(): callback returned CELL_GAMEDATA_CBRESULT_ERR_INVALID"); return CELL_GAMEDATA_ERROR_CBRESULT; default: - cellGame.Error("cellGameDataCheckCreate(2)(): callback returned unknown error (code=0x%x)"); + cellGame.Error("cellGameDataCheckCreate2(): callback returned unknown error (code=0x%x)"); return CELL_GAMEDATA_ERROR_CBRESULT; } } -int cellGameDataCheckCreate(PPUThread& CPU, u32 version, vm::ptr dirName, u32 errDialog, - vm::ptr cbResult, vm::ptr get, vm::ptr set)> funcStat, u32 container) +s32 cellGameDataCheckCreate(PPUThread& CPU, u32 version, vm::ptr dirName, u32 errDialog, vm::ptr funcStat, u32 container) { + cellGame.Warning("cellGameDataCheckCreate(version=0x%x, dirName=*0x%x, errDialog=0x%x, funcStat=*0x%x, container=%d)", version, dirName, errDialog, funcStat, container); + // TODO: almost identical, the only difference is that this function will always calculate the size of game data return cellGameDataCheckCreate2(CPU, version, dirName, errDialog, funcStat, container); } -int cellGameCreateGameData(vm::ptr init, vm::ptr tmp_contentInfoPath, vm::ptr tmp_usrdirPath) +s32 cellGameCreateGameData(vm::ptr init, vm::ptr tmp_contentInfoPath, vm::ptr tmp_usrdirPath) { - cellGame.Todo("cellGameCreateGameData(init_addr=0x%x, tmp_contentInfoPath_addr=0x%x, tmp_usrdirPath_addr=0x%x)", - init.addr(), tmp_contentInfoPath.addr(), tmp_usrdirPath.addr()); + cellGame.Error("cellGameCreateGameData(init=*0x%x, tmp_contentInfoPath=*0x%x, tmp_usrdirPath=*0x%x)", init, tmp_contentInfoPath, tmp_usrdirPath); + + std::string dir = init->titleId; + std::string tmp_contentInfo = "/dev_hdd0/game/TMP_" + dir; + std::string tmp_usrdir = "/dev_hdd0/game/TMP_" + dir + "/USRDIR"; + + if (!Emu.GetVFS().CreateDir(tmp_contentInfo)) + { + cellGame.Error("cellGameCreateGameData(): failed to create content directory ('%s')", tmp_contentInfo); + return CELL_GAME_ERROR_ACCESS_ERROR; // ??? + } + + if (!Emu.GetVFS().CreateDir(tmp_usrdir)) + { + cellGame.Error("cellGameCreateGameData(): failed to create USRDIR directory ('%s')", tmp_usrdir); + return CELL_GAME_ERROR_ACCESS_ERROR; // ??? + } - // TODO: create temporary game directory, set initial PARAM.SFO parameters // cellGameContentPermit should then move files in non-temporary location and return their non-temporary displacement + strcpy_trunc(*tmp_contentInfoPath, tmp_contentInfo); + strcpy_trunc(*tmp_usrdirPath, tmp_usrdir); + + contentInfo = dir; + usrdir.clear(); + path_set = true; + + cellGame.Success("cellGameCreateGameData(): temporary gamedata directory created ('%s')", tmp_contentInfo); + + // TODO: set initial PARAM.SFO parameters + return CELL_OK; } -int cellGameDeleteGameData() +s32 cellGameDeleteGameData() { UNIMPLEMENTED_FUNC(cellGame); return CELL_OK; } -int cellGameGetParamInt(u32 id, vm::ptr value) +s32 cellGameGetParamInt(u32 id, vm::ptr value) { - cellGame.Warning("cellGameGetParamInt(id=%d, value_addr=0x%x)", id, value.addr()); + cellGame.Warning("cellGameGetParamInt(id=%d, value=*0x%x)", id, value); // TODO: Access through cellGame***Check functions vfsFile f("/app_home/../PARAM.SFO"); - PSFLoader psf(f); - if(!psf.Load(false)) + const PSFLoader psf(f); + if (!psf) + { return CELL_GAME_ERROR_FAILURE; + } switch(id) { @@ -367,15 +454,17 @@ int cellGameGetParamInt(u32 id, vm::ptr value) return CELL_OK; } -int cellGameGetParamString(u32 id, vm::ptr buf, u32 bufsize) +s32 cellGameGetParamString(u32 id, vm::ptr buf, u32 bufsize) { - cellGame.Warning("cellGameGetParamString(id=%d, buf_addr=0x%x, bufsize=%d)", id, buf.addr(), bufsize); + cellGame.Warning("cellGameGetParamString(id=%d, buf=*0x%x, bufsize=%d)", id, buf, bufsize); // TODO: Access through cellGame***Check functions vfsFile f("/app_home/../PARAM.SFO"); - PSFLoader psf(f); - if(!psf.Load(false)) + const PSFLoader psf(f); + if (!psf) + { return CELL_GAME_ERROR_FAILURE; + } std::string data; switch(id) @@ -415,33 +504,33 @@ int cellGameGetParamString(u32 id, vm::ptr buf, u32 bufsize) return CELL_OK; } -int cellGameSetParamString() +s32 cellGameSetParamString() { UNIMPLEMENTED_FUNC(cellGame); return CELL_OK; } -int cellGameGetSizeKB() +s32 cellGameGetSizeKB() { UNIMPLEMENTED_FUNC(cellGame); return CELL_OK; } -int cellGameGetDiscContentInfoUpdatePath() +s32 cellGameGetDiscContentInfoUpdatePath() { UNIMPLEMENTED_FUNC(cellGame); return CELL_OK; } -int cellGameGetLocalWebContentPath() +s32 cellGameGetLocalWebContentPath() { UNIMPLEMENTED_FUNC(cellGame); return CELL_OK; } -int cellGameContentErrorDialog(s32 type, s32 errNeedSizeKB, vm::ptr dirName) +s32 cellGameContentErrorDialog(s32 type, s32 errNeedSizeKB, vm::ptr dirName) { - cellGame.Warning("cellGameContentErrorDialog(type=%d, errNeedSizeKB=%d, dirName_addr=0x%x)", type, errNeedSizeKB, dirName.addr()); + cellGame.Warning("cellGameContentErrorDialog(type=%d, errNeedSizeKB=%d, dirName=*0x%x)", type, errNeedSizeKB, dirName); std::string errorName; switch (type) @@ -475,13 +564,13 @@ int cellGameContentErrorDialog(s32 type, s32 errNeedSizeKB, vm::ptr return CELL_OK; } -int cellGameThemeInstall() +s32 cellGameThemeInstall() { UNIMPLEMENTED_FUNC(cellGame); return CELL_OK; } -int cellGameThemeInstallFromBuffer() +s32 cellGameThemeInstallFromBuffer() { UNIMPLEMENTED_FUNC(cellGame); return CELL_OK; @@ -517,3 +606,15 @@ Module cellGame("cellGame", []() REG_FUNC(cellGame, cellGameThemeInstallFromBuffer); //cellGame.AddFunc(, CellGameThemeInstallCallback); }); + +void cellSysutil_GameData_init() +{ + REG_FUNC(cellGame, cellHddGameCheck); + //REG_FUNC(cellGame, cellHddGameCheck2); + //REG_FUNC(cellGame, cellHddGameGetSizeKB); + //REG_FUNC(cellGame, cellHddGameSetSystemVer); + //REG_FUNC(cellGame, cellHddGameExitBroken); + + REG_FUNC(cellGame, cellGameDataCheckCreate); + REG_FUNC(cellGame, cellGameDataCheckCreate2); +} diff --git a/rpcs3/Emu/SysCalls/Modules/cellGame.h b/rpcs3/Emu/SysCalls/Modules/cellGame.h index 1ccda34eb1..284f89a75b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGame.h +++ b/rpcs3/Emu/SysCalls/Modules/cellGame.h @@ -200,3 +200,92 @@ struct CellGameDataStatSet vm::bptr setParam; be_t reserved; }; + +typedef void(CellGameDataStatCallback)(vm::ptr cbResult, vm::ptr get, vm::ptr set); + +// cellSysutil: cellHddGame +enum +{ + // Return Codes + CELL_HDDGAME_RET_CANCEL = 1, + CELL_HDDGAME_ERROR_CBRESULT = 0x8002ba01, + CELL_HDDGAME_ERROR_ACCESS_ERROR = 0x8002ba02, + CELL_HDDGAME_ERROR_INTERNAL = 0x8002ba03, + CELL_HDDGAME_ERROR_PARAM = 0x8002ba04, + CELL_HDDGAME_ERROR_NOSPACE = 0x8002ba05, + CELL_HDDGAME_ERROR_BROKEN = 0x8002ba06, + CELL_HDDGAME_ERROR_FAILURE = 0x8002ba07, + + // Callback Result + CELL_HDDGAME_CBRESULT_OK_CANCEL = 1, + CELL_HDDGAME_CBRESULT_OK = 0, + CELL_HDDGAME_CBRESULT_ERR_NOSPACE = -1, + CELL_HDDGAME_CBRESULT_ERR_BROKEN = -3, + CELL_HDDGAME_CBRESULT_ERR_NODATA = -4, + CELL_HDDGAME_CBRESULT_ERR_INVALID = -5, + + // Character Strings + CELL_HDDGAME_INVALIDMSG_MAX = 256, + CELL_HDDGAME_PATH_MAX = 1055, + CELL_HDDGAME_SYSP_TITLE_SIZE = 128, + CELL_HDDGAME_SYSP_TITLEID_SIZE = 10, + CELL_HDDGAME_SYSP_VERSION_SIZE = 6, + CELL_HDDGAME_SYSP_SYSTEMVER_SIZE = 8, + + // HDD Directory exists + CELL_HDDGAME_ISNEWDATA_EXIST = 0, + CELL_HDDGAME_ISNEWDATA_NODIR = 1, + + // Languages + CELL_HDDGAME_SYSP_LANGUAGE_NUM = 20, + + // Stat Get + CELL_HDDGAME_SIZEKB_NOTCALC = -1, +}; + +struct CellHddGameSystemFileParam +{ + char title[CELL_HDDGAME_SYSP_TITLE_SIZE]; + char titleLang[CELL_HDDGAME_SYSP_LANGUAGE_NUM][CELL_HDDGAME_SYSP_TITLE_SIZE]; + char titleId[CELL_HDDGAME_SYSP_TITLEID_SIZE]; + char reserved0[2]; + char dataVersion[CELL_HDDGAME_SYSP_VERSION_SIZE]; + char reserved1[2]; + be_t attribute; + be_t parentalLevel; + be_t resolution; + be_t soundFormat; + char reserved2[256]; +}; + +struct CellHddGameCBResult +{ + be_t result; + be_t errNeedSizeKB; + vm::bptr invalidMsg; + vm::bptr reserved; +}; + +struct CellHddGameStatGet +{ + be_t hddFreeSizeKB; + be_t isNewData; + char contentInfoPath[CELL_HDDGAME_PATH_MAX]; + char hddGamePath[CELL_HDDGAME_PATH_MAX]; + char reserved0[2]; + be_t atime; + be_t mtime; + be_t ctime; + CellHddGameSystemFileParam getParam; + be_t sizeKB; + be_t sysSizeKB; + char reserved1[68]; +}; + +struct CellHddGameStatSet +{ + vm::bptr setParam; + vm::bptr reserved; +}; + +typedef void(CellHddGameStatCallback)(vm::ptr cbResult, vm::ptr get, vm::ptr set); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index e3ff78e0f4..3541d12839 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -86,7 +86,7 @@ vm::ptr cellGcmGetReportDataAddressLocation(u32 index, u32 lo if (location == CELL_GCM_LOCATION_LOCAL) { if (index >= 2048) { cellGcmSys.Error("cellGcmGetReportDataAddressLocation: Wrong local index (%d)", index); - return vm::ptr::make(0); + return vm::null; } return vm::ptr::make((u32)Memory.RSXFBMem.GetStartAddr() + index * 0x10); } @@ -94,14 +94,14 @@ vm::ptr cellGcmGetReportDataAddressLocation(u32 index, u32 lo if (location == CELL_GCM_LOCATION_MAIN) { if (index >= 1024 * 1024) { cellGcmSys.Error("cellGcmGetReportDataAddressLocation: Wrong main index (%d)", index); - return vm::ptr::make(0); + return vm::null; } // TODO: It seems m_report_main_addr is not initialized return vm::ptr::make(Emu.GetGSManager().GetRender().m_report_main_addr + index * 0x10); } cellGcmSys.Error("cellGcmGetReportDataAddressLocation: Wrong location (%d)", location); - return vm::ptr::make(0); + return vm::null; } u64 cellGcmGetTimeStamp(u32 index) diff --git a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp index 1ce25e3082..e6c3da6484 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp @@ -4,8 +4,11 @@ #include "Emu/IdManager.h" #include "Emu/SysCalls/Modules.h" +extern "C" +{ #include "stblib/stb_image.h" -#include "stblib/stb_image.c" // (TODO: Should we put this elsewhere?) +#include "stblib/stb_image.c" +} #include "Emu/FS/VFS.h" #include "Emu/FS/vfsFileBase.h" @@ -15,22 +18,21 @@ extern Module cellGifDec; -int cellGifDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam) +s32 cellGifDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam) { UNIMPLEMENTED_FUNC(cellGifDec); return CELL_OK; } -int cellGifDecExtCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam, u32 extThreadInParam, u32 extThreadOutParam) +s32 cellGifDecExtCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam, u32 extThreadInParam, u32 extThreadOutParam) { UNIMPLEMENTED_FUNC(cellGifDec); return CELL_OK; } -int cellGifDecOpen(u32 mainHandle, vm::ptr subHandle, vm::ptr src, vm::ptr openInfo) +s32 cellGifDecOpen(u32 mainHandle, vm::ptr subHandle, vm::ptr src, vm::ptr openInfo) { - cellGifDec.Warning("cellGifDecOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x)", - mainHandle, subHandle.addr(), src.addr(), openInfo.addr()); + cellGifDec.Warning("cellGifDecOpen(mainHandle=0x%x, subHandle=*0x%x, src=*0x%x, openInfo=*0x%x)", mainHandle, subHandle, src, openInfo); std::shared_ptr current_subHandle(new CellGifDecSubHandle); current_subHandle->fd = 0; @@ -60,14 +62,16 @@ int cellGifDecOpen(u32 mainHandle, vm::ptr subHandle, vm::ptr info) +s32 cellGifDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr info) { - cellGifDec.Warning("cellGifDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x)", - mainHandle, subHandle, info.addr()); + cellGifDec.Warning("cellGifDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info=*0x%x)", mainHandle, subHandle, info); - std::shared_ptr subHandle_data; - if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data)) + const auto subHandle_data = Emu.GetIdManager().GetIDData(subHandle); + + if (!subHandle_data) + { return CELL_GIFDEC_ERROR_FATAL; + } const u32& fd = subHandle_data->fd; const u64& fileSize = subHandle_data->fileSize; @@ -112,14 +116,16 @@ int cellGifDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr return CELL_OK; } -int cellGifDecSetParameter(u32 mainHandle, u32 subHandle, vm::ptr inParam, vm::ptr outParam) +s32 cellGifDecSetParameter(u32 mainHandle, u32 subHandle, vm::ptr inParam, vm::ptr outParam) { - cellGifDec.Warning("cellGifDecSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x)", - mainHandle, subHandle, inParam.addr(), outParam.addr()); + cellGifDec.Warning("cellGifDecSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam=*0x%x, outParam=*0x%x)", mainHandle, subHandle, inParam, outParam); - std::shared_ptr subHandle_data; - if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data)) + const auto subHandle_data = Emu.GetIdManager().GetIDData(subHandle); + + if (!subHandle_data) + { return CELL_GIFDEC_ERROR_FATAL; + } CellGifDecInfo& current_info = subHandle_data->info; CellGifDecOutParam& current_outParam = subHandle_data->outParam; @@ -142,16 +148,18 @@ int cellGifDecSetParameter(u32 mainHandle, u32 subHandle, vm::ptr data, vm::ptr dataCtrlParam, vm::ptr dataOutInfo) +s32 cellGifDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, vm::ptr dataCtrlParam, vm::ptr dataOutInfo) { - cellGifDec.Warning("cellGifDecDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x)", - mainHandle, subHandle, data.addr(), dataCtrlParam.addr(), dataOutInfo.addr()); + cellGifDec.Warning("cellGifDecDecodeData(mainHandle=0x%x, subHandle=0x%x, data=*0x%x, dataCtrlParam=*0x%x, dataOutInfo=*0x%x)", mainHandle, subHandle, data, dataCtrlParam, dataOutInfo); dataOutInfo->status = CELL_GIFDEC_DEC_STATUS_STOP; - std::shared_ptr subHandle_data; - if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data)) + const auto subHandle_data = Emu.GetIdManager().GetIDData(subHandle); + + if (!subHandle_data) + { return CELL_GIFDEC_ERROR_FATAL; + } const u32& fd = subHandle_data->fd; const u64& fileSize = subHandle_data->fileSize; @@ -261,14 +269,16 @@ int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, vm::pt return CELL_OK; } -int cellGifDecClose(u32 mainHandle, u32 subHandle) +s32 cellGifDecClose(u32 mainHandle, u32 subHandle) { - cellGifDec.Warning("cellGifDecClose(mainHandle=0x%x, subHandle=0x%x)", - mainHandle, subHandle); + cellGifDec.Warning("cellGifDecClose(mainHandle=0x%x, subHandle=0x%x)", mainHandle, subHandle); - std::shared_ptr subHandle_data; - if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data)) + const auto subHandle_data = Emu.GetIdManager().GetIDData(subHandle); + + if (!subHandle_data) + { return CELL_GIFDEC_ERROR_FATAL; + } Emu.GetIdManager().RemoveID(subHandle_data->fd); Emu.GetIdManager().RemoveID(subHandle); @@ -276,7 +286,7 @@ int cellGifDecClose(u32 mainHandle, u32 subHandle) return CELL_OK; } -int cellGifDecDestroy(u32 mainHandle) +s32 cellGifDecDestroy(u32 mainHandle) { UNIMPLEMENTED_FUNC(cellGifDec); return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp index 600f58bb40..eb9463603c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp @@ -4,7 +4,10 @@ #include "Emu/IdManager.h" #include "Emu/SysCalls/Modules.h" +extern "C" +{ #include "stblib/stb_image.h" +} #include "Emu/FS/VFS.h" #include "Emu/FS/vfsFileBase.h" @@ -14,28 +17,27 @@ extern Module cellJpgDec; -int cellJpgDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam) +s32 cellJpgDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam) { UNIMPLEMENTED_FUNC(cellJpgDec); return CELL_OK; } -int cellJpgDecExtCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam, u32 extThreadInParam, u32 extThreadOutParam) +s32 cellJpgDecExtCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam, u32 extThreadInParam, u32 extThreadOutParam) { UNIMPLEMENTED_FUNC(cellJpgDec); return CELL_OK; } -int cellJpgDecDestroy(u32 mainHandle) +s32 cellJpgDecDestroy(u32 mainHandle) { UNIMPLEMENTED_FUNC(cellJpgDec); return CELL_OK; } -int cellJpgDecOpen(u32 mainHandle, vm::ptr subHandle, vm::ptr src, vm::ptr openInfo) +s32 cellJpgDecOpen(u32 mainHandle, vm::ptr subHandle, vm::ptr src, vm::ptr openInfo) { - cellJpgDec.Warning("cellJpgDecOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x)", - mainHandle, subHandle.addr(), src.addr(), openInfo.addr()); + cellJpgDec.Warning("cellJpgDecOpen(mainHandle=0x%x, subHandle=*0x%x, src=*0x%x, openInfo=*0x%x)", mainHandle, subHandle, src, openInfo); std::shared_ptr current_subHandle(new CellJpgDecSubHandle); @@ -66,14 +68,16 @@ int cellJpgDecOpen(u32 mainHandle, vm::ptr subHandle, vm::ptr subHandle_data; - if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data)) + const auto subHandle_data = Emu.GetIdManager().GetIDData(subHandle); + + if (!subHandle_data) + { return CELL_JPGDEC_ERROR_FATAL; + } Emu.GetIdManager().RemoveID(subHandle_data->fd); Emu.GetIdManager().RemoveID(subHandle); @@ -81,13 +85,16 @@ int cellJpgDecClose(u32 mainHandle, u32 subHandle) return CELL_OK; } -int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr info) +s32 cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr info) { - cellJpgDec.Log("cellJpgDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x)", mainHandle, subHandle, info.addr()); + cellJpgDec.Log("cellJpgDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info=*0x%x)", mainHandle, subHandle, info); - std::shared_ptr subHandle_data; - if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data)) + const auto subHandle_data = Emu.GetIdManager().GetIDData(subHandle); + + if (!subHandle_data) + { return CELL_JPGDEC_ERROR_FATAL; + } const u32& fd = subHandle_data->fd; const u64& fileSize = subHandle_data->fileSize; @@ -150,15 +157,18 @@ int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr return CELL_OK; } -int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, vm::ptr dataCtrlParam, vm::ptr dataOutInfo) +s32 cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, vm::ptr dataCtrlParam, vm::ptr dataOutInfo) { - cellJpgDec.Log("cellJpgDecDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x)", - mainHandle, subHandle, data.addr(), dataCtrlParam.addr(), dataOutInfo.addr()); + cellJpgDec.Log("cellJpgDecDecodeData(mainHandle=0x%x, subHandle=0x%x, data=*0x%x, dataCtrlParam=*0x%x, dataOutInfo=*0x%x)", mainHandle, subHandle, data, dataCtrlParam, dataOutInfo); dataOutInfo->status = CELL_JPGDEC_DEC_STATUS_STOP; - std::shared_ptr subHandle_data; - if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data)) + + const auto subHandle_data = Emu.GetIdManager().GetIDData(subHandle); + + if (!subHandle_data) + { return CELL_JPGDEC_ERROR_FATAL; + } const u32& fd = subHandle_data->fd; const u64& fileSize = subHandle_data->fileSize; @@ -283,14 +293,16 @@ int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr data, vm::pt return CELL_OK; } -int cellJpgDecSetParameter(u32 mainHandle, u32 subHandle, vm::ptr inParam, vm::ptr outParam) +s32 cellJpgDecSetParameter(u32 mainHandle, u32 subHandle, vm::ptr inParam, vm::ptr outParam) { - cellJpgDec.Log("cellJpgDecSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x)", - mainHandle, subHandle, inParam.addr(), outParam.addr()); + cellJpgDec.Log("cellJpgDecSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam=*0x%x, outParam=*0x%x)", mainHandle, subHandle, inParam, outParam); - std::shared_ptr subHandle_data; - if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data)) + const auto subHandle_data = Emu.GetIdManager().GetIDData(subHandle); + + if (!subHandle_data) + { return CELL_JPGDEC_ERROR_FATAL; + } CellJpgDecInfo& current_info = subHandle_data->info; CellJpgDecOutParam& current_outParam = subHandle_data->outParam; diff --git a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp index 7b96cefec4..cbf57a31aa 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.cpp @@ -5,52 +5,28 @@ #include "Emu/SysCalls/Callback.h" #include "Emu/SysCalls/CB_FUNC.h" -#include "Utilities/Log.h" -#include "Utilities/rMsgBox.h" #include "Emu/SysCalls/lv2/sys_time.h" #include "cellSysutil.h" #include "cellMsgDialog.h" extern Module cellSysutil; -enum MsgDialogState +std::unique_ptr g_msg_dialog; + +MsgDialogInstance::MsgDialogInstance() + : state(msgDialogNone) { - msgDialogNone, - msgDialogOpen, - msgDialogClose, - msgDialogAbort, -}; - -std::atomic g_msg_dialog_state(msgDialogNone); -u64 g_msg_dialog_status; -u64 g_msg_dialog_wait_until; -u32 g_msg_dialog_progress_bar_count; - -MsgDialogCreateCb MsgDialogCreate = nullptr; -MsgDialogDestroyCb MsgDialogDestroy = nullptr; -MsgDialogProgressBarSetMsgCb MsgDialogProgressBarSetMsg = nullptr; -MsgDialogProgressBarResetCb MsgDialogProgressBarReset = nullptr; -MsgDialogProgressBarIncCb MsgDialogProgressBarInc = nullptr; - -void SetMsgDialogCallbacks(MsgDialogCreateCb ccb, MsgDialogDestroyCb dcb, MsgDialogProgressBarSetMsgCb pbscb, MsgDialogProgressBarResetCb pbrcb, MsgDialogProgressBarIncCb pbicb) -{ - MsgDialogCreate = ccb; - MsgDialogDestroy = dcb; - MsgDialogProgressBarSetMsg = pbscb; - MsgDialogProgressBarReset = pbrcb; - MsgDialogProgressBarInc = pbicb; } -void MsgDialogClose() +void MsgDialogInstance::Close() { - g_msg_dialog_state = msgDialogClose; - g_msg_dialog_wait_until = get_system_time(); + state = msgDialogClose; + wait_until = get_system_time(); } -s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptr callback, u32 userData, u32 extParam) +s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptr callback, vm::ptr userData, vm::ptr extParam) { - cellSysutil.Warning("cellMsgDialogOpen2(type=0x%x, msgString_addr=0x%x, callback_addr=0x%x, userData=0x%x, extParam=0x%x)", - type, msgString.addr(), callback.addr(), userData, extParam); + cellSysutil.Warning("cellMsgDialogOpen2(type=0x%x, msgString=*0x%x, callback=*0x%x, userData=*0x%x, extParam=*0x%x)", type, msgString, callback, userData, extParam); if (!msgString || strlen(msgString.get_ptr()) >= 0x200 || type & -0x33f8) { @@ -107,18 +83,24 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptrstate.compare_exchange_strong(old, msgDialogOpen)) { return CELL_SYSUTIL_ERROR_BUSY; } - g_msg_dialog_wait_until = get_system_time() + 31536000000000ull; // some big value + g_msg_dialog->wait_until = get_system_time() + 31536000000000ull; // some big value switch (type & CELL_MSGDIALOG_TYPE_PROGRESSBAR) { - case CELL_MSGDIALOG_TYPE_PROGRESSBAR_DOUBLE: g_msg_dialog_progress_bar_count = 2; break; - case CELL_MSGDIALOG_TYPE_PROGRESSBAR_SINGLE: g_msg_dialog_progress_bar_count = 1; break; - default: g_msg_dialog_progress_bar_count = 0; break; + case CELL_MSGDIALOG_TYPE_PROGRESSBAR_DOUBLE: g_msg_dialog->progress_bar_count = 2; break; + case CELL_MSGDIALOG_TYPE_PROGRESSBAR_SINGLE: g_msg_dialog->progress_bar_count = 1; break; + default: g_msg_dialog->progress_bar_count = 0; break; + } + + switch (type & CELL_MSGDIALOG_TYPE_SE_MUTE) // TODO + { + case CELL_MSGDIALOG_TYPE_SE_MUTE_OFF: break; + case CELL_MSGDIALOG_TYPE_SE_MUTE_ON: break; } std::string msg = msgString.get_ptr(); @@ -127,24 +109,18 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptrstatus = CELL_MSGDIALOG_BUTTON_NONE; volatile bool m_signal = false; CallAfter([type, msg, &m_signal]() { if (Emu.IsStopped()) return; - MsgDialogCreate(type, msg.c_str(), g_msg_dialog_status); + g_msg_dialog->Create(type, msg); m_signal = true; }); @@ -159,20 +135,21 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptrstate == msgDialogOpen || (s64)(get_system_time() - g_msg_dialog->wait_until) < 0) { if (Emu.IsStopped()) { - g_msg_dialog_state = msgDialogAbort; + g_msg_dialog->state = msgDialogAbort; break; } std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack } - if (callback && (g_msg_dialog_state != msgDialogAbort)) + if (callback && (g_msg_dialog->state != msgDialogAbort)) { - const s32 status = (s32)g_msg_dialog_status; - Emu.GetCallbackManager().Register([callback, userData, status](PPUThread& PPU) -> s32 + const s32 status = g_msg_dialog->status; + + Emu.GetCallbackManager().Register([=](PPUThread& PPU) -> s32 { callback(PPU, status, userData); return CELL_OK; @@ -181,116 +158,93 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptrDestroy(); + g_msg_dialog->state = msgDialogNone; }); }); return CELL_OK; } -s32 cellMsgDialogOpenErrorCode(u32 errorCode, vm::ptr callback, u32 userData, u32 extParam) +s32 cellMsgDialogOpenErrorCode(PPUThread& CPU, u32 errorCode, vm::ptr callback, vm::ptr userData, vm::ptr extParam) { - cellSysutil.Warning("cellMsgDialogOpenErrorCode(errorCode=0x%x, callback_addr=0x%x, userData=0x%x, extParam=%d)", - errorCode, callback.addr(), userData, extParam); + cellSysutil.Warning("cellMsgDialogOpenErrorCode(errorCode=0x%x, callback=*0x%x, userData=*0x%x, extParam=*0x%x)", errorCode, callback, userData, extParam); + + std::string error; - std::string errorMessage; switch (errorCode) { - // Generic errors - case 0x80010001: errorMessage = "The resource is temporarily unavailable."; break; - case 0x80010002: errorMessage = "Invalid argument or flag."; break; - case 0x80010003: errorMessage = "The feature is not yet implemented."; break; - case 0x80010004: errorMessage = "Memory allocation failed."; break; - case 0x80010005: errorMessage = "The resource with the specified identifier does not exist."; break; - case 0x80010006: errorMessage = "The file does not exist."; break; - case 0x80010007: errorMessage = "The file is in unrecognized format / The file is not a valid ELF file."; break; - case 0x80010008: errorMessage = "Resource deadlock is avoided."; break; - case 0x80010009: errorMessage = "Operation not permitted."; break; - case 0x8001000A: errorMessage = "The device or resource is busy."; break; - case 0x8001000B: errorMessage = "The operation is timed out."; break; - case 0x8001000C: errorMessage = "The operation is aborted."; break; - case 0x8001000D: errorMessage = "Invalid memory access."; break; - case 0x8001000F: errorMessage = "State of the target thread is invalid."; break; - case 0x80010010: errorMessage = "Alignment is invalid."; break; - case 0x80010011: errorMessage = "Shortage of the kernel resources."; break; - case 0x80010012: errorMessage = "The file is a directory."; break; - case 0x80010013: errorMessage = "Operation cancelled."; break; - case 0x80010014: errorMessage = "Entry already exists."; break; - case 0x80010015: errorMessage = "Port is already connected."; break; - case 0x80010016: errorMessage = "Port is not connected."; break; - case 0x80010017: errorMessage = "Failure in authorizing SELF. Program authentication fail."; break; - case 0x80010018: errorMessage = "The file is not MSELF."; break; - case 0x80010019: errorMessage = "System version error."; break; - case 0x8001001A: errorMessage = "Fatal system error occurred while authorizing SELF. SELF auth failure."; break; - case 0x8001001B: errorMessage = "Math domain violation."; break; - case 0x8001001C: errorMessage = "Math range violation."; break; - case 0x8001001D: errorMessage = "Illegal multi-byte sequence in input."; break; - case 0x8001001E: errorMessage = "File position error."; break; - case 0x8001001F: errorMessage = "Syscall was interrupted."; break; - case 0x80010020: errorMessage = "File too large."; break; - case 0x80010021: errorMessage = "Too many links."; break; - case 0x80010022: errorMessage = "File table overflow."; break; - case 0x80010023: errorMessage = "No space left on device."; break; - case 0x80010024: errorMessage = "Not a TTY."; break; - case 0x80010025: errorMessage = "Broken pipe."; break; - case 0x80010026: errorMessage = "Read-only filesystem."; break; - case 0x80010027: errorMessage = "Illegal seek."; break; - case 0x80010028: errorMessage = "Arg list too long."; break; - case 0x80010029: errorMessage = "Access violation."; break; - case 0x8001002A: errorMessage = "Invalid file descriptor."; break; - case 0x8001002B: errorMessage = "Filesystem mounting failed."; break; - case 0x8001002C: errorMessage = "Too many files open."; break; - case 0x8001002D: errorMessage = "No device."; break; - case 0x8001002E: errorMessage = "Not a directory."; break; - case 0x8001002F: errorMessage = "No such device or IO."; break; - case 0x80010030: errorMessage = "Cross-device link error."; break; - case 0x80010031: errorMessage = "Bad Message."; break; - case 0x80010032: errorMessage = "In progress."; break; - case 0x80010033: errorMessage = "Message size error."; break; - case 0x80010034: errorMessage = "Name too long."; break; - case 0x80010035: errorMessage = "No lock."; break; - case 0x80010036: errorMessage = "Not empty."; break; - case 0x80010037: errorMessage = "Not supported."; break; - case 0x80010038: errorMessage = "File-system specific error."; break; - case 0x80010039: errorMessage = "Overflow occured."; break; - case 0x8001003A: errorMessage = "Filesystem not mounted."; break; - case 0x8001003B: errorMessage = "Not SData."; break; - case 0x8001003C: errorMessage = "Incorrect version in sys_load_param."; break; - case 0x8001003D: errorMessage = "Pointer is null."; break; - case 0x8001003E: errorMessage = "Pointer is null."; break; - default: errorMessage = "An error has occurred."; break; + case 0x80010001: error = "The resource is temporarily unavailable."; break; + case 0x80010002: error = "Invalid argument or flag."; break; + case 0x80010003: error = "The feature is not yet implemented."; break; + case 0x80010004: error = "Memory allocation failed."; break; + case 0x80010005: error = "The resource with the specified identifier does not exist."; break; + case 0x80010006: error = "The file does not exist."; break; + case 0x80010007: error = "The file is in unrecognized format / The file is not a valid ELF file."; break; + case 0x80010008: error = "Resource deadlock is avoided."; break; + case 0x80010009: error = "Operation not permitted."; break; + case 0x8001000A: error = "The device or resource is busy."; break; + case 0x8001000B: error = "The operation is timed out."; break; + case 0x8001000C: error = "The operation is aborted."; break; + case 0x8001000D: error = "Invalid memory access."; break; + case 0x8001000F: error = "State of the target thread is invalid."; break; + case 0x80010010: error = "Alignment is invalid."; break; + case 0x80010011: error = "Shortage of the kernel resources."; break; + case 0x80010012: error = "The file is a directory."; break; + case 0x80010013: error = "Operation cancelled."; break; + case 0x80010014: error = "Entry already exists."; break; + case 0x80010015: error = "Port is already connected."; break; + case 0x80010016: error = "Port is not connected."; break; + case 0x80010017: error = "Failure in authorizing SELF. Program authentication fail."; break; + case 0x80010018: error = "The file is not MSELF."; break; + case 0x80010019: error = "System version error."; break; + case 0x8001001A: error = "Fatal system error occurred while authorizing SELF. SELF auth failure."; break; + case 0x8001001B: error = "Math domain violation."; break; + case 0x8001001C: error = "Math range violation."; break; + case 0x8001001D: error = "Illegal multi-byte sequence in input."; break; + case 0x8001001E: error = "File position error."; break; + case 0x8001001F: error = "Syscall was interrupted."; break; + case 0x80010020: error = "File too large."; break; + case 0x80010021: error = "Too many links."; break; + case 0x80010022: error = "File table overflow."; break; + case 0x80010023: error = "No space left on device."; break; + case 0x80010024: error = "Not a TTY."; break; + case 0x80010025: error = "Broken pipe."; break; + case 0x80010026: error = "Read-only filesystem."; break; + case 0x80010027: error = "Illegal seek."; break; + case 0x80010028: error = "Arg list too long."; break; + case 0x80010029: error = "Access violation."; break; + case 0x8001002A: error = "Invalid file descriptor."; break; + case 0x8001002B: error = "Filesystem mounting failed."; break; + case 0x8001002C: error = "Too many files open."; break; + case 0x8001002D: error = "No device."; break; + case 0x8001002E: error = "Not a directory."; break; + case 0x8001002F: error = "No such device or IO."; break; + case 0x80010030: error = "Cross-device link error."; break; + case 0x80010031: error = "Bad Message."; break; + case 0x80010032: error = "In progress."; break; + case 0x80010033: error = "Message size error."; break; + case 0x80010034: error = "Name too long."; break; + case 0x80010035: error = "No lock."; break; + case 0x80010036: error = "Not empty."; break; + case 0x80010037: error = "Not supported."; break; + case 0x80010038: error = "File-system specific error."; break; + case 0x80010039: error = "Overflow occured."; break; + case 0x8001003A: error = "Filesystem not mounted."; break; + case 0x8001003B: error = "Not SData."; break; + case 0x8001003C: error = "Incorrect version in sys_load_param."; break; + case 0x8001003D: error = "Pointer is null."; break; + case 0x8001003E: error = "Pointer is null."; break; + default: error = "An error has occurred."; break; } - char errorCodeHex[12]; -#if __STDC_WANT_SECURE_LIB__ && !_WIN32_WCE - sprintf_s(errorCodeHex, "\n(%08x)", errorCode); -#else - sprintf(errorCodeHex, "\n(%08x)", errorCode); -#endif - errorMessage.append(errorCodeHex); + error.append(fmt::format("\n(%08x)", errorCode)); - u64 status; - int res = rMessageBox(errorMessage, "Error", rICON_ERROR | rOK); - switch (res) - { - case rOK: status = CELL_MSGDIALOG_BUTTON_OK; break; - default: - if (res) - { - status = CELL_MSGDIALOG_BUTTON_INVALID; - break; - } + vm::stackvar message(CPU, error.size() + 1); - status = CELL_MSGDIALOG_BUTTON_NONE; - break; - } + memcpy(message.get_ptr(), error.c_str(), message.size()); - if (callback) - callback((s32)status, userData); - - return CELL_OK; + return cellMsgDialogOpen2(CELL_MSGDIALOG_DIALOG_TYPE_ERROR | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK, message, callback, userData, extParam); } s32 cellMsgDialogClose(float delay) @@ -298,7 +252,8 @@ s32 cellMsgDialogClose(float delay) cellSysutil.Warning("cellMsgDialogClose(delay=%f)", delay); MsgDialogState old = msgDialogOpen; - if (!g_msg_dialog_state.compare_exchange_strong(old, msgDialogClose)) + + if (!g_msg_dialog->state.compare_exchange_strong(old, msgDialogClose)) { if (old == msgDialogNone) { @@ -310,8 +265,8 @@ s32 cellMsgDialogClose(float delay) } } - if (delay < 0.0f) delay = 0.0f; - g_msg_dialog_wait_until = get_system_time() + (u64)(delay * 1000); + g_msg_dialog->wait_until = get_system_time() + static_cast(std::max(delay, 0.0f) * 1000); + return CELL_OK; } @@ -320,7 +275,8 @@ s32 cellMsgDialogAbort() cellSysutil.Warning("cellMsgDialogAbort()"); MsgDialogState old = msgDialogOpen; - if (!g_msg_dialog_state.compare_exchange_strong(old, msgDialogAbort)) + + if (!g_msg_dialog->state.compare_exchange_strong(old, msgDialogAbort)) { if (old == msgDialogNone) { @@ -332,31 +288,27 @@ s32 cellMsgDialogAbort() } } - g_msg_dialog_wait_until = get_system_time(); + g_msg_dialog->wait_until = get_system_time(); + return CELL_OK; } s32 cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::ptr msgString) { - cellSysutil.Warning("cellMsgDialogProgressBarSetMsg(progressBarIndex=%d, msgString_addr=0x%x ['%s'])", - progressBarIndex, msgString.addr(), msgString.get_ptr()); + cellSysutil.Warning("cellMsgDialogProgressBarSetMsg(progressBarIndex=%d, msgString=*0x%x)", progressBarIndex, msgString); - if (g_msg_dialog_state != msgDialogOpen) + if (g_msg_dialog->state != msgDialogOpen) { return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED; } - if (progressBarIndex >= g_msg_dialog_progress_bar_count) + if (progressBarIndex >= g_msg_dialog->progress_bar_count) { return CELL_MSGDIALOG_ERROR_PARAM; } - std::string text = msgString.get_ptr(); + g_msg_dialog->ProgressBarSetMsg(progressBarIndex, msgString.get_ptr()); - CallAfter([text, progressBarIndex]() - { - MsgDialogProgressBarSetMsg(progressBarIndex, text.c_str()); - }); return CELL_OK; } @@ -364,20 +316,18 @@ s32 cellMsgDialogProgressBarReset(u32 progressBarIndex) { cellSysutil.Warning("cellMsgDialogProgressBarReset(progressBarIndex=%d)", progressBarIndex); - if (g_msg_dialog_state != msgDialogOpen) + if (g_msg_dialog->state != msgDialogOpen) { return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED; } - if (progressBarIndex >= g_msg_dialog_progress_bar_count) + if (progressBarIndex >= g_msg_dialog->progress_bar_count) { return CELL_MSGDIALOG_ERROR_PARAM; } - CallAfter([=]() - { - MsgDialogProgressBarReset(progressBarIndex); - }); + g_msg_dialog->ProgressBarReset(progressBarIndex); + return CELL_OK; } @@ -385,19 +335,28 @@ s32 cellMsgDialogProgressBarInc(u32 progressBarIndex, u32 delta) { cellSysutil.Warning("cellMsgDialogProgressBarInc(progressBarIndex=%d, delta=%d)", progressBarIndex, delta); - if (g_msg_dialog_state != msgDialogOpen) + if (g_msg_dialog->state != msgDialogOpen) { return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED; } - if (progressBarIndex >= g_msg_dialog_progress_bar_count) + if (progressBarIndex >= g_msg_dialog->progress_bar_count) { return CELL_MSGDIALOG_ERROR_PARAM; } - CallAfter([=]() - { - MsgDialogProgressBarInc(progressBarIndex, delta); - }); + g_msg_dialog->ProgressBarInc(progressBarIndex, delta); + return CELL_OK; } + +void cellSysutil_MsgDialog_init() +{ + REG_FUNC(cellSysutil, cellMsgDialogOpen2); + REG_FUNC(cellSysutil, cellMsgDialogOpenErrorCode); + REG_FUNC(cellSysutil, cellMsgDialogProgressBarSetMsg); + REG_FUNC(cellSysutil, cellMsgDialogProgressBarReset); + REG_FUNC(cellSysutil, cellMsgDialogProgressBarInc); + REG_FUNC(cellSysutil, cellMsgDialogClose); + REG_FUNC(cellSysutil, cellMsgDialogAbort); +} diff --git a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h index 3ce4d78e0b..25c1434fcc 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h +++ b/rpcs3/Emu/SysCalls/Modules/cellMsgDialog.h @@ -6,7 +6,7 @@ enum CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED = 0x8002b302, }; -enum CellMsgDialogType +enum CellMsgDialogType : u32 { CELL_MSGDIALOG_DIALOG_TYPE_ERROR = 0x00000000, CELL_MSGDIALOG_DIALOG_TYPE_NORMAL = 0x00000001, @@ -16,28 +16,28 @@ enum CellMsgDialogType CELL_MSGDIALOG_DEFAULT_CURSOR_NO = 0x00000100, }; -enum +enum : u32 { CELL_MSGDIALOG_TYPE_SE_TYPE = 0x1, CELL_MSGDIALOG_TYPE_SE_TYPE_ERROR = 0 << 0, CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL = 1 << 0, }; -enum +enum : u32 { CELL_MSGDIALOG_TYPE_SE_MUTE = 0x2, CELL_MSGDIALOG_TYPE_SE_MUTE_OFF = 0 << 1, CELL_MSGDIALOG_TYPE_SE_MUTE_ON = 1 << 1, }; -enum +enum : u32 { CELL_MSGDIALOG_TYPE_BG = 0x4, CELL_MSGDIALOG_TYPE_BG_VISIBLE = 0 << 2, CELL_MSGDIALOG_TYPE_BG_INVISIBLE = 1 << 2, }; -enum +enum : u32 { CELL_MSGDIALOG_TYPE_BUTTON_TYPE = 0x70, CELL_MSGDIALOG_TYPE_BUTTON_TYPE_NONE = 0 << 4, @@ -45,14 +45,14 @@ enum CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK = 2 << 4, }; -enum +enum : u32 { CELL_MSGDIALOG_TYPE_DISABLE_CANCEL = 0x80, CELL_MSGDIALOG_TYPE_DISABLE_CANCEL_OFF = 0 << 7, CELL_MSGDIALOG_TYPE_DISABLE_CANCEL_ON = 1 << 7, }; -enum +enum : u32 { CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR = 0x300, CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_NONE = 0 << 8, @@ -61,7 +61,7 @@ enum CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_OK = 0 << 8, }; -enum +enum : u32 { CELL_MSGDIALOG_TYPE_PROGRESSBAR = 0x3000, CELL_MSGDIALOG_TYPE_PROGRESSBAR_NONE = 0 << 12, @@ -69,7 +69,8 @@ enum CELL_MSGDIALOG_TYPE_PROGRESSBAR_DOUBLE = 2 << 12, }; -enum +// MsgDialog Button Type +enum : s32 { CELL_MSGDIALOG_BUTTON_NONE = -1, CELL_MSGDIALOG_BUTTON_INVALID = 0, @@ -79,22 +80,32 @@ enum CELL_MSGDIALOG_BUTTON_ESCAPE = 3, }; -typedef void(CellMsgDialogCallback)(s32 buttonType, u32 userData); +typedef void(CellMsgDialogCallback)(s32 buttonType, vm::ptr userData); -s32 cellMsgDialogOpen2(u32 type, vm::ptr msgString, vm::ptr callback, u32 userData, u32 extParam); -s32 cellMsgDialogOpenErrorCode(u32 errorCode, vm::ptr callback, u32 userData, u32 extParam); +enum MsgDialogState +{ + msgDialogNone, + msgDialogOpen, + msgDialogClose, + msgDialogAbort, +}; -s32 cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::ptr msgString); -s32 cellMsgDialogProgressBarReset(u32 progressBarIndex); -s32 cellMsgDialogProgressBarInc(u32 progressBarIndex, u32 delta); -s32 cellMsgDialogClose(float delay); -s32 cellMsgDialogAbort(); +struct MsgDialogInstance +{ + std::atomic state; -typedef void(*MsgDialogCreateCb)(u32 type, const char* msg, u64& status); -typedef void(*MsgDialogDestroyCb)(); -typedef void(*MsgDialogProgressBarSetMsgCb)(u32 progressBarIndex, const char* msg); -typedef void(*MsgDialogProgressBarResetCb)(u32 progressBarIndex); -typedef void(*MsgDialogProgressBarIncCb)(u32 progressBarIndex, u32 delta); + s32 status = 0; + u64 wait_until = 0; + u32 progress_bar_count = 0; -void SetMsgDialogCallbacks(MsgDialogCreateCb ccb, MsgDialogDestroyCb dcb, MsgDialogProgressBarSetMsgCb pbscb, MsgDialogProgressBarResetCb pbrcb, MsgDialogProgressBarIncCb pbicb); -void MsgDialogClose(); + MsgDialogInstance(); + virtual ~MsgDialogInstance() = default; + + virtual void Close(); + + virtual void Create(u32 type, std::string msg) = 0; + virtual void Destroy() = 0; + virtual void ProgressBarSetMsg(u32 progressBarIndex, std::string msg) = 0; + virtual void ProgressBarReset(u32 progressBarIndex) = 0; + virtual void ProgressBarInc(u32 progressBarIndex, u32 delta) = 0; +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index 162e7a6ee9..4f5ece6bfb 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -4,7 +4,10 @@ #include "Emu/IdManager.h" #include "Emu/SysCalls/Modules.h" +extern "C" +{ #include "stblib/stb_image.h" +} #include "Emu/FS/VFS.h" #include "Emu/FS/vfsFileBase.h" @@ -17,7 +20,7 @@ extern Module cellPngDec; s32 pngDecCreate( vm::ptr mainHandle, vm::ptr param, - vm::ptr ext = vm::ptr::make(0)) + vm::ptr ext = vm::null) { // alloc memory (should probably use param->cbCtrlMallocFunc) auto dec = CellPngDecMainHandle::make(Memory.Alloc(sizeof(PngDecoder), 128)); @@ -58,8 +61,8 @@ s32 pngDecOpen( vm::ptr subHandle, vm::ptr src, vm::ptr openInfo, - vm::ptr cb = vm::ptr::make(0), - vm::ptr param = vm::ptr::make(0)) + vm::ptr cb = vm::null, + vm::ptr param = vm::null) { // alloc memory (should probably use dec->malloc) auto stream = CellPngDecSubHandle::make(Memory.Alloc(sizeof(PngStream), 128)); @@ -125,7 +128,7 @@ s32 pngDecClose(CellPngDecSubHandle stream) s32 pngReadHeader( CellPngDecSubHandle stream, vm::ptr info, - vm::ptr extInfo = vm::ptr::make(0)) + vm::ptr extInfo = vm::null) { CellPngDecInfo& current_info = stream->info; @@ -191,8 +194,8 @@ s32 pngDecSetParameter( CellPngDecSubHandle stream, vm::ptr inParam, vm::ptr outParam, - vm::ptr extInParam = vm::ptr::make(0), - vm::ptr extOutParam = vm::ptr::make(0)) + vm::ptr extInParam = vm::null, + vm::ptr extOutParam = vm::null) { CellPngDecInfo& current_info = stream->info; CellPngDecOutParam& current_outParam = stream->outParam; @@ -237,8 +240,8 @@ s32 pngDecodeData( vm::ptr data, vm::ptr dataCtrlParam, vm::ptr dataOutInfo, - vm::ptr cbCtrlDisp = vm::ptr::make(0), - vm::ptr dispParam = vm::ptr::make(0)) + vm::ptr cbCtrlDisp = vm::null, + vm::ptr dispParam = vm::null) { dataOutInfo->status = CELL_PNGDEC_DEC_STATUS_STOP; @@ -365,8 +368,7 @@ s32 pngDecodeData( s32 cellPngDecCreate(vm::ptr mainHandle, vm::ptr threadInParam, vm::ptr threadOutParam) { - cellPngDec.Warning("cellPngDecCreate(mainHandle_addr=0x%x, threadInParam_addr=0x%x, threadOutParam_addr=0x%x)", - mainHandle.addr(), threadInParam.addr(), threadOutParam.addr()); + cellPngDec.Warning("cellPngDecCreate(mainHandle=**0x%x, threadInParam=*0x%x, threadOutParam=*0x%x)", mainHandle, threadInParam, threadOutParam); // create decoder if (auto res = pngDecCreate(mainHandle, threadInParam)) return res; @@ -384,8 +386,8 @@ s32 cellPngDecExtCreate( vm::ptr extThreadInParam, vm::ptr extThreadOutParam) { - cellPngDec.Warning("cellPngDecCreate(mainHandle_addr=0x%x, threadInParam_addr=0x%x, threadOutParam_addr=0x%x, extThreadInParam_addr=0x%x, extThreadOutParam_addr=0x%x)", - mainHandle.addr(), threadInParam.addr(), threadOutParam.addr(), extThreadInParam.addr(), extThreadOutParam.addr()); + cellPngDec.Warning("cellPngDecCreate(mainHandle=**0x%x, threadInParam=*0x%x, threadOutParam=*0x%x, extThreadInParam=*0x%x, extThreadOutParam=*0x%x)", + mainHandle, threadInParam, threadOutParam, extThreadInParam, extThreadOutParam); // create decoder if (auto res = pngDecCreate(mainHandle, threadInParam, extThreadInParam)) return res; @@ -400,7 +402,7 @@ s32 cellPngDecExtCreate( s32 cellPngDecDestroy(CellPngDecMainHandle mainHandle) { - cellPngDec.Warning("cellPngDecDestroy(mainHandle=0x%x)", mainHandle.addr()); + cellPngDec.Warning("cellPngDecDestroy(mainHandle=*0x%x)", mainHandle); // destroy decoder return pngDecDestroy(mainHandle); @@ -412,8 +414,7 @@ s32 cellPngDecOpen( vm::ptr src, vm::ptr openInfo) { - cellPngDec.Warning("cellPngDecOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x)", - mainHandle.addr(), subHandle.addr(), src.addr(), openInfo.addr()); + cellPngDec.Warning("cellPngDecOpen(mainHandle=*0x%x, subHandle=**0x%x, src=*0x%x, openInfo=*0x%x)", mainHandle, subHandle, src, openInfo); // create stream handle return pngDecOpen(mainHandle, subHandle, src, openInfo); @@ -427,8 +428,7 @@ s32 cellPngDecExtOpen( vm::ptr cbCtrlStrm, vm::ptr opnParam) { - cellPngDec.Warning("cellPngDecExtOpen(mainHandle=0x%x, subHandle_addr=0x%x, src_addr=0x%x, openInfo_addr=0x%x, cbCtrlStrm_addr=0x%x, opnParam_addr=0x%x)", - mainHandle.addr(), subHandle.addr(), src.addr(), openInfo.addr(), cbCtrlStrm.addr(), opnParam.addr()); + cellPngDec.Warning("cellPngDecExtOpen(mainHandle=*0x%x, subHandle=**0x%x, src=*0x%x, openInfo=*0x%x, cbCtrlStrm=*0x%x, opnParam=*0x%x)", mainHandle, subHandle, src, openInfo, cbCtrlStrm, opnParam); // create stream handle return pngDecOpen(mainHandle, subHandle, src, openInfo, cbCtrlStrm, opnParam); @@ -436,15 +436,14 @@ s32 cellPngDecExtOpen( s32 cellPngDecClose(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle) { - cellPngDec.Warning("cellPngDecClose(mainHandle=0x%x, subHandle=0x%x)", mainHandle.addr(), subHandle.addr()); + cellPngDec.Warning("cellPngDecClose(mainHandle=*0x%x, subHandle=*0x%x)", mainHandle, subHandle); return pngDecClose(subHandle); } s32 cellPngDecReadHeader(CellPngDecMainHandle mainHandle, CellPngDecSubHandle subHandle, vm::ptr info) { - cellPngDec.Warning("cellPngDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x)", - mainHandle.addr(), subHandle.addr(), info.addr()); + cellPngDec.Warning("cellPngDecReadHeader(mainHandle=*0x%x, subHandle=*0x%x, info=*0x%x)", mainHandle, subHandle, info); return pngReadHeader(subHandle, info); } @@ -455,8 +454,7 @@ s32 cellPngDecExtReadHeader( vm::ptr info, vm::ptr extInfo) { - cellPngDec.Warning("cellPngDecExtReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%x, extInfo_addr=0x%x)", - mainHandle.addr(), subHandle.addr(), info.addr(), extInfo.addr()); + cellPngDec.Warning("cellPngDecExtReadHeader(mainHandle=*0x%x, subHandle=*0x%x, info=*0x%x, extInfo=*0x%x)", mainHandle, subHandle, info, extInfo); return pngReadHeader(subHandle, info, extInfo); } @@ -467,8 +465,7 @@ s32 cellPngDecSetParameter( vm::ptr inParam, vm::ptr outParam) { - cellPngDec.Warning("cellPngDecSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x)", - mainHandle.addr(), subHandle.addr(), inParam.addr(), outParam.addr()); + cellPngDec.Warning("cellPngDecSetParameter(mainHandle=*0x%x, subHandle=*0x%x, inParam=*0x%x, outParam=*0x%x)", mainHandle, subHandle, inParam, outParam); return pngDecSetParameter(subHandle, inParam, outParam); } @@ -481,8 +478,7 @@ s32 cellPngDecExtSetParameter( vm::ptr extInParam, vm::ptr extOutParam) { - cellPngDec.Warning("cellPngDecExtSetParameter(mainHandle=0x%x, subHandle=0x%x, inParam_addr=0x%x, outParam_addr=0x%x, extInParam=0x%x, extOutParam=0x%x", - mainHandle.addr(), subHandle.addr(), inParam.addr(), outParam.addr(), extInParam.addr(), extOutParam.addr()); + cellPngDec.Warning("cellPngDecExtSetParameter(mainHandle=*0x%x, subHandle=*0x%x, inParam=*0x%x, outParam=*0x%x, extInParam=*0x%x, extOutParam=*0x%x", mainHandle, subHandle, inParam, outParam, extInParam, extOutParam); return pngDecSetParameter(subHandle, inParam, outParam, extInParam, extOutParam); } @@ -494,8 +490,8 @@ s32 cellPngDecDecodeData( vm::ptr dataCtrlParam, vm::ptr dataOutInfo) { - cellPngDec.Warning("cellPngDecDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x)", - mainHandle.addr(), subHandle.addr(), data.addr(), dataCtrlParam.addr(), dataOutInfo.addr()); + cellPngDec.Warning("cellPngDecDecodeData(mainHandle=*0x%x, subHandle=*0x%x, data=*0x%x, dataCtrlParam=*0x%x, dataOutInfo=*0x%x)", + mainHandle, subHandle, data, dataCtrlParam, dataOutInfo); return pngDecodeData(subHandle, data, dataCtrlParam, dataOutInfo); } @@ -509,8 +505,8 @@ s32 cellPngDecExtDecodeData( vm::ptr cbCtrlDisp, vm::ptr dispParam) { - cellPngDec.Warning("cellPngDecExtDecodeData(mainHandle=0x%x, subHandle=0x%x, data_addr=0x%x, dataCtrlParam_addr=0x%x, dataOutInfo_addr=0x%x, cbCtrlDisp_addr=0x%x, dispParam_addr=0x%x)", - mainHandle.addr(), subHandle.addr(), data.addr(), dataCtrlParam.addr(), dataOutInfo.addr(), cbCtrlDisp.addr(), dispParam.addr()); + cellPngDec.Warning("cellPngDecExtDecodeData(mainHandle=*0x%x, subHandle=*0x%x, data=*0x%x, dataCtrlParam=*0x%x, dataOutInfo=*0x%x, cbCtrlDisp=*0x%x, dispParam=*0x%x)", + mainHandle, subHandle, data, dataCtrlParam, dataOutInfo, cbCtrlDisp, dispParam); return pngDecodeData(subHandle, data, dataCtrlParam, dataOutInfo, cbCtrlDisp, dispParam); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index c280f9374f..3cda3208f7 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -603,7 +603,7 @@ void cellRescExit() if (IsPalTemporal()) { cellGcmSetSecondVFrequency(CELL_GCM_DISPLAY_FREQUENCY_DISABLE); - cellGcmSetVBlankHandler(vm::ptr::make(0)); + cellGcmSetVBlankHandler(vm::null); //GcmSysTypePrefix::cellGcmSetSecondVHandler(NULL); if (IsPalInterpolate()) @@ -770,7 +770,7 @@ int cellRescSetDisplayMode(u32 displayMode) videocfg->aspect = CELL_VIDEO_OUT_ASPECT_AUTO; videocfg->pitch = s_rescInternalInstance->m_dstPitch; - cellVideoOutConfigure(CELL_VIDEO_OUT_PRIMARY, videocfg, vm::ptr::make(0), 0); + cellVideoOutConfigure(CELL_VIDEO_OUT_PRIMARY, videocfg, vm::null, 0); if (IsPalInterpolate()) { @@ -780,20 +780,20 @@ int cellRescSetDisplayMode(u32 displayMode) cellGcmSetSecondVFrequency(CELL_GCM_DISPLAY_FREQUENCY_59_94HZ); //cellGcmSetVBlankHandler(IntrHandler50); //cellGcmSetSecondVHandler(IntrHandler60); - cellGcmSetFlipHandler(vm::ptr::make(0)); + cellGcmSetFlipHandler(vm::null); } else if (IsPalDrop()) { //InitLabels(); cellGcmSetSecondVFrequency(CELL_GCM_DISPLAY_FREQUENCY_59_94HZ); - cellGcmSetVBlankHandler(vm::ptr::make(0)); + cellGcmSetVBlankHandler(vm::null); //cellGcmSetSecondVHandler(IntrHandler60Drop); - cellGcmSetFlipHandler(vm::ptr::make(0)); + cellGcmSetFlipHandler(vm::null); } else if (IsPal60Hsync()) { cellGcmSetSecondVFrequency(CELL_GCM_DISPLAY_FREQUENCY_59_94HZ); - cellGcmSetVBlankHandler(vm::ptr::make(0)); + cellGcmSetVBlankHandler(vm::null); } if (s_rescInternalInstance->s_applicationVBlankHandler) SetVBlankHandler(s_rescInternalInstance->s_applicationVBlankHandler); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp b/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp index 5ca28a0f6c..1c2a7520d4 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSaveData.cpp @@ -7,322 +7,626 @@ #include "Emu/FS/VFS.h" #include "Emu/FS/vfsFile.h" #include "Emu/FS/vfsDir.h" +#include "Utilities/File.h" #include "Loader/PSF.h" #include "cellSaveData.h" -#ifdef _WIN32 - #include - #undef CreateFile -#else - #include - #include -#endif - extern Module cellSysutil; -// Auxiliary Classes -class sortSaveDataEntry +std::unique_ptr g_savedata_dialog; + +SaveDataDialogInstance::SaveDataDialogInstance() { - u32 sortType; - u32 sortOrder; +} + +// Auxiliary Classes +class SortSaveDataEntry +{ + const u32 m_type; + const u32 m_order; + public: - sortSaveDataEntry(u32 type, u32 order) : sortType(type), sortOrder(order) {} + SortSaveDataEntry(u32 type, u32 order) + : m_type(type) + , m_order(order) + { + } + bool operator()(const SaveDataEntry& entry1, const SaveDataEntry& entry2) const { - if (sortOrder == CELL_SAVEDATA_SORTORDER_DESCENT) + if (m_order == CELL_SAVEDATA_SORTORDER_DESCENT) { - if (sortType == CELL_SAVEDATA_SORTTYPE_MODIFIEDTIME) - return entry1.st_mtime_ >= entry2.st_mtime_; - if (sortType == CELL_SAVEDATA_SORTTYPE_SUBTITLE) + if (m_type == CELL_SAVEDATA_SORTTYPE_MODIFIEDTIME) + { + return entry1.mtime >= entry2.mtime; + } + + if (m_type == CELL_SAVEDATA_SORTTYPE_SUBTITLE) + { return entry1.subtitle >= entry2.subtitle; + } } - if (sortOrder == CELL_SAVEDATA_SORTORDER_ASCENT) + + if (m_order == CELL_SAVEDATA_SORTORDER_ASCENT) { - if (sortType == CELL_SAVEDATA_SORTTYPE_MODIFIEDTIME) - return entry1.st_mtime_ < entry2.st_mtime_; - if (sortType == CELL_SAVEDATA_SORTTYPE_SUBTITLE) + if (m_type == CELL_SAVEDATA_SORTTYPE_MODIFIEDTIME) + { + return entry1.mtime < entry2.mtime; + } + + if (m_type == CELL_SAVEDATA_SORTTYPE_SUBTITLE) + { return entry1.subtitle < entry2.subtitle; + } } + return true; } }; -// Auxiliary Functions -u64 getSaveDataSize(const std::string& dirName) +enum : u32 { - vfsDir dir(dirName); - if (!dir.IsOpened()) - return 0; + SAVEDATA_OP_AUTO_SAVE = 0, + SAVEDATA_OP_AUTO_LOAD = 1, + SAVEDATA_OP_LIST_AUTO_SAVE = 2, + SAVEDATA_OP_LIST_AUTO_LOAD = 3, + SAVEDATA_OP_LIST_SAVE = 4, + SAVEDATA_OP_LIST_LOAD = 5, + SAVEDATA_OP_FIXED_SAVE = 6, + SAVEDATA_OP_FIXED_LOAD = 7, - u64 totalSize = 0; - for(const DirEntryInfo* entry = dir.Read(); entry; entry = dir.Read()) { - if (entry->flags & DirEntry_TypeFile) { - vfsFile file(dirName+"/"+entry->name); - totalSize += file.GetSize(); - } - } - return totalSize; -} + SAVEDATA_OP_FIXED_DELETE = 14, +}; -void addSaveDataEntry(std::vector& saveEntries, const std::string& saveDir) +__noinline s32 savedata_op( + PPUThread& CPU, + u32 operation, + u32 version, + vm::ptr dirName, + u32 errDialog, + vm::ptr setList, + vm::ptr setBuf, + vm::ptr funcList, + vm::ptr funcFixed, + vm::ptr funcStat, + vm::ptr funcFile, + u32 container, + u32 unknown, // 0, 2, 6 + vm::ptr userdata, + u32 userId, + vm::ptr funcDone) { - // PSF parameters - vfsFile f(saveDir + "/PARAM.SFO"); - PSFLoader psf(f); - if(!psf.Load(false)) - return; + // TODO: check arguments - // PNG icon - std::string localPath; - Emu.GetVFS().GetDevice(saveDir + "/ICON0.PNG", localPath); + // try to lock the mutex (not sure how it originally works; std::try_to_lock makes it non-blocking) + std::unique_lock lock(g_savedata_dialog->mutex, std::try_to_lock); - u64 atime = 0; - u64 mtime = 0; - u64 ctime = 0; - - cellSysutil.Error("Running _stat in cellSaveData. Please report this to a RPCS3 developer!"); - - std::string real_path; - struct stat buf; - - Emu.GetVFS().GetDevice(f.GetPath(), real_path); - - if (stat(real_path.c_str(), &buf) != 0) - cellSysutil.Error("stat failed! (%s)", real_path.c_str()); - else + if (!lock) { - atime = buf.st_atime; - mtime = buf.st_mtime; - ctime = buf.st_ctime; + return CELL_SAVEDATA_ERROR_BUSY; } - SaveDataEntry saveEntry; - saveEntry.dirName = psf.GetString("SAVEDATA_DIRECTORY"); - saveEntry.listParam = psf.GetString("SAVEDATA_LIST_PARAM"); - saveEntry.title = psf.GetString("TITLE"); - saveEntry.subtitle = psf.GetString("SUB_TITLE"); - saveEntry.details = psf.GetString("DETAIL"); - saveEntry.sizeKB = (u32)(getSaveDataSize(saveDir) / 1024); - saveEntry.st_atime_ = atime; - saveEntry.st_mtime_ = mtime; - saveEntry.st_ctime_ = ctime; - saveEntry.iconBuf = NULL; // TODO: Here should be the PNG buffer - saveEntry.iconBufSize = 0; // TODO: Size of the PNG file - saveEntry.isNew = false; + std::string base_dir = "/dev_hdd0/home/00000001/savedata/"; // TODO: Get the path of the current or specified user - saveEntries.push_back(saveEntry); -} + vm::stackvar result(CPU); -void addNewSaveDataEntry(std::vector& saveEntries, vm::ptr newData) -{ - SaveDataEntry saveEntry; - saveEntry.dirName = newData->dirName.get_ptr(); - saveEntry.title = newData->icon->title.get_ptr(); - saveEntry.subtitle = newData->icon->title.get_ptr(); - saveEntry.iconBuf = newData->icon->iconBuf.get_ptr(); - saveEntry.iconBufSize = newData->icon->iconBufSize; - saveEntry.isNew = true; - // TODO: Add information stored in newData->iconPosition. (It's not very relevant) + result->userdata = userdata; // probably should be assigned only once (allows the callback to change it) - saveEntries.push_back(saveEntry); -} + SaveDataEntry save_entry; -u32 focusSaveDataEntry(const std::vector& saveEntries, u32 focusPosition) -{ - // TODO: Get the correct index. Right now, this returns the first element of the list. - return 0; -} - -void setSaveDataList(std::vector& saveEntries, vm::ptr fixedList, u32 fixedListNum) -{ - std::vector::iterator entry = saveEntries.begin(); - while (entry != saveEntries.end()) + if (setList) { - bool found = false; - for (u32 j = 0; j < fixedListNum; j++) + std::vector save_entries; + + vm::stackvar listGet(CPU); + + listGet->dirNum = 0; + listGet->dirListNum = 0; + listGet->dirList.set(setBuf->buf.addr()); + memset(listGet->reserved, 0, sizeof(listGet->reserved)); + + const auto prefix_list = fmt::split(setList->dirNamePrefix.get_ptr(), { "|" }); + + for (const auto entry : vfsDir(base_dir)) { - if (entry->dirName == (char*)fixedList[j].dirName) + if (!(entry->flags & DirEntry_TypeDir)) { - found = true; - break; + continue; + } + + for (const auto& prefix : prefix_list) + { + if (entry->name.substr(0, prefix.size()) == prefix) + { + // Count the amount of matches and the amount of listed directories + if (listGet->dirListNum++ < setBuf->dirListMax) + { + listGet->dirNum++; + + // PSF parameters + vfsFile f(base_dir + entry->name + "/PARAM.SFO"); + const PSFLoader psf(f); + + if (!psf) + { + break; + } + + SaveDataEntry save_entry2; + save_entry2.dirName = psf.GetString("SAVEDATA_DIRECTORY"); + save_entry2.listParam = psf.GetString("SAVEDATA_LIST_PARAM"); + save_entry2.title = psf.GetString("TITLE"); + save_entry2.subtitle = psf.GetString("SUB_TITLE"); + save_entry2.details = psf.GetString("DETAIL"); + + save_entry2.size = 0; + + for (const auto entry2 : vfsDir(base_dir + entry->name)) + { + save_entry2.size += entry2->size; + } + + save_entry2.atime = entry->access_time; + save_entry2.mtime = entry->modify_time; + save_entry2.ctime = entry->create_time; + //save_entry2.iconBuf = NULL; // TODO: Here should be the PNG buffer + //save_entry2.iconBufSize = 0; // TODO: Size of the PNG file + save_entry2.isNew = false; + + save_entries.push_back(save_entry2); + } + + break; + } } } - if (!found) - entry = saveEntries.erase(entry); - else - entry++; - } -} -void setSaveDataFixed(std::vector& saveEntries, vm::ptr fixedSet) -{ - std::vector::iterator entry = saveEntries.begin(); - while (entry != saveEntries.end()) - { - if (entry->dirName == fixedSet->dirName.get_ptr()) - entry = saveEntries.erase(entry); - else - entry++; - } + // Sort the entries + std::sort(save_entries.begin(), save_entries.end(), SortSaveDataEntry(setList->sortType, setList->sortOrder)); - if (saveEntries.size() == 0) - { - SaveDataEntry entry; - entry.dirName = fixedSet->dirName.get_ptr(); - entry.isNew = true; - saveEntries.push_back(entry); - } + // Fill the listGet->dirList array + auto dir_list = listGet->dirList.get_ptr(); - if (fixedSet->newIcon) - { - saveEntries[0].iconBuf = fixedSet->newIcon->iconBuf.get_ptr(); - saveEntries[0].iconBufSize = fixedSet->newIcon->iconBufSize; - saveEntries[0].title = fixedSet->newIcon->title.get_ptr(); - saveEntries[0].subtitle = fixedSet->newIcon->title.get_ptr(); - } -} + for (const auto& entry : save_entries) + { + auto& dir = *dir_list++; + strcpy_trunc(dir.dirName, entry.dirName); + strcpy_trunc(dir.listParam, entry.listParam); + memset(dir.reserved, 0, sizeof(dir.reserved)); + } -void getSaveDataStat(SaveDataEntry entry, vm::ptr statGet) -{ - if (entry.isNew) - statGet->isNewData = CELL_SAVEDATA_ISNEWDATA_YES; - else - statGet->isNewData = CELL_SAVEDATA_ISNEWDATA_NO; + s32 selected = -1; - statGet->bind = 0; // TODO ? - statGet->sizeKB = entry.sizeKB; - statGet->hddFreeSizeKB = 40000000; // 40 GB. TODO ? - statGet->sysSizeKB = 0; // TODO: This is the size of PARAM.SFO + PARAM.PDF - statGet->dir.st_atime_ = 0; // TODO ? - statGet->dir.st_mtime_ = 0; // TODO ? - statGet->dir.st_ctime_ = 0; // TODO ? - strcpy_trunc(statGet->dir.dirName, entry.dirName); + if (funcList) + { + vm::stackvar listSet(CPU); - statGet->getParam.attribute = 0; // TODO ? - strcpy_trunc(statGet->getParam.title, entry.title); - strcpy_trunc(statGet->getParam.subTitle, entry.subtitle); - strcpy_trunc(statGet->getParam.detail, entry.details); - strcpy_trunc(statGet->getParam.listParam, entry.listParam); + // List Callback + funcList(CPU, result, listGet, listSet); - statGet->fileNum = 0; - statGet->fileList.set(0); - statGet->fileListNum = 0; - std::string saveDir = "/dev_hdd0/home/00000001/savedata/" + entry.dirName; // TODO: Get the path of the current user - vfsDir dir(saveDir); - if (!dir.IsOpened()) - return; + if (result->result < 0) + { + return CELL_SAVEDATA_ERROR_CBRESULT; + } - std::vector fileEntries; - for(const DirEntryInfo* dirEntry = dir.Read(); dirEntry; dirEntry = dir.Read()) { - if (dirEntry->flags & DirEntry_TypeFile) { - if (dirEntry->name == "PARAM.SFO" || dirEntry->name == "PARAM.PFD") - continue; + // Clean save data list + save_entries.erase(std::remove_if(save_entries.begin(), save_entries.end(), [&listSet](const SaveDataEntry& entry) -> bool + { + for (u32 i = 0; i < listSet->fixedListNum; i++) + { + if (entry.dirName == listSet->fixedList[i].dirName) + { + return false; + } + } - statGet->fileNum++; - statGet->fileListNum++; - CellSaveDataFileStat fileEntry; - vfsFile file(saveDir + "/" + dirEntry->name); + return true; + }), save_entries.end()); - if (dirEntry->name == "ICON0.PNG") - fileEntry.fileType = CELL_SAVEDATA_FILETYPE_CONTENT_ICON0; - else if (dirEntry->name == "ICON1.PAM") - fileEntry.fileType = CELL_SAVEDATA_FILETYPE_CONTENT_ICON1; - else if (dirEntry->name == "PIC1.PNG") - fileEntry.fileType = CELL_SAVEDATA_FILETYPE_CONTENT_PIC1; - else if (dirEntry->name == "SND0.AT3") - fileEntry.fileType = CELL_SAVEDATA_FILETYPE_CONTENT_SND0; + // Focus save data + s32 focused = -1; - fileEntry.st_size = file.GetSize(); - fileEntry.st_atime_ = 0; // TODO ? - fileEntry.st_mtime_ = 0; // TODO ? - fileEntry.st_ctime_ = 0; // TODO ? - strcpy_trunc(fileEntry.fileName, dirEntry->name); + switch (const u32 pos_type = listSet->focusPosition) + { + case CELL_SAVEDATA_FOCUSPOS_DIRNAME: + { + for (s32 i = 0; i < save_entries.size(); i++) + { + if (save_entries[i].dirName == listSet->focusDirName.get_ptr()) + { + focused = i; + break; + } + } - fileEntries.push_back(fileEntry); + break; + } + case CELL_SAVEDATA_FOCUSPOS_LISTHEAD: + { + focused = save_entries.empty() ? -1 : 0; + break; + } + case CELL_SAVEDATA_FOCUSPOS_LISTTAIL: + { + focused = save_entries.size() - 1; + break; + } + case CELL_SAVEDATA_FOCUSPOS_LATEST: + { + s64 max = INT64_MIN; + + for (s32 i = 0; i < save_entries.size(); i++) + { + if (save_entries[i].mtime > max) + { + focused = i; + max = save_entries[i].mtime; + } + } + + break; + } + case CELL_SAVEDATA_FOCUSPOS_OLDEST: + { + s64 min = INT64_MAX; + + for (s32 i = 0; i < save_entries.size(); i++) + { + if (save_entries[i].mtime < min) + { + focused = i; + min = save_entries[i].mtime; + } + } + + break; + } + case CELL_SAVEDATA_FOCUSPOS_NEWDATA: + { + break; + } + default: + { + cellSysutil.Error("savedata_op(): unknown listSet->focusPosition (0x%x)", pos_type); + return CELL_SAVEDATA_ERROR_PARAM; + } + } + + // Display Save Data List + selected = g_savedata_dialog->ShowSaveDataList(save_entries, focused, listSet); + + if (selected == -1) + { + if (listSet->newData) + { + save_entry.dirName = listSet->newData->dirName.get_ptr(); + } + else + { + return CELL_OK; // ??? + } + } + } + + if (funcFixed) + { + vm::stackvar fixedSet(CPU); + + // Fixed Callback + funcFixed(CPU, result, listGet, fixedSet); + + if (result->result < 0) + { + return CELL_SAVEDATA_ERROR_CBRESULT; + } + + for (s32 i = 0; i < save_entries.size(); i++) + { + if (save_entries[i].dirName == fixedSet->dirName.get_ptr()) + { + selected = i; + break; + } + } + + if (selected == -1) + { + save_entry.dirName = fixedSet->dirName.get_ptr(); + } + } + + if (selected >= 0) + { + if (selected < save_entries.size()) + { + save_entry.dirName = std::move(save_entries[selected].dirName); + } + else + { + throw __FUNCTION__; + } } } - statGet->fileList.set((u32)Memory.Alloc(sizeof(CellSaveDataFileStat) * fileEntries.size(), 8)); - for (u32 i = 0; i < fileEntries.size(); i++) { - CellSaveDataFileStat *dst = &statGet->fileList[i]; - memcpy(dst, &fileEntries[i], sizeof(CellSaveDataFileStat)); - } -} - -s32 modifySaveDataFiles(vm::ptr funcFile, vm::ptr result, const std::string& saveDataDir) -{ - vm::var fileGet; - vm::var fileSet; - - if (!Emu.GetVFS().ExistsDir(saveDataDir)) - Emu.GetVFS().CreateDir(saveDataDir); - - fileGet->excSize = 0; - while (true) + if (dirName) { - funcFile(result, fileGet, fileSet); - if (result->result < 0) { - cellSysutil.Error("modifySaveDataFiles: CellSaveDataFileCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. + save_entry.dirName = dirName.get_ptr(); + } + + std::string dir_path = base_dir + save_entry.dirName + "/"; + std::string sfo_path = dir_path + "PARAM.SFO"; + + PSFLoader psf; + + // Load PARAM.SFO + { + vfsFile f(sfo_path); + psf.Load(f); + } + + // Get save stats + { + vm::stackvar statGet(CPU); + vm::stackvar statSet(CPU); + + std::string dir_local_path; + + Emu.GetVFS().GetDevice(dir_path, dir_local_path); + + fs::stat_t dir_info; + fs::stat(dir_local_path, dir_info); + + statGet->hddFreeSizeKB = 40 * 1024 * 1024; // 40 GB + statGet->isNewData = save_entry.isNew = !psf; + + statGet->dir.atime = save_entry.atime = dir_info.atime; + statGet->dir.mtime = save_entry.mtime = dir_info.mtime; + statGet->dir.ctime = save_entry.ctime = dir_info.ctime; + strcpy_trunc(statGet->dir.dirName, save_entry.dirName); + + statGet->getParam.attribute = psf.GetInteger("ATTRIBUTE"); // ??? + strcpy_trunc(statGet->getParam.title, save_entry.title = psf.GetString("TITLE")); + strcpy_trunc(statGet->getParam.subTitle, save_entry.subtitle = psf.GetString("SUB_TITLE")); + strcpy_trunc(statGet->getParam.detail, save_entry.details = psf.GetString("DETAIL")); + strcpy_trunc(statGet->getParam.listParam, save_entry.listParam = psf.GetString("SAVEDATA_LIST_PARAM")); + + statGet->bind = 0; + statGet->sizeKB = save_entry.size / 1024; + statGet->sysSizeKB = 0; // This is the size of system files, but PARAM.SFO is very small and PARAM.PDF is not used + + statGet->fileNum = 0; + statGet->fileList.set(setBuf->buf.addr()); + statGet->fileListNum = 0; + memset(statGet->reserved, 0, sizeof(statGet->reserved)); + + auto file_list = statGet->fileList.get_ptr(); + + for (const auto entry : vfsDir(dir_path)) + { + // only files, system files ignored, fileNum is limited by setBuf->fileListMax + if (entry->flags & DirEntry_TypeFile && entry->name != "PARAM.SFO" && statGet->fileListNum++ < setBuf->fileListMax) + { + statGet->fileNum++; + + auto& file = *file_list++; + + if (entry->name == "ICON0.PNG") + { + file.fileType = CELL_SAVEDATA_FILETYPE_CONTENT_ICON0; + } + else if (entry->name == "ICON1.PAM") + { + file.fileType = CELL_SAVEDATA_FILETYPE_CONTENT_ICON1; + } + else if (entry->name == "PIC1.PNG") + { + file.fileType = CELL_SAVEDATA_FILETYPE_CONTENT_PIC1; + } + else if (entry->name == "SND0.AT3") + { + file.fileType = CELL_SAVEDATA_FILETYPE_CONTENT_SND0; + } + else if (psf.GetInteger("*" + entry->name)) // let's put the list of protected files in PARAM.SFO (int param = 1 if protected) + { + file.fileType = CELL_SAVEDATA_FILETYPE_SECUREFILE; + } + else + { + file.fileType = CELL_SAVEDATA_FILETYPE_NORMALFILE; + } + + file.size = entry->size; + file.atime = entry->access_time; + file.mtime = entry->modify_time; + file.ctime = entry->create_time; + strcpy_trunc(file.fileName, entry->name); + } + } + + // Stat Callback + funcStat(CPU, result, statGet, statSet); + + if (result->result < 0) + { return CELL_SAVEDATA_ERROR_CBRESULT; } - if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST || result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM) { + + // Update PARAM.SFO + if (statSet->setParam) + { + psf.Clear(); + psf.SetString("ACCOUNT_ID", ""); // ??? + psf.SetInteger("ATTRIBUTE", statSet->setParam->attribute); + psf.SetString("CATEGORY", "SD"); // ??? + psf.SetString("PARAMS", ""); // ??? + psf.SetString("PARAMS2", ""); // ??? + psf.SetInteger("PARENTAL_LEVEL", 0); // ??? + psf.SetString("DETAIL", statSet->setParam->detail); + psf.SetString("SAVEDATA_DIRECTORY", save_entry.dirName); + psf.SetString("SAVEDATA_LIST_PARAM", statSet->setParam->listParam); + psf.SetString("SUB_TITLE", statSet->setParam->subTitle); + psf.SetString("TITLE", statSet->setParam->title); + } + + switch (const u32 mode = statSet->reCreateMode & 0xffff) + { + case CELL_SAVEDATA_RECREATE_NO: + case CELL_SAVEDATA_RECREATE_NO_NOBROKEN: + { + break; + } + case CELL_SAVEDATA_RECREATE_YES: + case CELL_SAVEDATA_RECREATE_YES_RESET_OWNER: + { + // kill it with fire + for (const auto entry : vfsDir(dir_path)) + { + if (entry->flags & DirEntry_TypeFile) + { + Emu.GetVFS().RemoveFile(dir_path + entry->name); + } + } + + break; + } + default: + { + cellSysutil.Error("savedata_op(): unknown statSet->reCreateMode (0x%x)", statSet->reCreateMode); + return CELL_SAVEDATA_ERROR_PARAM; + } + } + } + + // Create save directory if necessary + if (save_entry.isNew && !Emu.GetVFS().CreateDir(dir_path)) + { + // Let's ignore this error for now + } + + // Enter the loop where the save files are read/created/deleted + vm::stackvar fileGet(CPU); + vm::stackvar fileSet(CPU); + + fileGet->excSize = 0; + memset(fileGet->reserved, 0, sizeof(fileGet->reserved)); + + while (true) + { + funcFile(CPU, result, fileGet, fileSet); + + if (result->result < 0) + { + return CELL_SAVEDATA_ERROR_CBRESULT; + } + + if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST || result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM) + { break; } - std::string filepath = saveDataDir + '/'; - vfsStream* file = NULL; - void* buf = fileSet->fileBuf.get_ptr(); + std::string file_path; - switch ((u32)fileSet->fileType) + switch (const u32 type = fileSet->fileType) { - case CELL_SAVEDATA_FILETYPE_SECUREFILE: filepath += fileSet->fileName.get_ptr(); break; - case CELL_SAVEDATA_FILETYPE_NORMALFILE: filepath += fileSet->fileName.get_ptr(); break; - case CELL_SAVEDATA_FILETYPE_CONTENT_ICON0: filepath += "ICON0.PNG"; break; - case CELL_SAVEDATA_FILETYPE_CONTENT_ICON1: filepath += "ICON1.PAM"; break; - case CELL_SAVEDATA_FILETYPE_CONTENT_PIC1: filepath += "PIC1.PNG"; break; - case CELL_SAVEDATA_FILETYPE_CONTENT_SND0: filepath += "SND0.AT3"; break; - - default: - cellSysutil.Error("modifySaveDataFiles: Unknown fileType! Aborting..."); - return CELL_SAVEDATA_ERROR_PARAM; + case CELL_SAVEDATA_FILETYPE_SECUREFILE: + case CELL_SAVEDATA_FILETYPE_NORMALFILE: + { + file_path = fileSet->fileName.get_ptr(); + break; } - switch ((u32)fileSet->fileOperation) + case CELL_SAVEDATA_FILETYPE_CONTENT_ICON0: + { + file_path = "ICON0.PNG"; + break; + } + + case CELL_SAVEDATA_FILETYPE_CONTENT_ICON1: + { + file_path = "ICON1.PAM"; + break; + } + + case CELL_SAVEDATA_FILETYPE_CONTENT_PIC1: + { + file_path = "PIC1.PNG"; + break; + } + + case CELL_SAVEDATA_FILETYPE_CONTENT_SND0: + { + file_path = "SND0.AT3"; + break; + } + + default: + { + cellSysutil.Error("savedata_op(): unknown fileSet->fileType (0x%x)", type); + return CELL_SAVEDATA_ERROR_PARAM; + } + } + + psf.SetInteger("*" + file_path, fileSet->fileType.data() == se32(CELL_SAVEDATA_FILETYPE_SECUREFILE)); + + std::string local_path; + + Emu.GetVFS().GetDevice(dir_path + file_path, local_path); + + switch (const u32 op = fileSet->fileOperation) { case CELL_SAVEDATA_FILEOP_READ: - file = Emu.GetVFS().OpenFile(filepath, vfsRead); - fileGet->excSize = (u32)file->Read(buf, (u32)std::min(fileSet->fileSize, fileSet->fileBufSize)); // TODO: This may fail for big files because of the dest pointer. + { + fs::file file(local_path, o_read); + file.seek(fileSet->fileOffset); + fileGet->excSize = static_cast(file.read(fileSet->fileBuf.get_ptr(), std::min(fileSet->fileSize, fileSet->fileBufSize))); break; - - case CELL_SAVEDATA_FILEOP_WRITE: - Emu.GetVFS().CreateFile(filepath); - file = Emu.GetVFS().OpenFile(filepath, vfsWrite); - fileGet->excSize = (u32)file->Write(buf, (u32)std::min(fileSet->fileSize, fileSet->fileBufSize)); // TODO: This may fail for big files because of the dest pointer. - break; - - case CELL_SAVEDATA_FILEOP_DELETE: - Emu.GetVFS().RemoveFile(filepath); - fileGet->excSize = 0; - break; - - case CELL_SAVEDATA_FILEOP_WRITE_NOTRUNC: - cellSysutil.Todo("modifySaveDataFiles: CELL_SAVEDATA_FILEOP_WRITE_NOTRUNC"); - break; - - default: - cellSysutil.Error("modifySaveDataFiles: Unknown fileOperation! Aborting..."); - return CELL_SAVEDATA_ERROR_PARAM; } - if (file && file->IsOpened()) - file->Close(); + case CELL_SAVEDATA_FILEOP_WRITE: + { + fs::file file(local_path, o_write | o_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, from_cur)); // truncate + break; + } + + case CELL_SAVEDATA_FILEOP_DELETE: + { + fs::remove_file(local_path); + fileGet->excSize = 0; + break; + } + + case CELL_SAVEDATA_FILEOP_WRITE_NOTRUNC: + { + fs::file file(local_path, o_write | o_create); + file.seek(fileSet->fileOffset); + fileGet->excSize = static_cast(file.write(fileSet->fileBuf.get_ptr(), std::min(fileSet->fileSize, fileSet->fileBufSize))); + break; + } + + default: + { + cellSysutil.Error("savedata_op(): unknown fileSet->fileOperation (0x%x)", op); + return CELL_SAVEDATA_ERROR_PARAM; + } + } } + + // Write PARAM.SFO + if (psf) + { + vfsFile f(sfo_path, vfsWriteNew); + psf.Save(f); + } + return CELL_OK; } - // Functions s32 cellSaveDataListSave2( + PPUThread& CPU, u32 version, vm::ptr setList, vm::ptr setBuf, @@ -332,88 +636,14 @@ s32 cellSaveDataListSave2( u32 container, vm::ptr userdata) { - cellSysutil.Warning("cellSaveDataListSave2(version=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcList_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", - version, setList.addr(), setBuf.addr(), funcList.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); + cellSysutil.Warning("cellSaveDataListSave2(version=%d, setList=*0x%x, setBuf=*0x%x, funcList=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)", + version, setList, setBuf, funcList, funcStat, funcFile, container, userdata); - vm::var result; - vm::var listGet; - vm::var listSet; - vm::var statGet; - vm::var statSet; - - std::string saveBaseDir = "/dev_hdd0/home/00000001/savedata/"; // TODO: Get the path of the current user - vfsDir dir(saveBaseDir); - if(!dir.IsOpened()) - return CELL_SAVEDATA_ERROR_INTERNAL; - - std::string dirNamePrefix = setList->dirNamePrefix.get_ptr(); - std::vector saveEntries; - - for(const DirEntryInfo* entry = dir.Read(); entry; entry = dir.Read()) - { - if (entry->flags & DirEntry_TypeDir && entry->name.substr(0,dirNamePrefix.size()) == dirNamePrefix) - { - // Count the amount of matches and the amount of listed directories - listGet->dirListNum++; - if (listGet->dirListNum > setBuf->dirListMax) - continue; - listGet->dirNum++; - - std::string saveDir = saveBaseDir + entry->name; - addSaveDataEntry(saveEntries, saveDir); - } - } - - // Sort the entries and fill the listGet->dirList array - std::sort(saveEntries.begin(), saveEntries.end(), sortSaveDataEntry(setList->sortType, setList->sortOrder)); - listGet->dirList.set(setBuf->buf.addr()); - auto dirList = listGet->dirList.get_ptr(); - - for (u32 i=0; iresult < 0) { - cellSysutil.Error("cellSaveDataListSave2: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. - return CELL_SAVEDATA_ERROR_CBRESULT; - } - - setSaveDataList(saveEntries, listSet->fixedList, listSet->fixedListNum); - if (listSet->newData) - addNewSaveDataEntry(saveEntries, listSet->newData); - if (saveEntries.size() == 0) { - cellSysutil.Error("cellSaveDataListSave2: No save entries found!"); // TODO: Find a better way to handle this error - return CELL_OK; - } - - u32 focusIndex = focusSaveDataEntry(saveEntries, listSet->focusPosition); - // TODO: Display the dialog here - u32 selectedIndex = focusIndex; // TODO: Until the dialog is implemented, select always the focused entry - getSaveDataStat(saveEntries[selectedIndex], statGet); - result->userdata = userdata; - - funcStat(result, statGet, statSet); - Memory.Free(statGet->fileList.addr()); - if (result->result < 0) { - cellSysutil.Error("cellSaveDataListLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. - return CELL_SAVEDATA_ERROR_CBRESULT; - } - - /*if (statSet->setParam) - addNewSaveDataEntry(saveEntries, (u32)listSet->newData.addr()); // TODO: This *is* wrong - */ - - // Enter the loop where the save files are read/created/deleted. - s32 ret = modifySaveDataFiles(funcFile, result, saveBaseDir + (char*)statGet->dir.dirName); - - return ret; + return savedata_op(CPU, SAVEDATA_OP_LIST_SAVE, version, vm::null, 1, setList, setBuf, funcList, vm::null, funcStat, funcFile, container, 2, userdata, 0, vm::null); } s32 cellSaveDataListLoad2( + PPUThread& CPU, u32 version, vm::ptr setList, vm::ptr setBuf, @@ -423,89 +653,14 @@ s32 cellSaveDataListLoad2( u32 container, vm::ptr userdata) { - cellSysutil.Warning("cellSaveDataListLoad2(version=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcList_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", - version, setList.addr(), setBuf.addr(), funcList.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); + cellSysutil.Warning("cellSaveDataListLoad2(version=%d, setList=*0x%x, setBuf=*0x%x, funcList=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)", + version, setList, setBuf, funcList, funcStat, funcFile, container, userdata); - vm::var result; - vm::var listGet; - vm::var listSet; - vm::var statGet; - vm::var statSet; - - std::string saveBaseDir = "/dev_hdd0/home/00000001/savedata/"; // TODO: Get the path of the current user - vfsDir dir(saveBaseDir); - - if(!dir.IsOpened()) - return CELL_SAVEDATA_ERROR_INTERNAL; - - std::string dirNamePrefix = setList->dirNamePrefix.get_ptr(); - std::vector saveEntries; - - for(const DirEntryInfo* entry = dir.Read(); entry; entry = dir.Read()) - { - if (entry->flags & DirEntry_TypeDir && entry->name.substr(0,dirNamePrefix.size()) == dirNamePrefix) - { - // Count the amount of matches and the amount of listed directories - listGet->dirListNum++; - if (listGet->dirListNum > setBuf->dirListMax) - continue; - listGet->dirNum++; - - std::string saveDir = saveBaseDir + entry->name; - addSaveDataEntry(saveEntries, saveDir); - } - } - - // Sort the entries and fill the listGet->dirList array - std::sort(saveEntries.begin(), saveEntries.end(), sortSaveDataEntry(setList->sortType, setList->sortOrder)); - listGet->dirList.set(setBuf->buf.addr()); - auto dirList = listGet->dirList.get_ptr(); - - for (u32 i=0; iresult < 0) { - cellSysutil.Error("cellSaveDataListLoad2: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. - return CELL_SAVEDATA_ERROR_CBRESULT; - } - - setSaveDataList(saveEntries, listSet->fixedList, listSet->fixedListNum); - if (listSet->newData) - addNewSaveDataEntry(saveEntries, listSet->newData); - if (saveEntries.size() == 0) { - cellSysutil.Error("cellSaveDataListLoad2: No save entries found!"); // TODO: Find a better way to handle this error - return CELL_OK; - } - - u32 focusIndex = focusSaveDataEntry(saveEntries, listSet->focusPosition); - // TODO: Display the dialog here - u32 selectedIndex = focusIndex; // TODO: Until the dialog is implemented, select always the focused entry - getSaveDataStat(saveEntries[selectedIndex], statGet); - result->userdata = userdata; - - funcStat(result, statGet, statSet); - Memory.Free(statGet->fileList.addr()); - if (result->result < 0) { - cellSysutil.Error("cellSaveDataListLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. - return CELL_SAVEDATA_ERROR_CBRESULT; - } - - /*if (statSet->setParam) - // TODO: Write PARAM.SFO file - */ - - // Enter the loop where the save files are read/created/deleted. - s32 ret = modifySaveDataFiles(funcFile, result, saveBaseDir + (char*)statGet->dir.dirName); - - return ret; + return savedata_op(CPU, SAVEDATA_OP_LIST_LOAD, version, vm::null, 1, setList, setBuf, funcList, vm::null, funcStat, funcFile, container, 2, userdata, 0, vm::null); } s32 cellSaveDataFixedSave2( + PPUThread& CPU, u32 version, vm::ptr setList, vm::ptr setBuf, @@ -515,73 +670,14 @@ s32 cellSaveDataFixedSave2( u32 container, vm::ptr userdata) { - cellSysutil.Warning("cellSaveDataFixedSave2(version=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", - version, setList.addr(), setBuf.addr(), funcFixed.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); + cellSysutil.Warning("cellSaveDataFixedSave2(version=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)", + version, setList, setBuf, funcFixed, funcStat, funcFile, container, userdata); - vm::var result; - vm::var listGet; - vm::var fixedSet; - vm::var statGet; - vm::var statSet; - - std::string saveBaseDir = "/dev_hdd0/home/00000001/savedata/"; // TODO: Get the path of the current user - vfsDir dir(saveBaseDir); - if (!dir.IsOpened()) - return CELL_SAVEDATA_ERROR_INTERNAL; - - std::string dirNamePrefix = setList->dirNamePrefix.get_ptr(); - std::vector saveEntries; - for (const DirEntryInfo* entry = dir.Read(); entry; entry = dir.Read()) - { - if (entry->flags & DirEntry_TypeDir && entry->name.substr(0, dirNamePrefix.size()) == dirNamePrefix) - { - // Count the amount of matches and the amount of listed directories - listGet->dirListNum++; - if (listGet->dirListNum > setBuf->dirListMax) - continue; - listGet->dirNum++; - - std::string saveDir = saveBaseDir + entry->name; - addSaveDataEntry(saveEntries, saveDir); - } - } - - // Sort the entries and fill the listGet->dirList array - std::sort(saveEntries.begin(), saveEntries.end(), sortSaveDataEntry(setList->sortType, setList->sortOrder)); - listGet->dirList.set(setBuf->buf.addr()); - auto dirList = listGet->dirList.get_ptr(); - for (u32 i = 0; iresult < 0) { - cellSysutil.Error("cellSaveDataFixedSave2: CellSaveDataFixedCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. - return CELL_SAVEDATA_ERROR_CBRESULT; - } - setSaveDataFixed(saveEntries, fixedSet); - getSaveDataStat(saveEntries[0], statGet); // There should be only one element in this list - // TODO: Display the Yes|No dialog here - result->userdata = userdata; - - funcStat(result, statGet, statSet); - Memory.Free(statGet->fileList.addr()); - if (result->result < 0) { - cellSysutil.Error("cellSaveDataFixedSave2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. - return CELL_SAVEDATA_ERROR_CBRESULT; - } - /*if (statSet->setParam) - // TODO: Write PARAM.SFO file - */ - - // Enter the loop where the save files are read/created/deleted. - s32 ret = modifySaveDataFiles(funcFile, result, saveBaseDir + (char*)statGet->dir.dirName); - - return ret; + return savedata_op(CPU, SAVEDATA_OP_FIXED_SAVE, version, vm::null, 1, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 2, userdata, 0, vm::null); } s32 cellSaveDataFixedLoad2( + PPUThread& CPU, u32 version, vm::ptr setList, vm::ptr setBuf, @@ -591,73 +687,14 @@ s32 cellSaveDataFixedLoad2( u32 container, vm::ptr userdata) { - cellSysutil.Warning("cellSaveDataFixedLoad2(version=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", - version, setList.addr(), setBuf.addr(), funcFixed.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); + cellSysutil.Warning("cellSaveDataFixedLoad2(version=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)", + version, setList, setBuf, funcFixed, funcStat, funcFile, container, userdata); - vm::var result; - vm::var listGet; - vm::var fixedSet; - vm::var statGet; - vm::var statSet; - - std::string saveBaseDir = "/dev_hdd0/home/00000001/savedata/"; // TODO: Get the path of the current user - vfsDir dir(saveBaseDir); - if (!dir.IsOpened()) - return CELL_SAVEDATA_ERROR_INTERNAL; - - std::string dirNamePrefix = setList->dirNamePrefix.get_ptr(); - std::vector saveEntries; - for (const DirEntryInfo* entry = dir.Read(); entry; entry = dir.Read()) - { - if (entry->flags & DirEntry_TypeDir && entry->name.substr(0, dirNamePrefix.size()) == dirNamePrefix) - { - // Count the amount of matches and the amount of listed directories - listGet->dirListNum++; - if (listGet->dirListNum > setBuf->dirListMax) - continue; - listGet->dirNum++; - - std::string saveDir = saveBaseDir + entry->name; - addSaveDataEntry(saveEntries, saveDir); - } - } - - // Sort the entries and fill the listGet->dirList array - std::sort(saveEntries.begin(), saveEntries.end(), sortSaveDataEntry(setList->sortType, setList->sortOrder)); - listGet->dirList.set(setBuf->buf.addr()); - auto dirList = listGet->dirList.get_ptr(); - for (u32 i = 0; iresult < 0) { - cellSysutil.Error("cellSaveDataFixedLoad2: CellSaveDataFixedCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. - return CELL_SAVEDATA_ERROR_CBRESULT; - } - setSaveDataFixed(saveEntries, fixedSet); - getSaveDataStat(saveEntries[0], statGet); // There should be only one element in this list - // TODO: Display the Yes|No dialog here - result->userdata = userdata; - - funcStat(result, statGet, statSet); - Memory.Free(statGet->fileList.addr()); - if (result->result < 0) { - cellSysutil.Error("cellSaveDataFixedLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. - return CELL_SAVEDATA_ERROR_CBRESULT; - } - /*if (statSet->setParam) - // TODO: Write PARAM.SFO file - */ - - // Enter the loop where the save files are read/created/deleted. - s32 ret = modifySaveDataFiles(funcFile, result, saveBaseDir + (char*)statGet->dir.dirName); - - return ret; + return savedata_op(CPU, SAVEDATA_OP_FIXED_LOAD, version, vm::null, 1, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 2, userdata, 0, vm::null); } s32 cellSaveDataAutoSave2( + PPUThread& CPU, u32 version, vm::ptr dirName, u32 errDialog, @@ -667,58 +704,14 @@ s32 cellSaveDataAutoSave2( u32 container, vm::ptr userdata) { - cellSysutil.Warning("cellSaveDataAutoSave2(version=%d, dirName_addr=0x%x, errDialog=%d, setBuf_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", - version, dirName.addr(), errDialog, setBuf.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); + cellSysutil.Warning("cellSaveDataAutoSave2(version=%d, dirName=*0x%x, errDialog=%d, setBuf=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)", + version, dirName, errDialog, setBuf, funcStat, funcFile, container, userdata); - vm::var result; - vm::var statGet; - vm::var statSet; - - std::string saveBaseDir = "/dev_hdd0/home/00000001/savedata/"; // TODO: Get the path of the current user - vfsDir dir(saveBaseDir); - if (!dir.IsOpened()) - return CELL_SAVEDATA_ERROR_INTERNAL; - - std::string dirN = dirName.get_ptr(); - std::vector saveEntries; - for (const DirEntryInfo* entry = dir.Read(); entry; entry = dir.Read()) - { - if (entry->flags & DirEntry_TypeDir && entry->name == dirN) { - addSaveDataEntry(saveEntries, saveBaseDir + dirN); - } - } - - // The target entry does not exist - if (saveEntries.size() == 0) { - SaveDataEntry entry; - entry.dirName = dirN; - entry.sizeKB = 0; - entry.isNew = true; - saveEntries.push_back(entry); - } - - getSaveDataStat(saveEntries[0], statGet); // There should be only one element in this list - result->userdata = userdata; - funcStat(result, statGet, statSet); - - if (statGet->fileList) - Memory.Free(statGet->fileList.addr()); - - if (result->result < 0) { - cellSysutil.Error("cellSaveDataAutoSave2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. - return CELL_SAVEDATA_ERROR_CBRESULT; - } - /*if (statSet->setParam) - // TODO: Write PARAM.SFO file - */ - - // Enter the loop where the save files are read/created/deleted. - s32 ret = modifySaveDataFiles(funcFile, result, saveBaseDir + (char*)statGet->dir.dirName); - - return CELL_OK; + return savedata_op(CPU, SAVEDATA_OP_AUTO_SAVE, version, dirName, errDialog, vm::null, setBuf, vm::null, vm::null, funcStat, funcFile, container, 2, userdata, 0, vm::null); } s32 cellSaveDataAutoLoad2( + PPUThread& CPU, u32 version, vm::ptr dirName, u32 errDialog, @@ -728,53 +721,14 @@ s32 cellSaveDataAutoLoad2( u32 container, vm::ptr userdata) { - cellSysutil.Warning("cellSaveDataAutoLoad2(version=%d, dirName_addr=0x%x, errDialog=%d, setBuf_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", - version, dirName.addr(), errDialog, setBuf.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); + cellSysutil.Warning("cellSaveDataAutoLoad2(version=%d, dirName=*0x%x, errDialog=%d, setBuf=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)", + version, dirName, errDialog, setBuf, funcStat, funcFile, container, userdata); - vm::var result; - vm::var statGet; - vm::var statSet; - - std::string saveBaseDir = "/dev_hdd0/home/00000001/savedata/"; // TODO: Get the path of the current user - vfsDir dir(saveBaseDir); - if (!dir.IsOpened()) - return CELL_SAVEDATA_ERROR_INTERNAL; - - std::string dirN = dirName.get_ptr(); - std::vector saveEntries; - for (const DirEntryInfo* entry = dir.Read(); entry; entry = dir.Read()) - { - if (entry->flags & DirEntry_TypeDir && entry->name == dirN) { - addSaveDataEntry(saveEntries, saveBaseDir + dirN); - } - } - - // The target entry does not exist - if (saveEntries.size() == 0) { - cellSysutil.Error("cellSaveDataAutoLoad2: Couldn't find save entry (%s)", dirN.c_str()); - return CELL_OK; // TODO: Can anyone check the actual behaviour of a PS3 when saves are not found? - } - - getSaveDataStat(saveEntries[0], statGet); // There should be only one element in this list - result->userdata = userdata; - funcStat(result, statGet, statSet); - - Memory.Free(statGet->fileList.addr()); - if (result->result < 0) { - cellSysutil.Error("cellSaveDataAutoLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. - return CELL_SAVEDATA_ERROR_CBRESULT; - } - /*if (statSet->setParam) - // TODO: Write PARAM.SFO file - */ - - // Enter the loop where the save files are read/created/deleted. - s32 ret = modifySaveDataFiles(funcFile, result, saveBaseDir + (char*)statGet->dir.dirName); - - return CELL_OK; + return savedata_op(CPU, SAVEDATA_OP_AUTO_LOAD, version, dirName, errDialog, vm::null, setBuf, vm::null, vm::null, funcStat, funcFile, container, 2, userdata, 0, vm::null); } s32 cellSaveDataListAutoSave( + PPUThread& CPU, u32 version, u32 errDialog, vm::ptr setList, @@ -785,79 +739,14 @@ s32 cellSaveDataListAutoSave( u32 container, vm::ptr userdata) { - cellSysutil.Todo("cellSaveDataListAutoSave(version=%d, errDialog=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", - version, errDialog, setList.addr(), setBuf.addr(), funcFixed.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); + cellSysutil.Warning("cellSaveDataListAutoSave(version=%d, errDialog=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)", + version, errDialog, setList, setBuf, funcFixed, funcStat, funcFile, container, userdata); - //vm::var result; - //vm::var listGet; - //vm::var fixedSet; - //vm::var statGet; - //vm::var statSet; - - //std::string saveBaseDir = "/dev_hdd0/home/00000001/savedata/"; // TODO: Get the path of the current user - //vfsDir dir(saveBaseDir); - - //if (!dir.IsOpened()) - // return CELL_SAVEDATA_ERROR_INTERNAL; - - //std::string dirNamePrefix = setList->dirNamePrefix.get_ptr(); - //std::vector saveEntries; - - //for (const DirEntryInfo* entry = dir.Read(); entry; entry = dir.Read()) - //{ - // if (entry->flags & DirEntry_TypeDir && entry->name.substr(0, dirNamePrefix.size()) == dirNamePrefix) - // { - // // Count the amount of matches and the amount of listed directories - // listGet->dirListNum++; - // if (listGet->dirListNum > setBuf->dirListMax) - // continue; - // listGet->dirNum++; - - // std::string saveDir = saveBaseDir + entry->name; - // addSaveDataEntry(saveEntries, saveDir); - // } - //} - - //// Sort the entries and fill the listGet->dirList array - //std::sort(saveEntries.begin(), saveEntries.end(), sortSaveDataEntry(setList->sortType, setList->sortOrder)); - //listGet->dirList = vm::bptr::make(setBuf->buf.addr()); - //auto dirList = vm::get_ptr(listGet->dirList.addr()); - - //for (u32 i = 0; iresult < 0) { - // cellSysutil.Error("cellSaveDataListAutoSave: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. - // return CELL_SAVEDATA_ERROR_CBRESULT; - //} - - //setSaveDataFixed(saveEntries, fixedSet); - //getSaveDataStat(saveEntries[0], statGet); // There should be only one element in this list - //// TODO: Display the Yes|No dialog here - //result->userdata = userdata; - - //funcStat(result, statGet, statSet); - //Memory.Free(statGet->fileList.addr()); - //if (result->result < 0) { - // cellSysutil.Error("cellSaveDataListAutoSave: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. - // return CELL_SAVEDATA_ERROR_CBRESULT; - //} - - ///*if (statSet->setParam) - //// TODO: Write PARAM.SFO file - //*/ - - //// Enter the loop where the save files are read/created/deleted. - //s32 ret = modifySaveDataFiles(funcFile, result, saveBaseDir + (char*)statGet->dir.dirName); - return CELL_OK; + return savedata_op(CPU, SAVEDATA_OP_LIST_AUTO_SAVE, version, vm::null, errDialog, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 0, userdata, 0, vm::null); } s32 cellSaveDataListAutoLoad( + PPUThread& CPU, u32 version, u32 errDialog, vm::ptr setList, @@ -868,88 +757,21 @@ s32 cellSaveDataListAutoLoad( u32 container, vm::ptr userdata) { - cellSysutil.Warning("cellSaveDataListAutoLoad(version=%d, errDialog=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", - version, errDialog, setList.addr(), setBuf.addr(), funcFixed.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); + cellSysutil.Warning("cellSaveDataListAutoLoad(version=%d, errDialog=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)", + version, errDialog, setList, setBuf, funcFixed, funcStat, funcFile, container, userdata); - vm::var result; - vm::var listGet; - vm::var fixedSet; - vm::var statGet; - vm::var statSet; - - std::string saveBaseDir = "/dev_hdd0/home/00000001/savedata/"; // TODO: Get the path of the current user - vfsDir dir(saveBaseDir); - - if (!dir.IsOpened()) - return CELL_SAVEDATA_ERROR_INTERNAL; - - std::string dirNamePrefix = setList->dirNamePrefix.get_ptr(); - std::vector saveEntries; - - for (const DirEntryInfo* entry = dir.Read(); entry; entry = dir.Read()) - { - if (entry->flags & DirEntry_TypeDir && entry->name.substr(0, dirNamePrefix.size()) == dirNamePrefix) - { - // Count the amount of matches and the amount of listed directories - listGet->dirListNum++; - if (listGet->dirListNum > setBuf->dirListMax) - continue; - listGet->dirNum++; - - std::string saveDir = saveBaseDir + entry->name; - addSaveDataEntry(saveEntries, saveDir); - } - } - - // Sort the entries and fill the listGet->dirList array - std::sort(saveEntries.begin(), saveEntries.end(), sortSaveDataEntry(setList->sortType, setList->sortOrder)); - listGet->dirList = vm::bptr::make(setBuf->buf.addr()); - auto dirList = vm::get_ptr(listGet->dirList.addr()); - - for (u32 i = 0; idirList[i].reserved)); - } - - funcFixed(result, listGet, fixedSet); - - if (result->result < 0) { - cellSysutil.Error("cellSaveDataListAutoLoad: CellSaveDataListCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. - return CELL_SAVEDATA_ERROR_CBRESULT; - } - - setSaveDataFixed(saveEntries, fixedSet); - getSaveDataStat(saveEntries[0], statGet); // There should be only one element in this list - // TODO: Display the Yes|No dialog here - result->userdata = userdata; - - funcStat(result, statGet, statSet); - Memory.Free(statGet->fileList.addr()); - - if (result->result < 0) { - cellSysutil.Error("cellSaveDataFixedLoad2: CellSaveDataStatCallback failed."); // TODO: Once we verify that the entire SysCall is working, delete this debug error message. - return CELL_SAVEDATA_ERROR_CBRESULT; - } - - /*if (statSet->setParam) - // TODO: Write PARAM.SFO file - */ - - // Enter the loop where the save files are read/created/deleted. - s32 ret = modifySaveDataFiles(funcFile, result, saveBaseDir + (char*)statGet->dir.dirName); - - return CELL_OK; + return savedata_op(CPU, SAVEDATA_OP_LIST_AUTO_LOAD, version, vm::null, errDialog, setList, setBuf, vm::null, funcFixed, funcStat, funcFile, container, 0, userdata, 0, vm::null); } s32 cellSaveDataDelete2(u32 container) { - cellSysutil.Todo("cellSaveDataDelete2(container=%d)", container); + cellSysutil.Todo("cellSaveDataDelete2(container=0x%x)", container); return CELL_SAVEDATA_RET_CANCEL; } s32 cellSaveDataFixedDelete( + PPUThread& CPU, vm::ptr setList, vm::ptr setBuf, vm::ptr funcFixed, @@ -957,13 +779,14 @@ s32 cellSaveDataFixedDelete( u32 container, vm::ptr userdata) { - cellSysutil.Todo("cellSaveDataFixedDelete(setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcDone_addr=0x%x, container=%d, userdata_addr=0x%x)", - setList.addr(), setBuf.addr(), funcFixed.addr(), funcDone.addr(), container, userdata.addr()); + cellSysutil.Todo("cellSaveDataFixedDelete(setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcDone=*0x%x, container=0x%x, userdata=*0x%x)", + setList, setBuf, funcFixed, funcDone, container, userdata); return CELL_OK; } s32 cellSaveDataUserListSave( + PPUThread& CPU, u32 version, u32 userId, vm::ptr setList, @@ -974,13 +797,14 @@ s32 cellSaveDataUserListSave( u32 container, vm::ptr userdata) { - cellSysutil.Todo("cellSaveDataUserListSave(version=%d, userId=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcList_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", - version, userId, setList.addr(), setBuf.addr(), funcList.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); + cellSysutil.Todo("cellSaveDataUserListSave(version=%d, userId=%d, setList=*0x%x, setBuf=*0x%x, funcList=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)", + version, userId, setList, setBuf, funcList, funcStat, funcFile, container, userdata); return CELL_OK; } s32 cellSaveDataUserListLoad( + PPUThread& CPU, u32 version, u32 userId, vm::ptr setList, @@ -991,13 +815,14 @@ s32 cellSaveDataUserListLoad( u32 container, vm::ptr userdata) { - cellSysutil.Todo("cellSaveDataUserListLoad(version=%d, userId=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcList_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", - version, userId, setList.addr(), setBuf.addr(), funcList.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); + cellSysutil.Todo("cellSaveDataUserListLoad(version=%d, userId=%d, setList=*0x%x, setBuf=*0x%x, funcList=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)", + version, userId, setList, setBuf, funcList, funcStat, funcFile, container, userdata); return CELL_OK; } s32 cellSaveDataUserFixedSave( + PPUThread& CPU, u32 version, u32 userId, vm::ptr setList, @@ -1008,13 +833,14 @@ s32 cellSaveDataUserFixedSave( u32 container, vm::ptr userdata) { - cellSysutil.Todo("cellSaveDataUserFixedSave(version=%d, userId=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", - version, userId, setList.addr(), setBuf.addr(), funcFixed.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); + cellSysutil.Todo("cellSaveDataUserFixedSave(version=%d, userId=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)", + version, userId, setList, setBuf, funcFixed, funcStat, funcFile, container, userdata); return CELL_OK; } s32 cellSaveDataUserFixedLoad( + PPUThread& CPU, u32 version, u32 userId, vm::ptr setList, @@ -1025,13 +851,14 @@ s32 cellSaveDataUserFixedLoad( u32 container, vm::ptr userdata) { - cellSysutil.Todo("cellSaveDataUserFixedLoad(version=%d, userId=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", - version, userId, setList.addr(), setBuf.addr(), funcFixed.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); + cellSysutil.Todo("cellSaveDataUserFixedLoad(version=%d, userId=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)", + version, userId, setList, setBuf, funcFixed, funcStat, funcFile, container, userdata); return CELL_OK; } s32 cellSaveDataUserAutoSave( + PPUThread& CPU, u32 version, u32 userId, vm::ptr dirName, @@ -1042,13 +869,14 @@ s32 cellSaveDataUserAutoSave( u32 container, vm::ptr userdata) { - cellSysutil.Todo("cellSaveDataUserAutoSave(version=%d, userId=%d, dirName_addr=0x%x, errDialog=%d, setBuf_addr=0x%x, funcStat_addr=0x%x, funcFile=0x%x, container=%d, userdata_addr=0x%x)", - version, userId, dirName.addr(), errDialog, setBuf.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); + cellSysutil.Todo("cellSaveDataUserAutoSave(version=%d, userId=%d, dirName=*0x%x, errDialog=%d, setBuf=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)", + version, userId, dirName, errDialog, setBuf, funcStat, funcFile, container, userdata); return CELL_OK; } s32 cellSaveDataUserAutoLoad( + PPUThread& CPU, u32 version, u32 userId, vm::ptr dirName, @@ -1059,13 +887,14 @@ s32 cellSaveDataUserAutoLoad( u32 container, vm::ptr userdata) { - cellSysutil.Todo("cellSaveDataUserAutoLoad(version=%d, userId=%d, dirName_addr=0x%x, errDialog=%d, setBuf_addr=0x%x, funcStat_addr=0x%x, funcFile=0x%x, container=%d, userdata_addr=0x%x)", - version, userId, dirName.addr(), errDialog, setBuf.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); + cellSysutil.Todo("cellSaveDataUserAutoLoad(version=%d, userId=%d, dirName=*0x%x, errDialog=%d, setBuf=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)", + version, userId, dirName, errDialog, setBuf, funcStat, funcFile, container, userdata); return CELL_OK; } s32 cellSaveDataUserListAutoSave( + PPUThread& CPU, u32 version, u32 userId, u32 errDialog, @@ -1077,13 +906,14 @@ s32 cellSaveDataUserListAutoSave( u32 container, vm::ptr userdata) { - cellSysutil.Todo("cellSaveDataUserListAutoSave(version=%d, userId=%d, errDialog=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", - version, userId, errDialog, setList.addr(), setBuf.addr(), funcFixed.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); + cellSysutil.Todo("cellSaveDataUserListAutoSave(version=%d, userId=%d, errDialog=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)", + version, userId, errDialog, setList, setBuf, funcFixed, funcStat, funcFile, container, userdata); return CELL_OK; } s32 cellSaveDataUserListAutoLoad( + PPUThread& CPU, u32 version, u32 userId, u32 errDialog, @@ -1095,13 +925,14 @@ s32 cellSaveDataUserListAutoLoad( u32 container, vm::ptr userdata) { - cellSysutil.Todo("cellSaveDataUserListAutoLoad(version=%d, userId=%d, errDialog=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcStat_addr=0x%x, funcFile_addr=0x%x, container=%d, userdata_addr=0x%x)", - version, userId, errDialog, setList.addr(), setBuf.addr(), funcFixed.addr(), funcStat.addr(), funcFile.addr(), container, userdata.addr()); + cellSysutil.Todo("cellSaveDataUserListAutoLoad(version=%d, userId=%d, errDialog=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcStat=*0x%x, funcFile=*0x%x, container=0x%x, userdata=*0x%x)", + version, userId, errDialog, setList, setBuf, funcFixed, funcStat, funcFile, container, userdata); return CELL_OK; } s32 cellSaveDataUserFixedDelete( + PPUThread& CPU, u32 userId, vm::ptr setList, vm::ptr setBuf, @@ -1110,8 +941,8 @@ s32 cellSaveDataUserFixedDelete( u32 container, vm::ptr userdata) { - cellSysutil.Todo("cellSaveDataUserFixedDelete(userId=%d, setList_addr=0x%x, setBuf_addr=0x%x, funcFixed_addr=0x%x, funcDone_addr=0x%x, container=%d, userdata_addr=0x%x)", - userId, setList.addr(), setBuf.addr(), funcFixed.addr(), funcDone.addr(), container, userdata.addr()); + cellSysutil.Todo("cellSaveDataUserFixedDelete(userId=%d, setList=*0x%x, setBuf=*0x%x, funcFixed=*0x%x, funcDone=*0x%x, container=0x%x, userdata=*0x%x)", + userId, setList, setBuf, funcFixed, funcDone, container, userdata); return CELL_OK; } @@ -1126,6 +957,7 @@ void cellSaveDataEnableOverlay(s32 enable) // Functions (Extensions) s32 cellSaveDataListDelete( + PPUThread& CPU, vm::ptr setList, vm::ptr setBuf, vm::ptr funcList, @@ -1139,6 +971,7 @@ s32 cellSaveDataListDelete( } s32 cellSaveDataListImport( + PPUThread& CPU, vm::ptr setList, u32 maxSizeKB, vm::ptr funcDone, @@ -1151,6 +984,7 @@ s32 cellSaveDataListImport( } s32 cellSaveDataListExport( + PPUThread& CPU, vm::ptr setList, u32 maxSizeKB, vm::ptr funcDone, @@ -1163,6 +997,7 @@ s32 cellSaveDataListExport( } s32 cellSaveDataFixedImport( + PPUThread& CPU, vm::ptr dirName, u32 maxSizeKB, vm::ptr funcDone, @@ -1175,6 +1010,7 @@ s32 cellSaveDataFixedImport( } s32 cellSaveDataFixedExport( + PPUThread& CPU, vm::ptr dirName, u32 maxSizeKB, vm::ptr funcDone, @@ -1199,6 +1035,7 @@ s32 cellSaveDataGetListItem( } s32 cellSaveDataUserListDelete( + PPUThread& CPU, u32 userId, vm::ptr setList, vm::ptr setBuf, @@ -1213,6 +1050,7 @@ s32 cellSaveDataUserListDelete( } s32 cellSaveDataUserListImport( + PPUThread& CPU, u32 userId, vm::ptr setList, u32 maxSizeKB, @@ -1226,6 +1064,7 @@ s32 cellSaveDataUserListImport( } s32 cellSaveDataUserListExport( + PPUThread& CPU, u32 userId, vm::ptr setList, u32 maxSizeKB, @@ -1239,6 +1078,7 @@ s32 cellSaveDataUserListExport( } s32 cellSaveDataUserFixedImport( + PPUThread& CPU, u32 userId, vm::ptr dirName, u32 maxSizeKB, @@ -1252,6 +1092,7 @@ s32 cellSaveDataUserFixedImport( } s32 cellSaveDataUserFixedExport( + PPUThread& CPU, u32 userId, vm::ptr dirName, u32 maxSizeKB, diff --git a/rpcs3/Emu/SysCalls/Modules/cellSaveData.h b/rpcs3/Emu/SysCalls/Modules/cellSaveData.h index 48a7f0c60f..1c9351ca3a 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSaveData.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSaveData.h @@ -85,6 +85,13 @@ enum CELL_SAVEDATA_FILETYPE_CONTENT_ICON1 = 3, CELL_SAVEDATA_FILETYPE_CONTENT_PIC1 = 4, CELL_SAVEDATA_FILETYPE_CONTENT_SND0 = 5, + + // reCreateMode + CELL_SAVEDATA_RECREATE_NO = 0, + CELL_SAVEDATA_RECREATE_NO_NOBROKEN = 1, + CELL_SAVEDATA_RECREATE_YES = 2, + CELL_SAVEDATA_RECREATE_YES_RESET_OWNER = 3, + CELL_SAVEDATA_RECREATE_MASK = 0xffff, }; @@ -167,22 +174,22 @@ struct CellSaveDataSystemFileParam struct CellSaveDataDirStat { - be_t st_atime_; - be_t st_mtime_; - be_t st_ctime_; + be_t atime; + be_t mtime; + be_t ctime; char dirName[CELL_SAVEDATA_DIRNAME_SIZE]; }; struct CellSaveDataFileStat { be_t fileType; - u8 reserved1[4]; - be_t st_size; - be_t st_atime_; - be_t st_mtime_; - be_t st_ctime_; + char reserved1[4]; + be_t size; + be_t atime; + be_t mtime; + be_t ctime; char fileName[CELL_SAVEDATA_FILENAME_SIZE]; - u8 reserved2[3]; + char reserved2[3]; }; struct CellSaveDataStatGet @@ -271,11 +278,21 @@ struct SaveDataEntry std::string title; std::string subtitle; std::string details; - u32 sizeKB; - s64 st_atime_; - s64 st_mtime_; - s64 st_ctime_; - void* iconBuf; - u32 iconBufSize; + u64 size; + s64 atime; + s64 mtime; + s64 ctime; + //void* iconBuf; + //u32 iconBufSize; bool isNew; }; + +struct SaveDataDialogInstance +{ + std::mutex mutex; + + SaveDataDialogInstance(); + virtual ~SaveDataDialogInstance() = default; + + virtual s32 ShowSaveDataList(std::vector& save_entries, s32 focused, vm::ptr listSet) = 0; +}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp index f2474f841c..9f49bea788 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.cpp @@ -150,11 +150,12 @@ s32 spursInit( name += "CellSpursKernel0"; for (s32 num = 0; num < nSpus; num++, name[name.size() - 1]++) { - const u32 id = spu_thread_initialize(spurs->m.spuTG, num, vm::ptr::make(spurs.addr() + offsetof(CellSpurs, m.spuImg)), name, SYS_SPU_THREAD_OPTION_DEC_SYNC_TB_ENABLE, (u64)num << 32, spurs.addr(), 0, 0); - - static_cast(*Emu.GetCPU().GetThread(id).get()).RegisterHleFunction(spurs->m.spuImg.entry_point, spursKernelEntry); - - spurs->m.spus[num] = id; + spurs->m.spus[num] = spu_thread_initialize(spurs->m.spuTG, num, vm::ptr::make(spurs.addr() + offsetof(CellSpurs, m.spuImg)), + name, SYS_SPU_THREAD_OPTION_DEC_SYNC_TB_ENABLE, (u64)num << 32, spurs.addr(), 0, 0, [spurs](SPUThread& SPU) + { + SPU.RegisterHleFunction(spurs->m.spuImg.entry_point, spursKernelEntry); + SPU.FastCall(spurs->m.spuImg.entry_point); + }); } if (flags & SAF_SPU_PRINTF_ENABLED) @@ -305,7 +306,7 @@ s32 spursInit( { assert(!"sys_spu_thread_group_start() failed"); } - if (s32 res = sys_spu_thread_group_join(spurs->m.spuTG, vm::ptr::make(0), vm::ptr::make(0))) + if (s32 res = sys_spu_thread_group_join(spurs->m.spuTG, vm::null, vm::null)) { if (res == CELL_ESTAT) { @@ -474,7 +475,7 @@ s32 _cellSpursAttributeInitialize(vm::ptr attr, u32 revision s32 cellSpursAttributeSetMemoryContainerForSpuThread(vm::ptr attr, u32 container) { - cellSpurs.Warning("cellSpursAttributeSetMemoryContainerForSpuThread(attr_addr=0x%x, container=%d)", attr.addr(), container); + cellSpurs.Warning("cellSpursAttributeSetMemoryContainerForSpuThread(attr_addr=0x%x, container=0x%x)", attr.addr(), container); if (!attr) { @@ -706,7 +707,7 @@ s32 spursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr po s32 cellSpursAttachLv2EventQueue(vm::ptr spurs, u32 queue, vm::ptr port, s32 isDynamic) { - cellSpurs.Warning("cellSpursAttachLv2EventQueue(spurs_addr=0x%x, queue=%d, port_addr=0x%x, isDynamic=%d)", + cellSpurs.Warning("cellSpursAttachLv2EventQueue(spurs_addr=0x%x, queue=0x%x, port_addr=0x%x, isDynamic=%d)", spurs.addr(), queue, port.addr(), isDynamic); return spursAttachLv2EventQueue(spurs, queue, port, isDynamic, false); @@ -1050,10 +1051,10 @@ s32 cellSpursAddWorkload( *priorityTable, minContention, maxContention, - vm::ptr::make(0), - vm::ptr::make(0), - vm::ptr::make(0), - vm::ptr::make(0)); + vm::null, + vm::null, + vm::null, + vm::null); } s32 _cellSpursWorkloadAttributeInitialize( @@ -1159,16 +1160,16 @@ s32 cellSpursAddWorkloadWithAttribute(vm::ptr spurs, const vm::ptr::make(attr->m.pm.addr()), + attr->m.pm, attr->m.size, attr->m.data, attr->m.priority, attr->m.minContention, attr->m.maxContention, - vm::ptr::make(attr->m.nameClass.addr()), - vm::ptr::make(attr->m.nameInstance.addr()), - vm::ptr::make(attr->m.hook.addr()), - vm::ptr::make(attr->m.hookArg.addr())); + attr->m.nameClass, + attr->m.nameInstance, + attr->m.hook, + attr->m.hookArg); } s32 cellSpursRemoveWorkload() @@ -2182,14 +2183,14 @@ s32 spursCreateTaskset(vm::ptr spurs, vm::ptr tasks taskset.addr(), priority, 8 /*min_contention*/, max_contention); // TODO: Check return code - cellSpursWorkloadAttributeSetName(wkl_attr, vm::ptr::make(0), name); + cellSpursWorkloadAttributeSetName(wkl_attr, vm::null, name); // TODO: Check return code // TODO: cellSpursWorkloadAttributeSetShutdownCompletionEventHook(wkl_attr, hook, taskset); // TODO: Check return code vm::var> wid; - cellSpursAddWorkloadWithAttribute(spurs, vm::ptr::make(wid.addr()), vm::ptr::make(wkl_attr.addr())); + cellSpursAddWorkloadWithAttribute(spurs, vm::ptr::make(wid.addr()), wkl_attr); // TODO: Check return code taskset->m.wkl_flag_wait_task = 0x80; @@ -2235,7 +2236,7 @@ s32 cellSpursCreateTaskset(vm::ptr spurs, vm::ptr t cellSpurs.Warning("cellSpursCreateTaskset(spurs_addr=0x%x, taskset_addr=0x%x, args=0x%llx, priority_addr=0x%x, maxContention=%d)", spurs.addr(), taskset.addr(), args, priority.addr(), maxContention); - return spursCreateTaskset(spurs, taskset, args, priority, maxContention, vm::ptr::make(0), 6400/*CellSpursTaskset::size*/, 0); + return spursCreateTaskset(spurs, taskset, args, priority, maxContention, vm::null, 6400/*CellSpursTaskset::size*/, 0); } s32 cellSpursJoinTaskset(vm::ptr taskset) @@ -2395,8 +2396,8 @@ s32 spursTaskStart(vm::ptr taskset, u32 taskId) pendingReady._bit[taskId] = true; taskset->m.pending_ready = pendingReady; - cellSpursSendWorkloadSignal(vm::ptr::make((u32)taskset->m.spurs.addr()), taskset->m.wid); - auto rc = cellSpursWakeUp(GetCurrentPPUThread(), vm::ptr::make((u32)taskset->m.spurs.addr())); + cellSpursSendWorkloadSignal(taskset->m.spurs, taskset->m.wid); + auto rc = cellSpursWakeUp(GetCurrentPPUThread(), taskset->m.spurs); if (rc != CELL_OK) { if (rc == CELL_SPURS_POLICY_MODULE_ERROR_STAT) @@ -2478,8 +2479,8 @@ s32 _cellSpursSendSignal(vm::ptr taskset, u32 taskId) taskset->m.signalled = signalled; if (shouldSignal) { - cellSpursSendWorkloadSignal(vm::ptr::make((u32)taskset->m.spurs.addr()), taskset->m.wid); - auto rc = cellSpursWakeUp(GetCurrentPPUThread(), vm::ptr::make((u32)taskset->m.spurs.addr())); + cellSpursSendWorkloadSignal(taskset->m.spurs, taskset->m.wid); + auto rc = cellSpursWakeUp(GetCurrentPPUThread(), taskset->m.spurs); if (rc == CELL_SPURS_POLICY_MODULE_ERROR_STAT) { return CELL_SPURS_TASK_ERROR_STAT; @@ -2565,7 +2566,7 @@ s32 _cellSpursTasksetAttribute2Initialize(vm::ptr at memset(attribute.get_ptr(), 0, CellSpursTasksetAttribute2::size); attribute->m.revision = revision; - attribute->m.name.set(0); + attribute->m.name = vm::null; attribute->m.args = 0; for (s32 i = 0; i < 8; i++) @@ -2665,7 +2666,7 @@ s32 cellSpursCreateTaskset2(vm::ptr spurs, vm::ptr auto rc = spursCreateTaskset(spurs, vm::ptr::make(taskset.addr()), attr->m.args, vm::ptr::make(attr.addr() + offsetof(CellSpursTasksetAttribute, m.priority)), - attr->m.max_contention, vm::ptr::make(attr->m.name.addr()), CellSpursTaskset2::size, (u8)attr->m.enable_clear_ls); + attr->m.max_contention, attr->m.name, CellSpursTaskset2::size, (u8)attr->m.enable_clear_ls); if (rc != CELL_OK) { return rc; @@ -2773,7 +2774,7 @@ s32 cellSpursLookUpTasksetAddress(vm::ptr spurs, vm::ptr> data; - auto rc = cellSpursGetWorkloadData(spurs, vm::ptr::make(data.addr()), id); + auto rc = cellSpursGetWorkloadData(spurs, data, id); if (rc != CELL_OK) { // Convert policy module error code to a task error code diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index 6bf4e90285..ad0fed3b11 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -289,7 +289,7 @@ s32 syncRwmInitialize(vm::ptr rwm, vm::ptr buffer, u32 buffer } // prx: zeroize first u16 and second u16, write buffer_size in second u32, write buffer_addr in second u64 and sync - rwm->m_size = be_t::make(buffer_size); + rwm->m_size = buffer_size; rwm->m_buffer = buffer; rwm->data.exchange({}); @@ -488,9 +488,9 @@ s32 syncQueueInitialize(vm::ptr queue, vm::ptr buffer, u32 si } // prx: zeroize first u64, write size in third u32, write depth in fourth u32, write address in third u64 and sync - queue->m_size = be_t::make(size); - queue->m_depth = be_t::make(depth); - queue->m_buffer.set(buffer.addr()); + queue->m_size = size; + queue->m_depth = depth; + queue->m_buffer = buffer; queue->data.exchange({}); return CELL_OK; @@ -985,7 +985,7 @@ s32 syncLFQueueInitialize(vm::ptr queue, vm::ptr buffer, u3 if (old_value == 2) { - if (queue->m_size != size || queue->m_depth != depth || queue->m_buffer.addr().value() != buffer.addr()) + if (queue->m_size != size || queue->m_depth != depth || queue->m_buffer != buffer) { return CELL_SYNC_ERROR_INVAL; } @@ -1104,7 +1104,7 @@ s32 syncLFQueueGetPushPointer(vm::ptr queue, s32& pointer, u32 } } - if (s32 res = sys_event_queue_receive(GetCurrentPPUThread(), queue->m_eq_id, vm::ptr::make(0), 0)) + if (s32 res = sys_event_queue_receive(GetCurrentPPUThread(), queue->m_eq_id, vm::null, 0)) { assert(!"sys_event_queue_receive() failed"); } @@ -1448,7 +1448,7 @@ s32 syncLFQueueGetPopPointer(vm::ptr queue, s32& pointer, u32 i } } - if (s32 res = sys_event_queue_receive(GetCurrentPPUThread(), queue->m_eq_id, vm::ptr::make(0), 0)) + if (s32 res = sys_event_queue_receive(GetCurrentPPUThread(), queue->m_eq_id, vm::null, 0)) { assert(!"sys_event_queue_receive() failed"); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index c606030e8f..74c23480c6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -16,11 +16,8 @@ #include "Emu/Audio/AudioManager.h" #include "Emu/FS/VFS.h" #include "cellMsgDialog.h" -#include "cellGame.h" #include "cellSysutil.h" -typedef void (CellHddGameStatCallback)(vm::ptr cbResult, vm::ptr get, vm::ptr set); - extern Module cellSysutil; int cellSysutilGetSystemParamInt(int id, vm::ptr value) @@ -688,76 +685,6 @@ int cellSysCacheMount(vm::ptr param) return CELL_SYSCACHE_RET_OK_RELAYED; } -int cellHddGameCheck(u32 version, vm::ptr dirName, u32 errDialog, vm::ptr funcStat, u32 container) -{ - cellSysutil.Warning("cellHddGameCheck(version=%d, dirName_addr=0x%x, errDialog=%d, funcStat_addr=0x%x, container=%d)", - version, dirName.addr(), errDialog, funcStat.addr(), container); - - std::string dir = dirName.get_ptr(); - if (dir.size() != 9) - return CELL_HDDGAME_ERROR_PARAM; - - vm::var param; - vm::var result; - vm::var get; - vm::var set; - - get->hddFreeSizeKB = 40 * 1024 * 1024; // 40 GB, TODO: Use the free space of the computer's HDD where RPCS3 is being run. - get->isNewData = CELL_HDDGAME_ISNEWDATA_EXIST; - get->sysSizeKB = 0; // TODO - get->st_atime__ = 0; // TODO - get->st_ctime__ = 0; // TODO - get->st_mtime__ = 0; // TODO - get->sizeKB = CELL_HDDGAME_SIZEKB_NOTCALC; - memcpy(get->contentInfoPath, ("/dev_hdd0/game/" + dir).c_str(), CELL_HDDGAME_PATH_MAX); - memcpy(get->hddGamePath, ("/dev_hdd0/game/" + dir + "/USRDIR").c_str(), CELL_HDDGAME_PATH_MAX); - - if (!Emu.GetVFS().ExistsDir(("/dev_hdd0/game/" + dir).c_str())) - { - get->isNewData = CELL_HDDGAME_ISNEWDATA_NODIR; - } - else - { - // TODO: Is cellHddGameCheck really responsible for writing the information in get->getParam ? (If not, delete this else) - - vfsFile f(("/dev_hdd0/game/" + dir + "/PARAM.SFO").c_str()); - PSFLoader psf(f); - if (!psf.Load(false)) { - return CELL_HDDGAME_ERROR_BROKEN; - } - - get->getParam.parentalLevel = psf.GetInteger("PARENTAL_LEVEL"); - get->getParam.attribute = psf.GetInteger("ATTRIBUTE"); - get->getParam.resolution = psf.GetInteger("RESOLUTION"); - get->getParam.soundFormat = psf.GetInteger("SOUND_FORMAT"); - std::string title = psf.GetString("TITLE"); - strcpy_trunc(get->getParam.title, title); - std::string app_ver = psf.GetString("APP_VER"); - strcpy_trunc(get->getParam.dataVersion, app_ver); - strcpy_trunc(get->getParam.titleId, dir); - - for (u32 i=0; igetParam.titleLang[i], title); - } - } - - // TODO ? - - funcStat(result, get, set); - - if (result->result != CELL_HDDGAME_CBRESULT_OK && - result->result != CELL_HDDGAME_CBRESULT_OK_CANCEL) { - return CELL_HDDGAME_ERROR_CBRESULT; - } - - // TODO ? - - return CELL_OK; -} - bool bgm_playback_enabled = true; int cellSysutilEnableBgmPlayback() @@ -835,13 +762,9 @@ int cellWebBrowserEstimate2(const vm::ptr config, v return CELL_OK; } -extern int cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr dirName, u32 errDialog, - vm::ptr cbResult, vm::ptr get, vm::ptr set)> funcStat, u32 container); - -extern int cellGameDataCheckCreate(PPUThread& CPU, u32 version, vm::ptr dirName, u32 errDialog, - vm::ptr cbResult, vm::ptr get, vm::ptr set)> funcStat, u32 container); - extern void cellSysutil_SaveData_init(); +extern void cellSysutil_GameData_init(); +extern void cellSysutil_MsgDialog_init(); Module cellSysutil("cellSysutil", []() { @@ -851,6 +774,10 @@ Module cellSysutil("cellSysutil", []() v.arg.set(0); } + cellSysutil_SaveData_init(); // cellSaveData functions + cellSysutil_GameData_init(); // cellGameData, cellHddGame functions + cellSysutil_MsgDialog_init(); // cellMsgDialog functions + REG_FUNC(cellSysutil, cellSysutilGetSystemParamInt); REG_FUNC(cellSysutil, cellSysutilGetSystemParamString); @@ -866,14 +793,6 @@ Module cellSysutil("cellSysutil", []() REG_FUNC(cellSysutil, cellSysutilRegisterCallback); REG_FUNC(cellSysutil, cellSysutilUnregisterCallback); - REG_FUNC(cellSysutil, cellMsgDialogOpen2); - REG_FUNC(cellSysutil, cellMsgDialogOpenErrorCode); - REG_FUNC(cellSysutil, cellMsgDialogProgressBarSetMsg); - REG_FUNC(cellSysutil, cellMsgDialogProgressBarReset); - REG_FUNC(cellSysutil, cellMsgDialogProgressBarInc); - REG_FUNC(cellSysutil, cellMsgDialogClose); - REG_FUNC(cellSysutil, cellMsgDialogAbort); - REG_FUNC(cellSysutil, cellAudioOutGetState); REG_FUNC(cellSysutil, cellAudioOutConfigure); REG_FUNC(cellSysutil, cellAudioOutGetSoundAvailability); @@ -893,22 +812,8 @@ Module cellSysutil("cellSysutil", []() REG_FUNC(cellSysutil, cellSysCacheMount); REG_FUNC(cellSysutil, cellSysCacheClear); - REG_FUNC(cellSysutil, cellHddGameCheck); - //REG_FUNC(cellSysutil, cellHddGameCheck2); - //REG_FUNC(cellSysutil, cellHddGameGetSizeKB); - //REG_FUNC(cellSysutil, cellHddGameSetSystemVer); - //REG_FUNC(cellSysutil, cellHddGameExitBroken); - //REG_FUNC(cellSysutil, cellSysutilRegisterCallbackDispatcher); //REG_FUNC(cellSysutil, cellSysutilPacketWrite); - //REG_FUNC(cellSysutil, doc.write); - //REG_FUNC(cellSysutil, packet_read); - - // cellSaveData functions - cellSysutil_SaveData_init(); REG_FUNC(cellSysutil, cellWebBrowserEstimate2); - - REG_FUNC(cellSysutil, cellGameDataCheckCreate); - REG_FUNC(cellSysutil, cellGameDataCheckCreate2); }); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.h b/rpcs3/Emu/SysCalls/Modules/cellSysutil.h index 1e919b12f9..2c8fd2245c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.h @@ -152,91 +152,6 @@ enum CELL_SYSCACHE_ERROR_NOTMOUNTED = 0x8002bc04, // We don't really need to simulate the mounting, so this is probably useless }; -// cellSysutil: cellHddGame -enum -{ - // Return Codes - CELL_HDDGAME_RET_CANCEL = 1, - CELL_HDDGAME_ERROR_CBRESULT = 0x8002ba01, - CELL_HDDGAME_ERROR_ACCESS_ERROR = 0x8002ba02, - CELL_HDDGAME_ERROR_INTERNAL = 0x8002ba03, - CELL_HDDGAME_ERROR_PARAM = 0x8002ba04, - CELL_HDDGAME_ERROR_NOSPACE = 0x8002ba05, - CELL_HDDGAME_ERROR_BROKEN = 0x8002ba06, - CELL_HDDGAME_ERROR_FAILURE = 0x8002ba07, - - // Callback Result - CELL_HDDGAME_CBRESULT_OK_CANCEL = 1, - CELL_HDDGAME_CBRESULT_OK = 0, - CELL_HDDGAME_CBRESULT_ERR_NOSPACE = -1, - CELL_HDDGAME_CBRESULT_ERR_BROKEN = -3, - CELL_HDDGAME_CBRESULT_ERR_NODATA = -4, - CELL_HDDGAME_CBRESULT_ERR_INVALID = -5, - - // Character Strings - CELL_HDDGAME_INVALIDMSG_MAX = 256, - CELL_HDDGAME_PATH_MAX = 1055, - CELL_HDDGAME_SYSP_TITLE_SIZE = 128, - CELL_HDDGAME_SYSP_TITLEID_SIZE = 10, - CELL_HDDGAME_SYSP_VERSION_SIZE = 6, - CELL_HDDGAME_SYSP_SYSTEMVER_SIZE = 8, - - // HDD Directory exists - CELL_HDDGAME_ISNEWDATA_EXIST = 0, - CELL_HDDGAME_ISNEWDATA_NODIR = 1, - - // Languages - CELL_HDDGAME_SYSP_LANGUAGE_NUM = 20, - - // Stat Get - CELL_HDDGAME_SIZEKB_NOTCALC = -1, -}; - -struct CellHddGameSystemFileParam -{ - char title[CELL_HDDGAME_SYSP_TITLE_SIZE]; - char titleLang[CELL_HDDGAME_SYSP_LANGUAGE_NUM][CELL_HDDGAME_SYSP_TITLE_SIZE]; - char titleId[CELL_HDDGAME_SYSP_TITLEID_SIZE]; - u8 reserved0[2]; - char dataVersion[CELL_HDDGAME_SYSP_VERSION_SIZE]; - u8 reserved1[2]; - be_t attribute; - be_t parentalLevel; - be_t resolution; - be_t soundFormat; - u8 reserved2[256]; -}; - -struct CellHddGameStatGet -{ - be_t hddFreeSizeKB; - be_t isNewData; - u8 contentInfoPath[CELL_HDDGAME_PATH_MAX]; - u8 hddGamePath[CELL_HDDGAME_PATH_MAX]; - u8 reserved0[2]; - be_t st_atime__; - be_t st_mtime__; - be_t st_ctime__; - CellHddGameSystemFileParam getParam; - be_t sizeKB; - be_t sysSizeKB; - u8 reserved1[68]; -}; - -struct CellHddGameStatSet -{ - vm::bptr setParam; - be_t reserved_addr; // void* -}; - -struct CellHddGameCBResult -{ - be_t result; - be_t errNeedSizeKB; - be_t invalidMsg_addr; // char* - be_t reserved_addr; // void* -}; - typedef s32 CellWebBrowserId; typedef vm::ptr CellWebBrowserClientSession; typedef void(CellWebBrowserCallback)(s32 cb_type, CellWebBrowserClientSession, vm::ptr usrdata); @@ -303,4 +218,3 @@ struct CellWebBrowserConfig2 be_t resolution_factor; be_t magic_number_; }; - diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp index c03177d2a9..35d9c100b2 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp @@ -12,6 +12,7 @@ extern "C" #include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include "libavutil/imgutils.h" +#include "libswscale/swscale.h" } #include "Emu/CPU/CPUThreadManager.h" @@ -216,7 +217,7 @@ u32 vdecOpen(VideoDecoder* vdec_ptr) vdec.id = vdec_id; vdec.vdecCb = static_cast(Emu.GetCPU().AddThread(CPU_THREAD_PPU).get()); - vdec.vdecCb->SetName(fmt::format("VideoDecoder[%d] Callback", vdec_id)); + vdec.vdecCb->SetName(fmt::format("VideoDecoder[0x%x] Callback", vdec_id)); vdec.vdecCb->SetEntry(0); vdec.vdecCb->SetPrio(1001); vdec.vdecCb->SetStackSize(0x10000); @@ -224,7 +225,7 @@ u32 vdecOpen(VideoDecoder* vdec_ptr) vdec.vdecCb->InitRegs(); vdec.vdecCb->DoRun(); - thread_t t(fmt::format("VideoDecoder[%d] Thread", vdec_id), [vdec_ptr, sptr]() + thread_t t(fmt::format("VideoDecoder[0x%x] Thread", vdec_id), [vdec_ptr, sptr]() { VideoDecoder& vdec = *vdec_ptr; VdecTask& task = vdec.task; @@ -269,12 +270,6 @@ u32 vdecOpen(VideoDecoder* vdec_ptr) { int err; - if (task.mode != CELL_VDEC_DEC_MODE_NORMAL) - { - cellVdec.Error("vdecDecodeAu: unsupported decoding mode(%d)", task.mode); - break; - } - vdec.reader.addr = task.addr; vdec.reader.size = task.size; //LOG_NOTICE(HLE, "Video AU: size = 0x%x, pts = 0x%llx, dts = 0x%llx", task.size, task.pts, task.dts); @@ -558,46 +553,45 @@ u32 vdecOpen(VideoDecoder* vdec_ptr) return vdec_id; } -int cellVdecQueryAttr(vm::ptr type, vm::ptr attr) +s32 cellVdecQueryAttr(vm::ptr type, vm::ptr attr) { - cellVdec.Warning("cellVdecQueryAttr(type_addr=0x%x, attr_addr=0x%x)", type.addr(), attr.addr()); + cellVdec.Warning("cellVdecQueryAttr(type=*0x%x, attr=*0x%x)", type, attr); return vdecQueryAttr(type->codecType, type->profileLevel, 0, attr); } -int cellVdecQueryAttrEx(vm::ptr type, vm::ptr attr) +s32 cellVdecQueryAttrEx(vm::ptr type, vm::ptr attr) { - cellVdec.Warning("cellVdecQueryAttrEx(type_addr=0x%x, attr_addr=0x%x)", type.addr(), attr.addr()); + cellVdec.Warning("cellVdecQueryAttrEx(type=*0x%x, attr=*0x%x)", type, attr); return vdecQueryAttr(type->codecType, type->profileLevel, type->codecSpecificInfo_addr, attr); } -int cellVdecOpen(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle) +s32 cellVdecOpen(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle) { - cellVdec.Warning("cellVdecOpen(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)", - type.addr(), res.addr(), cb.addr(), handle.addr()); + cellVdec.Warning("cellVdecOpen(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle); *handle = vdecOpen(new VideoDecoder(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc, cb->cbArg)); return CELL_OK; } -int cellVdecOpenEx(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle) +s32 cellVdecOpenEx(vm::ptr type, vm::ptr res, vm::ptr cb, vm::ptr handle) { - cellVdec.Warning("cellVdecOpenEx(type_addr=0x%x, res_addr=0x%x, cb_addr=0x%x, handle_addr=0x%x)", - type.addr(), res.addr(), cb.addr(), handle.addr()); + cellVdec.Warning("cellVdecOpenEx(type=*0x%x, res=*0x%x, cb=*0x%x, handle=*0x%x)", type, res, cb, handle); *handle = vdecOpen(new VideoDecoder(type->codecType, type->profileLevel, res->memAddr, res->memSize, cb->cbFunc, cb->cbArg)); return CELL_OK; } -int cellVdecClose(u32 handle) +s32 cellVdecClose(u32 handle) { - cellVdec.Warning("cellVdecClose(handle=%d)", handle); + cellVdec.Warning("cellVdecClose(handle=0x%x)", handle); - std::shared_ptr vdec; - if (!Emu.GetIdManager().GetIDData(handle, vdec)) + const auto vdec = Emu.GetIdManager().GetIDData(handle); + + if (!vdec) { return CELL_VDEC_ERROR_ARG; } @@ -620,12 +614,13 @@ int cellVdecClose(u32 handle) return CELL_OK; } -int cellVdecStartSeq(u32 handle) +s32 cellVdecStartSeq(u32 handle) { - cellVdec.Log("cellVdecStartSeq(handle=%d)", handle); + cellVdec.Log("cellVdecStartSeq(handle=0x%x)", handle); - std::shared_ptr vdec; - if (!Emu.GetIdManager().GetIDData(handle, vdec)) + const auto vdec = Emu.GetIdManager().GetIDData(handle); + + if (!vdec) { return CELL_VDEC_ERROR_ARG; } @@ -634,12 +629,13 @@ int cellVdecStartSeq(u32 handle) return CELL_OK; } -int cellVdecEndSeq(u32 handle) +s32 cellVdecEndSeq(u32 handle) { - cellVdec.Warning("cellVdecEndSeq(handle=%d)", handle); + cellVdec.Warning("cellVdecEndSeq(handle=0x%x)", handle); - std::shared_ptr vdec; - if (!Emu.GetIdManager().GetIDData(handle, vdec)) + const auto vdec = Emu.GetIdManager().GetIDData(handle); + + if (!vdec) { return CELL_VDEC_ERROR_ARG; } @@ -648,16 +644,22 @@ int cellVdecEndSeq(u32 handle) return CELL_OK; } -int cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::ptr auInfo) +s32 cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::ptr auInfo) { - cellVdec.Log("cellVdecDecodeAu(handle=%d, mode=0x%x, auInfo_addr=0x%x)", handle, mode, auInfo.addr()); + cellVdec.Log("cellVdecDecodeAu(handle=0x%x, mode=%d, auInfo=*0x%x)", handle, mode, auInfo); - std::shared_ptr vdec; - if (!Emu.GetIdManager().GetIDData(handle, vdec)) + const auto vdec = Emu.GetIdManager().GetIDData(handle); + + if (!vdec || mode > CELL_VDEC_DEC_MODE_PB_SKIP) { return CELL_VDEC_ERROR_ARG; } + if (mode != CELL_VDEC_DEC_MODE_NORMAL) + { + cellVdec.Fatal("cellVdecDecodeAu(): unsupported decoding mode (%d)", mode); + } + // TODO: check info VdecTask task(vdecDecodeAu); task.mode = mode; @@ -672,12 +674,13 @@ int cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::ptr format, vm::ptr outBuff) +s32 cellVdecGetPicture(u32 handle, vm::ptr format, vm::ptr outBuff) { - cellVdec.Log("cellVdecGetPicture(handle=%d, format_addr=0x%x, outBuff_addr=0x%x)", handle, format.addr(), outBuff.addr()); + cellVdec.Log("cellVdecGetPicture(handle=0x%x, format=*0x%x, outBuff=*0x%x)", handle, format, outBuff); - std::shared_ptr vdec; - if (!Emu.GetIdManager().GetIDData(handle, vdec)) + const auto vdec = Emu.GetIdManager().GetIDData(handle); + + if (!vdec || !format) { return CELL_VDEC_ERROR_ARG; } @@ -703,9 +706,25 @@ int cellVdecGetPicture(u32 handle, vm::ptr format, vm:: if (outBuff) { - if (format->formatType != CELL_VDEC_PICFMT_YUV420_PLANAR) + const auto f = vdec->ctx->pix_fmt; + const auto w = vdec->ctx->width; + const auto h = vdec->ctx->height; + + auto out_f = AV_PIX_FMT_YUV420P; + + std::unique_ptr alpha_plane; + + switch (const u32 type = format->formatType) { - cellVdec.Fatal("cellVdecGetPicture: unknown formatType(%d)", format->formatType); + case CELL_VDEC_PICFMT_ARGB32_ILV: out_f = AV_PIX_FMT_ARGB; alpha_plane.reset(new u8[w * h]); break; + case CELL_VDEC_PICFMT_RGBA32_ILV: out_f = AV_PIX_FMT_RGBA; alpha_plane.reset(new u8[w * h]); break; + case CELL_VDEC_PICFMT_UYVY422_ILV: out_f = AV_PIX_FMT_UYVY422; break; + case CELL_VDEC_PICFMT_YUV420_PLANAR: out_f = AV_PIX_FMT_YUV420P; break; + + default: + { + cellVdec.Fatal("cellVdecGetPicture: unknown formatType(%d)", type); + } } if (format->colorMatrixType != CELL_VDEC_COLOR_MATRIX_TYPE_BT709) @@ -713,26 +732,79 @@ int cellVdecGetPicture(u32 handle, vm::ptr format, vm:: cellVdec.Fatal("cellVdecGetPicture: unknown colorMatrixType(%d)", format->colorMatrixType); } - const u32 buf_size = align(av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1), 128); - - // TODO: zero padding bytes - - int err = av_image_copy_to_buffer(outBuff.get_ptr(), buf_size, frame->data, frame->linesize, vdec->ctx->pix_fmt, frame->width, frame->height, 1); - if (err < 0) + if (alpha_plane) { - cellVdec.Fatal("cellVdecGetPicture: av_image_copy_to_buffer failed (err=0x%x)", err); + memset(alpha_plane.get(), format->alpha, w * h); } + + auto in_f = AV_PIX_FMT_YUV420P; + + switch (f) + { + case AV_PIX_FMT_YUV420P: in_f = alpha_plane ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P; break; + + default: + { + cellVdec.Fatal("cellVdecGetPicture: unknown pix_fmt(%d)", f); + } + } + + std::unique_ptr sws(sws_getContext(w, h, in_f, w, h, out_f, SWS_POINT, NULL, NULL, NULL), sws_freeContext); + + u8* in_data[4] = { frame->data[0], frame->data[1], frame->data[2], alpha_plane.get() }; + int in_line[4] = { frame->linesize[0], frame->linesize[1], frame->linesize[2], w * 1 }; + u8* out_data[4] = { outBuff.get_ptr() }; + int out_line[4] = { w * 4 }; + + if (!alpha_plane) + { + out_data[1] = out_data[0] + w * h; + out_data[2] = out_data[0] + w * h * 5 / 4; + out_line[0] = w; + out_line[1] = w / 2; + out_line[2] = w / 2; + } + + sws_scale(sws.get(), in_data, in_line, 0, h, out_data, out_line); + + //const u32 buf_size = align(av_image_get_buffer_size(vdec->ctx->pix_fmt, vdec->ctx->width, vdec->ctx->height, 1), 128); + + //// TODO: zero padding bytes + + //int err = av_image_copy_to_buffer(outBuff.get_ptr(), buf_size, frame->data, frame->linesize, vdec->ctx->pix_fmt, frame->width, frame->height, 1); + //if (err < 0) + //{ + // cellVdec.Fatal("cellVdecGetPicture: av_image_copy_to_buffer failed (err=0x%x)", err); + //} } return CELL_OK; } -int cellVdecGetPicItem(u32 handle, vm::ptr picItem_ptr) +s32 _nid_a21aa896(PPUThread& CPU, u32 handle, vm::ptr format2, vm::ptr outBuff, u32 arg4) { - cellVdec.Log("cellVdecGetPicItem(handle=%d, picItem_ptr_addr=0x%x)", handle, picItem_ptr.addr()); + cellVdec.Warning("_nid_a21aa896(handle=0x%x, format2=*0x%x, outBuff=*0x%x, arg4=*0x%x)", handle, format2, outBuff, arg4); - std::shared_ptr vdec; - if (!Emu.GetIdManager().GetIDData(handle, vdec)) + if (arg4 || format2->unk0 || format2->unk1) + { + cellVdec.Fatal("_nid_a21aa896(): unknown arguments (arg4=*0x%x, unk0=0x%x, unk1=0x%x)", arg4, format2->unk0, format2->unk1); + } + + vm::stackvar format(CPU); + format->formatType = format2->formatType; + format->colorMatrixType = format2->colorMatrixType; + format->alpha = format2->alpha; + + return cellVdecGetPicture(handle, format, outBuff); +} + +s32 cellVdecGetPicItem(u32 handle, vm::ptr> picItem) +{ + cellVdec.Log("cellVdecGetPicItem(handle=0x%x, picItem=**0x%x)", handle, picItem); + + const auto vdec = Emu.GetIdManager().GetIDData(handle); + + if (!vdec) { return CELL_VDEC_ERROR_ARG; } @@ -746,7 +818,7 @@ int cellVdecGetPicItem(u32 handle, vm::ptr picItem_ptr) AVFrame& frame = *vf.data; - auto info = vm::ptr::make(vdec->memAddr + vdec->memBias); + const auto info = vm::ptr::make(vdec->memAddr + vdec->memBias); vdec->memBias += 512; if (vdec->memBias + 512 > vdec->memSize) @@ -867,16 +939,17 @@ int cellVdecGetPicItem(u32 handle, vm::ptr picItem_ptr) cellVdec.Fatal("cellVdecGetPicItem(MPEG2)"); } - *picItem_ptr = info.addr(); + *picItem = info; return CELL_OK; } -int cellVdecSetFrameRate(u32 handle, CellVdecFrameRate frc) +s32 cellVdecSetFrameRate(u32 handle, CellVdecFrameRate frc) { - cellVdec.Log("cellVdecSetFrameRate(handle=%d, frc=0x%x)", handle, frc); + cellVdec.Log("cellVdecSetFrameRate(handle=0x%x, frc=0x%x)", handle, frc); - std::shared_ptr vdec; - if (!Emu.GetIdManager().GetIDData(handle, vdec)) + const auto vdec = Emu.GetIdManager().GetIDData(handle); + + if (!vdec) { return CELL_VDEC_ERROR_ARG; } @@ -900,6 +973,7 @@ Module cellVdec("cellVdec", []() REG_FUNC(cellVdec, cellVdecEndSeq); REG_FUNC(cellVdec, cellVdecDecodeAu); REG_FUNC(cellVdec, cellVdecGetPicture); + REG_UNNAMED(cellVdec, a21aa896); REG_FUNC(cellVdec, cellVdecGetPicItem); REG_FUNC(cellVdec, cellVdecSetFrameRate); }); diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.h b/rpcs3/Emu/SysCalls/Modules/cellVdec.h index 4770a10d13..66de0968fe 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.h @@ -12,7 +12,7 @@ enum CELL_VDEC_ERROR_FATAL = 0x80610180, }; -enum CellVdecCodecType +enum CellVdecCodecType : u32 { CELL_VDEC_CODEC_TYPE_MPEG2 = 0x00000000, CELL_VDEC_CODEC_TYPE_AVC = 0x00000001, @@ -20,7 +20,7 @@ enum CellVdecCodecType }; // Callback Messages -enum CellVdecMsgType +enum CellVdecMsgType : u32 { CELL_VDEC_MSG_TYPE_AUDONE, // decoding finished CELL_VDEC_MSG_TYPE_PICOUT, // picture done @@ -37,7 +37,7 @@ enum CellVdecDecodeMode : u32 }; // Output Picture Format Type -enum CellVdecPicFormatType +enum CellVdecPicFormatType : u32 { CELL_VDEC_PICFMT_ARGB32_ILV, CELL_VDEC_PICFMT_RGBA32_ILV, @@ -46,13 +46,13 @@ enum CellVdecPicFormatType }; // Output Color Matrix Coef -enum CellVdecColorMatrixType +enum CellVdecColorMatrixType : u32 { CELL_VDEC_COLOR_MATRIX_TYPE_BT601, CELL_VDEC_COLOR_MATRIX_TYPE_BT709, }; -enum CellVdecPicAttr +enum CellVdecPicAttr : u32 { CELL_VDEC_PICITEM_ATTR_NORMAL, CELL_VDEC_PICITEM_ATTR_SKIPPED, @@ -163,6 +163,15 @@ struct CellVdecPicFormat u8 alpha; }; +struct CellVdecPicFormat2 +{ + be_t formatType; + be_t colorMatrixType; + be_t unk0; + u8 alpha; + be_t unk1; +}; + typedef u32(CellVdecCbMsg)(u32 handle, CellVdecMsgType msgType, s32 msgData, u32 cbArg); // Callback Function Information @@ -349,8 +358,6 @@ struct CellVdecAvcInfo be_t reserved[2]; }; -const int sz = sizeof(CellVdecAvcInfo); - // DIVX Profile enum DIVX_level : u8 { diff --git a/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp b/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp index 910b1c731e..9691ff1d93 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVpost.cpp @@ -13,9 +13,9 @@ extern "C" extern Module cellVpost; -int cellVpostQueryAttr(vm::ptr cfgParam, vm::ptr attr) +s32 cellVpostQueryAttr(vm::ptr cfgParam, vm::ptr attr) { - cellVpost.Warning("cellVpostQueryAttr(cfgParam_addr=0x%x, attr_addr=0x%x)", cfgParam.addr(), attr.addr()); + cellVpost.Warning("cellVpostQueryAttr(cfgParam=*0x%x, attr=*0x%x)", cfgParam, attr); // TODO: check cfgParam and output values @@ -37,32 +37,31 @@ u32 vpostOpen(VpostInstance* data) return id; } -int cellVpostOpen(vm::ptr cfgParam, vm::ptr resource, vm::ptr handle) +s32 cellVpostOpen(vm::ptr cfgParam, vm::ptr resource, vm::ptr handle) { - cellVpost.Warning("cellVpostOpen(cfgParam_addr=0x%x, resource_addr=0x%x, handle_addr=0x%x)", - cfgParam.addr(), resource.addr(), handle.addr()); + cellVpost.Warning("cellVpostOpen(cfgParam=*0x%x, resource=*0x%x, handle=*0x%x)", cfgParam, resource, handle); // TODO: check values *handle = vpostOpen(new VpostInstance(cfgParam->outPicFmt == CELL_VPOST_PIC_FMT_OUT_RGBA_ILV)); return CELL_OK; } -int cellVpostOpenEx(vm::ptr cfgParam, vm::ptr resource, vm::ptr handle) +s32 cellVpostOpenEx(vm::ptr cfgParam, vm::ptr resource, vm::ptr handle) { - cellVpost.Warning("cellVpostOpenEx(cfgParam_addr=0x%x, resource_addr=0x%x, handle_addr=0x%x)", - cfgParam.addr(), resource.addr(), handle.addr()); + cellVpost.Warning("cellVpostOpenEx(cfgParam=*0x%x, resource=*0x%x, handle=*0x%x)", cfgParam, resource, handle); // TODO: check values *handle = vpostOpen(new VpostInstance(cfgParam->outPicFmt == CELL_VPOST_PIC_FMT_OUT_RGBA_ILV)); return CELL_OK; } -int cellVpostClose(u32 handle) +s32 cellVpostClose(u32 handle) { cellVpost.Warning("cellVpostClose(handle=0x%x)", handle); - std::shared_ptr vpost; - if (!Emu.GetIdManager().GetIDData(handle, vpost)) + const auto vpost = Emu.GetIdManager().GetIDData(handle); + + if (!vpost) { return CELL_VPOST_ERROR_C_ARG_HDL_INVALID; } @@ -71,14 +70,13 @@ int cellVpostClose(u32 handle) return CELL_OK; } -int cellVpostExec(u32 handle, vm::ptr inPicBuff, vm::ptr ctrlParam, - vm::ptr outPicBuff, vm::ptr picInfo) +s32 cellVpostExec(u32 handle, vm::ptr inPicBuff, vm::ptr ctrlParam, vm::ptr outPicBuff, vm::ptr picInfo) { - cellVpost.Log("cellVpostExec(handle=0x%x, inPicBuff_addr=0x%x, ctrlParam_addr=0x%x, outPicBuff_addr=0x%x, picInfo_addr=0x%x)", - handle, inPicBuff.addr(), ctrlParam.addr(), outPicBuff.addr(), picInfo.addr()); + cellVpost.Log("cellVpostExec(handle=0x%x, inPicBuff=*0x%x, ctrlParam=*0x%x, outPicBuff=*0x%x, picInfo=*0x%x)", handle, inPicBuff, ctrlParam, outPicBuff, picInfo); - std::shared_ptr vpost; - if (!Emu.GetIdManager().GetIDData(handle, vpost)) + const auto vpost = Emu.GetIdManager().GetIDData(handle); + + if (!vpost) { return CELL_VPOST_ERROR_E_ARG_HDL_INVALID; } diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp index dcf5cc2863..ca2bd68e5d 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -23,7 +23,7 @@ std::vector ssp; int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, vm::ptr addr, u32 samples) { - libmixer.Log("cellAANAddData(handle=%d, port=%d, offset=0x%x, addr_addr=0x%x, samples=%d)", aan_handle, aan_port, offset, addr.addr(), samples); + libmixer.Log("cellAANAddData(handle=0x%x, port=0x%x, offset=0x%x, addr_addr=0x%x, samples=%d)", aan_handle, aan_port, offset, addr.addr(), samples); u32 type = aan_port >> 16; u32 port = aan_port & 0xffff; @@ -44,7 +44,7 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, vm::ptr addr if (aan_handle != 0x11111111 || samples != 256 || !type || offset != 0) { - libmixer.Error("cellAANAddData(handle=%d, port=%d, offset=0x%x, addr_addr=0x%x, samples=%d): invalid parameters", aan_handle, aan_port, offset, addr.addr(), samples); + libmixer.Error("cellAANAddData(handle=0x%x, port=0x%x, offset=0x%x, addr_addr=0x%x, samples=%d): invalid parameters", aan_handle, aan_port, offset, addr.addr(), samples); return CELL_LIBMIXER_ERROR_INVALID_PARAMATER; } @@ -104,7 +104,7 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, vm::ptr addr int cellAANConnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) { - libmixer.Warning("cellAANConnect(receive=%d, receivePortNo=%d, source=%d, sourcePortNo=%d)", + libmixer.Warning("cellAANConnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcePortNo=0x%x)", receive, receivePortNo, source, sourcePortNo); std::lock_guard lock(mixer_mutex); @@ -122,7 +122,7 @@ int cellAANConnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) int cellAANDisconnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) { - libmixer.Warning("cellAANDisconnect(receive=%d, receivePortNo=%d, source=%d, sourcePortNo=%d)", + libmixer.Warning("cellAANDisconnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcePortNo=0x%x)", receive, receivePortNo, source, sourcePortNo); std::lock_guard lock(mixer_mutex); @@ -165,7 +165,7 @@ int cellSSPlayerCreate(vm::ptr handle, vm::ptr config) int cellSSPlayerRemove(u32 handle) { - libmixer.Warning("cellSSPlayerRemove(handle=%d)", handle); + libmixer.Warning("cellSSPlayerRemove(handle=0x%x)", handle); std::lock_guard lock(mixer_mutex); @@ -184,7 +184,7 @@ int cellSSPlayerRemove(u32 handle) int cellSSPlayerSetWave(u32 handle, vm::ptr waveInfo, vm::ptr commonInfo) { - libmixer.Warning("cellSSPlayerSetWave(handle=%d, waveInfo_addr=0x%x, commonInfo_addr=0x%x)", + libmixer.Warning("cellSSPlayerSetWave(handle=0x%x, waveInfo_addr=0x%x, commonInfo_addr=0x%x)", handle, waveInfo.addr(), commonInfo.addr()); std::lock_guard lock(mixer_mutex); @@ -208,7 +208,7 @@ int cellSSPlayerSetWave(u32 handle, vm::ptr waveInfo, vm: int cellSSPlayerPlay(u32 handle, vm::ptr info) { - libmixer.Warning("cellSSPlayerPlay(handle=%d, info_addr=0x%x)", handle, info.addr()); + libmixer.Warning("cellSSPlayerPlay(handle=0x%x, info_addr=0x%x)", handle, info.addr()); std::lock_guard lock(mixer_mutex); @@ -232,7 +232,7 @@ int cellSSPlayerPlay(u32 handle, vm::ptr info) int cellSSPlayerStop(u32 handle, u32 mode) { - libmixer.Warning("cellSSPlayerStop(handle=%d, mode=0x%x)", handle, mode); + libmixer.Warning("cellSSPlayerStop(handle=0x%x, mode=0x%x)", handle, mode); std::lock_guard lock(mixer_mutex); @@ -251,7 +251,7 @@ int cellSSPlayerStop(u32 handle, u32 mode) int cellSSPlayerSetParam(u32 handle, vm::ptr info) { - libmixer.Warning("cellSSPlayerSetParam(handle=%d, info_addr=0x%x)", handle, info.addr()); + libmixer.Warning("cellSSPlayerSetParam(handle=0x%x, info_addr=0x%x)", handle, info.addr()); std::lock_guard lock(mixer_mutex); @@ -274,7 +274,7 @@ int cellSSPlayerSetParam(u32 handle, vm::ptr info) int cellSSPlayerGetState(u32 handle) { - libmixer.Warning("cellSSPlayerGetState(handle=%d)", handle); + libmixer.Warning("cellSSPlayerGetState(handle=0x%x)", handle); std::lock_guard lock(mixer_mutex); @@ -319,8 +319,7 @@ int cellSurMixerCreate(vm::ptr config) port.size = port.channel * port.block * AUDIO_SAMPLES * sizeof(float); port.tag = 0; port.level = 1.0f; - port.level_set = 1.0f; - port.level_inc = 0.0f; + port.level_set.data = { 1.0f, 0.0f }; libmixer.Warning("*** audio port opened (port=%d)", g_surmx.audio_port); diff --git a/rpcs3/Emu/SysCalls/Modules/sceNp.cpp b/rpcs3/Emu/SysCalls/Modules/sceNp.cpp index 82b7f305fe..20367f4c82 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNp.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNp.cpp @@ -5,7 +5,7 @@ #include "Emu/SysCalls/lv2/sys_process.h" #include "Emu/FS/VFS.h" -#include "Utilities/rFile.h" +#include "Utilities/File.h" #include "Emu/FS/vfsDir.h" #include "Crypto/unedat.h" #include "sceNp.h" @@ -140,8 +140,8 @@ int npDrmIsAvailable(u32 k_licensee_addr, vm::ptr drm_path) if (DecryptEDAT(enc_drm_path_local, dec_drm_path_local, 8, rap_path_local, k_licensee, false) >= 0) { // If decryption succeeds, replace the encrypted file with it. - rRemoveFile(enc_drm_path_local); - rRename(dec_drm_path_local, enc_drm_path_local); + fs::remove_file(enc_drm_path_local); + fs::rename(dec_drm_path_local, enc_drm_path_local); } return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp index fb657fe3c4..5bc935199b 100644 --- a/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sceNpTrophy.cpp @@ -79,7 +79,7 @@ static sceNpTrophyInternalContext& getContext(u32 context) { // Functions int sceNpTrophyInit(u32 pool_addr, u32 poolSize, u32 containerId, u64 options) { - sceNpTrophy.Log("sceNpTrophyInit(pool_addr=0x%x, poolSize=%d, containerId=%d, options=0x%llx)", pool_addr, poolSize, containerId, options); + sceNpTrophy.Log("sceNpTrophyInit(pool_addr=0x%x, poolSize=%d, containerId=0x%x, options=0x%llx)", pool_addr, poolSize, containerId, options); if (sceNpTrophyInstance.m_bInitialized) return SCE_NP_TROPHY_ERROR_ALREADY_INITIALIZED; @@ -145,7 +145,7 @@ int sceNpTrophyCreateHandle(vm::ptr handle) int sceNpTrophyRegisterContext(u32 context, u32 handle, vm::ptr statusCb, u32 arg_addr, u64 options) { - sceNpTrophy.Warning("sceNpTrophyRegisterContext(context=%d, handle=%d, statusCb_addr=0x%x, arg_addr=0x%x, options=0x%llx)", + sceNpTrophy.Warning("sceNpTrophyRegisterContext(context=0x%x, handle=0x%x, statusCb_addr=0x%x, arg_addr=0x%x, options=0x%llx)", context, handle, statusCb.addr(), arg_addr, options); if (!(sceNpTrophyInstance.m_bInitialized)) @@ -224,7 +224,7 @@ int sceNpTrophySetSoundLevel() int sceNpTrophyGetRequiredDiskSpace(u32 context, u32 handle, vm::ptr reqspace, u64 options) { - sceNpTrophy.Warning("sceNpTrophyGetRequiredDiskSpace(context=%d, handle=%d, reqspace_addr=0x%x, options=0x%llx)", + sceNpTrophy.Warning("sceNpTrophyGetRequiredDiskSpace(context=0x%x, handle=0x%x, reqspace_addr=0x%x, options=0x%llx)", context, handle, reqspace.addr(), options); if (!sceNpTrophyInstance.m_bInitialized) @@ -251,7 +251,7 @@ int sceNpTrophyDestroyContext() int sceNpTrophyAbortHandle(u32 handle) { - sceNpTrophy.Todo("sceNpTrophyAbortHandle(handle=%d)", handle); + sceNpTrophy.Todo("sceNpTrophyAbortHandle(handle=0x%x)", handle); // TODO: ? @@ -263,7 +263,7 @@ int sceNpTrophyAbortHandle(u32 handle) int sceNpTrophyGetGameInfo(u32 context, u32 handle, vm::ptr details, vm::ptr data) { - sceNpTrophy.Warning("sceNpTrophyGetGameInfo(context=%d, handle=%d, details_addr=0x%x, data_addr=0x%x)", + sceNpTrophy.Warning("sceNpTrophyGetGameInfo(context=0x%x, handle=0x%x, details_addr=0x%x, data_addr=0x%x)", context, handle, details.addr(), data.addr()); if (!sceNpTrophyInstance.m_bInitialized) @@ -321,7 +321,7 @@ int sceNpTrophyDestroyHandle() int sceNpTrophyUnlockTrophy(u32 context, u32 handle, s32 trophyId, vm::ptr platinumId) { - sceNpTrophy.Warning("sceNpTrophyUnlockTrophy(context=%d, handle=%d, trophyId=%d, platinumId_addr=0x%x)", + sceNpTrophy.Warning("sceNpTrophyUnlockTrophy(context=0x%x, handle=0x%x, trophyId=%d, platinumId_addr=0x%x)", context, handle, trophyId, platinumId.addr()); if (!sceNpTrophyInstance.m_bInitialized) @@ -358,7 +358,7 @@ int sceNpTrophyTerm() int sceNpTrophyGetTrophyUnlockState(u32 context, u32 handle, vm::ptr flags, vm::ptr count) { - sceNpTrophy.Warning("sceNpTrophyGetTrophyUnlockState(context=%d, handle=%d, flags_addr=0x%x, count_addr=0x%x)", + sceNpTrophy.Warning("sceNpTrophyGetTrophyUnlockState(context=0x%x, handle=0x%x, flags_addr=0x%x, count_addr=0x%x)", context, handle, flags.addr(), count.addr()); if (!sceNpTrophyInstance.m_bInitialized) @@ -395,7 +395,7 @@ int sceNpTrophyGetTrophyIcon() int sceNpTrophyGetTrophyInfo(u32 context, u32 handle, s32 trophyId, vm::ptr details, vm::ptr data) { - sceNpTrophy.Warning("sceNpTrophyGetTrophyInfo(context=%d, handle=%d, trophyId=%d, details_addr=0x%x, data_addr=0x%x)", + sceNpTrophy.Warning("sceNpTrophyGetTrophyInfo(context=0x%x, handle=0x%x, trophyId=%d, details_addr=0x%x, data_addr=0x%x)", context, handle, trophyId, details.addr(), data.addr()); if (!sceNpTrophyInstance.m_bInitialized) diff --git a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp index f5d3426e95..b0d5761d15 100644 --- a/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sysPrxForUser.cpp @@ -117,7 +117,7 @@ s32 sys_lwmutex_create(vm::ptr lwmutex, vm::ptrlock_var = { { lwmutex::free, lwmutex::zero } }; lwmutex->attribute = attr->recursive | attr->protocol; lwmutex->recursive_count = 0; - lwmutex->sleep_queue = Emu.GetIdManager().GetNewID(lw); + lwmutex->sleep_queue = Emu.GetIdManager().GetNewID(lw, TYPE_LWMUTEX); return CELL_OK; } @@ -501,7 +501,7 @@ s32 sys_lwcond_signal_all(PPUThread& CPU, vm::ptr lwcond) s32 sys_lwcond_signal_to(PPUThread& CPU, vm::ptr lwcond, u32 ppu_thread_id) { - sysPrxForUser.Log("sys_lwcond_signal_to(lwcond=*0x%x, ppu_thread_id=%d)", lwcond, ppu_thread_id); + sysPrxForUser.Log("sys_lwcond_signal_to(lwcond=*0x%x, ppu_thread_id=0x%x)", lwcond, ppu_thread_id); const vm::ptr lwmutex = lwcond->lwmutex; @@ -579,7 +579,7 @@ s32 sys_lwcond_wait(PPUThread& CPU, vm::ptr lwcond, u64 timeout) lwmutex->recursive_count = 0; // call the syscall - s32 res = _sys_lwcond_queue_wait(lwcond->lwcond_queue, lwmutex->sleep_queue, timeout); + s32 res = _sys_lwcond_queue_wait(CPU, lwcond->lwcond_queue, lwmutex->sleep_queue, timeout); if (res == CELL_OK || res == CELL_ESRCH) { @@ -821,7 +821,7 @@ s64 _sys_process_at_Exitspawn() s32 sys_interrupt_thread_disestablish(PPUThread& CPU, u32 ih) { - sysPrxForUser.Todo("sys_interrupt_thread_disestablish(ih=%d)", ih); + sysPrxForUser.Todo("sys_interrupt_thread_disestablish(ih=0x%x)", ih); return _sys_interrupt_thread_disestablish(ih, vm::stackvar>(CPU)); } @@ -982,6 +982,13 @@ vm::ptr _sys_strcat(vm::ptr dest, vm::ptr source) return dest; } +vm::ptr _sys_strchr(vm::ptr str, s32 ch) +{ + sysPrxForUser.Log("_sys_strchr(str=*0x%x, ch=0x%x)", str, ch); + + return vm::ptr::make(vm::get_addr(strchr(str.get_ptr(), ch))); +} + vm::ptr _sys_strncat(vm::ptr dest, vm::ptr source, u32 len) { sysPrxForUser.Log("_sys_strncat(dest=*0x%x, source=*0x%x, len=%d)", dest, source, len); @@ -1012,7 +1019,7 @@ vm::ptr _sys_strncpy(vm::ptr dest, vm::ptr source, u32 l if (!dest || !source) { - return vm::ptr::make(0); + return vm::null; } if (strncpy(dest.get_ptr(), source.get_ptr(), len) != dest.get_ptr()) @@ -1053,7 +1060,7 @@ s32 _sys_spu_printf_finalize() s32 _sys_spu_printf_attach_group(PPUThread& CPU, u32 group) { - sysPrxForUser.Warning("_sys_spu_printf_attach_group(group=%d)", group); + sysPrxForUser.Warning("_sys_spu_printf_attach_group(group=0x%x)", group); if (!spu_printf_agcb) { @@ -1065,7 +1072,7 @@ s32 _sys_spu_printf_attach_group(PPUThread& CPU, u32 group) s32 _sys_spu_printf_detach_group(PPUThread& CPU, u32 group) { - sysPrxForUser.Warning("_sys_spu_printf_detach_group(group=%d)", group); + sysPrxForUser.Warning("_sys_spu_printf_detach_group(group=0x%x)", group); if (!spu_printf_dgcb) { @@ -1077,7 +1084,7 @@ s32 _sys_spu_printf_detach_group(PPUThread& CPU, u32 group) s32 _sys_spu_printf_attach_thread(PPUThread& CPU, u32 thread) { - sysPrxForUser.Warning("_sys_spu_printf_attach_thread(thread=%d)", thread); + sysPrxForUser.Warning("_sys_spu_printf_attach_thread(thread=0x%x)", thread); if (!spu_printf_atcb) { @@ -1089,7 +1096,7 @@ s32 _sys_spu_printf_attach_thread(PPUThread& CPU, u32 thread) s32 _sys_spu_printf_detach_thread(PPUThread& CPU, u32 thread) { - sysPrxForUser.Warning("_sys_spu_printf_detach_thread(thread=%d)", thread); + sysPrxForUser.Warning("_sys_spu_printf_detach_thread(thread=0x%x)", thread); if (!spu_printf_dtcb) { @@ -1149,7 +1156,7 @@ s32 _sys_printf(vm::ptr fmt) // va_args... sysPrxForUser.Todo("_sys_printf(fmt=*0x%x, ...)", fmt); // probably, assertion failed - sysPrxForUser.Warning("_sys_printf: \n%s", fmt.get_ptr()); + sysPrxForUser.Fatal("_sys_printf: \n%s", fmt.get_ptr()); Emu.Pause(); return CELL_OK; } @@ -1210,6 +1217,65 @@ void sys_spinlock_unlock(vm::ptr> lock) g_sys_spinlock_wm.notify(lock.addr()); } +s32 sys_ppu_thread_create(PPUThread& CPU, vm::ptr thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr threadname) +{ + sysPrxForUser.Warning("sys_ppu_thread_create(thread_id=*0x%x, entry=0x%x, arg=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname=*0x%x)", thread_id, entry, arg, prio, stacksize, flags, threadname); + + // (allocate TLS) + // (return CELL_ENOMEM if failed) + // ... + + vm::stackvar attr(CPU); + + attr->entry = entry; + attr->tls = 0; + + // call the syscall + if (s32 res = _sys_ppu_thread_create(thread_id, attr, arg, 0, prio, stacksize, flags, threadname)) + { + return res; + } + + // run the thread + return flags & SYS_PPU_THREAD_CREATE_INTERRUPT ? CELL_OK : sys_ppu_thread_start(static_cast(*thread_id)); +} + +s32 sys_ppu_thread_get_id(PPUThread& CPU, vm::ptr thread_id) +{ + sysPrxForUser.Log("sys_ppu_thread_get_id(thread_id=*0x%x)", thread_id); + + *thread_id = CPU.GetId(); + + return CELL_OK; +} + +void sys_ppu_thread_exit(PPUThread& CPU, u64 val) +{ + sysPrxForUser.Log("sys_ppu_thread_exit(val=0x%llx)", val); + + // (call registered atexit functions) + // (deallocate TLS) + // ... + + // call the syscall + _sys_ppu_thread_exit(CPU, val); +} + +std::mutex g_once_mutex; + +void sys_ppu_thread_once(PPUThread& CPU, vm::ptr> once_ctrl, vm::ptr init) +{ + sysPrxForUser.Warning("sys_ppu_thread_once(once_ctrl=*0x%x, init=*0x%x)", once_ctrl, init); + + std::lock_guard lock(g_once_mutex); + + if (once_ctrl->compare_and_swap_test(be_t::make(SYS_PPU_THREAD_ONCE_INIT), be_t::make(SYS_PPU_THREAD_DONE_INIT))) + { + // call init function using current thread context + init(CPU); + } +} + Module sysPrxForUser("sysPrxForUser", []() { g_tls_start = 0; @@ -1304,6 +1370,7 @@ Module sysPrxForUser("sysPrxForUser", []() REG_FUNC(sysPrxForUser, _sys_strcmp); REG_FUNC(sysPrxForUser, _sys_strncmp); REG_FUNC(sysPrxForUser, _sys_strcat); + REG_FUNC(sysPrxForUser, _sys_strchr); REG_FUNC(sysPrxForUser, _sys_strncat); REG_FUNC(sysPrxForUser, _sys_strcpy); REG_FUNC(sysPrxForUser, _sys_strncpy); diff --git a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp b/rpcs3/Emu/SysCalls/Modules/sys_net.cpp index fe69ad6560..4dcfe97863 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_net.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_net.cpp @@ -19,7 +19,7 @@ extern "C" extern Module sys_net; -vm::ptr g_lastError = vm::ptr::make(0); +vm::ptr g_lastError = vm::null; // Auxiliary Functions @@ -478,7 +478,7 @@ s32 sys_net_finalize_network() { sys_net.Warning("sys_net_initialize_network_ex()"); Memory.Free(g_lastError.addr()); - g_lastError = vm::ptr::make(0); + g_lastError = vm::null; #ifdef _WIN32 WSACleanup(); #endif diff --git a/rpcs3/Emu/SysCalls/SyncPrimitivesManager.cpp b/rpcs3/Emu/SysCalls/SyncPrimitivesManager.cpp deleted file mode 100644 index 9ddad0616c..0000000000 --- a/rpcs3/Emu/SysCalls/SyncPrimitivesManager.cpp +++ /dev/null @@ -1,75 +0,0 @@ -#include "stdafx.h" -#include "Utilities/Log.h" -#include "Emu/System.h" -#include "Emu/IdManager.h" -#include "Utilities/Thread.h" - -#include "lv2/sleep_queue.h" -#include "lv2/sys_lwmutex.h" -#include "lv2/sys_lwcond.h" -#include "lv2/sys_mutex.h" -#include "lv2/sys_cond.h" -#include "lv2/sys_semaphore.h" -#include "SyncPrimitivesManager.h" - -SemaphoreAttributes SyncPrimManager::GetSemaphoreData(u32 id) -{ - std::shared_ptr sem; - if (!Emu.GetIdManager().GetIDData(id, sem)) - { - return{}; - } - - return{ std::string((const char*)&sem->name, 8), sem->value, sem->max }; -} - -LwMutexAttributes SyncPrimManager::GetLwMutexData(u32 id) -{ - std::shared_ptr sq; - if (!Emu.GetIdManager().GetIDData(id, sq)) - { - return{}; - } - - return{ std::string((const char*)&sq->name, 8) }; -} - -std::string SyncPrimManager::GetSyncPrimName(u32 id, IDType type) -{ - switch (type) - { - case TYPE_LWCOND: - { - std::shared_ptr lw; - if (Emu.GetIdManager().GetIDData(id, lw)) - { - return std::string((const char*)&lw->name, 8); - } - break; - } - - case TYPE_MUTEX: - { - std::shared_ptr mutex; - if (Emu.GetIdManager().GetIDData(id, mutex)) - { - return std::string((const char*)&mutex->name, 8); - } - break; - } - - case TYPE_COND: - { - std::shared_ptr cond; - if (Emu.GetIdManager().GetIDData(id, cond)) - { - return std::string((const char*)&cond->name, 8); - } - break; - } - default: break; - } - - LOG_ERROR(GENERAL, "SyncPrimManager::GetSyncPrimName(id=%d, type=%d) failed", id, type); - return "NOT_FOUND"; -} diff --git a/rpcs3/Emu/SysCalls/SyncPrimitivesManager.h b/rpcs3/Emu/SysCalls/SyncPrimitivesManager.h deleted file mode 100644 index 34f20c05f8..0000000000 --- a/rpcs3/Emu/SysCalls/SyncPrimitivesManager.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -struct SemaphoreAttributes -{ - std::string name; - s32 count; - s32 max_count; -}; - -struct LwMutexAttributes -{ - std::string name; -}; - -class SyncPrimManager -{ -private: - -public: - SemaphoreAttributes GetSemaphoreData(u32 id); - LwMutexAttributes GetLwMutexData(u32 id); - std::string GetSyncPrimName(u32 id, IDType type); - - void Close() - { - } -}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/SysCalls.cpp b/rpcs3/Emu/SysCalls/SysCalls.cpp index fa4a7db522..7f3608fbfb 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.cpp +++ b/rpcs3/Emu/SysCalls/SysCalls.cpp @@ -75,7 +75,7 @@ const ppu_func_caller sc_table[1024] = null_func, null_func, null_func, null_func, null_func, null_func, null_func, null_func, null_func, //32-40 UNS - bind_func(sys_internal_ppu_thread_exit), //41 (0x029) + bind_func(_sys_ppu_thread_exit), //41 (0x029) null_func, //42 (0x02A) UNS bind_func(sys_ppu_thread_yield), //43 (0x02B) bind_func(sys_ppu_thread_join), //44 (0x02C) @@ -86,8 +86,8 @@ const ppu_func_caller sc_table[1024] = bind_func(sys_ppu_thread_get_stack_information), //49 (0x031) null_func,//bind_func(sys_ppu_thread_stop), //50 (0x032) ROOT null_func,//bind_func(sys_ppu_thread_restart), //51 (0x033) ROOT - null_func,//bind_func(sys_ppu_thread_create), //52 (0x034) DBG - null_func,//bind_func(sys_ppu_thread_start), //53 (0x035) + bind_func(_sys_ppu_thread_create), //52 (0x034) DBG + bind_func(sys_ppu_thread_start), //53 (0x035) null_func,//bind_func(sys_ppu_...), //54 (0x036) ROOT null_func,//bind_func(sys_ppu_...), //55 (0x037) ROOT bind_func(sys_ppu_thread_rename), //56 (0x038) @@ -888,34 +888,32 @@ const ppu_func_caller sc_table[1024] = void null_func(PPUThread& CPU) { - LOG_ERROR(HLE, "Unimplemented syscall %lld: %s -> CELL_OK", CPU.GPR[11], SysCalls::GetFuncName(CPU.GPR[11])); + const auto code = CPU.GPR[11]; + LOG_ERROR(HLE, "Unimplemented syscall %lld: %s -> CELL_OK", code, SysCalls::GetFuncName(~code)); CPU.GPR[3] = 0; - return; } void SysCalls::DoSyscall(PPUThread& CPU, u64 code) { - auto old_last_syscall = CPU.m_last_syscall; - CPU.m_last_syscall = code; - if (code >= 1024) { + CPU.m_last_syscall = code; throw "Invalid syscall number"; } - - //Auto Pause using simple singleton. - Debug::AutoPause::getInstance().TryPause(code); + + auto old_last_syscall = CPU.m_last_syscall; + CPU.m_last_syscall = ~code; if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(PPU, "Syscall %d called: %s", code, SysCalls::GetFuncName(code)); + LOG_NOTICE(PPU, "Syscall %lld called: %s", code, SysCalls::GetFuncName(~code)); } sc_table[code](CPU); if (Ini.HLELogging.GetValue()) { - LOG_NOTICE(PPU, "Syscall %d finished: %s -> 0x%llx", code, SysCalls::GetFuncName(code), CPU.GPR[3]); + LOG_NOTICE(PPU, "Syscall %lld finished: %s -> 0x%llx", code, SysCalls::GetFuncName(~code), CPU.GPR[3]); } CPU.m_last_syscall = old_last_syscall; diff --git a/rpcs3/Emu/SysCalls/lv2/sleep_queue.cpp b/rpcs3/Emu/SysCalls/lv2/sleep_queue.cpp index cc1ebc702f..0cf0fa52f7 100644 --- a/rpcs3/Emu/SysCalls/lv2/sleep_queue.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sleep_queue.cpp @@ -149,7 +149,7 @@ u32 sleep_queue_t::signal(u32 protocol) u64 sel = ~0ull; for (auto& v : m_waiting) { - if (std::shared_ptr t = Emu.GetCPU().GetThread(v)) + if (const auto t = Emu.GetCPU().GetThread(v)) { const u64 prio = t->GetPrio(); if (prio < highest_prio) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp index 844fb58641..6dab5c62b4 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_cond.cpp @@ -15,13 +15,13 @@ SysCallBase sys_cond("sys_cond"); s32 sys_cond_create(vm::ptr cond_id, u32 mutex_id, vm::ptr attr) { - sys_cond.Warning("sys_cond_create(cond_id=*0x%x, mutex_id=%d, attr=*0x%x)", cond_id, mutex_id, attr); + sys_cond.Warning("sys_cond_create(cond_id=*0x%x, mutex_id=0x%x, attr=*0x%x)", cond_id, mutex_id, attr); LV2_LOCK; - std::shared_ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(mutex_id); - if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } @@ -46,18 +46,18 @@ s32 sys_cond_create(vm::ptr cond_id, u32 mutex_id, vm::ptr cond; + const auto cond = Emu.GetIdManager().GetIDData(cond_id); - if (!Emu.GetIdManager().GetIDData(cond_id, cond)) + if (!cond) { return CELL_ESRCH; } - if (cond->waiters || cond->signaled) + if (!cond->waiters.empty() || cond->signaled) { return CELL_EBUSY; } @@ -74,21 +74,21 @@ s32 sys_cond_destroy(u32 cond_id) s32 sys_cond_signal(u32 cond_id) { - sys_cond.Log("sys_cond_signal(cond_id=%d)", cond_id); + sys_cond.Log("sys_cond_signal(cond_id=0x%x)", cond_id); LV2_LOCK; - std::shared_ptr cond; + const auto cond = Emu.GetIdManager().GetIDData(cond_id); - if (!Emu.GetIdManager().GetIDData(cond_id, cond)) + if (!cond) { return CELL_ESRCH; } - if (cond->waiters) + if (!cond->waiters.empty()) { cond->signaled++; - cond->waiters--; + cond->waiters.erase(cond->waiters.begin()); cond->cv.notify_one(); } @@ -97,20 +97,21 @@ s32 sys_cond_signal(u32 cond_id) s32 sys_cond_signal_all(u32 cond_id) { - sys_cond.Log("sys_cond_signal_all(cond_id=%d)", cond_id); + sys_cond.Log("sys_cond_signal_all(cond_id=0x%x)", cond_id); LV2_LOCK; - std::shared_ptr cond; + const auto cond = Emu.GetIdManager().GetIDData(cond_id); - if (!Emu.GetIdManager().GetIDData(cond_id, cond)) + if (!cond) { return CELL_ESRCH; } - if (cond->waiters) + if (const u32 count = vm::cast(cond->waiters.size())) { - cond->signaled += cond->waiters.exchange(0); + cond->signaled += count; + cond->waiters.clear(); cond->cv.notify_all(); } @@ -119,13 +120,13 @@ s32 sys_cond_signal_all(u32 cond_id) s32 sys_cond_signal_to(u32 cond_id, u32 thread_id) { - sys_cond.Todo("sys_cond_signal_to(cond_id=%d, thread_id=%d)", cond_id, thread_id); + sys_cond.Log("sys_cond_signal_to(cond_id=0x%x, thread_id=0x%x)", cond_id, thread_id); LV2_LOCK; - std::shared_ptr cond; + const auto cond = Emu.GetIdManager().GetIDData(cond_id); - if (!Emu.GetIdManager().GetIDData(cond_id, cond)) + if (!cond) { return CELL_ESRCH; } @@ -135,13 +136,15 @@ s32 sys_cond_signal_to(u32 cond_id, u32 thread_id) return CELL_ESRCH; } - if (!cond->waiters) + const auto found = cond->waiters.find(thread_id); + + if (found == cond->waiters.end()) { return CELL_EPERM; } cond->signaled++; - cond->waiters--; + cond->waiters.erase(found); cond->cv.notify_one(); return CELL_OK; @@ -149,28 +152,28 @@ s32 sys_cond_signal_to(u32 cond_id, u32 thread_id) s32 sys_cond_wait(PPUThread& CPU, u32 cond_id, u64 timeout) { - sys_cond.Log("sys_cond_wait(cond_id=%d, timeout=%lld)", cond_id, timeout); + sys_cond.Log("sys_cond_wait(cond_id=0x%x, timeout=%lld)", cond_id, timeout); const u64 start_time = get_system_time(); LV2_LOCK; - std::shared_ptr cond; + const auto cond = Emu.GetIdManager().GetIDData(cond_id); - if (!Emu.GetIdManager().GetIDData(cond_id, cond)) + if (!cond) { return CELL_ESRCH; } - std::shared_ptr thread = Emu.GetCPU().GetThread(CPU.GetId()); + const auto thread = Emu.GetCPU().GetThread(CPU.GetId()); if (cond->mutex->owner.owner_before(thread) || thread.owner_before(cond->mutex->owner)) // check equality { return CELL_EPERM; } - // protocol is ignored in current implementation - cond->waiters++; + // add waiter; protocol is ignored in current implementation + cond->waiters.emplace(CPU.GetId()); // unlock mutex cond->mutex->owner.reset(); @@ -183,24 +186,28 @@ s32 sys_cond_wait(PPUThread& CPU, u32 cond_id, u64 timeout) // save recursive value const u32 recursive_value = cond->mutex->recursive_count.exchange(0); - while (!cond->mutex->owner.expired() || !cond->signaled) + while (!cond->mutex->owner.expired() || !cond->signaled || cond->waiters.count(CPU.GetId())) { const bool is_timedout = timeout && get_system_time() - start_time > timeout; - // check timeout only if no thread signaled (the flaw of avoiding sleep queue) - if (is_timedout && cond->mutex->owner.expired() && !cond->signaled) + // check timeout + if (is_timedout && cond->mutex->owner.expired()) { // cancel waiting if the mutex is free, restore its owner and recursive value cond->mutex->owner = thread; cond->mutex->recursive_count = recursive_value; - cond->waiters--; + + if (!cond->waiters.erase(CPU.GetId())) + { + throw __FUNCTION__; + } return CELL_ETIMEDOUT; } if (Emu.IsStopped()) { - sys_cond.Warning("sys_cond_wait(id=%d) aborted", cond_id); + sys_cond.Warning("sys_cond_wait(id=0x%x) aborted", cond_id); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_cond.h b/rpcs3/Emu/SysCalls/lv2/sys_cond.h index 6b2bda4720..43164e58c7 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_cond.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_cond.h @@ -24,9 +24,9 @@ struct cond_t // TODO: use sleep queue, possibly remove condition variable std::condition_variable cv; - std::atomic waiters; + std::unordered_set waiters; - cond_t(std::shared_ptr& mutex, u64 name) + cond_t(const std::shared_ptr& mutex, u64 name) : mutex(mutex) , name(name) , signaled(0) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp index fbe5ea7b8d..21f77b3b88 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event.cpp @@ -63,13 +63,13 @@ s32 sys_event_queue_create(vm::ptr equeue_id, vm::ptr s32 sys_event_queue_destroy(u32 equeue_id, s32 mode) { - sys_event.Warning("sys_event_queue_destroy(equeue_id=%d, mode=%d)", equeue_id, mode); + sys_event.Warning("sys_event_queue_destroy(equeue_id=0x%x, mode=%d)", equeue_id, mode); LV2_LOCK; - std::shared_ptr queue; + const auto queue = Emu.GetIdManager().GetIDData(equeue_id); - if (!Emu.GetIdManager().GetIDData(equeue_id, queue)) + if (!queue) { return CELL_ESRCH; } @@ -102,13 +102,13 @@ s32 sys_event_queue_destroy(u32 equeue_id, s32 mode) s32 sys_event_queue_tryreceive(u32 equeue_id, vm::ptr event_array, s32 size, vm::ptr number) { - sys_event.Log("sys_event_queue_tryreceive(equeue_id=%d, event_array=*0x%x, size=%d, number=*0x%x)", equeue_id, event_array, size, number); + sys_event.Log("sys_event_queue_tryreceive(equeue_id=0x%x, event_array=*0x%x, size=%d, number=*0x%x)", equeue_id, event_array, size, number); LV2_LOCK; - std::shared_ptr queue; + const auto queue = Emu.GetIdManager().GetIDData(equeue_id); - if (!Emu.GetIdManager().GetIDData(equeue_id, queue)) + if (!queue) { return CELL_ESRCH; } @@ -140,15 +140,15 @@ s32 sys_event_queue_tryreceive(u32 equeue_id, vm::ptr event_array, s32 sys_event_queue_receive(PPUThread& CPU, u32 equeue_id, vm::ptr dummy_event, u64 timeout) { - sys_event.Log("sys_event_queue_receive(equeue_id=%d, event=*0x%x, timeout=0x%llx)", equeue_id, dummy_event, timeout); + sys_event.Log("sys_event_queue_receive(equeue_id=0x%x, event=*0x%x, timeout=0x%llx)", equeue_id, dummy_event, timeout); const u64 start_time = get_system_time(); LV2_LOCK; - std::shared_ptr queue; + const auto queue = Emu.GetIdManager().GetIDData(equeue_id); - if (!Emu.GetIdManager().GetIDData(equeue_id, queue)) + if (!queue) { return CELL_ESRCH; } @@ -177,7 +177,7 @@ s32 sys_event_queue_receive(PPUThread& CPU, u32 equeue_id, vm::ptr if (Emu.IsStopped()) { - sys_event.Warning("sys_event_queue_receive(equeue_id=%d) aborted", equeue_id); + sys_event.Warning("sys_event_queue_receive(equeue_id=0x%x) aborted", equeue_id); return CELL_OK; } @@ -199,18 +199,18 @@ s32 sys_event_queue_receive(PPUThread& CPU, u32 equeue_id, vm::ptr s32 sys_event_queue_drain(u32 equeue_id) { - sys_event.Log("sys_event_queue_drain(equeue_id=%d)", equeue_id); + sys_event.Log("sys_event_queue_drain(equeue_id=0x%x)", equeue_id); LV2_LOCK; - std::shared_ptr queue; + const auto queue = Emu.GetIdManager().GetIDData(equeue_id); - if (!Emu.GetIdManager().GetIDData(equeue_id, queue)) + if (!queue) { return CELL_ESRCH; } - queue->events = {}; + queue->events.clear(); return CELL_OK; } @@ -241,13 +241,13 @@ s32 sys_event_port_create(vm::ptr eport_id, s32 port_type, u64 name) s32 sys_event_port_destroy(u32 eport_id) { - sys_event.Warning("sys_event_port_destroy(eport_id=%d)", eport_id); + sys_event.Warning("sys_event_port_destroy(eport_id=0x%x)", eport_id); LV2_LOCK; - std::shared_ptr port; + const auto port = Emu.GetIdManager().GetIDData(eport_id); - if (!Emu.GetIdManager().GetIDData(eport_id, port)) + if (!port) { return CELL_ESRCH; } @@ -264,14 +264,14 @@ s32 sys_event_port_destroy(u32 eport_id) s32 sys_event_port_connect_local(u32 eport_id, u32 equeue_id) { - sys_event.Warning("sys_event_port_connect_local(eport_id=%d, equeue_id=%d)", eport_id, equeue_id); + sys_event.Warning("sys_event_port_connect_local(eport_id=0x%x, equeue_id=0x%x)", eport_id, equeue_id); LV2_LOCK; - std::shared_ptr port; - std::shared_ptr queue; + const auto port = Emu.GetIdManager().GetIDData(eport_id); + const auto queue = Emu.GetIdManager().GetIDData(equeue_id); - if (!Emu.GetIdManager().GetIDData(eport_id, port) || !Emu.GetIdManager().GetIDData(equeue_id, queue)) + if (!port || !queue) { return CELL_ESRCH; } @@ -293,18 +293,18 @@ s32 sys_event_port_connect_local(u32 eport_id, u32 equeue_id) s32 sys_event_port_disconnect(u32 eport_id) { - sys_event.Warning("sys_event_port_disconnect(eport_id=%d)", eport_id); + sys_event.Warning("sys_event_port_disconnect(eport_id=0x%x)", eport_id); LV2_LOCK; - std::shared_ptr port; + const auto port = Emu.GetIdManager().GetIDData(eport_id); - if (!Emu.GetIdManager().GetIDData(eport_id, port)) + if (!port) { return CELL_ESRCH; } - std::shared_ptr queue = port->queue.lock(); + const auto queue = port->queue.lock(); if (!queue) { @@ -313,16 +313,6 @@ s32 sys_event_port_disconnect(u32 eport_id) // CELL_EBUSY is not returned - //const u64 source = port->name ? port->name : ((u64)process_getpid() << 32) | (u64)eport_id; - - //for (auto& event : queue->events) - //{ - // if (event.source == source) - // { - // return CELL_EBUSY; // ??? - // } - //} - port->queue.reset(); return CELL_OK; @@ -330,18 +320,18 @@ s32 sys_event_port_disconnect(u32 eport_id) s32 sys_event_port_send(u32 eport_id, u64 data1, u64 data2, u64 data3) { - sys_event.Log("sys_event_port_send(eport_id=%d, data1=0x%llx, data2=0x%llx, data3=0x%llx)", eport_id, data1, data2, data3); + sys_event.Log("sys_event_port_send(eport_id=0x%x, data1=0x%llx, data2=0x%llx, data3=0x%llx)", eport_id, data1, data2, data3); LV2_LOCK; - std::shared_ptr port; + const auto port = Emu.GetIdManager().GetIDData(eport_id); - if (!Emu.GetIdManager().GetIDData(eport_id, port)) + if (!port) { return CELL_ESRCH; } - std::shared_ptr queue = port->queue.lock(); + const auto queue = port->queue.lock(); if (!queue) { @@ -355,7 +345,7 @@ s32 sys_event_port_send(u32 eport_id, u64 data1, u64 data2, u64 data3) const u64 source = port->name ? port->name : ((u64)process_getpid() << 32) | (u64)eport_id; - queue->push(source, data1, data2, data3); + queue->push(lv2_lock, source, data1, data2, data3); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event.h b/rpcs3/Emu/SysCalls/lv2/sys_event.h index 842d4b267a..d5e2045bda 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_event.h @@ -95,8 +95,10 @@ struct event_queue_t { } - void push(u64 source, u64 data1, u64 data2, u64 data3) + void push(lv2_lock_type& lv2_lock, u64 source, u64 data1, u64 data2, u64 data3) { + CHECK_LV2_LOCK(lv2_lock); + events.emplace_back(source, data1, data2, data3); if (waiters) diff --git a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp index bd1857bdd4..b645ff86c6 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_event_flag.cpp @@ -56,13 +56,13 @@ s32 sys_event_flag_create(vm::ptr id, vm::ptr attr, u6 s32 sys_event_flag_destroy(u32 id) { - sys_event_flag.Warning("sys_event_flag_destroy(id=%d)", id); + sys_event_flag.Warning("sys_event_flag_destroy(id=0x%x)", id); LV2_LOCK; - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(id); - if (!Emu.GetIdManager().GetIDData(id, ef)) + if (!ef) { return CELL_ESRCH; } @@ -79,7 +79,7 @@ s32 sys_event_flag_destroy(u32 id) s32 sys_event_flag_wait(u32 id, u64 bitptn, u32 mode, vm::ptr result, u64 timeout) { - sys_event_flag.Log("sys_event_flag_wait(id=%d, bitptn=0x%llx, mode=0x%x, result=*0x%x, timeout=0x%llx)", id, bitptn, mode, result, timeout); + sys_event_flag.Log("sys_event_flag_wait(id=0x%x, bitptn=0x%llx, mode=0x%x, result=*0x%x, timeout=0x%llx)", id, bitptn, mode, result, timeout); const u64 start_time = get_system_time(); @@ -105,9 +105,9 @@ s32 sys_event_flag_wait(u32 id, u64 bitptn, u32 mode, vm::ptr result, u64 t default: return CELL_EINVAL; } - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(id); - if (!Emu.GetIdManager().GetIDData(id, ef)) + if (!ef) { return CELL_ESRCH; } @@ -161,7 +161,7 @@ s32 sys_event_flag_wait(u32 id, u64 bitptn, u32 mode, vm::ptr result, u64 t if (Emu.IsStopped()) { - sys_event_flag.Warning("sys_event_flag_wait(id=%d) aborted", id); + sys_event_flag.Warning("sys_event_flag_wait(id=0x%x) aborted", id); return CELL_OK; } @@ -188,7 +188,7 @@ s32 sys_event_flag_wait(u32 id, u64 bitptn, u32 mode, vm::ptr result, u64 t s32 sys_event_flag_trywait(u32 id, u64 bitptn, u32 mode, vm::ptr result) { - sys_event_flag.Log("sys_event_flag_trywait(id=%d, bitptn=0x%llx, mode=0x%x, result=*0x%x)", id, bitptn, mode, result); + sys_event_flag.Log("sys_event_flag_trywait(id=0x%x, bitptn=0x%llx, mode=0x%x, result=*0x%x)", id, bitptn, mode, result); LV2_LOCK; @@ -212,9 +212,9 @@ s32 sys_event_flag_trywait(u32 id, u64 bitptn, u32 mode, vm::ptr result) default: return CELL_EINVAL; } - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(id); - if (!Emu.GetIdManager().GetIDData(id, ef)) + if (!ef) { return CELL_ESRCH; } @@ -248,13 +248,13 @@ s32 sys_event_flag_trywait(u32 id, u64 bitptn, u32 mode, vm::ptr result) s32 sys_event_flag_set(u32 id, u64 bitptn) { - sys_event_flag.Log("sys_event_flag_set(id=%d, bitptn=0x%llx)", id, bitptn); + sys_event_flag.Log("sys_event_flag_set(id=0x%x, bitptn=0x%llx)", id, bitptn); LV2_LOCK; - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(id); - if (!Emu.GetIdManager().GetIDData(id, ef)) + if (!ef) { return CELL_ESRCH; } @@ -276,13 +276,13 @@ s32 sys_event_flag_set(u32 id, u64 bitptn) s32 sys_event_flag_clear(u32 id, u64 bitptn) { - sys_event_flag.Log("sys_event_flag_clear(id=%d, bitptn=0x%llx)", id, bitptn); + sys_event_flag.Log("sys_event_flag_clear(id=0x%x, bitptn=0x%llx)", id, bitptn); LV2_LOCK; - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(id); - if (!Emu.GetIdManager().GetIDData(id, ef)) + if (!ef) { return CELL_ESRCH; } @@ -299,7 +299,7 @@ s32 sys_event_flag_clear(u32 id, u64 bitptn) s32 sys_event_flag_cancel(u32 id, vm::ptr num) { - sys_event_flag.Log("sys_event_flag_cancel(id=%d, num=*0x%x)", id, num); + sys_event_flag.Log("sys_event_flag_cancel(id=0x%x, num=*0x%x)", id, num); LV2_LOCK; @@ -308,9 +308,9 @@ s32 sys_event_flag_cancel(u32 id, vm::ptr num) *num = 0; } - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(id); - if (!Emu.GetIdManager().GetIDData(id, ef)) + if (!ef) { return CELL_ESRCH; } @@ -335,7 +335,7 @@ s32 sys_event_flag_cancel(u32 id, vm::ptr num) s32 sys_event_flag_get(u32 id, vm::ptr flags) { - sys_event_flag.Log("sys_event_flag_get(id=%d, flags=*0x%x)", id, flags); + sys_event_flag.Log("sys_event_flag_get(id=0x%x, flags=*0x%x)", id, flags); LV2_LOCK; @@ -344,9 +344,9 @@ s32 sys_event_flag_get(u32 id, vm::ptr flags) return CELL_EFAULT; } - std::shared_ptr ef; + const auto ef = Emu.GetIdManager().GetIDData(id); - if (!Emu.GetIdManager().GetIDData(id, ef)) + if (!ef) { *flags = 0; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp index f252098984..d538425152 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_fs.cpp @@ -4,16 +4,9 @@ #include "Emu/IdManager.h" #include "Emu/SysCalls/SysCalls.h" -#ifdef _WIN32 -#include -#undef CreateFile -#else -#include -#include -#endif - #include "Emu/FS/VFS.h" #include "Emu/FS/vfsFile.h" +#include "Emu/FS/vfsLocalFile.h" #include "Emu/FS/vfsDir.h" #include "sys_fs.h" @@ -32,95 +25,87 @@ s32 sys_fs_open(vm::ptr path, s32 flags, vm::ptr fd, s32 mode, sys_fs.Warning("sys_fs_open(path=*0x%x, flags=%#o, fd=*0x%x, mode=%#o, arg=*0x%x, size=0x%llx)", path, flags, fd, mode, arg, size); sys_fs.Warning("*** path = '%s'", path.get_ptr()); - std::shared_ptr file; + if (!path[0]) + { + sys_fs.Error("sys_fs_open('%s') failed: path is invalid", path.get_ptr()); + return CELL_FS_EINVAL; + } + + std::string local_path; + + const auto device = Emu.GetVFS().GetDevice(path.get_ptr(), local_path); + + if (!device) + { + sys_fs.Error("sys_fs_open('%s') failed: device not mounted", path.get_ptr()); + return CELL_FS_ENOTMOUNTED; + } // TODO: other checks for path - if (Emu.GetVFS().ExistsDir(path.get_ptr())) + if (fs::is_dir(local_path)) { - sys_fs.Error("sys_fs_open(): '%s' is a directory", path.get_ptr()); + sys_fs.Error("sys_fs_open('%s') failed: path is a directory", path.get_ptr()); return CELL_FS_EISDIR; } - switch (flags) + u32 open_mode = 0; + + switch (flags & CELL_FS_O_ACCMODE) { - case CELL_FS_O_RDONLY: - { - file.reset(Emu.GetVFS().OpenFile(path.get_ptr(), vfsRead)); - break; + case CELL_FS_O_RDONLY: open_mode |= o_read; break; + case CELL_FS_O_WRONLY: open_mode |= o_write; break; + case CELL_FS_O_RDWR: open_mode |= o_read | o_write; break; } - case CELL_FS_O_WRONLY: - case CELL_FS_O_RDWR: + if (flags & CELL_FS_O_CREAT) { - file.reset(Emu.GetVFS().OpenFile(path.get_ptr(), vfsReadWrite)); - break; - } - - case CELL_FS_O_WRONLY | CELL_FS_O_CREAT: - case CELL_FS_O_RDWR | CELL_FS_O_CREAT: - { - Emu.GetVFS().CreateFile(path.get_ptr()); - file.reset(Emu.GetVFS().OpenFile(path.get_ptr(), vfsReadWrite)); - break; + open_mode |= o_create; } - case CELL_FS_O_WRONLY | CELL_FS_O_APPEND: + if (flags & CELL_FS_O_TRUNC) { - file.reset(Emu.GetVFS().OpenFile(path.get_ptr(), vfsWriteAppend)); - break; + open_mode |= o_trunc; } - case CELL_FS_O_WRONLY | CELL_FS_O_CREAT | CELL_FS_O_EXCL: - case CELL_FS_O_RDWR | CELL_FS_O_CREAT | CELL_FS_O_EXCL: // ??? + if (flags & CELL_FS_O_EXCL) { - file.reset(Emu.GetVFS().OpenFile(path.get_ptr(), vfsWriteExcl)); - - if ((!file || !file->IsOpened()) && Emu.GetVFS().ExistsFile(path.get_ptr())) + if (flags & CELL_FS_O_CREAT) { - return CELL_FS_EEXIST; + open_mode |= o_excl; + } + else + { + open_mode = 0; // error } - - break; } - case CELL_FS_O_WRONLY | CELL_FS_O_TRUNC: + if (flags & ~(CELL_FS_O_ACCMODE | CELL_FS_O_CREAT | CELL_FS_O_TRUNC | CELL_FS_O_EXCL)) { - file.reset(Emu.GetVFS().OpenFile(path.get_ptr(), vfsWrite)); - break; + open_mode = 0; // error } - case CELL_FS_O_WRONLY | CELL_FS_O_CREAT | CELL_FS_O_TRUNC: + if ((flags & CELL_FS_O_ACCMODE) == CELL_FS_O_ACCMODE) { - Emu.GetVFS().CreateFile(path.get_ptr()); - file.reset(Emu.GetVFS().OpenFile(path.get_ptr(), vfsWrite)); - break; + open_mode = 0; // error } - case CELL_FS_O_WRONLY | CELL_FS_O_CREAT | CELL_FS_O_APPEND: + if (!open_mode) { - Emu.GetVFS().CreateFile(path.get_ptr()); - file.reset(Emu.GetVFS().OpenFile(path.get_ptr(), vfsWriteAppend)); - break; - } - - case CELL_FS_O_RDWR | CELL_FS_O_CREAT | CELL_FS_O_TRUNC: - { - Emu.GetVFS().CreateFile(path.get_ptr(), true); - file.reset(Emu.GetVFS().OpenFile(path.get_ptr(), vfsReadWrite)); - break; + sys_fs.Fatal("sys_fs_open('%s'): invalid or unimplemented flags (%#o)", path.get_ptr(), flags); } - default: - { - sys_fs.Error("sys_fs_open(): invalid or unimplemented flags (%#o)", flags); - return CELL_FS_EINVAL; - } - } + std::shared_ptr file(Emu.GetVFS().OpenFile(path.get_ptr(), open_mode)); if (!file || !file->IsOpened()) { - sys_fs.Error("sys_fs_open(): failed to open '%s' (flags=%#o, mode=%#o)", path.get_ptr(), flags, mode); + sys_fs.Error("sys_fs_open('%s'): failed to open file (flags=%#o, mode=%#o)", path.get_ptr(), flags, mode); + + if (open_mode & o_excl) + { + return CELL_FS_EEXIST; // approximation + } + return CELL_FS_ENOENT; } @@ -135,9 +120,9 @@ s32 sys_fs_read(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nread) { sys_fs.Log("sys_fs_read(fd=0x%x, buf=0x%x, nbytes=0x%llx, nread=0x%x)", fd, buf, nbytes, nread); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file) || file->flags & CELL_FS_O_WRONLY) + if (!file || file->flags & CELL_FS_O_WRONLY) { return CELL_FS_EBADF; } @@ -153,9 +138,9 @@ s32 sys_fs_write(u32 fd, vm::ptr buf, u64 nbytes, vm::ptr nwrit { sys_fs.Log("sys_fs_write(fd=0x%x, buf=*0x%x, nbytes=0x%llx, nwrite=*0x%x)", fd, buf, nbytes, nwrite); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file) || !(file->flags & CELL_FS_O_ACCMODE)) + if (!file || !(file->flags & CELL_FS_O_ACCMODE)) { return CELL_FS_EBADF; } @@ -173,9 +158,9 @@ s32 sys_fs_close(u32 fd) { sys_fs.Log("sys_fs_close(fd=0x%x)", fd); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; } @@ -196,7 +181,7 @@ s32 sys_fs_opendir(vm::ptr path, vm::ptr fd) if (!directory || !directory->IsOpened()) { - sys_fs.Error("sys_fs_opendir(): failed to open '%s'", path.get_ptr()); + sys_fs.Error("sys_fs_opendir('%s'): failed to open directory", path.get_ptr()); return CELL_FS_ENOENT; } @@ -209,9 +194,9 @@ s32 sys_fs_readdir(u32 fd, vm::ptr dir, vm::ptr nread) { sys_fs.Warning("sys_fs_readdir(fd=0x%x, dir=*0x%x, nread=*0x%x)", fd, dir, nread); - std::shared_ptr directory; + const auto directory = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, directory)) + if (!directory) { return CELL_FS_EBADF; } @@ -237,9 +222,9 @@ s32 sys_fs_closedir(u32 fd) { sys_fs.Log("sys_fs_closedir(fd=0x%x)", fd); - std::shared_ptr directory; + const auto directory = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, directory)) + if (!directory) { return CELL_FS_EBADF; } @@ -254,108 +239,70 @@ s32 sys_fs_stat(vm::ptr path, vm::ptr sb) sys_fs.Warning("sys_fs_stat(path=*0x%x, sb=*0x%x)", path, sb); sys_fs.Warning("*** path = '%s'", path.get_ptr()); - const std::string _path = path.get_ptr(); + std::string local_path; - u32 mode = 0; - s32 uid = 0; - s32 gid = 0; - u64 atime = 0; - u64 mtime = 0; - u64 ctime = 0; - u64 size = 0; - - std::string real_path; - - Emu.GetVFS().GetDevice(_path, real_path); - - int stat_result; -#ifdef _WIN32 - struct _stat64 buf; - stat_result = _stat64(real_path.c_str(), &buf); -#else - struct stat buf; - stat_result = stat(real_path.c_str(), &buf); -#endif - if (stat_result) + if (!Emu.GetVFS().GetDevice(path.get_ptr(), local_path)) { - sys_fs.Error("sys_fs_stat(): stat('%s') failed -> 0x%x", real_path.c_str(), stat_result); - } - else - { - mode = buf.st_mode; - uid = buf.st_uid; - gid = buf.st_gid; - atime = buf.st_atime; - mtime = buf.st_mtime; - ctime = buf.st_ctime; - size = buf.st_size; + sys_fs.Warning("sys_fs_stat('%s') failed: not mounted", path.get_ptr()); + return CELL_FS_ENOTMOUNTED; } - sb->mode = - CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR | - CELL_FS_S_IRGRP | CELL_FS_S_IWGRP | CELL_FS_S_IXGRP | - CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH; - - if (sb->mode == mode) - sys_fs.Error("sys_fs_stat(): mode is the same (0x%x)", mode); - - sb->uid = uid; - sb->gid = gid; - sb->atime = atime; - sb->mtime = mtime; - sb->ctime = ctime; - sb->blksize = 4096; + fs::stat_t info; + if (!fs::stat(local_path, info) || !info.exists) { - vfsDir dir(_path); - if (dir.IsOpened()) - { - sb->mode |= CELL_FS_S_IFDIR; - return CELL_OK; - } + sys_fs.Error("sys_fs_stat('%s') failed: not found", path.get_ptr()); + return CELL_FS_ENOENT; } - { - vfsFile f(_path); - if (f.IsOpened()) - { - sb->mode |= CELL_FS_S_IFREG; - sb->size = f.GetSize(); - return CELL_OK; - } - } + sb->mode = info.is_directory ? CELL_FS_S_IFDIR | 0777 : CELL_FS_S_IFREG | 0666; + sb->uid = 1; // ??? + sb->gid = 1; // ??? + sb->atime = info.atime; + sb->mtime = info.mtime; + sb->ctime = info.ctime; + sb->size = info.size; + sb->blksize = 4096; // ??? - if (sb->size == size && size != 0) - sys_fs.Error("sys_fs_stat(): size is the same (0x%x)", size); - - sys_fs.Warning("sys_fs_stat(): '%s' not found", path.get_ptr()); - return CELL_FS_ENOENT; + return CELL_OK; } s32 sys_fs_fstat(u32 fd, vm::ptr sb) { sys_fs.Warning("sys_fs_fstat(fd=0x%x, sb=*0x%x)", fd, sb); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; } - sb->mode = - CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR | - CELL_FS_S_IRGRP | CELL_FS_S_IWGRP | CELL_FS_S_IXGRP | - CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH; + std::lock_guard lock(file->mutex); - sb->mode |= CELL_FS_S_IFREG; //TODO: dir CELL_FS_S_IFDIR - sb->uid = 0; - sb->gid = 0; - sb->atime = 0; //TODO - sb->mtime = 0; //TODO - sb->ctime = 0; //TODO - sb->size = file->file->GetSize(); - sb->blksize = 4096; + const auto local_file = dynamic_cast(file->file.get()); + + if (!local_file) + { + sys_fs.Error("sys_fs_fstat(fd=0x%x): not a local file"); + return CELL_FS_ENOTSUP; + } + + fs::stat_t info; + + if (!local_file->GetFile().stat(info)) + { + return CELL_FS_EIO; // ??? + } + + sb->mode = info.is_directory ? CELL_FS_S_IFDIR | 0777 : CELL_FS_S_IFREG | 0666; + sb->uid = 1; // ??? + sb->gid = 1; // ??? + sb->atime = info.atime; + sb->mtime = info.mtime; + sb->ctime = info.ctime; // ctime may be incorrect + sb->size = info.size; + sb->blksize = 4096; // ??? return CELL_OK; } @@ -365,14 +312,14 @@ s32 sys_fs_mkdir(vm::ptr path, s32 mode) sys_fs.Warning("sys_fs_mkdir(path=*0x%x, mode=%#o)", path, mode); sys_fs.Warning("*** path = '%s'", path.get_ptr()); - const std::string _path = path.get_ptr(); + std::string ps3_path = path.get_ptr(); - if (Emu.GetVFS().ExistsDir(_path)) + if (Emu.GetVFS().ExistsDir(ps3_path)) { return CELL_FS_EEXIST; } - if (!Emu.GetVFS().CreateDir(_path)) + if (!Emu.GetVFS().CreatePath(ps3_path)) { return CELL_FS_EIO; // ??? } @@ -387,12 +334,11 @@ s32 sys_fs_rename(vm::ptr from, vm::ptr to) sys_fs.Warning("*** from = '%s'", from.get_ptr()); sys_fs.Warning("*** to = '%s'", to.get_ptr()); - std::string _from = from.get_ptr(); - std::string _to = to.get_ptr(); + std::string ps3_path = from.get_ptr(); - if (Emu.GetVFS().ExistsDir(_from)) + if (Emu.GetVFS().ExistsDir(ps3_path)) { - if (!Emu.GetVFS().RenameDir(_from, _to)) + if (!Emu.GetVFS().RenameDir(ps3_path, to.get_ptr())) { return CELL_FS_EIO; // ??? } @@ -401,9 +347,9 @@ s32 sys_fs_rename(vm::ptr from, vm::ptr to) return CELL_OK; } - if (Emu.GetVFS().ExistsFile(_from)) + if (Emu.GetVFS().ExistsFile(ps3_path)) { - if (!Emu.GetVFS().RenameFile(_from, _to)) + if (!Emu.GetVFS().RenameFile(ps3_path, to.get_ptr())) { return CELL_FS_EIO; // ??? } @@ -420,18 +366,18 @@ s32 sys_fs_rmdir(vm::ptr path) sys_fs.Warning("sys_fs_rmdir(path=*0x%x)", path); sys_fs.Warning("*** path = '%s'", path.get_ptr()); - std::string _path = path.get_ptr(); + std::string ps3_path = path.get_ptr(); - if (!Emu.GetVFS().RemoveDir(_path)) + if (!Emu.GetVFS().ExistsDir(ps3_path)) { - if (Emu.GetVFS().ExistsDir(_path)) - { - return CELL_FS_EIO; // ??? - } - return CELL_FS_ENOENT; } + if (!Emu.GetVFS().RemoveDir(ps3_path)) + { + return CELL_FS_EIO; // ??? + } + sys_fs.Notice("sys_fs_rmdir(): directory '%s' removed", path.get_ptr()); return CELL_OK; } @@ -441,18 +387,18 @@ s32 sys_fs_unlink(vm::ptr path) sys_fs.Warning("sys_fs_unlink(path=*0x%x)", path); sys_fs.Warning("*** path = '%s'", path.get_ptr()); - std::string _path = path.get_ptr(); + std::string ps3_path = path.get_ptr(); - if (!Emu.GetVFS().RemoveFile(_path)) + if (!Emu.GetVFS().ExistsFile(ps3_path)) { - if (Emu.GetVFS().ExistsFile(_path)) - { - return CELL_FS_EIO; // ??? - } - return CELL_FS_ENOENT; } + if (!Emu.GetVFS().RemoveFile(ps3_path)) + { + return CELL_FS_EIO; // ??? + } + sys_fs.Notice("sys_fs_unlink(): file '%s' deleted", path.get_ptr()); return CELL_OK; } @@ -468,41 +414,35 @@ s32 sys_fs_lseek(u32 fd, s64 offset, s32 whence, vm::ptr pos) { sys_fs.Log("sys_fs_lseek(fd=0x%x, offset=0x%llx, whence=0x%x, pos=*0x%x)", fd, offset, whence, pos); - vfsSeekMode seek_mode; - - switch (whence) + if (whence >= 3) { - case CELL_FS_SEEK_SET: seek_mode = vfsSeekSet; break; - case CELL_FS_SEEK_CUR: seek_mode = vfsSeekCur; break; - case CELL_FS_SEEK_END: seek_mode = vfsSeekEnd; break; - default: - sys_fs.Error("sys_fs_lseek(fd=0x%x): unknown seek whence (0x%x)", fd, whence); + sys_fs.Error("sys_fs_lseek(fd=0x%x): unknown seek whence (%d)", fd, whence); return CELL_FS_EINVAL; } - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { return CELL_FS_EBADF; } std::lock_guard lock(file->mutex); - *pos = file->file->Seek(offset, seek_mode); + *pos = file->file->Seek(offset, whence); return CELL_OK; } s32 sys_fs_fget_block_size(u32 fd, vm::ptr sector_size, vm::ptr block_size, vm::ptr arg4, vm::ptr arg5) { - sys_fs.Todo("sys_fs_fget_block_size(fd=%d, sector_size=*0x%x, block_size=*0x%x, arg4=*0x%x, arg5=*0x%x)", fd, sector_size, block_size, arg4, arg5); + sys_fs.Todo("sys_fs_fget_block_size(fd=0x%x, sector_size=*0x%x, block_size=*0x%x, arg4=*0x%x, arg5=*0x%x)", fd, sector_size, block_size, arg4, arg5); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file) { - CELL_FS_EBADF; + return CELL_FS_EBADF; } *sector_size = 4096; // ? @@ -527,28 +467,16 @@ s32 sys_fs_truncate(vm::ptr path, u64 size) sys_fs.Warning("sys_fs_truncate(path=*0x%x, size=0x%llx)", path, size); sys_fs.Warning("*** path = '%s'", path.get_ptr()); - vfsFile f(path.get_ptr(), vfsReadWrite); - if (!f.IsOpened()) + std::string ps3_path = path.get_ptr(); + + if (!Emu.GetVFS().ExistsFile(ps3_path)) { - sys_fs.Warning("sys_fs_truncate(): '%s' not found", path.get_ptr()); return CELL_FS_ENOENT; } - u64 initialSize = f.GetSize(); - - if (initialSize < size) + if (!Emu.GetVFS().TruncateFile(ps3_path, size)) { - u64 last_pos = f.Tell(); - f.Seek(0, vfsSeekEnd); - static const char nullbyte = 0; - f.Seek(size - initialSize - 1, vfsSeekCur); - f.Write(&nullbyte, sizeof(char)); - f.Seek(last_pos, vfsSeekSet); - } - - if (initialSize > size) - { - // (TODO) + return CELL_FS_EIO; // ??? } return CELL_OK; @@ -558,28 +486,26 @@ s32 sys_fs_ftruncate(u32 fd, u64 size) { sys_fs.Warning("sys_fs_ftruncate(fd=0x%x, size=0x%llx)", fd, size); - std::shared_ptr file; + const auto file = Emu.GetIdManager().GetIDData(fd); - if (!Emu.GetIdManager().GetIDData(fd, file)) + if (!file || !(file->flags & CELL_FS_O_ACCMODE)) { - CELL_FS_EBADF; + return CELL_FS_EBADF; } - u64 initialSize = file->file->GetSize(); + std::lock_guard lock(file->mutex); - if (initialSize < size) + const auto local_file = dynamic_cast(file->file.get()); + + if (!local_file) { - u64 last_pos = file->file->Tell(); - file->file->Seek(0, vfsSeekEnd); - static const char nullbyte = 0; - file->file->Seek(size - initialSize - 1, vfsSeekCur); - file->file->Write(&nullbyte, sizeof(char)); - file->file->Seek(last_pos, vfsSeekSet); + sys_fs.Error("sys_fs_ftruncate(fd=0x%x): not a local file"); + return CELL_FS_ENOTSUP; } - if (initialSize > size) + if (!local_file->GetFile().trunc(size)) { - // (TODO) + return CELL_FS_EIO; // ??? } return CELL_OK; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp index f124378b37..89a6146f34 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_interrupt.cpp @@ -23,7 +23,7 @@ s32 sys_interrupt_tag_destroy(u32 intrtag) return CELL_ESRCH; } - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(intrtag & 0xff); + const auto t = Emu.GetCPU().GetRawSPUThread(intrtag & 0xff); if (!t) { @@ -58,7 +58,7 @@ s32 sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u64 intrthread, return CELL_ESRCH; } - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(intrtag & 0xff); + const auto t = Emu.GetCPU().GetRawSPUThread(intrtag & 0xff); if (!t) { @@ -71,7 +71,7 @@ s32 sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u64 intrthread, // CELL_ESTAT is not returned (can't detect exact condition) - std::shared_ptr it = Emu.GetCPU().GetThread((u32)intrthread); + const auto it = Emu.GetCPU().GetThread((u32)intrthread); if (!it) { @@ -106,15 +106,20 @@ s32 sys_interrupt_thread_establish(vm::ptr ih, u32 intrtag, u64 intrthread, ppu.custom_task = [t, &tag, arg](PPUThread& CPU) { - auto func = vm::ptr::make(CPU.entry); + const auto func = vm::ptr::make(CPU.entry); + const auto pc = vm::read32(func.addr()); + const auto rtoc = vm::read32(func.addr() + 4); std::unique_lock cond_lock(tag.handler_mutex); while (!Emu.IsStopped()) { + // call interrupt handler until int status is clear if (tag.stat.read_relaxed()) { - func(CPU, arg); // call interrupt handler until int status is clear + //func(CPU, arg); + CPU.GPR[3] = arg; + CPU.FastCall2(pc, rtoc); } tag.cond.wait_for(cond_lock, std::chrono::milliseconds(1)); @@ -132,8 +137,9 @@ s32 _sys_interrupt_thread_disestablish(u32 ih, vm::ptr r13) { sys_interrupt.Todo("_sys_interrupt_thread_disestablish(ih=0x%x, r13=*0x%x)", ih, r13); - std::shared_ptr handler; - if (!Emu.GetIdManager().GetIDData(ih, handler)) + const auto handler = Emu.GetIdManager().GetIDData(ih); + + if (!handler) { return CELL_ESRCH; } @@ -151,5 +157,8 @@ void sys_interrupt_thread_eoi(PPUThread& CPU) { sys_interrupt.Log("sys_interrupt_thread_eoi()"); + // TODO: maybe it should actually unwind the stack (ensure that all the automatic objects are finalized)? + CPU.GPR[1] = align(CPU.GetStackAddr() + CPU.GetStackSize(), 0x200) - 0x200; // supercrutch (just to hide error messages) + CPU.FastStop(); } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp index a2765b462a..5c20d92f56 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.cpp @@ -17,12 +17,13 @@ void lwcond_create(sys_lwcond_t& lwcond, sys_lwmutex_t& lwmutex, u64 name) { std::shared_ptr cond(new lwcond_t(name)); + lwcond.lwmutex.set(vm::get_addr(&lwmutex)); lwcond.lwcond_queue = Emu.GetIdManager().GetNewID(cond, TYPE_LWCOND); } s32 _sys_lwcond_create(vm::ptr lwcond_id, u32 lwmutex_id, vm::ptr control, u64 name, u32 arg5) { - sys_lwcond.Warning("_sys_lwcond_create(lwcond_id=*0x%x, lwmutex_id=%d, control=*0x%x, name=0x%llx, arg5=0x%x)", lwcond_id, lwmutex_id, control, name, arg5); + sys_lwcond.Warning("_sys_lwcond_create(lwcond_id=*0x%x, lwmutex_id=0x%x, control=*0x%x, name=0x%llx, arg5=0x%x)", lwcond_id, lwmutex_id, control, name, arg5); std::shared_ptr cond(new lwcond_t(name)); @@ -33,18 +34,18 @@ s32 _sys_lwcond_create(vm::ptr lwcond_id, u32 lwmutex_id, vm::ptr cond; + const auto cond = Emu.GetIdManager().GetIDData(lwcond_id); - if (!Emu.GetIdManager().GetIDData(lwcond_id, cond)) + if (!cond) { return CELL_ESRCH; } - if (cond->waiters) + if (!cond->waiters.empty() || cond->signaled1 || cond->signaled2) { return CELL_EBUSY; } @@ -56,40 +57,30 @@ s32 _sys_lwcond_destroy(u32 lwcond_id) s32 _sys_lwcond_signal(u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mode) { - sys_lwcond.Log("_sys_lwcond_signal(lwcond_id=%d, lwmutex_id=%d, ppu_thread_id=%d, mode=%d)", lwcond_id, lwmutex_id, ppu_thread_id, mode); + sys_lwcond.Log("_sys_lwcond_signal(lwcond_id=0x%x, lwmutex_id=0x%x, ppu_thread_id=0x%x, mode=%d)", lwcond_id, lwmutex_id, ppu_thread_id, mode); LV2_LOCK; - std::shared_ptr cond; - std::shared_ptr mutex; + const auto cond = Emu.GetIdManager().GetIDData(lwcond_id); + const auto mutex = Emu.GetIdManager().GetIDData(lwmutex_id); - if (!Emu.GetIdManager().GetIDData(lwcond_id, cond)) + if (!cond || (lwmutex_id && !mutex)) { return CELL_ESRCH; } - if (lwmutex_id && !Emu.GetIdManager().GetIDData(lwmutex_id, mutex)) - { - return CELL_ESRCH; - } - - // ppu_thread_id is ignored in current implementation - if (mode != 1 && mode != 2 && mode != 3) { sys_lwcond.Error("_sys_lwcond_signal(%d): invalid mode (%d)", lwcond_id, mode); } - if (~ppu_thread_id) - { - sys_lwcond.Todo("_sys_lwcond_signal(%d): ppu_thread_id (%d)", lwcond_id, ppu_thread_id); - } + const auto found = ~ppu_thread_id ? cond->waiters.find(ppu_thread_id) : cond->waiters.begin(); if (mode == 1) { // mode 1: lightweight mutex was initially owned by the calling thread - if (!cond->waiters) + if (found == cond->waiters.end()) { return CELL_EPERM; } @@ -100,7 +91,7 @@ s32 _sys_lwcond_signal(u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mod { // mode 2: lightweight mutex was not owned by the calling thread and waiter hasn't been increased - if (!cond->waiters) + if (found == cond->waiters.end()) { return CELL_OK; } @@ -111,7 +102,7 @@ s32 _sys_lwcond_signal(u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mod { // in mode 3, lightweight mutex was forcefully owned by the calling thread - if (!cond->waiters) + if (found == cond->waiters.end()) { return ~ppu_thread_id ? CELL_ENOENT : CELL_EPERM; } @@ -119,29 +110,22 @@ s32 _sys_lwcond_signal(u32 lwcond_id, u32 lwmutex_id, u32 ppu_thread_id, u32 mod cond->signaled1++; } - if (--cond->waiters) - { - cond->cv.notify_one(); - } + cond->waiters.erase(found); + cond->cv.notify_one(); return CELL_OK; } s32 _sys_lwcond_signal_all(u32 lwcond_id, u32 lwmutex_id, u32 mode) { - sys_lwcond.Log("_sys_lwcond_signal_all(lwcond_id=%d, lwmutex_id=%d, mode=%d)", lwcond_id, lwmutex_id, mode); + sys_lwcond.Log("_sys_lwcond_signal_all(lwcond_id=0x%x, lwmutex_id=0x%x, mode=%d)", lwcond_id, lwmutex_id, mode); LV2_LOCK; - std::shared_ptr cond; - std::shared_ptr mutex; + const auto cond = Emu.GetIdManager().GetIDData(lwcond_id); + const auto mutex = Emu.GetIdManager().GetIDData(lwmutex_id); - if (!Emu.GetIdManager().GetIDData(lwcond_id, cond)) - { - return CELL_ESRCH; - } - - if (lwmutex_id && !Emu.GetIdManager().GetIDData(lwmutex_id, mutex)) + if (!cond || (lwmutex_id && !mutex)) { return CELL_ESRCH; } @@ -151,10 +135,11 @@ s32 _sys_lwcond_signal_all(u32 lwcond_id, u32 lwmutex_id, u32 mode) sys_lwcond.Error("_sys_lwcond_signal_all(%d): invalid mode (%d)", lwcond_id, mode); } - const s32 count = cond->waiters.exchange(0); + const u32 count = vm::cast(cond->waiters.size()); if (count) { + cond->waiters.clear(); cond->cv.notify_all(); } @@ -176,23 +161,18 @@ s32 _sys_lwcond_signal_all(u32 lwcond_id, u32 lwmutex_id, u32 mode) } } -s32 _sys_lwcond_queue_wait(u32 lwcond_id, u32 lwmutex_id, u64 timeout) +s32 _sys_lwcond_queue_wait(PPUThread& CPU, u32 lwcond_id, u32 lwmutex_id, u64 timeout) { - sys_lwcond.Log("_sys_lwcond_queue_wait(lwcond_id=%d, lwmutex_id=%d, timeout=0x%llx)", lwcond_id, lwmutex_id, timeout); + sys_lwcond.Log("_sys_lwcond_queue_wait(lwcond_id=0x%x, lwmutex_id=0x%x, timeout=0x%llx)", lwcond_id, lwmutex_id, timeout); const u64 start_time = get_system_time(); LV2_LOCK; - std::shared_ptr cond; - std::shared_ptr mutex; + const auto cond = Emu.GetIdManager().GetIDData(lwcond_id); + const auto mutex = Emu.GetIdManager().GetIDData(lwmutex_id); - if (!Emu.GetIdManager().GetIDData(lwcond_id, cond)) - { - return CELL_ESRCH; - } - - if (!Emu.GetIdManager().GetIDData(lwmutex_id, mutex)) + if (!cond || !mutex) { return CELL_ESRCH; } @@ -205,18 +185,28 @@ s32 _sys_lwcond_queue_wait(u32 lwcond_id, u32 lwmutex_id, u64 timeout) mutex->cv.notify_one(); } - // protocol is ignored in current implementation - cond->waiters++; + // add waiter; protocol is ignored in current implementation + cond->waiters.emplace(CPU.GetId()); - while (!(cond->signaled1 && mutex->signaled) && !cond->signaled2) + while ((!(cond->signaled1 && mutex->signaled) && !cond->signaled2) || cond->waiters.count(CPU.GetId())) { const bool is_timedout = timeout && get_system_time() - start_time > timeout; - // check timeout only if no thread signaled in mode 1 (the flaw of avoiding sleep queue) - if (is_timedout && !cond->signaled1) + // check timeout + if (is_timedout) { // cancel waiting - cond->waiters--; + if (!cond->waiters.erase(CPU.GetId())) + { + if (cond->signaled1 && !mutex->signaled) + { + cond->signaled1--; + } + else + { + throw __FUNCTION__; + } + } if (mutex->signaled) { @@ -232,7 +222,7 @@ s32 _sys_lwcond_queue_wait(u32 lwcond_id, u32 lwmutex_id, u64 timeout) if (Emu.IsStopped()) { - sys_lwcond.Warning("_sys_lwcond_queue_wait(lwcond_id=%d) aborted", lwcond_id); + sys_lwcond.Warning("_sys_lwcond_queue_wait(lwcond_id=0x%x) aborted", lwcond_id); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h index ef02f85899..7e94ccbdc2 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_lwcond.h @@ -26,7 +26,7 @@ struct lwcond_t // TODO: use sleep queue std::condition_variable cv; - std::atomic waiters; + std::unordered_set waiters; lwcond_t(u64 name) : name(name) @@ -47,4 +47,4 @@ s32 _sys_lwcond_create(vm::ptr lwcond_id, u32 lwmutex_id, vm::ptr lwmutex_id, u32 protocol, vm::ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(lwmutex_id); - if (!Emu.GetIdManager().GetIDData(lwmutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } @@ -71,15 +71,15 @@ s32 _sys_lwmutex_destroy(u32 lwmutex_id) s32 _sys_lwmutex_lock(u32 lwmutex_id, u64 timeout) { - sys_lwmutex.Log("_sys_lwmutex_lock(lwmutex_id=%d, timeout=0x%llx)", lwmutex_id, timeout); + sys_lwmutex.Log("_sys_lwmutex_lock(lwmutex_id=0x%x, timeout=0x%llx)", lwmutex_id, timeout); const u64 start_time = get_system_time(); LV2_LOCK; - std::shared_ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(lwmutex_id); - if (!Emu.GetIdManager().GetIDData(lwmutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } @@ -97,7 +97,7 @@ s32 _sys_lwmutex_lock(u32 lwmutex_id, u64 timeout) if (Emu.IsStopped()) { - sys_lwmutex.Warning("_sys_lwmutex_lock(lwmutex_id=%d) aborted", lwmutex_id); + sys_lwmutex.Warning("_sys_lwmutex_lock(lwmutex_id=0x%x) aborted", lwmutex_id); return CELL_OK; } @@ -113,13 +113,13 @@ s32 _sys_lwmutex_lock(u32 lwmutex_id, u64 timeout) s32 _sys_lwmutex_trylock(u32 lwmutex_id) { - sys_lwmutex.Log("_sys_lwmutex_trylock(lwmutex_id=%d)", lwmutex_id); + sys_lwmutex.Log("_sys_lwmutex_trylock(lwmutex_id=0x%x)", lwmutex_id); LV2_LOCK; - std::shared_ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(lwmutex_id); - if (!Emu.GetIdManager().GetIDData(lwmutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } @@ -136,20 +136,20 @@ s32 _sys_lwmutex_trylock(u32 lwmutex_id) s32 _sys_lwmutex_unlock(u32 lwmutex_id) { - sys_lwmutex.Log("_sys_lwmutex_unlock(lwmutex_id=%d)", lwmutex_id); + sys_lwmutex.Log("_sys_lwmutex_unlock(lwmutex_id=0x%x)", lwmutex_id); LV2_LOCK; - std::shared_ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(lwmutex_id); - if (!Emu.GetIdManager().GetIDData(lwmutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } if (mutex->signaled) { - sys_lwmutex.Fatal("_sys_lwmutex_unlock(lwmutex_id=%d): already signaled", lwmutex_id); + sys_lwmutex.Fatal("_sys_lwmutex_unlock(lwmutex_id=0x%x): already signaled", lwmutex_id); } mutex->signaled++; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp b/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp index 3022274177..335873dc23 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_memory.cpp @@ -45,9 +45,12 @@ s32 sys_memory_allocate_from_container(u32 size, u32 cid, u32 flags, u32 alloc_a sys_memory.Log("sys_memory_allocate_from_container(size=0x%x, cid=0x%x, flags=0x%x)", size, cid, flags); // Check if this container ID is valid. - std::shared_ptr ct; - if (!Emu.GetIdManager().GetIDData(cid, ct)) + const auto ct = Emu.GetIdManager().GetIDData(cid); + + if (!ct) + { return CELL_ESRCH; + } // Check page size. switch(flags) @@ -132,12 +135,15 @@ s32 sys_memory_container_create(vm::ptr cid, u32 yield_size) s32 sys_memory_container_destroy(u32 cid) { - sys_memory.Warning("sys_memory_container_destroy(cid=%d)", cid); + sys_memory.Warning("sys_memory_container_destroy(cid=0x%x)", cid); // Check if this container ID is valid. - std::shared_ptr ct; - if (!Emu.GetIdManager().GetIDData(cid, ct)) + const auto ct = Emu.GetIdManager().GetIDData(cid); + + if (!ct) + { return CELL_ESRCH; + } // Release the allocated memory and remove the ID. Memory.Free(ct->addr); @@ -148,12 +154,15 @@ s32 sys_memory_container_destroy(u32 cid) s32 sys_memory_container_get_size(vm::ptr mem_info, u32 cid) { - sys_memory.Warning("sys_memory_container_get_size(mem_info_addr=0x%x, cid=%d)", mem_info.addr(), cid); + sys_memory.Warning("sys_memory_container_get_size(mem_info_addr=0x%x, cid=0x%x)", mem_info.addr(), cid); // Check if this container ID is valid. - std::shared_ptr ct; - if (!Emu.GetIdManager().GetIDData(cid, ct)) + const auto ct = Emu.GetIdManager().GetIDData(cid); + + if (!ct) + { return CELL_ESRCH; + } // HACK: Return all memory. mem_info->total_user_memory = ct->size; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp b/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp index bc5a78c60b..ddbee52e5b 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_mmapper.cpp @@ -85,13 +85,16 @@ s32 sys_mmapper_allocate_memory(u32 size, u64 flags, vm::ptr mem_id) s32 sys_mmapper_allocate_memory_from_container(u32 size, u32 cid, u64 flags, vm::ptr mem_id) { - sys_mmapper.Warning("sys_mmapper_allocate_memory_from_container(size=0x%x, cid=%d, flags=0x%llx, mem_id_addr=0x%x)", + sys_mmapper.Warning("sys_mmapper_allocate_memory_from_container(size=0x%x, cid=0x%x, flags=0x%llx, mem_id_addr=0x%x)", size, cid, flags, mem_id.addr()); // Check if this container ID is valid. - std::shared_ptr ct; - if(!Emu.GetIdManager().GetIDData(cid, ct)) + const auto ct = Emu.GetIdManager().GetIDData(cid); + + if (!ct) + { return CELL_ESRCH; + } // Check page granularity. switch(flags & (SYS_MEMORY_PAGE_SIZE_1M | SYS_MEMORY_PAGE_SIZE_64K)) @@ -142,9 +145,12 @@ s32 sys_mmapper_free_memory(u32 mem_id) sys_mmapper.Warning("sys_mmapper_free_memory(mem_id=0x%x)", mem_id); // Check if this mem ID is valid. - std::shared_ptr info; - if(!Emu.GetIdManager().GetIDData(mem_id, info)) + const auto info = Emu.GetIdManager().GetIDData(mem_id); + + if (!info) + { return CELL_ESRCH; + } // Release the allocated memory and remove the ID. Emu.GetIdManager().RemoveID(mem_id); @@ -157,9 +163,12 @@ s32 sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags) sys_mmapper.Warning("sys_mmapper_map_memory(start_addr=0x%x, mem_id=0x%x, flags=0x%llx)", start_addr, mem_id, flags); // Check if this mem ID is valid. - std::shared_ptr info; - if(!Emu.GetIdManager().GetIDData(mem_id, info)) + const auto info = Emu.GetIdManager().GetIDData(mem_id); + + if (!info) + { return CELL_ESRCH; + } // Map the memory into the process address. if(!Memory.Map(start_addr, info->size)) @@ -177,9 +186,12 @@ s32 sys_mmapper_search_and_map(u32 start_addr, u32 mem_id, u64 flags, u32 alloc_ start_addr, mem_id, flags, alloc_addr); // Check if this mem ID is valid. - std::shared_ptr info; - if(!Emu.GetIdManager().GetIDData(mem_id, info)) + const auto info = Emu.GetIdManager().GetIDData(mem_id); + + if (!info) + { return CELL_ESRCH; + } // Search for a mappable address. u32 addr; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp index 29ee05df8d..a2241c62aa 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_mutex.cpp @@ -50,13 +50,13 @@ s32 sys_mutex_create(vm::ptr mutex_id, vm::ptr attr) s32 sys_mutex_destroy(u32 mutex_id) { - sys_mutex.Warning("sys_mutex_destroy(mutex_id=%d)", mutex_id); + sys_mutex.Warning("sys_mutex_destroy(mutex_id=0x%x)", mutex_id); LV2_LOCK; - std::shared_ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(mutex_id); - if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } @@ -84,20 +84,20 @@ s32 sys_mutex_destroy(u32 mutex_id) s32 sys_mutex_lock(PPUThread& CPU, u32 mutex_id, u64 timeout) { - sys_mutex.Log("sys_mutex_lock(mutex_id=%d, timeout=0x%llx)", mutex_id, timeout); + sys_mutex.Log("sys_mutex_lock(mutex_id=0x%x, timeout=0x%llx)", mutex_id, timeout); const u64 start_time = get_system_time(); LV2_LOCK; - std::shared_ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(mutex_id); - if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } - std::shared_ptr thread = Emu.GetCPU().GetThread(CPU.GetId(), CPU_THREAD_PPU); + const auto thread = Emu.GetCPU().GetThread(CPU.GetId(), CPU_THREAD_PPU); if (!mutex->owner.owner_before(thread) && !thread.owner_before(mutex->owner)) // check equality { @@ -129,7 +129,7 @@ s32 sys_mutex_lock(PPUThread& CPU, u32 mutex_id, u64 timeout) if (Emu.IsStopped()) { - sys_mutex.Warning("sys_mutex_lock(id=%d) aborted", mutex_id); + sys_mutex.Warning("sys_mutex_lock(mutex_id=0x%x) aborted", mutex_id); return CELL_OK; } @@ -144,18 +144,18 @@ s32 sys_mutex_lock(PPUThread& CPU, u32 mutex_id, u64 timeout) s32 sys_mutex_trylock(PPUThread& CPU, u32 mutex_id) { - sys_mutex.Log("sys_mutex_trylock(mutex_id=%d)", mutex_id); + sys_mutex.Log("sys_mutex_trylock(mutex_id=0x%x)", mutex_id); LV2_LOCK; - std::shared_ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(mutex_id); - if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } - std::shared_ptr thread = Emu.GetCPU().GetThread(CPU.GetId()); + const auto thread = Emu.GetCPU().GetThread(CPU.GetId()); if (!mutex->owner.owner_before(thread) && !thread.owner_before(mutex->owner)) // check equality { @@ -186,20 +186,20 @@ s32 sys_mutex_trylock(PPUThread& CPU, u32 mutex_id) s32 sys_mutex_unlock(PPUThread& CPU, u32 mutex_id) { - sys_mutex.Log("sys_mutex_unlock(mutex_id=%d)", mutex_id); + sys_mutex.Log("sys_mutex_unlock(mutex_id=0x%x)", mutex_id); LV2_LOCK; - std::shared_ptr mutex; + const auto mutex = Emu.GetIdManager().GetIDData(mutex_id); - if (!Emu.GetIdManager().GetIDData(mutex_id, mutex)) + if (!mutex) { return CELL_ESRCH; } - std::shared_ptr thread = Emu.GetCPU().GetThread(CPU.GetId()); + const auto thread = Emu.GetCPU().GetThread(CPU.GetId()); - if (mutex->owner.owner_before(thread) || thread.owner_before(mutex->owner)) // check equality + if (mutex->owner.owner_before(thread) || thread.owner_before(mutex->owner)) // check inequality { return CELL_EPERM; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp index 282d985b68..e40550a097 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.cpp @@ -10,8 +10,10 @@ SysCallBase sys_ppu_thread("sys_ppu_thread"); -void ppu_thread_exit(PPUThread& CPU, u64 errorcode) +void _sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode) { + sys_ppu_thread.Log("_sys_ppu_thread_exit(errorcode=0x%llx)", errorcode); + CPU.SetExitStatus(errorcode); CPU.Stop(); @@ -25,37 +27,25 @@ void ppu_thread_exit(PPUThread& CPU, u64 errorcode) } } -void sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode) -{ - sys_ppu_thread.Log("sys_ppu_thread_exit(0x%llx)", errorcode); - - ppu_thread_exit(CPU, errorcode); -} - -void sys_internal_ppu_thread_exit(PPUThread& CPU, u64 errorcode) -{ - sys_ppu_thread.Warning("sys_internal_ppu_thread_exit(0x%llx)", errorcode); - - ppu_thread_exit(CPU, errorcode); -} - -s32 sys_ppu_thread_yield() +void sys_ppu_thread_yield() { sys_ppu_thread.Log("sys_ppu_thread_yield()"); // Note: Or do we actually want to yield? std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack - return CELL_OK; } -s32 sys_ppu_thread_join(u64 thread_id, vm::ptr vptr) +s32 sys_ppu_thread_join(u32 thread_id, vm::ptr vptr) { - sys_ppu_thread.Warning("sys_ppu_thread_join(thread_id=%lld, vptr_addr=0x%x)", thread_id, vptr.addr()); + sys_ppu_thread.Warning("sys_ppu_thread_join(thread_id=0x%x, vptr=*0x%x)", thread_id, vptr); - std::shared_ptr thr = Emu.GetCPU().GetThread(thread_id); - if (!thr) return - CELL_ESRCH; + const auto t = Emu.GetCPU().GetThread(thread_id); - while (thr->IsAlive()) + if (!t) + { + return CELL_ESRCH; + } + + while (t->IsAlive()) { if (Emu.IsStopped()) { @@ -65,98 +55,117 @@ s32 sys_ppu_thread_join(u64 thread_id, vm::ptr vptr) std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack } - *vptr = thr->GetExitStatus(); + *vptr = t->GetExitStatus(); Emu.GetCPU().RemoveThread(thread_id); return CELL_OK; } -s32 sys_ppu_thread_detach(u64 thread_id) +s32 sys_ppu_thread_detach(u32 thread_id) { - sys_ppu_thread.Todo("sys_ppu_thread_detach(thread_id=%lld)", thread_id); + sys_ppu_thread.Warning("sys_ppu_thread_detach(thread_id=0x%x)", thread_id); - std::shared_ptr thr = Emu.GetCPU().GetThread(thread_id); - if (!thr) + const auto t = Emu.GetCPU().GetThread(thread_id); + + if (!t) + { return CELL_ESRCH; + } - if (!thr->IsJoinable()) + if (!t->IsJoinable()) + { return CELL_EINVAL; - thr->SetJoinable(false); + } + + t->SetJoinable(false); return CELL_OK; } void sys_ppu_thread_get_join_state(PPUThread& CPU, vm::ptr isjoinable) { - sys_ppu_thread.Warning("sys_ppu_thread_get_join_state(isjoinable_addr=0x%x)", isjoinable.addr()); + sys_ppu_thread.Warning("sys_ppu_thread_get_join_state(isjoinable=*0x%x)", isjoinable); *isjoinable = CPU.IsJoinable(); } -s32 sys_ppu_thread_set_priority(u64 thread_id, s32 prio) +s32 sys_ppu_thread_set_priority(u32 thread_id, s32 prio) { - sys_ppu_thread.Log("sys_ppu_thread_set_priority(thread_id=%lld, prio=%d)", thread_id, prio); + sys_ppu_thread.Log("sys_ppu_thread_set_priority(thread_id=0x%x, prio=%d)", thread_id, prio); - std::shared_ptr thr = Emu.GetCPU().GetThread(thread_id); - if (!thr) + const auto t = Emu.GetCPU().GetThread(thread_id); + + if (!t) + { return CELL_ESRCH; + } - thr->SetPrio(prio); + t->SetPrio(prio); return CELL_OK; } -s32 sys_ppu_thread_get_priority(u64 thread_id, u32 prio_addr) +s32 sys_ppu_thread_get_priority(u32 thread_id, vm::ptr priop) { - sys_ppu_thread.Log("sys_ppu_thread_get_priority(thread_id=%lld, prio_addr=0x%x)", thread_id, prio_addr); + sys_ppu_thread.Log("sys_ppu_thread_get_priority(thread_id=0x%x, priop=*0x%x)", thread_id, priop); - std::shared_ptr thr = Emu.GetCPU().GetThread(thread_id); - if(!thr) return CELL_ESRCH; + const auto t = Emu.GetCPU().GetThread(thread_id); - vm::write32(prio_addr, (s32)thr->GetPrio()); - - return CELL_OK; -} - -s32 sys_ppu_thread_get_stack_information(PPUThread& CPU, u32 info_addr) -{ - sys_ppu_thread.Log("sys_ppu_thread_get_stack_information(info_addr=0x%x)", info_addr); - - vm::write32(info_addr, (u32)CPU.GetStackAddr()); - vm::write32(info_addr + 4, CPU.GetStackSize()); - - return CELL_OK; -} - -s32 sys_ppu_thread_stop(u64 thread_id) -{ - sys_ppu_thread.Warning("sys_ppu_thread_stop(thread_id=%lld)", thread_id); - - std::shared_ptr thr = Emu.GetCPU().GetThread(thread_id); - if (!thr) + if (!t) + { return CELL_ESRCH; + } - thr->Stop(); + *priop = static_cast(t->GetPrio()); return CELL_OK; } -s32 sys_ppu_thread_restart(u64 thread_id) +s32 sys_ppu_thread_get_stack_information(PPUThread& CPU, vm::ptr sp) { - sys_ppu_thread.Warning("sys_ppu_thread_restart(thread_id=%lld)", thread_id); + sys_ppu_thread.Log("sys_ppu_thread_get_stack_information(sp=*0x%x)", sp); - std::shared_ptr thr = Emu.GetCPU().GetThread(thread_id); - if (!thr) + sp->pst_addr = CPU.GetStackAddr(); + sp->pst_size = CPU.GetStackSize(); + + return CELL_OK; +} + +s32 sys_ppu_thread_stop(u32 thread_id) +{ + sys_ppu_thread.Error("sys_ppu_thread_stop(thread_id=0x%x)", thread_id); + + const auto t = Emu.GetCPU().GetThread(thread_id); + + if (!t) + { return CELL_ESRCH; + } - thr->Stop(); - thr->Run(); + t->Stop(); + + return CELL_OK; +} + +s32 sys_ppu_thread_restart(u32 thread_id) +{ + sys_ppu_thread.Error("sys_ppu_thread_restart(thread_id=0x%x)", thread_id); + + const auto t = Emu.GetCPU().GetThread(thread_id); + + if (!t) + { + return CELL_ESRCH; + } + + t->Stop(); + t->Run(); return CELL_OK; } u32 ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, bool is_joinable, bool is_interrupt, std::string name, std::function task) { - auto new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); + const auto new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); auto& ppu = static_cast(*new_thread); @@ -177,54 +186,69 @@ u32 ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, bool is_joina return ppu.GetId(); } -s32 sys_ppu_thread_create(vm::ptr thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr threadname) +s32 _sys_ppu_thread_create(vm::ptr thread_id, vm::ptr param, u64 arg, u64 unk, s32 prio, u32 stacksize, u64 flags, vm::ptr threadname) { - sys_ppu_thread.Warning("sys_ppu_thread_create(thread_id=*0x%x, entry=0x%x, arg=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname=*0x%x)", thread_id, entry, arg, prio, stacksize, flags, threadname); + sys_ppu_thread.Warning("_sys_ppu_thread_create(thread_id=*0x%x, param=*0x%x, arg=0x%llx, unk=0x%llx, prio=%d, stacksize=0x%x, flags=0x%llx, threadname=*0x%x)", + thread_id, param, arg, unk, prio, stacksize, flags, threadname); if (prio < 0 || prio > 3071) { return CELL_EINVAL; } - bool is_joinable = flags & SYS_PPU_THREAD_CREATE_JOINABLE; - bool is_interrupt = flags & SYS_PPU_THREAD_CREATE_INTERRUPT; + const bool is_joinable = flags & SYS_PPU_THREAD_CREATE_JOINABLE; + const bool is_interrupt = flags & SYS_PPU_THREAD_CREATE_INTERRUPT; if (is_joinable && is_interrupt) { return CELL_EPERM; } - *thread_id = ppu_thread_create(entry, arg, prio, stacksize, is_joinable, is_interrupt, threadname ? threadname.get_ptr() : ""); - return CELL_OK; -} + const auto new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); -std::mutex g_once_mutex; + auto& ppu = static_cast(*new_thread); -void sys_ppu_thread_once(PPUThread& CPU, vm::ptr> once_ctrl, vm::ptr init) -{ - sys_ppu_thread.Warning("sys_ppu_thread_once(once_ctrl=*0x%x, init=*0x%x)", once_ctrl, init); + ppu.SetEntry(param->entry); + ppu.SetPrio(prio); + ppu.SetStackSize(stacksize < 0x4000 ? 0x4000 : stacksize); // (hack) adjust minimal stack size + ppu.SetJoinable(is_joinable); + ppu.SetName(threadname ? threadname.get_ptr() : ""); + ppu.Run(); - std::lock_guard lock(g_once_mutex); + ppu.GPR[3] = arg; + ppu.GPR[4] = unk; // actually unknown - if (once_ctrl->compare_and_swap_test(be_t::make(SYS_PPU_THREAD_ONCE_INIT), be_t::make(SYS_PPU_THREAD_DONE_INIT))) + if (u32 tls = param->tls) // hack { - init(CPU); + ppu.GPR[13] = tls; } -} -s32 sys_ppu_thread_get_id(PPUThread& CPU, vm::ptr thread_id) -{ - sys_ppu_thread.Log("sys_ppu_thread_get_id(thread_id_addr=0x%x)", thread_id.addr()); + *thread_id = ppu.GetId(); - *thread_id = CPU.GetId(); return CELL_OK; } -s32 sys_ppu_thread_rename(u64 thread_id, vm::ptr name) +s32 sys_ppu_thread_start(u32 thread_id) { - sys_ppu_thread.Log("sys_ppu_thread_rename(thread_id=0x%llx, name=*0x%x)", thread_id, name); + sys_ppu_thread.Warning("sys_ppu_thread_start(thread_id=0x%x)", thread_id); - std::shared_ptr t = Emu.GetCPU().GetThread(thread_id, CPU_THREAD_PPU); + const auto t = Emu.GetCPU().GetThread(thread_id, CPU_THREAD_PPU); + + if (!t) + { + return CELL_ESRCH; + } + + t->Exec(); + + return CELL_OK; +} + +s32 sys_ppu_thread_rename(u32 thread_id, vm::ptr name) +{ + sys_ppu_thread.Error("sys_ppu_thread_rename(thread_id=0x%x, name=*0x%x)", thread_id, name); + + const auto t = Emu.GetCPU().GetThread(thread_id, CPU_THREAD_PPU); if (!t) { @@ -232,5 +256,6 @@ s32 sys_ppu_thread_rename(u64 thread_id, vm::ptr name) } t->SetThreadName(name.get_ptr()); + return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h index 5894d5d9c3..8aeb276359 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_ppu_thread.h @@ -15,22 +15,32 @@ enum : u64 SYS_PPU_THREAD_CREATE_INTERRUPT = 0x2, }; +struct sys_ppu_thread_stack_t +{ + be_t pst_addr; + be_t pst_size; +}; + +struct ppu_thread_param_t +{ + be_t entry; // vm::bptr + be_t tls; // vm::bptr +}; + // Aux u32 ppu_thread_create(u32 entry, u64 arg, s32 prio, u32 stacksize, bool is_joinable, bool is_interrupt, std::string name, std::function task = nullptr); // SysCalls -void sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode); -void sys_internal_ppu_thread_exit(PPUThread& CPU, u64 errorcode); -s32 sys_ppu_thread_yield(); -s32 sys_ppu_thread_join(u64 thread_id, vm::ptr vptr); -s32 sys_ppu_thread_detach(u64 thread_id); +void _sys_ppu_thread_exit(PPUThread& CPU, u64 errorcode); +void sys_ppu_thread_yield(); +s32 sys_ppu_thread_join(u32 thread_id, vm::ptr vptr); +s32 sys_ppu_thread_detach(u32 thread_id); void sys_ppu_thread_get_join_state(PPUThread& CPU, vm::ptr isjoinable); -s32 sys_ppu_thread_set_priority(u64 thread_id, s32 prio); -s32 sys_ppu_thread_get_priority(u64 thread_id, u32 prio_addr); -s32 sys_ppu_thread_get_stack_information(PPUThread& CPU, u32 info_addr); -s32 sys_ppu_thread_stop(u64 thread_id); -s32 sys_ppu_thread_restart(u64 thread_id); -s32 sys_ppu_thread_create(vm::ptr thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr threadname); -void sys_ppu_thread_once(PPUThread& CPU, vm::ptr> once_ctrl, vm::ptr init); -s32 sys_ppu_thread_get_id(PPUThread& CPU, vm::ptr thread_id); -s32 sys_ppu_thread_rename(u64 thread_id, vm::ptr name); +s32 sys_ppu_thread_set_priority(u32 thread_id, s32 prio); +s32 sys_ppu_thread_get_priority(u32 thread_id, vm::ptr priop); +s32 sys_ppu_thread_get_stack_information(PPUThread& CPU, vm::ptr sp); +s32 sys_ppu_thread_stop(u32 thread_id); +s32 sys_ppu_thread_restart(u32 thread_id); +s32 _sys_ppu_thread_create(vm::ptr thread_id, vm::ptr param, u64 arg, u64 arg4, s32 prio, u32 stacksize, u64 flags, vm::ptr threadname); +s32 sys_ppu_thread_start(u32 thread_id); +s32 sys_ppu_thread_rename(u32 thread_id, vm::ptr name); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_process.cpp b/rpcs3/Emu/SysCalls/lv2/sys_process.cpp index ccafdcab30..1d850ec15f 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_process.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_process.cpp @@ -326,7 +326,7 @@ s32 process_get_sdk_version(u32 pid, s32& ver) s32 sys_process_get_sdk_version(u32 pid, vm::ptr version) { - sys_process.Warning("sys_process_get_sdk_version(pid=%d, version_addr=0x%x)", pid, version.addr()); + sys_process.Warning("sys_process_get_sdk_version(pid=0x%x, version_addr=0x%x)", pid, version.addr()); s32 sdk_ver; s32 ret = process_get_sdk_version(pid, sdk_ver); @@ -343,13 +343,13 @@ s32 sys_process_get_sdk_version(u32 pid, vm::ptr version) s32 sys_process_kill(u32 pid) { - sys_process.Todo("sys_process_kill(pid=%d)", pid); + sys_process.Todo("sys_process_kill(pid=0x%x)", pid); return CELL_OK; } s32 sys_process_wait_for_child(u32 pid, vm::ptr status, u64 unk) { - sys_process.Todo("sys_process_wait_for_child(pid=%d, status_addr=0x%x, unk=0x%llx", + sys_process.Todo("sys_process_wait_for_child(pid=0x%x, status_addr=0x%x, unk=0x%llx", pid, status.addr(), unk); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp b/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp index a9da2cf0fb..58b5fa1597 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_prx.cpp @@ -64,12 +64,15 @@ s32 sys_prx_load_module_on_memcontainer_by_fd() s32 sys_prx_start_module(s32 id, u32 args, u32 argp_addr, vm::ptr modres, u64 flags, vm::ptr pOpt) { - sys_prx.Todo("sys_prx_start_module(id=%d, args=%d, argp_addr=0x%x, modres_addr=0x%x, flags=0x%llx, pOpt=0x%x)", + sys_prx.Todo("sys_prx_start_module(id=0x%x, args=%d, argp_addr=0x%x, modres_addr=0x%x, flags=0x%llx, pOpt=0x%x)", id, args, argp_addr, modres.addr(), flags, pOpt.addr()); - std::shared_ptr prx; - if (!Emu.GetIdManager().GetIDData(id, prx)) + const auto prx = Emu.GetIdManager().GetIDData(id); + + if (!prx) + { return CELL_ESRCH; + } if (prx->isStarted) return CELL_PRX_ERROR_ALREADY_STARTED; @@ -79,12 +82,15 @@ s32 sys_prx_start_module(s32 id, u32 args, u32 argp_addr, vm::ptr modres, u s32 sys_prx_stop_module(s32 id, u32 args, u32 argp_addr, vm::ptr modres, u64 flags, vm::ptr pOpt) { - sys_prx.Todo("sys_prx_stop_module(id=%d, args=%d, argp_addr=0x%x, modres_addr=0x%x, flags=0x%llx, pOpt=0x%x)", + sys_prx.Todo("sys_prx_stop_module(id=0x%x, args=%d, argp_addr=0x%x, modres_addr=0x%x, flags=0x%llx, pOpt=0x%x)", id, args, argp_addr, modres.addr(), flags, pOpt.addr()); - std::shared_ptr prx; - if (!Emu.GetIdManager().GetIDData(id, prx)) + const auto prx = Emu.GetIdManager().GetIDData(id); + + if (!prx) + { return CELL_ESRCH; + } if (!prx->isStarted) return CELL_PRX_ERROR_ALREADY_STOPPED; @@ -94,12 +100,16 @@ s32 sys_prx_stop_module(s32 id, u32 args, u32 argp_addr, vm::ptr modres, u6 s32 sys_prx_unload_module(s32 id, u64 flags, vm::ptr pOpt) { - sys_prx.Todo("sys_prx_unload_module(id=%d, flags=0x%llx, pOpt=0x%x)", id, flags, pOpt.addr()); + sys_prx.Todo("sys_prx_unload_module(id=0x%x, flags=0x%llx, pOpt=0x%x)", id, flags, pOpt.addr()); // Get the PRX, free the used memory and delete the object and its ID - std::shared_ptr prx; - if (!Emu.GetIdManager().GetIDData(id, prx)) + const auto prx = Emu.GetIdManager().GetIDData(id); + + if (!prx) + { return CELL_ESRCH; + } + Memory.Free(prx->address); Emu.GetIdManager().RemoveID(id); diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp index 81c79aacf4..9757486276 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_rwlock.cpp @@ -45,13 +45,13 @@ s32 sys_rwlock_create(vm::ptr rw_lock_id, vm::ptr a s32 sys_rwlock_destroy(u32 rw_lock_id) { - sys_rwlock.Warning("sys_rwlock_destroy(rw_lock_id=%d)", rw_lock_id); + sys_rwlock.Warning("sys_rwlock_destroy(rw_lock_id=0x%x)", rw_lock_id); LV2_LOCK; - std::shared_ptr rwlock; + const auto rwlock = Emu.GetIdManager().GetIDData(rw_lock_id); - if (!Emu.GetIdManager().GetIDData(rw_lock_id, rwlock)) + if (!rwlock) { return CELL_ESRCH; } @@ -68,15 +68,15 @@ s32 sys_rwlock_destroy(u32 rw_lock_id) s32 sys_rwlock_rlock(u32 rw_lock_id, u64 timeout) { - sys_rwlock.Log("sys_rwlock_rlock(rw_lock_id=%d, timeout=0x%llx)", rw_lock_id, timeout); + sys_rwlock.Log("sys_rwlock_rlock(rw_lock_id=0x%x, timeout=0x%llx)", rw_lock_id, timeout); const u64 start_time = get_system_time(); LV2_LOCK; - std::shared_ptr rwlock; + const auto rwlock = Emu.GetIdManager().GetIDData(rw_lock_id); - if (!Emu.GetIdManager().GetIDData(rw_lock_id, rwlock)) + if (!rwlock) { return CELL_ESRCH; } @@ -94,7 +94,7 @@ s32 sys_rwlock_rlock(u32 rw_lock_id, u64 timeout) if (Emu.IsStopped()) { - sys_rwlock.Warning("sys_rwlock_rlock(id=%d) aborted", rw_lock_id); + sys_rwlock.Warning("sys_rwlock_rlock(rw_lock_id=0x%x) aborted", rw_lock_id); return CELL_OK; } @@ -109,13 +109,13 @@ s32 sys_rwlock_rlock(u32 rw_lock_id, u64 timeout) s32 sys_rwlock_tryrlock(u32 rw_lock_id) { - sys_rwlock.Log("sys_rwlock_tryrlock(rw_lock_id=%d)", rw_lock_id); + sys_rwlock.Log("sys_rwlock_tryrlock(rw_lock_id=0x%x)", rw_lock_id); LV2_LOCK; - std::shared_ptr rwlock; + const auto rwlock = Emu.GetIdManager().GetIDData(rw_lock_id); - if (!Emu.GetIdManager().GetIDData(rw_lock_id, rwlock)) + if (!rwlock) { return CELL_ESRCH; } @@ -132,13 +132,13 @@ s32 sys_rwlock_tryrlock(u32 rw_lock_id) s32 sys_rwlock_runlock(u32 rw_lock_id) { - sys_rwlock.Log("sys_rwlock_runlock(rw_lock_id=%d)", rw_lock_id); + sys_rwlock.Log("sys_rwlock_runlock(rw_lock_id=0x%x)", rw_lock_id); LV2_LOCK; - std::shared_ptr rwlock; + const auto rwlock = Emu.GetIdManager().GetIDData(rw_lock_id); - if (!Emu.GetIdManager().GetIDData(rw_lock_id, rwlock)) + if (!rwlock) { return CELL_ESRCH; } @@ -158,15 +158,15 @@ s32 sys_rwlock_runlock(u32 rw_lock_id) s32 sys_rwlock_wlock(PPUThread& CPU, u32 rw_lock_id, u64 timeout) { - sys_rwlock.Log("sys_rwlock_wlock(rw_lock_id=%d, timeout=0x%llx)", rw_lock_id, timeout); + sys_rwlock.Log("sys_rwlock_wlock(rw_lock_id=0x%x, timeout=0x%llx)", rw_lock_id, timeout); const u64 start_time = get_system_time(); LV2_LOCK; - std::shared_ptr rwlock; + const auto rwlock = Emu.GetIdManager().GetIDData(rw_lock_id); - if (!Emu.GetIdManager().GetIDData(rw_lock_id, rwlock)) + if (!rwlock) { return CELL_ESRCH; } @@ -189,7 +189,7 @@ s32 sys_rwlock_wlock(PPUThread& CPU, u32 rw_lock_id, u64 timeout) if (Emu.IsStopped()) { - sys_rwlock.Warning("sys_rwlock_wlock(id=%d) aborted", rw_lock_id); + sys_rwlock.Warning("sys_rwlock_wlock(rw_lock_id=0x%x) aborted", rw_lock_id); return CELL_OK; } @@ -204,13 +204,13 @@ s32 sys_rwlock_wlock(PPUThread& CPU, u32 rw_lock_id, u64 timeout) s32 sys_rwlock_trywlock(PPUThread& CPU, u32 rw_lock_id) { - sys_rwlock.Log("sys_rwlock_trywlock(rw_lock_id=%d)", rw_lock_id); + sys_rwlock.Log("sys_rwlock_trywlock(rw_lock_id=0x%x)", rw_lock_id); LV2_LOCK; - std::shared_ptr rwlock; + const auto rwlock = Emu.GetIdManager().GetIDData(rw_lock_id); - if (!Emu.GetIdManager().GetIDData(rw_lock_id, rwlock)) + if (!rwlock) { return CELL_ESRCH; } @@ -232,13 +232,13 @@ s32 sys_rwlock_trywlock(PPUThread& CPU, u32 rw_lock_id) s32 sys_rwlock_wunlock(PPUThread& CPU, u32 rw_lock_id) { - sys_rwlock.Log("sys_rwlock_wunlock(rw_lock_id=%d)", rw_lock_id); + sys_rwlock.Log("sys_rwlock_wunlock(rw_lock_id=0x%x)", rw_lock_id); LV2_LOCK; - std::shared_ptr rwlock; + const auto rwlock = Emu.GetIdManager().GetIDData(rw_lock_id); - if (!Emu.GetIdManager().GetIDData(rw_lock_id, rwlock)) + if (!rwlock) { return CELL_ESRCH; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp index 72b7fd7bd0..56db6b34aa 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_semaphore.cpp @@ -57,13 +57,13 @@ s32 sys_semaphore_create(vm::ptr sem, vm::ptr at s32 sys_semaphore_destroy(u32 sem) { - sys_semaphore.Warning("sys_semaphore_destroy(sem=%d)", sem); + sys_semaphore.Warning("sys_semaphore_destroy(sem=0x%x)", sem); LV2_LOCK; - std::shared_ptr semaphore; + const auto semaphore = Emu.GetIdManager().GetIDData(sem); - if (!Emu.GetIdManager().GetIDData(sem, semaphore)) + if (!semaphore) { return CELL_ESRCH; } @@ -80,15 +80,15 @@ s32 sys_semaphore_destroy(u32 sem) s32 sys_semaphore_wait(u32 sem, u64 timeout) { - sys_semaphore.Log("sys_semaphore_wait(sem=%d, timeout=0x%llx)", sem, timeout); + sys_semaphore.Log("sys_semaphore_wait(sem=0x%x, timeout=0x%llx)", sem, timeout); const u64 start_time = get_system_time(); LV2_LOCK; - std::shared_ptr semaphore; + const auto semaphore = Emu.GetIdManager().GetIDData(sem); - if (!Emu.GetIdManager().GetIDData(sem, semaphore)) + if (!semaphore) { return CELL_ESRCH; } @@ -121,13 +121,13 @@ s32 sys_semaphore_wait(u32 sem, u64 timeout) s32 sys_semaphore_trywait(u32 sem) { - sys_semaphore.Log("sys_semaphore_trywait(sem=%d)", sem); + sys_semaphore.Log("sys_semaphore_trywait(sem=0x%x)", sem); LV2_LOCK; - std::shared_ptr semaphore; + const auto semaphore = Emu.GetIdManager().GetIDData(sem); - if (!Emu.GetIdManager().GetIDData(sem, semaphore)) + if (!semaphore) { return CELL_ESRCH; } @@ -144,13 +144,13 @@ s32 sys_semaphore_trywait(u32 sem) s32 sys_semaphore_post(u32 sem, s32 count) { - sys_semaphore.Log("sys_semaphore_post(sem=%d, count=%d)", sem, count); + sys_semaphore.Log("sys_semaphore_post(sem=0x%x, count=%d)", sem, count); LV2_LOCK; - std::shared_ptr semaphore; + const auto semaphore = Emu.GetIdManager().GetIDData(sem); - if (!Emu.GetIdManager().GetIDData(sem, semaphore)) + if (!semaphore) { return CELL_ESRCH; } @@ -180,7 +180,7 @@ s32 sys_semaphore_post(u32 sem, s32 count) s32 sys_semaphore_get_value(u32 sem, vm::ptr count) { - sys_semaphore.Log("sys_semaphore_get_value(sem=%d, count=*0x%x)", sem, count); + sys_semaphore.Log("sys_semaphore_get_value(sem=0x%x, count=*0x%x)", sem, count); if (!count) { @@ -189,9 +189,9 @@ s32 sys_semaphore_get_value(u32 sem, vm::ptr count) LV2_LOCK; - std::shared_ptr semaphore; + const auto semaphore = Emu.GetIdManager().GetIDData(sem); - if (!Emu.GetIdManager().GetIDData(sem, semaphore)) + if (!semaphore) { return CELL_ESRCH; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp index ee8f1ca6dd..7790bb0f4b 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.cpp @@ -99,7 +99,7 @@ u32 spu_thread_initialize(u32 group_id, u32 spu_num, vm::ptr img, sys_spu.Todo("Unsupported SPU Thread options (0x%x)", option); } - auto t = Emu.GetCPU().AddThread(CPU_THREAD_SPU); + const auto t = Emu.GetCPU().AddThread(CPU_THREAD_SPU); auto& spu = static_cast(*t); @@ -108,8 +108,7 @@ u32 spu_thread_initialize(u32 group_id, u32 spu_num, vm::ptr img, spu.SetName(name); spu.m_custom_task = task; - std::shared_ptr group; - Emu.GetIdManager().GetIDData(group_id, group); + const auto group = Emu.GetIdManager().GetIDData(group_id); spu.tg = group; group->threads[spu_num] = t; @@ -137,12 +136,13 @@ u32 spu_thread_initialize(u32 group_id, u32 spu_num, vm::ptr img, s32 sys_spu_thread_initialize(vm::ptr thread, u32 group_id, u32 spu_num, vm::ptr img, vm::ptr attr, vm::ptr arg) { - sys_spu.Warning("sys_spu_thread_initialize(thread=*0x%x, group=%d, spu_num=%d, img=*0x%x, attr=*0x%x, arg=*0x%x)", thread, group_id, spu_num, img, attr, arg); + sys_spu.Warning("sys_spu_thread_initialize(thread=*0x%x, group=0x%x, spu_num=%d, img=*0x%x, attr=*0x%x, arg=*0x%x)", thread, group_id, spu_num, img, attr, arg); LV2_LOCK; - std::shared_ptr group; - if (!Emu.GetIdManager().GetIDData(group_id, group)) + const auto group = Emu.GetIdManager().GetIDData(group_id); + + if (!group) { return CELL_ESRCH; } @@ -163,11 +163,12 @@ s32 sys_spu_thread_initialize(vm::ptr thread, u32 group_id, u32 spu_num, vm s32 sys_spu_thread_set_argument(u32 id, vm::ptr arg) { - sys_spu.Warning("sys_spu_thread_set_argument(id=%d, arg=*0x%x)", id, arg); + sys_spu.Warning("sys_spu_thread_set_argument(id=0x%x, arg=*0x%x)", id, arg); LV2_LOCK; - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + if (!t) { return CELL_ESRCH; @@ -175,7 +176,7 @@ s32 sys_spu_thread_set_argument(u32 id, vm::ptr arg) auto& spu = static_cast(*t); - std::shared_ptr group = spu.tg.lock(); + const auto group = spu.tg.lock(); assert(spu.index < group->threads.size()); @@ -189,11 +190,11 @@ s32 sys_spu_thread_set_argument(u32 id, vm::ptr arg) s32 sys_spu_thread_get_exit_status(u32 id, vm::ptr status) { - sys_spu.Warning("sys_spu_thread_get_exit_status(id=%d, status=*0x%x)", id, status); + sys_spu.Warning("sys_spu_thread_get_exit_status(id=0x%x, status=*0x%x)", id, status); LV2_LOCK; - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -242,12 +243,13 @@ s32 sys_spu_thread_group_create(vm::ptr id, u32 num, s32 prio, vm::ptr group; - if (!Emu.GetIdManager().GetIDData(id, group)) + const auto group = Emu.GetIdManager().GetIDData(id); + + if (!group) { return CELL_ESRCH; } @@ -279,12 +281,13 @@ s32 sys_spu_thread_group_destroy(u32 id) s32 sys_spu_thread_group_start(u32 id) { - sys_spu.Warning("sys_spu_thread_group_start(id=%d)", id); + sys_spu.Warning("sys_spu_thread_group_start(id=0x%x)", id); LV2_LOCK; - std::shared_ptr group; - if (!Emu.GetIdManager().GetIDData(id, group)) + const auto group = Emu.GetIdManager().GetIDData(id); + + if (!group) { return CELL_ESRCH; } @@ -326,10 +329,7 @@ s32 sys_spu_thread_group_start(u32 id) // because SPU_THREAD_GROUP_STATUS_READY is not possible, run event is delivered immediately - if (std::shared_ptr queue = group->ep_run.lock()) - { - queue->push(SYS_SPU_THREAD_GROUP_EVENT_RUN_KEY, id, 0, 0); // TODO: check data2 and data3 - } + group->send_run_event(lv2_lock, id, 0, 0); // TODO: check data2 and data3 for (auto& t : group->threads) { @@ -344,12 +344,13 @@ s32 sys_spu_thread_group_start(u32 id) s32 sys_spu_thread_group_suspend(u32 id) { - sys_spu.Log("sys_spu_thread_group_suspend(id=%d)", id); + sys_spu.Log("sys_spu_thread_group_suspend(id=0x%x)", id); LV2_LOCK; - std::shared_ptr group; - if (!Emu.GetIdManager().GetIDData(id, group)) + const auto group = Emu.GetIdManager().GetIDData(id); + + if (!group) { return CELL_ESRCH; } @@ -398,12 +399,13 @@ s32 sys_spu_thread_group_suspend(u32 id) s32 sys_spu_thread_group_resume(u32 id) { - sys_spu.Log("sys_spu_thread_group_resume(id=%d)", id); + sys_spu.Log("sys_spu_thread_group_resume(id=0x%x)", id); LV2_LOCK; - std::shared_ptr group; - if (!Emu.GetIdManager().GetIDData(id, group)) + const auto group = Emu.GetIdManager().GetIDData(id); + + if (!group) { return CELL_ESRCH; } @@ -444,19 +446,20 @@ s32 sys_spu_thread_group_resume(u32 id) s32 sys_spu_thread_group_yield(u32 id) { - sys_spu.Log("sys_spu_thread_group_yield(id=%d)", id); + sys_spu.Log("sys_spu_thread_group_yield(id=0x%x)", id); LV2_LOCK; - std::shared_ptr group; - if (!Emu.GetIdManager().GetIDData(id, group)) + const auto group = Emu.GetIdManager().GetIDData(id); + + if (!group) { return CELL_ESRCH; } if (group->state != SPU_THREAD_GROUP_STATUS_RUNNING) { - return CELL_EINVAL; + return CELL_ESTAT; } // SPU_THREAD_GROUP_STATUS_READY state is not used, so this function does nothing @@ -466,16 +469,15 @@ s32 sys_spu_thread_group_yield(u32 id) s32 sys_spu_thread_group_terminate(u32 id, s32 value) { - sys_spu.Warning("sys_spu_thread_group_terminate(id=%d, value=0x%x)", id, value); + sys_spu.Warning("sys_spu_thread_group_terminate(id=0x%x, value=0x%x)", id, value); LV2_LOCK; // seems the id can be either SPU Thread Group or SPU Thread + auto thread = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + auto group = Emu.GetIdManager().GetIDData(id); - std::shared_ptr group; - std::shared_ptr thread = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); - - if (!Emu.GetIdManager().GetIDData(id, group) && !thread) + if (!group && !thread) { return CELL_ESRCH; } @@ -510,7 +512,7 @@ s32 sys_spu_thread_group_terminate(u32 id, s32 value) if ((group->state <= SPU_THREAD_GROUP_STATUS_INITIALIZED) || (group->state == SPU_THREAD_GROUP_STATUS_WAITING)) { - return CELL_EINVAL; + return CELL_ESTAT; } for (auto& t : group->threads) @@ -534,12 +536,13 @@ s32 sys_spu_thread_group_terminate(u32 id, s32 value) s32 sys_spu_thread_group_join(u32 id, vm::ptr cause, vm::ptr status) { - sys_spu.Warning("sys_spu_thread_group_join(id=%d, cause=*0x%x, status=*0x%x)", id, cause, status); + sys_spu.Warning("sys_spu_thread_group_join(id=0x%x, cause=*0x%x, status=*0x%x)", id, cause, status); LV2_LOCK; - std::shared_ptr group; - if (!Emu.GetIdManager().GetIDData(id, group)) + const auto group = Emu.GetIdManager().GetIDData(id); + + if (!group) { return CELL_ESRCH; } @@ -580,7 +583,7 @@ s32 sys_spu_thread_group_join(u32 id, vm::ptr cause, vm::ptr status) if (Emu.IsStopped()) { - sys_spu.Warning("sys_spu_thread_group_join(id=%d) aborted", id); + sys_spu.Warning("sys_spu_thread_group_join(id=0x%x) aborted", id); return CELL_OK; } @@ -619,9 +622,9 @@ s32 sys_spu_thread_group_join(u32 id, vm::ptr cause, vm::ptr status) s32 sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type) { - sys_spu.Log("sys_spu_thread_write_ls(id=%d, address=0x%x, value=0x%llx, type=%d)", id, address, value, type); + sys_spu.Log("sys_spu_thread_write_ls(id=0x%x, address=0x%x, value=0x%llx, type=%d)", id, address, value, type); - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -654,9 +657,9 @@ s32 sys_spu_thread_write_ls(u32 id, u32 address, u64 value, u32 type) s32 sys_spu_thread_read_ls(u32 id, u32 address, vm::ptr value, u32 type) { - sys_spu.Log("sys_spu_thread_read_ls(id=%d, address=0x%x, value=*0x%x, type=%d)", id, address, value, type); + sys_spu.Log("sys_spu_thread_read_ls(id=0x%x, address=0x%x, value=*0x%x, type=%d)", id, address, value, type); - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -689,9 +692,9 @@ s32 sys_spu_thread_read_ls(u32 id, u32 address, vm::ptr value, u32 type) s32 sys_spu_thread_write_spu_mb(u32 id, u32 value) { - sys_spu.Warning("sys_spu_thread_write_spu_mb(id=%d, value=0x%x)", id, value); + sys_spu.Warning("sys_spu_thread_write_spu_mb(id=0x%x, value=0x%x)", id, value); - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -707,9 +710,9 @@ s32 sys_spu_thread_write_spu_mb(u32 id, u32 value) s32 sys_spu_thread_set_spu_cfg(u32 id, u64 value) { - sys_spu.Warning("sys_spu_thread_set_spu_cfg(id=%d, value=0x%x)", id, value); + sys_spu.Warning("sys_spu_thread_set_spu_cfg(id=0x%x, value=0x%x)", id, value); - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -730,9 +733,9 @@ s32 sys_spu_thread_set_spu_cfg(u32 id, u64 value) s32 sys_spu_thread_get_spu_cfg(u32 id, vm::ptr value) { - sys_spu.Warning("sys_spu_thread_get_spu_cfg(id=%d, value=*0x%x)", id, value); + sys_spu.Warning("sys_spu_thread_get_spu_cfg(id=0x%x, value=*0x%x)", id, value); - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -748,9 +751,9 @@ s32 sys_spu_thread_get_spu_cfg(u32 id, vm::ptr value) s32 sys_spu_thread_write_snr(u32 id, u32 number, u32 value) { - sys_spu.Log("sys_spu_thread_write_snr(id=%d, number=%d, value=0x%x)", id, number, value); + sys_spu.Log("sys_spu_thread_write_snr(id=0x%x, number=%d, value=0x%x)", id, number, value); - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -771,14 +774,14 @@ s32 sys_spu_thread_write_snr(u32 id, u32 number, u32 value) s32 sys_spu_thread_group_connect_event(u32 id, u32 eq, u32 et) { - sys_spu.Warning("sys_spu_thread_group_connect_event(id=%d, eq=%d, et=%d)", id, eq, et); + sys_spu.Warning("sys_spu_thread_group_connect_event(id=0x%x, eq=0x%x, et=%d)", id, eq, et); LV2_LOCK; - std::shared_ptr group; - std::shared_ptr queue; + const auto group = Emu.GetIdManager().GetIDData(id); + const auto queue = Emu.GetIdManager().GetIDData(eq); - if (!Emu.GetIdManager().GetIDData(id, group) || !Emu.GetIdManager().GetIDData(eq, queue)) + if (!group || !queue) { return CELL_ESRCH; } @@ -827,13 +830,13 @@ s32 sys_spu_thread_group_connect_event(u32 id, u32 eq, u32 et) s32 sys_spu_thread_group_disconnect_event(u32 id, u32 et) { - sys_spu.Warning("sys_spu_thread_group_disconnect_event(id=%d, et=%d)", id, et); + sys_spu.Warning("sys_spu_thread_group_disconnect_event(id=0x%x, et=%d)", id, et); LV2_LOCK; - std::shared_ptr group; + const auto group = Emu.GetIdManager().GetIDData(id); - if (!Emu.GetIdManager().GetIDData(id, group)) + if (!group) { return CELL_ESRCH; } @@ -890,15 +893,14 @@ s32 sys_spu_thread_tryreceive_event(u32 spuq_num, mem32_t d1, mem32_t d2, mem32_ s32 sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup) { - sys_spu.Warning("sys_spu_thread_connect_event(id=%d, eq=%d, et=%d, spup=%d)", id, eq, et, spup); + sys_spu.Warning("sys_spu_thread_connect_event(id=0x%x, eq=0x%x, et=%d, spup=%d)", id, eq, et, spup); LV2_LOCK; - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto queue = Emu.GetIdManager().GetIDData(eq); - std::shared_ptr queue; - - if (!t || !Emu.GetIdManager().GetIDData(eq, queue)) + if (!t || !queue) { return CELL_ESRCH; } @@ -925,11 +927,11 @@ s32 sys_spu_thread_connect_event(u32 id, u32 eq, u32 et, u8 spup) s32 sys_spu_thread_disconnect_event(u32 id, u32 et, u8 spup) { - sys_spu.Warning("sys_spu_thread_disconnect_event(id=%d, event_type=%d, spup=%d)", id, et, spup); + sys_spu.Warning("sys_spu_thread_disconnect_event(id=0x%x, et=%d, spup=%d)", id, et, spup); LV2_LOCK; - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -958,15 +960,14 @@ s32 sys_spu_thread_disconnect_event(u32 id, u32 et, u8 spup) s32 sys_spu_thread_bind_queue(u32 id, u32 spuq, u32 spuq_num) { - sys_spu.Warning("sys_spu_thread_bind_queue(id=%d, spuq=%d, spuq_num=0x%x)", id, spuq, spuq_num); + sys_spu.Warning("sys_spu_thread_bind_queue(id=0x%x, spuq=0x%x, spuq_num=0x%x)", id, spuq, spuq_num); LV2_LOCK; - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto queue = Emu.GetIdManager().GetIDData(spuq); - std::shared_ptr queue; - - if (!t || !Emu.GetIdManager().GetIDData(spuq, queue)) + if (!t || !queue) { return CELL_ESRCH; } @@ -1005,11 +1006,11 @@ s32 sys_spu_thread_bind_queue(u32 id, u32 spuq, u32 spuq_num) s32 sys_spu_thread_unbind_queue(u32 id, u32 spuq_num) { - sys_spu.Warning("sys_spu_thread_unbind_queue(id=%d, spuq_num=0x%x)", id, spuq_num); + sys_spu.Warning("sys_spu_thread_unbind_queue(id=0x%x, spuq_num=0x%x)", id, spuq_num); LV2_LOCK; - std::shared_ptr t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); + const auto t = Emu.GetCPU().GetThread(id, CPU_THREAD_SPU); if (!t) { @@ -1033,14 +1034,14 @@ s32 sys_spu_thread_unbind_queue(u32 id, u32 spuq_num) s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, vm::ptr spup) { - sys_spu.Warning("sys_spu_thread_group_connect_event_all_threads(id=%d, eq=%d, req=0x%llx, spup=*0x%x)", id, eq, req, spup); + sys_spu.Warning("sys_spu_thread_group_connect_event_all_threads(id=0x%x, eq=0x%x, req=0x%llx, spup=*0x%x)", id, eq, req, spup); LV2_LOCK; - std::shared_ptr group; - std::shared_ptr queue; + const auto group = Emu.GetIdManager().GetIDData(id); + const auto queue = Emu.GetIdManager().GetIDData(eq); - if (!Emu.GetIdManager().GetIDData(id, group) || !Emu.GetIdManager().GetIDData(eq, queue)) + if (!group || !queue) { return CELL_ESRCH; } @@ -1108,12 +1109,13 @@ s32 sys_spu_thread_group_connect_event_all_threads(u32 id, u32 eq, u64 req, vm:: s32 sys_spu_thread_group_disconnect_event_all_threads(u32 id, u8 spup) { - sys_spu.Warning("sys_spu_thread_group_disconnect_event_all_threads(id=%d, spup=%d)", id, spup); + sys_spu.Warning("sys_spu_thread_group_disconnect_event_all_threads(id=0x%x, spup=%d)", id, spup); LV2_LOCK; - std::shared_ptr group; - if (!Emu.GetIdManager().GetIDData(id, group)) + const auto group = Emu.GetIdManager().GetIDData(id); + + if (!group) { return CELL_ESRCH; } @@ -1142,7 +1144,7 @@ s32 sys_raw_spu_create(vm::ptr id, vm::ptr attr) LV2_LOCK; - auto t = Emu.GetCPU().AddThread(CPU_THREAD_RAW_SPU); + const auto t = Emu.GetCPU().AddThread(CPU_THREAD_RAW_SPU); if (!t) { @@ -1164,7 +1166,7 @@ s32 sys_raw_spu_destroy(u32 id) LV2_LOCK; - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) { @@ -1191,7 +1193,7 @@ s32 sys_raw_spu_create_interrupt_tag(u32 id, u32 class_id, u32 hwthread, vm::ptr return CELL_EINVAL; } - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) { @@ -1221,7 +1223,7 @@ s32 sys_raw_spu_set_int_mask(u32 id, u32 class_id, u64 mask) return CELL_EINVAL; } - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) { @@ -1244,7 +1246,7 @@ s32 sys_raw_spu_get_int_mask(u32 id, u32 class_id, vm::ptr mask) return CELL_EINVAL; } - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) { @@ -1267,7 +1269,7 @@ s32 sys_raw_spu_set_int_stat(u32 id, u32 class_id, u64 stat) return CELL_EINVAL; } - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) { @@ -1290,7 +1292,7 @@ s32 sys_raw_spu_get_int_stat(u32 id, u32 class_id, vm::ptr stat) return CELL_EINVAL; } - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) { @@ -1308,7 +1310,7 @@ s32 sys_raw_spu_read_puint_mb(u32 id, vm::ptr value) { sys_spu.Log("sys_raw_spu_read_puint_mb(id=%d, value=*0x%x)", id, value); - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) { @@ -1331,7 +1333,7 @@ s32 sys_raw_spu_set_spu_cfg(u32 id, u32 value) sys_spu.Fatal("sys_raw_spu_set_spu_cfg(id=%d, value=0x%x)", id, value); } - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) { @@ -1349,7 +1351,7 @@ s32 sys_raw_spu_get_spu_cfg(u32 id, vm::ptr value) { sys_spu.Log("sys_raw_spu_get_spu_afg(id=%d, value=*0x%x)", id, value); - std::shared_ptr t = Emu.GetCPU().GetRawSPUThread(id); + const auto t = Emu.GetCPU().GetRawSPUThread(id); if (!t) { diff --git a/rpcs3/Emu/SysCalls/lv2/sys_spu.h b/rpcs3/Emu/SysCalls/lv2/sys_spu.h index cfa67f082c..45884f9744 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_spu.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_spu.h @@ -1,6 +1,6 @@ #pragma once -struct event_queue_t; +#include "sys_event.h" enum : s32 { @@ -172,6 +172,36 @@ struct spu_group_t , join_state(0) { } + + void send_run_event(lv2_lock_type& lv2_lock, u64 data1, u64 data2, u64 data3) + { + CHECK_LV2_LOCK(lv2_lock); + + if (const auto queue = ep_run.lock()) + { + queue->push(lv2_lock, SYS_SPU_THREAD_GROUP_EVENT_RUN_KEY, data1, data2, data3); + } + } + + void send_exception_event(lv2_lock_type& lv2_lock, u64 data1, u64 data2, u64 data3) + { + CHECK_LV2_LOCK(lv2_lock); + + if (const auto queue = ep_exception.lock()) + { + queue->push(lv2_lock, SYS_SPU_THREAD_GROUP_EVENT_EXCEPTION_KEY, data1, data2, data3); + } + } + + void send_sysmodule_event(lv2_lock_type& lv2_lock, u64 data1, u64 data2, u64 data3) + { + CHECK_LV2_LOCK(lv2_lock); + + if (const auto queue = ep_sysmodule.lock()) + { + queue->push(lv2_lock, SYS_SPU_THREAD_GROUP_EVENT_SYSTEM_MODULE_KEY, data1, data2, data3); + } + } }; class SPUThread; diff --git a/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp b/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp index 823199a827..c1fb0ffa59 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_timer.cpp @@ -18,7 +18,7 @@ s32 sys_timer_create(vm::ptr timer_id) std::shared_ptr timer(new lv2_timer_t); - thread_t(fmt::format("Timer[%d] Thread", (*timer_id = Emu.GetIdManager().GetNewID(timer, TYPE_TIMER))), [timer]() + thread_t(fmt::format("Timer[0x%x] Thread", (*timer_id = Emu.GetIdManager().GetNewID(timer, TYPE_TIMER))), [timer]() { LV2_LOCK; @@ -28,11 +28,11 @@ s32 sys_timer_create(vm::ptr timer_id) { if (get_system_time() >= timer->start) { - std::shared_ptr queue = timer->port.lock(); + const auto queue = timer->port.lock(); if (queue) { - queue->push(timer->source, timer->data1, timer->data2, timer->start); + queue->push(lv2_lock, timer->source, timer->data1, timer->data2, timer->start); } if (timer->period && queue) @@ -58,13 +58,13 @@ s32 sys_timer_create(vm::ptr timer_id) s32 sys_timer_destroy(u32 timer_id) { - sys_timer.Warning("sys_timer_destroy(timer_id=%d)", timer_id); + sys_timer.Warning("sys_timer_destroy(timer_id=0x%x)", timer_id); LV2_LOCK; - std::shared_ptr timer; + const auto timer = Emu.GetIdManager().GetIDData(timer_id); - if (!Emu.GetIdManager().GetIDData(timer_id, timer)) + if (!timer) { return CELL_ESRCH; } @@ -81,13 +81,13 @@ s32 sys_timer_destroy(u32 timer_id) s32 sys_timer_get_information(u32 timer_id, vm::ptr info) { - sys_timer.Warning("sys_timer_get_information(timer_id=%d, info=*0x%x)", timer_id, info); + sys_timer.Warning("sys_timer_get_information(timer_id=0x%x, info=*0x%x)", timer_id, info); LV2_LOCK; - std::shared_ptr timer; + const auto timer = Emu.GetIdManager().GetIDData(timer_id); - if (!Emu.GetIdManager().GetIDData(timer_id, timer)) + if (!timer) { return CELL_ESRCH; } @@ -102,15 +102,15 @@ s32 sys_timer_get_information(u32 timer_id, vm::ptr inf s32 _sys_timer_start(u32 timer_id, u64 base_time, u64 period) { - sys_timer.Warning("_sys_timer_start(timer_id=%d, base_time=0x%llx, period=0x%llx)", timer_id, base_time, period); + sys_timer.Warning("_sys_timer_start(timer_id=0x%x, base_time=0x%llx, period=0x%llx)", timer_id, base_time, period); const u64 start_time = get_system_time(); LV2_LOCK; - std::shared_ptr timer; + const auto timer = Emu.GetIdManager().GetIDData(timer_id); - if (!Emu.GetIdManager().GetIDData(timer_id, timer)) + if (!timer) { return CELL_ESRCH; } @@ -160,9 +160,9 @@ s32 sys_timer_stop(u32 timer_id) LV2_LOCK; - std::shared_ptr timer; + const auto timer = Emu.GetIdManager().GetIDData(timer_id); - if (!Emu.GetIdManager().GetIDData(timer_id, timer)) + if (!timer) { return CELL_ESRCH; } @@ -174,14 +174,14 @@ s32 sys_timer_stop(u32 timer_id) s32 sys_timer_connect_event_queue(u32 timer_id, u32 queue_id, u64 name, u64 data1, u64 data2) { - sys_timer.Warning("sys_timer_connect_event_queue(timer_id=%d, queue_id=%d, name=0x%llx, data1=0x%llx, data2=0x%llx)", timer_id, queue_id, name, data1, data2); + sys_timer.Warning("sys_timer_connect_event_queue(timer_id=0x%x, queue_id=0x%x, name=0x%llx, data1=0x%llx, data2=0x%llx)", timer_id, queue_id, name, data1, data2); LV2_LOCK; - std::shared_ptr timer; - std::shared_ptr queue; + const auto timer = Emu.GetIdManager().GetIDData(timer_id); + const auto queue = Emu.GetIdManager().GetIDData(queue_id); - if (!Emu.GetIdManager().GetIDData(timer_id, timer) || !Emu.GetIdManager().GetIDData(queue_id, queue)) + if (!timer || !queue) { return CELL_ESRCH; } @@ -201,13 +201,13 @@ s32 sys_timer_connect_event_queue(u32 timer_id, u32 queue_id, u64 name, u64 data s32 sys_timer_disconnect_event_queue(u32 timer_id) { - sys_timer.Warning("sys_timer_disconnect_event_queue(timer_id=%d)", timer_id); + sys_timer.Warning("sys_timer_disconnect_event_queue(timer_id=0x%x)", timer_id); LV2_LOCK; - std::shared_ptr timer; + const auto timer = Emu.GetIdManager().GetIDData(timer_id); - if (!Emu.GetIdManager().GetIDData(timer_id, timer)) + if (!timer) { return CELL_ESRCH; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp b/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp index f68bc2895b..da5144cd04 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_vm.cpp @@ -12,7 +12,7 @@ std::shared_ptr current_ct; s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, u32 addr) { - sys_vm.Error("sys_vm_memory_map(vsize=0x%x, psize=0x%x, cidr=0x%x, flags=0x%llx, policy=0x%llx, addr_addr=0x%x)", + sys_vm.Error("sys_vm_memory_map(vsize=0x%x, psize=0x%x, cid=0x%x, flags=0x%llx, policy=0x%llx, addr_addr=0x%x)", vsize, psize, cid, flag, policy, addr); // Check virtual size. @@ -39,8 +39,12 @@ s32 sys_vm_memory_map(u32 vsize, u32 psize, u32 cid, u64 flag, u64 policy, u32 a else { // Check memory container. - std::shared_ptr ct; - if(!Emu.GetIdManager().GetIDData(cid, ct)) return CELL_ESRCH; + const auto ct = Emu.GetIdManager().GetIDData(cid); + + if (!ct) + { + return CELL_ESRCH; + } current_ct = ct; } diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index e5d6bf05b3..fe7578ab0a 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -1,6 +1,6 @@ #include "stdafx.h" #include "Utilities/Log.h" -#include "Utilities/rFile.h" +#include "Utilities/File.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" @@ -26,12 +26,12 @@ #include "Emu/Audio/AudioManager.h" #include "Emu/FS/VFS.h" #include "Emu/Event.h" -#include "Emu/SysCalls/SyncPrimitivesManager.h" #include "Loader/PSF.h" +#include "Loader/ELF64.h" +#include "Loader/ELF32.h" #include "../Crypto/unself.h" -#include #include using namespace PPU_instr; @@ -55,7 +55,6 @@ Emulator::Emulator() , m_callback_manager(new CallbackManager()) , m_event_manager(new EventManager()) , m_module_manager(new ModuleManager()) - , m_sync_prim_manager(new SyncPrimManager()) , m_vfs(new VFS()) { m_loader.register_handler(new loader::handlers::elf32); @@ -74,7 +73,6 @@ Emulator::~Emulator() delete m_callback_manager; delete m_event_manager; delete m_module_manager; - delete m_sync_prim_manager; delete m_vfs; } @@ -149,11 +147,12 @@ bool Emulator::BootGame(const std::string& path, bool direct) "/USRDIR/EBOOT.BIN", "/EBOOT.BIN" }; + auto curpath = path; if (direct) { - if (rFile::Access(curpath, rFile::read)) + if (fs::is_file(curpath)) { SetPath(curpath); Load(); @@ -166,7 +165,7 @@ bool Emulator::BootGame(const std::string& path, bool direct) { curpath = path + elf_path[i]; - if (rFile::Access(curpath, rFile::read)) + if (fs::is_file(curpath)) { SetPath(curpath); Load(); @@ -182,30 +181,69 @@ void Emulator::Load() { GetModuleManager().Init(); - if (!rExists(m_path)) return; + if (!fs::is_file(m_path)) return; + + const std::string elf_dir = m_path.substr(0, m_path.find_last_of("/\\", std::string::npos, 2) + 1); if (IsSelf(m_path)) { - std::string elf_path = rFileName(m_path).GetPath(); + const std::string full_name = m_path.substr(elf_dir.length()); - if (fmt::CmpNoCase(rFileName(m_path).GetFullName(),"EBOOT.BIN") == 0) + 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") { - elf_path += "/BOOT.BIN"; + m_path = elf_dir + "BOOT.BIN"; + } + else if (fmt::toupper(ext) == ".SELF") + { + m_path = elf_dir + base_name + ".elf"; + } + else if (fmt::toupper(ext) == ".SPRX") + { + m_path = elf_dir + base_name + ".prx"; } else { - elf_path += "/" + rFileName(m_path).GetName() + ".elf"; + m_path = elf_dir + base_name + ".decrypted" + ext; } - if (!DecryptSelf(elf_path, m_path)) - return; + LOG_NOTICE(LOADER, "Decrypting '%s%s'...", elf_dir, full_name); - m_path = elf_path; + if (!DecryptSelf(m_path, elf_dir + full_name)) + { + return; + } } LOG_NOTICE(LOADER, "Loading '%s'...", m_path.c_str()); GetInfo().Reset(); - GetVFS().Init(rFileName(m_path).GetPath()); + GetVFS().Init(elf_dir); + + // /dev_bdvd/ mounting + vfsFile f("/app_home/../dev_bdvd.path"); + if (f.IsOpened()) + { + // load specified /dev_bdvd/ directory and mount it + std::string bdvd; + bdvd.resize(f.GetSize()); + f.Read(&bdvd[0], bdvd.size()); + + Emu.GetVFS().Mount("/dev_bdvd/", bdvd, new vfsDeviceLocalFile()); + } + else if (fs::is_file(elf_dir + "../../PS3_DISC.SFB")) // guess loading disc game + { + const auto dir_list = fmt::split(elf_dir, { "/", "\\" }); + + // check latest two directories + if (dir_list.size() >= 2 && dir_list.back() == "USRDIR" && *(dir_list.end() - 2) == "PS3_GAME") + { + // mount detected /dev_bdvd/ directory + Emu.GetVFS().Mount("/dev_bdvd/", elf_dir.substr(0, elf_dir.length() - 17), new vfsDeviceLocalFile()); + } + } LOG_NOTICE(LOADER, " "); //used to be skip_line LOG_NOTICE(LOADER, "Mount info:"); @@ -215,9 +253,8 @@ void Emulator::Load() } LOG_NOTICE(LOADER, " "); //used to be skip_line - vfsFile sfo("/app_home/../PARAM.SFO"); - PSFLoader psf(sfo); - psf.Load(false); + f.Open("/app_home/../PARAM.SFO"); + const PSFLoader psf(f); std::string title = psf.GetString("TITLE"); std::string title_id = psf.GetString("TITLE_ID"); LOG_NOTICE(LOADER, "Title: %s", title.c_str()); @@ -226,30 +263,21 @@ void Emulator::Load() title.length() ? SetTitle(title) : SetTitle(m_path); SetTitleID(title_id); - // bdvd inserting imitation - vfsFile f1("/app_home/../dev_bdvd.path"); - if (f1.IsOpened()) - { - std::string bdvd; - bdvd.resize(f1.GetSize()); - f1.Read(&bdvd[0], bdvd.size()); - - // load desired /dev_bdvd/ real directory and remount - Emu.GetVFS().Mount("/dev_bdvd/", bdvd, new vfsDeviceLocalFile()); - LOG_NOTICE(LOADER, "/dev_bdvd/ remounted into %s", bdvd.c_str()); - } - LOG_NOTICE(LOADER, " "); //used to be skip_line - if (m_elf_path.empty()) { - GetVFS().GetDeviceLocal(m_path, m_elf_path); + if (!GetVFS().GetDeviceLocal(m_path, m_elf_path)) + { + m_elf_path = "/host_root/" + m_path; // should be probably app_home + } + + LOG_NOTICE(LOADER, "Elf path: %s", m_elf_path); } - vfsFile f(m_elf_path); + f.Open(m_elf_path); if (!f.IsOpened()) { - LOG_ERROR(LOADER, "Elf not found! (%s - %s)", m_path.c_str(), m_elf_path.c_str()); + LOG_ERROR(LOADER, "Opening '%s' failed", m_path.c_str()); return; } @@ -352,13 +380,11 @@ void Emulator::Stop() finalize_psv_modules(); clear_all_psv_objects(); - for (auto& v : g_armv7_dump) + for (auto& v : decltype(g_armv7_dump)(std::move(g_armv7_dump))) { LOG_NOTICE(ARMv7, v.second); } - g_armv7_dump.clear(); - m_rsx_callback = 0; // TODO: check finalization order @@ -379,7 +405,6 @@ void Emulator::Stop() GetMouseManager().Close(); GetCallbackManager().Clear(); GetModuleManager().Close(); - GetSyncPrimManager().Close(); CurGameInfo.Reset(); Memory.Close(); @@ -411,9 +436,7 @@ void Emulator::SavePoints(const std::string& path) void Emulator::LoadPoints(const std::string& path) { - struct stat buf; - if (!stat(path.c_str(), &buf)) - return; + if (!fs::is_file(path)) return; std::ifstream f(path, std::ios::binary); if (!f.is_open()) return; @@ -426,7 +449,7 @@ void Emulator::LoadPoints(const std::string& path) if (version != bpdb_version || (sizeof(u16) + break_count * sizeof(u64) + sizeof(u32) + marked_count * sizeof(u64) + sizeof(u32)) != length) { - LOG_ERROR(LOADER, "'%s' is broken", path.c_str()); + LOG_ERROR(LOADER, "'%s' is broken (version=0x%x, break_count=0x%x, marked_count=0x%x, length=0x%x)", path, version, break_count, marked_count, length); return; } diff --git a/rpcs3/Emu/System.h b/rpcs3/Emu/System.h index acd5db21e5..5f8c114132 100644 --- a/rpcs3/Emu/System.h +++ b/rpcs3/Emu/System.h @@ -21,7 +21,6 @@ class CallbackManager; class CPUThread; class EventManager; class ModuleManager; -class SyncPrimManager; struct VFS; struct EmuInfo @@ -91,7 +90,6 @@ class Emulator CallbackManager* m_callback_manager; EventManager* m_event_manager; ModuleManager* m_module_manager; - SyncPrimManager* m_sync_prim_manager; VFS* m_vfs; EmuInfo m_info; @@ -152,7 +150,6 @@ public: std::vector& GetMarkedPoints() { return m_marked_points; } EventManager& GetEventManager() { return *m_event_manager; } ModuleManager& GetModuleManager() { return *m_module_manager; } - SyncPrimManager& GetSyncPrimManager() { return *m_sync_prim_manager; } void SetTLSData(u32 addr, u32 filesz, u32 memsz) { @@ -199,7 +196,10 @@ public: __forceinline bool IsReady() const { return m_status == Ready; } }; -#define LV2_LOCK std::unique_lock lv2_lock(Emu.GetCoreMutex()) +using lv2_lock_type = std::unique_lock; + +#define LV2_LOCK lv2_lock_type lv2_lock(Emu.GetCoreMutex()) +#define CHECK_LV2_LOCK(x) assert((x).owns_lock() && (x).mutex() == &Emu.GetCoreMutex()) extern Emulator Emu; diff --git a/rpcs3/Gui/AutoPauseManager.cpp b/rpcs3/Gui/AutoPauseManager.cpp index 11dbc5e9d9..732b57f4f1 100644 --- a/rpcs3/Gui/AutoPauseManager.cpp +++ b/rpcs3/Gui/AutoPauseManager.cpp @@ -4,7 +4,7 @@ #include #include #include "Utilities/Log.h" -#include "Utilities/rFile.h" +#include "Utilities/File.h" enum { @@ -71,24 +71,23 @@ void AutoPauseManagerDialog::LoadEntries(void) m_entries.clear(); m_entries.reserve(16); - if (rExists("pause.bin")) + fs::file list("pause.bin"); + + if (list) { - rFile list; - list.Open("pause.bin", rFile::read); //System calls ID and Function calls ID are all u32 iirc. u32 num; - size_t fmax = list.Length(); + size_t fmax = list.size(); size_t fcur = 0; - list.Seek(0); + list.seek(0); while (fcur <= fmax - sizeof(u32)) { - list.Read(&num, sizeof(u32)); + list.read(&num, sizeof(u32)); fcur += sizeof(u32); if (num == 0xFFFFFFFF) break; m_entries.emplace_back(num); } - list.Close(); } } @@ -97,24 +96,18 @@ void AutoPauseManagerDialog::LoadEntries(void) //This would always use a 0xFFFFFFFF as end of the pause.bin void AutoPauseManagerDialog::SaveEntries(void) { - if (rExists("pause.bin")) - { - rRemoveFile("pause.bin"); - } - rFile list; - list.Open("pause.bin", rFile::write); + fs::file list("pause.bin", o_write | o_create | o_trunc); //System calls ID and Function calls ID are all u32 iirc. u32 num = 0; - list.Seek(0); + list.seek(0); for (size_t i = 0; i < m_entries.size(); ++i) { if (num == 0xFFFFFFFF) continue; num = m_entries[i]; - list.Write(&num, sizeof(u32)); + list.write(&num, sizeof(u32)); } num = 0xFFFFFFFF; - list.Write(&num, sizeof(u32)); - list.Close(); + list.write(&num, sizeof(u32)); } void AutoPauseManagerDialog::UpdateList(void) diff --git a/rpcs3/Gui/AutoPauseManager.h b/rpcs3/Gui/AutoPauseManager.h index c3b207b237..1579eeba67 100644 --- a/rpcs3/Gui/AutoPauseManager.h +++ b/rpcs3/Gui/AutoPauseManager.h @@ -1,4 +1,5 @@ #pragma once +#include class AutoPauseManagerDialog : public wxDialog { @@ -37,4 +38,4 @@ public: AutoPauseSettingsDialog(wxWindow* parent, u32 *entry); void OnOk(wxCommandEvent& event); void OnUpdateValue(wxCommandEvent& event); -}; \ No newline at end of file +}; diff --git a/rpcs3/Gui/GameViewer.cpp b/rpcs3/Gui/GameViewer.cpp index 6a2d9a8fe0..f2527a1d35 100644 --- a/rpcs3/Gui/GameViewer.cpp +++ b/rpcs3/Gui/GameViewer.cpp @@ -1,7 +1,7 @@ #include "stdafx_gui.h" #include "Utilities/AutoPause.h" #include "Utilities/Log.h" -#include "Utilities/rFile.h" +//#include "Utilities/File.h" #include "Emu/Memory/Memory.h" #include "Emu/System.h" #include "Emu/FS/VFS.h" @@ -130,23 +130,27 @@ void GameViewer::LoadPSF() m_game_data.clear(); for(uint i=0; iAddRoot(fmt::Format("Process, ID = 0x00000001, Total Memory Usage = 0x%x (%0.2f MB)", total_memory_usage, (float)total_memory_usage / (1024 * 1024))); + union name64 + { + u64 u64_data; + char string[8]; + + name64(u64 data) + : u64_data(data & 0x00ffffffffffffffull) + { + } + + const char* operator &() const + { + return string; + } + }; + // TODO: FileSystem // Semaphores @@ -59,10 +82,10 @@ void KernelExplorer::Update() { sprintf(name, "Semaphores (%d)", count); const auto& node = m_tree->AppendItem(root, name); - for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_SEMAPHORE)) + for (const auto id : Emu.GetIdManager().GetTypeIDs(TYPE_SEMAPHORE)) { - auto sem = Emu.GetSyncPrimManager().GetSemaphoreData(id); - sprintf(name, "Semaphore: ID = 0x%08x '%s', Count = %d, Max Count = %d", id, sem.name.c_str(), sem.count, sem.max_count); + const auto sem = Emu.GetIdManager().GetIDData(id); + sprintf(name, "Semaphore: ID = 0x%x '%s', Count = %d, Max Count = %d, Waiters = %d", id, &name64(sem->name), sem->value.load(), sem->max, sem->waiters.load()); m_tree->AppendItem(node, name); } } @@ -73,9 +96,10 @@ void KernelExplorer::Update() { sprintf(name, "Mutexes (%d)", count); const auto& node = m_tree->AppendItem(root, name); - for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_MUTEX)) + for (const auto id : Emu.GetIdManager().GetTypeIDs(TYPE_MUTEX)) { - sprintf(name, "Mutex: ID = 0x%08x '%s'", id, Emu.GetSyncPrimManager().GetSyncPrimName(id, TYPE_MUTEX).c_str()); + const auto mutex = Emu.GetIdManager().GetIDData(id); + sprintf(name, "Mutex: ID = 0x%x '%s'", id, &name64(mutex->name)); m_tree->AppendItem(node, name); } } @@ -84,12 +108,12 @@ void KernelExplorer::Update() count = Emu.GetIdManager().GetTypeCount(TYPE_LWMUTEX); if (count) { - sprintf(name, "Light Weight Mutexes (%d)", count); + sprintf(name, "Lightweight Mutexes (%d)", count); const auto& node = m_tree->AppendItem(root, name); - for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_LWMUTEX)) + for (const auto id : Emu.GetIdManager().GetTypeIDs(TYPE_LWMUTEX)) { - auto lwm = Emu.GetSyncPrimManager().GetLwMutexData(id); - sprintf(name, "LW Mutex: ID = 0x%08x '%s'", id, lwm.name.c_str()); + const auto lwm = Emu.GetIdManager().GetIDData(id); + sprintf(name, "Lightweight Mutex: ID = 0x%x '%s'", id, &name64(lwm->name)); m_tree->AppendItem(node, name); } } @@ -100,9 +124,10 @@ void KernelExplorer::Update() { sprintf(name, "Condition Variables (%d)", count); const auto& node = m_tree->AppendItem(root, name); - for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_COND)) + for (const auto id : Emu.GetIdManager().GetTypeIDs(TYPE_COND)) { - sprintf(name, "Condition Variable: ID = 0x%08x '%s'", id, Emu.GetSyncPrimManager().GetSyncPrimName(id, TYPE_COND).c_str()); + const auto cond = Emu.GetIdManager().GetIDData(id); + sprintf(name, "Condition Variable: ID = 0x%x '%s'", id, &name64(cond->name)); m_tree->AppendItem(node, name); } } @@ -111,11 +136,12 @@ void KernelExplorer::Update() count = Emu.GetIdManager().GetTypeCount(TYPE_LWCOND); if (count) { - sprintf(name, "Light Weight Condition Variables (%d)", count); + sprintf(name, "Lightweight Condition Variables (%d)", count); const auto& node = m_tree->AppendItem(root, name); - for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_LWCOND)) + for (const auto id : Emu.GetIdManager().GetTypeIDs(TYPE_LWCOND)) { - sprintf(name, "LW Condition Variable: ID = 0x%08x '%s'", id, Emu.GetSyncPrimManager().GetSyncPrimName(id, TYPE_LWCOND).c_str()); + const auto lwc = Emu.GetIdManager().GetIDData(id); + sprintf(name, "Lightweight Condition Variable: ID = 0x%x '%s'", id, &name64(lwc->name)); m_tree->AppendItem(node, name); } } @@ -126,9 +152,24 @@ void KernelExplorer::Update() { sprintf(name, "Event Queues (%d)", count); const auto& node = m_tree->AppendItem(root, name); - for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_EVENT_QUEUE)) + for (const auto id : Emu.GetIdManager().GetTypeIDs(TYPE_EVENT_QUEUE)) { - sprintf(name, "Event Queue: ID = 0x%08x", id); + const auto queue = Emu.GetIdManager().GetIDData(id); + sprintf(name, "Event Queue: ID = 0x%x '%s', Key = %#llx", id, &name64(queue->name), queue->key); + m_tree->AppendItem(node, name); + } + } + + // Event Ports + count = Emu.GetIdManager().GetTypeCount(TYPE_EVENT_PORT); + if (count) + { + sprintf(name, "Event Ports (%d)", count); + const auto& node = m_tree->AppendItem(root, name); + for (const auto id : Emu.GetIdManager().GetTypeIDs(TYPE_EVENT_PORT)) + { + const auto port = Emu.GetIdManager().GetIDData(id); + sprintf(name, "Event Port: ID = 0x%x, Name = %#llx", id, port->name); m_tree->AppendItem(node, name); } } @@ -143,7 +184,7 @@ void KernelExplorer::Update() //m_tree->AppendItem(node, name); for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_PRX)) { - sprintf(name, "PRX: ID = 0x%08x", id); + sprintf(name, "PRX: ID = 0x%x", id); m_tree->AppendItem(node, name); } } @@ -156,7 +197,7 @@ void KernelExplorer::Update() const auto& node = m_tree->AppendItem(root, name); for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_MEM)) { - sprintf(name, "Memory Container: ID = 0x%08x", id); + sprintf(name, "Memory Container: ID = 0x%x", id); m_tree->AppendItem(node, name); } } @@ -169,7 +210,7 @@ void KernelExplorer::Update() const auto& node = m_tree->AppendItem(root, name); for (const auto& id : Emu.GetIdManager().GetTypeIDs(TYPE_EVENT_FLAG)) { - sprintf(name, "Event Flag: ID = 0x%08x", id); + sprintf(name, "Event Flag: ID = 0x%x", id); m_tree->AppendItem(node, name); } } diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index ae4ae0556a..924647c1c8 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -122,9 +122,9 @@ MainFrame::MainFrame() SetMenuBar(menubar); // Panels + m_log_frame = new LogFrame(this); m_game_viewer = new GameViewer(this); m_debugger_frame = new DebuggerPanel(this); - m_log_frame = new LogFrame(this); AddPane(m_game_viewer, "Game List", wxAUI_DOCK_CENTRE); AddPane(m_log_frame, "Log", wxAUI_DOCK_BOTTOM); @@ -235,8 +235,7 @@ void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event)) stopped = true; } - wxFileDialog ctrl (this, L"Select PKG", wxEmptyString, wxEmptyString, "PKG files (*.pkg)|*.pkg|All files (*.*)|*.*", - wxFD_OPEN | wxFD_FILE_MUST_EXIST); + wxFileDialog ctrl(this, L"Select PKG", wxEmptyString, wxEmptyString, "PKG files (*.pkg)|*.pkg|All files (*.*)|*.*", wxFD_OPEN | wxFD_FILE_MUST_EXIST); if(ctrl.ShowModal() == wxID_CANCEL) { @@ -247,14 +246,11 @@ void MainFrame::InstallPkg(wxCommandEvent& WXUNUSED(event)) Emu.Stop(); // Open and install PKG file - std::string filePath = ctrl.GetPath().ToStdString(); - rFile pkg_f(filePath, rFile::read); // TODO: Use VFS to install PKG files + fs::file pkg_f(ctrl.GetPath().ToStdString(), o_read); - if (pkg_f.IsOpened()) + if (pkg_f) { - PKGLoader pkg(pkg_f); - pkg.Install("/dev_hdd0/game/"); - pkg.Close(); + PKGLoader::Install(pkg_f, "/dev_hdd0/game/"); // Refresh game list m_game_viewer->Refresh(); diff --git a/rpcs3/Gui/MsgDialog.cpp b/rpcs3/Gui/MsgDialog.cpp index e45519f40d..6a713908d8 100644 --- a/rpcs3/Gui/MsgDialog.cpp +++ b/rpcs3/Gui/MsgDialog.cpp @@ -1,37 +1,31 @@ #include "stdafx_gui.h" +#include "rpcs3.h" #include "Emu/Memory/Memory.h" #include "Emu/SysCalls/lv2/sys_time.h" -#include "Emu/SysCalls/Modules/cellMsgDialog.h" #include "MsgDialog.h" -wxDialog* m_dialog = nullptr; -wxGauge* m_gauge1 = nullptr; -wxGauge* m_gauge2 = nullptr; -wxStaticText* m_text1 = nullptr; -wxStaticText* m_text2 = nullptr; - -void MsgDialogCreate(u32 type, const char* msg, u64& status) +void MsgDialogFrame::Create(u32 type, std::string msg) { - wxWindow* parent = nullptr; // TODO: align it better + wxWindow* parent = nullptr; // TODO: align the window better m_gauge1 = nullptr; m_gauge2 = nullptr; m_text1 = nullptr; m_text2 = nullptr; - wxButton* m_button_ok = nullptr; - wxButton* m_button_yes = nullptr; - wxButton* m_button_no = nullptr; + m_button_ok = nullptr; + m_button_yes = nullptr; + m_button_no = nullptr; m_dialog = new wxDialog(parent, wxID_ANY, type & CELL_MSGDIALOG_TYPE_SE_TYPE ? "" : "Error", wxDefaultPosition, wxDefaultSize); m_dialog->SetExtraStyle(m_dialog->GetExtraStyle() | wxWS_EX_TRANSIENT); m_dialog->SetTransparent(127 + (type & CELL_MSGDIALOG_TYPE_BG) * (128 / CELL_MSGDIALOG_TYPE_BG_INVISIBLE)); - wxSizer* sizer1 = new wxBoxSizer(wxVERTICAL); + m_sizer1 = new wxBoxSizer(wxVERTICAL); - wxStaticText* m_text = new wxStaticText(m_dialog, wxID_ANY, wxString(msg, wxConvUTF8)); - sizer1->Add(m_text, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16); + m_text = new wxStaticText(m_dialog, wxID_ANY, wxString(msg.c_str(), wxConvUTF8)); + m_sizer1->Add(m_text, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16); switch (type & CELL_MSGDIALOG_TYPE_PROGRESSBAR) { @@ -49,26 +43,27 @@ void MsgDialogCreate(u32 type, const char* msg, u64& status) if (m_gauge1) { - sizer1->Add(m_text1, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 8); - sizer1->Add(m_gauge1, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT, 16); + m_sizer1->Add(m_text1, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 8); + m_sizer1->Add(m_gauge1, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT, 16); m_gauge1->SetValue(0); } + if (m_gauge2) { - sizer1->Add(m_text2, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 8); - sizer1->Add(m_gauge2, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT, 16); + m_sizer1->Add(m_text2, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 8); + m_sizer1->Add(m_gauge2, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT, 16); m_gauge2->SetValue(0); } - wxBoxSizer* buttons = new wxBoxSizer(wxHORIZONTAL); + m_buttons = new wxBoxSizer(wxHORIZONTAL); - switch (type & CELL_MSGDIALOG_TYPE_BUTTON_TYPE) + if (type & CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO) { - case CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO: m_button_yes = new wxButton(m_dialog, wxID_YES); - buttons->Add(m_button_yes, 0, wxALIGN_CENTER_HORIZONTAL | wxRIGHT, 8); + m_buttons->Add(m_button_yes, 0, wxALIGN_CENTER_HORIZONTAL | wxRIGHT, 8); m_button_no = new wxButton(m_dialog, wxID_NO); - buttons->Add(m_button_no, 0, wxALIGN_CENTER_HORIZONTAL, 16); + m_buttons->Add(m_button_no, 0, wxALIGN_CENTER_HORIZONTAL, 16); + if ((type & CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR) == CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_NO) { m_button_no->SetFocus(); @@ -78,36 +73,36 @@ void MsgDialogCreate(u32 type, const char* msg, u64& status) m_button_yes->SetFocus(); } - sizer1->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16); - break; + m_sizer1->Add(m_buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16); + } - case CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK: + if (type & CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK) + { m_button_ok = new wxButton(m_dialog, wxID_OK); - buttons->Add(m_button_ok, 0, wxALIGN_CENTER_HORIZONTAL, 16); + m_buttons->Add(m_button_ok, 0, wxALIGN_CENTER_HORIZONTAL, 16); + if ((type & CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR) == CELL_MSGDIALOG_TYPE_DEFAULT_CURSOR_OK) { m_button_ok->SetFocus(); } - sizer1->Add(buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16); - break; + m_sizer1->Add(m_buttons, 0, wxALIGN_CENTER_HORIZONTAL | wxLEFT | wxRIGHT | wxTOP, 16); } - sizer1->AddSpacer(16); + m_sizer1->AddSpacer(16); - m_dialog->SetSizerAndFit(sizer1); + m_dialog->SetSizerAndFit(m_sizer1); m_dialog->Centre(wxBOTH); m_dialog->Show(); m_dialog->Enable(); m_dialog->Bind(wxEVT_BUTTON, [&](wxCommandEvent& event) { - status = (event.GetId() == wxID_NO) ? CELL_MSGDIALOG_BUTTON_NO : CELL_MSGDIALOG_BUTTON_YES /* OK */; - m_dialog->Hide(); - MsgDialogClose(); + this->status = (event.GetId() == wxID_NO) ? CELL_MSGDIALOG_BUTTON_NO : CELL_MSGDIALOG_BUTTON_YES /* OK */; + this->m_dialog->Hide(); + this->Close(); }); - m_dialog->Bind(wxEVT_CLOSE_WINDOW, [&](wxCloseEvent& event) { if (type & CELL_MSGDIALOG_TYPE_DISABLE_CANCEL) @@ -115,44 +110,53 @@ void MsgDialogCreate(u32 type, const char* msg, u64& status) } else { - status = CELL_MSGDIALOG_BUTTON_ESCAPE; - m_dialog->Hide(); - MsgDialogClose(); + this->status = CELL_MSGDIALOG_BUTTON_ESCAPE; + this->m_dialog->Hide(); + this->Close(); } }); } -void MsgDialogDestroy() +void MsgDialogFrame::Destroy() { delete m_dialog; m_dialog = nullptr; } -void MsgDialogProgressBarSetMsg(u32 index, const char* msg) +void MsgDialogFrame::ProgressBarSetMsg(u32 index, std::string msg) { - if (m_dialog) + wxGetApp().CallAfter([=]() { - if (index == 0 && m_text1) m_text1->SetLabelText(wxString(msg, wxConvUTF8)); - if (index == 1 && m_text2) m_text2->SetLabelText(wxString(msg, wxConvUTF8)); - m_dialog->Layout(); - m_dialog->Fit(); - } + if (m_dialog) + { + if (index == 0 && m_text1) m_text1->SetLabelText(wxString(msg.c_str(), wxConvUTF8)); + if (index == 1 && m_text2) m_text2->SetLabelText(wxString(msg.c_str(), wxConvUTF8)); + m_dialog->Layout(); + m_dialog->Fit(); + } + }); } -void MsgDialogProgressBarReset(u32 index) +void MsgDialogFrame::ProgressBarReset(u32 index) { - if (m_dialog) + wxGetApp().CallAfter([=]() { - if (index == 0 && m_gauge1) m_gauge1->SetValue(0); - if (index == 1 && m_gauge2) m_gauge2->SetValue(0); - } + if (m_dialog) + { + if (index == 0 && m_gauge1) m_gauge1->SetValue(0); + if (index == 1 && m_gauge2) m_gauge2->SetValue(0); + } + }); } -void MsgDialogProgressBarInc(u32 index, u32 delta) +void MsgDialogFrame::ProgressBarInc(u32 index, u32 delta) { - if (m_dialog) + wxGetApp().CallAfter([=]() { - if (index == 0 && m_gauge1) m_gauge1->SetValue(m_gauge1->GetValue() + delta); - if (index == 1 && m_gauge2) m_gauge2->SetValue(m_gauge2->GetValue() + delta); - } + if (m_dialog) + { + if (index == 0 && m_gauge1) m_gauge1->SetValue(m_gauge1->GetValue() + delta); + if (index == 1 && m_gauge2) m_gauge2->SetValue(m_gauge2->GetValue() + delta); + } + }); } diff --git a/rpcs3/Gui/MsgDialog.h b/rpcs3/Gui/MsgDialog.h index 2f669b9736..413e4efe4e 100644 --- a/rpcs3/Gui/MsgDialog.h +++ b/rpcs3/Gui/MsgDialog.h @@ -1,7 +1,25 @@ #pragma once -void MsgDialogCreate(u32 type, const char* msg, u64& status); -void MsgDialogDestroy(); -void MsgDialogProgressBarSetMsg(u32 index, const char* msg); -void MsgDialogProgressBarReset(u32 index); -void MsgDialogProgressBarInc(u32 index, u32 delta); +#include "Emu/SysCalls/Modules/cellMsgDialog.h" + +class MsgDialogFrame : public MsgDialogInstance +{ + wxDialog* m_dialog; + wxGauge* m_gauge1; + wxGauge* m_gauge2; + wxStaticText* m_text1; + wxStaticText* m_text2; + wxButton* m_button_ok; + wxButton* m_button_yes; + wxButton* m_button_no; + wxStaticText* m_text; + wxSizer* m_sizer1; + wxSizer* m_buttons; + +public: + virtual void Create(u32 type, std::string msg) override; + virtual void Destroy() override; + virtual void ProgressBarSetMsg(u32 progressBarIndex, std::string msg) override; + virtual void ProgressBarReset(u32 progressBarIndex) override; + virtual void ProgressBarInc(u32 progressBarIndex, u32 delta) override; +}; diff --git a/rpcs3/Gui/SaveDataDialog.cpp b/rpcs3/Gui/SaveDataDialog.cpp new file mode 100644 index 0000000000..36749a61db --- /dev/null +++ b/rpcs3/Gui/SaveDataDialog.cpp @@ -0,0 +1,9 @@ +#include "stdafx_gui.h" +#include "Emu/Memory/Memory.h" + +#include "SaveDataDialog.h" + +s32 SaveDataDialogFrame::ShowSaveDataList(std::vector& save_entries, s32 focused, vm::ptr listSet) +{ + return focused; +} diff --git a/rpcs3/Gui/SaveDataDialog.h b/rpcs3/Gui/SaveDataDialog.h new file mode 100644 index 0000000000..9a0650e1ed --- /dev/null +++ b/rpcs3/Gui/SaveDataDialog.h @@ -0,0 +1,8 @@ +#pragma once +#include "Emu/SysCalls/Modules/cellSaveData.h" + +class SaveDataDialogFrame : public SaveDataDialogInstance +{ +public: + virtual s32 ShowSaveDataList(std::vector& save_entries, s32 focused, vm::ptr listSet) override; +}; diff --git a/rpcs3/Gui/SaveDataUtility.cpp b/rpcs3/Gui/SaveDataUtility.cpp index 534188d076..517f03642a 100644 --- a/rpcs3/Gui/SaveDataUtility.cpp +++ b/rpcs3/Gui/SaveDataUtility.cpp @@ -3,7 +3,7 @@ #include #include #include "Utilities/Log.h" -#include "Utilities/rFile.h" +//#include "Utilities/File.h" //Cause i can not decide what struct to be used to fill those. Just use no real data now. //Currently variable info isn't used. it supposed to be a container for the information passed by other. diff --git a/rpcs3/Gui/SaveDataUtility.h b/rpcs3/Gui/SaveDataUtility.h index 38a9bbbd1b..a96fdd4aeb 100644 --- a/rpcs3/Gui/SaveDataUtility.h +++ b/rpcs3/Gui/SaveDataUtility.h @@ -1,4 +1,5 @@ #pragma once +#include //TODO: Implement function calls related to Save Data List. //Those function calls may be needed to use this GUI. diff --git a/rpcs3/Gui/VHDDManager.cpp b/rpcs3/Gui/VHDDManager.cpp index aa818aa7a8..4792d44647 100644 --- a/rpcs3/Gui/VHDDManager.cpp +++ b/rpcs3/Gui/VHDDManager.cpp @@ -122,7 +122,7 @@ void VHDDExplorer::Import(const std::string& path, const std::string& to) return; } - if(!m_hdd->Open(to, vfsWrite)) + if(!m_hdd->Open(to, o_write)) { wxMessageBox("IMPORT ERROR: file open error."); return; diff --git a/rpcs3/Ini.cpp b/rpcs3/Ini.cpp index 609d3c2855..1b1d4d165b 100644 --- a/rpcs3/Ini.cpp +++ b/rpcs3/Ini.cpp @@ -1,6 +1,6 @@ #include "stdafx.h" #include "Utilities/rPlatform.h" -#include "Utilities/StrFmt.h" +#include "Utilities/simpleini/SimpleIni.h" #include "Ini.h" #include @@ -8,6 +8,7 @@ #define DEF_CONFIG_NAME "./rpcs3.ini" +//TODO: make thread safe/remove static singleton CSimpleIniCaseA *getIniFile() { static bool inited = false; @@ -98,7 +99,7 @@ static std::string WindowInfoToString(const WindowInfo& wind) //Ini Ini::Ini() { - m_Config = getIniFile(); + m_config = getIniFile(); } Ini::~Ini() @@ -109,55 +110,55 @@ Ini::~Ini() //TODO: saving the file after each change seems like overkill but that's how wx did it void Ini::Save(const std::string& section, const std::string& key, int value) { - m_Config->SetLongValue(section.c_str(), key.c_str(), value); + static_cast(m_config)->SetLongValue(section.c_str(), key.c_str(), value); saveIniFile(); } void Ini::Save(const std::string& section, const std::string& key, bool value) { - m_Config->SetBoolValue(section.c_str(), key.c_str(), value); + static_cast(m_config)->SetBoolValue(section.c_str(), key.c_str(), value); saveIniFile(); } void Ini::Save(const std::string& section, const std::string& key, std::pair value) { - m_Config->SetValue(section.c_str(), key.c_str(), SizeToString(value).c_str()); + static_cast(m_config)->SetValue(section.c_str(), key.c_str(), SizeToString(value).c_str()); saveIniFile(); } void Ini::Save(const std::string& section, const std::string& key, const std::string& value) { - m_Config->SetValue(section.c_str(), key.c_str(), value.c_str()); + static_cast(m_config)->SetValue(section.c_str(), key.c_str(), value.c_str()); saveIniFile(); } void Ini::Save(const std::string& section, const std::string& key, WindowInfo value) { - m_Config->SetValue(section.c_str(), key.c_str(), WindowInfoToString(value).c_str()); + static_cast(m_config)->SetValue(section.c_str(), key.c_str(), WindowInfoToString(value).c_str()); saveIniFile(); } int Ini::Load(const std::string& section, const std::string& key, const int def_value) { - return m_Config->GetLongValue(section.c_str(), key.c_str(), def_value); + return static_cast(m_config)->GetLongValue(section.c_str(), key.c_str(), def_value); } bool Ini::Load(const std::string& section, const std::string& key, const bool def_value) { - return StringToBool(m_Config->GetValue(section.c_str(), key.c_str(), BoolToString(def_value).c_str())); + return StringToBool(static_cast(m_config)->GetValue(section.c_str(), key.c_str(), BoolToString(def_value).c_str())); } std::pair Ini::Load(const std::string& section, const std::string& key, const std::pair def_value) { - return StringToSize(m_Config->GetValue(section.c_str(), key.c_str(), SizeToString(def_value).c_str())); + return StringToSize(static_cast(m_config)->GetValue(section.c_str(), key.c_str(), SizeToString(def_value).c_str())); } std::string Ini::Load(const std::string& section, const std::string& key, const std::string& def_value) { - return std::string(m_Config->GetValue(section.c_str(), key.c_str(), def_value.c_str())); + return std::string(static_cast(m_config)->GetValue(section.c_str(), key.c_str(), def_value.c_str())); } WindowInfo Ini::Load(const std::string& section, const std::string& key, const WindowInfo& def_value) { - return StringToWindowInfo(m_Config->GetValue(section.c_str(), key.c_str(), WindowInfoToString(def_value).c_str())); + return StringToWindowInfo(static_cast(m_config)->GetValue(section.c_str(), key.c_str(), WindowInfoToString(def_value).c_str())); } diff --git a/rpcs3/Ini.h b/rpcs3/Ini.h index 5f1155489d..19383577e5 100644 --- a/rpcs3/Ini.h +++ b/rpcs3/Ini.h @@ -1,11 +1,5 @@ #pragma once -#include -#include "Utilities/simpleini/SimpleIni.h" - -//TODO: make thread safe/remove static singleton -CSimpleIniCaseA *getIniFile(); - //TODO: move this to the gui module struct WindowInfo { @@ -26,7 +20,7 @@ public: virtual ~Ini(); protected: - CSimpleIniCaseA *m_Config; + void* m_config; Ini(); diff --git a/rpcs3/Loader/ELF32.cpp b/rpcs3/Loader/ELF32.cpp index a6885f93ce..6ef662b641 100644 --- a/rpcs3/Loader/ELF32.cpp +++ b/rpcs3/Loader/ELF32.cpp @@ -1,7 +1,6 @@ #include "stdafx.h" #include "Ini.h" #include "Utilities/Log.h" -#include "Utilities/rFile.h" #include "Emu/FS/vfsStream.h" #include "Emu/Memory/Memory.h" #include "ELF32.h" @@ -144,7 +143,7 @@ namespace loader u32 vnid_addr = 0; std::unordered_map vnid_list; - auto proc_param = vm::psv::ptr::make(0); + vm::psv::ptr proc_param = vm::null; for (auto& shdr : m_shdrs) { @@ -153,11 +152,9 @@ namespace loader m_stream->Seek(handler::get_stream_offset() + m_shdrs[m_ehdr.data_le.e_shstrndx].data_le.sh_offset + shdr.data_le.sh_name); std::string name; - while (!m_stream->Eof()) + char c; + while (m_stream->SRead(c) && c) { - char c; - m_stream->Read(&c, 1); - if (c == 0) break; name.push_back(c); } diff --git a/rpcs3/Loader/ELF32.h b/rpcs3/Loader/ELF32.h index 6a13b6f7cb..76cc910ec2 100644 --- a/rpcs3/Loader/ELF32.h +++ b/rpcs3/Loader/ELF32.h @@ -2,7 +2,6 @@ #include "Loader.h" struct vfsStream; -class rFile; namespace loader { diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index 56999154e1..30fbd4d5ba 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -1,6 +1,5 @@ #include "stdafx.h" #include "Utilities/Log.h" -#include "Utilities/rFile.h" #include "Emu/FS/vfsStream.h" #include "Emu/FS/vfsFile.h" #include "Emu/FS/vfsDir.h" diff --git a/rpcs3/Loader/ELF64.h b/rpcs3/Loader/ELF64.h index 85416d5def..baa634eb95 100644 --- a/rpcs3/Loader/ELF64.h +++ b/rpcs3/Loader/ELF64.h @@ -2,7 +2,6 @@ #include "Loader.h" struct vfsStream; -class rFile; namespace loader { diff --git a/rpcs3/Loader/Loader.h b/rpcs3/Loader/Loader.h index 9ff96b0dc5..0cafa3554a 100644 --- a/rpcs3/Loader/Loader.h +++ b/rpcs3/Loader/Loader.h @@ -3,7 +3,6 @@ struct vfsFileBase; struct vfsStream; -class rFile; #ifdef _DEBUG //#define LOADER_DEBUG diff --git a/rpcs3/Loader/PKG.cpp b/rpcs3/Loader/PKG.cpp index 022a11085e..e484e2afa0 100644 --- a/rpcs3/Loader/PKG.cpp +++ b/rpcs3/Loader/PKG.cpp @@ -1,39 +1,42 @@ #include "stdafx.h" #include "Utilities/Log.h" #include "Utilities/rMsgBox.h" -#include "Utilities/rFile.h" +#include "Utilities/File.h" #include "PKG.h" #include "../Crypto/unpkg.h" -PKGLoader::PKGLoader(rFile& f) : pkg_f(f) -{ -} - -bool PKGLoader::Install(std::string dest) +bool PKGLoader::Install(const fs::file& pkg_f, std::string dest) { // Initial checks - if (!pkg_f.IsOpened()) + if (!pkg_f) + { return false; + } // TODO: This shouldn't use current dir dest.insert(0, 1, '.'); if (!dest.empty() && dest.back() != '/') + { dest += '/'; + } // Fetch title ID from the header. char title_id[48]; - pkg_f.Seek(48); - pkg_f.Read(title_id, 48); + pkg_f.seek(48); + pkg_f.read(title_id, 48); std::string titleID = std::string(title_id).substr(7, 9); - if (rExists(dest + titleID)) { - rMessageDialog d_overwrite(NULL, "Another installation found. Do you want to overwrite it?", "PKG Decrypter / Installer", rYES_NO|rCENTRE); - if (d_overwrite.ShowModal() != rID_YES) { + if (fs::is_dir(dest + titleID)) + { + if (rMessageDialog(NULL, "Another installation found. Do you want to overwrite it?", "PKG Decrypter / Installer", rYES_NO | rCENTRE).ShowModal() != rID_YES) + { LOG_ERROR(LOADER, "PKG Loader: Another installation found in: %s", titleID.c_str()); return false; } - } else if (!rMkdir(dest + titleID)) { + } + else if (!fs::create_dir(dest + titleID)) + { LOG_ERROR(LOADER, "PKG Loader: Could not create the installation directory: %s", titleID.c_str()); return false; } @@ -50,8 +53,3 @@ bool PKGLoader::Install(std::string dest) return true; } } - -bool PKGLoader::Close() -{ - return pkg_f.Close(); -} diff --git a/rpcs3/Loader/PKG.h b/rpcs3/Loader/PKG.h index 3c18619d11..1a51c71199 100644 --- a/rpcs3/Loader/PKG.h +++ b/rpcs3/Loader/PKG.h @@ -1,13 +1,8 @@ #pragma once -class rFile; +namespace fs { struct file; } -class PKGLoader +struct PKGLoader { - rFile& pkg_f; - -public: - PKGLoader(rFile& f); - virtual bool Install(std::string dest); - virtual bool Close(); + static bool Install(const fs::file& pkg_f, std::string dest); }; diff --git a/rpcs3/Loader/PSF.cpp b/rpcs3/Loader/PSF.cpp index 6bf66f4378..e6d78fdcae 100644 --- a/rpcs3/Loader/PSF.cpp +++ b/rpcs3/Loader/PSF.cpp @@ -3,111 +3,285 @@ #include "Emu/FS/vfsStream.h" #include "PSF.h" -PSFLoader::PSFLoader(vfsStream& f) : psf_f(f) +bool PSFLoader::Load(vfsStream& stream) { -} + PSFHeader header; -PSFEntry* PSFLoader::SearchEntry(const std::string& key) -{ - for(auto& entry : m_entries) + // load header + if (!stream.SRead(header)) { - if(entry.name == key) - return &entry; + return false; } - return nullptr; -} - -bool PSFLoader::Load(bool show) -{ - if(!psf_f.IsOpened()) return false; - - m_show_log = show; - - if(!LoadHeader()) return false; - if(!LoadKeyTable()) return false; - if(!LoadDataTable()) return false; - - return true; -} - -bool PSFLoader::Close() -{ - return psf_f.Close(); -} - -bool PSFLoader::LoadHeader() -{ - if(psf_f.Read(&m_header, sizeof(PSFHeader)) != sizeof(PSFHeader)) - return false; - - if(!m_header.CheckMagic()) - return false; - - if(m_show_log) LOG_NOTICE(LOADER, "PSF version: 0x%x", m_header.psf_version); - - m_psfindxs.clear(); - m_entries.clear(); - m_psfindxs.resize(m_header.psf_entries_num); - m_entries.resize(m_header.psf_entries_num); - - for(u32 i=0; i indices; - while(!psf_f.Eof()) + indices.resize(header.entries_num); + + if (!stream.SRead(indices[0], sizeof(PSFDefTable) * header.entries_num)) + { + return false; + } + + // load key table + if (header.off_key_table > header.off_data_table) + { + LOG_ERROR(LOADER, "PSFLoader::Load() failed: off_key_table=0x%x, off_data_table=0x%x", header.off_key_table, header.off_data_table); + return false; + } + + const u32 key_table_size = header.off_data_table - header.off_key_table; + + std::unique_ptr keys(new char[key_table_size + 1]); + + stream.Seek(header.off_key_table); + + if (stream.Read(keys.get(), key_table_size) != key_table_size) + { + return false; + } + + keys.get()[key_table_size] = 0; + + // load entries + std::vector entries; + + entries.resize(header.entries_num); + + for (u32 i = 0; i < header.entries_num; ++i) + { + entries[i].fmt = indices[i].param_fmt; + + if (indices[i].key_off >= key_table_size) { - char c; - psf_f.Read(&c, 1); - m_entries[i].name[c_pos++] = c; + return false; + } - if(c_pos >= sizeof(m_entries[i].name) || c == '\0') + entries[i].name = keys.get() + indices[i].key_off; + + // load data + stream.Seek(header.off_data_table + indices[i].data_off); + + if (indices[i].param_fmt == PSF_PARAM_INT && indices[i].param_len == 4 && indices[i].param_max == 4) + { + // load int data + + if (!stream.SRead(entries[i].vint)) + { + return false; + } + } + else if (indices[i].param_fmt == PSF_PARAM_STR && indices[i].param_max >= indices[i].param_len) + { + // load str data + + const u32 size = indices[i].param_len; + + std::unique_ptr str(new char[size + 1]); + + if (stream.Read(str.get(), size) != size) + { + return false; + } + + str.get()[size] = 0; + + entries[i].vstr = str.get(); + } + else + { + LOG_ERROR(LOADER, "PSFLoader::Load() failed: (i=%d) fmt=0x%x, len=0x%x, max=0x%x", i, indices[i].param_fmt, indices[i].param_len, indices[i].param_max); + return false; + } + } + + // reset data + m_entries = std::move(entries); + + return true; +} + +bool PSFLoader::Save(vfsStream& stream) const +{ + std::vector indices; + + indices.resize(m_entries.size()); + + // generate header + PSFHeader header; + header.magic = *(u32*)"\0PSF"; + header.version = 0x101; + header.entries_num = static_cast(m_entries.size()); + header.off_key_table = sizeof(PSFHeader) + sizeof(PSFDefTable) * header.entries_num; + + { + // calculate key table length and generate indices + + u32& key_offset = header.off_data_table = 0; + u32 data_offset = 0; + + for (u32 i = 0; i < m_entries.size(); i++) + { + indices[i].key_off = key_offset; + indices[i].data_off = data_offset; + indices[i].param_fmt = m_entries[i].fmt; + + key_offset += static_cast(m_entries[i].name.size()) + 1; // key size + + switch (m_entries[i].fmt) // calculate data size + { + case PSF_PARAM_STR: + { + data_offset += (indices[i].param_len = indices[i].param_max = static_cast(m_entries[i].vstr.size()) + 1); break; + } + case PSF_PARAM_INT: + { + data_offset += (indices[i].param_len = indices[i].param_max = 4); + break; + } + default: + { + data_offset += (indices[i].param_len = indices[i].param_max = 0); + LOG_ERROR(LOADER, "PSFLoader::Save(): (i=%d) unknown entry format (0x%x, key='%s')", i, m_entries[i].fmt, m_entries[i].name); + } + } + } + } + + header.off_data_table += header.off_key_table; + + // save header + if (!stream.SWrite(header)) + { + return false; + } + + // save indices + if (!stream.SWrite(indices[0], sizeof(PSFDefTable) * m_entries.size())) + { + return false; + } + + // save key table + for (const auto& entry : m_entries) + { + if (!stream.SWrite(entry.name[0], entry.name.size() + 1)) + { + return false; + } + } + + // save data + for (const auto& entry : m_entries) + { + switch (entry.fmt) + { + case PSF_PARAM_STR: + { + if (!stream.SWrite(entry.vstr[0], entry.vstr.size() + 1)) + { + return false; + } + break; + } + case PSF_PARAM_INT: + { + if (!stream.SWrite(entry.vint)) + { + return false; + } + break; + } } } return true; } -bool PSFLoader::LoadDataTable() +void PSFLoader::Clear() { - for(u32 i=0; iFormatString(); - else - return ""; + for (auto& entry : m_entries) + { + if (key == entry.name) + { + entry.fmt = fmt; + return entry; + } + } + + PSFEntry new_entry = {}; + new_entry.fmt = fmt; + new_entry.name = key; + m_entries.push_back(new_entry); + + return m_entries.back(); } -u32 PSFLoader::GetInteger(const std::string& key) +std::string PSFLoader::GetString(const std::string& key, std::string def) const { - if(PSFEntry* entry = SearchEntry(key)) - return entry->FormatInteger(); - else - return 0; + if (const auto entry = SearchEntry(key)) + { + if (entry->fmt == PSF_PARAM_STR) + { + return entry->vstr; + } + } + + return def; +} + +s32 PSFLoader::GetInteger(const std::string& key, s32 def) const +{ + if (const auto entry = SearchEntry(key)) + { + if (entry->fmt == PSF_PARAM_INT) + { + return entry->vint; + } + } + + return def; +} + +void PSFLoader::SetString(const std::string& key, std::string value) +{ + AddEntry(key, PSF_PARAM_STR).vstr = value; +} + +void PSFLoader::SetInteger(const std::string& key, s32 value) +{ + AddEntry(key, PSF_PARAM_INT).vint = value; } diff --git a/rpcs3/Loader/PSF.h b/rpcs3/Loader/PSF.h index 8fdfa8a532..7b5532dd7f 100644 --- a/rpcs3/Loader/PSF.h +++ b/rpcs3/Loader/PSF.h @@ -1,72 +1,75 @@ #pragma once -#include "Loader.h" struct vfsStream; struct PSFHeader { - u32 psf_magic; - u32 psf_version; - u32 psf_offset_key_table; - u32 psf_offset_data_table; - u32 psf_entries_num; - - bool CheckMagic() const { return psf_magic == *(u32*)"\0PSF"; } + u32 magic; + u32 version; + u32 off_key_table; + u32 off_data_table; + u32 entries_num; }; -struct PSFDefTbl +struct PSFDefTable { - u16 psf_key_table_offset; - u16 psf_param_fmt; - u32 psf_param_len; - u32 psf_param_max_len; - u32 psf_data_tbl_offset; + u16 key_off; + u16 param_fmt; + u32 param_len; + u32 param_max; + u32 data_off; +}; + +enum : u16 +{ + PSF_PARAM_UNK = 0x0004, + PSF_PARAM_STR = 0x0204, + PSF_PARAM_INT = 0x0404, }; struct PSFEntry { - char name[128]; u16 fmt; - char param[4096]; + std::string name; - std::string FormatString() const - { - switch(fmt) - { - default: - case 0x0400: - case 0x0402: - return std::string(param); - case 0x0404: - return fmt::Format("0x%x", FormatInteger()); - } - } - - u32 FormatInteger() const - { - return *(u32*)param; - } + s32 vint; + std::string vstr; }; class PSFLoader { - vfsStream& psf_f; - - PSFHeader m_header; - std::vector m_psfindxs; std::vector m_entries; - bool m_show_log; - - bool LoadHeader(); - bool LoadKeyTable(); - bool LoadDataTable(); public: - PSFLoader(vfsStream& f); - virtual bool Load(bool show = true); - virtual bool Close(); + PSFLoader() = default; - PSFEntry* SearchEntry(const std::string& key); - std::string GetString(const std::string& key); - u32 GetInteger(const std::string& key); -}; \ No newline at end of file + PSFLoader(vfsStream& stream) + { + Load(stream); + } + + virtual ~PSFLoader() = default; + + bool Load(vfsStream& stream); + + bool Save(vfsStream& stream) const; + + void Clear(); + + operator bool() const + { + return !m_entries.empty(); + } + + const PSFEntry* SearchEntry(const std::string& key) const; + + PSFEntry& AddEntry(const std::string& key, u16 type); + + std::string GetString(const std::string& key, std::string def = "") const; + + s32 GetInteger(const std::string& key, s32 def = 0) const; + + void SetString(const std::string& key, std::string value); + + void SetInteger(const std::string& key, s32 value); +}; diff --git a/rpcs3/Loader/TROPUSR.cpp b/rpcs3/Loader/TROPUSR.cpp index 7d6b7fb655..d7ba52d755 100644 --- a/rpcs3/Loader/TROPUSR.cpp +++ b/rpcs3/Loader/TROPUSR.cpp @@ -22,7 +22,6 @@ bool TROPUSRLoader::Load(const std::string& filepath, const std::string& configp if (m_file) Close(); - // TODO: This seems to be always true... A bug in ExistsFile() ? if (!Emu.GetVFS().ExistsFile(filepath)) Generate(filepath, configpath); @@ -102,10 +101,7 @@ bool TROPUSRLoader::Save(const std::string& filepath) if (m_file) Close(); - if (!Emu.GetVFS().ExistsFile(filepath)) - Emu.GetVFS().CreateFile(filepath); - - m_file = Emu.GetVFS().OpenFile(filepath, vfsWrite); + m_file = Emu.GetVFS().OpenFile(filepath, vfsWriteNew); m_file->Write(&m_header, sizeof(TROPUSRHeader)); for (const TROPUSRTableHeader& tableHeader : m_tableHeaders) diff --git a/rpcs3/Loader/TRP.cpp b/rpcs3/Loader/TRP.cpp index 6c02e4221a..4ced4804d6 100644 --- a/rpcs3/Loader/TRP.cpp +++ b/rpcs3/Loader/TRP.cpp @@ -26,12 +26,9 @@ bool TRPLoader::Install(std::string dest, bool show) for (const TRPEntry& entry : m_entries) { char* buffer = new char [(u32)entry.size]; - Emu.GetVFS().CreateFile(dest+entry.name); - vfsFile file(dest+entry.name, vfsWrite); trp_f.Seek(entry.offset); trp_f.Read(buffer, entry.size); - file.Write(buffer, entry.size); - file.Close(); + vfsFile(dest + entry.name, vfsWriteNew).Write(buffer, entry.size); delete[] buffer; } diff --git a/rpcs3/Loader/TRP.h b/rpcs3/Loader/TRP.h index 64d491d414..006df5f18e 100644 --- a/rpcs3/Loader/TRP.h +++ b/rpcs3/Loader/TRP.h @@ -1,5 +1,4 @@ #pragma once -#include "Loader.h" struct vfsStream; @@ -41,4 +40,4 @@ public: virtual void RenameEntry(const char *oldname, const char *newname); virtual bool Close(); -}; \ No newline at end of file +}; diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index c3329dfd33..5b35d41c97 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -29,7 +29,7 @@ - + @@ -282,7 +282,6 @@ - @@ -312,7 +311,7 @@ - + @@ -522,7 +521,6 @@ - diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 6ef16d3491..facf1494db 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -599,9 +599,6 @@ Utilities - - Utilities - Utilities @@ -647,9 +644,6 @@ Emu\CPU\ARMv7\Modules - - Emu\SysCalls - Utilities @@ -866,6 +860,9 @@ Emu\CPU\Cell + + Utilities + @@ -1405,9 +1402,6 @@ Utilities - - Utilities - Utilities @@ -1447,9 +1441,6 @@ Emu\SysCalls - - Emu\SysCalls - Crypto @@ -1555,5 +1546,8 @@ Emu\CPU\Cell + + Utilities + \ No newline at end of file diff --git a/rpcs3/rpcs3.cpp b/rpcs3/rpcs3.cpp index c13b8465e1..20a5c9d01f 100644 --- a/rpcs3/rpcs3.cpp +++ b/rpcs3/rpcs3.cpp @@ -22,8 +22,8 @@ #include "Emu/Io/XInput/XInputPadHandler.h" #endif -#include "Emu/SysCalls/Modules/cellMsgDialog.h" #include "Gui/MsgDialog.h" +#include "Gui/SaveDataDialog.h" #include "Gui/GLGSFrame.h" #include @@ -41,7 +41,10 @@ wxDEFINE_EVENT(wxEVT_DBG_COMMAND, wxCommandEvent); IMPLEMENT_APP(Rpcs3App) Rpcs3App* TheApp; -std::string simplify_path(const std::string& path, bool is_dir); +extern std::string simplify_path(const std::string& path, bool is_dir); + +extern std::unique_ptr g_msg_dialog; +extern std::unique_ptr g_savedata_dialog; bool Rpcs3App::OnInit() { @@ -134,7 +137,8 @@ bool Rpcs3App::OnInit() return new GLGSFrame(); }); - SetMsgDialogCallbacks(MsgDialogCreate, MsgDialogDestroy, MsgDialogProgressBarSetMsg, MsgDialogProgressBarReset, MsgDialogProgressBarInc); + g_msg_dialog.reset(new MsgDialogFrame); + g_savedata_dialog.reset(new SaveDataDialogFrame); TheApp = this; SetAppName(_PRGNAME_); @@ -144,8 +148,6 @@ bool Rpcs3App::OnInit() const wxString executablePath = wxPathOnly(wxStandardPaths::Get().GetExecutablePath()); wxSetWorkingDirectory(executablePath); - main_thread = std::this_thread::get_id(); - Ini.Load(); Emu.Init(); Emu.SetEmulatorPath(executablePath.ToStdString()); diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 5ec09d62b6..24f977e5a7 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -183,6 +183,7 @@ + @@ -224,6 +225,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index 82eaf2b9ea..5fe6acdcb5 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -99,6 +99,9 @@ Gui + + Gui + @@ -200,8 +203,8 @@ Gui - + Gui - + \ No newline at end of file diff --git a/rpcs3/stdafx.h b/rpcs3/stdafx.h index d0acf68a9c..b6a071cf0e 100644 --- a/rpcs3/stdafx.h +++ b/rpcs3/stdafx.h @@ -31,8 +31,6 @@ #include #include #include -#include -#include #include #include #include @@ -40,7 +38,6 @@ #include #include -#include #include "Utilities/GNU.h" typedef unsigned int uint;