mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-09 16:31:28 +12:00
commit
d18d19870f
159 changed files with 5702 additions and 5951 deletions
|
@ -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;
|
||||
|
|
|
@ -879,90 +879,6 @@ template<typename T, typename T1, T1 value> struct _se<be_t<T>, T1, value> : pub
|
|||
#define se32(x) _se<u32, decltype(x), x>::value
|
||||
#define se64(x) _se<u64, decltype(x), x>::value
|
||||
|
||||
template<typename T> __forceinline u8 Read8(T& f)
|
||||
{
|
||||
u8 ret;
|
||||
f.Read(&ret, sizeof(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T> __forceinline u16 Read16(T& f)
|
||||
{
|
||||
be_t<u16> ret;
|
||||
f.Read(&ret, sizeof(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T> __forceinline u32 Read32(T& f)
|
||||
{
|
||||
be_t<u32> ret;
|
||||
f.Read(&ret, sizeof(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T> __forceinline u64 Read64(T& f)
|
||||
{
|
||||
be_t<u64> ret;
|
||||
f.Read(&ret, sizeof(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T> __forceinline u16 Read16LE(T& f)
|
||||
{
|
||||
u16 ret;
|
||||
f.Read(&ret, sizeof(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T> __forceinline u32 Read32LE(T& f)
|
||||
{
|
||||
u32 ret;
|
||||
f.Read(&ret, sizeof(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T> __forceinline u64 Read64LE(T& f)
|
||||
{
|
||||
u64 ret;
|
||||
f.Read(&ret, sizeof(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T> __forceinline void Write8(T& f, const u8 data)
|
||||
{
|
||||
f.Write(&data, sizeof(data));
|
||||
}
|
||||
|
||||
template<typename T> __forceinline void Write16LE(T& f, const u16 data)
|
||||
{
|
||||
f.Write(&data, sizeof(data));
|
||||
}
|
||||
|
||||
template<typename T> __forceinline void Write32LE(T& f, const u32 data)
|
||||
{
|
||||
f.Write(&data, sizeof(data));
|
||||
}
|
||||
|
||||
template<typename T> __forceinline void Write64LE(T& f, const u64 data)
|
||||
{
|
||||
f.Write(&data, sizeof(data));
|
||||
}
|
||||
|
||||
template<typename T> __forceinline void Write16(T& f, const u16 data)
|
||||
{
|
||||
Write16LE(f, re16(data));
|
||||
}
|
||||
|
||||
template<typename T> __forceinline void Write32(T& f, const u32 data)
|
||||
{
|
||||
Write32LE(f, re32(data));
|
||||
}
|
||||
|
||||
template<typename T> __forceinline void Write64(T& f, const u64 data)
|
||||
{
|
||||
Write64LE(f, re64(data));
|
||||
}
|
||||
|
||||
template<typename Tto, typename Tfrom>
|
||||
struct convert_le_be_t
|
||||
{
|
||||
|
|
672
Utilities/File.cpp
Normal file
672
Utilities/File.cpp
Normal file
|
@ -0,0 +1,672 @@
|
|||
#include "stdafx.h"
|
||||
#include "Log.h"
|
||||
#pragma warning(push)
|
||||
#pragma message("TODO: remove wx dependency: <wx/dir.h>")
|
||||
#pragma warning(disable : 4996)
|
||||
#include <wx/dir.h>
|
||||
#pragma warning(pop)
|
||||
#include "File.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
|
||||
#define GET_API_ERROR static_cast<u64>(GetLastError())
|
||||
|
||||
std::unique_ptr<wchar_t[]> ConvertUTF8ToWChar(const std::string& source)
|
||||
{
|
||||
const size_t length = source.size() + 1; // size + null terminator
|
||||
|
||||
const int size = source.size() < INT_MAX ? static_cast<int>(length) : throw std::length_error(__FUNCTION__);
|
||||
|
||||
std::unique_ptr<wchar_t[]> 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 <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__)
|
||||
#include <copyfile.h>
|
||||
#else
|
||||
#include <sys/sendfile.h>
|
||||
#endif
|
||||
#include "errno.h"
|
||||
|
||||
#define GET_API_ERROR static_cast<u64>(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<void*>(new wxDir());
|
||||
}
|
||||
|
||||
rDir::~rDir()
|
||||
{
|
||||
delete reinterpret_cast<wxDir*>(handle);
|
||||
}
|
||||
|
||||
rDir::rDir(const std::string &path)
|
||||
{
|
||||
handle = reinterpret_cast<void*>(new wxDir(fmt::FromUTF8(path)));
|
||||
}
|
||||
|
||||
bool rDir::Open(const std::string& path)
|
||||
{
|
||||
return reinterpret_cast<wxDir*>(handle)->Open(fmt::FromUTF8(path));
|
||||
}
|
||||
|
||||
bool rDir::IsOpened() const
|
||||
{
|
||||
return reinterpret_cast<wxDir*>(handle)->IsOpened();
|
||||
}
|
||||
|
||||
bool rDir::GetFirst(std::string *filename) const
|
||||
{
|
||||
wxString str;
|
||||
bool res;
|
||||
res = reinterpret_cast<wxDir*>(handle)->GetFirst(&str);
|
||||
*filename = str.ToStdString();
|
||||
return res;
|
||||
}
|
||||
|
||||
bool rDir::GetNext(std::string *filename) const
|
||||
{
|
||||
wxString str;
|
||||
bool res;
|
||||
res = reinterpret_cast<wxDir*>(handle)->GetNext(&str);
|
||||
*filename = str.ToStdString();
|
||||
return res;
|
||||
}
|
97
Utilities/File.h
Normal file
97
Utilities/File.h
Normal file
|
@ -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;
|
||||
};
|
|
@ -5,11 +5,11 @@
|
|||
#include <iostream>
|
||||
#include <cinttypes>
|
||||
#include "Thread.h"
|
||||
#include "rFile.h"
|
||||
#include "File.h"
|
||||
|
||||
using namespace Log;
|
||||
|
||||
LogManager *gLogManager = nullptr;
|
||||
std::unique_ptr<LogManager> 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<LogListener> listener)
|
|||
channel.addListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
void LogManager::removeListener(std::shared_ptr<LogListener> listener)
|
||||
{
|
||||
for (auto& channel : mChannels)
|
||||
|
@ -233,12 +235,14 @@ void LogManager::removeListener(std::shared_ptr<LogListener> 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<u32>(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})
|
||||
|
||||
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) };
|
||||
Log::LogManager::getInstance().log(msg);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
#include "stdafx.h"
|
||||
#pragma warning(push)
|
||||
#pragma message("TODO: remove wx dependency: <wx/string.h>")
|
||||
#pragma warning(disable : 4996)
|
||||
#include <wx/string.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
std::string u128::to_hex() const
|
||||
{
|
||||
|
@ -218,7 +222,7 @@ std::string fmt::merge(std::vector<std::string> 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<std::vector<std::string>> sources, const std::string& separator)
|
||||
|
|
|
@ -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<typename T>
|
||||
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<typename T>
|
||||
//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<typename ... Args>
|
||||
std::string SFormat(const std::string &fmt, Args&& ... parameters)
|
||||
{
|
||||
std::ostringstream os;
|
||||
std::string::size_type pos = 0;
|
||||
std::initializer_list<empty_t> { write(fmt, os, pos, parameters)... };
|
||||
//template<typename ... Args>
|
||||
//std::string SFormat(const std::string &fmt, Args&& ... parameters)
|
||||
//{
|
||||
// std::ostringstream os;
|
||||
// std::string::size_type pos = 0;
|
||||
// std::initializer_list<empty_t> { 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<typename T>
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
static std::thread::id main_thread;
|
||||
|
||||
class NamedThreadBase
|
||||
{
|
||||
std::string m_name;
|
||||
|
|
|
@ -1,414 +0,0 @@
|
|||
#include "stdafx.h"
|
||||
#include "Log.h"
|
||||
#pragma warning(disable : 4996)
|
||||
#include <wx/dir.h>
|
||||
#include <wx/file.h>
|
||||
#include <wx/filename.h>
|
||||
#include "rFile.h"
|
||||
#include "errno.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
|
||||
// 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<void*>(new wxFile());
|
||||
}
|
||||
|
||||
rFile::rFile(const std::string& filename, rFile::OpenMode open)
|
||||
{
|
||||
|
||||
handle = reinterpret_cast<void*>(new wxFile(fmt::FromUTF8(filename), convertOpenMode(open)));
|
||||
}
|
||||
|
||||
rFile::rFile(int fd)
|
||||
{
|
||||
handle = reinterpret_cast<void*>(new wxFile(fd));
|
||||
}
|
||||
|
||||
rFile::~rFile()
|
||||
{
|
||||
delete reinterpret_cast<wxFile*>(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<wxFile*>(handle)->Write(buffer,count);
|
||||
}
|
||||
|
||||
bool rFile::Write(const std::string &text)
|
||||
{
|
||||
return reinterpret_cast<wxFile*>(handle)->Write(reinterpret_cast<const void*>(text.c_str()),text.size()) != 0;
|
||||
}
|
||||
|
||||
bool rFile::Close()
|
||||
{
|
||||
return reinterpret_cast<wxFile*>(handle)->Close();
|
||||
}
|
||||
|
||||
bool rFile::Create(const std::string &filename, bool overwrite, int access)
|
||||
{
|
||||
return reinterpret_cast<wxFile*>(handle)->Create(fmt::FromUTF8(filename), overwrite, access);
|
||||
}
|
||||
|
||||
bool rFile::Open(const std::string &filename, rFile::OpenMode mode, int access)
|
||||
{
|
||||
return reinterpret_cast<wxFile*>(handle)->Open(fmt::FromUTF8(filename), convertOpenMode(mode), access);
|
||||
}
|
||||
|
||||
bool rFile::IsOpened() const
|
||||
{
|
||||
return reinterpret_cast<wxFile*>(handle)->IsOpened();
|
||||
}
|
||||
|
||||
size_t rFile::Length() const
|
||||
{
|
||||
return reinterpret_cast<wxFile*>(handle)->Length();
|
||||
}
|
||||
|
||||
size_t rFile::Read(void *buffer, size_t count)
|
||||
{
|
||||
return reinterpret_cast<wxFile*>(handle)->Read(buffer,count);
|
||||
}
|
||||
|
||||
size_t rFile::Seek(size_t ofs, rSeekMode mode)
|
||||
{
|
||||
return reinterpret_cast<wxFile*>(handle)->Seek(ofs, convertSeekMode(mode));
|
||||
}
|
||||
|
||||
size_t rFile::Tell() const
|
||||
{
|
||||
return reinterpret_cast<wxFile*>(handle)->Tell();
|
||||
}
|
||||
|
||||
rDir::rDir()
|
||||
{
|
||||
handle = reinterpret_cast<void*>(new wxDir());
|
||||
}
|
||||
|
||||
rDir::~rDir()
|
||||
{
|
||||
delete reinterpret_cast<wxDir*>(handle);
|
||||
}
|
||||
|
||||
rDir::rDir(const std::string &path)
|
||||
{
|
||||
handle = reinterpret_cast<void*>(new wxDir(fmt::FromUTF8(path)));
|
||||
}
|
||||
|
||||
bool rDir::Open(const std::string& path)
|
||||
{
|
||||
return reinterpret_cast<wxDir*>(handle)->Open(fmt::FromUTF8(path));
|
||||
}
|
||||
|
||||
bool rDir::IsOpened() const
|
||||
{
|
||||
return reinterpret_cast<wxDir*>(handle)->IsOpened();
|
||||
}
|
||||
|
||||
bool rDir::GetFirst(std::string *filename) const
|
||||
{
|
||||
wxString str;
|
||||
bool res;
|
||||
res = reinterpret_cast<wxDir*>(handle)->GetFirst(&str);
|
||||
*filename = str.ToStdString();
|
||||
return res;
|
||||
}
|
||||
|
||||
bool rDir::GetNext(std::string *filename) const
|
||||
{
|
||||
wxString str;
|
||||
bool res;
|
||||
res = reinterpret_cast<wxDir*>(handle)->GetNext(&str);
|
||||
*filename = str.ToStdString();
|
||||
return res;
|
||||
}
|
||||
|
||||
rFileName::rFileName()
|
||||
{
|
||||
handle = reinterpret_cast<void*>(new wxFileName());
|
||||
}
|
||||
|
||||
rFileName::~rFileName()
|
||||
{
|
||||
delete reinterpret_cast<wxFileName*>(handle);
|
||||
}
|
||||
|
||||
rFileName::rFileName(const rFileName& filename)
|
||||
{
|
||||
handle = reinterpret_cast<void*>(new wxFileName(*reinterpret_cast<wxFileName*>(filename.handle)));
|
||||
}
|
||||
|
||||
|
||||
rFileName::rFileName(const std::string& name)
|
||||
{
|
||||
handle = reinterpret_cast<void*>(new wxFileName(fmt::FromUTF8(name)));
|
||||
}
|
||||
|
||||
std::string rFileName::GetFullPath()
|
||||
{
|
||||
return fmt::ToUTF8(reinterpret_cast<wxFileName*>(handle)->GetFullPath());
|
||||
}
|
||||
|
||||
std::string rFileName::GetPath()
|
||||
{
|
||||
return fmt::ToUTF8(reinterpret_cast<wxFileName*>(handle)->GetPath());
|
||||
}
|
||||
|
||||
std::string rFileName::GetName()
|
||||
{
|
||||
return fmt::ToUTF8(reinterpret_cast<wxFileName*>(handle)->GetName());
|
||||
}
|
||||
|
||||
std::string rFileName::GetFullName()
|
||||
{
|
||||
return fmt::ToUTF8(reinterpret_cast<wxFileName*>(handle)->GetFullName());
|
||||
}
|
||||
|
||||
bool rFileName::Normalize()
|
||||
{
|
||||
return reinterpret_cast<wxFileName*>(handle)->Normalize();
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
|
@ -1,7 +1,10 @@
|
|||
#include "stdafx.h"
|
||||
#include "restore_new.h"
|
||||
#pragma warning(push)
|
||||
#pragma message("TODO: remove wx dependency: <wx/msgdlg.h>")
|
||||
#pragma warning(disable : 4996)
|
||||
#include <wx/msgdlg.h>
|
||||
#pragma warning(pop)
|
||||
#include "define_new_memleakdetect.h"
|
||||
#include "rMsgBox.h"
|
||||
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#include "stdafx.h"
|
||||
#include "restore_new.h"
|
||||
#pragma warning(push)
|
||||
#pragma message("TODO: remove wx dependency: <wx/image.h>")
|
||||
#pragma warning(disable : 4996)
|
||||
#include <wx/image.h>
|
||||
#pragma warning(pop)
|
||||
#include "define_new_memleakdetect.h"
|
||||
|
||||
#ifndef _WIN32
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
#include "stdafx.h"
|
||||
#include "rTime.h"
|
||||
#pragma warning(push)
|
||||
#pragma message("TODO: remove wx dependency: <wx/datetime.h>")
|
||||
#pragma warning(disable : 4996)
|
||||
#include <wx/datetime.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
std::string rDefaultDateTimeFormat = "%c";
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#include "stdafx.h"
|
||||
#include "Utilities/rXml.h"
|
||||
#pragma warning(push)
|
||||
#pragma message("TODO: remove wx dependency: <wx/xml/xml.h>")
|
||||
#pragma warning(disable : 4996)
|
||||
#include <wx/xml/xml.h>
|
||||
#pragma warning(pop)
|
||||
|
||||
rXmlNode::rXmlNode()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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: <wx/progdlg.h>")
|
||||
#pragma warning(disable : 4996)
|
||||
#include <wx/progdlg.h>
|
||||
#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; i<parts; i++)
|
||||
{
|
||||
memset(buf, 0, sizeof(buf));
|
||||
u32 length = pkg_f.Read(buf, BUF_SIZE);
|
||||
u32 length = pkg_f.read(buf, BUF_SIZE);
|
||||
u32 bits = (length + HASH_LEN - 1) / HASH_LEN;
|
||||
|
||||
if (m_header->pkg_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));
|
||||
else
|
||||
out.Write(buf, BUF_SIZE);
|
||||
{
|
||||
out.write(buf, BUF_SIZE - (size - entry.file_size));
|
||||
}
|
||||
out.Close();
|
||||
else
|
||||
{
|
||||
out.write(buf, BUF_SIZE);
|
||||
}
|
||||
}
|
||||
|
||||
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<PKGEntry> 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;
|
||||
}
|
||||
|
|
|
@ -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<u32> pad; // Padding (zeros)
|
||||
};
|
||||
|
||||
class rFile;
|
||||
namespace fs { struct file; }
|
||||
|
||||
extern int Unpack(rFile& dec_pkg_f, std::string src, std::string dst);
|
||||
int Unpack(const fs::file& dec_pkg_f, std::string src, std::string dst);
|
||||
|
|
|
@ -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: <wx/mstream.h> <wx/zstream.h>")
|
||||
#pragma warning(disable : 4996)
|
||||
#include <wx/mstream.h>
|
||||
#include <wx/zstream.h>
|
||||
#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<u16> 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<u32> 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<u64> 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;
|
||||
}
|
||||
}
|
||||
|
||||
bool DecryptSelf(const std::string& elf, const std::string& self)
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "Loader/ELF64.h"
|
||||
#include "Loader/ELF32.h"
|
||||
#include "key_vault.h"
|
||||
|
||||
struct vfsStream;
|
||||
|
||||
struct AppInfo
|
||||
{
|
||||
u64 authid;
|
||||
|
@ -13,7 +12,6 @@ struct AppInfo
|
|||
u64 padding;
|
||||
|
||||
void Load(vfsStream& f);
|
||||
|
||||
void Show();
|
||||
};
|
||||
|
||||
|
@ -27,7 +25,6 @@ struct SectionInfo
|
|||
u32 encrypted;
|
||||
|
||||
void Load(vfsStream& f);
|
||||
|
||||
void Show();
|
||||
};
|
||||
|
||||
|
@ -39,7 +36,6 @@ struct SCEVersionInfo
|
|||
u32 unknown;
|
||||
|
||||
void Load(vfsStream& f);
|
||||
|
||||
void Show();
|
||||
};
|
||||
|
||||
|
@ -49,9 +45,11 @@ struct ControlInfo
|
|||
u32 size;
|
||||
u64 next;
|
||||
|
||||
union {
|
||||
union
|
||||
{
|
||||
// type 1 0x30 bytes
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
u32 ctrl_flag1;
|
||||
u32 unknown1;
|
||||
u32 unknown2;
|
||||
|
@ -60,23 +58,29 @@ struct ControlInfo
|
|||
u32 unknown5;
|
||||
u32 unknown6;
|
||||
u32 unknown7;
|
||||
|
||||
} control_flags;
|
||||
|
||||
// type 2 0x30 bytes
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
u8 digest[20];
|
||||
u64 unknown;
|
||||
|
||||
} file_digest_30;
|
||||
|
||||
// type 2 0x40 bytes
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
u8 digest1[20];
|
||||
u8 digest2[20];
|
||||
u64 unknown;
|
||||
|
||||
} file_digest_40;
|
||||
|
||||
// type 3 0x90 bytes
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
u32 magic;
|
||||
u32 unknown1;
|
||||
u32 license;
|
||||
|
@ -87,11 +91,11 @@ struct ControlInfo
|
|||
u8 xordigest[16];
|
||||
u64 unknown2;
|
||||
u64 unknown3;
|
||||
|
||||
} npdrm;
|
||||
};
|
||||
|
||||
void Load(vfsStream& f);
|
||||
|
||||
void Show();
|
||||
};
|
||||
|
||||
|
@ -104,7 +108,6 @@ struct MetadataInfo
|
|||
u8 iv_pad[0x10];
|
||||
|
||||
void Load(u8* in);
|
||||
|
||||
void Show();
|
||||
};
|
||||
|
||||
|
@ -119,7 +122,6 @@ struct MetadataHeader
|
|||
u32 unknown3;
|
||||
|
||||
void Load(u8* in);
|
||||
|
||||
void Show();
|
||||
};
|
||||
|
||||
|
@ -137,7 +139,6 @@ struct MetadataSectionHeader
|
|||
u32 compressed;
|
||||
|
||||
void Load(u8* in);
|
||||
|
||||
void Show();
|
||||
};
|
||||
|
||||
|
@ -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.
|
||||
|
|
|
@ -64,7 +64,7 @@ s32 sceKernelStartThread(s32 threadId, u32 argSize, vm::psv::ptr<const void> pAr
|
|||
{
|
||||
sceLibKernel.Warning("sceKernelStartThread(threadId=0x%x, argSize=0x%x, pArgBlock=*0x%x)", threadId, argSize, pArgBlock);
|
||||
|
||||
std::shared_ptr<CPUThread> 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<CPUThread> 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<s32> pExitStatus, vm::psv:
|
|||
{
|
||||
sceLibKernel.Warning("sceKernelWaitThreadEnd(threadId=0x%x, pExitStatus=*0x%x, pTimeout=*0x%x)", threadId, pExitStatus, pTimeout);
|
||||
|
||||
std::shared_ptr<CPUThread> t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7);
|
||||
const auto t = Emu.GetCPU().GetThread(threadId, CPU_THREAD_ARMv7);
|
||||
|
||||
if (!t)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<typename T, arg_class type, int g_count, int f_count, int v_count>
|
||||
struct bind_arg;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -112,26 +112,14 @@ void CPUThreadManager::RemoveThread(u32 id)
|
|||
|
||||
std::shared_ptr<CPUThread> CPUThreadManager::GetThread(u32 id)
|
||||
{
|
||||
std::shared_ptr<CPUThread> res;
|
||||
|
||||
if (!id) return nullptr;
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(id, res)) return nullptr;
|
||||
|
||||
return res;
|
||||
return Emu.GetIdManager().GetIDData<CPUThread>(id);
|
||||
}
|
||||
|
||||
std::shared_ptr<CPUThread> CPUThreadManager::GetThread(u32 id, CPUThreadType type)
|
||||
{
|
||||
std::shared_ptr<CPUThread> 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<CPUThread> CPUThreadManager::GetRawSPUThread(u32 index)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
class CPUThread;
|
||||
class RawSPUThread;
|
||||
enum CPUThreadType : unsigned char;
|
||||
|
||||
class CPUThreadManager
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#ifdef LLVM_AVAILABLE
|
||||
#define PPU_LLVM_RECOMPILER 1
|
||||
|
||||
#include <list>
|
||||
#include "Emu/Cell/PPUDecoder.h"
|
||||
#include "Emu/Cell/PPUThread.h"
|
||||
#include "Emu/Cell/PPUInterpreter.h"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "stdafx_gui.h"
|
||||
#include "PPUProgramCompiler.h"
|
||||
#include "Utilities/rFile.h"
|
||||
#include "Utilities/File.h"
|
||||
/*
|
||||
using namespace PPU_instr;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
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);
|
||||
|
|
|
@ -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<float>(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));
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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<u8>(CPU.offset);
|
||||
//SPUDisAsm dis_asm(CPUDisAsm_InterpreterMode);
|
||||
//dis_asm.offset = vm::get_ptr<u8>(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<u32, void*, void*, void*, u32>());
|
||||
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))
|
||||
//std::string log = fmt::format("========== START POSITION 0x%x ==========\n\n", start * 4);
|
||||
//log += stringLogger.getString();
|
||||
//if (!entry[start].pointer)
|
||||
//{
|
||||
// LOG_ERROR(Log::SPU, "RtlAddFunctionTable() failed");
|
||||
// LOG_ERROR(Log::SPU, "SPURecompilerCore::Compile(pos=0x%x) failed", start * sizeof(u32));
|
||||
// log += "========== FAILED ============\n\n";
|
||||
// Emu.Pause();
|
||||
//}
|
||||
#endif
|
||||
}
|
||||
log.Close();
|
||||
//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<void>(m_offset), imm_table.data(), &g_imm_table);
|
||||
res = func(cpu, vm::get_ptr<void>(m_offset), imm_table.data(), &g_spu_imm);
|
||||
|
||||
if (res & 0x1000000)
|
||||
{
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
|
||||
#include <cfenv>
|
||||
|
||||
const g_spu_imm_table_t g_spu_imm;
|
||||
|
||||
class spu_inter_func_list_t
|
||||
{
|
||||
std::array<spu_inter_func_t, 2048> 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<spu_group_t> group = tg.lock();
|
||||
std::shared_ptr<CPUThread> 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<SPUThread&>(*t);
|
||||
auto& spu = static_cast<SPUThread&>(*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<event_queue_t> 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<event_queue_t> 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<event_flag_t> ef;
|
||||
const auto ef = Emu.GetIdManager().GetIDData<event_flag_t>(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<event_flag_t> ef;
|
||||
const auto ef = Emu.GetIdManager().GetIDData<event_flag_t>(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<spu_group_t> group = tg.lock();
|
||||
const auto group = tg.lock();
|
||||
|
||||
if (!group)
|
||||
{
|
||||
|
|
|
@ -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<float>(exp2(i)));
|
||||
}
|
||||
for (u32 i = 0; i < sizeof(fsmh_table) / sizeof(fsmh_table[0]); i++)
|
||||
{
|
||||
for (u32 j = 0; j < 8; j++) mmToU16Ptr(fsmh_table[i])[j] = (i & (1 << j)) ? ~0 : 0;
|
||||
}
|
||||
for (u32 i = 0; i < sizeof(fsmb_table) / sizeof(fsmb_table[0]); i++)
|
||||
|
||||
__forceinline __m128 operator [] (s32 scale) const
|
||||
{
|
||||
for (u32 j = 0; j < 16; j++) mmToU8Ptr(fsmb_table[i])[j] = (i & (1 << j)) ? ~0 : 0;
|
||||
return m_data[scale + 155];
|
||||
}
|
||||
}
|
||||
const scale;
|
||||
|
||||
g_spu_imm_table_t()
|
||||
{
|
||||
for (u32 i = 0; i < sizeof(fsm) / sizeof(fsm[0]); i++)
|
||||
{
|
||||
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<u8>(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<u8>(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<u8>((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
|
||||
{
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -6,22 +6,20 @@
|
|||
#include "Ini.h"
|
||||
#include "Emu/System.h"
|
||||
#include "Utilities/Log.h"
|
||||
#include <sys/stat.h> // To check whether directory exists
|
||||
|
||||
#undef CreateFile
|
||||
|
||||
std::vector<std::string> simplify_path_blocks(const std::string& path)
|
||||
{
|
||||
// fmt::tolower() removed
|
||||
std::vector<std::string> 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<vfsFileBase> 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<vfsDirBase> res(dev->GetNewDirStream());
|
||||
std::unique_ptr<vfsDirBase> 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<vfsFileBase> res(dev->GetNewFileStream());
|
||||
std::unique_ptr<vfsFileBase> 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<vfsDirBase> res(dev->GetNewDirStream());
|
||||
std::unique_ptr<vfsDirBase> 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<vfsFileBase> res(dev->GetNewFileStream());
|
||||
std::unique_ptr<vfsFileBase> 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<vfsDirBase> res(dev->GetNewDirStream());
|
||||
std::unique_ptr<vfsDirBase> 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<vfsFileBase> res(dev->GetNewFileStream());
|
||||
std::unique_ptr<vfsFileBase> 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<vfsDirBase> res(dev->GetNewDirStream());
|
||||
std::unique_ptr<vfsDirBase> 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<VFSManagerEntry>& 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<VFSManagerEntry>& 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<count; ++i)
|
||||
{
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
class vfsDevice;
|
||||
struct vfsFileBase;
|
||||
class vfsDirBase;
|
||||
enum vfsOpenMode : u8;
|
||||
|
||||
enum vfsDeviceType
|
||||
{
|
||||
|
@ -76,16 +75,18 @@ struct VFS
|
|||
|
||||
std::string GetLinked(const std::string& ps3_path) const;
|
||||
|
||||
vfsFileBase* OpenFile(const std::string& ps3_path, vfsOpenMode mode) const;
|
||||
vfsFileBase* OpenFile(const std::string& ps3_path, u32 mode) const;
|
||||
vfsDirBase* OpenDir(const std::string& ps3_path) const;
|
||||
bool CreateFile(const std::string& ps3_path, bool overwrite = false) const;
|
||||
bool CreateDir(const std::string& ps3_path) const;
|
||||
bool CreatePath(const std::string& ps3_path) const;
|
||||
bool RemoveFile(const std::string& ps3_path) const;
|
||||
bool RemoveDir(const std::string& ps3_path) const;
|
||||
bool ExistsFile(const std::string& ps3_path) const;
|
||||
bool ExistsDir(const std::string& ps3_path) const;
|
||||
bool RenameFile(const std::string& ps3_path_from, const std::string& ps3_path_to) const;
|
||||
bool RenameDir(const std::string& ps3_path_from, const std::string& ps3_path_to) const;
|
||||
bool CopyFile(const std::string& ps3_path_from, const std::string& ps3_path_to, bool overwrite = true) const;
|
||||
bool TruncateFile(const std::string& ps3_path, u64 length) const;
|
||||
|
||||
vfsDevice* GetDevice(const std::string& ps3_path, std::string& path) const;
|
||||
vfsDevice* GetDeviceLocal(const std::string& local_path, std::string& path) const;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "stdafx.h"
|
||||
#include "vfsDevice.h"
|
||||
#include "Utilities/rFile.h"
|
||||
|
||||
vfsDevice::vfsDevice(const std::string& ps3_path, const std::string& local_path)
|
||||
: m_ps3_path(ps3_path)
|
||||
|
@ -46,16 +45,13 @@ u32 vfsDevice::CmpLocalPath(const std::string& local_path)
|
|||
if(local_path.length() < m_local_path.length())
|
||||
return 0;
|
||||
|
||||
rFileName path0(m_local_path);
|
||||
path0.Normalize();
|
||||
|
||||
#ifdef _WIN32
|
||||
#define DL "\\"
|
||||
#else
|
||||
#define DL "/"
|
||||
#endif
|
||||
|
||||
std::vector<std::string> arr0 = fmt::rSplit(path0.GetFullPath(), DL);
|
||||
std::vector<std::string> arr0 = fmt::rSplit(m_local_path, DL);
|
||||
std::vector<std::string> 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)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "stdafx.h"
|
||||
#include "Utilities/rFile.h"
|
||||
#include "Utilities/File.h"
|
||||
#include "vfsDirBase.h"
|
||||
|
||||
vfsDirBase::vfsDirBase(vfsDevice* device)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -8,21 +8,20 @@ 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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
#include "vfsDirBase.h"
|
||||
#include "Utilities/rFile.h"
|
||||
#include "Utilities/File.h"
|
||||
|
||||
class vfsLocalDir : public vfsDirBase
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
virtual const fs::file& GetFile() const { return m_file; }
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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<typename T> __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;
|
||||
template<typename T> __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;
|
||||
};
|
|
@ -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<void>(vm::cast(m_addr + Tell())), src, size);
|
||||
return vfsStream::Write(src, size);
|
||||
memcpy(vm::get_ptr<void>(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<void>(vm::cast(m_addr + Tell())), size);
|
||||
return vfsStream::Read(dst, size);
|
||||
memcpy(dst, vm::get_ptr<void>(vm::cast(m_addr + m_pos)), count);
|
||||
m_pos += count;
|
||||
return count;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
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;
|
||||
}
|
||||
};
|
|
@ -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();
|
||||
}
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -122,22 +122,6 @@ public:
|
|||
return m_cur_id++;
|
||||
}
|
||||
|
||||
template<typename T> bool GetIDData(const u32 id, std::shared_ptr<T>& result)
|
||||
{
|
||||
std::lock_guard<std::mutex> 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<T>();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template<typename T> std::shared_ptr<T> GetIDData(const u32 id)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
|
|
|
@ -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<PPUThread&>(CPU);
|
||||
PPUThread& context = static_cast<PPUThread&>(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<u32>(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<PPUThread&>(CPU);
|
||||
PPUThread& context = static_cast<PPUThread&>(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<ARMv7Thread&>(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;
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace vm
|
|||
void dealloc(u32 addr, memory_location location = user_space);
|
||||
|
||||
template<typename T = void>
|
||||
T* const get_ptr(u32 addr)
|
||||
T* get_ptr(u32 addr)
|
||||
{
|
||||
return reinterpret_cast<T*>(static_cast<u8*>(g_base_addr) + addr);
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ namespace vm
|
|||
}
|
||||
|
||||
template<typename T = void>
|
||||
T* const priv_ptr(u32 addr)
|
||||
T* priv_ptr(u32 addr)
|
||||
{
|
||||
return reinterpret_cast<T*>(static_cast<u8*>(g_priv_addr) + addr);
|
||||
}
|
||||
|
@ -107,15 +107,11 @@ namespace vm
|
|||
template<>
|
||||
struct cast_ptr<unsigned long>
|
||||
{
|
||||
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<u32>(addr);
|
||||
if (res != addr)
|
||||
{
|
||||
vm::error(addr, func);
|
||||
}
|
||||
|
||||
return res;
|
||||
return cast_ptr<u64>::cast(addr, func);
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -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<typename T, int lvl = 1, typename AT = u32> using bptrl = _ptr_base<T, lvl, typename to_be_t<AT>::type>;
|
||||
|
||||
//BE pointer to BE data
|
||||
// BE pointer to BE data
|
||||
template<typename T, int lvl = 1, typename AT = u32> using bptrb = _ptr_base<typename to_be_t<T>::type, lvl, typename to_be_t<AT>::type>;
|
||||
|
||||
//LE pointer to BE data
|
||||
// LE pointer to BE data
|
||||
template<typename T, int lvl = 1, typename AT = u32> using lptrb = _ptr_base<typename to_be_t<T>::type, lvl, AT>;
|
||||
|
||||
//LE pointer to LE data
|
||||
// LE pointer to LE data
|
||||
template<typename T, int lvl = 1, typename AT = u32> using lptrl = _ptr_base<T, lvl, AT>;
|
||||
|
||||
namespace ps3
|
||||
{
|
||||
//default pointer for HLE functions (LE pointer to BE data)
|
||||
// default pointer for HLE functions (LE pointer to BE data)
|
||||
template<typename T, int lvl = 1, typename AT = u32> using ptr = lptrb<T, lvl, AT>;
|
||||
|
||||
//default pointer for HLE structures (BE pointer to BE data)
|
||||
// default pointer for HLE structures (BE pointer to BE data)
|
||||
template<typename T, int lvl = 1, typename AT = u32> using bptr = bptrb<T, lvl, AT>;
|
||||
}
|
||||
|
||||
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<typename T, int lvl = 1, typename AT = u32> using ptr = lptrl<T, lvl, AT>;
|
||||
}
|
||||
|
||||
//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<typename T, int lvl, typename AT> operator _ptr_base<T, lvl, AT>() const
|
||||
{
|
||||
const std::array<AT, 1> value = {};
|
||||
return _ptr_base<T, lvl, AT>::make(value[0]);
|
||||
}
|
||||
};
|
||||
|
||||
// vm::null is convertible to any vm::ptr type as null pointer in virtual memory
|
||||
static null_t null;
|
||||
}
|
||||
|
||||
namespace fmt
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
#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<CgBinaryProgram>(ptr);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -2484,19 +2484,20 @@ 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;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
while (!TestDestroy()) try
|
||||
|
|
|
@ -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<typename T, _func_arg_type type, int g_count, int f_count, int v_count>
|
||||
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<T>(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<void, T...>::call(CPU, pc, rtoc, args...);
|
||||
|
||||
static_assert(!std::is_pointer<RT>::value, "Invalid callback result type (pointer)");
|
||||
static_assert(!std::is_reference<RT>::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<typename AT, typename RT, typename... T>
|
||||
__forceinline RT _ptr_base<RT(T...), 1, AT>::operator()(CPUThread& CPU, T... args) const
|
||||
__forceinline RT _ptr_base<RT(T...), 1, AT>::operator()(PPUThread& CPU, T... args) const
|
||||
{
|
||||
auto data = vm::get_ptr<be_t<u32>>(vm::cast(m_addr));
|
||||
const auto data = vm::get_ptr<be_t<u32>>(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<RT, T...>::call(static_cast<PPUThread&>(CPU), pc, rtoc, args...);
|
||||
return cb_detail::_func_caller<RT, T...>::call(CPU, pc, rtoc, args...);
|
||||
}
|
||||
|
||||
template<typename AT, typename RT, typename... T>
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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<be_t<u32>>(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())
|
||||
{
|
||||
|
|
|
@ -33,7 +33,7 @@ struct ModuleFunc
|
|||
{
|
||||
}
|
||||
|
||||
ModuleFunc(u32 id, u32 flags, Module* module, const char* name, ppu_func_caller func, vm::ptr<void()> lle_func = vm::ptr<void()>::make(0))
|
||||
ModuleFunc(u32 id, u32 flags, Module* module, const char* name, ppu_func_caller func, vm::ptr<void()> lle_func = vm::null)
|
||||
: id(id)
|
||||
, flags(flags)
|
||||
, module(module)
|
||||
|
|
|
@ -226,7 +226,7 @@ u32 adecOpen(AudioDecoder* adec_ptr)
|
|||
adec.id = adec_id;
|
||||
|
||||
adec.adecCb = static_cast<PPUThread*>(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<CellAdecType> type, vm::ptr<CellAdecAttr> attr)
|
||||
s32 cellAdecQueryAttr(vm::ptr<CellAdecType> type, vm::ptr<CellAdecAttr> 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<CellAdecType> type, vm::ptr<CellAdecAttr> attr)
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAdecOpen(vm::ptr<CellAdecType> type, vm::ptr<CellAdecResource> res, vm::ptr<CellAdecCb> cb, vm::ptr<u32> handle)
|
||||
s32 cellAdecOpen(vm::ptr<CellAdecType> type, vm::ptr<CellAdecResource> res, vm::ptr<CellAdecCb> cb, vm::ptr<u32> 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<CellAdecType> type, vm::ptr<CellAdecResourceEx> res, vm::ptr<CellAdecCb> cb, vm::ptr<u32> handle)
|
||||
s32 cellAdecOpenEx(vm::ptr<CellAdecType> type, vm::ptr<CellAdecResourceEx> res, vm::ptr<CellAdecCb> cb, vm::ptr<u32> 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<CellAdecType> type, vm::ptr<CellAdecResourceEx> res, vm::ptr<CellAdecCb> cb, vm::ptr<u32> handle)
|
||||
{
|
||||
cellAdec.Warning("cellAdecClose(handle=%d)", handle);
|
||||
return cellAdecOpenEx(type, res, cb, handle);
|
||||
}
|
||||
|
||||
std::shared_ptr<AudioDecoder> adec;
|
||||
if (!Emu.GetIdManager().GetIDData(handle, adec))
|
||||
s32 cellAdecClose(u32 handle)
|
||||
{
|
||||
cellAdec.Warning("cellAdecClose(handle=0x%x)", handle);
|
||||
|
||||
const auto adec = Emu.GetIdManager().GetIDData<AudioDecoder>(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<AudioDecoder> adec;
|
||||
if (!Emu.GetIdManager().GetIDData(handle, adec))
|
||||
const auto adec = Emu.GetIdManager().GetIDData<AudioDecoder>(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<const CellAdecParamAtracX>::make(param_addr);
|
||||
const auto atx = vm::ptr<const CellAdecParamAtracX>::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<const CellAdecParamMP3>::make(param_addr);
|
||||
const auto mp3 = vm::ptr<const CellAdecParamMP3>::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<AudioDecoder> adec;
|
||||
if (!Emu.GetIdManager().GetIDData(handle, adec))
|
||||
const auto adec = Emu.GetIdManager().GetIDData<AudioDecoder>(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<CellAdecAuInfo> auInfo)
|
||||
s32 cellAdecDecodeAu(u32 handle, vm::ptr<CellAdecAuInfo> 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<AudioDecoder> adec;
|
||||
if (!Emu.GetIdManager().GetIDData(handle, adec))
|
||||
const auto adec = Emu.GetIdManager().GetIDData<AudioDecoder>(handle);
|
||||
|
||||
if (!adec)
|
||||
{
|
||||
return CELL_ADEC_ERROR_ARG;
|
||||
}
|
||||
|
@ -664,12 +680,13 @@ int cellAdecDecodeAu(u32 handle, vm::ptr<CellAdecAuInfo> auInfo)
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAdecGetPcm(u32 handle, vm::ptr<float> outBuffer)
|
||||
s32 cellAdecGetPcm(u32 handle, vm::ptr<float> 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<AudioDecoder> adec;
|
||||
if (!Emu.GetIdManager().GetIDData(handle, adec))
|
||||
const auto adec = Emu.GetIdManager().GetIDData<AudioDecoder>(handle);
|
||||
|
||||
if (!adec)
|
||||
{
|
||||
return CELL_ADEC_ERROR_ARG;
|
||||
}
|
||||
|
@ -779,12 +796,13 @@ int cellAdecGetPcm(u32 handle, vm::ptr<float> outBuffer)
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellAdecGetPcmItem(u32 handle, vm::ptr<u32> pcmItem_ptr)
|
||||
s32 cellAdecGetPcmItem(u32 handle, vm::ptr<vm::bptr<CellAdecPcmItem>> 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<AudioDecoder> adec;
|
||||
if (!Emu.GetIdManager().GetIDData(handle, adec))
|
||||
const auto adec = Emu.GetIdManager().GetIDData<AudioDecoder>(handle);
|
||||
|
||||
if (!adec)
|
||||
{
|
||||
return CELL_ADEC_ERROR_ARG;
|
||||
}
|
||||
|
@ -798,7 +816,7 @@ int cellAdecGetPcmItem(u32 handle, vm::ptr<u32> pcmItem_ptr)
|
|||
|
||||
AVFrame* frame = af.data;
|
||||
|
||||
auto pcm = vm::ptr<CellAdecPcmItem>::make(adec->memAddr + adec->memBias);
|
||||
const auto pcm = vm::ptr<CellAdecPcmItem>::make(adec->memAddr + adec->memBias);
|
||||
|
||||
adec->memBias += 512;
|
||||
if (adec->memBias + 512 > adec->memSize)
|
||||
|
@ -853,7 +871,7 @@ int cellAdecGetPcmItem(u32 handle, vm::ptr<u32> 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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
if (port.level_set - port.level <= 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))
|
||||
{
|
||||
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<event_queue_t> 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<CellAudioPortParam> audioParam, vm::ptr<u32> 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<std::mutex> 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
|
||||
{
|
||||
|
|
|
@ -108,9 +108,15 @@ struct AudioPortConfig
|
|||
u32 addr;
|
||||
u32 read_index_addr;
|
||||
u32 size;
|
||||
|
||||
struct level_set_t
|
||||
{
|
||||
float value;
|
||||
float inc;
|
||||
};
|
||||
|
||||
float level;
|
||||
float level_set;
|
||||
float level_inc;
|
||||
atomic_le_t<level_set_t> level_set;
|
||||
};
|
||||
|
||||
struct AudioConfig //custom structure
|
||||
|
|
|
@ -6,15 +6,15 @@
|
|||
|
||||
extern Module cellAvconfExt;
|
||||
|
||||
int cellVideoOutConvertCursorColor()
|
||||
s32 cellVideoOutConvertCursorColor()
|
||||
{
|
||||
UNIMPLEMENTED_FUNC(cellAvconfExt);
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellVideoOutGetScreenSize(u32 videoOut, vm::ptr<float> screenSize)
|
||||
s32 cellVideoOutGetScreenSize(u32 videoOut, vm::ptr<float> 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<float> 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<float> 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;
|
||||
|
|
|
@ -284,16 +284,18 @@ void dmuxQueryAttr(u32 info_addr /* may be 0 */, vm::ptr<CellDmuxAttr> attr)
|
|||
attr->memSize = 0x10000; // 0x3e8e6 from ps3
|
||||
}
|
||||
|
||||
void dmuxQueryEsAttr(u32 info_addr /* may be 0 */, vm::ptr<const CellCodecEsFilterId> esFilterId,
|
||||
const u32 esSpecificInfo_addr, vm::ptr<CellDmuxEsAttr> attr)
|
||||
void dmuxQueryEsAttr(u32 info /* may be 0 */, vm::ptr<const CellCodecEsFilterId> esFilterId, u32 esSpecificInfo, vm::ptr<CellDmuxEsAttr> 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<PPUThread*>(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<const CellDmuxType> demuxerType, vm::ptr<CellDmuxAttr> demuxerAttr)
|
||||
s32 cellDmuxQueryAttr(vm::ptr<const CellDmuxType> type, vm::ptr<CellDmuxAttr> 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<const CellDmuxType2> demuxerType2, vm::ptr<CellDmuxAttr> demuxerAttr)
|
||||
s32 cellDmuxQueryAttr2(vm::ptr<const CellDmuxType2> type2, vm::ptr<CellDmuxAttr> 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<const CellDmuxType> demuxerType, vm::ptr<const CellDmuxResource> demuxerResource,
|
||||
vm::ptr<const CellDmuxCb> demuxerCb, vm::ptr<u32> demuxerHandle)
|
||||
s32 cellDmuxOpen(vm::ptr<const CellDmuxType> type, vm::ptr<const CellDmuxResource> res, vm::ptr<const CellDmuxCb> cb, vm::ptr<u32> 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<const CellDmuxType> demuxerType, vm::ptr<const CellDmuxResourceEx> demuxerResourceEx,
|
||||
vm::ptr<const CellDmuxCb> demuxerCb, vm::ptr<u32> demuxerHandle)
|
||||
s32 cellDmuxOpenEx(vm::ptr<const CellDmuxType> type, vm::ptr<const CellDmuxResourceEx> resEx, vm::ptr<const CellDmuxCb> cb, vm::ptr<u32> 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<const CellDmuxType2> demuxerType2, vm::ptr<const CellDmuxResource2> demuxerResource2,
|
||||
vm::ptr<const CellDmuxCb> demuxerCb, vm::ptr<u32> demuxerHandle)
|
||||
s32 _nid_e075fabc(vm::ptr<const CellDmuxType> type, vm::ptr<const CellDmuxResourceEx> resEx, vm::ptr<const CellDmuxCb> cb, vm::ptr<u32> 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<const CellDmuxType2> type2, vm::ptr<const CellDmuxResource2> res2, vm::ptr<const CellDmuxCb> cb, vm::ptr<u32> 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<Demuxer> dmux;
|
||||
if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux))
|
||||
const auto dmux = Emu.GetIdManager().GetIDData<Demuxer>(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<Demuxer>(demuxerHandle);
|
||||
Emu.GetIdManager().RemoveID<Demuxer>(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<Demuxer> dmux;
|
||||
if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux))
|
||||
const auto dmux = Emu.GetIdManager().GetIDData<Demuxer>(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<Demuxer> dmux;
|
||||
if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux))
|
||||
const auto dmux = Emu.GetIdManager().GetIDData<Demuxer>(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<Demuxer> dmux;
|
||||
if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux))
|
||||
const auto dmux = Emu.GetIdManager().GetIDData<Demuxer>(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<const CellDmuxType> demuxerType, vm::ptr<const CellCodecEsFilterId> esFilterId,
|
||||
const u32 esSpecificInfo_addr, vm::ptr<CellDmuxEsAttr> esAttr)
|
||||
s32 cellDmuxQueryEsAttr(vm::ptr<const CellDmuxType> type, vm::ptr<const CellCodecEsFilterId> esFilterId, u32 esSpecificInfo, vm::ptr<CellDmuxEsAttr> 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<const CellDmuxType2> demuxerType2, vm::ptr<const CellCodecEsFilterId> esFilterId,
|
||||
const u32 esSpecificInfo_addr, vm::ptr<CellDmuxEsAttr> esAttr)
|
||||
s32 cellDmuxQueryEsAttr2(vm::ptr<const CellDmuxType2> type2, vm::ptr<const CellCodecEsFilterId> esFilterId, u32 esSpecificInfo, vm::ptr<CellDmuxEsAttr> 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<const CellCodecEsFilterId> esFilterId,
|
||||
vm::ptr<const CellDmuxEsResource> esResourceInfo, vm::ptr<const CellDmuxEsCb> esCb,
|
||||
const u32 esSpecificInfo_addr, vm::ptr<u32> esHandle)
|
||||
s32 cellDmuxEnableEs(u32 handle, vm::ptr<const CellCodecEsFilterId> esFilterId, vm::ptr<const CellDmuxEsResource> esResourceInfo, vm::ptr<const CellDmuxEsCb> esCb, u32 esSpecificInfo, vm::ptr<u32> 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<Demuxer> dmux;
|
||||
if (!Emu.GetIdManager().GetIDData(demuxerHandle, dmux))
|
||||
const auto dmux = Emu.GetIdManager().GetIDData<Demuxer>(handle);
|
||||
|
||||
if (!dmux)
|
||||
{
|
||||
return CELL_DMUX_ERROR_ARG;
|
||||
}
|
||||
|
@ -1007,14 +1004,14 @@ int cellDmuxEnableEs(u32 demuxerHandle, vm::ptr<const CellCodecEsFilterId> esFil
|
|||
|
||||
std::shared_ptr<ElementaryStream> 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<const CellCodecEsFilterId> esFil
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellDmuxDisableEs(u32 esHandle)
|
||||
s32 cellDmuxDisableEs(u32 esHandle)
|
||||
{
|
||||
cellDmux.Warning("cellDmuxDisableEs(esHandle=0x%x)", esHandle);
|
||||
|
||||
std::shared_ptr<ElementaryStream> es;
|
||||
if (!Emu.GetIdManager().GetIDData(esHandle, es))
|
||||
const auto es = Emu.GetIdManager().GetIDData<ElementaryStream>(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<ElementaryStream> es;
|
||||
if (!Emu.GetIdManager().GetIDData(esHandle, es))
|
||||
const auto es = Emu.GetIdManager().GetIDData<ElementaryStream>(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<u32> auInfo_ptr, vm::ptr<u32> auSpecificInfo_ptr)
|
||||
s32 cellDmuxGetAu(u32 esHandle, vm::ptr<u32> auInfo, vm::ptr<u32> 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<ElementaryStream> es;
|
||||
if (!Emu.GetIdManager().GetIDData(esHandle, es))
|
||||
const auto es = Emu.GetIdManager().GetIDData<ElementaryStream>(esHandle);
|
||||
|
||||
if (!es)
|
||||
{
|
||||
return CELL_DMUX_ERROR_ARG;
|
||||
}
|
||||
|
@ -1078,18 +1077,18 @@ int cellDmuxGetAu(u32 esHandle, vm::ptr<u32> auInfo_ptr, vm::ptr<u32> 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<u32> auInfo_ptr, vm::ptr<u32> auSpecificInfo_ptr)
|
||||
s32 cellDmuxPeekAu(u32 esHandle, vm::ptr<u32> auInfo, vm::ptr<u32> 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<ElementaryStream> es;
|
||||
if (!Emu.GetIdManager().GetIDData(esHandle, es))
|
||||
const auto es = Emu.GetIdManager().GetIDData<ElementaryStream>(esHandle);
|
||||
|
||||
if (!es)
|
||||
{
|
||||
return CELL_DMUX_ERROR_ARG;
|
||||
}
|
||||
|
@ -1101,18 +1100,18 @@ int cellDmuxPeekAu(u32 esHandle, vm::ptr<u32> auInfo_ptr, vm::ptr<u32> 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<u32> auInfoEx_ptr, vm::ptr<u32> auSpecificInfo_ptr)
|
||||
s32 cellDmuxGetAuEx(u32 esHandle, vm::ptr<u32> auInfoEx, vm::ptr<u32> 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<ElementaryStream> es;
|
||||
if (!Emu.GetIdManager().GetIDData(esHandle, es))
|
||||
const auto es = Emu.GetIdManager().GetIDData<ElementaryStream>(esHandle);
|
||||
|
||||
if (!es)
|
||||
{
|
||||
return CELL_DMUX_ERROR_ARG;
|
||||
}
|
||||
|
@ -1124,18 +1123,18 @@ int cellDmuxGetAuEx(u32 esHandle, vm::ptr<u32> auInfoEx_ptr, vm::ptr<u32> 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<u32> auInfoEx_ptr, vm::ptr<u32> auSpecificInfo_ptr)
|
||||
s32 cellDmuxPeekAuEx(u32 esHandle, vm::ptr<u32> auInfoEx, vm::ptr<u32> 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<ElementaryStream> es;
|
||||
if (!Emu.GetIdManager().GetIDData(esHandle, es))
|
||||
const auto es = Emu.GetIdManager().GetIDData<ElementaryStream>(esHandle);
|
||||
|
||||
if (!es)
|
||||
{
|
||||
return CELL_DMUX_ERROR_ARG;
|
||||
}
|
||||
|
@ -1147,17 +1146,18 @@ int cellDmuxPeekAuEx(u32 esHandle, vm::ptr<u32> auInfoEx_ptr, vm::ptr<u32> 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<ElementaryStream> es;
|
||||
if (!Emu.GetIdManager().GetIDData(esHandle, es))
|
||||
const auto es = Emu.GetIdManager().GetIDData<ElementaryStream>(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<ElementaryStream> es;
|
||||
if (!Emu.GetIdManager().GetIDData(esHandle, es))
|
||||
const auto es = Emu.GetIdManager().GetIDData<ElementaryStream>(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);
|
||||
|
|
|
@ -169,7 +169,7 @@ struct CellDmuxPamfSpecificInfo
|
|||
struct CellDmuxType2
|
||||
{
|
||||
be_t<CellDmuxStreamType> streamType;
|
||||
be_t<u32> streamSpecificInfo_addr;
|
||||
be_t<u32> streamSpecificInfo;
|
||||
};
|
||||
|
||||
struct CellDmuxResource
|
||||
|
|
|
@ -84,7 +84,7 @@ vm::ptr<void> cellFiberPpuSelf()
|
|||
cellFiber.Log("cellFiberPpuSelf() -> nullptr"); // TODO
|
||||
|
||||
// returns fiber structure (zero for simple PPU thread)
|
||||
return vm::ptr<void>::make(0);
|
||||
return vm::null;
|
||||
}
|
||||
|
||||
int cellFiberPpuSendSignal()
|
||||
|
|
|
@ -210,37 +210,41 @@ s32 cellFsGetDirectoryEntries(u32 fd, vm::ptr<CellFsDirectoryEntry> 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<vfsDirBase> directory;
|
||||
const auto directory = Emu.GetIdManager().GetIDData<vfsDirBase>(fd);
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(fd, directory))
|
||||
if (!directory)
|
||||
{
|
||||
return CELL_FS_EBADF;
|
||||
}
|
||||
|
||||
const DirEntryInfo* info = directory->Read();
|
||||
if (info)
|
||||
u32 count = 0;
|
||||
|
||||
entries_size /= sizeof(CellFsDirectoryEntry);
|
||||
|
||||
for (; count < entries_size; count++)
|
||||
{
|
||||
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;
|
||||
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->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->entry_name.d_type = (info->flags & DirEntry_TypeFile) ? CELL_FS_TYPE_REGULAR : CELL_FS_TYPE_DIRECTORY;
|
||||
entries->entry_name.d_namlen = u8(std::min<size_t>(info->name.length(), CELL_FS_MAX_FS_FILE_NAME_LENGTH));
|
||||
strcpy_trunc(entries->entry_name.d_name, info->name);
|
||||
*data_count = 1;
|
||||
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<size_t>(info->name.length(), CELL_FS_MAX_FS_FILE_NAME_LENGTH));
|
||||
strcpy_trunc(entries[count].entry_name.d_name, info->name);
|
||||
}
|
||||
else
|
||||
{
|
||||
*data_count = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*data_count = count;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
@ -251,9 +255,9 @@ s32 cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr<void> buf, u64 buffer_size,
|
|||
|
||||
// TODO: use single sys_fs_fcntl syscall
|
||||
|
||||
std::shared_ptr<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(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<const void> buf, u64 data_
|
|||
|
||||
// TODO: use single sys_fs_fcntl syscall
|
||||
|
||||
std::shared_ptr<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(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<const CellFsRingBuffer> ringbuf)
|
|||
return CELL_FS_EINVAL;
|
||||
}
|
||||
|
||||
std::shared_ptr<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(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<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(fd);
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
if (!file)
|
||||
{
|
||||
return CELL_FS_EBADF; // ???
|
||||
}
|
||||
|
@ -387,9 +391,9 @@ s32 cellFsStReadGetRingBuf(u32 fd, vm::ptr<CellFsRingBuffer> ringbuf)
|
|||
{
|
||||
cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, ringbuf=*0x%x)", fd, ringbuf);
|
||||
|
||||
std::shared_ptr<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(fd);
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
if (!file)
|
||||
{
|
||||
return CELL_FS_EBADF;
|
||||
}
|
||||
|
@ -411,9 +415,9 @@ s32 cellFsStReadGetStatus(u32 fd, vm::ptr<u64> status)
|
|||
{
|
||||
cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, status=*0x%x)", fd, status);
|
||||
|
||||
std::shared_ptr<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(fd);
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
if (!file)
|
||||
{
|
||||
return CELL_FS_EBADF;
|
||||
}
|
||||
|
@ -445,9 +449,9 @@ s32 cellFsStReadGetRegid(u32 fd, vm::ptr<u64> regid)
|
|||
{
|
||||
cellFs.Warning("cellFsStReadGetRingBuf(fd=0x%x, regid=*0x%x)", fd, regid);
|
||||
|
||||
std::shared_ptr<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(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<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(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<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(fd);
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
if (!file)
|
||||
{
|
||||
return CELL_FS_EBADF;
|
||||
}
|
||||
|
@ -579,9 +583,9 @@ s32 cellFsStRead(u32 fd, vm::ptr<u8> buf, u64 size, vm::ptr<u64> rsize)
|
|||
{
|
||||
cellFs.Warning("cellFsStRead(fd=0x%x, buf=*0x%x, size=0x%llx, rsize=*0x%x)", fd, buf, size, rsize);
|
||||
|
||||
std::shared_ptr<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(fd);
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
if (!file)
|
||||
{
|
||||
return CELL_FS_EBADF;
|
||||
}
|
||||
|
@ -613,9 +617,9 @@ s32 cellFsStReadGetCurrentAddr(u32 fd, vm::ptr<u32> addr, vm::ptr<u64> size)
|
|||
{
|
||||
cellFs.Warning("cellFsStReadGetCurrentAddr(fd=0x%x, addr=*0x%x, size=*0x%x)", fd, addr, size);
|
||||
|
||||
std::shared_ptr<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(fd);
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
if (!file)
|
||||
{
|
||||
return CELL_FS_EBADF;
|
||||
}
|
||||
|
@ -646,9 +650,9 @@ s32 cellFsStReadPutCurrentAddr(u32 fd, vm::ptr<u8> addr, u64 size)
|
|||
{
|
||||
cellFs.Warning("cellFsStReadPutCurrentAddr(fd=0x%x, addr=*0x%x, size=0x%llx)", fd, addr, size);
|
||||
|
||||
std::shared_ptr<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(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<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(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<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(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<vfsFileBase> packed_stream(Emu.GetVFS().OpenFile(packed_file, vfsRead));
|
||||
std::shared_ptr<vfsFileBase> unpacked_stream(Emu.GetVFS().OpenFile(unpacked_file, vfsWrite));
|
||||
std::shared_ptr<vfsFileBase> 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<CellFsAio> aio, bool write, s32 xid, fs_aio_cb_t func)
|
|||
s32 error = CELL_OK;
|
||||
u64 result = 0;
|
||||
|
||||
std::shared_ptr<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(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<fs_file_t> file;
|
||||
const auto file = Emu.GetIdManager().GetIDData<fs_file_t>(fd);
|
||||
|
||||
if (!Emu.GetIdManager().GetIDData(fd, file))
|
||||
if (!file)
|
||||
{
|
||||
CELL_FS_EBADF;
|
||||
return CELL_FS_EBADF;
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
|
|
|
@ -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<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGameContentSize> size, vm::ptr<char[CELL_GAME_DIRNAME_SIZE]> dirName)
|
||||
s32 cellHddGameCheck(PPUThread& CPU, u32 version, vm::ptr<const char> dirName, u32 errDialog, vm::ptr<CellHddGameStatCallback> 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<CellHddGameSystemFileParam> param;
|
||||
vm::var<CellHddGameCBResult> result;
|
||||
vm::var<CellHddGameStatGet> get;
|
||||
vm::var<CellHddGameStatSet> 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<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGameContentSize> size, vm::ptr<char[CELL_GAME_DIRNAME_SIZE]> 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<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGa
|
|||
}
|
||||
|
||||
vfsFile f("/app_home/../PARAM.SFO");
|
||||
if (!f.IsOpened())
|
||||
{
|
||||
cellGame.Error("cellGameBootCheck(): 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("cellGameBootCheck(): CELL_GAME_ERROR_ACCESS_ERROR (cannot read PARAM.SFO)");
|
||||
return CELL_GAME_ERROR_ACCESS_ERROR;
|
||||
|
@ -84,15 +151,9 @@ int cellGameBootCheck(vm::ptr<u32> type, vm::ptr<u32> attributes, vm::ptr<CellGa
|
|||
return CELL_GAME_RET_OK;
|
||||
}
|
||||
|
||||
int cellGamePatchCheck(vm::ptr<CellGameContentSize> size, u32 reserved_addr)
|
||||
s32 cellGamePatchCheck(vm::ptr<CellGameContentSize> size, vm::ptr<void> 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<CellGameContentSize> 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<CellGameContentSize> size, u32 reserved_addr)
|
|||
return CELL_GAME_RET_OK;
|
||||
}
|
||||
|
||||
int cellGameDataCheck(u32 type, vm::ptr<const char> dirName, vm::ptr<CellGameContentSize> size)
|
||||
s32 cellGameDataCheck(u32 type, vm::ptr<const char> dirName, vm::ptr<CellGameContentSize> 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<const char> dirName, vm::ptr<CellGameCon
|
|||
return CELL_GAME_RET_OK;
|
||||
}
|
||||
|
||||
int cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPath, vm::ptr<char[CELL_GAME_PATH_MAX]> usrdirPath)
|
||||
s32 cellGameContentPermit(vm::ptr<char[CELL_GAME_PATH_MAX]> contentInfoPath, vm::ptr<char[CELL_GAME_PATH_MAX]> 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<char[CELL_GAME_PATH_MAX]> contentInfoPath, vm:
|
|||
return CELL_GAME_RET_OK;
|
||||
}
|
||||
|
||||
int cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr<const char> dirName, u32 errDialog,
|
||||
vm::ptr<void(vm::ptr<CellGameDataCBResult> cbResult, vm::ptr<CellGameDataStatGet> get, vm::ptr<CellGameDataStatSet> set)> funcStat, u32 container)
|
||||
s32 cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr<const char> dirName, u32 errDialog, vm::ptr<CellGameDataStatCallback> 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<const char> 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<const char> 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<const char> dirName, u32 errDialog,
|
||||
vm::ptr<void(vm::ptr<CellGameDataCBResult> cbResult, vm::ptr<CellGameDataStatGet> get, vm::ptr<CellGameDataStatSet> set)> funcStat, u32 container)
|
||||
s32 cellGameDataCheckCreate(PPUThread& CPU, u32 version, vm::ptr<const char> dirName, u32 errDialog, vm::ptr<CellGameDataStatCallback> 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<CellGameSetInitParams> init, vm::ptr<char> tmp_contentInfoPath, vm::ptr<char> tmp_usrdirPath)
|
||||
s32 cellGameCreateGameData(vm::ptr<CellGameSetInitParams> init, vm::ptr<char[CELL_GAME_PATH_MAX]> tmp_contentInfoPath, vm::ptr<char[CELL_GAME_PATH_MAX]> 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<u32> value)
|
||||
s32 cellGameGetParamInt(u32 id, vm::ptr<u32> 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<u32> value)
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellGameGetParamString(u32 id, vm::ptr<char> buf, u32 bufsize)
|
||||
s32 cellGameGetParamString(u32 id, vm::ptr<char> 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<char> 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<const char> dirName)
|
||||
s32 cellGameContentErrorDialog(s32 type, s32 errNeedSizeKB, vm::ptr<const char> 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<const char>
|
|||
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);
|
||||
}
|
||||
|
|
|
@ -200,3 +200,92 @@ struct CellGameDataStatSet
|
|||
vm::bptr<CellGameDataSystemFileParam> setParam;
|
||||
be_t<u32> reserved;
|
||||
};
|
||||
|
||||
typedef void(CellGameDataStatCallback)(vm::ptr<CellGameDataCBResult> cbResult, vm::ptr<CellGameDataStatGet> get, vm::ptr<CellGameDataStatSet> 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<u32> attribute;
|
||||
be_t<u32> parentalLevel;
|
||||
be_t<u32> resolution;
|
||||
be_t<u32> soundFormat;
|
||||
char reserved2[256];
|
||||
};
|
||||
|
||||
struct CellHddGameCBResult
|
||||
{
|
||||
be_t<u32> result;
|
||||
be_t<s32> errNeedSizeKB;
|
||||
vm::bptr<char> invalidMsg;
|
||||
vm::bptr<void> reserved;
|
||||
};
|
||||
|
||||
struct CellHddGameStatGet
|
||||
{
|
||||
be_t<s32> hddFreeSizeKB;
|
||||
be_t<u32> isNewData;
|
||||
char contentInfoPath[CELL_HDDGAME_PATH_MAX];
|
||||
char hddGamePath[CELL_HDDGAME_PATH_MAX];
|
||||
char reserved0[2];
|
||||
be_t<s64> atime;
|
||||
be_t<s64> mtime;
|
||||
be_t<s64> ctime;
|
||||
CellHddGameSystemFileParam getParam;
|
||||
be_t<s32> sizeKB;
|
||||
be_t<s32> sysSizeKB;
|
||||
char reserved1[68];
|
||||
};
|
||||
|
||||
struct CellHddGameStatSet
|
||||
{
|
||||
vm::bptr<CellHddGameSystemFileParam> setParam;
|
||||
vm::bptr<void> reserved;
|
||||
};
|
||||
|
||||
typedef void(CellHddGameStatCallback)(vm::ptr<CellHddGameCBResult> cbResult, vm::ptr<CellHddGameStatGet> get, vm::ptr<CellHddGameStatSet> set);
|
||||
|
|
|
@ -86,7 +86,7 @@ vm::ptr<CellGcmReportData> 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<CellGcmReportData>::make(0);
|
||||
return vm::null;
|
||||
}
|
||||
return vm::ptr<CellGcmReportData>::make((u32)Memory.RSXFBMem.GetStartAddr() + index * 0x10);
|
||||
}
|
||||
|
@ -94,14 +94,14 @@ vm::ptr<CellGcmReportData> 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<CellGcmReportData>::make(0);
|
||||
return vm::null;
|
||||
}
|
||||
// TODO: It seems m_report_main_addr is not initialized
|
||||
return vm::ptr<CellGcmReportData>::make(Emu.GetGSManager().GetRender().m_report_main_addr + index * 0x10);
|
||||
}
|
||||
|
||||
cellGcmSys.Error("cellGcmGetReportDataAddressLocation: Wrong location (%d)", location);
|
||||
return vm::ptr<CellGcmReportData>::make(0);
|
||||
return vm::null;
|
||||
}
|
||||
|
||||
u64 cellGcmGetTimeStamp(u32 index)
|
||||
|
|
|
@ -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<u32> subHandle, vm::ptr<CellGifDecSrc> src, vm::ptr<CellGifDecOpnInfo> openInfo)
|
||||
s32 cellGifDecOpen(u32 mainHandle, vm::ptr<u32> subHandle, vm::ptr<CellGifDecSrc> src, vm::ptr<CellGifDecOpnInfo> 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<CellGifDecSubHandle> current_subHandle(new CellGifDecSubHandle);
|
||||
current_subHandle->fd = 0;
|
||||
|
@ -60,14 +62,16 @@ int cellGifDecOpen(u32 mainHandle, vm::ptr<u32> subHandle, vm::ptr<CellGifDecSrc
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellGifDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr<CellGifDecInfo> info)
|
||||
s32 cellGifDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr<CellGifDecInfo> 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<CellGifDecSubHandle> subHandle_data;
|
||||
if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data))
|
||||
const auto subHandle_data = Emu.GetIdManager().GetIDData<CellGifDecSubHandle>(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<CellGifDecInfo>
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellGifDecSetParameter(u32 mainHandle, u32 subHandle, vm::ptr<const CellGifDecInParam> inParam, vm::ptr<CellGifDecOutParam> outParam)
|
||||
s32 cellGifDecSetParameter(u32 mainHandle, u32 subHandle, vm::ptr<const CellGifDecInParam> inParam, vm::ptr<CellGifDecOutParam> 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<CellGifDecSubHandle> subHandle_data;
|
||||
if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data))
|
||||
const auto subHandle_data = Emu.GetIdManager().GetIDData<CellGifDecSubHandle>(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<const CellGifD
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr<u8> data, vm::ptr<const CellGifDecDataCtrlParam> dataCtrlParam, vm::ptr<CellGifDecDataOutInfo> dataOutInfo)
|
||||
s32 cellGifDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr<u8> data, vm::ptr<const CellGifDecDataCtrlParam> dataCtrlParam, vm::ptr<CellGifDecDataOutInfo> 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<CellGifDecSubHandle> subHandle_data;
|
||||
if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data))
|
||||
const auto subHandle_data = Emu.GetIdManager().GetIDData<CellGifDecSubHandle>(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<u8> 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<CellGifDecSubHandle> subHandle_data;
|
||||
if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data))
|
||||
const auto subHandle_data = Emu.GetIdManager().GetIDData<CellGifDecSubHandle>(subHandle);
|
||||
|
||||
if (!subHandle_data)
|
||||
{
|
||||
return CELL_GIFDEC_ERROR_FATAL;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().RemoveID<fs_file_t>(subHandle_data->fd);
|
||||
Emu.GetIdManager().RemoveID<CellGifDecSubHandle>(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;
|
||||
|
|
|
@ -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<u32> subHandle, vm::ptr<CellJpgDecSrc> src, vm::ptr<CellJpgDecOpnInfo> openInfo)
|
||||
s32 cellJpgDecOpen(u32 mainHandle, vm::ptr<u32> subHandle, vm::ptr<CellJpgDecSrc> src, vm::ptr<CellJpgDecOpnInfo> 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<CellJpgDecSubHandle> current_subHandle(new CellJpgDecSubHandle);
|
||||
|
||||
|
@ -66,14 +68,16 @@ int cellJpgDecOpen(u32 mainHandle, vm::ptr<u32> subHandle, vm::ptr<CellJpgDecSrc
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellJpgDecClose(u32 mainHandle, u32 subHandle)
|
||||
s32 cellJpgDecClose(u32 mainHandle, u32 subHandle)
|
||||
{
|
||||
cellJpgDec.Warning("cellJpgDecOpen(mainHandle=0x%x, subHandle=0x%x)",
|
||||
mainHandle, subHandle);
|
||||
cellJpgDec.Warning("cellJpgDecOpen(mainHandle=0x%x, subHandle=0x%x)", mainHandle, subHandle);
|
||||
|
||||
std::shared_ptr<CellJpgDecSubHandle> subHandle_data;
|
||||
if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data))
|
||||
const auto subHandle_data = Emu.GetIdManager().GetIDData<CellJpgDecSubHandle>(subHandle);
|
||||
|
||||
if (!subHandle_data)
|
||||
{
|
||||
return CELL_JPGDEC_ERROR_FATAL;
|
||||
}
|
||||
|
||||
Emu.GetIdManager().RemoveID<fs_file_t>(subHandle_data->fd);
|
||||
Emu.GetIdManager().RemoveID<CellJpgDecSubHandle>(subHandle);
|
||||
|
@ -81,13 +85,16 @@ int cellJpgDecClose(u32 mainHandle, u32 subHandle)
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr<CellJpgDecInfo> info)
|
||||
s32 cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, vm::ptr<CellJpgDecInfo> 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<CellJpgDecSubHandle> subHandle_data;
|
||||
if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data))
|
||||
const auto subHandle_data = Emu.GetIdManager().GetIDData<CellJpgDecSubHandle>(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<CellJpgDecInfo>
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr<u8> data, vm::ptr<const CellJpgDecDataCtrlParam> dataCtrlParam, vm::ptr<CellJpgDecDataOutInfo> dataOutInfo)
|
||||
s32 cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, vm::ptr<u8> data, vm::ptr<const CellJpgDecDataCtrlParam> dataCtrlParam, vm::ptr<CellJpgDecDataOutInfo> 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<CellJpgDecSubHandle> subHandle_data;
|
||||
if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data))
|
||||
|
||||
const auto subHandle_data = Emu.GetIdManager().GetIDData<CellJpgDecSubHandle>(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<u8> data, vm::pt
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellJpgDecSetParameter(u32 mainHandle, u32 subHandle, vm::ptr<const CellJpgDecInParam> inParam, vm::ptr<CellJpgDecOutParam> outParam)
|
||||
s32 cellJpgDecSetParameter(u32 mainHandle, u32 subHandle, vm::ptr<const CellJpgDecInParam> inParam, vm::ptr<CellJpgDecOutParam> 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<CellJpgDecSubHandle> subHandle_data;
|
||||
if(!Emu.GetIdManager().GetIDData(subHandle, subHandle_data))
|
||||
const auto subHandle_data = Emu.GetIdManager().GetIDData<CellJpgDecSubHandle>(subHandle);
|
||||
|
||||
if (!subHandle_data)
|
||||
{
|
||||
return CELL_JPGDEC_ERROR_FATAL;
|
||||
}
|
||||
|
||||
CellJpgDecInfo& current_info = subHandle_data->info;
|
||||
CellJpgDecOutParam& current_outParam = subHandle_data->outParam;
|
||||
|
|
|
@ -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<MsgDialogInstance> g_msg_dialog;
|
||||
|
||||
MsgDialogInstance::MsgDialogInstance()
|
||||
: state(msgDialogNone)
|
||||
{
|
||||
msgDialogNone,
|
||||
msgDialogOpen,
|
||||
msgDialogClose,
|
||||
msgDialogAbort,
|
||||
};
|
||||
|
||||
std::atomic<MsgDialogState> 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<const char> msgString, vm::ptr<CellMsgDialogCallback> callback, u32 userData, u32 extParam)
|
||||
s32 cellMsgDialogOpen2(u32 type, vm::ptr<const char> msgString, vm::ptr<CellMsgDialogCallback> callback, vm::ptr<void> userData, vm::ptr<void> 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,28 +83,18 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr<const char> msgString, vm::ptr<CellMsgD
|
|||
}
|
||||
|
||||
MsgDialogState old = msgDialogNone;
|
||||
if (!g_msg_dialog_state.compare_exchange_strong(old, msgDialogOpen))
|
||||
if (!g_msg_dialog->state.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;
|
||||
}
|
||||
|
||||
std::string msg = msgString.get_ptr();
|
||||
|
||||
thread_t t("MsgDialog Thread", [type, msg, callback, userData, extParam]()
|
||||
{
|
||||
switch (type & CELL_MSGDIALOG_TYPE_SE_TYPE)
|
||||
{
|
||||
case CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL: LOG_WARNING(HLE, "%s", msg.c_str()); break;
|
||||
case CELL_MSGDIALOG_TYPE_SE_TYPE_ERROR: LOG_ERROR(HLE, "%s", msg.c_str()); 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
|
||||
|
@ -137,14 +103,24 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr<const char> msgString, vm::ptr<CellMsgD
|
|||
case CELL_MSGDIALOG_TYPE_SE_MUTE_ON: break;
|
||||
}
|
||||
|
||||
g_msg_dialog_status = CELL_MSGDIALOG_BUTTON_NONE;
|
||||
std::string msg = msgString.get_ptr();
|
||||
|
||||
thread_t t("MsgDialog Thread", [type, msg, callback, userData, extParam]()
|
||||
{
|
||||
switch (type & CELL_MSGDIALOG_TYPE_SE_TYPE)
|
||||
{
|
||||
case CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL: cellSysutil.Warning("%s", msg); break;
|
||||
case CELL_MSGDIALOG_TYPE_SE_TYPE_ERROR: cellSysutil.Error("%s", msg); break;
|
||||
}
|
||||
|
||||
g_msg_dialog->status = 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<const char> msgString, vm::ptr<CellMsgD
|
|||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
}
|
||||
|
||||
while (g_msg_dialog_state == msgDialogOpen || (s64)(get_system_time() - g_msg_dialog_wait_until) < 0)
|
||||
while (g_msg_dialog->state == 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<const char> msgString, vm::ptr<CellMsgD
|
|||
|
||||
CallAfter([]()
|
||||
{
|
||||
MsgDialogDestroy();
|
||||
|
||||
g_msg_dialog_state = msgDialogNone;
|
||||
g_msg_dialog->Destroy();
|
||||
g_msg_dialog->state = msgDialogNone;
|
||||
});
|
||||
});
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
s32 cellMsgDialogOpenErrorCode(u32 errorCode, vm::ptr<CellMsgDialogCallback> callback, u32 userData, u32 extParam)
|
||||
s32 cellMsgDialogOpenErrorCode(PPUThread& CPU, u32 errorCode, vm::ptr<CellMsgDialogCallback> callback, vm::ptr<void> userData, vm::ptr<void> 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<char> 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<u64>(std::max<float>(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<const char> 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);
|
||||
}
|
||||
|
|
|
@ -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<void> userData);
|
||||
|
||||
s32 cellMsgDialogOpen2(u32 type, vm::ptr<const char> msgString, vm::ptr<CellMsgDialogCallback> callback, u32 userData, u32 extParam);
|
||||
s32 cellMsgDialogOpenErrorCode(u32 errorCode, vm::ptr<CellMsgDialogCallback> callback, u32 userData, u32 extParam);
|
||||
enum MsgDialogState
|
||||
{
|
||||
msgDialogNone,
|
||||
msgDialogOpen,
|
||||
msgDialogClose,
|
||||
msgDialogAbort,
|
||||
};
|
||||
|
||||
s32 cellMsgDialogProgressBarSetMsg(u32 progressBarIndex, vm::ptr<const char> msgString);
|
||||
s32 cellMsgDialogProgressBarReset(u32 progressBarIndex);
|
||||
s32 cellMsgDialogProgressBarInc(u32 progressBarIndex, u32 delta);
|
||||
s32 cellMsgDialogClose(float delay);
|
||||
s32 cellMsgDialogAbort();
|
||||
struct MsgDialogInstance
|
||||
{
|
||||
std::atomic<MsgDialogState> 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;
|
||||
};
|
||||
|
|
|
@ -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<u32> mainHandle,
|
||||
vm::ptr<const CellPngDecThreadInParam> param,
|
||||
vm::ptr<const CellPngDecExtThreadInParam> ext = vm::ptr<const CellPngDecExtThreadInParam>::make(0))
|
||||
vm::ptr<const CellPngDecExtThreadInParam> 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<u32> subHandle,
|
||||
vm::ptr<const CellPngDecSrc> src,
|
||||
vm::ptr<CellPngDecOpnInfo> openInfo,
|
||||
vm::ptr<const CellPngDecCbCtrlStrm> cb = vm::ptr<const CellPngDecCbCtrlStrm>::make(0),
|
||||
vm::ptr<const CellPngDecOpnParam> param = vm::ptr<const CellPngDecOpnParam>::make(0))
|
||||
vm::ptr<const CellPngDecCbCtrlStrm> cb = vm::null,
|
||||
vm::ptr<const CellPngDecOpnParam> 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<CellPngDecInfo> info,
|
||||
vm::ptr<CellPngDecExtInfo> extInfo = vm::ptr<CellPngDecExtInfo>::make(0))
|
||||
vm::ptr<CellPngDecExtInfo> extInfo = vm::null)
|
||||
{
|
||||
CellPngDecInfo& current_info = stream->info;
|
||||
|
||||
|
@ -191,8 +194,8 @@ s32 pngDecSetParameter(
|
|||
CellPngDecSubHandle stream,
|
||||
vm::ptr<const CellPngDecInParam> inParam,
|
||||
vm::ptr<CellPngDecOutParam> outParam,
|
||||
vm::ptr<const CellPngDecExtInParam> extInParam = vm::ptr<const CellPngDecExtInParam>::make(0),
|
||||
vm::ptr<CellPngDecExtOutParam> extOutParam = vm::ptr<CellPngDecExtOutParam>::make(0))
|
||||
vm::ptr<const CellPngDecExtInParam> extInParam = vm::null,
|
||||
vm::ptr<CellPngDecExtOutParam> extOutParam = vm::null)
|
||||
{
|
||||
CellPngDecInfo& current_info = stream->info;
|
||||
CellPngDecOutParam& current_outParam = stream->outParam;
|
||||
|
@ -237,8 +240,8 @@ s32 pngDecodeData(
|
|||
vm::ptr<u8> data,
|
||||
vm::ptr<const CellPngDecDataCtrlParam> dataCtrlParam,
|
||||
vm::ptr<CellPngDecDataOutInfo> dataOutInfo,
|
||||
vm::ptr<const CellPngDecCbCtrlDisp> cbCtrlDisp = vm::ptr<const CellPngDecCbCtrlDisp>::make(0),
|
||||
vm::ptr<CellPngDecDispParam> dispParam = vm::ptr<CellPngDecDispParam>::make(0))
|
||||
vm::ptr<const CellPngDecCbCtrlDisp> cbCtrlDisp = vm::null,
|
||||
vm::ptr<CellPngDecDispParam> dispParam = vm::null)
|
||||
{
|
||||
dataOutInfo->status = CELL_PNGDEC_DEC_STATUS_STOP;
|
||||
|
||||
|
@ -365,8 +368,7 @@ s32 pngDecodeData(
|
|||
|
||||
s32 cellPngDecCreate(vm::ptr<u32> mainHandle, vm::ptr<const CellPngDecThreadInParam> threadInParam, vm::ptr<CellPngDecThreadOutParam> 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<const CellPngDecExtThreadInParam> extThreadInParam,
|
||||
vm::ptr<CellPngDecExtThreadOutParam> 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<const CellPngDecSrc> src,
|
||||
vm::ptr<CellPngDecOpnInfo> 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<const CellPngDecCbCtrlStrm> cbCtrlStrm,
|
||||
vm::ptr<const CellPngDecOpnParam> 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<CellPngDecInfo> 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<CellPngDecInfo> info,
|
||||
vm::ptr<CellPngDecExtInfo> 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<const CellPngDecInParam> inParam,
|
||||
vm::ptr<CellPngDecOutParam> 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<const CellPngDecExtInParam> extInParam,
|
||||
vm::ptr<CellPngDecExtOutParam> 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<const CellPngDecDataCtrlParam> dataCtrlParam,
|
||||
vm::ptr<CellPngDecDataOutInfo> 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<const CellPngDecCbCtrlDisp> cbCtrlDisp,
|
||||
vm::ptr<CellPngDecDispParam> 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);
|
||||
}
|
||||
|
|
|
@ -603,7 +603,7 @@ void cellRescExit()
|
|||
if (IsPalTemporal())
|
||||
{
|
||||
cellGcmSetSecondVFrequency(CELL_GCM_DISPLAY_FREQUENCY_DISABLE);
|
||||
cellGcmSetVBlankHandler(vm::ptr<void(u32)>::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<CellVideoOutOption>::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<void(u32)>::make(0));
|
||||
cellGcmSetFlipHandler(vm::null);
|
||||
}
|
||||
else if (IsPalDrop())
|
||||
{
|
||||
//InitLabels();
|
||||
cellGcmSetSecondVFrequency(CELL_GCM_DISPLAY_FREQUENCY_59_94HZ);
|
||||
cellGcmSetVBlankHandler(vm::ptr<void(u32)>::make(0));
|
||||
cellGcmSetVBlankHandler(vm::null);
|
||||
//cellGcmSetSecondVHandler(IntrHandler60Drop);
|
||||
cellGcmSetFlipHandler(vm::ptr<void(u32)>::make(0));
|
||||
cellGcmSetFlipHandler(vm::null);
|
||||
}
|
||||
else if (IsPal60Hsync())
|
||||
{
|
||||
cellGcmSetSecondVFrequency(CELL_GCM_DISPLAY_FREQUENCY_59_94HZ);
|
||||
cellGcmSetVBlankHandler(vm::ptr<void(u32)>::make(0));
|
||||
cellGcmSetVBlankHandler(vm::null);
|
||||
}
|
||||
|
||||
if (s_rescInternalInstance->s_applicationVBlankHandler) SetVBlankHandler(s_rescInternalInstance->s_applicationVBlankHandler);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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<s64> st_atime_;
|
||||
be_t<s64> st_mtime_;
|
||||
be_t<s64> st_ctime_;
|
||||
be_t<s64> atime;
|
||||
be_t<s64> mtime;
|
||||
be_t<s64> ctime;
|
||||
char dirName[CELL_SAVEDATA_DIRNAME_SIZE];
|
||||
};
|
||||
|
||||
struct CellSaveDataFileStat
|
||||
{
|
||||
be_t<u32> fileType;
|
||||
u8 reserved1[4];
|
||||
be_t<u64> st_size;
|
||||
be_t<s64> st_atime_;
|
||||
be_t<s64> st_mtime_;
|
||||
be_t<s64> st_ctime_;
|
||||
char reserved1[4];
|
||||
be_t<u64> size;
|
||||
be_t<s64> atime;
|
||||
be_t<s64> mtime;
|
||||
be_t<s64> 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<SaveDataEntry>& save_entries, s32 focused, vm::ptr<CellSaveDataListSet> listSet) = 0;
|
||||
};
|
||||
|
|
|
@ -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<sys_spu_image>::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<SPUThread&>(*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<sys_spu_image>::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<u32>::make(0), vm::ptr<u32>::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<CellSpursAttribute> attr, u32 revision
|
|||
|
||||
s32 cellSpursAttributeSetMemoryContainerForSpuThread(vm::ptr<CellSpursAttribute> 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<CellSpurs> spurs, u32 queue, vm::ptr<u8> po
|
|||
|
||||
s32 cellSpursAttachLv2EventQueue(vm::ptr<CellSpurs> spurs, u32 queue, vm::ptr<u8> 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<const char>::make(0),
|
||||
vm::ptr<const char>::make(0),
|
||||
vm::ptr<CellSpursShutdownCompletionEventHook>::make(0),
|
||||
vm::ptr<void>::make(0));
|
||||
vm::null,
|
||||
vm::null,
|
||||
vm::null,
|
||||
vm::null);
|
||||
}
|
||||
|
||||
s32 _cellSpursWorkloadAttributeInitialize(
|
||||
|
@ -1159,16 +1160,16 @@ s32 cellSpursAddWorkloadWithAttribute(vm::ptr<CellSpurs> spurs, const vm::ptr<u3
|
|||
return spursAddWorkload(
|
||||
spurs,
|
||||
wid,
|
||||
vm::ptr<const void>::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<const char>::make(attr->m.nameClass.addr()),
|
||||
vm::ptr<const char>::make(attr->m.nameInstance.addr()),
|
||||
vm::ptr<CellSpursShutdownCompletionEventHook>::make(attr->m.hook.addr()),
|
||||
vm::ptr<void>::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<CellSpurs> spurs, vm::ptr<CellSpursTaskset> tasks
|
|||
taskset.addr(), priority, 8 /*min_contention*/, max_contention);
|
||||
// TODO: Check return code
|
||||
|
||||
cellSpursWorkloadAttributeSetName(wkl_attr, vm::ptr<const char>::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<be_t<u32>> wid;
|
||||
cellSpursAddWorkloadWithAttribute(spurs, vm::ptr<u32>::make(wid.addr()), vm::ptr<const CellSpursWorkloadAttribute>::make(wkl_attr.addr()));
|
||||
cellSpursAddWorkloadWithAttribute(spurs, vm::ptr<u32>::make(wid.addr()), wkl_attr);
|
||||
// TODO: Check return code
|
||||
|
||||
taskset->m.wkl_flag_wait_task = 0x80;
|
||||
|
@ -2235,7 +2236,7 @@ s32 cellSpursCreateTaskset(vm::ptr<CellSpurs> spurs, vm::ptr<CellSpursTaskset> 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<const char>::make(0), 6400/*CellSpursTaskset::size*/, 0);
|
||||
return spursCreateTaskset(spurs, taskset, args, priority, maxContention, vm::null, 6400/*CellSpursTaskset::size*/, 0);
|
||||
}
|
||||
|
||||
s32 cellSpursJoinTaskset(vm::ptr<CellSpursTaskset> taskset)
|
||||
|
@ -2395,8 +2396,8 @@ s32 spursTaskStart(vm::ptr<CellSpursTaskset> taskset, u32 taskId)
|
|||
pendingReady._bit[taskId] = true;
|
||||
taskset->m.pending_ready = pendingReady;
|
||||
|
||||
cellSpursSendWorkloadSignal(vm::ptr<CellSpurs>::make((u32)taskset->m.spurs.addr()), taskset->m.wid);
|
||||
auto rc = cellSpursWakeUp(GetCurrentPPUThread(), vm::ptr<CellSpurs>::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<CellSpursTaskset> taskset, u32 taskId)
|
|||
taskset->m.signalled = signalled;
|
||||
if (shouldSignal)
|
||||
{
|
||||
cellSpursSendWorkloadSignal(vm::ptr<CellSpurs>::make((u32)taskset->m.spurs.addr()), taskset->m.wid);
|
||||
auto rc = cellSpursWakeUp(GetCurrentPPUThread(), vm::ptr<CellSpurs>::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<CellSpursTasksetAttribute2> 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<CellSpurs> spurs, vm::ptr<CellSpursTaskset2>
|
|||
|
||||
auto rc = spursCreateTaskset(spurs, vm::ptr<CellSpursTaskset>::make(taskset.addr()), attr->m.args,
|
||||
vm::ptr<const u8[8]>::make(attr.addr() + offsetof(CellSpursTasksetAttribute, m.priority)),
|
||||
attr->m.max_contention, vm::ptr<const char>::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<CellSpurs> spurs, vm::ptr<CellSpursTas
|
|||
}
|
||||
|
||||
vm::var<be_t<u64>> data;
|
||||
auto rc = cellSpursGetWorkloadData(spurs, vm::ptr<u64>::make(data.addr()), id);
|
||||
auto rc = cellSpursGetWorkloadData(spurs, data, id);
|
||||
if (rc != CELL_OK)
|
||||
{
|
||||
// Convert policy module error code to a task error code
|
||||
|
|
|
@ -289,7 +289,7 @@ s32 syncRwmInitialize(vm::ptr<CellSyncRwm> rwm, vm::ptr<void> 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<u32>::make(buffer_size);
|
||||
rwm->m_size = buffer_size;
|
||||
rwm->m_buffer = buffer;
|
||||
rwm->data.exchange({});
|
||||
|
||||
|
@ -488,9 +488,9 @@ s32 syncQueueInitialize(vm::ptr<CellSyncQueue> queue, vm::ptr<u8> 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<u32>::make(size);
|
||||
queue->m_depth = be_t<u32>::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<CellSyncLFQueue> queue, vm::ptr<u8> 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<CellSyncLFQueue> queue, s32& pointer, u32
|
|||
}
|
||||
}
|
||||
|
||||
if (s32 res = sys_event_queue_receive(GetCurrentPPUThread(), queue->m_eq_id, vm::ptr<sys_event_t>::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<CellSyncLFQueue> queue, s32& pointer, u32 i
|
|||
}
|
||||
}
|
||||
|
||||
if (s32 res = sys_event_queue_receive(GetCurrentPPUThread(), queue->m_eq_id, vm::ptr<sys_event_t>::make(0), 0))
|
||||
if (s32 res = sys_event_queue_receive(GetCurrentPPUThread(), queue->m_eq_id, vm::null, 0))
|
||||
{
|
||||
assert(!"sys_event_queue_receive() failed");
|
||||
}
|
||||
|
|
|
@ -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<CellHddGameCBResult> cbResult, vm::ptr<CellHddGameStatGet> get, vm::ptr<CellHddGameStatSet> set);
|
||||
|
||||
extern Module cellSysutil;
|
||||
|
||||
int cellSysutilGetSystemParamInt(int id, vm::ptr<u32> value)
|
||||
|
@ -688,76 +685,6 @@ int cellSysCacheMount(vm::ptr<CellSysCacheParam> param)
|
|||
return CELL_SYSCACHE_RET_OK_RELAYED;
|
||||
}
|
||||
|
||||
int cellHddGameCheck(u32 version, vm::ptr<const char> dirName, u32 errDialog, vm::ptr<CellHddGameStatCallback> 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<CellHddGameSystemFileParam> param;
|
||||
vm::var<CellHddGameCBResult> result;
|
||||
vm::var<CellHddGameStatGet> get;
|
||||
vm::var<CellHddGameStatSet> 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; 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;
|
||||
}
|
||||
|
||||
bool bgm_playback_enabled = true;
|
||||
|
||||
int cellSysutilEnableBgmPlayback()
|
||||
|
@ -835,13 +762,9 @@ int cellWebBrowserEstimate2(const vm::ptr<const CellWebBrowserConfig2> config, v
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
extern int cellGameDataCheckCreate2(PPUThread& CPU, u32 version, vm::ptr<const char> dirName, u32 errDialog,
|
||||
vm::ptr<void(vm::ptr<CellGameDataCBResult> cbResult, vm::ptr<CellGameDataStatGet> get, vm::ptr<CellGameDataStatSet> set)> funcStat, u32 container);
|
||||
|
||||
extern int cellGameDataCheckCreate(PPUThread& CPU, u32 version, vm::ptr<const char> dirName, u32 errDialog,
|
||||
vm::ptr<void(vm::ptr<CellGameDataCBResult> cbResult, vm::ptr<CellGameDataStatGet> get, vm::ptr<CellGameDataStatSet> 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);
|
||||
});
|
||||
|
|
|
@ -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<u32> attribute;
|
||||
be_t<u32> parentalLevel;
|
||||
be_t<u32> resolution;
|
||||
be_t<u32> soundFormat;
|
||||
u8 reserved2[256];
|
||||
};
|
||||
|
||||
struct CellHddGameStatGet
|
||||
{
|
||||
be_t<s32> hddFreeSizeKB;
|
||||
be_t<u32> isNewData;
|
||||
u8 contentInfoPath[CELL_HDDGAME_PATH_MAX];
|
||||
u8 hddGamePath[CELL_HDDGAME_PATH_MAX];
|
||||
u8 reserved0[2];
|
||||
be_t<u64> st_atime__;
|
||||
be_t<u64> st_mtime__;
|
||||
be_t<u64> st_ctime__;
|
||||
CellHddGameSystemFileParam getParam;
|
||||
be_t<s32> sizeKB;
|
||||
be_t<s32> sysSizeKB;
|
||||
u8 reserved1[68];
|
||||
};
|
||||
|
||||
struct CellHddGameStatSet
|
||||
{
|
||||
vm::bptr<CellHddGameSystemFileParam> setParam;
|
||||
be_t<u32> reserved_addr; // void*
|
||||
};
|
||||
|
||||
struct CellHddGameCBResult
|
||||
{
|
||||
be_t<u32> result;
|
||||
be_t<s32> errNeedSizeKB;
|
||||
be_t<u32> invalidMsg_addr; // char*
|
||||
be_t<u32> reserved_addr; // void*
|
||||
};
|
||||
|
||||
typedef s32 CellWebBrowserId;
|
||||
typedef vm::ptr<void> CellWebBrowserClientSession;
|
||||
typedef void(CellWebBrowserCallback)(s32 cb_type, CellWebBrowserClientSession, vm::ptr<void> usrdata);
|
||||
|
@ -303,4 +218,3 @@ struct CellWebBrowserConfig2
|
|||
be_t<float> resolution_factor;
|
||||
be_t<s32> magic_number_;
|
||||
};
|
||||
|
||||
|
|
|
@ -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<PPUThread*>(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<const CellVdecType> type, vm::ptr<CellVdecAttr> attr)
|
||||
s32 cellVdecQueryAttr(vm::ptr<const CellVdecType> type, vm::ptr<CellVdecAttr> 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<const CellVdecTypeEx> type, vm::ptr<CellVdecAttr> attr)
|
||||
s32 cellVdecQueryAttrEx(vm::ptr<const CellVdecTypeEx> type, vm::ptr<CellVdecAttr> 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<const CellVdecType> type, vm::ptr<const CellVdecResource> res, vm::ptr<const CellVdecCb> cb, vm::ptr<u32> handle)
|
||||
s32 cellVdecOpen(vm::ptr<const CellVdecType> type, vm::ptr<const CellVdecResource> res, vm::ptr<const CellVdecCb> cb, vm::ptr<u32> 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<const CellVdecTypeEx> type, vm::ptr<const CellVdecResourceEx> res, vm::ptr<const CellVdecCb> cb, vm::ptr<u32> handle)
|
||||
s32 cellVdecOpenEx(vm::ptr<const CellVdecTypeEx> type, vm::ptr<const CellVdecResourceEx> res, vm::ptr<const CellVdecCb> cb, vm::ptr<u32> 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<VideoDecoder> vdec;
|
||||
if (!Emu.GetIdManager().GetIDData(handle, vdec))
|
||||
const auto vdec = Emu.GetIdManager().GetIDData<VideoDecoder>(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<VideoDecoder> vdec;
|
||||
if (!Emu.GetIdManager().GetIDData(handle, vdec))
|
||||
const auto vdec = Emu.GetIdManager().GetIDData<VideoDecoder>(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<VideoDecoder> vdec;
|
||||
if (!Emu.GetIdManager().GetIDData(handle, vdec))
|
||||
const auto vdec = Emu.GetIdManager().GetIDData<VideoDecoder>(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<const CellVdecAuInfo> auInfo)
|
||||
s32 cellVdecDecodeAu(u32 handle, CellVdecDecodeMode mode, vm::ptr<const CellVdecAuInfo> 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<VideoDecoder> vdec;
|
||||
if (!Emu.GetIdManager().GetIDData(handle, vdec))
|
||||
const auto vdec = Emu.GetIdManager().GetIDData<VideoDecoder>(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<const CellVdec
|
|||
return CELL_OK;
|
||||
}
|
||||
|
||||
int cellVdecGetPicture(u32 handle, vm::ptr<const CellVdecPicFormat> format, vm::ptr<u8> outBuff)
|
||||
s32 cellVdecGetPicture(u32 handle, vm::ptr<const CellVdecPicFormat> format, vm::ptr<u8> 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<VideoDecoder> vdec;
|
||||
if (!Emu.GetIdManager().GetIDData(handle, vdec))
|
||||
const auto vdec = Emu.GetIdManager().GetIDData<VideoDecoder>(handle);
|
||||
|
||||
if (!vdec || !format)
|
||||
{
|
||||
return CELL_VDEC_ERROR_ARG;
|
||||
}
|
||||
|
@ -703,9 +706,25 @@ int cellVdecGetPicture(u32 handle, vm::ptr<const CellVdecPicFormat> 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<u8[]> 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<const CellVdecPicFormat> 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<SwsContext, void(*)(SwsContext*)> 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<u32> picItem_ptr)
|
||||
s32 _nid_a21aa896(PPUThread& CPU, u32 handle, vm::ptr<const CellVdecPicFormat2> format2, vm::ptr<u8> 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<VideoDecoder> 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<CellVdecPicFormat> 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<vm::bptr<CellVdecPicItem>> picItem)
|
||||
{
|
||||
cellVdec.Log("cellVdecGetPicItem(handle=0x%x, picItem=**0x%x)", handle, picItem);
|
||||
|
||||
const auto vdec = Emu.GetIdManager().GetIDData<VideoDecoder>(handle);
|
||||
|
||||
if (!vdec)
|
||||
{
|
||||
return CELL_VDEC_ERROR_ARG;
|
||||
}
|
||||
|
@ -746,7 +818,7 @@ int cellVdecGetPicItem(u32 handle, vm::ptr<u32> picItem_ptr)
|
|||
|
||||
AVFrame& frame = *vf.data;
|
||||
|
||||
auto info = vm::ptr<CellVdecPicItem>::make(vdec->memAddr + vdec->memBias);
|
||||
const auto info = vm::ptr<CellVdecPicItem>::make(vdec->memAddr + vdec->memBias);
|
||||
|
||||
vdec->memBias += 512;
|
||||
if (vdec->memBias + 512 > vdec->memSize)
|
||||
|
@ -867,16 +939,17 @@ int cellVdecGetPicItem(u32 handle, vm::ptr<u32> 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<VideoDecoder> vdec;
|
||||
if (!Emu.GetIdManager().GetIDData(handle, vdec))
|
||||
const auto vdec = Emu.GetIdManager().GetIDData<VideoDecoder>(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);
|
||||
});
|
||||
|
|
|
@ -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<CellVdecPicFormatType> formatType;
|
||||
be_t<CellVdecColorMatrixType> colorMatrixType;
|
||||
be_t<u32> unk0;
|
||||
u8 alpha;
|
||||
be_t<u32> unk1;
|
||||
};
|
||||
|
||||
typedef u32(CellVdecCbMsg)(u32 handle, CellVdecMsgType msgType, s32 msgData, u32 cbArg);
|
||||
|
||||
// Callback Function Information
|
||||
|
@ -349,8 +358,6 @@ struct CellVdecAvcInfo
|
|||
be_t<u64> reserved[2];
|
||||
};
|
||||
|
||||
const int sz = sizeof(CellVdecAvcInfo);
|
||||
|
||||
// DIVX Profile
|
||||
enum DIVX_level : u8
|
||||
{
|
||||
|
|
|
@ -13,9 +13,9 @@ extern "C"
|
|||
|
||||
extern Module cellVpost;
|
||||
|
||||
int cellVpostQueryAttr(vm::ptr<const CellVpostCfgParam> cfgParam, vm::ptr<CellVpostAttr> attr)
|
||||
s32 cellVpostQueryAttr(vm::ptr<const CellVpostCfgParam> cfgParam, vm::ptr<CellVpostAttr> 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<const CellVpostCfgParam> cfgParam, vm::ptr<const CellVpostResource> resource, vm::ptr<u32> handle)
|
||||
s32 cellVpostOpen(vm::ptr<const CellVpostCfgParam> cfgParam, vm::ptr<const CellVpostResource> resource, vm::ptr<u32> 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<const CellVpostCfgParam> cfgParam, vm::ptr<const CellVpostResourceEx> resource, vm::ptr<u32> handle)
|
||||
s32 cellVpostOpenEx(vm::ptr<const CellVpostCfgParam> cfgParam, vm::ptr<const CellVpostResourceEx> resource, vm::ptr<u32> 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<VpostInstance> vpost;
|
||||
if (!Emu.GetIdManager().GetIDData(handle, vpost))
|
||||
const auto vpost = Emu.GetIdManager().GetIDData<VpostInstance>(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<const u8> inPicBuff, vm::ptr<const CellVpostCtrlParam> ctrlParam,
|
||||
vm::ptr<u8> outPicBuff, vm::ptr<CellVpostPictureInfo> picInfo)
|
||||
s32 cellVpostExec(u32 handle, vm::ptr<const u8> inPicBuff, vm::ptr<const CellVpostCtrlParam> ctrlParam, vm::ptr<u8> outPicBuff, vm::ptr<CellVpostPictureInfo> 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<VpostInstance> vpost;
|
||||
if (!Emu.GetIdManager().GetIDData(handle, vpost))
|
||||
const auto vpost = Emu.GetIdManager().GetIDData<VpostInstance>(handle);
|
||||
|
||||
if (!vpost)
|
||||
{
|
||||
return CELL_VPOST_ERROR_E_ARG_HDL_INVALID;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ std::vector<SSPlayer> ssp;
|
|||
|
||||
int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, vm::ptr<float> 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<float> 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<float> 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<std::mutex> 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<std::mutex> lock(mixer_mutex);
|
||||
|
@ -165,7 +165,7 @@ int cellSSPlayerCreate(vm::ptr<u32> handle, vm::ptr<CellSSPlayerConfig> config)
|
|||
|
||||
int cellSSPlayerRemove(u32 handle)
|
||||
{
|
||||
libmixer.Warning("cellSSPlayerRemove(handle=%d)", handle);
|
||||
libmixer.Warning("cellSSPlayerRemove(handle=0x%x)", handle);
|
||||
|
||||
std::lock_guard<std::mutex> lock(mixer_mutex);
|
||||
|
||||
|
@ -184,7 +184,7 @@ int cellSSPlayerRemove(u32 handle)
|
|||
|
||||
int cellSSPlayerSetWave(u32 handle, vm::ptr<CellSSPlayerWaveParam> waveInfo, vm::ptr<CellSSPlayerCommonParam> 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<std::mutex> lock(mixer_mutex);
|
||||
|
@ -208,7 +208,7 @@ int cellSSPlayerSetWave(u32 handle, vm::ptr<CellSSPlayerWaveParam> waveInfo, vm:
|
|||
|
||||
int cellSSPlayerPlay(u32 handle, vm::ptr<CellSSPlayerRuntimeInfo> 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<std::mutex> lock(mixer_mutex);
|
||||
|
||||
|
@ -232,7 +232,7 @@ int cellSSPlayerPlay(u32 handle, vm::ptr<CellSSPlayerRuntimeInfo> 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<std::mutex> lock(mixer_mutex);
|
||||
|
||||
|
@ -251,7 +251,7 @@ int cellSSPlayerStop(u32 handle, u32 mode)
|
|||
|
||||
int cellSSPlayerSetParam(u32 handle, vm::ptr<CellSSPlayerRuntimeInfo> 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<std::mutex> lock(mixer_mutex);
|
||||
|
||||
|
@ -274,7 +274,7 @@ int cellSSPlayerSetParam(u32 handle, vm::ptr<CellSSPlayerRuntimeInfo> info)
|
|||
|
||||
int cellSSPlayerGetState(u32 handle)
|
||||
{
|
||||
libmixer.Warning("cellSSPlayerGetState(handle=%d)", handle);
|
||||
libmixer.Warning("cellSSPlayerGetState(handle=0x%x)", handle);
|
||||
|
||||
std::lock_guard<std::mutex> lock(mixer_mutex);
|
||||
|
||||
|
@ -319,8 +319,7 @@ int cellSurMixerCreate(vm::ptr<const CellSurMixerConfig> 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);
|
||||
|
||||
|
|
|
@ -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<const char> 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;
|
||||
|
|
|
@ -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<u32> handle)
|
|||
|
||||
int sceNpTrophyRegisterContext(u32 context, u32 handle, vm::ptr<SceNpTrophyStatusCallback> 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<u64> 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<SceNpTrophyGameDetails> details, vm::ptr<SceNpTrophyGameData> 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<u32> 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<SceNpTrophyFlagArray> flags, vm::ptr<u32> 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<SceNpTrophyDetails> details, vm::ptr<SceNpTrophyData> 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)
|
||||
|
|
|
@ -117,7 +117,7 @@ s32 sys_lwmutex_create(vm::ptr<sys_lwmutex_t> lwmutex, vm::ptr<sys_lwmutex_attri
|
|||
lwmutex->lock_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<sys_lwcond_t> lwcond)
|
|||
|
||||
s32 sys_lwcond_signal_to(PPUThread& CPU, vm::ptr<sys_lwcond_t> 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<sys_lwmutex_t> lwmutex = lwcond->lwmutex;
|
||||
|
||||
|
@ -579,7 +579,7 @@ s32 sys_lwcond_wait(PPUThread& CPU, vm::ptr<sys_lwcond_t> 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<be_t<u64>>(CPU));
|
||||
}
|
||||
|
@ -982,6 +982,13 @@ vm::ptr<char> _sys_strcat(vm::ptr<char> dest, vm::ptr<const char> source)
|
|||
return dest;
|
||||
}
|
||||
|
||||
vm::ptr<const char> _sys_strchr(vm::ptr<const char> str, s32 ch)
|
||||
{
|
||||
sysPrxForUser.Log("_sys_strchr(str=*0x%x, ch=0x%x)", str, ch);
|
||||
|
||||
return vm::ptr<const char>::make(vm::get_addr(strchr(str.get_ptr(), ch)));
|
||||
}
|
||||
|
||||
vm::ptr<char> _sys_strncat(vm::ptr<char> dest, vm::ptr<const char> source, u32 len)
|
||||
{
|
||||
sysPrxForUser.Log("_sys_strncat(dest=*0x%x, source=*0x%x, len=%d)", dest, source, len);
|
||||
|
@ -1012,7 +1019,7 @@ vm::ptr<char> _sys_strncpy(vm::ptr<char> dest, vm::ptr<const char> source, u32 l
|
|||
|
||||
if (!dest || !source)
|
||||
{
|
||||
return vm::ptr<char>::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<const char> 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<atomic_t<u32>> lock)
|
|||
g_sys_spinlock_wm.notify(lock.addr());
|
||||
}
|
||||
|
||||
s32 sys_ppu_thread_create(PPUThread& CPU, vm::ptr<u64> thread_id, u32 entry, u64 arg, s32 prio, u32 stacksize, u64 flags, vm::ptr<const char> 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<ppu_thread_param_t> 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<u32>(*thread_id));
|
||||
}
|
||||
|
||||
s32 sys_ppu_thread_get_id(PPUThread& CPU, vm::ptr<u64> 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<atomic_t<u32>> once_ctrl, vm::ptr<void()> init)
|
||||
{
|
||||
sysPrxForUser.Warning("sys_ppu_thread_once(once_ctrl=*0x%x, init=*0x%x)", once_ctrl, init);
|
||||
|
||||
std::lock_guard<std::mutex> lock(g_once_mutex);
|
||||
|
||||
if (once_ctrl->compare_and_swap_test(be_t<u32>::make(SYS_PPU_THREAD_ONCE_INIT), be_t<u32>::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);
|
||||
|
|
|
@ -19,7 +19,7 @@ extern "C"
|
|||
|
||||
extern Module sys_net;
|
||||
|
||||
vm::ptr<s32> g_lastError = vm::ptr<s32>::make(0);
|
||||
vm::ptr<s32> 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<s32>::make(0);
|
||||
g_lastError = vm::null;
|
||||
#ifdef _WIN32
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
|
|
@ -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<semaphore_t> 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<sleep_queue_t> 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<lwcond_t> lw;
|
||||
if (Emu.GetIdManager().GetIDData(id, lw))
|
||||
{
|
||||
return std::string((const char*)&lw->name, 8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TYPE_MUTEX:
|
||||
{
|
||||
std::shared_ptr<mutex_t> mutex;
|
||||
if (Emu.GetIdManager().GetIDData(id, mutex))
|
||||
{
|
||||
return std::string((const char*)&mutex->name, 8);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case TYPE_COND:
|
||||
{
|
||||
std::shared_ptr<cond_t> 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";
|
||||
}
|
|
@ -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()
|
||||
{
|
||||
}
|
||||
};
|
|
@ -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;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue