Merge pull request #1062 from Nekotekina/master

SPURecompiler improved
This commit is contained in:
Hykem 2015-04-25 19:32:47 +01:00
commit d18d19870f
159 changed files with 5702 additions and 5951 deletions

View file

@ -2,7 +2,7 @@
#include "rpcs3/Ini.h"
#include "AutoPause.h"
#include "Utilities/Log.h"
#include "Utilities/rFile.h"
#include "Utilities/File.h"
#include "Emu/System.h"
using namespace Debug;
@ -44,23 +44,22 @@ AutoPause::~AutoPause(void)
//This would be able to create in a GUI window.
void AutoPause::Reload(void)
{
if (rExists("pause.bin"))
if (fs::is_file("pause.bin"))
{
m_pause_function.clear();
m_pause_function.reserve(16);
m_pause_syscall.clear();
m_pause_syscall.reserve(16);
rFile list;
list.Open("pause.bin", rFile::read);
fs::file list("pause.bin");
//System calls ID and Function calls ID are all u32 iirc.
u32 num;
size_t fmax = list.Length();
size_t fmax = list.size();
size_t fcur = 0;
list.Seek(0);
list.seek(0);
while (fcur <= fmax - sizeof(u32))
{
list.Read(&num, sizeof(u32));
list.read(&num, sizeof(u32));
fcur += sizeof(u32);
if (num == 0xFFFFFFFF) break;
@ -77,12 +76,8 @@ void AutoPause::Reload(void)
LOG_WARNING(HLE, "Auto Pause: Find Function Call ID 0x%x", num);
}
}
list.Close();
}
else
{
LOG_WARNING(HLE, "No pause.bin found, Auto Pause will not work.");
}
m_pause_syscall_enable = Ini.DBGAutoPauseSystemCall.GetValue();
m_pause_function_enable = Ini.DBGAutoPauseFunctionCall.GetValue();
initialized = true;
@ -125,4 +120,4 @@ void AutoPause::TryPause(u32 code) {
}
}
}
}
}

View file

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

View file

@ -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})
Log::LogMessage msg{ type, sev, std::move(text) };
Log::LogManager::getInstance().log(msg);
if (g_log_manager)
{
// another msvc bug makes this not work, uncomment this when it's fixed
//g_log_manager->log({logType, severity, text});
Log::LogMessage msg{ type, sev, std::move(text) };
g_log_manager->log(msg);
}
else
{
rMessageBox(text,
sev == Notice ? "Notice" :
sev == Warning ? "Warning" :
sev == Success ? "Success" :
sev == Error ? "Error" : "Unknown",
sev == Notice ? rICON_INFORMATION :
sev == Warning ? rICON_EXCLAMATION :
sev == Error ? rICON_ERROR : rICON_INFORMATION);
}
}

View file

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

View file

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

View file

@ -1,7 +1,5 @@
#pragma once
static std::thread::id main_thread;
class NamedThreadBase
{
std::string m_name;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -33,4 +33,4 @@ typedef struct
unsigned long long file_size;
} EDAT_HEADER;
int DecryptEDAT(const std::string& input_file_name, const std::string& output_file_name, int mode, const std::string& rap_file_name, unsigned char *custom_klic, bool verbose);
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);

View file

@ -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));
{
out.write(buf, BUF_SIZE - (size - entry.file_size));
}
else
out.Write(buf, BUF_SIZE);
{
out.write(buf, BUF_SIZE);
}
}
out.Close();
return true;
}
else
{
LOG_ERROR(LOADER, "PKG Loader: Could not create file: %s", path.c_str());
LOG_ERROR(LOADER, "PKG Loader: Could not create file '%s'", path);
return false;
}
}
case PKG_FILE_ENTRY_FOLDER:
{
auto path = dir + std::string(buf, entry.name_size);
if (!rExists(path) && !rMkdir(path))
const std::string path = dir + std::string(buf, entry.name_size);
if (!fs::is_dir(path) && !fs::create_dir(path))
{
LOG_ERROR(LOADER, "PKG Loader: Could not create directory: %s", path.c_str());
LOG_ERROR(LOADER, "PKG Loader: Could not create directory: %s", path);
return false;
}
@ -220,41 +243,44 @@ bool UnpackEntry(rFile& dec_pkg_f, const PKGEntry& entry, std::string dir)
}
}
int Unpack(rFile& pkg_f, std::string src, std::string dst)
int Unpack(const fs::file& pkg_f, std::string src, std::string dst)
{
PKGHeader* m_header = (PKGHeader*) malloc (sizeof(PKGHeader));
rFile dec_pkg_f;
// TODO: This shouldn't use current dir
std::string decryptedFile = "./dev_hdd1/" + src + ".dec";
dec_pkg_f.Create(decryptedFile, true);
fs::file dec_pkg_f(decryptedFile, o_read | o_write | o_create | o_trunc);
if (Decrypt(pkg_f, dec_pkg_f, m_header) < 0)
{
return -1;
dec_pkg_f.Close();
}
rFile n_dec_pkg_f(decryptedFile, rFile::read);
dec_pkg_f.seek(0);
std::vector<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;
}

View file

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

View file

@ -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;
}
// Leave the file untouched.
return false;
}
bool DecryptSelf(const std::string& elf, const std::string& self)

View file

@ -1,186 +1,187 @@
#pragma once
#include "Loader/ELF64.h"
#include "Loader/ELF32.h"
#include "key_vault.h"
struct vfsStream;
struct AppInfo
{
u64 authid;
u32 vendor_id;
u32 self_type;
u64 version;
u64 padding;
u64 authid;
u32 vendor_id;
u32 self_type;
u64 version;
u64 padding;
void Load(vfsStream& f);
void Show();
void Load(vfsStream& f);
void Show();
};
struct SectionInfo
{
u64 offset;
u64 size;
u32 compressed;
u32 unknown1;
u32 unknown2;
u32 encrypted;
u64 offset;
u64 size;
u32 compressed;
u32 unknown1;
u32 unknown2;
u32 encrypted;
void Load(vfsStream& f);
void Show();
void Load(vfsStream& f);
void Show();
};
struct SCEVersionInfo
{
u32 subheader_type;
u32 present;
u32 size;
u32 unknown;
u32 subheader_type;
u32 present;
u32 size;
u32 unknown;
void Load(vfsStream& f);
void Show();
void Load(vfsStream& f);
void Show();
};
struct ControlInfo
{
u32 type;
u32 size;
u64 next;
u32 type;
u32 size;
u64 next;
union {
// type 1 0x30 bytes
struct {
u32 ctrl_flag1;
u32 unknown1;
u32 unknown2;
u32 unknown3;
u32 unknown4;
u32 unknown5;
u32 unknown6;
u32 unknown7;
} control_flags;
union
{
// type 1 0x30 bytes
struct
{
u32 ctrl_flag1;
u32 unknown1;
u32 unknown2;
u32 unknown3;
u32 unknown4;
u32 unknown5;
u32 unknown6;
u32 unknown7;
// type 2 0x30 bytes
struct {
u8 digest[20];
u64 unknown;
} file_digest_30;
} control_flags;
// type 2 0x40 bytes
struct {
u8 digest1[20];
u8 digest2[20];
u64 unknown;
} file_digest_40;
// type 2 0x30 bytes
struct
{
u8 digest[20];
u64 unknown;
// type 3 0x90 bytes
struct {
u32 magic;
u32 unknown1;
u32 license;
u32 type;
u8 content_id[48];
u8 digest[16];
u8 invdigest[16];
u8 xordigest[16];
u64 unknown2;
u64 unknown3;
} npdrm;
};
} file_digest_30;
void Load(vfsStream& f);
// type 2 0x40 bytes
struct
{
u8 digest1[20];
u8 digest2[20];
u64 unknown;
void Show();
} file_digest_40;
// type 3 0x90 bytes
struct
{
u32 magic;
u32 unknown1;
u32 license;
u32 type;
u8 content_id[48];
u8 digest[16];
u8 invdigest[16];
u8 xordigest[16];
u64 unknown2;
u64 unknown3;
} npdrm;
};
void Load(vfsStream& f);
void Show();
};
struct MetadataInfo
{
u8 key[0x10];
u8 key_pad[0x10];
u8 iv[0x10];
u8 iv_pad[0x10];
u8 key[0x10];
u8 key_pad[0x10];
u8 iv[0x10];
u8 iv_pad[0x10];
void Load(u8* in);
void Show();
void Load(u8* in);
void Show();
};
struct MetadataHeader
{
u64 signature_input_length;
u32 unknown1;
u32 section_count;
u32 key_count;
u32 opt_header_size;
u32 unknown2;
u32 unknown3;
u64 signature_input_length;
u32 unknown1;
u32 section_count;
u32 key_count;
u32 opt_header_size;
u32 unknown2;
u32 unknown3;
void Load(u8* in);
void Show();
void Load(u8* in);
void Show();
};
struct MetadataSectionHeader
{
u64 data_offset;
u64 data_size;
u32 type;
u32 program_idx;
u32 hashed;
u32 sha1_idx;
u32 encrypted;
u32 key_idx;
u32 iv_idx;
u32 compressed;
u64 data_offset;
u64 data_size;
u32 type;
u32 program_idx;
u32 hashed;
u32 sha1_idx;
u32 encrypted;
u32 key_idx;
u32 iv_idx;
u32 compressed;
void Load(u8* in);
void Show();
void Load(u8* in);
void Show();
};
struct SectionHash
{
u8 sha1[20];
u8 padding[12];
u8 hmac_key[64];
u8 sha1[20];
u8 padding[12];
u8 hmac_key[64];
void Load(vfsStream& f);
void Load(vfsStream& f);
};
struct CapabilitiesInfo
{
u32 type;
u32 capabilities_size;
u32 next;
u32 unknown1;
u64 unknown2;
u64 unknown3;
u64 flags;
u32 unknown4;
u32 unknown5;
u32 type;
u32 capabilities_size;
u32 next;
u32 unknown1;
u64 unknown2;
u64 unknown3;
u64 flags;
u32 unknown4;
u32 unknown5;
void Load(vfsStream& f);
void Load(vfsStream& f);
};
struct Signature
{
u8 r[21];
u8 s[21];
u8 padding[6];
u8 r[21];
u8 s[21];
u8 padding[6];
void Load(vfsStream& f);
void Load(vfsStream& f);
};
struct SelfSection
{
u8 *data;
u64 size;
u64 offset;
u8 *data;
u64 size;
u64 offset;
void Load(vfsStream& f);
void Load(vfsStream& f);
};
struct Elf32_Ehdr
@ -204,55 +205,10 @@ struct Elf32_Ehdr
u16 e_shentsize;
u16 e_shnum;
u16 e_shstrndx;
void Load(vfsStream& f);
void Show() {}
bool IsLittleEndian() const
{
return e_data == 1;
}
void Load(vfsStream& f)
{
e_magic = Read32(f);
e_class = Read8(f);
e_data = Read8(f);
e_curver = Read8(f);
e_os_abi = Read8(f);
if (IsLittleEndian())
{
e_abi_ver = Read64LE(f);
e_type = Read16LE(f);
e_machine = Read16LE(f);
e_version = Read32LE(f);
e_entry = Read32LE(f);
e_phoff = Read32LE(f);
e_shoff = Read32LE(f);
e_flags = Read32LE(f);
e_ehsize = Read16LE(f);
e_phentsize = Read16LE(f);
e_phnum = Read16LE(f);
e_shentsize = Read16LE(f);
e_shnum = Read16LE(f);
e_shstrndx = Read16LE(f);
}
else
{
e_abi_ver = Read64(f);
e_type = Read16(f);
e_machine = Read16(f);
e_version = Read32(f);
e_entry = Read32(f);
e_phoff = Read32(f);
e_shoff = Read32(f);
e_flags = Read32(f);
e_ehsize = Read16(f);
e_phentsize = Read16(f);
e_phnum = Read16(f);
e_shentsize = Read16(f);
e_shnum = Read16(f);
e_shstrndx = Read16(f);
}
}
bool IsLittleEndian() const { return e_data == 1; }
bool CheckMagic() const { return e_magic == 0x7F454C46; }
u32 GetEntry() const { return e_entry; }
};
@ -269,25 +225,12 @@ struct Elf32_Shdr
u32 sh_info;
u32 sh_addralign;
u32 sh_entsize;
void Load(vfsStream& f)
{
sh_name = Read32(f);
sh_type = Read32(f);
sh_flags = Read32(f);
sh_addr = Read32(f);
sh_offset = Read32(f);
sh_size = Read32(f);
sh_link = Read32(f);
sh_info = Read32(f);
sh_addralign = Read32(f);
sh_entsize = Read32(f);
}
void LoadLE(vfsStream& f)
{
f.Read(this, sizeof(*this));
}
void Load(vfsStream& f);
void LoadLE(vfsStream& f);
void Show() {}
};
struct Elf32_Phdr
{
u32 p_type;
@ -298,21 +241,9 @@ struct Elf32_Phdr
u32 p_memsz;
u32 p_flags;
u32 p_align;
void Load(vfsStream& f)
{
p_type = Read32(f);
p_offset = Read32(f);
p_vaddr = Read32(f);
p_paddr = Read32(f);
p_filesz = Read32(f);
p_memsz = Read32(f);
p_flags = Read32(f);
p_align = Read32(f);
}
void LoadLE(vfsStream& f)
{
f.Read(this, sizeof(*this));
}
void Load(vfsStream& f);
void LoadLE(vfsStream& f);
void Show() {}
};
@ -337,28 +268,8 @@ struct Elf64_Ehdr
u16 e_shentsize;
u16 e_shnum;
u16 e_shstrndx;
void Load(vfsStream& f)
{
e_magic = Read32(f);
e_class = Read8(f);
e_data = Read8(f);
e_curver = Read8(f);
e_os_abi = Read8(f);
e_abi_ver = Read64(f);
e_type = Read16(f);
e_machine = Read16(f);
e_version = Read32(f);
e_entry = Read64(f);
e_phoff = Read64(f);
e_shoff = Read64(f);
e_flags = Read32(f);
e_ehsize = Read16(f);
e_phentsize = Read16(f);
e_phnum = Read16(f);
e_shentsize = Read16(f);
e_shnum = Read16(f);
e_shstrndx = Read16(f);
}
void Load(vfsStream& f);
void Show() {}
bool CheckMagic() const { return e_magic == 0x7F454C46; }
u64 GetEntry() const { return e_entry; }
@ -376,19 +287,8 @@ struct Elf64_Shdr
u32 sh_info;
u64 sh_addralign;
u64 sh_entsize;
void Load(vfsStream& f)
{
sh_name = Read32(f);
sh_type = Read32(f);
sh_flags = Read64(f);
sh_addr = Read64(f);
sh_offset = Read64(f);
sh_size = Read64(f);
sh_link = Read32(f);
sh_info = Read32(f);
sh_addralign = Read64(f);
sh_entsize = Read64(f);
}
void Load(vfsStream& f);
void Show(){}
};
@ -402,17 +302,8 @@ struct Elf64_Phdr
u64 p_filesz;
u64 p_memsz;
u64 p_align;
void Load(vfsStream& f)
{
p_type = Read32(f);
p_flags = Read32(f);
p_offset = Read64(f);
p_vaddr = Read64(f);
p_paddr = Read64(f);
p_filesz = Read64(f);
p_memsz = Read64(f);
p_align = Read64(f);
}
void Load(vfsStream& f);
void Show(){}
};
@ -425,16 +316,8 @@ struct SceHeader
u32 se_meta;
u64 se_hsize;
u64 se_esize;
void Load(vfsStream& f)
{
se_magic = Read32(f);
se_hver = Read32(f);
se_flags = Read16(f);
se_type = Read16(f);
se_meta = Read32(f);
se_hsize = Read64(f);
se_esize = Read64(f);
}
void Load(vfsStream& f);
void Show(){}
bool CheckMagic() const { return se_magic == 0x53434500; }
};
@ -451,23 +334,11 @@ struct SelfHeader
u64 se_controloff;
u64 se_controlsize;
u64 pad;
void Load(vfsStream& f)
{
se_htype = Read64(f);
se_appinfooff = Read64(f);
se_elfoff = Read64(f);
se_phdroff = Read64(f);
se_shdroff = Read64(f);
se_secinfoff = Read64(f);
se_sceveroff = Read64(f);
se_controloff = Read64(f);
se_controlsize = Read64(f);
pad = Read64(f);
}
void Load(vfsStream& f);
void Show(){}
};
class SELFDecrypter
{
// Main SELF file stream.

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,7 +1,6 @@
#pragma once
class CPUThread;
class RawSPUThread;
enum CPUThreadType : unsigned char;
class CPUThreadManager

View file

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

View file

@ -1,6 +1,6 @@
#include "stdafx_gui.h"
#include "PPUProgramCompiler.h"
#include "Utilities/rFile.h"
#include "Utilities/File.h"
/*
using namespace PPU_instr;

View file

@ -663,7 +663,7 @@ void PPUThread::FastCall2(u32 addr, u32 rtoc)
{
auto old_status = m_status;
auto old_PC = PC;
auto old_stack = GPR[1]; // only saved and restored (may be wrong)
auto old_stack = GPR[1];
auto old_rtoc = GPR[2];
auto old_LR = LR;
auto old_thread = GetCurrentNamedThread();
@ -680,7 +680,13 @@ void PPUThread::FastCall2(u32 addr, u32 rtoc)
m_status = old_status;
PC = old_PC;
GPR[1] = old_stack;
if (GPR[1] != old_stack && !Emu.IsStopped()) // GPR[1] shouldn't change
{
LOG_ERROR(PPU, "PPUThread::FastCall2(0x%x,0x%x): stack inconsistency (SP=0x%llx, old=0x%llx)", addr, rtoc, GPR[1], old_stack);
GPR[1] = old_stack;
}
GPR[2] = old_rtoc;
LR = old_LR;
SetCurrentNamedThread(old_thread);

View file

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

View file

@ -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))
//{
// LOG_ERROR(Log::SPU, "RtlAddFunctionTable() failed");
//}
#endif
}
log.Close();
//std::string log = fmt::format("========== START POSITION 0x%x ==========\n\n", start * 4);
//log += stringLogger.getString();
//if (!entry[start].pointer)
//{
// LOG_ERROR(Log::SPU, "SPURecompilerCore::Compile(pos=0x%x) failed", start * sizeof(u32));
// log += "========== FAILED ============\n\n";
// Emu.Pause();
//}
//else
//{
// log += fmt::format("========== COMPILED %d (excess %d), time: [start=%lld (decoding=%lld), finalize=%lld]\n\n",
// entry[start].count, excess, stamp1 - stamp0, time0, get_system_time() - stamp1);
//}
//fs::file(fmt::Format("SPUjit_%d.log", this->CPU.GetId()), o_write | o_create | (first ? o_trunc : o_append)).write(log.c_str(), log.size());
m_enc->compiler = nullptr;
first = false;
}
@ -217,9 +204,6 @@ u32 SPURecompilerCore::DecodeMemory(const u32 address)
i < (u32)pos + (u32)entry[pos].count)
{
runtime.release(entry[i].pointer);
#ifdef _WIN32
//RtlDeleteFunctionTable(&entry[i].info);
#endif
entry[i].pointer = nullptr;
for (u32 j = i; j < i + (u32)entry[i].count; j++)
{
@ -264,7 +248,7 @@ u32 SPURecompilerCore::DecodeMemory(const u32 address)
}
u32 res = pos;
res = func(cpu, vm::get_ptr<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)
{

View file

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

View file

@ -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++)
__forceinline __m128 operator [] (s32 scale) const
{
for (u32 j = 0; j < 8; j++) mmToU16Ptr(fsmh_table[i])[j] = (i & (1 << j)) ? ~0 : 0;
return m_data[scale + 155];
}
for (u32 i = 0; i < sizeof(fsmb_table) / sizeof(fsmb_table[0]); i++)
}
const scale;
g_spu_imm_table_t()
{
for (u32 i = 0; i < sizeof(fsm) / sizeof(fsm[0]); i++)
{
for (u32 j = 0; j < 16; j++) mmToU8Ptr(fsmb_table[i])[j] = (i & (1 << j)) ? ~0 : 0;
for (u32 j = 0; j < 4; j++)
{
fsm[i]._u32[j] = (i & (1 << j)) ? 0xffffffff : 0;
}
}
for (u32 i = 0; i < sizeof(fsmh) / sizeof(fsmh[0]); i++)
{
for (u32 j = 0; j < 8; j++)
{
fsmh[i]._u16[j] = (i & (1 << j)) ? 0xffff : 0;
}
}
for (u32 i = 0; i < sizeof(fsmb) / sizeof(fsmb[0]); i++)
{
for (u32 j = 0; j < 16; j++)
{
fsmb[i]._u8[j] = (i & (1 << j)) ? 0xff : 0;
}
}
for (u32 i = 0; i < sizeof(sldq_pshufb) / sizeof(sldq_pshufb[0]); i++)
{
for (u32 j = 0; j < 16; j++) mmToU8Ptr(sldq_pshufb[i])[j] = (u8)(j - i);
for (u32 j = 0; j < 16; j++)
{
sldq_pshufb[i]._u8[j] = static_cast<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
{

View file

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

View file

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

View file

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

View file

@ -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)
@ -252,4 +246,4 @@ void vfsDevice::Unlock() const
bool vfsDevice::TryLock() const
{
return m_mtx_lock.try_lock();
}
}

View file

@ -1,5 +1,5 @@
#include "stdafx.h"
#include "Utilities/rFile.h"
#include "Utilities/File.h"
#include "vfsDirBase.h"
vfsDirBase::vfsDirBase(vfsDevice* device)
@ -63,4 +63,4 @@ const DirEntryInfo* vfsDirBase::First()
{
m_pos = 0;
return Read();
}
}

View file

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

View file

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

View file

@ -8,22 +8,21 @@ private:
public:
vfsFile();
vfsFile(const std::string& path, vfsOpenMode mode = vfsRead);
vfsFile(const std::string& path, u32 mode = vfsRead);
virtual bool Open(const std::string& path, vfsOpenMode mode = vfsRead) override;
virtual bool Create(const std::string& path, bool overwrite = false) override;
virtual bool Open(const std::string& path, u32 mode = vfsRead) override;
virtual bool Exists(const std::string& path) override;
virtual bool Rename(const std::string& from, const std::string& to) override;
virtual bool Remove(const std::string& path) override;
virtual bool Close() override;
virtual u64 GetSize() override;
virtual u64 GetSize() const override;
virtual u64 Write(const void* src, u64 size) override;
virtual u64 Read(void* dst, u64 size) override;
virtual u64 Seek(s64 offset, vfsSeekMode mode = vfsSeekSet) override;
virtual u64 Seek(s64 offset, u32 mode = from_begin) override;
virtual u64 Tell() const override;
virtual bool IsOpened() const override;
};
};

View file

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

View file

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

View file

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

View file

@ -1,6 +1,6 @@
#pragma once
#include "vfsDirBase.h"
#include "Utilities/rFile.h"
#include "Utilities/File.h"
class vfsLocalDir : public vfsDirBase
{

View file

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

View file

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

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -2484,18 +2484,19 @@ void RSXThread::Task()
if (get_system_time() - start_time > m_vblank_count * 1000000 / 60)
{
m_vblank_count++;
if (m_vblank_handler)
if (auto cb = m_vblank_handler)
{
auto cb = m_vblank_handler;
Emu.GetCallbackManager().Async([cb](PPUThread& CPU)
Emu.GetCallbackManager().Async([=](PPUThread& CPU)
{
cb(CPU, 1);
});
}
continue;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
else
{
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
}
}
});

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -96,10 +96,10 @@ s32 cellAudioInit()
u16 buf_u16[out_buffer_size];
for (size_t i = 0; i < out_buffer_size; i += 8)
{
static const __m128 float2u16 = { 0x8000, 0x8000, 0x8000, 0x8000 };
const auto scale = _mm_set1_ps(0x8000);
(__m128i&)(buf_u16[i]) = _mm_packs_epi32(
_mm_cvtps_epi32(_mm_mul_ps((__m128&)(buffer[i]), float2u16)),
_mm_cvtps_epi32(_mm_mul_ps((__m128&)(buffer[i + 4]), float2u16)));
_mm_cvtps_epi32(_mm_mul_ps(_mm_load_ps(buffer + i), scale)),
_mm_cvtps_epi32(_mm_mul_ps(_mm_load_ps(buffer + i + 4), scale)));
}
if (!opened)
@ -206,25 +206,17 @@ s32 cellAudioInit()
auto step_volume = [](AudioPortConfig& port) // part of cellAudioSetPortLevel functionality
{
if (port.level_inc)
{
port.level += port.level_inc;
const auto param = port.level_set.read_sync();
if (port.level_inc > 0.0f)
if (param.inc != 0.0f)
{
port.level += param.inc;
const bool dec = param.inc < 0.0f;
if ((!dec && param.value - port.level <= 0.0f) || (dec && param.value - port.level >= 0.0f))
{
if (port.level_set - port.level <= 0.0f)
{
port.level = port.level_set;
port.level_inc = 0.0f;
}
}
else
{
if (port.level_set - port.level >= 0.0f)
{
port.level = port.level_set;
port.level_inc = 0.0f;
}
port.level = param.value;
port.level_set.compare_and_swap(param, { param.value, 0.0f });
}
}
};
@ -397,9 +389,9 @@ s32 cellAudioInit()
for (auto key : g_audio.keys)
{
if (std::shared_ptr<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
{

View file

@ -108,9 +108,15 @@ struct AudioPortConfig
u32 addr;
u32 read_index_addr;
u32 size;
float level;
float level_set;
float level_inc;
struct level_set_t
{
float value;
float inc;
};
float level;
atomic_le_t<level_set_t> level_set;
};
struct AudioConfig //custom structure

View file

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

View file

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

View file

@ -169,7 +169,7 @@ struct CellDmuxPamfSpecificInfo
struct CellDmuxType2
{
be_t<CellDmuxStreamType> streamType;
be_t<u32> streamSpecificInfo_addr;
be_t<u32> streamSpecificInfo;
};
struct CellDmuxResource

View file

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

View file

@ -210,38 +210,42 @@ 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)
{
entries->attribute.mode =
CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR |
CELL_FS_S_IRGRP | CELL_FS_S_IWGRP | CELL_FS_S_IXGRP |
CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH;
u32 count = 0;
entries->attribute.uid = 0;
entries->attribute.gid = 0;
entries->attribute.atime = 0; //TODO
entries->attribute.mtime = 0; //TODO
entries->attribute.ctime = 0; //TODO
entries->attribute.blksize = 4096;
entries_size /= sizeof(CellFsDirectoryEntry);
entries->entry_name.d_type = (info->flags & DirEntry_TypeFile) ? CELL_FS_TYPE_REGULAR : CELL_FS_TYPE_DIRECTORY;
entries->entry_name.d_namlen = u8(std::min<size_t>(info->name.length(), CELL_FS_MAX_FS_FILE_NAME_LENGTH));
strcpy_trunc(entries->entry_name.d_name, info->name);
*data_count = 1;
}
else
for (; count < entries_size; count++)
{
*data_count = 0;
if (const auto info = directory->Read())
{
entries[count].attribute.mode = info->flags & DirEntry_TypeDir ? CELL_FS_S_IFDIR | 0777 : CELL_FS_S_IFREG | 0666;
entries[count].attribute.uid = 1; // ???
entries[count].attribute.gid = 1; // ???
entries[count].attribute.atime = info->access_time;
entries[count].attribute.mtime = info->modify_time;
entries[count].attribute.ctime = info->create_time;
entries[count].attribute.size = info->size;
entries[count].attribute.blksize = 4096; // ???
entries[count].entry_name.d_type = info->flags & DirEntry_TypeFile ? CELL_FS_TYPE_REGULAR : CELL_FS_TYPE_DIRECTORY;
entries[count].entry_name.d_namlen = u8(std::min<size_t>(info->name.length(), CELL_FS_MAX_FS_FILE_NAME_LENGTH));
strcpy_trunc(entries[count].entry_name.d_name, info->name);
}
else
{
break;
}
}
*data_count = count;
return CELL_OK;
}
@ -251,9 +255,9 @@ s32 cellFsReadWithOffset(u32 fd, u64 offset, vm::ptr<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;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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,18 +83,24 @@ 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;
case CELL_MSGDIALOG_TYPE_PROGRESSBAR_DOUBLE: g_msg_dialog->progress_bar_count = 2; break;
case CELL_MSGDIALOG_TYPE_PROGRESSBAR_SINGLE: g_msg_dialog->progress_bar_count = 1; break;
default: g_msg_dialog->progress_bar_count = 0; break;
}
switch (type & CELL_MSGDIALOG_TYPE_SE_MUTE) // TODO
{
case CELL_MSGDIALOG_TYPE_SE_MUTE_OFF: break;
case CELL_MSGDIALOG_TYPE_SE_MUTE_ON: break;
}
std::string msg = msgString.get_ptr();
@ -127,24 +109,18 @@ s32 cellMsgDialogOpen2(u32 type, vm::ptr<const char> msgString, vm::ptr<CellMsgD
{
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_SE_TYPE_NORMAL: cellSysutil.Warning("%s", msg); break;
case CELL_MSGDIALOG_TYPE_SE_TYPE_ERROR: cellSysutil.Error("%s", msg); break;
}
switch (type & CELL_MSGDIALOG_TYPE_SE_MUTE) // TODO
{
case CELL_MSGDIALOG_TYPE_SE_MUTE_OFF: break;
case CELL_MSGDIALOG_TYPE_SE_MUTE_ON: break;
}
g_msg_dialog_status = CELL_MSGDIALOG_BUTTON_NONE;
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);
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

Some files were not shown because too many files have changed in this diff Show more