mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-11-22 10:42:36 +01:00
- Implemented be_t, mem_struct_ptr_t, vfsFile.
- Improved sys_fs, cellPngDec, cellJpgDec, cellGifDec modules.
This commit is contained in:
parent
efd336b743
commit
dd48f827c3
154
Utilities/BEType.h
Normal file
154
Utilities/BEType.h
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
#pragma once
|
||||||
|
#pragma warning(disable: 4739)
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class be_t
|
||||||
|
{
|
||||||
|
static_assert(sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, "Bad be_t type");
|
||||||
|
T m_data;
|
||||||
|
|
||||||
|
public:
|
||||||
|
be_t()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
be_t(const T& value)
|
||||||
|
{
|
||||||
|
FromLE(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1>
|
||||||
|
be_t(const be_t<T1>& value)
|
||||||
|
{
|
||||||
|
FromBE(value.ToBE());
|
||||||
|
}
|
||||||
|
|
||||||
|
T ToBE() const
|
||||||
|
{
|
||||||
|
return m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
T ToLE() const
|
||||||
|
{
|
||||||
|
T res;
|
||||||
|
|
||||||
|
switch(sizeof(T))
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
res = m_data;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
(u16&)res = _byteswap_ushort((u16&)m_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
(u32&)res = _byteswap_ulong((u32&)m_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
(u64&)res = _byteswap_uint64((u64&)m_data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FromBE(const T& value)
|
||||||
|
{
|
||||||
|
m_data = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FromLE(const T& value)
|
||||||
|
{
|
||||||
|
switch(sizeof(T))
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
m_data = value;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
(u16&)m_data = _byteswap_ushort((u16&)value);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
(u32&)m_data = _byteswap_ulong((u32&)value);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
(u64&)m_data = _byteswap_uint64((u64&)value);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(0);
|
||||||
|
m_data = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//template<typename T1>
|
||||||
|
operator const T() const
|
||||||
|
{
|
||||||
|
return ToLE();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1>
|
||||||
|
operator const be_t<T1>() const
|
||||||
|
{
|
||||||
|
be_t<T1> res;
|
||||||
|
res.FromBE(ToBE());
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
be_t& operator = (const T& right)
|
||||||
|
{
|
||||||
|
FromLE(right);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
be_t& operator = (const be_t& right)
|
||||||
|
{
|
||||||
|
m_data = right.m_data;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1> be_t& operator += (T1 right) { return *this = T(*this) + right; }
|
||||||
|
template<typename T1> be_t& operator -= (T1 right) { return *this = T(*this) - right; }
|
||||||
|
template<typename T1> be_t& operator *= (T1 right) { return *this = T(*this) * right; }
|
||||||
|
template<typename T1> be_t& operator /= (T1 right) { return *this = T(*this) / right; }
|
||||||
|
template<typename T1> be_t& operator %= (T1 right) { return *this = T(*this) % right; }
|
||||||
|
template<typename T1> be_t& operator &= (T1 right) { return *this = T(*this) & right; }
|
||||||
|
template<typename T1> be_t& operator |= (T1 right) { return *this = T(*this) | right; }
|
||||||
|
template<typename T1> be_t& operator ^= (T1 right) { return *this = T(*this) ^ right; }
|
||||||
|
template<typename T1> be_t& operator <<= (T1 right) { return *this = T(*this) << right; }
|
||||||
|
template<typename T1> be_t& operator >>= (T1 right) { return *this = T(*this) >> right; }
|
||||||
|
|
||||||
|
template<typename T1> be_t& operator += (const be_t<T1>& right) { return *this = ToLE() + right.ToLE(); }
|
||||||
|
template<typename T1> be_t& operator -= (const be_t<T1>& right) { return *this = ToLE() - right.ToLE(); }
|
||||||
|
template<typename T1> be_t& operator *= (const be_t<T1>& right) { return *this = ToLE() * right.ToLE(); }
|
||||||
|
template<typename T1> be_t& operator /= (const be_t<T1>& right) { return *this = ToLE() / right.ToLE(); }
|
||||||
|
template<typename T1> be_t& operator %= (const be_t<T1>& right) { return *this = ToLE() % right.ToLE(); }
|
||||||
|
template<typename T1> be_t& operator &= (const be_t<T1>& right) { return *this = ToBE() & right.ToBE(); }
|
||||||
|
template<typename T1> be_t& operator |= (const be_t<T1>& right) { return *this = ToBE() | right.ToBE(); }
|
||||||
|
template<typename T1> be_t& operator ^= (const be_t<T1>& right) { return *this = ToBE() ^ right.ToBE(); }
|
||||||
|
|
||||||
|
template<typename T1> be_t operator & (const be_t<T1>& right) const { be_t<T> res; res.FromBE(ToBE() & right.ToBE()); return res; }
|
||||||
|
template<typename T1> be_t operator | (const be_t<T1>& right) const { be_t<T> res; res.FromBE(ToBE() | right.ToBE()); return res; }
|
||||||
|
template<typename T1> be_t operator ^ (const be_t<T1>& right) const { be_t<T> res; res.FromBE(ToBE() ^ right.ToBE()); return res; }
|
||||||
|
|
||||||
|
template<typename T1> bool operator == (T1 right) const { return ToLE() == right; }
|
||||||
|
template<typename T1> bool operator != (T1 right) const { return !(*this == right); }
|
||||||
|
template<typename T1> bool operator > (T1 right) const { return ToLE() > right; }
|
||||||
|
template<typename T1> bool operator < (T1 right) const { return ToLE() < right; }
|
||||||
|
template<typename T1> bool operator >= (T1 right) const { return ToLE() >= right; }
|
||||||
|
template<typename T1> bool operator <= (T1 right) const { return ToLE() <= right; }
|
||||||
|
|
||||||
|
template<typename T1> bool operator == (const be_t<T1>& right) const { return ToBE() == right.ToBE(); }
|
||||||
|
template<typename T1> bool operator != (const be_t<T1>& right) const { return !(*this == right); }
|
||||||
|
template<typename T1> bool operator > (const be_t<T1>& right) const { return ToLE() > right.ToLE(); }
|
||||||
|
template<typename T1> bool operator < (const be_t<T1>& right) const { return ToLE() < right.ToLE(); }
|
||||||
|
template<typename T1> bool operator >= (const be_t<T1>& right) const { return ToLE() >= right.ToLE(); }
|
||||||
|
template<typename T1> bool operator <= (const be_t<T1>& right) const { return ToLE() <= right.ToLE(); }
|
||||||
|
};
|
@ -101,6 +101,28 @@ vfsDevice* VFS::GetDevice(const wxString& ps3_path, wxString& path)
|
|||||||
return &m_devices[max_i];
|
return &m_devices[max_i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vfsDevice* VFS::GetDeviceLocal(const wxString& local_path, wxString& path)
|
||||||
|
{
|
||||||
|
u32 max_eq;
|
||||||
|
s32 max_i=-1;
|
||||||
|
|
||||||
|
for(u32 i=0; i<m_devices.GetCount(); ++i)
|
||||||
|
{
|
||||||
|
const u32 eq = m_devices[i].CmpLocalPath(local_path);
|
||||||
|
|
||||||
|
if(max_i < 0 || eq > max_eq)
|
||||||
|
{
|
||||||
|
max_eq = eq;
|
||||||
|
max_i = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(max_i < 0) return nullptr;
|
||||||
|
|
||||||
|
path = vfsDevice::GetPs3Path(m_devices[max_i].GetPs3Path(), local_path(max_eq, local_path.Len() - max_eq));
|
||||||
|
return &m_devices[max_i];
|
||||||
|
}
|
||||||
|
|
||||||
void VFS::Init(const wxString& path)
|
void VFS::Init(const wxString& path)
|
||||||
{
|
{
|
||||||
Array<VFSManagerEntry> entries;
|
Array<VFSManagerEntry> entries;
|
||||||
|
@ -36,6 +36,7 @@ struct VFS
|
|||||||
void Create(const wxString& ps3_path);
|
void Create(const wxString& ps3_path);
|
||||||
void Close(vfsStream*& device);
|
void Close(vfsStream*& device);
|
||||||
vfsDevice* GetDevice(const wxString& ps3_path, wxString& path);
|
vfsDevice* GetDevice(const wxString& ps3_path, wxString& path);
|
||||||
|
vfsDevice* GetDeviceLocal(const wxString& local_path, wxString& path);
|
||||||
|
|
||||||
void Init(const wxString& path);
|
void Init(const wxString& path);
|
||||||
void SaveLoadDevices(Array<VFSManagerEntry>& res, bool is_load);
|
void SaveLoadDevices(Array<VFSManagerEntry>& res, bool is_load);
|
||||||
|
@ -36,6 +36,19 @@ u32 vfsDevice::CmpPs3Path(const wxString& ps3_path)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 vfsDevice::CmpLocalPath(const wxString& local_path)
|
||||||
|
{
|
||||||
|
const u32 lim = min(m_local_path.Len(), local_path.Len());
|
||||||
|
u32 ret = 0;
|
||||||
|
|
||||||
|
for(u32 i=0; i<lim; ++i, ++ret)
|
||||||
|
{
|
||||||
|
if(m_local_path[i] != local_path[i]) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
wxString vfsDevice::ErasePath(const wxString& path, u32 start_dir_count, u32 end_dir_count)
|
wxString vfsDevice::ErasePath(const wxString& path, u32 start_dir_count, u32 end_dir_count)
|
||||||
{
|
{
|
||||||
u32 from = 0;
|
u32 from = 0;
|
||||||
|
@ -32,6 +32,7 @@ public:
|
|||||||
void SetPath(const wxString& ps3_path, const wxString& local_path);
|
void SetPath(const wxString& ps3_path, const wxString& local_path);
|
||||||
|
|
||||||
u32 CmpPs3Path(const wxString& ps3_path);
|
u32 CmpPs3Path(const wxString& ps3_path);
|
||||||
|
u32 CmpLocalPath(const wxString& local_path);
|
||||||
|
|
||||||
static wxString ErasePath(const wxString& local_path, u32 start_dir_count, u32 end_dir_count);
|
static wxString ErasePath(const wxString& local_path, u32 start_dir_count, u32 end_dir_count);
|
||||||
static wxString GetRoot(const wxString& local_path);
|
static wxString GetRoot(const wxString& local_path);
|
||||||
|
84
rpcs3/Emu/FS/vfsFile.cpp
Normal file
84
rpcs3/Emu/FS/vfsFile.cpp
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "vfsFile.h"
|
||||||
|
|
||||||
|
vfsFile::vfsFile()
|
||||||
|
: vfsFileBase()
|
||||||
|
, m_stream(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
vfsFile::vfsFile(const wxString path, vfsOpenMode mode)
|
||||||
|
: vfsFileBase()
|
||||||
|
, m_stream(nullptr)
|
||||||
|
{
|
||||||
|
Open(path, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
vfsFile::~vfsFile()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
vfsDevice* vfsFile::GetNew()
|
||||||
|
{
|
||||||
|
return new vfsFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfsFile::Open(const wxString& path, vfsOpenMode mode)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
|
||||||
|
m_stream = Emu.GetVFS().Open(path, mode);
|
||||||
|
|
||||||
|
return m_stream && m_stream->IsOpened();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfsFile::Create(const wxString& path)
|
||||||
|
{
|
||||||
|
if(wxFileExists(path)) return false;
|
||||||
|
|
||||||
|
wxFile f;
|
||||||
|
return f.Create(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfsFile::Close()
|
||||||
|
{
|
||||||
|
if(m_stream)
|
||||||
|
{
|
||||||
|
delete m_stream;
|
||||||
|
m_stream = nullptr;
|
||||||
|
return vfsFileBase::Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 vfsFile::GetSize()
|
||||||
|
{
|
||||||
|
return m_stream->GetSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 vfsFile::Write(const void* src, u64 size)
|
||||||
|
{
|
||||||
|
return m_stream->Write(src, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 vfsFile::Read(void* dst, u64 size)
|
||||||
|
{
|
||||||
|
return m_stream->Read(dst, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 vfsFile::Seek(s64 offset, vfsSeekMode mode)
|
||||||
|
{
|
||||||
|
return m_stream->Seek(offset, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 vfsFile::Tell() const
|
||||||
|
{
|
||||||
|
return m_stream->Tell();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool vfsFile::IsOpened() const
|
||||||
|
{
|
||||||
|
return m_stream && m_stream->IsOpened() && vfsFileBase::IsOpened();
|
||||||
|
}
|
29
rpcs3/Emu/FS/vfsFile.h
Normal file
29
rpcs3/Emu/FS/vfsFile.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "vfsFileBase.h"
|
||||||
|
|
||||||
|
class vfsFile : public vfsFileBase
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
vfsStream* m_stream;
|
||||||
|
|
||||||
|
public:
|
||||||
|
vfsFile();
|
||||||
|
vfsFile(const wxString path, vfsOpenMode mode = vfsRead);
|
||||||
|
~vfsFile();
|
||||||
|
|
||||||
|
virtual vfsDevice* GetNew() override;
|
||||||
|
|
||||||
|
virtual bool Open(const wxString& path, vfsOpenMode mode = vfsRead) override;
|
||||||
|
virtual bool Create(const wxString& path) override;
|
||||||
|
virtual bool Close() override;
|
||||||
|
|
||||||
|
virtual u64 GetSize() 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 Tell() const override;
|
||||||
|
|
||||||
|
virtual bool IsOpened() const override;
|
||||||
|
};
|
@ -5,21 +5,32 @@ vfsStreamMemory::vfsStreamMemory() : vfsStream()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
vfsStreamMemory::vfsStreamMemory(u64 addr) : vfsStream()
|
vfsStreamMemory::vfsStreamMemory(u64 addr, u64 size) : vfsStream()
|
||||||
{
|
{
|
||||||
Open(addr);
|
Open(addr, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vfsStreamMemory::Open(u64 addr)
|
void vfsStreamMemory::Open(u64 addr, u64 size)
|
||||||
{
|
{
|
||||||
m_addr = addr;
|
m_addr = addr;
|
||||||
|
m_size = size ? size : ~0ULL;
|
||||||
|
|
||||||
vfsStream::Reset();
|
vfsStream::Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 vfsStreamMemory::GetSize()
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
u64 vfsStreamMemory::Write(const void* src, u64 size)
|
u64 vfsStreamMemory::Write(const void* src, u64 size)
|
||||||
{
|
{
|
||||||
if(!Memory.IsGoodAddr(m_addr + Tell(), size)) return 0;
|
if(Tell() + size > GetSize())
|
||||||
|
{
|
||||||
|
size = GetSize() - Tell();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!size || !Memory.IsGoodAddr(m_addr + Tell(), size)) return 0;
|
||||||
|
|
||||||
memcpy(&Memory[m_addr + Tell()], src, size);
|
memcpy(&Memory[m_addr + Tell()], src, size);
|
||||||
|
|
||||||
@ -28,7 +39,12 @@ u64 vfsStreamMemory::Write(const void* src, u64 size)
|
|||||||
|
|
||||||
u64 vfsStreamMemory::Read(void* dst, u64 size)
|
u64 vfsStreamMemory::Read(void* dst, u64 size)
|
||||||
{
|
{
|
||||||
if(!Memory.IsGoodAddr(m_addr + Tell(), size)) return 0;
|
if(Tell() + size > GetSize())
|
||||||
|
{
|
||||||
|
size = GetSize() - Tell();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!size || !Memory.IsGoodAddr(m_addr + Tell(), size)) return 0;
|
||||||
|
|
||||||
memcpy(dst, &Memory[m_addr + Tell()], size);
|
memcpy(dst, &Memory[m_addr + Tell()], size);
|
||||||
|
|
||||||
|
@ -4,12 +4,15 @@
|
|||||||
struct vfsStreamMemory : public vfsStream
|
struct vfsStreamMemory : public vfsStream
|
||||||
{
|
{
|
||||||
u64 m_addr;
|
u64 m_addr;
|
||||||
|
u64 m_size;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
vfsStreamMemory();
|
vfsStreamMemory();
|
||||||
vfsStreamMemory(u64 addr);
|
vfsStreamMemory(u64 addr, u64 size = 0);
|
||||||
|
|
||||||
void Open(u64 addr);
|
void Open(u64 addr, u64 size = 0);
|
||||||
|
|
||||||
|
virtual u64 GetSize() override;
|
||||||
|
|
||||||
virtual u64 Write(const void* src, u64 size) override;
|
virtual u64 Write(const void* src, u64 size) override;
|
||||||
virtual u64 Read(void* dst, u64 size) override;
|
virtual u64 Read(void* dst, u64 size) override;
|
||||||
|
@ -310,7 +310,7 @@ void FragmentDecompilerThread::Task()
|
|||||||
|
|
||||||
if(dst.end) break;
|
if(dst.end) break;
|
||||||
|
|
||||||
data.SetOffset(m_offset);
|
data.Skip(m_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_shader = BuildCode();
|
m_shader = BuildCode();
|
||||||
|
@ -369,24 +369,56 @@ public:
|
|||||||
|
|
||||||
extern MemoryBase Memory;
|
extern MemoryBase Memory;
|
||||||
|
|
||||||
class MemoryAllocator
|
template<typename T> class mem_struct_ptr_t
|
||||||
{
|
{
|
||||||
u32 m_addr;
|
const u32 m_addr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MemoryAllocator(u32 size, u32 align = 1)
|
mem_struct_ptr_t(u32 addr) : m_addr(addr)
|
||||||
{
|
{
|
||||||
m_addr = Memory.Alloc(size, align);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
~MemoryAllocator()
|
operator T&()
|
||||||
{
|
{
|
||||||
Memory.Free(m_addr);
|
return (T&)Memory[m_addr];
|
||||||
}
|
}
|
||||||
|
|
||||||
operator u32() const
|
operator const T&() const
|
||||||
{
|
{
|
||||||
return m_addr;
|
return (const T&)Memory[m_addr];
|
||||||
|
}
|
||||||
|
|
||||||
|
T* operator -> ()
|
||||||
|
{
|
||||||
|
return (T*)&Memory[m_addr];
|
||||||
|
}
|
||||||
|
|
||||||
|
const T* operator -> () const
|
||||||
|
{
|
||||||
|
return (const T*)&Memory[m_addr];
|
||||||
|
}
|
||||||
|
|
||||||
|
T& operator [](uint index)
|
||||||
|
{
|
||||||
|
return (T&)Memory[m_addr + sizeof(T) * index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& operator [](uint index) const
|
||||||
|
{
|
||||||
|
return (const T&)Memory[m_addr + sizeof(T) * index];
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GetAddr() const { return m_addr; }
|
||||||
|
|
||||||
|
bool IsGood() const
|
||||||
|
{
|
||||||
|
return Memory.IsGoodAddr(m_addr, sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
mem_struct_ptr_t& operator = (const T& right)
|
||||||
|
{
|
||||||
|
memcpy(&Memory[m_addr], &right, sizeof(T));
|
||||||
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -395,35 +427,20 @@ template<typename T> class mem_t
|
|||||||
const u32 m_addr;
|
const u32 m_addr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
mem_t(u64 addr) : m_addr(addr)
|
mem_t(u32 addr) : m_addr(addr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_t& operator = (T right)
|
mem_t& operator = (T right)
|
||||||
{
|
{
|
||||||
switch(sizeof(T))
|
(be_t<T>&)Memory[m_addr] = right;
|
||||||
{
|
|
||||||
case 1: Memory.Write8(m_addr, right); return *this;
|
|
||||||
case 2: Memory.Write16(m_addr, right); return *this;
|
|
||||||
case 4: Memory.Write32(m_addr, right); return *this;
|
|
||||||
case 8: Memory.Write64(m_addr, right); return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(0);
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
operator const T() const
|
operator const T() const
|
||||||
{
|
{
|
||||||
switch(sizeof(T))
|
return (be_t<T>&)Memory[m_addr];
|
||||||
{
|
|
||||||
case 1: return Memory.Read8(m_addr);
|
|
||||||
case 2: return Memory.Read16(m_addr);
|
|
||||||
case 4: return Memory.Read32(m_addr);
|
|
||||||
case 8: return Memory.Read64(m_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mem_t& operator += (T right) { return *this = (*this) + right; }
|
mem_t& operator += (T right) { return *this = (*this) + right; }
|
||||||
@ -437,7 +454,7 @@ public:
|
|||||||
mem_t& operator <<= (T right) { return *this = (*this) << right; }
|
mem_t& operator <<= (T right) { return *this = (*this) << right; }
|
||||||
mem_t& operator >>= (T right) { return *this = (*this) >> right; }
|
mem_t& operator >>= (T right) { return *this = (*this) >> right; }
|
||||||
|
|
||||||
u64 GetAddr() const { return m_addr; }
|
u32 GetAddr() const { return m_addr; }
|
||||||
|
|
||||||
bool IsGood() const
|
bool IsGood() const
|
||||||
{
|
{
|
||||||
@ -447,88 +464,181 @@ public:
|
|||||||
|
|
||||||
template<typename T> class mem_ptr_t
|
template<typename T> class mem_ptr_t
|
||||||
{
|
{
|
||||||
u64 m_addr;
|
u32 m_addr;
|
||||||
const u64 m_iaddr;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
mem_ptr_t(u64 addr)
|
mem_ptr_t(u32 addr) : m_addr(addr)
|
||||||
: m_addr(addr)
|
|
||||||
, m_iaddr(addr)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator = (T right)
|
void operator = (T right)
|
||||||
{
|
{
|
||||||
switch(sizeof(T))
|
(be_t<T>&)Memory[m_addr] = right;
|
||||||
{
|
|
||||||
case 1: Memory.Write8(m_addr, right); return;
|
|
||||||
case 2: Memory.Write16(m_addr, right); return;
|
|
||||||
case 4: Memory.Write32(m_addr, right); return;
|
|
||||||
case 8: Memory.Write64(m_addr, right); return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ConLog.Error("Bad mem_t size! (%d : 0x%llx)", sizeof(T), m_addr);
|
u32 operator += (T right)
|
||||||
}
|
|
||||||
|
|
||||||
operator u8() const { return Memory.Read8(m_addr); }
|
|
||||||
operator u16() const { return Memory.Read16(m_addr); }
|
|
||||||
operator u32() const { return Memory.Read32(m_addr); }
|
|
||||||
operator u64() const { return Memory.Read64(m_addr); }
|
|
||||||
|
|
||||||
u64 operator += (T right)
|
|
||||||
{
|
{
|
||||||
*this = right;
|
*this = right;
|
||||||
m_addr += sizeof(T);
|
m_addr += sizeof(T);
|
||||||
return m_addr;
|
return m_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
const T operator [] (u64 i) const
|
u32 GetAddr() const { return m_addr; }
|
||||||
|
u32 Skip(const u32 offset) { return m_addr += offset; }
|
||||||
|
|
||||||
|
operator be_t<T>*() { return GetPtr(); }
|
||||||
|
operator void*() { return GetPtr(); }
|
||||||
|
operator be_t<T>*() const { return GetPtr(); }
|
||||||
|
operator void*() const { return GetPtr(); }
|
||||||
|
|
||||||
|
const char* GetString() const
|
||||||
{
|
{
|
||||||
const u64 offset = i*sizeof(T);
|
return (const char*)&Memory[m_addr];
|
||||||
(*(mem_ptr_t*)this).m_addr += offset;
|
|
||||||
const T ret = *this;
|
|
||||||
(*(mem_ptr_t*)this).m_addr -= offset;
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() { m_addr = m_iaddr; }
|
be_t<T>* GetPtr()
|
||||||
u64 GetCurAddr() const { return m_addr; }
|
{
|
||||||
u64 GetAddr() const { return m_iaddr; }
|
return (be_t<T>*)&Memory[m_addr];
|
||||||
u64 SetOffset(const u32 offset) { return m_addr += offset; }
|
}
|
||||||
|
|
||||||
|
const be_t<T>* GetPtr() const
|
||||||
|
{
|
||||||
|
return (const be_t<T>*)&Memory[m_addr];
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class mem_class_t
|
class mem_class_t
|
||||||
{
|
{
|
||||||
u64 addr;
|
u32 m_addr;
|
||||||
const u64 iaddr;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
mem_class_t(u64 _addr)
|
mem_class_t(u32 addr) : m_addr(addr)
|
||||||
: addr(_addr)
|
|
||||||
, iaddr(_addr)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> u64 operator += (T right)
|
template<typename T> u32 operator += (T right)
|
||||||
{
|
{
|
||||||
mem_t<T> m(addr);
|
mem_t<T>& m((mem_t<T>&)*this);
|
||||||
m = right;
|
m = right;
|
||||||
addr += sizeof(T);
|
m_addr += sizeof(T);
|
||||||
return addr;
|
return m_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> operator T()
|
template<typename T> operator T()
|
||||||
{
|
{
|
||||||
mem_t<T> m(addr);
|
mem_t<T>& m((mem_t<T>&)*this);
|
||||||
const T ret = m;
|
const T ret = m;
|
||||||
addr += sizeof(T);
|
m_addr += sizeof(T);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Reset() { addr = iaddr; }
|
u64 GetAddr() const { return m_addr; }
|
||||||
u64 GetCurAddr() const { return addr; }
|
void SetAddr(const u64 addr) { m_addr = addr; }
|
||||||
u64 GetAddr() const { return iaddr; }
|
};
|
||||||
void SetAddr(const u64 _addr) { addr = _addr; }
|
|
||||||
|
template<typename T>
|
||||||
|
class MemoryAllocator
|
||||||
|
{
|
||||||
|
u32 m_addr;
|
||||||
|
u32 m_size;
|
||||||
|
T* m_ptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
MemoryAllocator(u32 size = sizeof(T), u32 align = 1)
|
||||||
|
: m_size(size)
|
||||||
|
, m_addr(Memory.Alloc(size, align))
|
||||||
|
, m_ptr((T*)&Memory[m_addr])
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~MemoryAllocator()
|
||||||
|
{
|
||||||
|
Memory.Free(m_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
T* operator -> ()
|
||||||
|
{
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* GetPtr()
|
||||||
|
{
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T* GetPtr() const
|
||||||
|
{
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T* operator -> () const
|
||||||
|
{
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GetAddr() const
|
||||||
|
{
|
||||||
|
return m_addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 GetSize() const
|
||||||
|
{
|
||||||
|
return m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsGood() const
|
||||||
|
{
|
||||||
|
return Memory.IsGoodAddr(m_addr, sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1>
|
||||||
|
operator const T1() const
|
||||||
|
{
|
||||||
|
return T1(*m_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1>
|
||||||
|
operator T1()
|
||||||
|
{
|
||||||
|
return T1(*m_ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator const T&() const
|
||||||
|
{
|
||||||
|
return *m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator T&()
|
||||||
|
{
|
||||||
|
return *m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator const T*() const
|
||||||
|
{
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
operator T*()
|
||||||
|
{
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T1>
|
||||||
|
operator const mem_t<T1>() const
|
||||||
|
{
|
||||||
|
return GetAddr();
|
||||||
|
}
|
||||||
|
|
||||||
|
operator const mem_struct_ptr_t<T>() const
|
||||||
|
{
|
||||||
|
return GetAddr();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename NT>
|
||||||
|
NT* To(uint offset = 0)
|
||||||
|
{
|
||||||
|
return (NT*)(m_ptr + offset);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef mem_t<u8> mem8_t;
|
typedef mem_t<u8> mem8_t;
|
||||||
|
@ -2297,22 +2297,22 @@ s64 SysCalls::DoFunc(const u32 id)
|
|||||||
case 0x1ea02e2f: FUNC_LOG_ERROR("TODO: cellFsArcadeHddSerialNumber");
|
case 0x1ea02e2f: FUNC_LOG_ERROR("TODO: cellFsArcadeHddSerialNumber");
|
||||||
case 0x2664c8ae: FUNC_LOG_ERROR("TODO: cellFsStReadInit");
|
case 0x2664c8ae: FUNC_LOG_ERROR("TODO: cellFsStReadInit");
|
||||||
case 0x27800c6b: FUNC_LOG_ERROR("TODO: cellFsStRead");
|
case 0x27800c6b: FUNC_LOG_ERROR("TODO: cellFsStRead");
|
||||||
case 0x2796fdf3: return cellFsRmdir(SC_ARGS_1);//FUNC_LOG_ERROR("TODO: cellFsRmdir");
|
case 0x2796fdf3: FUNC_LOG_ERROR("TODO: cellFsRmdir");
|
||||||
case 0x2cb51f0d: return cellFsClose(SC_ARGS_1);//FUNC_LOG_ERROR("TODO: cellFsClose");
|
case 0x2cb51f0d: FUNC_LOG_ERROR("TODO: cellFsClose");
|
||||||
case 0x2cf1296b: FUNC_LOG_ERROR("TODO: cellFsAllocateFileAreaByFdWithoutZeroFill");
|
case 0x2cf1296b: FUNC_LOG_ERROR("TODO: cellFsAllocateFileAreaByFdWithoutZeroFill");
|
||||||
case 0x3140f6e1: FUNC_LOG_ERROR("TODO: cellFsSetIoBuffer");
|
case 0x3140f6e1: FUNC_LOG_ERROR("TODO: cellFsSetIoBuffer");
|
||||||
case 0x3394f037: FUNC_LOG_ERROR("TODO: cellFsAllocateFileAreaByFdWithInitialData");
|
case 0x3394f037: FUNC_LOG_ERROR("TODO: cellFsAllocateFileAreaByFdWithInitialData");
|
||||||
case 0x3a1c8393: FUNC_LOG_ERROR("TODO: cellFsTruncate2");
|
case 0x3a1c8393: FUNC_LOG_ERROR("TODO: cellFsTruncate2");
|
||||||
case 0x3f61245c: return cellFsOpendir(SC_ARGS_2);//FUNC_LOG_ERROR("TODO: cellFsOpendir");
|
case 0x3f61245c: FUNC_LOG_ERROR("TODO: cellFsOpendir");
|
||||||
case 0x4cef342e: FUNC_LOG_ERROR("TODO: cellFsAioWrite");
|
case 0x4cef342e: FUNC_LOG_ERROR("TODO: cellFsAioWrite");
|
||||||
case 0x4d5ff8e2: return cellFsRead(SC_ARGS_4);//FUNC_LOG_ERROR("TODO: cellFsRead");
|
case 0x4d5ff8e2: FUNC_LOG_ERROR("TODO: cellFsRead");
|
||||||
case 0x5c74903d: return cellFsReaddir(SC_ARGS_3);//FUNC_LOG_ERROR("TODO: cellFsReaddir");
|
case 0x5c74903d: FUNC_LOG_ERROR("TODO: cellFsReaddir");
|
||||||
case 0x606f9f42: FUNC_LOG_ERROR("TODO: cellFsChangeFileSizeWithoutAllocation");
|
case 0x606f9f42: FUNC_LOG_ERROR("TODO: cellFsChangeFileSizeWithoutAllocation");
|
||||||
case 0x6d3bb15b: FUNC_LOG_ERROR("TODO: cellFsSdataOpenByFd");
|
case 0x6d3bb15b: FUNC_LOG_ERROR("TODO: cellFsSdataOpenByFd");
|
||||||
case 0x718bf5f8: return cellFsOpen(SC_ARGS_5);//FUNC_LOG_ERROR("TODO: cellFsOpen");
|
case 0x718bf5f8: FUNC_LOG_ERROR("TODO: cellFsOpen");
|
||||||
case 0x75f16dc5: FUNC_LOG_ERROR("TODO: cellFsSetIoBufferFromDefaultContainer");
|
case 0x75f16dc5: FUNC_LOG_ERROR("TODO: cellFsSetIoBufferFromDefaultContainer");
|
||||||
case 0x7a0329a1: FUNC_LOG_ERROR("TODO: cellFsAllocateFileAreaWithoutZeroFill");
|
case 0x7a0329a1: FUNC_LOG_ERROR("TODO: cellFsAllocateFileAreaWithoutZeroFill");
|
||||||
case 0x7de6dced: return cellFsStat(SC_ARGS_2); //FUNC_LOG_ERROR("TODO: cellFsStat");
|
case 0x7de6dced: FUNC_LOG_ERROR("TODO: cellFsStat");
|
||||||
case 0x7f13fc8c: FUNC_LOG_ERROR("TODO: cellFsAioCancel");
|
case 0x7f13fc8c: FUNC_LOG_ERROR("TODO: cellFsAioCancel");
|
||||||
case 0x7f4677a8: FUNC_LOG_ERROR("TODO: cellFsUnlink");
|
case 0x7f4677a8: FUNC_LOG_ERROR("TODO: cellFsUnlink");
|
||||||
case 0x81f33783: FUNC_LOG_ERROR("TODO: cellFsStReadPutCurrentAddr");
|
case 0x81f33783: FUNC_LOG_ERROR("TODO: cellFsStReadPutCurrentAddr");
|
||||||
@ -2326,11 +2326,11 @@ s64 SysCalls::DoFunc(const u32 id)
|
|||||||
case 0x9b882495: FUNC_LOG_ERROR("TODO: cellFsGetDirectoryEntries");
|
case 0x9b882495: FUNC_LOG_ERROR("TODO: cellFsGetDirectoryEntries");
|
||||||
case 0x9f951810: FUNC_LOG_ERROR("TODO: cellFsAioFinish");
|
case 0x9f951810: FUNC_LOG_ERROR("TODO: cellFsAioFinish");
|
||||||
case 0xa01ee33a: FUNC_LOG_ERROR("TODO: cellFsRegisterConversionCallback");
|
case 0xa01ee33a: FUNC_LOG_ERROR("TODO: cellFsRegisterConversionCallback");
|
||||||
case 0xa397d042: return cellFsLseek(SC_ARGS_4);//FUNC_LOG_ERROR("TODO: cellFsLseek");
|
case 0xa397d042: FUNC_LOG_ERROR("TODO: cellFsLseek");
|
||||||
case 0xaa3b4bcd: FUNC_LOG_ERROR("TODO: cellFsGetFreeSize");
|
case 0xaa3b4bcd: FUNC_LOG_ERROR("TODO: cellFsGetFreeSize");
|
||||||
case 0xb1840b53: FUNC_LOG_ERROR("TODO: cellFsSdataOpen");
|
case 0xb1840b53: FUNC_LOG_ERROR("TODO: cellFsSdataOpen");
|
||||||
case 0xb3afee8b: FUNC_LOG_ERROR("TODO: cellFsStReadGetRingBuf");
|
case 0xb3afee8b: FUNC_LOG_ERROR("TODO: cellFsStReadGetRingBuf");
|
||||||
case 0xba901fe6: return cellFsMkdir(SC_ARGS_2);//FUNC_LOG_ERROR("TODO: cellFsMkdir");
|
case 0xba901fe6: FUNC_LOG_ERROR("TODO: cellFsMkdir");
|
||||||
case 0xbd273a88: FUNC_LOG_ERROR("TODO: cellFsStReadGetRegid");
|
case 0xbd273a88: FUNC_LOG_ERROR("TODO: cellFsStReadGetRegid");
|
||||||
case 0xbef554a4: FUNC_LOG_ERROR("TODO: cellFsUtime");
|
case 0xbef554a4: FUNC_LOG_ERROR("TODO: cellFsUtime");
|
||||||
case 0xc1c507e7: FUNC_LOG_ERROR("TODO: cellFsAioRead");
|
case 0xc1c507e7: FUNC_LOG_ERROR("TODO: cellFsAioRead");
|
||||||
@ -2340,16 +2340,16 @@ s64 SysCalls::DoFunc(const u32 id)
|
|||||||
case 0xd73938df: FUNC_LOG_ERROR("TODO: cellFsStReadFinish");
|
case 0xd73938df: FUNC_LOG_ERROR("TODO: cellFsStReadFinish");
|
||||||
case 0xdb869f20: FUNC_LOG_ERROR("TODO: cellFsAioInit");
|
case 0xdb869f20: FUNC_LOG_ERROR("TODO: cellFsAioInit");
|
||||||
case 0xe15939c3: FUNC_LOG_ERROR("TODO: cellFsChangeFileSizeByFdWithoutAllocation");
|
case 0xe15939c3: FUNC_LOG_ERROR("TODO: cellFsChangeFileSizeByFdWithoutAllocation");
|
||||||
case 0xecdcf2ab: return cellFsWrite(SC_ARGS_4);//FUNC_LOG_ERROR("TODO: cellFsWrite");
|
case 0xecdcf2ab: FUNC_LOG_ERROR("TODO: cellFsWrite");
|
||||||
case 0xef3efa34: return cellFsFstat(SC_ARGS_2);//FUNC_LOG_ERROR("TODO: cellFsFstat");
|
case 0xef3efa34: FUNC_LOG_ERROR("TODO: cellFsFstat");
|
||||||
case 0xf12eecc8: return cellFsRename(SC_ARGS_2);//FUNC_LOG_ERROR("TODO: cellFsRename");
|
case 0xf12eecc8: FUNC_LOG_ERROR("TODO: cellFsRename");
|
||||||
case 0xf8e5d9a0: FUNC_LOG_ERROR("TODO: cellFsStReadStop");
|
case 0xf8e5d9a0: FUNC_LOG_ERROR("TODO: cellFsStReadStop");
|
||||||
case 0xf94baa80: FUNC_LOG_ERROR("TODO: cellFsUnregisterL10nCallbacks");
|
case 0xf94baa80: FUNC_LOG_ERROR("TODO: cellFsUnregisterL10nCallbacks");
|
||||||
case 0xff42dcc3: return cellFsClosedir(SC_ARGS_1);//FUNC_LOG_ERROR("TODO: cellFsClosedir");
|
case 0xff42dcc3: FUNC_LOG_ERROR("TODO: cellFsClosedir");
|
||||||
case 0x068fcbc6: FUNC_LOG_ERROR("TODO: sys_config_start");
|
case 0x068fcbc6: FUNC_LOG_ERROR("TODO: sys_config_start");
|
||||||
case 0x0d5f2c14: FUNC_LOG_ERROR("TODO: cellPadClearBuf");
|
case 0x0d5f2c14: FUNC_LOG_ERROR("TODO: cellPadClearBuf");
|
||||||
case 0x0e2dfaad: FUNC_LOG_ERROR("TODO: cellPadInfoPressMode");
|
case 0x0e2dfaad: FUNC_LOG_ERROR("TODO: cellPadInfoPressMode");
|
||||||
case 0x1cf98800: return cellPadInit(SC_ARGS_1);//FUNC_LOG_ERROR("TODO: cellPadInit");
|
case 0x1cf98800: FUNC_LOG_ERROR("TODO: cellPadInit");
|
||||||
case 0x1f71ecbe: FUNC_LOG_ERROR("TODO: cellKbGetConfiguration");
|
case 0x1f71ecbe: FUNC_LOG_ERROR("TODO: cellKbGetConfiguration");
|
||||||
case 0x2073b7f6: FUNC_LOG_ERROR("TODO: cellKbClearBuf");
|
case 0x2073b7f6: FUNC_LOG_ERROR("TODO: cellKbClearBuf");
|
||||||
case 0x20a97ba2: FUNC_LOG_ERROR("TODO: cellPadLddRegisterController");
|
case 0x20a97ba2: FUNC_LOG_ERROR("TODO: cellPadLddRegisterController");
|
||||||
@ -2365,24 +2365,24 @@ s64 SysCalls::DoFunc(const u32 id)
|
|||||||
case 0x4ab1fa77: FUNC_LOG_ERROR("TODO: cellKbCnvRawCode");
|
case 0x4ab1fa77: FUNC_LOG_ERROR("TODO: cellKbCnvRawCode");
|
||||||
case 0x4cc9b68d: FUNC_LOG_ERROR("TODO: cellPadPeriphGetInfo");
|
case 0x4cc9b68d: FUNC_LOG_ERROR("TODO: cellPadPeriphGetInfo");
|
||||||
case 0x4d0b3b1f: FUNC_LOG_ERROR("TODO: cellMouseInfoTabletMode");
|
case 0x4d0b3b1f: FUNC_LOG_ERROR("TODO: cellMouseInfoTabletMode");
|
||||||
case 0x4d9b75d5: return cellPadEnd();//FUNC_LOG_ERROR("TODO: cellPadEnd");
|
case 0x4d9b75d5: FUNC_LOG_ERROR("TODO: cellPadEnd");
|
||||||
case 0x578e3c98: return cellPadSetPortSetting(SC_ARGS_2);//FUNC_LOG_ERROR("TODO: cellPadSetPortSetting");
|
case 0x578e3c98: FUNC_LOG_ERROR("TODO: cellPadSetPortSetting");
|
||||||
case 0x5baf30fb: FUNC_LOG_ERROR("TODO: cellMouseGetInfo");
|
case 0x5baf30fb: FUNC_LOG_ERROR("TODO: cellMouseGetInfo");
|
||||||
case 0x5f81900c: FUNC_LOG_ERROR("TODO: sys_config_unregister_service");
|
case 0x5f81900c: FUNC_LOG_ERROR("TODO: sys_config_unregister_service");
|
||||||
case 0x6ae10596: FUNC_LOG_ERROR("TODO: sys_config_add_service_listener");
|
case 0x6ae10596: FUNC_LOG_ERROR("TODO: sys_config_add_service_listener");
|
||||||
case 0x6bc09c61: return cellPadGetDataExtra(SC_ARGS_3);//FUNC_LOG_ERROR("TODO: cellPadGetDataExtra");
|
case 0x6bc09c61: FUNC_LOG_ERROR("TODO: cellPadGetDataExtra");
|
||||||
case 0x6bd131f0: FUNC_LOG_ERROR("TODO: cellMouseGetDataList");
|
case 0x6bd131f0: FUNC_LOG_ERROR("TODO: cellMouseGetDataList");
|
||||||
case 0x6d367953: FUNC_LOG_ERROR("TODO: sys_config_stop");
|
case 0x6d367953: FUNC_LOG_ERROR("TODO: sys_config_stop");
|
||||||
case 0x78200559: FUNC_LOG_ERROR("TODO: cellPadInfoSensorMode");
|
case 0x78200559: FUNC_LOG_ERROR("TODO: cellPadInfoSensorMode");
|
||||||
case 0x78f058a2: FUNC_LOG_ERROR("TODO: sys_config_register_service");
|
case 0x78f058a2: FUNC_LOG_ERROR("TODO: sys_config_register_service");
|
||||||
case 0x7c5d5fc1: FUNC_LOG_ERROR("TODO: cellPadDbgPeriphRegisterDevice");
|
case 0x7c5d5fc1: FUNC_LOG_ERROR("TODO: cellPadDbgPeriphRegisterDevice");
|
||||||
case 0x8a00f264: FUNC_LOG_ERROR("TODO: cellPadPeriphGetData");
|
case 0x8a00f264: FUNC_LOG_ERROR("TODO: cellPadPeriphGetData");
|
||||||
case 0x8b72cda1: return cellPadGetData(SC_ARGS_2);//FUNC_LOG_ERROR("TODO: cellPadGetData");
|
case 0x8b72cda1: FUNC_LOG_ERROR("TODO: cellPadGetData");
|
||||||
case 0x8b8231e5: FUNC_LOG_ERROR("TODO: cellPadLddGetPortNo");
|
case 0x8b8231e5: FUNC_LOG_ERROR("TODO: cellPadLddGetPortNo");
|
||||||
case 0x94b98e39: FUNC_LOG_ERROR("TODO: cellPadDbgLddSetDataInsertMode");
|
case 0x94b98e39: FUNC_LOG_ERROR("TODO: cellPadDbgLddSetDataInsertMode");
|
||||||
case 0xa328cc35: FUNC_LOG_ERROR("TODO: cellMouseGetRawData");
|
case 0xa328cc35: FUNC_LOG_ERROR("TODO: cellMouseGetRawData");
|
||||||
case 0xa5f85e4d: FUNC_LOG_ERROR("TODO: cellKbSetCodeType");
|
case 0xa5f85e4d: FUNC_LOG_ERROR("TODO: cellKbSetCodeType");
|
||||||
case 0xa703a51d: return cellPadGetInfo2(SC_ARGS_1);//FUNC_LOG_ERROR("TODO: cellPadGetInfo2");
|
case 0xa703a51d: FUNC_LOG_ERROR("TODO: cellPadGetInfo2");
|
||||||
case 0xa74396e5: FUNC_LOG_ERROR("TODO: cellPadDbgLddRegisterController");
|
case 0xa74396e5: FUNC_LOG_ERROR("TODO: cellPadDbgLddRegisterController");
|
||||||
case 0xbafd6409: FUNC_LOG_ERROR("TODO: cellPadLddDataInsert");
|
case 0xbafd6409: FUNC_LOG_ERROR("TODO: cellPadLddDataInsert");
|
||||||
case 0xbe5be3ba: FUNC_LOG_ERROR("TODO: cellPadSetSensorMode");
|
case 0xbe5be3ba: FUNC_LOG_ERROR("TODO: cellPadSetSensorMode");
|
||||||
|
@ -21,53 +21,95 @@ enum
|
|||||||
CELL_GIFDEC_ERROR_CB_PARAM = 0x80611307,
|
CELL_GIFDEC_ERROR_CB_PARAM = 0x80611307,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CellGifDecStreamSrcSel
|
||||||
|
{
|
||||||
|
CELL_GIFDEC_FILE = 0, //Input from a file
|
||||||
|
CELL_GIFDEC_BUFFER = 1, //Input from a buffer
|
||||||
|
};
|
||||||
|
|
||||||
enum CellGifDecColorSpace
|
enum CellGifDecColorSpace
|
||||||
{
|
{
|
||||||
CELL_GIFDEC_RGBA = 10,
|
CELL_GIFDEC_RGBA = 10,
|
||||||
CELL_GIFDEC_ARGB = 20,
|
CELL_GIFDEC_ARGB = 20,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CellGifDecRecordType
|
||||||
|
{
|
||||||
|
CELL_GIFDEC_RECORD_TYPE_IMAGE_DESC = 1, // Image data block
|
||||||
|
CELL_GIFDEC_RECORD_TYPE_EXTENSION = 2, // Extension block
|
||||||
|
CELL_GIFDEC_RECORD_TYPE_TERMINATE = 3, // Trailer block
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CellGifDecDecodeStatus
|
||||||
|
{
|
||||||
|
CELL_GIFDEC_DEC_STATUS_FINISH = 0, //Decoding finished
|
||||||
|
CELL_GIFDEC_DEC_STATUS_STOP = 1, //Decoding halted
|
||||||
|
};
|
||||||
|
|
||||||
struct CellGifDecInfo
|
struct CellGifDecInfo
|
||||||
{
|
{
|
||||||
u32 SWidth;
|
be_t<u32> SWidth;
|
||||||
u32 SHeight;
|
be_t<u32> SHeight;
|
||||||
u32 SGlobalColorTableFlag;
|
be_t<u32> SGlobalColorTableFlag;
|
||||||
u32 SColorResolution;
|
be_t<u32> SColorResolution;
|
||||||
u32 SSortFlag;
|
be_t<u32> SSortFlag;
|
||||||
u32 SSizeOfGlobalColorTable;
|
be_t<u32> SSizeOfGlobalColorTable;
|
||||||
u32 SBackGroundColor;
|
be_t<u32> SBackGroundColor;
|
||||||
u32 SPixelAspectRatio;
|
be_t<u32> SPixelAspectRatio;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellGifDecSrc
|
struct CellGifDecSrc
|
||||||
{
|
{
|
||||||
u32 srcSelect; // CellGifDecStreamSrcSel
|
be_t<u32> srcSelect;
|
||||||
u32 fileName; // const char*
|
be_t<u32> fileName;
|
||||||
u64 fileOffset; // int64_t
|
be_t<s64> fileOffset;
|
||||||
u32 fileSize;
|
be_t<u64> fileSize;
|
||||||
u32 streamPtr;
|
be_t<u32> streamPtr;
|
||||||
u32 streamSize;
|
be_t<u32> streamSize;
|
||||||
u32 spuThreadEnable; // CellGifDecSpuThreadEna
|
be_t<u32> spuThreadEnable;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellGifDecInParam
|
struct CellGifDecInParam
|
||||||
{
|
{
|
||||||
u32 *commandPtr;
|
be_t<u32> commandPtr;
|
||||||
u32 colorSpace; // CellGifDecColorSpace
|
be_t<u32> colorSpace; // CellGifDecColorSpace
|
||||||
u8 outputColorAlpha1;
|
be_t<u8> outputColorAlpha1;
|
||||||
u8 outputColorAlpha2;
|
be_t<u8> outputColorAlpha2;
|
||||||
u8 reserved[2];
|
be_t<u8> reserved[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellGifDecOutParam
|
struct CellGifDecOutParam
|
||||||
{
|
{
|
||||||
u64 outputWidthByte;
|
be_t<u64> outputWidthByte;
|
||||||
u32 outputWidth;
|
be_t<u32> outputWidth;
|
||||||
u32 outputHeight;
|
be_t<u32> outputHeight;
|
||||||
u32 outputComponents;
|
be_t<u32> outputComponents;
|
||||||
u32 outputBitDepth;
|
be_t<u32> outputBitDepth;
|
||||||
u32 outputColorSpace; // CellGifDecColorSpace
|
be_t<u32> outputColorSpace; // CellGifDecColorSpace
|
||||||
u32 useMemorySpace;
|
be_t<u32> useMemorySpace;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CellGifDecExtension
|
||||||
|
{
|
||||||
|
be_t<u8> label;
|
||||||
|
be_t<u32> data;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CellGifDecDataOutInfo
|
||||||
|
{
|
||||||
|
be_t<u32> recordType;
|
||||||
|
CellGifDecExtension outExtension;
|
||||||
|
be_t<u32> status;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CellGifDecOpnInfo
|
||||||
|
{
|
||||||
|
be_t<u32> initSpaceAllocated;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CellGifDecDataCtrlParam
|
||||||
|
{
|
||||||
|
be_t<u64> outputBytesPerLine;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellGifDecSubHandle //Custom struct
|
struct CellGifDecSubHandle //Custom struct
|
||||||
@ -78,7 +120,6 @@ struct CellGifDecSubHandle //Custom struct
|
|||||||
CellGifDecOutParam outParam;
|
CellGifDecOutParam outParam;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int cellGifDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam)
|
int cellGifDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED_FUNC(cellGifDec);
|
UNIMPLEMENTED_FUNC(cellGifDec);
|
||||||
@ -91,164 +132,188 @@ int cellGifDecExtCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam, u
|
|||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellGifDecOpen(u32 mainHandle, mem32_t subHandle, u32 src_addr, u32 openInfo)
|
int cellGifDecOpen(u32 mainHandle, mem32_t subHandle, const mem_struct_ptr_t<CellGifDecSrc> src, mem_struct_ptr_t<CellGifDecOpnInfo> openInfo)
|
||||||
{
|
{
|
||||||
//u32 srcSelect = Memory.Read32(src_addr);
|
/*
|
||||||
u32 fileName = Memory.Read32(src_addr+4);
|
vfsStream* stream;
|
||||||
//u64 fileOffset = Memory.Read32(src_addr+8);
|
|
||||||
//u32 fileSize = Memory.Read32(src_addr+12);
|
switch(src->srcSelect)
|
||||||
//u32 streamPtr = Memory.Read32(src_addr+16);
|
{
|
||||||
//u32 streamSize = Memory.Read32(src_addr+20);
|
case CELL_GIFDEC_FILE:
|
||||||
//u32 spuThreadEnable = Memory.Read32(src_addr+24);
|
stream = Emu.GetVFS().Open(src->fileName.GetString(), vfsRead);
|
||||||
|
stream->Seek(src->fileOffset);
|
||||||
|
src->fileSize;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CELL_GIFDEC_BUFFER:
|
||||||
|
if(src->streamSize < 5)
|
||||||
|
return CELL_GIFDEC_ERROR_ARG;
|
||||||
|
|
||||||
|
stream = new vfsStreamMemory(src->streamPtr.GetAddr(), src->streamSize);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return CELL_GIFDEC_ERROR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!stream->IsOpened())
|
||||||
|
{
|
||||||
|
return CELL_GIFDEC_ERROR_OPEN_FILE;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
CellGifDecSubHandle *current_subHandle = new CellGifDecSubHandle;
|
CellGifDecSubHandle *current_subHandle = new CellGifDecSubHandle;
|
||||||
|
|
||||||
// Get file descriptor
|
// Get file descriptor
|
||||||
u32 fd_addr = Memory.Alloc(sizeof(u32), 1);
|
MemoryAllocator<be_t<u32>> fd;
|
||||||
int ret = cellFsOpen(fileName, 0, fd_addr, NULL, 0);
|
int ret = cellFsOpen(src->fileName, 0, fd, NULL, 0);
|
||||||
current_subHandle->fd = Memory.Read32(fd_addr);
|
current_subHandle->fd = fd->ToLE();
|
||||||
Memory.Free(fd_addr);
|
if(ret != CELL_OK) return CELL_GIFDEC_ERROR_OPEN_FILE;
|
||||||
if(ret != 0) return CELL_GIFDEC_ERROR_OPEN_FILE;
|
|
||||||
|
|
||||||
// Get size of file
|
// Get size of file
|
||||||
u32 sb_addr = Memory.Alloc(52,1); // Alloc a CellFsStat struct
|
MemoryAllocator<CellFsStat> sb; // Alloc a CellFsStat struct
|
||||||
cellFsFstat(current_subHandle->fd, sb_addr);
|
ret = cellFsFstat(current_subHandle->fd, sb);
|
||||||
current_subHandle->fileSize = Memory.Read64(sb_addr+36); // Get CellFsStat.st_size
|
if(ret != CELL_OK) return ret;
|
||||||
Memory.Free(sb_addr);
|
current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size
|
||||||
|
|
||||||
// From now, every u32 subHandle argument is a pointer to a CellPngDecSubHandle struct.
|
// From now, every u32 subHandle argument is a pointer to a CellPngDecSubHandle struct.
|
||||||
subHandle += (u32)current_subHandle;
|
subHandle = cellGifDec.GetNewId(current_subHandle);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellGifDecReadHeader(u32 mainHandle, u32 subHandle, mem_class_t info)
|
int cellGifDecReadHeader(u32 mainHandle, u32 subHandle, mem_struct_ptr_t<CellGifDecInfo> info)
|
||||||
{
|
{
|
||||||
const u32& fd = ((CellGifDecSubHandle*)subHandle)->fd;
|
ID sub_handle_id_data;
|
||||||
const u64& fileSize = ((CellGifDecSubHandle*)subHandle)->fileSize;
|
if(!cellGifDec.CheckId(subHandle, sub_handle_id_data))
|
||||||
CellGifDecInfo& current_info = ((CellGifDecSubHandle*)subHandle)->info;
|
return CELL_GIFDEC_ERROR_FATAL;
|
||||||
|
|
||||||
|
auto subHandle_data = (CellGifDecSubHandle*)sub_handle_id_data.m_data;
|
||||||
|
|
||||||
|
const u32& fd = subHandle_data->fd;
|
||||||
|
const u64& fileSize = subHandle_data->fileSize;
|
||||||
|
CellGifDecInfo& current_info = subHandle_data->info;
|
||||||
|
|
||||||
//Write the header to buffer
|
//Write the header to buffer
|
||||||
u32 buffer = Memory.Alloc(13,1); // Alloc buffer for GIF header
|
MemoryAllocator<u8> buffer(13); // Alloc buffer for GIF header
|
||||||
u32 nread = Memory.Alloc(8,1);
|
MemoryAllocator<be_t<u64>> pos, nread;
|
||||||
u32 pos_addr = Memory.Alloc(8,1);
|
|
||||||
cellFsLseek(fd, 0, 0, pos_addr);
|
|
||||||
cellFsRead(fd, buffer, 13, nread);
|
|
||||||
Memory.Free(nread);
|
|
||||||
Memory.Free(pos_addr);
|
|
||||||
|
|
||||||
if (Memory.Read32(buffer) != 0x47494638 ||
|
cellFsLseek(fd, 0, CELL_SEEK_SET, pos);
|
||||||
(Memory.Read16(buffer+4) != 0x3961 &&
|
cellFsRead(fd, buffer.GetAddr(), buffer.GetSize(), nread);
|
||||||
Memory.Read16(buffer+4) != 0x3761)) // Error: The first 6 bytes are not a valid GIF signature
|
|
||||||
|
if (*buffer.To<be_t<u32>>(0) != 0x47494638 ||
|
||||||
|
(*buffer.To<u16>(4) != 0x6139 && *buffer.To<u16>(4) != 0x6137)) // Error: The first 6 bytes are not a valid GIF signature
|
||||||
{
|
{
|
||||||
Memory.Free(buffer);
|
|
||||||
return CELL_GIFDEC_ERROR_STREAM_FORMAT; // Surprisingly there is no error code related with headerss
|
return CELL_GIFDEC_ERROR_STREAM_FORMAT; // Surprisingly there is no error code related with headerss
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 packedField = Memory.Read8(buffer+10);
|
u8 packedField = buffer[10];
|
||||||
current_info.SWidth = Memory.Read8(buffer+6) + Memory.Read8(buffer+7) * 256;
|
current_info.SWidth = buffer[6] + buffer[7] * 0x100;
|
||||||
current_info.SHeight = Memory.Read8(buffer+8) + Memory.Read8(buffer+9) * 256;
|
current_info.SHeight = buffer[8] + buffer[9] * 0x100;
|
||||||
current_info.SGlobalColorTableFlag = packedField >> 7;
|
current_info.SGlobalColorTableFlag = packedField >> 7;
|
||||||
current_info.SColorResolution = ((packedField >> 4) & 7)+1;
|
current_info.SColorResolution = ((packedField >> 4) & 7)+1;
|
||||||
current_info.SSortFlag = (packedField >> 3) & 1;
|
current_info.SSortFlag = (packedField >> 3) & 1;
|
||||||
current_info.SSizeOfGlobalColorTable = (packedField & 7)+1;
|
current_info.SSizeOfGlobalColorTable = (packedField & 7)+1;
|
||||||
current_info.SBackGroundColor = Memory.Read8(buffer+11);
|
current_info.SBackGroundColor = buffer[11];
|
||||||
current_info.SPixelAspectRatio = Memory.Read8(buffer+12);
|
current_info.SPixelAspectRatio = buffer[12];
|
||||||
|
|
||||||
info += current_info.SWidth;
|
info = current_info;
|
||||||
info += current_info.SHeight;
|
|
||||||
info += current_info.SGlobalColorTableFlag;
|
|
||||||
info += current_info.SColorResolution;
|
|
||||||
info += current_info.SSortFlag;
|
|
||||||
info += current_info.SSizeOfGlobalColorTable;
|
|
||||||
info += current_info.SBackGroundColor;
|
|
||||||
info += current_info.SPixelAspectRatio;
|
|
||||||
Memory.Free(buffer);
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellGifDecSetParameter(u32 mainHandle, u32 subHandle, u32 inParam_addr, mem_class_t outParam)
|
int cellGifDecSetParameter(u32 mainHandle, u32 subHandle, const mem_struct_ptr_t<CellGifDecInParam> inParam, mem_struct_ptr_t<CellGifDecOutParam> outParam)
|
||||||
{
|
{
|
||||||
CellGifDecInfo& current_info = ((CellGifDecSubHandle*)subHandle)->info;
|
ID sub_handle_id_data;
|
||||||
CellGifDecOutParam& current_outParam = ((CellGifDecSubHandle*)subHandle)->outParam;
|
if(!cellGifDec.CheckId(subHandle, sub_handle_id_data))
|
||||||
|
return CELL_GIFDEC_ERROR_FATAL;
|
||||||
|
|
||||||
|
auto subHandle_data = (CellGifDecSubHandle*)sub_handle_id_data.m_data;
|
||||||
|
|
||||||
|
CellGifDecInfo& current_info = subHandle_data->info;
|
||||||
|
CellGifDecOutParam& current_outParam = subHandle_data->outParam;
|
||||||
|
|
||||||
current_outParam.outputWidthByte = (current_info.SWidth * current_info.SColorResolution * 3)/8;
|
current_outParam.outputWidthByte = (current_info.SWidth * current_info.SColorResolution * 3)/8;
|
||||||
current_outParam.outputWidth = current_info.SWidth;
|
current_outParam.outputWidth = current_info.SWidth;
|
||||||
current_outParam.outputHeight = current_info.SHeight;
|
current_outParam.outputHeight = current_info.SHeight;
|
||||||
current_outParam.outputColorSpace = Memory.Read32(inParam_addr+4);
|
current_outParam.outputColorSpace = inParam->colorSpace;
|
||||||
switch (current_outParam.outputColorSpace)
|
switch (current_outParam.outputColorSpace)
|
||||||
{
|
{
|
||||||
case CELL_GIFDEC_RGBA: current_outParam.outputComponents = 4; break;
|
case CELL_GIFDEC_RGBA:
|
||||||
case CELL_GIFDEC_ARGB: current_outParam.outputComponents = 4; break;
|
case CELL_GIFDEC_ARGB: current_outParam.outputComponents = 4; break;
|
||||||
default: return CELL_GIFDEC_ERROR_ARG; // Not supported color space
|
default: return CELL_GIFDEC_ERROR_ARG; // Not supported color space
|
||||||
}
|
}
|
||||||
current_outParam.outputBitDepth = 0; // Unimplemented
|
current_outParam.outputBitDepth = 0; // Unimplemented
|
||||||
current_outParam.useMemorySpace = 0; // Unimplemented
|
current_outParam.useMemorySpace = 0; // Unimplemented
|
||||||
|
|
||||||
outParam += current_outParam.outputWidthByte;
|
outParam = current_outParam;
|
||||||
outParam += current_outParam.outputWidth;
|
|
||||||
outParam += current_outParam.outputHeight;
|
|
||||||
outParam += current_outParam.outputComponents;
|
|
||||||
outParam += current_outParam.outputBitDepth;
|
|
||||||
outParam += current_outParam.outputColorSpace;
|
|
||||||
outParam += current_outParam.useMemorySpace;
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, u32 dataCtrlParam_addr, mem_class_t dataOutInfo)
|
int cellGifDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const mem_struct_ptr_t<CellGifDecDataCtrlParam> dataCtrlParam, mem_struct_ptr_t<CellGifDecDataOutInfo> dataOutInfo)
|
||||||
{
|
{
|
||||||
const u32& fd = ((CellGifDecSubHandle*)subHandle)->fd;
|
dataOutInfo->status = CELL_GIFDEC_DEC_STATUS_STOP;
|
||||||
const u64& fileSize = ((CellGifDecSubHandle*)subHandle)->fileSize;
|
|
||||||
const CellGifDecOutParam& current_outParam = ((CellGifDecSubHandle*)subHandle)->outParam; // (TODO: We should use the outParam)
|
ID sub_handle_id_data;
|
||||||
|
if(!cellGifDec.CheckId(subHandle, sub_handle_id_data))
|
||||||
|
return CELL_GIFDEC_ERROR_FATAL;
|
||||||
|
|
||||||
|
auto subHandle_data = (CellGifDecSubHandle*)sub_handle_id_data.m_data;
|
||||||
|
|
||||||
|
const u32& fd = subHandle_data->fd;
|
||||||
|
const u64& fileSize = subHandle_data->fileSize;
|
||||||
|
const CellGifDecOutParam& current_outParam = subHandle_data->outParam;
|
||||||
|
|
||||||
//Copy the GIF file to a buffer
|
//Copy the GIF file to a buffer
|
||||||
u32 buffer = Memory.Alloc(fileSize,1);
|
MemoryAllocator<unsigned char> gif(fileSize);
|
||||||
u32 nread = Memory.Alloc(8,1);
|
MemoryAllocator<u64> pos, nread;
|
||||||
u32 pos_addr = Memory.Alloc(8,1);
|
cellFsLseek(fd, 0, CELL_SEEK_SET, pos);
|
||||||
cellFsLseek(fd, 0, 0, pos_addr);
|
cellFsRead(fd, gif.GetAddr(), gif.GetSize(), nread);
|
||||||
cellFsRead(fd, buffer, fileSize, nread);
|
|
||||||
Memory.Free(nread);
|
|
||||||
Memory.Free(pos_addr);
|
|
||||||
|
|
||||||
//Decode GIF file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
//Decode GIF file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
||||||
int width, height, actual_components;
|
int width, height, actual_components;
|
||||||
unsigned char *gif = (unsigned char*)Memory.VirtualToRealAddr(buffer);
|
std::shared_ptr<unsigned char> image(stbi_load_from_memory(gif, fileSize, &width, &height, &actual_components, 4));
|
||||||
unsigned char *image = stbi_load_from_memory(gif, fileSize, &width, &height, &actual_components, 4);
|
|
||||||
Memory.Free(buffer);
|
|
||||||
if (!image) return CELL_GIFDEC_ERROR_STREAM_FORMAT;
|
if (!image) return CELL_GIFDEC_ERROR_STREAM_FORMAT;
|
||||||
|
|
||||||
u32 image_size = width * height * 4;
|
uint image_size = width * height * 4;
|
||||||
if (current_outParam.outputColorSpace == CELL_GIFDEC_RGBA){
|
|
||||||
for(u32 i = 0; i < image_size; i+=4){
|
|
||||||
data += image[i+0];
|
|
||||||
data += image[i+1];
|
|
||||||
data += image[i+2];
|
|
||||||
data += image[i+3];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (current_outParam.outputColorSpace == CELL_GIFDEC_ARGB){
|
|
||||||
for(u32 i = 0; i < image_size; i+=4){
|
|
||||||
data += image[i+3];
|
|
||||||
data += image[i+0];
|
|
||||||
data += image[i+1];
|
|
||||||
data += image[i+2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete[] image;
|
|
||||||
|
|
||||||
dataOutInfo += (u32)1; // The output data is an image (dataOutInfo.recordType = 1)
|
switch(current_outParam.outputColorSpace)
|
||||||
dataOutInfo += (u32)0; // outExtension.label = 0
|
{
|
||||||
dataOutInfo += Memory.Alloc(20,1); // outExtension.data allocated (TODO: Is this the best way to avoid exceptions when trying to access this data? Will this produce a memory leak?)
|
case CELL_GIFDEC_RGBA:
|
||||||
|
memcpy(data, image.get(), image_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CELL_GIFDEC_ARGB:
|
||||||
|
for(uint i = 0; i < image_size; i+=4)
|
||||||
|
{
|
||||||
|
data += image.get()[i+3];
|
||||||
|
data += image.get()[i+0];
|
||||||
|
data += image.get()[i+1];
|
||||||
|
data += image.get()[i+2];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return CELL_GIFDEC_ERROR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
dataOutInfo->status = CELL_GIFDEC_DEC_STATUS_FINISH;
|
||||||
|
dataOutInfo->recordType = CELL_GIFDEC_RECORD_TYPE_IMAGE_DESC;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellGifDecClose(u32 mainHandle, u32 subHandle)
|
int cellGifDecClose(u32 mainHandle, u32 subHandle)
|
||||||
{
|
{
|
||||||
cellFsClose( ((CellGifDecSubHandle*)subHandle)->fd );
|
ID sub_handle_id_data;
|
||||||
delete (CellGifDecSubHandle*)subHandle;
|
if(!cellGifDec.CheckId(subHandle, sub_handle_id_data))
|
||||||
|
return CELL_GIFDEC_ERROR_FATAL;
|
||||||
|
|
||||||
|
auto subHandle_data = (CellGifDecSubHandle*)sub_handle_id_data.m_data;
|
||||||
|
|
||||||
|
cellFsClose(subHandle_data->fd);
|
||||||
|
Emu.GetIdManager().RemoveID(subHandle);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -34,48 +34,72 @@ enum CellJpgDecColorSpace
|
|||||||
CELL_JPG_GRAYSCALE_TO_ALPHA_ARGB = 41,
|
CELL_JPG_GRAYSCALE_TO_ALPHA_ARGB = 41,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CellJpgDecDecodeStatus
|
||||||
|
{
|
||||||
|
CELL_JPGDEC_DEC_STATUS_FINISH = 0, //Decoding finished
|
||||||
|
CELL_JPGDEC_DEC_STATUS_STOP = 1, //Decoding halted
|
||||||
|
};
|
||||||
|
|
||||||
struct CellJpgDecInfo
|
struct CellJpgDecInfo
|
||||||
{
|
{
|
||||||
u32 imageWidth;
|
be_t<u32> imageWidth;
|
||||||
u32 imageHeight;
|
be_t<u32> imageHeight;
|
||||||
u32 numComponents;
|
be_t<u32> numComponents;
|
||||||
u32 colorSpace; // CellJpgDecColorSpace
|
be_t<u32> colorSpace; // CellJpgDecColorSpace
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellJpgDecSrc
|
struct CellJpgDecSrc
|
||||||
{
|
{
|
||||||
u32 srcSelect; // CellJpgDecStreamSrcSel
|
be_t<u32> srcSelect; // CellJpgDecStreamSrcSel
|
||||||
u32 fileName; // const char*
|
be_t<u32> fileName; // const char*
|
||||||
u64 fileOffset; // int64_t
|
be_t<u64> fileOffset; // int64_t
|
||||||
u32 fileSize;
|
be_t<u32> fileSize;
|
||||||
u32 streamPtr;
|
be_t<u32> streamPtr;
|
||||||
u32 streamSize;
|
be_t<u32> streamSize;
|
||||||
u32 spuThreadEnable; // CellJpgDecSpuThreadEna
|
be_t<u32> spuThreadEnable; // CellJpgDecSpuThreadEna
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellJpgDecInParam
|
struct CellJpgDecInParam
|
||||||
{
|
{
|
||||||
u32 *commandPtr;
|
be_t<u32> commandPtr;
|
||||||
u32 downScale;
|
be_t<u32> downScale;
|
||||||
u32 method; // CellJpgDecMethod
|
be_t<u32> method; // CellJpgDecMethod
|
||||||
u32 outputMode; // CellJpgDecOutputMode
|
be_t<u32> outputMode; // CellJpgDecOutputMode
|
||||||
u32 outputColorSpace; // CellJpgDecColorSpace
|
be_t<u32> outputColorSpace; // CellJpgDecColorSpace
|
||||||
u8 outputColorAlpha;
|
be_t<u8> outputColorAlpha;
|
||||||
u8 reserved[3];
|
be_t<u8> reserved[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellJpgDecOutParam
|
struct CellJpgDecOutParam
|
||||||
{
|
{
|
||||||
u64 outputWidthByte;
|
be_t<u64> outputWidthByte;
|
||||||
u32 outputWidth;
|
be_t<u32> outputWidth;
|
||||||
u32 outputHeight;
|
be_t<u32> outputHeight;
|
||||||
u32 outputComponents;
|
be_t<u32> outputComponents;
|
||||||
u32 outputMode; // CellJpgDecOutputMode
|
be_t<u32> outputMode; // CellJpgDecOutputMode
|
||||||
u32 outputColorSpace; // CellJpgDecColorSpace
|
be_t<u32> outputColorSpace; // CellJpgDecColorSpace
|
||||||
u32 downScale;
|
be_t<u32> downScale;
|
||||||
u32 useMemorySpace;
|
be_t<u32> useMemorySpace;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct CellJpgDecOpnInfo
|
||||||
|
{
|
||||||
|
be_t<u32> initSpaceAllocated;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CellJpgDecDataCtrlParam
|
||||||
|
{
|
||||||
|
be_t<u64> outputBytesPerLine;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CellJpgDecDataOutInfo
|
||||||
|
{
|
||||||
|
be_t<float> mean;
|
||||||
|
be_t<u32> outputLines;
|
||||||
|
be_t<u32> status;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct CellJpgDecSubHandle //Custom struct
|
struct CellJpgDecSubHandle //Custom struct
|
||||||
{
|
{
|
||||||
u32 fd;
|
u32 fd;
|
||||||
@ -84,7 +108,6 @@ struct CellJpgDecSubHandle //Custom struct
|
|||||||
CellJpgDecOutParam outParam;
|
CellJpgDecOutParam outParam;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int cellJpgDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam)
|
int cellJpgDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED_FUNC(cellJpgDec);
|
UNIMPLEMENTED_FUNC(cellJpgDec);
|
||||||
@ -103,11 +126,11 @@ int cellJpgDecDestroy(u32 mainHandle)
|
|||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellJpgDecOpen(u32 mainHandle, mem32_t subHandle, u32 src_addr, u32 openInfo)
|
int cellJpgDecOpen(u32 mainHandle, mem32_t subHandle, u32 src_addr, mem_struct_ptr_t<CellJpgDecOpnInfo> openInfo)
|
||||||
{
|
{
|
||||||
//u32 srcSelect = Memory.Read32(src_addr);
|
//u32 srcSelect = Memory.Read32(src_addr);
|
||||||
u32 fileName = Memory.Read32(src_addr+4);
|
u32 fileName = Memory.Read32(src_addr+4);
|
||||||
//u64 fileOffset = Memory.Read32(src_addr+8);
|
//u32 fileOffset = Memory.Read32(src_addr+8);
|
||||||
//u32 fileSize = Memory.Read32(src_addr+12);
|
//u32 fileSize = Memory.Read32(src_addr+12);
|
||||||
//u32 streamPtr = Memory.Read32(src_addr+16);
|
//u32 streamPtr = Memory.Read32(src_addr+16);
|
||||||
//u32 streamSize = Memory.Read32(src_addr+20);
|
//u32 streamSize = Memory.Read32(src_addr+20);
|
||||||
@ -116,165 +139,200 @@ int cellJpgDecOpen(u32 mainHandle, mem32_t subHandle, u32 src_addr, u32 openInfo
|
|||||||
CellJpgDecSubHandle *current_subHandle = new CellJpgDecSubHandle;
|
CellJpgDecSubHandle *current_subHandle = new CellJpgDecSubHandle;
|
||||||
|
|
||||||
// Get file descriptor
|
// Get file descriptor
|
||||||
u32 fd_addr = Memory.Alloc(sizeof(u32), 1);
|
MemoryAllocator<be_t<u32>> fd;
|
||||||
int ret = cellFsOpen(fileName, 0, fd_addr, NULL, 0);
|
int ret = cellFsOpen(fileName, 0, fd, NULL, 0);
|
||||||
current_subHandle->fd = Memory.Read32(fd_addr);
|
current_subHandle->fd = fd->ToLE();
|
||||||
Memory.Free(fd_addr);
|
if(ret != CELL_OK) return CELL_JPGDEC_ERROR_OPEN_FILE;
|
||||||
if(ret != 0) return CELL_JPGDEC_ERROR_OPEN_FILE;
|
|
||||||
|
|
||||||
// Get size of file
|
// Get size of file
|
||||||
u32 sb_addr = Memory.Alloc(52,1); // Alloc a CellFsStat struct
|
MemoryAllocator<CellFsStat> sb; // Alloc a CellFsStat struct
|
||||||
cellFsFstat(current_subHandle->fd, sb_addr);
|
ret = cellFsFstat(current_subHandle->fd, sb);
|
||||||
current_subHandle->fileSize = Memory.Read64(sb_addr+36); // Get CellFsStat.st_size
|
if(ret != CELL_OK) return ret;
|
||||||
Memory.Free(sb_addr);
|
current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size
|
||||||
|
|
||||||
// From now, every u32 subHandle argument is a pointer to a CellPngDecSubHandle struct.
|
// From now, every u32 subHandle argument is a pointer to a CellPngDecSubHandle struct.
|
||||||
subHandle += (u32)current_subHandle;
|
subHandle = cellJpgDec.GetNewId(current_subHandle);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellJpgDecClose(u32 mainHandle, u32 subHandle)
|
int cellJpgDecClose(u32 mainHandle, u32 subHandle)
|
||||||
{
|
{
|
||||||
cellFsClose( ((CellJpgDecSubHandle*)subHandle)->fd );
|
ID sub_handle_id_data;
|
||||||
delete (CellJpgDecSubHandle*)subHandle;
|
if(!cellJpgDec.CheckId(subHandle, sub_handle_id_data))
|
||||||
|
return CELL_JPGDEC_ERROR_FATAL;
|
||||||
|
|
||||||
|
auto subHandle_data = (CellJpgDecSubHandle*)sub_handle_id_data.m_data;
|
||||||
|
|
||||||
|
cellFsClose(subHandle_data->fd);
|
||||||
|
Emu.GetIdManager().RemoveID(subHandle);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, mem_class_t info)
|
int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, mem_struct_ptr_t<CellJpgDecInfo> info)
|
||||||
{
|
{
|
||||||
const u32& fd = ((CellJpgDecSubHandle*)subHandle)->fd;
|
cellJpgDec.Log("cellJpgDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%llx)", mainHandle, subHandle, info.GetAddr());
|
||||||
const u64& fileSize = ((CellJpgDecSubHandle*)subHandle)->fileSize;
|
ID sub_handle_id_data;
|
||||||
CellJpgDecInfo& current_info = ((CellJpgDecSubHandle*)subHandle)->info;
|
if(!cellJpgDec.CheckId(subHandle, sub_handle_id_data))
|
||||||
|
return CELL_JPGDEC_ERROR_FATAL;
|
||||||
|
|
||||||
|
auto subHandle_data = (CellJpgDecSubHandle*)sub_handle_id_data.m_data;
|
||||||
|
|
||||||
|
const u32& fd = subHandle_data->fd;
|
||||||
|
const u64& fileSize = subHandle_data->fileSize;
|
||||||
|
CellJpgDecInfo& current_info = subHandle_data->info;
|
||||||
|
|
||||||
//Copy the JPG file to a buffer
|
//Copy the JPG file to a buffer
|
||||||
u32 buffer = Memory.Alloc(fileSize,1);
|
MemoryAllocator<u8> buffer(fileSize);
|
||||||
u32 nread = Memory.Alloc(8,1);
|
MemoryAllocator<be_t<u64>> pos, nread;
|
||||||
u32 pos_addr = Memory.Alloc(8,1);
|
|
||||||
cellFsLseek(fd, 0, 0, pos_addr);
|
|
||||||
cellFsRead(fd, buffer, fileSize, nread);
|
|
||||||
Memory.Free(nread);
|
|
||||||
Memory.Free(pos_addr);
|
|
||||||
|
|
||||||
if (Memory.Read32(buffer) != 0xFFD8FFE0 || // Error: Not a valid SOI header
|
cellFsLseek(fd, 0, CELL_SEEK_SET, pos);
|
||||||
Memory.Read32(buffer+6) != 0x4A464946) // Error: Not a valid JFIF string
|
cellFsRead(fd, buffer.GetAddr(), buffer.GetSize(), nread);
|
||||||
|
|
||||||
|
if (*buffer.To<u32>(0) != 0xE0FFD8FF || // Error: Not a valid SOI header
|
||||||
|
*buffer.To<u32>(6) != 0x4649464A) // Error: Not a valid JFIF string
|
||||||
{
|
{
|
||||||
Memory.Free(buffer);
|
|
||||||
return CELL_JPGDEC_ERROR_HEADER;
|
return CELL_JPGDEC_ERROR_HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 i = 4;
|
u32 i = 4;
|
||||||
u16 block_length = Memory.Read8(buffer+i)*0xFF + Memory.Read8(buffer+i+1);
|
|
||||||
while(i < fileSize)
|
if(i >= fileSize)
|
||||||
|
return CELL_JPGDEC_ERROR_HEADER;
|
||||||
|
|
||||||
|
u16 block_length = buffer[i] * 0xFF + buffer[i+1];
|
||||||
|
|
||||||
|
while(true)
|
||||||
{
|
{
|
||||||
i += block_length; // Increase the file index to get to the next block
|
i += block_length; // Increase the file index to get to the next block
|
||||||
if (i >= fileSize){
|
if (i >= fileSize || // Check to protect against segmentation faults
|
||||||
Memory.Free(buffer);
|
buffer[i] != 0xFF) // Check that we are truly at the start of another block
|
||||||
return CELL_JPGDEC_ERROR_HEADER; // Check to protect against segmentation faults
|
{
|
||||||
|
return CELL_JPGDEC_ERROR_HEADER;
|
||||||
}
|
}
|
||||||
if(Memory.Read8(buffer+i) != 0xFF){
|
|
||||||
Memory.Free(buffer);
|
if(buffer[i+1] == 0xC0)
|
||||||
return CELL_JPGDEC_ERROR_HEADER; // Check that we are truly at the start of another block
|
|
||||||
}
|
|
||||||
if(Memory.Read8(buffer+i+1) == 0xC0){
|
|
||||||
break; // 0xFFC0 is the "Start of frame" marker which contains the file size
|
break; // 0xFFC0 is the "Start of frame" marker which contains the file size
|
||||||
}
|
|
||||||
i += 2; // Skip the block marker
|
i += 2; // Skip the block marker
|
||||||
block_length = Memory.Read8(buffer+i)*0xFF + Memory.Read8(buffer+i+1); // Go to the next block
|
block_length = buffer[i] * 0xFF + buffer[i+1]; // Go to the next block
|
||||||
}
|
}
|
||||||
|
|
||||||
current_info.imageWidth = Memory.Read8(buffer+i+7)*256 + Memory.Read8(buffer+i+8);
|
current_info.imageWidth = buffer[i+7]*0x100 + buffer[i+8];
|
||||||
current_info.imageHeight = Memory.Read8(buffer+i+5)*256 + Memory.Read8(buffer+i+6);
|
current_info.imageHeight = buffer[i+5]*0x100 + buffer[i+6];
|
||||||
current_info.numComponents = 3; // Unimplemented
|
current_info.numComponents = 3; // Unimplemented
|
||||||
current_info.colorSpace = CELL_JPG_RGB; // Unimplemented
|
current_info.colorSpace = CELL_JPG_RGB;
|
||||||
|
|
||||||
info += current_info.imageWidth;
|
info = current_info;
|
||||||
info += current_info.imageHeight;
|
|
||||||
info += current_info.numComponents;
|
|
||||||
info += current_info.colorSpace;
|
|
||||||
Memory.Free(buffer);
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, u32 dataCtrlParam_addr, u32 dataOutInfo_addr)
|
int cellJpgDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const mem_struct_ptr_t<CellJpgDecDataCtrlParam> dataCtrlParam, mem_struct_ptr_t<CellJpgDecDataOutInfo> dataOutInfo)
|
||||||
{
|
{
|
||||||
const u32& fd = ((CellJpgDecSubHandle*)subHandle)->fd;
|
dataOutInfo->status = CELL_JPGDEC_DEC_STATUS_STOP;
|
||||||
const u64& fileSize = ((CellJpgDecSubHandle*)subHandle)->fileSize;
|
ID sub_handle_id_data;
|
||||||
const CellJpgDecOutParam& current_outParam = ((CellJpgDecSubHandle*)subHandle)->outParam; // (TODO: We should use the outParam)
|
if(!cellJpgDec.CheckId(subHandle, sub_handle_id_data))
|
||||||
|
return CELL_JPGDEC_ERROR_FATAL;
|
||||||
|
|
||||||
|
auto subHandle_data = (CellJpgDecSubHandle*)sub_handle_id_data.m_data;
|
||||||
|
|
||||||
|
const u32& fd = subHandle_data->fd;
|
||||||
|
const u64& fileSize = subHandle_data->fileSize;
|
||||||
|
const CellJpgDecOutParam& current_outParam = subHandle_data->outParam;
|
||||||
|
|
||||||
//Copy the JPG file to a buffer
|
//Copy the JPG file to a buffer
|
||||||
u32 buffer = Memory.Alloc(fileSize,1);
|
MemoryAllocator<unsigned char> jpg(fileSize);
|
||||||
u32 nread = Memory.Alloc(8,1);
|
MemoryAllocator<u64> pos, nread;
|
||||||
u32 pos_addr = Memory.Alloc(8,1);
|
cellFsLseek(fd, 0, CELL_SEEK_SET, pos);
|
||||||
cellFsLseek(fd, 0, 0, pos_addr);
|
cellFsRead(fd, jpg.GetAddr(), jpg.GetSize(), nread);
|
||||||
cellFsRead(fd, buffer, fileSize, nread);
|
|
||||||
Memory.Free(nread);
|
|
||||||
Memory.Free(pos_addr);
|
|
||||||
|
|
||||||
//Decode JPG file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
//Decode JPG file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
||||||
int width, height, actual_components;
|
int width, height, actual_components;
|
||||||
unsigned char *jpg = (unsigned char*)Memory.VirtualToRealAddr(buffer);
|
std::shared_ptr<unsigned char> image(stbi_load_from_memory(jpg, fileSize, &width, &height, &actual_components, 4));
|
||||||
unsigned char *image = stbi_load_from_memory(jpg, fileSize, &width, &height, &actual_components, 4);
|
|
||||||
Memory.Free(buffer);
|
|
||||||
if (!image) return CELL_JPGDEC_ERROR_STREAM_FORMAT;
|
if (!image) return CELL_JPGDEC_ERROR_STREAM_FORMAT;
|
||||||
|
|
||||||
u32 image_size = width * height * 4;
|
uint image_size = width * height;
|
||||||
if (current_outParam.outputColorSpace == CELL_JPG_RGBA){
|
switch(current_outParam.outputColorSpace)
|
||||||
for(u32 i = 0; i < image_size; i+=4){
|
{
|
||||||
data += image[i+0];
|
case CELL_JPG_RGBA:
|
||||||
data += image[i+1];
|
case CELL_JPG_RGB:
|
||||||
data += image[i+2];
|
image_size *= current_outParam.outputColorSpace == CELL_JPG_RGBA ? 4 : 3;
|
||||||
data += image[i+3];
|
memcpy(data, image.get(), image_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CELL_JPG_ARGB:
|
||||||
|
image_size *= 4;
|
||||||
|
|
||||||
|
for(u32 i = 0; i < image_size; i+=4)
|
||||||
|
{
|
||||||
|
data += image.get()[i+3];
|
||||||
|
data += image.get()[i+0];
|
||||||
|
data += image.get()[i+1];
|
||||||
|
data += image.get()[i+2];
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CELL_JPG_GRAYSCALE:
|
||||||
|
case CELL_JPG_YCbCr:
|
||||||
|
case CELL_JPG_UPSAMPLE_ONLY:
|
||||||
|
case CELL_JPG_GRAYSCALE_TO_ALPHA_RGBA:
|
||||||
|
case CELL_JPG_GRAYSCALE_TO_ALPHA_ARGB:
|
||||||
|
cellJpgDec.Error("cellJpgDecDecodeData: Unsupported color space (%d)", current_outParam.outputColorSpace.ToLE());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return CELL_JPGDEC_ERROR_ARG;
|
||||||
}
|
}
|
||||||
else if (current_outParam.outputColorSpace == CELL_JPG_ARGB){
|
|
||||||
for(u32 i = 0; i < image_size; i+=4){
|
dataOutInfo->status = CELL_JPGDEC_DEC_STATUS_FINISH;
|
||||||
data += image[i+3];
|
|
||||||
data += image[i+0];
|
if(dataCtrlParam->outputBytesPerLine)
|
||||||
data += image[i+1];
|
dataOutInfo->outputLines = image_size / dataCtrlParam->outputBytesPerLine;
|
||||||
data += image[i+2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete[] image;
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellJpgDecSetParameter(u32 mainHandle, u32 subHandle, u32 inParam_addr, mem_class_t outParam)
|
int cellJpgDecSetParameter(u32 mainHandle, u32 subHandle, const mem_struct_ptr_t<CellJpgDecInParam> inParam, mem_struct_ptr_t<CellJpgDecOutParam> outParam)
|
||||||
{
|
{
|
||||||
CellJpgDecInfo& current_info = ((CellJpgDecSubHandle*)subHandle)->info;
|
ID sub_handle_id_data;
|
||||||
CellJpgDecOutParam& current_outParam = ((CellJpgDecSubHandle*)subHandle)->outParam;
|
if(!cellJpgDec.CheckId(subHandle, sub_handle_id_data))
|
||||||
|
return CELL_JPGDEC_ERROR_FATAL;
|
||||||
|
|
||||||
|
auto subHandle_data = (CellJpgDecSubHandle*)sub_handle_id_data.m_data;
|
||||||
|
|
||||||
|
CellJpgDecInfo& current_info = subHandle_data->info;
|
||||||
|
CellJpgDecOutParam& current_outParam = subHandle_data->outParam;
|
||||||
|
|
||||||
current_outParam.outputWidthByte = (current_info.imageWidth * current_info.numComponents);
|
current_outParam.outputWidthByte = (current_info.imageWidth * current_info.numComponents);
|
||||||
current_outParam.outputWidth = current_info.imageWidth;
|
current_outParam.outputWidth = current_info.imageWidth;
|
||||||
current_outParam.outputHeight = current_info.imageHeight;
|
current_outParam.outputHeight = current_info.imageHeight;
|
||||||
current_outParam.outputColorSpace = Memory.Read32(inParam_addr+16);
|
current_outParam.outputColorSpace = inParam->outputColorSpace;
|
||||||
|
|
||||||
switch (current_outParam.outputColorSpace)
|
switch (current_outParam.outputColorSpace)
|
||||||
{
|
{
|
||||||
case CELL_JPG_GRAYSCALE: current_outParam.outputComponents = 1; break;
|
case CELL_JPG_GRAYSCALE: current_outParam.outputComponents = 1; break;
|
||||||
case CELL_JPG_RGB: current_outParam.outputComponents = 3; break;
|
|
||||||
|
case CELL_JPG_RGB:
|
||||||
case CELL_JPG_YCbCr: current_outParam.outputComponents = 3; break;
|
case CELL_JPG_YCbCr: current_outParam.outputComponents = 3; break;
|
||||||
case CELL_JPG_RGBA: current_outParam.outputComponents = 4; break;
|
|
||||||
case CELL_JPG_UPSAMPLE_ONLY: current_outParam.outputComponents = current_info.numComponents; break;
|
case CELL_JPG_UPSAMPLE_ONLY: current_outParam.outputComponents = current_info.numComponents; break;
|
||||||
case CELL_JPG_ARGB: current_outParam.outputComponents = 4; break;
|
|
||||||
case CELL_JPG_GRAYSCALE_TO_ALPHA_RGBA: current_outParam.outputComponents = 4; break;
|
case CELL_JPG_RGBA:
|
||||||
|
case CELL_JPG_ARGB:
|
||||||
|
case CELL_JPG_GRAYSCALE_TO_ALPHA_RGBA:
|
||||||
case CELL_JPG_GRAYSCALE_TO_ALPHA_ARGB: current_outParam.outputComponents = 4; break;
|
case CELL_JPG_GRAYSCALE_TO_ALPHA_ARGB: current_outParam.outputComponents = 4; break;
|
||||||
|
|
||||||
default: return CELL_JPGDEC_ERROR_ARG; // Not supported color space
|
default: return CELL_JPGDEC_ERROR_ARG; // Not supported color space
|
||||||
}
|
}
|
||||||
current_outParam.outputMode = Memory.Read32(inParam_addr+12);
|
|
||||||
current_outParam.downScale = Memory.Read32(inParam_addr+4);
|
current_outParam.outputMode = inParam->outputMode;
|
||||||
|
current_outParam.downScale = inParam->downScale;
|
||||||
current_outParam.useMemorySpace = 0; // Unimplemented
|
current_outParam.useMemorySpace = 0; // Unimplemented
|
||||||
|
|
||||||
outParam += current_outParam.outputWidthByte;
|
outParam = current_outParam;
|
||||||
outParam += current_outParam.outputWidth;
|
|
||||||
outParam += current_outParam.outputHeight;
|
|
||||||
outParam += current_outParam.outputComponents;
|
|
||||||
outParam += current_outParam.outputMode;
|
|
||||||
outParam += current_outParam.outputColorSpace;
|
|
||||||
outParam += current_outParam.downScale;
|
|
||||||
outParam += current_outParam.useMemorySpace;
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -32,49 +32,68 @@ enum CellPngDecColorSpace
|
|||||||
CELL_PNGDEC_ARGB = 20,
|
CELL_PNGDEC_ARGB = 20,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum CellPngDecDecodeStatus
|
||||||
|
{
|
||||||
|
CELL_PNGDEC_DEC_STATUS_FINISH = 0, //Decoding finished
|
||||||
|
CELL_PNGDEC_DEC_STATUS_STOP = 1, //Decoding halted
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CellPngDecDataOutInfo
|
||||||
|
{
|
||||||
|
be_t<u32> chunkInformation;
|
||||||
|
be_t<u32> numText;
|
||||||
|
be_t<u32> numUnknownChunk;
|
||||||
|
be_t<u32> status;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CellPngDecDataCtrlParam
|
||||||
|
{
|
||||||
|
be_t<u64> outputBytesPerLine;
|
||||||
|
};
|
||||||
|
|
||||||
struct CellPngDecInfo
|
struct CellPngDecInfo
|
||||||
{
|
{
|
||||||
u32 imageWidth;
|
be_t<u32> imageWidth;
|
||||||
u32 imageHeight;
|
be_t<u32> imageHeight;
|
||||||
u32 numComponents;
|
be_t<u32> numComponents;
|
||||||
u32 colorSpace; // CellPngDecColorSpace
|
be_t<u32> colorSpace; // CellPngDecColorSpace
|
||||||
u32 bitDepth;
|
be_t<u32> bitDepth;
|
||||||
u32 interlaceMethod; // CellPngDecInterlaceMode
|
be_t<u32> interlaceMethod; // CellPngDecInterlaceMode
|
||||||
u32 chunkInformation;
|
be_t<u32> chunkInformation;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellPngDecSrc
|
struct CellPngDecSrc
|
||||||
{
|
{
|
||||||
u32 srcSelect; // CellPngDecStreamSrcSel
|
be_t<u32> srcSelect; // CellPngDecStreamSrcSel
|
||||||
u32 fileName; // const char*
|
be_t<u32> fileName; // const char*
|
||||||
u64 fileOffset; // int64_t
|
be_t<u64> fileOffset; // int64_t
|
||||||
u32 fileSize;
|
be_t<u32> fileSize;
|
||||||
u32 streamPtr;
|
be_t<u32> streamPtr;
|
||||||
u32 streamSize;
|
be_t<u32> streamSize;
|
||||||
u32 spuThreadEnable; // CellPngDecSpuThreadEna
|
be_t<u32> spuThreadEnable; // CellPngDecSpuThreadEna
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellPngDecInParam
|
struct CellPngDecInParam
|
||||||
{
|
{
|
||||||
u32 *commandPtr;
|
be_t<u32> commandPtr;
|
||||||
u32 outputMode; // CellPngDecOutputMode
|
be_t<u32> outputMode; // CellPngDecOutputMode
|
||||||
u32 outputColorSpace; // CellPngDecColorSpace
|
be_t<u32> outputColorSpace; // CellPngDecColorSpace
|
||||||
u32 outputBitDepth;
|
be_t<u32> outputBitDepth;
|
||||||
u32 outputPackFlag; // CellPngDecPackFlag
|
be_t<u32> outputPackFlag; // CellPngDecPackFlag
|
||||||
u32 outputAlphaSelect; // CellPngDecAlphaSelect
|
be_t<u32> outputAlphaSelect; // CellPngDecAlphaSelect
|
||||||
u32 outputColorAlpha;
|
be_t<u32> outputColorAlpha;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellPngDecOutParam
|
struct CellPngDecOutParam
|
||||||
{
|
{
|
||||||
u64 outputWidthByte;
|
be_t<u64> outputWidthByte;
|
||||||
u32 outputWidth;
|
be_t<u32> outputWidth;
|
||||||
u32 outputHeight;
|
be_t<u32> outputHeight;
|
||||||
u32 outputComponents;
|
be_t<u32> outputComponents;
|
||||||
u32 outputBitDepth;
|
be_t<u32> outputBitDepth;
|
||||||
u32 outputMode; // CellPngDecOutputMode
|
be_t<u32> outputMode; // CellPngDecOutputMode
|
||||||
u32 outputColorSpace; // CellPngDecColorSpace
|
be_t<u32> outputColorSpace; // CellPngDecColorSpace
|
||||||
u32 useMemorySpace;
|
be_t<u32> useMemorySpace;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CellPngDecSubHandle //Custom struct
|
struct CellPngDecSubHandle //Custom struct
|
||||||
@ -85,7 +104,6 @@ struct CellPngDecSubHandle //Custom struct
|
|||||||
CellPngDecOutParam outParam;
|
CellPngDecOutParam outParam;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int cellPngDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam)
|
int cellPngDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED_FUNC(cellPngDec);
|
UNIMPLEMENTED_FUNC(cellPngDec);
|
||||||
@ -102,7 +120,7 @@ int cellPngDecOpen(u32 mainHandle, mem32_t subHandle, u32 src_addr, u32 openInfo
|
|||||||
{
|
{
|
||||||
//u32 srcSelect = Memory.Read32(src_addr);
|
//u32 srcSelect = Memory.Read32(src_addr);
|
||||||
u32 fileName = Memory.Read32(src_addr+4);
|
u32 fileName = Memory.Read32(src_addr+4);
|
||||||
//u64 fileOffset = Memory.Read32(src_addr+8);
|
//u32 fileOffset = Memory.Read32(src_addr+8);
|
||||||
//u32 fileSize = Memory.Read32(src_addr+12);
|
//u32 fileSize = Memory.Read32(src_addr+12);
|
||||||
//u32 streamPtr = Memory.Read32(src_addr+16);
|
//u32 streamPtr = Memory.Read32(src_addr+16);
|
||||||
//u32 streamSize = Memory.Read32(src_addr+20);
|
//u32 streamSize = Memory.Read32(src_addr+20);
|
||||||
@ -111,61 +129,68 @@ int cellPngDecOpen(u32 mainHandle, mem32_t subHandle, u32 src_addr, u32 openInfo
|
|||||||
CellPngDecSubHandle *current_subHandle = new CellPngDecSubHandle;
|
CellPngDecSubHandle *current_subHandle = new CellPngDecSubHandle;
|
||||||
|
|
||||||
// Get file descriptor
|
// Get file descriptor
|
||||||
u32 fd_addr = Memory.Alloc(sizeof(u32), 1);
|
MemoryAllocator<be_t<u32>> fd;
|
||||||
int ret = cellFsOpen(fileName, 0, fd_addr, NULL, 0);
|
int ret = cellFsOpen(fileName, 0, fd, NULL, 0);
|
||||||
current_subHandle->fd = Memory.Read32(fd_addr);
|
current_subHandle->fd = fd->ToLE();
|
||||||
Memory.Free(fd_addr);
|
if(ret != CELL_OK) return CELL_PNGDEC_ERROR_OPEN_FILE;
|
||||||
if(ret != 0) return CELL_PNGDEC_ERROR_OPEN_FILE;
|
|
||||||
|
|
||||||
// Get size of file
|
// Get size of file
|
||||||
u32 sb_addr = Memory.Alloc(52,1); // Alloc a CellFsStat struct
|
MemoryAllocator<CellFsStat> sb; // Alloc a CellFsStat struct
|
||||||
cellFsFstat(current_subHandle->fd, sb_addr);
|
ret = cellFsFstat(current_subHandle->fd, sb);
|
||||||
current_subHandle->fileSize = Memory.Read64(sb_addr+36); // Get CellFsStat.st_size
|
if(ret != CELL_OK) return ret;
|
||||||
Memory.Free(sb_addr);
|
current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size
|
||||||
|
|
||||||
// From now, every u32 subHandle argument is a pointer to a CellPngDecSubHandle struct.
|
// From now, every u32 subHandle argument is a pointer to a CellPngDecSubHandle struct.
|
||||||
subHandle += (u32)current_subHandle;
|
subHandle = cellPngDec.GetNewId(current_subHandle);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellPngDecClose(u32 mainHandle, u32 subHandle)
|
int cellPngDecClose(u32 mainHandle, u32 subHandle)
|
||||||
{
|
{
|
||||||
cellFsClose( ((CellPngDecSubHandle*)subHandle)->fd );
|
ID sub_handle_id_data;
|
||||||
delete (CellPngDecSubHandle*)subHandle;
|
if(!cellPngDec.CheckId(subHandle, sub_handle_id_data))
|
||||||
|
return CELL_PNGDEC_ERROR_FATAL;
|
||||||
|
|
||||||
|
auto subHandle_data = (CellPngDecSubHandle*)sub_handle_id_data.m_data;
|
||||||
|
|
||||||
|
cellFsClose(subHandle_data->fd);
|
||||||
|
Emu.GetIdManager().RemoveID(subHandle);
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, mem_class_t info)
|
int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, mem_struct_ptr_t<CellPngDecInfo> info)
|
||||||
{
|
{
|
||||||
const u32& fd = ((CellPngDecSubHandle*)subHandle)->fd;
|
cellPngDec.Log("cellPngDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%llx)", mainHandle, subHandle, info.GetAddr());
|
||||||
const u64& fileSize = ((CellPngDecSubHandle*)subHandle)->fileSize;
|
ID sub_handle_id_data;
|
||||||
CellPngDecInfo& current_info = ((CellPngDecSubHandle*)subHandle)->info;
|
if(!cellPngDec.CheckId(subHandle, sub_handle_id_data))
|
||||||
|
return CELL_PNGDEC_ERROR_FATAL;
|
||||||
|
|
||||||
|
auto subHandle_data = (CellPngDecSubHandle*)sub_handle_id_data.m_data;
|
||||||
|
|
||||||
|
const u32& fd = subHandle_data->fd;
|
||||||
|
const u64& fileSize = subHandle_data->fileSize;
|
||||||
|
CellPngDecInfo& current_info = subHandle_data->info;
|
||||||
|
|
||||||
//Check size of file
|
//Check size of file
|
||||||
if(fileSize < 29) return CELL_PNGDEC_ERROR_HEADER; // Error: The file is smaller than the length of a PNG header
|
if(fileSize < 29) return CELL_PNGDEC_ERROR_HEADER; // Error: The file is smaller than the length of a PNG header
|
||||||
|
|
||||||
//Write the header to buffer
|
//Write the header to buffer
|
||||||
u32 buffer = Memory.Alloc(34,1); // Alloc buffer for PNG header
|
MemoryAllocator<be_t<u32>> buffer(34); // Alloc buffer for PNG header
|
||||||
u32 nread = Memory.Alloc(8,1);
|
MemoryAllocator<be_t<u64>> pos, nread;
|
||||||
u32 pos_addr = Memory.Alloc(8,1);
|
|
||||||
cellFsLseek(fd, 0, 0, pos_addr);
|
|
||||||
cellFsRead(fd, buffer, 34, nread);
|
|
||||||
Memory.Free(nread);
|
|
||||||
Memory.Free(pos_addr);
|
|
||||||
|
|
||||||
if (Memory.Read32(buffer) != 0x89504E47 ||
|
cellFsLseek(fd, 0, CELL_SEEK_SET, pos);
|
||||||
Memory.Read32(buffer+4) != 0x0D0A1A0A || // Error: The first 8 bytes are not a valid PNG signature
|
cellFsRead(fd, buffer.GetAddr(), buffer.GetSize(), nread);
|
||||||
Memory.Read32(buffer+12) != 0x49484452) // Error: The PNG file does not start with an IHDR chunk
|
|
||||||
|
if (buffer[0] != 0x89504E47 ||
|
||||||
|
buffer[1] != 0x0D0A1A0A || // Error: The first 8 bytes are not a valid PNG signature
|
||||||
|
buffer[3] != 0x49484452) // Error: The PNG file does not start with an IHDR chunk
|
||||||
{
|
{
|
||||||
Memory.Free(buffer);
|
|
||||||
return CELL_PNGDEC_ERROR_HEADER;
|
return CELL_PNGDEC_ERROR_HEADER;
|
||||||
}
|
}
|
||||||
|
|
||||||
current_info.imageWidth = Memory.Read32(buffer+16);
|
switch (buffer.To<u8>()[25])
|
||||||
current_info.imageHeight = Memory.Read32(buffer+20);
|
|
||||||
switch (Memory.Read8(buffer+25))
|
|
||||||
{
|
{
|
||||||
case 0: current_info.colorSpace = CELL_PNGDEC_GRAYSCALE; current_info.numComponents = 1; break;
|
case 0: current_info.colorSpace = CELL_PNGDEC_GRAYSCALE; current_info.numComponents = 1; break;
|
||||||
case 2: current_info.colorSpace = CELL_PNGDEC_RGB; current_info.numComponents = 3; break;
|
case 2: current_info.colorSpace = CELL_PNGDEC_RGB; current_info.numComponents = 3; break;
|
||||||
@ -174,97 +199,113 @@ int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, mem_class_t info)
|
|||||||
case 6: current_info.colorSpace = CELL_PNGDEC_RGBA; current_info.numComponents = 4; break;
|
case 6: current_info.colorSpace = CELL_PNGDEC_RGBA; current_info.numComponents = 4; break;
|
||||||
default: return CELL_PNGDEC_ERROR_HEADER; // Not supported color type
|
default: return CELL_PNGDEC_ERROR_HEADER; // Not supported color type
|
||||||
}
|
}
|
||||||
current_info.bitDepth = Memory.Read8(buffer+24);
|
|
||||||
current_info.interlaceMethod = Memory.Read8(buffer+28);
|
current_info.imageWidth = buffer[4];
|
||||||
|
current_info.imageHeight = buffer[5];
|
||||||
|
current_info.bitDepth = buffer.To<u8>()[24];
|
||||||
|
current_info.interlaceMethod = buffer.To<u8>()[28];
|
||||||
current_info.chunkInformation = 0; // Unimplemented
|
current_info.chunkInformation = 0; // Unimplemented
|
||||||
|
|
||||||
info += current_info.imageWidth;
|
info = current_info;
|
||||||
info += current_info.imageHeight;
|
|
||||||
info += current_info.numComponents;
|
|
||||||
info += current_info.colorSpace;
|
|
||||||
info += current_info.bitDepth;
|
|
||||||
info += current_info.interlaceMethod;
|
|
||||||
info += current_info.chunkInformation;
|
|
||||||
Memory.Free(buffer);
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, u32 dataCtrlParam_addr, mem_class_t dataOutInfo)
|
int cellPngDecDecodeData(u32 mainHandle, u32 subHandle, mem8_ptr_t data, const mem_struct_ptr_t<CellPngDecDataCtrlParam> dataCtrlParam, mem_struct_ptr_t<CellPngDecDataOutInfo> dataOutInfo)
|
||||||
{
|
{
|
||||||
const u32& fd = ((CellPngDecSubHandle*)subHandle)->fd;
|
dataOutInfo->status = CELL_PNGDEC_DEC_STATUS_STOP;
|
||||||
const u64& fileSize = ((CellPngDecSubHandle*)subHandle)->fileSize;
|
ID sub_handle_id_data;
|
||||||
const CellPngDecOutParam& current_outParam = ((CellPngDecSubHandle*)subHandle)->outParam;
|
if(!cellPngDec.CheckId(subHandle, sub_handle_id_data))
|
||||||
|
return CELL_PNGDEC_ERROR_FATAL;
|
||||||
|
|
||||||
|
auto subHandle_data = (CellPngDecSubHandle*)sub_handle_id_data.m_data;
|
||||||
|
|
||||||
|
const u32& fd = subHandle_data->fd;
|
||||||
|
const u64& fileSize = subHandle_data->fileSize;
|
||||||
|
const CellPngDecOutParam& current_outParam = subHandle_data->outParam;
|
||||||
|
|
||||||
//Copy the PNG file to a buffer
|
//Copy the PNG file to a buffer
|
||||||
u32 buffer = Memory.Alloc(fileSize,1);
|
MemoryAllocator<unsigned char> png(fileSize);
|
||||||
u32 nread = Memory.Alloc(8,1);
|
MemoryAllocator<u64> pos, nread;
|
||||||
u32 pos_addr = Memory.Alloc(sizeof(u64),1);
|
cellFsLseek(fd, 0, CELL_SEEK_SET, pos);
|
||||||
cellFsLseek(fd, 0, 0, pos_addr);
|
cellFsRead(fd, png.GetAddr(), png.GetSize(), nread);
|
||||||
cellFsRead(fd, buffer, fileSize, nread);
|
|
||||||
Memory.Free(nread);
|
|
||||||
Memory.Free(pos_addr);
|
|
||||||
|
|
||||||
//Decode PNG file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
//Decode PNG file. (TODO: Is there any faster alternative? Can we do it without external libraries?)
|
||||||
int width, height, actual_components;
|
int width, height, actual_components;
|
||||||
unsigned char *png = (unsigned char*)Memory.VirtualToRealAddr(buffer);
|
std::shared_ptr<unsigned char> image(stbi_load_from_memory(png, fileSize, &width, &height, &actual_components, 4));
|
||||||
unsigned char *image = stbi_load_from_memory(png, fileSize, &width, &height, &actual_components, 4);
|
|
||||||
Memory.Free(buffer);
|
|
||||||
if (!image) return CELL_PNGDEC_ERROR_STREAM_FORMAT;
|
if (!image) return CELL_PNGDEC_ERROR_STREAM_FORMAT;
|
||||||
|
|
||||||
u32 image_size = width * height * 4;
|
uint image_size = width * height;
|
||||||
if (current_outParam.outputColorSpace == CELL_PNGDEC_RGBA){
|
switch(current_outParam.outputColorSpace)
|
||||||
for(u32 i = 0; i < image_size; i+=4){
|
{
|
||||||
data += image[i+0];
|
case CELL_PNGDEC_RGB:
|
||||||
data += image[i+1];
|
case CELL_PNGDEC_RGBA:
|
||||||
data += image[i+2];
|
image_size *= current_outParam.outputColorSpace == CELL_PNGDEC_RGBA ? 4 : 3;
|
||||||
data += image[i+3];
|
memcpy(data, image.get(), image_size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CELL_PNGDEC_ARGB:
|
||||||
|
image_size *= 4;
|
||||||
|
|
||||||
|
for(uint i = 0; i < image_size; i+=4)
|
||||||
|
{
|
||||||
|
data += image.get()[i+3];
|
||||||
|
data += image.get()[i+0];
|
||||||
|
data += image.get()[i+1];
|
||||||
|
data += image.get()[i+2];
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CELL_PNGDEC_GRAYSCALE:
|
||||||
|
case CELL_PNGDEC_PALETTE:
|
||||||
|
case CELL_PNGDEC_GRAYSCALE_ALPHA:
|
||||||
|
cellPngDec.Error("cellPngDecDecodeData: Unsupported color space (%d)", current_outParam.outputColorSpace.ToLE());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return CELL_PNGDEC_ERROR_ARG;
|
||||||
}
|
}
|
||||||
else if (current_outParam.outputColorSpace == CELL_PNGDEC_ARGB){
|
|
||||||
for(u32 i = 0; i < image_size; i+=4){
|
dataOutInfo->status = CELL_PNGDEC_DEC_STATUS_FINISH;
|
||||||
data += image[i+3];
|
|
||||||
data += image[i+0];
|
|
||||||
data += image[i+1];
|
|
||||||
data += image[i+2];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete[] image;
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellPngDecSetParameter(u32 mainHandle, u32 subHandle, u32 inParam_addr, mem_class_t outParam)
|
int cellPngDecSetParameter(u32 mainHandle, u32 subHandle, const mem_struct_ptr_t<CellPngDecInParam> inParam, mem_struct_ptr_t<CellPngDecOutParam> outParam)
|
||||||
{
|
{
|
||||||
CellPngDecInfo& current_info = ((CellPngDecSubHandle*)subHandle)->info;
|
ID sub_handle_id_data;
|
||||||
CellPngDecOutParam& current_outParam = ((CellPngDecSubHandle*)subHandle)->outParam;
|
if(!cellPngDec.CheckId(subHandle, sub_handle_id_data))
|
||||||
|
return CELL_PNGDEC_ERROR_FATAL;
|
||||||
|
|
||||||
|
auto subHandle_data = (CellPngDecSubHandle*)sub_handle_id_data.m_data;
|
||||||
|
|
||||||
|
CellPngDecInfo& current_info = subHandle_data->info;
|
||||||
|
CellPngDecOutParam& current_outParam = subHandle_data->outParam;
|
||||||
|
|
||||||
current_outParam.outputWidthByte = (current_info.imageWidth * current_info.numComponents * current_info.bitDepth) / 8;
|
current_outParam.outputWidthByte = (current_info.imageWidth * current_info.numComponents * current_info.bitDepth) / 8;
|
||||||
current_outParam.outputWidth = current_info.imageWidth;
|
current_outParam.outputWidth = current_info.imageWidth;
|
||||||
current_outParam.outputHeight = current_info.imageHeight;
|
current_outParam.outputHeight = current_info.imageHeight;
|
||||||
current_outParam.outputColorSpace = Memory.Read32(inParam_addr+8);
|
current_outParam.outputColorSpace = inParam->outputColorSpace;
|
||||||
switch (current_outParam.outputColorSpace)
|
switch (current_outParam.outputColorSpace)
|
||||||
{
|
{
|
||||||
|
case CELL_PNGDEC_PALETTE:
|
||||||
case CELL_PNGDEC_GRAYSCALE: current_outParam.outputComponents = 1; break;
|
case CELL_PNGDEC_GRAYSCALE: current_outParam.outputComponents = 1; break;
|
||||||
|
|
||||||
case CELL_PNGDEC_GRAYSCALE_ALPHA: current_outParam.outputComponents = 2; break;
|
case CELL_PNGDEC_GRAYSCALE_ALPHA: current_outParam.outputComponents = 2; break;
|
||||||
case CELL_PNGDEC_PALETTE: current_outParam.outputComponents = 1; break;
|
|
||||||
case CELL_PNGDEC_RGB: current_outParam.outputComponents = 3; break;
|
case CELL_PNGDEC_RGB: current_outParam.outputComponents = 3; break;
|
||||||
case CELL_PNGDEC_RGBA: current_outParam.outputComponents = 4; break;
|
|
||||||
|
case CELL_PNGDEC_RGBA:
|
||||||
case CELL_PNGDEC_ARGB: current_outParam.outputComponents = 4; break;
|
case CELL_PNGDEC_ARGB: current_outParam.outputComponents = 4; break;
|
||||||
|
|
||||||
default: return CELL_PNGDEC_ERROR_ARG; // Not supported color space
|
default: return CELL_PNGDEC_ERROR_ARG; // Not supported color space
|
||||||
}
|
}
|
||||||
current_outParam.outputBitDepth = Memory.Read32(inParam_addr+12);
|
|
||||||
current_outParam.outputMode = Memory.Read32(inParam_addr+4);
|
current_outParam.outputBitDepth = inParam->outputBitDepth;
|
||||||
|
current_outParam.outputMode = inParam->outputMode;
|
||||||
current_outParam.useMemorySpace = 0; // Unimplemented
|
current_outParam.useMemorySpace = 0; // Unimplemented
|
||||||
|
|
||||||
outParam += current_outParam.outputWidthByte;
|
outParam = current_outParam;
|
||||||
outParam += current_outParam.outputWidth;
|
|
||||||
outParam += current_outParam.outputHeight;
|
|
||||||
outParam += current_outParam.outputComponents;
|
|
||||||
outParam += current_outParam.outputBitDepth;
|
|
||||||
outParam += current_outParam.outputMode;
|
|
||||||
outParam += current_outParam.outputColorSpace;
|
|
||||||
outParam += current_outParam.useMemorySpace;
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ class binder_func_1 : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_1(func_t call) : func_caller(), m_call(call) {}
|
binder_func_1(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_1)); }
|
virtual void operator()() { declCPU(); RESULT(m_call((T1&)SC_ARG_0)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T1>
|
template<typename T1>
|
||||||
@ -43,7 +43,7 @@ class binder_func_1<void, T1> : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_1(func_t call) : func_caller(), m_call(call) {}
|
binder_func_1(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); m_call(SC_ARGS_1); }
|
virtual void operator()() { declCPU(); m_call((T1&)SC_ARG_0); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TR, typename T1, typename T2>
|
template<typename TR, typename T1, typename T2>
|
||||||
@ -54,7 +54,7 @@ class binder_func_2 : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_2(func_t call) : func_caller(), m_call(call) {}
|
binder_func_2(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_2)); }
|
virtual void operator()() { declCPU(); RESULT(m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T1, typename T2>
|
template<typename T1, typename T2>
|
||||||
@ -65,7 +65,7 @@ class binder_func_2<void, T1, T2> : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_2(func_t call) : func_caller(), m_call(call) {}
|
binder_func_2(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); m_call(SC_ARGS_2); }
|
virtual void operator()() { declCPU(); m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TR, typename T1, typename T2, typename T3>
|
template<typename TR, typename T1, typename T2, typename T3>
|
||||||
@ -76,7 +76,7 @@ class binder_func_3 : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_3(func_t call) : func_caller(), m_call(call) {}
|
binder_func_3(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_3)); }
|
virtual void operator()() { declCPU(); RESULT(m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T1, typename T2, typename T3>
|
template<typename T1, typename T2, typename T3>
|
||||||
@ -87,7 +87,7 @@ class binder_func_3<void, T1, T2, T3> : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_3(func_t call) : func_caller(), m_call(call) {}
|
binder_func_3(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); m_call(SC_ARGS_3); }
|
virtual void operator()() { declCPU(); m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TR, typename T1, typename T2, typename T3, typename T4>
|
template<typename TR, typename T1, typename T2, typename T3, typename T4>
|
||||||
@ -98,7 +98,7 @@ class binder_func_4 : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_4(func_t call) : func_caller(), m_call(call) {}
|
binder_func_4(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_4)); }
|
virtual void operator()() { declCPU(); RESULT(m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T1, typename T2, typename T3, typename T4>
|
template<typename T1, typename T2, typename T3, typename T4>
|
||||||
@ -109,7 +109,7 @@ class binder_func_4<void, T1, T2, T3, T4> : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_4(func_t call) : func_caller(), m_call(call) {}
|
binder_func_4(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); m_call(SC_ARGS_4); }
|
virtual void operator()() { declCPU(); m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5>
|
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||||
@ -120,7 +120,7 @@ class binder_func_5 : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_5(func_t call) : func_caller(), m_call(call) {}
|
binder_func_5(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_5)); }
|
virtual void operator()() { declCPU(); RESULT(m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3, (T5&)SC_ARG_4)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T1, typename T2, typename T3, typename T4, typename T5>
|
template<typename T1, typename T2, typename T3, typename T4, typename T5>
|
||||||
@ -131,7 +131,7 @@ class binder_func_5<void, T1, T2, T3, T4, T5> : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_5(func_t call) : func_caller(), m_call(call) {}
|
binder_func_5(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); m_call(SC_ARGS_5); }
|
virtual void operator()() { declCPU(); m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3, (T5&)SC_ARG_4); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||||
@ -142,7 +142,7 @@ class binder_func_6 : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_6(func_t call) : func_caller(), m_call(call) {}
|
binder_func_6(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_6)); }
|
virtual void operator()() { declCPU(); RESULT(m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3, (T5&)SC_ARG_4, (T6&)SC_ARG_5)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
|
||||||
@ -153,7 +153,7 @@ class binder_func_6<void, T1, T2, T3, T4, T5, T6> : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_6(func_t call) : func_caller(), m_call(call) {}
|
binder_func_6(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); m_call(SC_ARGS_6); }
|
virtual void operator()() { declCPU(); m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3, (T5&)SC_ARG_4, (T6&)SC_ARG_5); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
||||||
@ -164,7 +164,7 @@ class binder_func_7 : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_7(func_t call) : func_caller(), m_call(call) {}
|
binder_func_7(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_7)); }
|
virtual void operator()() { declCPU(); RESULT(m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3, (T5&)SC_ARG_4, (T6&)SC_ARG_5, (T7&)SC_ARG_6)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
|
||||||
@ -175,7 +175,7 @@ class binder_func_7<void, T1, T2, T3, T4, T5, T6, T7> : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_7(func_t call) : func_caller(), m_call(call) {}
|
binder_func_7(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); m_call(SC_ARGS_7); }
|
virtual void operator()() { declCPU(); m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3, (T5&)SC_ARG_4, (T6&)SC_ARG_5, (T7&)SC_ARG_6); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
||||||
@ -186,7 +186,7 @@ class binder_func_8 : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_8(func_t call) : func_caller(), m_call(call) {}
|
binder_func_8(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_8)); }
|
virtual void operator()() { declCPU(); RESULT(m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3, (T5&)SC_ARG_4, (T6&)SC_ARG_5, (T7&)SC_ARG_6, (T8&)SC_ARG_7)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
|
||||||
@ -197,7 +197,7 @@ class binder_func_8<void, T1, T2, T3, T4, T5, T6, T7, T8> : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_8(func_t call) : func_caller(), m_call(call) {}
|
binder_func_8(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); m_call(SC_ARGS_8); }
|
virtual void operator()() { declCPU(); m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3, (T5&)SC_ARG_4, (T6&)SC_ARG_5, (T7&)SC_ARG_6, (T8&)SC_ARG_7); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
||||||
@ -208,7 +208,7 @@ class binder_func_9 : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_9(func_t call) : func_caller(), m_call(call) {}
|
binder_func_9(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_9)); }
|
virtual void operator()() { declCPU(); RESULT(m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3, (T5&)SC_ARG_4, (T6&)SC_ARG_5, (T7&)SC_ARG_6, (T8&)SC_ARG_7, (T9&)SC_ARG_8)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
|
||||||
@ -219,7 +219,7 @@ class binder_func_9<void, T1, T2, T3, T4, T5, T6, T7, T8, T9> : public func_call
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_9(func_t call) : func_caller(), m_call(call) {}
|
binder_func_9(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); m_call(SC_ARGS_9); }
|
virtual void operator()() { declCPU(); m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3, (T5&)SC_ARG_4, (T6&)SC_ARG_5, (T7&)SC_ARG_6, (T8&)SC_ARG_7, (T9&)SC_ARG_8); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
|
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
|
||||||
@ -230,7 +230,7 @@ class binder_func_10 : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_10(func_t call) : func_caller(), m_call(call) {}
|
binder_func_10(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_10)); }
|
virtual void operator()() { declCPU(); RESULT(m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3, (T5&)SC_ARG_4, (T6&)SC_ARG_5, (T7&)SC_ARG_6, (T8&)SC_ARG_7, (T9&)SC_ARG_8, (T10&)SC_ARG_9)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
|
||||||
@ -241,7 +241,7 @@ class binder_func_10<void, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> : public fun
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_10(func_t call) : func_caller(), m_call(call) {}
|
binder_func_10(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); m_call(SC_ARGS_10); }
|
virtual void operator()() { declCPU(); m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3, (T5&)SC_ARG_4, (T6&)SC_ARG_5, (T7&)SC_ARG_6, (T8&)SC_ARG_7, (T9&)SC_ARG_8, (T10&)SC_ARG_9); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
|
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
|
||||||
@ -252,7 +252,7 @@ class binder_func_11 : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_11(func_t call) : func_caller(), m_call(call) {}
|
binder_func_11(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_11)); }
|
virtual void operator()() { declCPU(); RESULT(m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3, (T5&)SC_ARG_4, (T6&)SC_ARG_5, (T7&)SC_ARG_6, (T8&)SC_ARG_7, (T9&)SC_ARG_8, (T10&)SC_ARG_9, (T11&)SC_ARG_10)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11>
|
||||||
@ -263,7 +263,7 @@ class binder_func_11<void, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> : publi
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_11(func_t call) : func_caller(), m_call(call) {}
|
binder_func_11(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); m_call(SC_ARGS_11); }
|
virtual void operator()() { declCPU(); m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3, (T5&)SC_ARG_4, (T6&)SC_ARG_5, (T7&)SC_ARG_6, (T8&)SC_ARG_7, (T9&)SC_ARG_8, (T10&)SC_ARG_9, (T11&)SC_ARG_10); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12>
|
template<typename TR, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12>
|
||||||
@ -274,7 +274,7 @@ class binder_func_12 : public func_caller
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_12(func_t call) : func_caller(), m_call(call) {}
|
binder_func_12(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); RESULT(m_call(SC_ARGS_12)); }
|
virtual void operator()() { declCPU(); RESULT(m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3, (T5&)SC_ARG_4, (T6&)SC_ARG_5, (T7&)SC_ARG_6, (T8&)SC_ARG_7, (T9&)SC_ARG_8, (T10&)SC_ARG_9, (T11&)SC_ARG_10, (T12&)SC_ARG_11)); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12>
|
template<typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10, typename T11, typename T12>
|
||||||
@ -285,7 +285,7 @@ class binder_func_12<void, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> :
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
binder_func_12(func_t call) : func_caller(), m_call(call) {}
|
binder_func_12(func_t call) : func_caller(), m_call(call) {}
|
||||||
virtual void operator()() { declCPU(); m_call(SC_ARGS_12); }
|
virtual void operator()() { declCPU(); m_call((T1&)SC_ARG_0, (T2&)SC_ARG_1, (T3&)SC_ARG_2, (T4&)SC_ARG_3, (T5&)SC_ARG_4, (T6&)SC_ARG_5, (T7&)SC_ARG_6, (T8&)SC_ARG_7, (T9&)SC_ARG_8, (T10&)SC_ARG_9, (T11&)SC_ARG_10, (T12&)SC_ARG_11); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TR>
|
template<typename TR>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "ErrorCodes.h"
|
#include "ErrorCodes.h"
|
||||||
|
#include "lv2/SC_FileSystem.h"
|
||||||
//#define SYSCALLS_DEBUG
|
//#define SYSCALLS_DEBUG
|
||||||
|
|
||||||
#define declCPU PPUThread& CPU = GetCurrentPPUThread
|
#define declCPU PPUThread& CPU = GetCurrentPPUThread
|
||||||
@ -176,14 +176,14 @@ extern int sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags);
|
|||||||
|
|
||||||
//cellFs
|
//cellFs
|
||||||
extern int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size);
|
extern int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size);
|
||||||
extern int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread_addr);
|
extern int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread);
|
||||||
extern int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite_addr);
|
extern int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite);
|
||||||
extern int cellFsClose(u32 fd);
|
extern int cellFsClose(u32 fd);
|
||||||
extern int cellFsOpendir(u32 path_addr, mem32_t fd);
|
extern int cellFsOpendir(u32 path_addr, mem32_t fd);
|
||||||
extern int cellFsReaddir(u32 fd, u32 dir_addr, mem64_t nread);
|
extern int cellFsReaddir(u32 fd, u32 dir_addr, mem64_t nread);
|
||||||
extern int cellFsClosedir(u32 fd);
|
extern int cellFsClosedir(u32 fd);
|
||||||
extern int cellFsStat(u32 path_addr, mem_class_t sb);
|
extern int cellFsStat(u32 path_addr, mem_struct_ptr_t<CellFsStat> sb);
|
||||||
extern int cellFsFstat(u32 fd, mem_class_t sb);
|
extern int cellFsFstat(u32 fd, mem_struct_ptr_t<CellFsStat> sb);
|
||||||
extern int cellFsMkdir(u32 path_addr, u32 mode);
|
extern int cellFsMkdir(u32 path_addr, u32 mode);
|
||||||
extern int cellFsRename(u32 from_addr, u32 to_addr);
|
extern int cellFsRename(u32 from_addr, u32 to_addr);
|
||||||
extern int cellFsRmdir(u32 path_addr);
|
extern int cellFsRmdir(u32 path_addr);
|
||||||
@ -278,18 +278,31 @@ extern u64 sys_time_get_timebase_frequency();
|
|||||||
|
|
||||||
#define UNIMPLEMENTED_FUNC(module) module.Error("Unimplemented function: "__FUNCTION__)
|
#define UNIMPLEMENTED_FUNC(module) module.Error("Unimplemented function: "__FUNCTION__)
|
||||||
|
|
||||||
#define SC_ARGS_1 CPU.GPR[3]
|
#define SC_ARG_0 CPU.GPR[3]
|
||||||
#define SC_ARGS_2 SC_ARGS_1,CPU.GPR[4]
|
#define SC_ARG_1 CPU.GPR[4]
|
||||||
#define SC_ARGS_3 SC_ARGS_2,CPU.GPR[5]
|
#define SC_ARG_2 CPU.GPR[5]
|
||||||
#define SC_ARGS_4 SC_ARGS_3,CPU.GPR[6]
|
#define SC_ARG_3 CPU.GPR[6]
|
||||||
#define SC_ARGS_5 SC_ARGS_4,CPU.GPR[7]
|
#define SC_ARG_4 CPU.GPR[7]
|
||||||
#define SC_ARGS_6 SC_ARGS_5,CPU.GPR[8]
|
#define SC_ARG_5 CPU.GPR[8]
|
||||||
#define SC_ARGS_7 SC_ARGS_6,CPU.GPR[9]
|
#define SC_ARG_6 CPU.GPR[9]
|
||||||
#define SC_ARGS_8 SC_ARGS_7,CPU.GPR[10]
|
#define SC_ARG_7 CPU.GPR[10]
|
||||||
#define SC_ARGS_9 SC_ARGS_8,CPU.GPR[11]
|
#define SC_ARG_8 CPU.GPR[11]
|
||||||
#define SC_ARGS_10 SC_ARGS_9,CPU.GPR[12]
|
#define SC_ARG_9 CPU.GPR[12]
|
||||||
#define SC_ARGS_11 SC_ARGS_10,CPU.GPR[13]
|
#define SC_ARG_10 CPU.GPR[13]
|
||||||
#define SC_ARGS_12 SC_ARGS_11,CPU.GPR[14]
|
#define SC_ARG_11 CPU.GPR[14]
|
||||||
|
|
||||||
|
#define SC_ARGS_1 SC_ARG_0
|
||||||
|
#define SC_ARGS_2 SC_ARGS_1,SC_ARG_1
|
||||||
|
#define SC_ARGS_3 SC_ARGS_2,SC_ARG_2
|
||||||
|
#define SC_ARGS_4 SC_ARGS_3,SC_ARG_3
|
||||||
|
#define SC_ARGS_5 SC_ARGS_4,SC_ARG_4
|
||||||
|
#define SC_ARGS_6 SC_ARGS_5,SC_ARG_5
|
||||||
|
#define SC_ARGS_7 SC_ARGS_6,SC_ARG_6
|
||||||
|
#define SC_ARGS_8 SC_ARGS_7,SC_ARG_7
|
||||||
|
#define SC_ARGS_9 SC_ARGS_8,SC_ARG_8
|
||||||
|
#define SC_ARGS_10 SC_ARGS_9,SC_ARG_9
|
||||||
|
#define SC_ARGS_11 SC_ARGS_10,SC_ARG_10
|
||||||
|
#define SC_ARGS_12 SC_ARGS_11,SC_ARG_11
|
||||||
|
|
||||||
extern bool dump_enable;
|
extern bool dump_enable;
|
||||||
class PPUThread;
|
class PPUThread;
|
||||||
|
@ -1,87 +1,7 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "SC_FileSystem.h"
|
||||||
#include "Emu/SysCalls/SysCalls.h"
|
#include "Emu/SysCalls/SysCalls.h"
|
||||||
|
|
||||||
enum CellFsOflag
|
|
||||||
{
|
|
||||||
LV2_O_RDONLY = 000000,
|
|
||||||
LV2_O_WRONLY = 000001,
|
|
||||||
LV2_O_RDWR = 000002,
|
|
||||||
LV2_O_ACCMODE = 000003,
|
|
||||||
LV2_O_CREAT = 000100,
|
|
||||||
LV2_O_EXCL = 000200,
|
|
||||||
LV2_O_TRUNC = 001000,
|
|
||||||
LV2_O_APPEND = 002000,
|
|
||||||
LV2_O_MSELF = 010000,
|
|
||||||
};
|
|
||||||
|
|
||||||
#define CELL_FS_TYPE_UNKNOWN 0
|
|
||||||
|
|
||||||
enum CellFsSeek
|
|
||||||
{
|
|
||||||
LV2_SEEK_SET,
|
|
||||||
LV2_SEEK_CUR,
|
|
||||||
LV2_SEEK_END,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum CellFsLength
|
|
||||||
{
|
|
||||||
LV2_MAX_FS_PATH_LENGTH = 1024,
|
|
||||||
LV2_MAX_FS_FILE_NAME_LENGTH = 255,
|
|
||||||
LV2_MAX_FS_MP_LENGTH = 31,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
CELL_FS_S_IFDIR = 0040000, //directory
|
|
||||||
CELL_FS_S_IFREG = 0100000, //regular
|
|
||||||
CELL_FS_S_IFLNK = 0120000, //symbolic link
|
|
||||||
CELL_FS_S_IFWHT = 0160000, //unknown
|
|
||||||
|
|
||||||
CELL_FS_S_IRUSR = 0000400, //R for owner
|
|
||||||
CELL_FS_S_IWUSR = 0000200, //W for owner
|
|
||||||
CELL_FS_S_IXUSR = 0000100, //X for owner
|
|
||||||
|
|
||||||
CELL_FS_S_IRGRP = 0000040, //R for group
|
|
||||||
CELL_FS_S_IWGRP = 0000020, //W for group
|
|
||||||
CELL_FS_S_IXGRP = 0000010, //X for group
|
|
||||||
|
|
||||||
CELL_FS_S_IROTH = 0000004, //R for other
|
|
||||||
CELL_FS_S_IWOTH = 0000002, //W for other
|
|
||||||
CELL_FS_S_IXOTH = 0000001, //X for other
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CellFsStat
|
|
||||||
{
|
|
||||||
u32 st_mode;
|
|
||||||
s32 st_uid;
|
|
||||||
s32 st_gid;
|
|
||||||
u64 st_atime;
|
|
||||||
u64 st_mtime;
|
|
||||||
u64 st_ctime;
|
|
||||||
u64 st_size;
|
|
||||||
u64 st_blksize;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CellFsUtimbuf
|
|
||||||
{
|
|
||||||
u64 actime;
|
|
||||||
u64 modtime;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CellFsDirent
|
|
||||||
{
|
|
||||||
u8 d_type;
|
|
||||||
u8 d_namlen;
|
|
||||||
char d_name[LV2_MAX_FS_FILE_NAME_LENGTH + 1];
|
|
||||||
};
|
|
||||||
|
|
||||||
enum FsDirentType
|
|
||||||
{
|
|
||||||
CELL_FS_TYPE_DIRECTORY = 1,
|
|
||||||
CELL_FS_TYPE_REGULAR = 2,
|
|
||||||
CELL_FS_TYPE_SYMLINK = 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
extern Module sys_fs;
|
extern Module sys_fs;
|
||||||
|
|
||||||
int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
||||||
@ -94,9 +14,9 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
|||||||
//ConLog.Warning("path: %s [%s]", ppath, path);
|
//ConLog.Warning("path: %s [%s]", ppath, path);
|
||||||
|
|
||||||
s32 _oflags = flags;
|
s32 _oflags = flags;
|
||||||
if(flags & LV2_O_CREAT)
|
if(flags & CELL_O_CREAT)
|
||||||
{
|
{
|
||||||
_oflags &= ~LV2_O_CREAT;
|
_oflags &= ~CELL_O_CREAT;
|
||||||
/*
|
/*
|
||||||
//create path
|
//create path
|
||||||
for(uint p=1;p<ppath.Length();p++)
|
for(uint p=1;p<ppath.Length();p++)
|
||||||
@ -125,35 +45,35 @@ int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size)
|
|||||||
|
|
||||||
vfsOpenMode o_mode;
|
vfsOpenMode o_mode;
|
||||||
|
|
||||||
switch(flags & LV2_O_ACCMODE)
|
switch(flags & CELL_O_ACCMODE)
|
||||||
{
|
{
|
||||||
case LV2_O_RDONLY:
|
case CELL_O_RDONLY:
|
||||||
_oflags &= ~LV2_O_RDONLY;
|
_oflags &= ~CELL_O_RDONLY;
|
||||||
o_mode = vfsRead;
|
o_mode = vfsRead;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LV2_O_WRONLY:
|
case CELL_O_WRONLY:
|
||||||
_oflags &= ~LV2_O_WRONLY;
|
_oflags &= ~CELL_O_WRONLY;
|
||||||
|
|
||||||
if(flags & LV2_O_APPEND)
|
if(flags & CELL_O_APPEND)
|
||||||
{
|
{
|
||||||
_oflags &= ~LV2_O_APPEND;
|
_oflags &= ~CELL_O_APPEND;
|
||||||
o_mode = vfsWriteAppend;
|
o_mode = vfsWriteAppend;
|
||||||
}
|
}
|
||||||
else if(flags & LV2_O_EXCL)
|
else if(flags & CELL_O_EXCL)
|
||||||
{
|
{
|
||||||
_oflags &= ~LV2_O_EXCL;
|
_oflags &= ~CELL_O_EXCL;
|
||||||
o_mode = vfsWriteExcl;
|
o_mode = vfsWriteExcl;
|
||||||
}
|
}
|
||||||
else //if(flags & LV2_O_TRUNC)
|
else //if(flags & CELL_O_TRUNC)
|
||||||
{
|
{
|
||||||
_oflags &= ~LV2_O_TRUNC;
|
_oflags &= ~CELL_O_TRUNC;
|
||||||
o_mode = vfsWrite;
|
o_mode = vfsWrite;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LV2_O_RDWR:
|
case CELL_O_RDWR:
|
||||||
_oflags &= ~LV2_O_RDWR;
|
_oflags &= ~CELL_O_RDWR;
|
||||||
o_mode = vfsReadWrite;
|
o_mode = vfsReadWrite;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -187,7 +107,10 @@ int cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread)
|
|||||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||||
vfsStream& file = *(vfsStream*)id.m_data;
|
vfsStream& file = *(vfsStream*)id.m_data;
|
||||||
|
|
||||||
nread = file.Read(Memory.GetMemFromAddr(buf_addr), nbytes);
|
const u64 res = nbytes ? file.Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;
|
||||||
|
|
||||||
|
if(nread.IsGood())
|
||||||
|
nread = res;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
@ -205,7 +128,10 @@ int cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite)
|
|||||||
nbytes = block.GetSize() - (buf_addr - block.GetStartAddr());
|
nbytes = block.GetSize() - (buf_addr - block.GetStartAddr());
|
||||||
}
|
}
|
||||||
|
|
||||||
nwrite = nbytes ? file.Write(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;
|
const u64 res = nbytes ? file.Write(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;
|
||||||
|
|
||||||
|
if(nwrite.IsGood())
|
||||||
|
nwrite = res;
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
@ -242,7 +168,7 @@ int cellFsClosedir(u32 fd)
|
|||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellFsStat(const u32 path_addr, mem_class_t sb)
|
int cellFsStat(const u32 path_addr, mem_struct_ptr_t<CellFsStat> sb)
|
||||||
{
|
{
|
||||||
const wxString& path = Memory.ReadString(path_addr);
|
const wxString& path = Memory.ReadString(path_addr);
|
||||||
sys_fs.Log("cellFsFstat(path: %s, sb_addr: 0x%x)", path, sb.GetAddr());
|
sys_fs.Log("cellFsFstat(path: %s, sb_addr: 0x%x)", path, sb.GetAddr());
|
||||||
@ -265,63 +191,43 @@ int cellFsStat(const u32 path_addr, mem_class_t sb)
|
|||||||
return CELL_ENOENT;
|
return CELL_ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
CellFsStat stat;
|
sb->st_mode =
|
||||||
stat.st_mode =
|
|
||||||
CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR |
|
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_IRGRP | CELL_FS_S_IWGRP | CELL_FS_S_IXGRP |
|
||||||
CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH;
|
CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH;
|
||||||
|
|
||||||
stat.st_mode |= CELL_FS_S_IFREG; //TODO: dir CELL_FS_S_IFDIR
|
sb->st_mode |= CELL_FS_S_IFREG; //TODO: dir CELL_FS_S_IFDIR
|
||||||
stat.st_uid = 0;
|
sb->st_uid = 0;
|
||||||
stat.st_gid = 0;
|
sb->st_gid = 0;
|
||||||
stat.st_atime = 0; //TODO
|
sb->st_atime = 0; //TODO
|
||||||
stat.st_mtime = 0; //TODO
|
sb->st_mtime = 0; //TODO
|
||||||
stat.st_ctime = 0; //TODO
|
sb->st_ctime = 0; //TODO
|
||||||
stat.st_size = f->GetSize();
|
sb->st_size = f->GetSize();
|
||||||
stat.st_blksize = 4096;
|
sb->st_blksize = 4096;
|
||||||
|
|
||||||
sb += stat.st_mode;
|
|
||||||
sb += stat.st_uid;
|
|
||||||
sb += stat.st_gid;
|
|
||||||
sb += stat.st_atime;
|
|
||||||
sb += stat.st_mtime;
|
|
||||||
sb += stat.st_ctime;
|
|
||||||
sb += stat.st_size;
|
|
||||||
sb += stat.st_blksize;
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cellFsFstat(u32 fd, mem_class_t sb)
|
int cellFsFstat(u32 fd, mem_struct_ptr_t<CellFsStat> sb)
|
||||||
{
|
{
|
||||||
sys_fs.Log("cellFsFstat(fd: %d, sb_addr: 0x%x)", fd, sb.GetAddr());
|
sys_fs.Log("cellFsFstat(fd: %d, sb_addr: 0x%x)", fd, sb.GetAddr());
|
||||||
ID id;
|
ID id;
|
||||||
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH;
|
||||||
vfsStream& file = *(vfsStream*)id.m_data;
|
vfsStream& file = *(vfsStream*)id.m_data;
|
||||||
|
|
||||||
CellFsStat stat;
|
sb->st_mode =
|
||||||
stat.st_mode =
|
|
||||||
CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR |
|
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_IRGRP | CELL_FS_S_IWGRP | CELL_FS_S_IXGRP |
|
||||||
CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH;
|
CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH;
|
||||||
|
|
||||||
stat.st_mode |= CELL_FS_S_IFREG; //TODO: dir CELL_FS_S_IFDIR
|
sb->st_mode |= CELL_FS_S_IFREG; //TODO: dir CELL_FS_S_IFDIR
|
||||||
stat.st_uid = 0;
|
sb->st_uid = 0;
|
||||||
stat.st_gid = 0;
|
sb->st_gid = 0;
|
||||||
stat.st_atime = 0; //TODO
|
sb->st_atime = 0; //TODO
|
||||||
stat.st_mtime = 0; //TODO
|
sb->st_mtime = 0; //TODO
|
||||||
stat.st_ctime = 0; //TODO
|
sb->st_ctime = 0; //TODO
|
||||||
stat.st_size = file.GetSize();
|
sb->st_size = file.GetSize();
|
||||||
stat.st_blksize = 4096;
|
sb->st_blksize = 4096;
|
||||||
|
|
||||||
sb += stat.st_mode;
|
|
||||||
sb += stat.st_uid;
|
|
||||||
sb += stat.st_gid;
|
|
||||||
sb += stat.st_atime;
|
|
||||||
sb += stat.st_mtime;
|
|
||||||
sb += stat.st_ctime;
|
|
||||||
sb += stat.st_size;
|
|
||||||
sb += stat.st_blksize;
|
|
||||||
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
@ -379,9 +285,9 @@ int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos)
|
|||||||
sys_fs.Log("cellFsLseek(fd: %d, offset: 0x%llx, whence: %d, pos_addr: 0x%x)", fd, offset, whence, pos.GetAddr());
|
sys_fs.Log("cellFsLseek(fd: %d, offset: 0x%llx, whence: %d, pos_addr: 0x%x)", fd, offset, whence, pos.GetAddr());
|
||||||
switch(whence)
|
switch(whence)
|
||||||
{
|
{
|
||||||
case LV2_SEEK_SET: seek_mode = vfsSeekSet; break;
|
case CELL_SEEK_SET: seek_mode = vfsSeekSet; break;
|
||||||
case LV2_SEEK_CUR: seek_mode = vfsSeekCur; break;
|
case CELL_SEEK_CUR: seek_mode = vfsSeekCur; break;
|
||||||
case LV2_SEEK_END: seek_mode = vfsSeekEnd; break;
|
case CELL_SEEK_END: seek_mode = vfsSeekEnd; break;
|
||||||
default:
|
default:
|
||||||
sys_fs.Error(fd, "Unknown seek whence! (%d)", whence);
|
sys_fs.Error(fd, "Unknown seek whence! (%d)", whence);
|
||||||
return CELL_EINVAL;
|
return CELL_EINVAL;
|
||||||
|
82
rpcs3/Emu/SysCalls/lv2/SC_FileSystem.h
Normal file
82
rpcs3/Emu/SysCalls/lv2/SC_FileSystem.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
enum CellFsOflag
|
||||||
|
{
|
||||||
|
CELL_O_RDONLY = 000000,
|
||||||
|
CELL_O_WRONLY = 000001,
|
||||||
|
CELL_O_RDWR = 000002,
|
||||||
|
CELL_O_ACCMODE = 000003,
|
||||||
|
CELL_O_CREAT = 000100,
|
||||||
|
CELL_O_EXCL = 000200,
|
||||||
|
CELL_O_TRUNC = 001000,
|
||||||
|
CELL_O_APPEND = 002000,
|
||||||
|
CELL_O_MSELF = 010000,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const u32 CELL_FS_TYPE_UNKNOWN = 0;
|
||||||
|
|
||||||
|
enum CellFsSeek
|
||||||
|
{
|
||||||
|
CELL_SEEK_SET,
|
||||||
|
CELL_SEEK_CUR,
|
||||||
|
CELL_SEEK_END,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum CellFsLength
|
||||||
|
{
|
||||||
|
CELL_MAX_FS_PATH_LENGTH = 1024,
|
||||||
|
CELL_MAX_FS_FILE_NAME_LENGTH = 255,
|
||||||
|
CELL_MAX_FS_MP_LENGTH = 31,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CELL_FS_S_IFDIR = 0040000, //directory
|
||||||
|
CELL_FS_S_IFREG = 0100000, //regular
|
||||||
|
CELL_FS_S_IFLNK = 0120000, //symbolic link
|
||||||
|
CELL_FS_S_IFWHT = 0160000, //unknown
|
||||||
|
|
||||||
|
CELL_FS_S_IRUSR = 0000400, //R for owner
|
||||||
|
CELL_FS_S_IWUSR = 0000200, //W for owner
|
||||||
|
CELL_FS_S_IXUSR = 0000100, //X for owner
|
||||||
|
|
||||||
|
CELL_FS_S_IRGRP = 0000040, //R for group
|
||||||
|
CELL_FS_S_IWGRP = 0000020, //W for group
|
||||||
|
CELL_FS_S_IXGRP = 0000010, //X for group
|
||||||
|
|
||||||
|
CELL_FS_S_IROTH = 0000004, //R for other
|
||||||
|
CELL_FS_S_IWOTH = 0000002, //W for other
|
||||||
|
CELL_FS_S_IXOTH = 0000001, //X for other
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FsDirentType
|
||||||
|
{
|
||||||
|
CELL_FS_TYPE_DIRECTORY = 1,
|
||||||
|
CELL_FS_TYPE_REGULAR = 2,
|
||||||
|
CELL_FS_TYPE_SYMLINK = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CellFsStat
|
||||||
|
{
|
||||||
|
be_t<u32> st_mode;
|
||||||
|
be_t<s32> st_uid;
|
||||||
|
be_t<s32> st_gid;
|
||||||
|
be_t<u64> st_atime;
|
||||||
|
be_t<u64> st_mtime;
|
||||||
|
be_t<u64> st_ctime;
|
||||||
|
be_t<u64> st_size;
|
||||||
|
be_t<u64> st_blksize;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CellFsUtimbuf
|
||||||
|
{
|
||||||
|
be_t<u64> actime;
|
||||||
|
be_t<u64> modtime;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct CellFsDirent
|
||||||
|
{
|
||||||
|
u8 d_type;
|
||||||
|
u8 d_namlen;
|
||||||
|
char d_name[CELL_MAX_FS_FILE_NAME_LENGTH + 1];
|
||||||
|
};
|
@ -99,16 +99,21 @@ void Emulator::Load()
|
|||||||
}
|
}
|
||||||
ConLog.SkipLn();
|
ConLog.SkipLn();
|
||||||
|
|
||||||
const auto f = m_elf_path.Len() ? OpenFile(m_elf_path) : std::shared_ptr<vfsLocalFile>(new vfsLocalFile(m_path));
|
if(m_elf_path.IsEmpty())
|
||||||
|
{
|
||||||
|
GetVFS().GetDeviceLocal(m_path, m_elf_path);
|
||||||
|
}
|
||||||
|
|
||||||
if(!f->IsOpened())
|
vfsFile f(m_elf_path);
|
||||||
|
|
||||||
|
if(!f.IsOpened())
|
||||||
{
|
{
|
||||||
ConLog.Error("Elf not found! (%s - %s)", m_path, m_elf_path);
|
ConLog.Error("Elf not found! (%s - %s)", m_path, m_elf_path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_error;
|
bool is_error;
|
||||||
Loader l(*f);
|
Loader l(f);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -206,6 +206,7 @@
|
|||||||
<ClCompile Include="Emu\DbgConsole.cpp" />
|
<ClCompile Include="Emu\DbgConsole.cpp" />
|
||||||
<ClCompile Include="Emu\FS\VFS.cpp" />
|
<ClCompile Include="Emu\FS\VFS.cpp" />
|
||||||
<ClCompile Include="Emu\FS\vfsDevice.cpp" />
|
<ClCompile Include="Emu\FS\vfsDevice.cpp" />
|
||||||
|
<ClCompile Include="Emu\FS\vfsFile.cpp" />
|
||||||
<ClCompile Include="Emu\FS\vfsFileBase.cpp" />
|
<ClCompile Include="Emu\FS\vfsFileBase.cpp" />
|
||||||
<ClCompile Include="Emu\FS\vfsLocalFile.cpp" />
|
<ClCompile Include="Emu\FS\vfsLocalFile.cpp" />
|
||||||
<ClCompile Include="Emu\FS\vfsStream.cpp" />
|
<ClCompile Include="Emu\FS\vfsStream.cpp" />
|
||||||
@ -291,6 +292,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="..\Utilities\Array.h" />
|
<ClInclude Include="..\Utilities\Array.h" />
|
||||||
|
<ClInclude Include="..\Utilities\BEType.h" />
|
||||||
<ClInclude Include="..\Utilities\IdManager.h" />
|
<ClInclude Include="..\Utilities\IdManager.h" />
|
||||||
<ClInclude Include="..\Utilities\MTProgressDialog.h" />
|
<ClInclude Include="..\Utilities\MTProgressDialog.h" />
|
||||||
<ClInclude Include="..\Utilities\Thread.h" />
|
<ClInclude Include="..\Utilities\Thread.h" />
|
||||||
|
@ -307,6 +307,9 @@
|
|||||||
<ClCompile Include="Emu\SysCalls\lv2\SC_Mouse.cpp">
|
<ClCompile Include="Emu\SysCalls\lv2\SC_Mouse.cpp">
|
||||||
<Filter>Emu\SysCalls\lv2</Filter>
|
<Filter>Emu\SysCalls\lv2</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Emu\FS\vfsFile.cpp">
|
||||||
|
<Filter>Emu\FS</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="rpcs3.rc" />
|
<ResourceCompile Include="rpcs3.rc" />
|
||||||
@ -474,5 +477,8 @@
|
|||||||
<ClInclude Include="Emu\Cell\PPUProgramCompiler.h">
|
<ClInclude Include="Emu\Cell\PPUProgramCompiler.h">
|
||||||
<Filter>Include</Filter>
|
<Filter>Include</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\Utilities\BEType.h">
|
||||||
|
<Filter>Utilities</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
@ -186,6 +186,7 @@ enum Status
|
|||||||
Ready,
|
Ready,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#include "Utilities/BEType.h"
|
||||||
#include "Utilities/Thread.h"
|
#include "Utilities/Thread.h"
|
||||||
#include "Utilities/Array.h"
|
#include "Utilities/Array.h"
|
||||||
#include "Utilities/Timer.h"
|
#include "Utilities/Timer.h"
|
||||||
@ -202,6 +203,7 @@ enum Status
|
|||||||
|
|
||||||
#include "Emu/FS/vfsFileBase.h"
|
#include "Emu/FS/vfsFileBase.h"
|
||||||
#include "Emu/FS/vfsLocalFile.h"
|
#include "Emu/FS/vfsLocalFile.h"
|
||||||
|
#include "Emu/FS/vfsFile.h"
|
||||||
#include "Emu/FS/vfsStream.h"
|
#include "Emu/FS/vfsStream.h"
|
||||||
#include "Emu/FS/vfsStreamMemory.h"
|
#include "Emu/FS/vfsStreamMemory.h"
|
||||||
#include "rpcs3.h"
|
#include "rpcs3.h"
|
||||||
|
Loading…
Reference in New Issue
Block a user