diff --git a/Utilities/BEType.h b/Utilities/BEType.h new file mode 100644 index 0000000000..ba9ade3830 --- /dev/null +++ b/Utilities/BEType.h @@ -0,0 +1,154 @@ +#pragma once +#pragma warning(disable: 4739) + +template +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 + be_t(const be_t& 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 + operator const T() const + { + return ToLE(); + } + + template + operator const be_t() const + { + be_t 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 be_t& operator += (T1 right) { return *this = T(*this) + right; } + template be_t& operator -= (T1 right) { return *this = T(*this) - right; } + template be_t& operator *= (T1 right) { return *this = T(*this) * right; } + template be_t& operator /= (T1 right) { return *this = T(*this) / right; } + template be_t& operator %= (T1 right) { return *this = T(*this) % right; } + template be_t& operator &= (T1 right) { return *this = T(*this) & right; } + template be_t& operator |= (T1 right) { return *this = T(*this) | right; } + template be_t& operator ^= (T1 right) { return *this = T(*this) ^ right; } + template be_t& operator <<= (T1 right) { return *this = T(*this) << right; } + template be_t& operator >>= (T1 right) { return *this = T(*this) >> right; } + + template be_t& operator += (const be_t& right) { return *this = ToLE() + right.ToLE(); } + template be_t& operator -= (const be_t& right) { return *this = ToLE() - right.ToLE(); } + template be_t& operator *= (const be_t& right) { return *this = ToLE() * right.ToLE(); } + template be_t& operator /= (const be_t& right) { return *this = ToLE() / right.ToLE(); } + template be_t& operator %= (const be_t& right) { return *this = ToLE() % right.ToLE(); } + template be_t& operator &= (const be_t& right) { return *this = ToBE() & right.ToBE(); } + template be_t& operator |= (const be_t& right) { return *this = ToBE() | right.ToBE(); } + template be_t& operator ^= (const be_t& right) { return *this = ToBE() ^ right.ToBE(); } + + template be_t operator & (const be_t& right) const { be_t res; res.FromBE(ToBE() & right.ToBE()); return res; } + template be_t operator | (const be_t& right) const { be_t res; res.FromBE(ToBE() | right.ToBE()); return res; } + template be_t operator ^ (const be_t& right) const { be_t res; res.FromBE(ToBE() ^ right.ToBE()); return res; } + + template bool operator == (T1 right) const { return ToLE() == right; } + template bool operator != (T1 right) const { return !(*this == right); } + template bool operator > (T1 right) const { return ToLE() > right; } + template bool operator < (T1 right) const { return ToLE() < right; } + template bool operator >= (T1 right) const { return ToLE() >= right; } + template bool operator <= (T1 right) const { return ToLE() <= right; } + + template bool operator == (const be_t& right) const { return ToBE() == right.ToBE(); } + template bool operator != (const be_t& right) const { return !(*this == right); } + template bool operator > (const be_t& right) const { return ToLE() > right.ToLE(); } + template bool operator < (const be_t& right) const { return ToLE() < right.ToLE(); } + template bool operator >= (const be_t& right) const { return ToLE() >= right.ToLE(); } + template bool operator <= (const be_t& right) const { return ToLE() <= right.ToLE(); } +}; \ No newline at end of file diff --git a/rpcs3/Emu/FS/VFS.cpp b/rpcs3/Emu/FS/VFS.cpp index 0a162f9f2c..ffaf97737e 100644 --- a/rpcs3/Emu/FS/VFS.cpp +++ b/rpcs3/Emu/FS/VFS.cpp @@ -101,6 +101,28 @@ vfsDevice* VFS::GetDevice(const wxString& ps3_path, wxString& path) 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 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) { Array entries; diff --git a/rpcs3/Emu/FS/VFS.h b/rpcs3/Emu/FS/VFS.h index 798e951142..49f7798a22 100644 --- a/rpcs3/Emu/FS/VFS.h +++ b/rpcs3/Emu/FS/VFS.h @@ -36,6 +36,7 @@ struct VFS void Create(const wxString& ps3_path); void Close(vfsStream*& device); vfsDevice* GetDevice(const wxString& ps3_path, wxString& path); + vfsDevice* GetDeviceLocal(const wxString& local_path, wxString& path); void Init(const wxString& path); void SaveLoadDevices(Array& res, bool is_load); diff --git a/rpcs3/Emu/FS/vfsDevice.cpp b/rpcs3/Emu/FS/vfsDevice.cpp index 2a05018c11..570e60dd52 100644 --- a/rpcs3/Emu/FS/vfsDevice.cpp +++ b/rpcs3/Emu/FS/vfsDevice.cpp @@ -36,6 +36,19 @@ u32 vfsDevice::CmpPs3Path(const wxString& ps3_path) 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; iIsOpened(); +} + +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(); +} diff --git a/rpcs3/Emu/FS/vfsFile.h b/rpcs3/Emu/FS/vfsFile.h new file mode 100644 index 0000000000..d9777b7203 --- /dev/null +++ b/rpcs3/Emu/FS/vfsFile.h @@ -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; +}; \ No newline at end of file diff --git a/rpcs3/Emu/FS/vfsStreamMemory.cpp b/rpcs3/Emu/FS/vfsStreamMemory.cpp index 1b0900b7da..8bb08090e6 100644 --- a/rpcs3/Emu/FS/vfsStreamMemory.cpp +++ b/rpcs3/Emu/FS/vfsStreamMemory.cpp @@ -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_size = size ? size : ~0ULL; vfsStream::Reset(); } +u64 vfsStreamMemory::GetSize() +{ + return m_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); @@ -28,7 +39,12 @@ u64 vfsStreamMemory::Write(const void* src, 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); diff --git a/rpcs3/Emu/FS/vfsStreamMemory.h b/rpcs3/Emu/FS/vfsStreamMemory.h index 086f7109d5..00cb675013 100644 --- a/rpcs3/Emu/FS/vfsStreamMemory.h +++ b/rpcs3/Emu/FS/vfsStreamMemory.h @@ -4,12 +4,15 @@ struct vfsStreamMemory : public vfsStream { u64 m_addr; + u64 m_size; public: 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 Read(void* dst, u64 size) override; diff --git a/rpcs3/Emu/GS/GL/FragmentProgram.cpp b/rpcs3/Emu/GS/GL/FragmentProgram.cpp index 3cb79fdae5..a8adf334ac 100644 --- a/rpcs3/Emu/GS/GL/FragmentProgram.cpp +++ b/rpcs3/Emu/GS/GL/FragmentProgram.cpp @@ -310,7 +310,7 @@ void FragmentDecompilerThread::Task() if(dst.end) break; - data.SetOffset(m_offset); + data.Skip(m_offset); } m_shader = BuildCode(); diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index f80f2bbcbc..37576f9982 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -369,24 +369,56 @@ public: extern MemoryBase Memory; -class MemoryAllocator +template class mem_struct_ptr_t { - u32 m_addr; + const u32 m_addr; 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 class mem_t const u32 m_addr; public: - mem_t(u64 addr) : m_addr(addr) + mem_t(u32 addr) : m_addr(addr) { } mem_t& operator = (T right) { - switch(sizeof(T)) - { - 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; - } + (be_t&)Memory[m_addr] = right; - assert(0); return *this; } operator const T() const { - switch(sizeof(T)) - { - 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); + return (be_t&)Memory[m_addr]; } 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; } - u64 GetAddr() const { return m_addr; } + u32 GetAddr() const { return m_addr; } bool IsGood() const { @@ -447,88 +464,181 @@ public: template class mem_ptr_t { - u64 m_addr; - const u64 m_iaddr; + u32 m_addr; public: - mem_ptr_t(u64 addr) - : m_addr(addr) - , m_iaddr(addr) + mem_ptr_t(u32 addr) : m_addr(addr) { } void operator = (T right) { - switch(sizeof(T)) - { - 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); + (be_t&)Memory[m_addr] = 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) + u32 operator += (T right) { *this = right; m_addr += sizeof(T); 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*() { return GetPtr(); } + operator void*() { return GetPtr(); } + operator be_t*() const { return GetPtr(); } + operator void*() const { return GetPtr(); } + + const char* GetString() const { - const u64 offset = i*sizeof(T); - (*(mem_ptr_t*)this).m_addr += offset; - const T ret = *this; - (*(mem_ptr_t*)this).m_addr -= offset; - return ret; + return (const char*)&Memory[m_addr]; } - void Reset() { m_addr = m_iaddr; } - u64 GetCurAddr() const { return m_addr; } - u64 GetAddr() const { return m_iaddr; } - u64 SetOffset(const u32 offset) { return m_addr += offset; } + be_t* GetPtr() + { + return (be_t*)&Memory[m_addr]; + } + + const be_t* GetPtr() const + { + return (const be_t*)&Memory[m_addr]; + } }; class mem_class_t { - u64 addr; - const u64 iaddr; + u32 m_addr; public: - mem_class_t(u64 _addr) - : addr(_addr) - , iaddr(_addr) + mem_class_t(u32 addr) : m_addr(addr) { } - template u64 operator += (T right) + template u32 operator += (T right) { - mem_t m(addr); + mem_t& m((mem_t&)*this); m = right; - addr += sizeof(T); - return addr; + m_addr += sizeof(T); + return m_addr; } template operator T() { - mem_t m(addr); + mem_t& m((mem_t&)*this); const T ret = m; - addr += sizeof(T); + m_addr += sizeof(T); return ret; } - void Reset() { addr = iaddr; } - u64 GetCurAddr() const { return addr; } - u64 GetAddr() const { return iaddr; } - void SetAddr(const u64 _addr) { addr = _addr; } + u64 GetAddr() const { return m_addr; } + void SetAddr(const u64 addr) { m_addr = addr; } +}; + +template +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 + operator const T1() const + { + return T1(*m_ptr); + } + + template + 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 + operator const mem_t() const + { + return GetAddr(); + } + + operator const mem_struct_ptr_t() const + { + return GetAddr(); + } + + template + NT* To(uint offset = 0) + { + return (NT*)(m_ptr + offset); + } }; typedef mem_t mem8_t; diff --git a/rpcs3/Emu/SysCalls/FuncList.cpp b/rpcs3/Emu/SysCalls/FuncList.cpp index e80e866100..5c5d90e433 100644 --- a/rpcs3/Emu/SysCalls/FuncList.cpp +++ b/rpcs3/Emu/SysCalls/FuncList.cpp @@ -2297,22 +2297,22 @@ s64 SysCalls::DoFunc(const u32 id) case 0x1ea02e2f: FUNC_LOG_ERROR("TODO: cellFsArcadeHddSerialNumber"); case 0x2664c8ae: FUNC_LOG_ERROR("TODO: cellFsStReadInit"); case 0x27800c6b: FUNC_LOG_ERROR("TODO: cellFsStRead"); - case 0x2796fdf3: return cellFsRmdir(SC_ARGS_1);//FUNC_LOG_ERROR("TODO: cellFsRmdir"); - case 0x2cb51f0d: return cellFsClose(SC_ARGS_1);//FUNC_LOG_ERROR("TODO: cellFsClose"); + case 0x2796fdf3: FUNC_LOG_ERROR("TODO: cellFsRmdir"); + case 0x2cb51f0d: FUNC_LOG_ERROR("TODO: cellFsClose"); case 0x2cf1296b: FUNC_LOG_ERROR("TODO: cellFsAllocateFileAreaByFdWithoutZeroFill"); case 0x3140f6e1: FUNC_LOG_ERROR("TODO: cellFsSetIoBuffer"); case 0x3394f037: FUNC_LOG_ERROR("TODO: cellFsAllocateFileAreaByFdWithInitialData"); 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 0x4d5ff8e2: return cellFsRead(SC_ARGS_4);//FUNC_LOG_ERROR("TODO: cellFsRead"); - case 0x5c74903d: return cellFsReaddir(SC_ARGS_3);//FUNC_LOG_ERROR("TODO: cellFsReaddir"); + case 0x4d5ff8e2: FUNC_LOG_ERROR("TODO: cellFsRead"); + case 0x5c74903d: FUNC_LOG_ERROR("TODO: cellFsReaddir"); case 0x606f9f42: FUNC_LOG_ERROR("TODO: cellFsChangeFileSizeWithoutAllocation"); 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 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 0x7f4677a8: FUNC_LOG_ERROR("TODO: cellFsUnlink"); 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 0x9f951810: FUNC_LOG_ERROR("TODO: cellFsAioFinish"); 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 0xb1840b53: FUNC_LOG_ERROR("TODO: cellFsSdataOpen"); 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 0xbef554a4: FUNC_LOG_ERROR("TODO: cellFsUtime"); 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 0xdb869f20: FUNC_LOG_ERROR("TODO: cellFsAioInit"); case 0xe15939c3: FUNC_LOG_ERROR("TODO: cellFsChangeFileSizeByFdWithoutAllocation"); - case 0xecdcf2ab: return cellFsWrite(SC_ARGS_4);//FUNC_LOG_ERROR("TODO: cellFsWrite"); - case 0xef3efa34: return cellFsFstat(SC_ARGS_2);//FUNC_LOG_ERROR("TODO: cellFsFstat"); - case 0xf12eecc8: return cellFsRename(SC_ARGS_2);//FUNC_LOG_ERROR("TODO: cellFsRename"); + case 0xecdcf2ab: FUNC_LOG_ERROR("TODO: cellFsWrite"); + case 0xef3efa34: FUNC_LOG_ERROR("TODO: cellFsFstat"); + case 0xf12eecc8: FUNC_LOG_ERROR("TODO: cellFsRename"); case 0xf8e5d9a0: FUNC_LOG_ERROR("TODO: cellFsStReadStop"); 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 0x0d5f2c14: FUNC_LOG_ERROR("TODO: cellPadClearBuf"); 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 0x2073b7f6: FUNC_LOG_ERROR("TODO: cellKbClearBuf"); 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 0x4cc9b68d: FUNC_LOG_ERROR("TODO: cellPadPeriphGetInfo"); case 0x4d0b3b1f: FUNC_LOG_ERROR("TODO: cellMouseInfoTabletMode"); - case 0x4d9b75d5: return cellPadEnd();//FUNC_LOG_ERROR("TODO: cellPadEnd"); - case 0x578e3c98: return cellPadSetPortSetting(SC_ARGS_2);//FUNC_LOG_ERROR("TODO: cellPadSetPortSetting"); + case 0x4d9b75d5: FUNC_LOG_ERROR("TODO: cellPadEnd"); + case 0x578e3c98: FUNC_LOG_ERROR("TODO: cellPadSetPortSetting"); case 0x5baf30fb: FUNC_LOG_ERROR("TODO: cellMouseGetInfo"); case 0x5f81900c: FUNC_LOG_ERROR("TODO: sys_config_unregister_service"); 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 0x6d367953: FUNC_LOG_ERROR("TODO: sys_config_stop"); case 0x78200559: FUNC_LOG_ERROR("TODO: cellPadInfoSensorMode"); case 0x78f058a2: FUNC_LOG_ERROR("TODO: sys_config_register_service"); case 0x7c5d5fc1: FUNC_LOG_ERROR("TODO: cellPadDbgPeriphRegisterDevice"); 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 0x94b98e39: FUNC_LOG_ERROR("TODO: cellPadDbgLddSetDataInsertMode"); case 0xa328cc35: FUNC_LOG_ERROR("TODO: cellMouseGetRawData"); 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 0xbafd6409: FUNC_LOG_ERROR("TODO: cellPadLddDataInsert"); case 0xbe5be3ba: FUNC_LOG_ERROR("TODO: cellPadSetSensorMode"); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp index 0f0b8da426..93ca74c373 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGifDec.cpp @@ -21,53 +21,95 @@ enum 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 { CELL_GIFDEC_RGBA = 10, 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 { - u32 SWidth; - u32 SHeight; - u32 SGlobalColorTableFlag; - u32 SColorResolution; - u32 SSortFlag; - u32 SSizeOfGlobalColorTable; - u32 SBackGroundColor; - u32 SPixelAspectRatio; + be_t SWidth; + be_t SHeight; + be_t SGlobalColorTableFlag; + be_t SColorResolution; + be_t SSortFlag; + be_t SSizeOfGlobalColorTable; + be_t SBackGroundColor; + be_t SPixelAspectRatio; }; struct CellGifDecSrc { - u32 srcSelect; // CellGifDecStreamSrcSel - u32 fileName; // const char* - u64 fileOffset; // int64_t - u32 fileSize; - u32 streamPtr; - u32 streamSize; - u32 spuThreadEnable; // CellGifDecSpuThreadEna + be_t srcSelect; + be_t fileName; + be_t fileOffset; + be_t fileSize; + be_t streamPtr; + be_t streamSize; + be_t spuThreadEnable; }; struct CellGifDecInParam { - u32 *commandPtr; - u32 colorSpace; // CellGifDecColorSpace - u8 outputColorAlpha1; - u8 outputColorAlpha2; - u8 reserved[2]; + be_t commandPtr; + be_t colorSpace; // CellGifDecColorSpace + be_t outputColorAlpha1; + be_t outputColorAlpha2; + be_t reserved[2]; }; struct CellGifDecOutParam { - u64 outputWidthByte; - u32 outputWidth; - u32 outputHeight; - u32 outputComponents; - u32 outputBitDepth; - u32 outputColorSpace; // CellGifDecColorSpace - u32 useMemorySpace; + be_t outputWidthByte; + be_t outputWidth; + be_t outputHeight; + be_t outputComponents; + be_t outputBitDepth; + be_t outputColorSpace; // CellGifDecColorSpace + be_t useMemorySpace; +}; + +struct CellGifDecExtension +{ + be_t label; + be_t data; +}; + +struct CellGifDecDataOutInfo +{ + be_t recordType; + CellGifDecExtension outExtension; + be_t status; +}; + +struct CellGifDecOpnInfo +{ + be_t initSpaceAllocated; +}; + +struct CellGifDecDataCtrlParam +{ + be_t outputBytesPerLine; }; struct CellGifDecSubHandle //Custom struct @@ -78,7 +120,6 @@ struct CellGifDecSubHandle //Custom struct CellGifDecOutParam outParam; }; - int cellGifDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam) { UNIMPLEMENTED_FUNC(cellGifDec); @@ -91,164 +132,188 @@ int cellGifDecExtCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam, u 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 src, mem_struct_ptr_t openInfo) { - //u32 srcSelect = Memory.Read32(src_addr); - u32 fileName = Memory.Read32(src_addr+4); - //u64 fileOffset = Memory.Read32(src_addr+8); - //u32 fileSize = Memory.Read32(src_addr+12); - //u32 streamPtr = Memory.Read32(src_addr+16); - //u32 streamSize = Memory.Read32(src_addr+20); - //u32 spuThreadEnable = Memory.Read32(src_addr+24); + /* + vfsStream* stream; + + switch(src->srcSelect) + { + case CELL_GIFDEC_FILE: + 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; // Get file descriptor - u32 fd_addr = Memory.Alloc(sizeof(u32), 1); - int ret = cellFsOpen(fileName, 0, fd_addr, NULL, 0); - current_subHandle->fd = Memory.Read32(fd_addr); - Memory.Free(fd_addr); - if(ret != 0) return CELL_GIFDEC_ERROR_OPEN_FILE; + MemoryAllocator> fd; + int ret = cellFsOpen(src->fileName, 0, fd, NULL, 0); + current_subHandle->fd = fd->ToLE(); + if(ret != CELL_OK) return CELL_GIFDEC_ERROR_OPEN_FILE; // Get size of file - u32 sb_addr = Memory.Alloc(52,1); // Alloc a CellFsStat struct - cellFsFstat(current_subHandle->fd, sb_addr); - current_subHandle->fileSize = Memory.Read64(sb_addr+36); // Get CellFsStat.st_size - Memory.Free(sb_addr); + MemoryAllocator sb; // Alloc a CellFsStat struct + ret = cellFsFstat(current_subHandle->fd, sb); + if(ret != CELL_OK) return ret; + current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size // 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; } -int cellGifDecReadHeader(u32 mainHandle, u32 subHandle, mem_class_t info) +int cellGifDecReadHeader(u32 mainHandle, u32 subHandle, mem_struct_ptr_t info) { - const u32& fd = ((CellGifDecSubHandle*)subHandle)->fd; - const u64& fileSize = ((CellGifDecSubHandle*)subHandle)->fileSize; - CellGifDecInfo& current_info = ((CellGifDecSubHandle*)subHandle)->info; + 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; + CellGifDecInfo& current_info = subHandle_data->info; //Write the header to buffer - u32 buffer = Memory.Alloc(13,1); // Alloc buffer for GIF header - u32 nread = Memory.Alloc(8,1); - 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); + MemoryAllocator buffer(13); // Alloc buffer for GIF header + MemoryAllocator> pos, nread; - if (Memory.Read32(buffer) != 0x47494638 || - (Memory.Read16(buffer+4) != 0x3961 && - Memory.Read16(buffer+4) != 0x3761)) // Error: The first 6 bytes are not a valid GIF signature + cellFsLseek(fd, 0, CELL_SEEK_SET, pos); + cellFsRead(fd, buffer.GetAddr(), buffer.GetSize(), nread); + + if (*buffer.To>(0) != 0x47494638 || + (*buffer.To(4) != 0x6139 && *buffer.To(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 } - u8 packedField = Memory.Read8(buffer+10); - current_info.SWidth = Memory.Read8(buffer+6) + Memory.Read8(buffer+7) * 256; - current_info.SHeight = Memory.Read8(buffer+8) + Memory.Read8(buffer+9) * 256; + u8 packedField = buffer[10]; + current_info.SWidth = buffer[6] + buffer[7] * 0x100; + current_info.SHeight = buffer[8] + buffer[9] * 0x100; current_info.SGlobalColorTableFlag = packedField >> 7; current_info.SColorResolution = ((packedField >> 4) & 7)+1; current_info.SSortFlag = (packedField >> 3) & 1; current_info.SSizeOfGlobalColorTable = (packedField & 7)+1; - current_info.SBackGroundColor = Memory.Read8(buffer+11); - current_info.SPixelAspectRatio = Memory.Read8(buffer+12); + current_info.SBackGroundColor = buffer[11]; + current_info.SPixelAspectRatio = buffer[12]; - info += current_info.SWidth; - 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); + info = current_info; 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 inParam, mem_struct_ptr_t outParam) { - CellGifDecInfo& current_info = ((CellGifDecSubHandle*)subHandle)->info; - CellGifDecOutParam& current_outParam = ((CellGifDecSubHandle*)subHandle)->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; + + 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.outputWidth = current_info.SWidth; - current_outParam.outputHeight = current_info.SHeight; - current_outParam.outputColorSpace = Memory.Read32(inParam_addr+4); + current_outParam.outputWidth = current_info.SWidth; + current_outParam.outputHeight = current_info.SHeight; + current_outParam.outputColorSpace = inParam->colorSpace; switch (current_outParam.outputColorSpace) { - case CELL_GIFDEC_RGBA: current_outParam.outputComponents = 4; break; - case CELL_GIFDEC_ARGB: current_outParam.outputComponents = 4; break; - default: return CELL_GIFDEC_ERROR_ARG; // Not supported color space + case CELL_GIFDEC_RGBA: + case CELL_GIFDEC_ARGB: current_outParam.outputComponents = 4; break; + default: return CELL_GIFDEC_ERROR_ARG; // Not supported color space } - current_outParam.outputBitDepth = 0; // Unimplemented - current_outParam.useMemorySpace = 0; // Unimplemented + current_outParam.outputBitDepth = 0; // Unimplemented + current_outParam.useMemorySpace = 0; // Unimplemented - outParam += current_outParam.outputWidthByte; - outParam += current_outParam.outputWidth; - outParam += current_outParam.outputHeight; - outParam += current_outParam.outputComponents; - outParam += current_outParam.outputBitDepth; - outParam += current_outParam.outputColorSpace; - outParam += current_outParam.useMemorySpace; + outParam = current_outParam; 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 dataCtrlParam, mem_struct_ptr_t dataOutInfo) { - const u32& fd = ((CellGifDecSubHandle*)subHandle)->fd; - const u64& fileSize = ((CellGifDecSubHandle*)subHandle)->fileSize; - const CellGifDecOutParam& current_outParam = ((CellGifDecSubHandle*)subHandle)->outParam; // (TODO: We should use the outParam) + dataOutInfo->status = CELL_GIFDEC_DEC_STATUS_STOP; + + 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 - u32 buffer = Memory.Alloc(fileSize,1); - u32 nread = Memory.Alloc(8,1); - 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); + MemoryAllocator gif(fileSize); + MemoryAllocator pos, nread; + cellFsLseek(fd, 0, CELL_SEEK_SET, pos); + cellFsRead(fd, gif.GetAddr(), gif.GetSize(), nread); //Decode GIF file. (TODO: Is there any faster alternative? Can we do it without external libraries?) int width, height, actual_components; - unsigned char *gif = (unsigned char*)Memory.VirtualToRealAddr(buffer); - unsigned char *image = stbi_load_from_memory(gif, fileSize, &width, &height, &actual_components, 4); - Memory.Free(buffer); + std::shared_ptr image(stbi_load_from_memory(gif, fileSize, &width, &height, &actual_components, 4)); if (!image) return CELL_GIFDEC_ERROR_STREAM_FORMAT; - u32 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; + uint image_size = width * height * 4; - dataOutInfo += (u32)1; // The output data is an image (dataOutInfo.recordType = 1) - 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?) + switch(current_outParam.outputColorSpace) + { + 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; } int cellGifDecClose(u32 mainHandle, u32 subHandle) { - cellFsClose( ((CellGifDecSubHandle*)subHandle)->fd ); - delete (CellGifDecSubHandle*)subHandle; + 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; + + cellFsClose(subHandle_data->fd); + Emu.GetIdManager().RemoveID(subHandle); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp index b637558370..c112b1f80f 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellJpgDec.cpp @@ -34,48 +34,72 @@ enum CellJpgDecColorSpace 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 { - u32 imageWidth; - u32 imageHeight; - u32 numComponents; - u32 colorSpace; // CellJpgDecColorSpace + be_t imageWidth; + be_t imageHeight; + be_t numComponents; + be_t colorSpace; // CellJpgDecColorSpace }; struct CellJpgDecSrc { - u32 srcSelect; // CellJpgDecStreamSrcSel - u32 fileName; // const char* - u64 fileOffset; // int64_t - u32 fileSize; - u32 streamPtr; - u32 streamSize; - u32 spuThreadEnable; // CellJpgDecSpuThreadEna + be_t srcSelect; // CellJpgDecStreamSrcSel + be_t fileName; // const char* + be_t fileOffset; // int64_t + be_t fileSize; + be_t streamPtr; + be_t streamSize; + be_t spuThreadEnable; // CellJpgDecSpuThreadEna }; struct CellJpgDecInParam { - u32 *commandPtr; - u32 downScale; - u32 method; // CellJpgDecMethod - u32 outputMode; // CellJpgDecOutputMode - u32 outputColorSpace; // CellJpgDecColorSpace - u8 outputColorAlpha; - u8 reserved[3]; + be_t commandPtr; + be_t downScale; + be_t method; // CellJpgDecMethod + be_t outputMode; // CellJpgDecOutputMode + be_t outputColorSpace; // CellJpgDecColorSpace + be_t outputColorAlpha; + be_t reserved[3]; }; struct CellJpgDecOutParam { - u64 outputWidthByte; - u32 outputWidth; - u32 outputHeight; - u32 outputComponents; - u32 outputMode; // CellJpgDecOutputMode - u32 outputColorSpace; // CellJpgDecColorSpace - u32 downScale; - u32 useMemorySpace; + be_t outputWidthByte; + be_t outputWidth; + be_t outputHeight; + be_t outputComponents; + be_t outputMode; // CellJpgDecOutputMode + be_t outputColorSpace; // CellJpgDecColorSpace + be_t downScale; + be_t useMemorySpace; }; +struct CellJpgDecOpnInfo +{ + be_t initSpaceAllocated; +}; + +struct CellJpgDecDataCtrlParam +{ + be_t outputBytesPerLine; +}; + +struct CellJpgDecDataOutInfo +{ + be_t mean; + be_t outputLines; + be_t status; +}; + + struct CellJpgDecSubHandle //Custom struct { u32 fd; @@ -84,7 +108,6 @@ struct CellJpgDecSubHandle //Custom struct CellJpgDecOutParam outParam; }; - int cellJpgDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam) { UNIMPLEMENTED_FUNC(cellJpgDec); @@ -103,11 +126,11 @@ int cellJpgDecDestroy(u32 mainHandle) 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 openInfo) { //u32 srcSelect = Memory.Read32(src_addr); 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 streamPtr = Memory.Read32(src_addr+16); //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; // Get file descriptor - u32 fd_addr = Memory.Alloc(sizeof(u32), 1); - int ret = cellFsOpen(fileName, 0, fd_addr, NULL, 0); - current_subHandle->fd = Memory.Read32(fd_addr); - Memory.Free(fd_addr); - if(ret != 0) return CELL_JPGDEC_ERROR_OPEN_FILE; + MemoryAllocator> fd; + int ret = cellFsOpen(fileName, 0, fd, NULL, 0); + current_subHandle->fd = fd->ToLE(); + if(ret != CELL_OK) return CELL_JPGDEC_ERROR_OPEN_FILE; // Get size of file - u32 sb_addr = Memory.Alloc(52,1); // Alloc a CellFsStat struct - cellFsFstat(current_subHandle->fd, sb_addr); - current_subHandle->fileSize = Memory.Read64(sb_addr+36); // Get CellFsStat.st_size - Memory.Free(sb_addr); + MemoryAllocator sb; // Alloc a CellFsStat struct + ret = cellFsFstat(current_subHandle->fd, sb); + if(ret != CELL_OK) return ret; + current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size // 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; } int cellJpgDecClose(u32 mainHandle, u32 subHandle) { - cellFsClose( ((CellJpgDecSubHandle*)subHandle)->fd ); - delete (CellJpgDecSubHandle*)subHandle; + ID sub_handle_id_data; + 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; } -int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, mem_class_t info) +int cellJpgDecReadHeader(u32 mainHandle, u32 subHandle, mem_struct_ptr_t info) { - const u32& fd = ((CellJpgDecSubHandle*)subHandle)->fd; - const u64& fileSize = ((CellJpgDecSubHandle*)subHandle)->fileSize; - CellJpgDecInfo& current_info = ((CellJpgDecSubHandle*)subHandle)->info; + cellJpgDec.Log("cellJpgDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%llx)", mainHandle, subHandle, info.GetAddr()); + ID sub_handle_id_data; + 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 - u32 buffer = Memory.Alloc(fileSize,1); - u32 nread = Memory.Alloc(8,1); - 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); + MemoryAllocator buffer(fileSize); + MemoryAllocator> pos, nread; - if (Memory.Read32(buffer) != 0xFFD8FFE0 || // Error: Not a valid SOI header - Memory.Read32(buffer+6) != 0x4A464946) // Error: Not a valid JFIF string + cellFsLseek(fd, 0, CELL_SEEK_SET, pos); + cellFsRead(fd, buffer.GetAddr(), buffer.GetSize(), nread); + + if (*buffer.To(0) != 0xE0FFD8FF || // Error: Not a valid SOI header + *buffer.To(6) != 0x4649464A) // Error: Not a valid JFIF string { - Memory.Free(buffer); return CELL_JPGDEC_ERROR_HEADER; } u32 i = 4; - u16 block_length = Memory.Read8(buffer+i)*0xFF + Memory.Read8(buffer+i+1); - while(i < fileSize) - { - i += block_length; // Increase the file index to get to the next block - if (i >= fileSize){ - Memory.Free(buffer); - return CELL_JPGDEC_ERROR_HEADER; // Check to protect against segmentation faults - } - if(Memory.Read8(buffer+i) != 0xFF){ - Memory.Free(buffer); - 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 - } - i += 2; // Skip the block marker - block_length = Memory.Read8(buffer+i)*0xFF + Memory.Read8(buffer+i+1); // Go to the next block - } - - current_info.imageWidth = Memory.Read8(buffer+i+7)*256 + Memory.Read8(buffer+i+8); - current_info.imageHeight = Memory.Read8(buffer+i+5)*256 + Memory.Read8(buffer+i+6); - current_info.numComponents = 3; // Unimplemented - current_info.colorSpace = CELL_JPG_RGB; // Unimplemented - - info += current_info.imageWidth; - info += current_info.imageHeight; - info += current_info.numComponents; - info += current_info.colorSpace; - Memory.Free(buffer); + 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 + if (i >= fileSize || // Check to protect against segmentation faults + buffer[i] != 0xFF) // Check that we are truly at the start of another block + { + return CELL_JPGDEC_ERROR_HEADER; + } + + if(buffer[i+1] == 0xC0) + break; // 0xFFC0 is the "Start of frame" marker which contains the file size + + i += 2; // Skip the block marker + block_length = buffer[i] * 0xFF + buffer[i+1]; // Go to the next block + } + + current_info.imageWidth = buffer[i+7]*0x100 + buffer[i+8]; + current_info.imageHeight = buffer[i+5]*0x100 + buffer[i+6]; + current_info.numComponents = 3; // Unimplemented + current_info.colorSpace = CELL_JPG_RGB; + + info = current_info; + 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 dataCtrlParam, mem_struct_ptr_t dataOutInfo) { - const u32& fd = ((CellJpgDecSubHandle*)subHandle)->fd; - const u64& fileSize = ((CellJpgDecSubHandle*)subHandle)->fileSize; - const CellJpgDecOutParam& current_outParam = ((CellJpgDecSubHandle*)subHandle)->outParam; // (TODO: We should use the outParam) + dataOutInfo->status = CELL_JPGDEC_DEC_STATUS_STOP; + ID sub_handle_id_data; + 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 - u32 buffer = Memory.Alloc(fileSize,1); - u32 nread = Memory.Alloc(8,1); - 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); + MemoryAllocator jpg(fileSize); + MemoryAllocator pos, nread; + cellFsLseek(fd, 0, CELL_SEEK_SET, pos); + cellFsRead(fd, jpg.GetAddr(), jpg.GetSize(), nread); //Decode JPG file. (TODO: Is there any faster alternative? Can we do it without external libraries?) int width, height, actual_components; - unsigned char *jpg = (unsigned char*)Memory.VirtualToRealAddr(buffer); - unsigned char *image = stbi_load_from_memory(jpg, fileSize, &width, &height, &actual_components, 4); - Memory.Free(buffer); + std::shared_ptr image(stbi_load_from_memory(jpg, fileSize, &width, &height, &actual_components, 4)); + if (!image) return CELL_JPGDEC_ERROR_STREAM_FORMAT; - u32 image_size = width * height * 4; - if (current_outParam.outputColorSpace == CELL_JPG_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]; + uint image_size = width * height; + switch(current_outParam.outputColorSpace) + { + case CELL_JPG_RGBA: + case CELL_JPG_RGB: + image_size *= current_outParam.outputColorSpace == CELL_JPG_RGBA ? 4 : 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){ - data += image[i+3]; - data += image[i+0]; - data += image[i+1]; - data += image[i+2]; - } - } - delete[] image; + + dataOutInfo->status = CELL_JPGDEC_DEC_STATUS_FINISH; + + if(dataCtrlParam->outputBytesPerLine) + dataOutInfo->outputLines = image_size / dataCtrlParam->outputBytesPerLine; 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 inParam, mem_struct_ptr_t outParam) { - CellJpgDecInfo& current_info = ((CellJpgDecSubHandle*)subHandle)->info; - CellJpgDecOutParam& current_outParam = ((CellJpgDecSubHandle*)subHandle)->outParam; + ID sub_handle_id_data; + 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.outputWidth = current_info.imageWidth; current_outParam.outputHeight = current_info.imageHeight; - current_outParam.outputColorSpace = Memory.Read32(inParam_addr+16); + current_outParam.outputColorSpace = inParam->outputColorSpace; + switch (current_outParam.outputColorSpace) { case CELL_JPG_GRAYSCALE: current_outParam.outputComponents = 1; break; - case CELL_JPG_RGB: 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_ARGB: current_outParam.outputComponents = 4; break; - case CELL_JPG_GRAYSCALE_TO_ALPHA_RGBA: 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 - } - current_outParam.outputMode = Memory.Read32(inParam_addr+12); - current_outParam.downScale = Memory.Read32(inParam_addr+4); - current_outParam.useMemorySpace = 0; // Unimplemented - outParam += current_outParam.outputWidthByte; - 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; + case CELL_JPG_RGB: + case CELL_JPG_YCbCr: current_outParam.outputComponents = 3; break; + + case CELL_JPG_UPSAMPLE_ONLY: current_outParam.outputComponents = current_info.numComponents; 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; + + default: return CELL_JPGDEC_ERROR_ARG; // Not supported color space + } + + current_outParam.outputMode = inParam->outputMode; + current_outParam.downScale = inParam->downScale; + current_outParam.useMemorySpace = 0; // Unimplemented + + outParam = current_outParam; return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp index 5cb71d7714..4f130f0a52 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPngDec.cpp @@ -32,49 +32,68 @@ enum CellPngDecColorSpace 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 chunkInformation; + be_t numText; + be_t numUnknownChunk; + be_t status; +}; + +struct CellPngDecDataCtrlParam +{ + be_t outputBytesPerLine; +}; + struct CellPngDecInfo { - u32 imageWidth; - u32 imageHeight; - u32 numComponents; - u32 colorSpace; // CellPngDecColorSpace - u32 bitDepth; - u32 interlaceMethod; // CellPngDecInterlaceMode - u32 chunkInformation; + be_t imageWidth; + be_t imageHeight; + be_t numComponents; + be_t colorSpace; // CellPngDecColorSpace + be_t bitDepth; + be_t interlaceMethod; // CellPngDecInterlaceMode + be_t chunkInformation; }; struct CellPngDecSrc { - u32 srcSelect; // CellPngDecStreamSrcSel - u32 fileName; // const char* - u64 fileOffset; // int64_t - u32 fileSize; - u32 streamPtr; - u32 streamSize; - u32 spuThreadEnable; // CellPngDecSpuThreadEna + be_t srcSelect; // CellPngDecStreamSrcSel + be_t fileName; // const char* + be_t fileOffset; // int64_t + be_t fileSize; + be_t streamPtr; + be_t streamSize; + be_t spuThreadEnable; // CellPngDecSpuThreadEna }; struct CellPngDecInParam { - u32 *commandPtr; - u32 outputMode; // CellPngDecOutputMode - u32 outputColorSpace; // CellPngDecColorSpace - u32 outputBitDepth; - u32 outputPackFlag; // CellPngDecPackFlag - u32 outputAlphaSelect; // CellPngDecAlphaSelect - u32 outputColorAlpha; + be_t commandPtr; + be_t outputMode; // CellPngDecOutputMode + be_t outputColorSpace; // CellPngDecColorSpace + be_t outputBitDepth; + be_t outputPackFlag; // CellPngDecPackFlag + be_t outputAlphaSelect; // CellPngDecAlphaSelect + be_t outputColorAlpha; }; struct CellPngDecOutParam { - u64 outputWidthByte; - u32 outputWidth; - u32 outputHeight; - u32 outputComponents; - u32 outputBitDepth; - u32 outputMode; // CellPngDecOutputMode - u32 outputColorSpace; // CellPngDecColorSpace - u32 useMemorySpace; + be_t outputWidthByte; + be_t outputWidth; + be_t outputHeight; + be_t outputComponents; + be_t outputBitDepth; + be_t outputMode; // CellPngDecOutputMode + be_t outputColorSpace; // CellPngDecColorSpace + be_t useMemorySpace; }; struct CellPngDecSubHandle //Custom struct @@ -85,7 +104,6 @@ struct CellPngDecSubHandle //Custom struct CellPngDecOutParam outParam; }; - int cellPngDecCreate(u32 mainHandle, u32 threadInParam, u32 threadOutParam) { 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 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 streamPtr = Memory.Read32(src_addr+16); //u32 streamSize = Memory.Read32(src_addr+20); @@ -111,160 +129,183 @@ int cellPngDecOpen(u32 mainHandle, mem32_t subHandle, u32 src_addr, u32 openInfo CellPngDecSubHandle *current_subHandle = new CellPngDecSubHandle; // Get file descriptor - u32 fd_addr = Memory.Alloc(sizeof(u32), 1); - int ret = cellFsOpen(fileName, 0, fd_addr, NULL, 0); - current_subHandle->fd = Memory.Read32(fd_addr); - Memory.Free(fd_addr); - if(ret != 0) return CELL_PNGDEC_ERROR_OPEN_FILE; + MemoryAllocator> fd; + int ret = cellFsOpen(fileName, 0, fd, NULL, 0); + current_subHandle->fd = fd->ToLE(); + if(ret != CELL_OK) return CELL_PNGDEC_ERROR_OPEN_FILE; // Get size of file - u32 sb_addr = Memory.Alloc(52,1); // Alloc a CellFsStat struct - cellFsFstat(current_subHandle->fd, sb_addr); - current_subHandle->fileSize = Memory.Read64(sb_addr+36); // Get CellFsStat.st_size - Memory.Free(sb_addr); + MemoryAllocator sb; // Alloc a CellFsStat struct + ret = cellFsFstat(current_subHandle->fd, sb); + if(ret != CELL_OK) return ret; + current_subHandle->fileSize = sb->st_size; // Get CellFsStat.st_size // 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; } int cellPngDecClose(u32 mainHandle, u32 subHandle) { - cellFsClose( ((CellPngDecSubHandle*)subHandle)->fd ); - delete (CellPngDecSubHandle*)subHandle; + ID sub_handle_id_data; + 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; } -int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, mem_class_t info) +int cellPngDecReadHeader(u32 mainHandle, u32 subHandle, mem_struct_ptr_t info) { - const u32& fd = ((CellPngDecSubHandle*)subHandle)->fd; - const u64& fileSize = ((CellPngDecSubHandle*)subHandle)->fileSize; - CellPngDecInfo& current_info = ((CellPngDecSubHandle*)subHandle)->info; + cellPngDec.Log("cellPngDecReadHeader(mainHandle=0x%x, subHandle=0x%x, info_addr=0x%llx)", mainHandle, subHandle, info.GetAddr()); + ID sub_handle_id_data; + 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 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 - u32 buffer = Memory.Alloc(34,1); // Alloc buffer for PNG header - u32 nread = Memory.Alloc(8,1); - 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); + MemoryAllocator> buffer(34); // Alloc buffer for PNG header + MemoryAllocator> pos, nread; - if (Memory.Read32(buffer) != 0x89504E47 || - Memory.Read32(buffer+4) != 0x0D0A1A0A || // Error: The first 8 bytes are not a valid PNG signature - Memory.Read32(buffer+12) != 0x49484452) // Error: The PNG file does not start with an IHDR chunk + cellFsLseek(fd, 0, CELL_SEEK_SET, pos); + cellFsRead(fd, buffer.GetAddr(), buffer.GetSize(), nread); + + 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; } - current_info.imageWidth = Memory.Read32(buffer+16); - current_info.imageHeight = Memory.Read32(buffer+20); - switch (Memory.Read8(buffer+25)) + switch (buffer.To()[25]) { - 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 3: current_info.colorSpace = CELL_PNGDEC_PALETTE; current_info.numComponents = 1; break; - case 4: current_info.colorSpace = CELL_PNGDEC_GRAYSCALE_ALPHA; current_info.numComponents = 2; break; - case 6: current_info.colorSpace = CELL_PNGDEC_RGBA; current_info.numComponents = 4; 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 3: current_info.colorSpace = CELL_PNGDEC_PALETTE; current_info.numComponents = 1; break; + case 4: current_info.colorSpace = CELL_PNGDEC_GRAYSCALE_ALPHA; current_info.numComponents = 2; break; + case 6: current_info.colorSpace = CELL_PNGDEC_RGBA; current_info.numComponents = 4; break; 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.chunkInformation = 0; // Unimplemented - info += current_info.imageWidth; - 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); - + current_info.imageWidth = buffer[4]; + current_info.imageHeight = buffer[5]; + current_info.bitDepth = buffer.To()[24]; + current_info.interlaceMethod = buffer.To()[28]; + current_info.chunkInformation = 0; // Unimplemented + + info = current_info; + 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 dataCtrlParam, mem_struct_ptr_t dataOutInfo) { - const u32& fd = ((CellPngDecSubHandle*)subHandle)->fd; - const u64& fileSize = ((CellPngDecSubHandle*)subHandle)->fileSize; - const CellPngDecOutParam& current_outParam = ((CellPngDecSubHandle*)subHandle)->outParam; + dataOutInfo->status = CELL_PNGDEC_DEC_STATUS_STOP; + ID sub_handle_id_data; + 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 - u32 buffer = Memory.Alloc(fileSize,1); - u32 nread = Memory.Alloc(8,1); - u32 pos_addr = Memory.Alloc(sizeof(u64),1); - cellFsLseek(fd, 0, 0, pos_addr); - cellFsRead(fd, buffer, fileSize, nread); - Memory.Free(nread); - Memory.Free(pos_addr); + MemoryAllocator png(fileSize); + MemoryAllocator pos, nread; + cellFsLseek(fd, 0, CELL_SEEK_SET, pos); + cellFsRead(fd, png.GetAddr(), png.GetSize(), nread); //Decode PNG file. (TODO: Is there any faster alternative? Can we do it without external libraries?) int width, height, actual_components; - unsigned char *png = (unsigned char*)Memory.VirtualToRealAddr(buffer); - unsigned char *image = stbi_load_from_memory(png, fileSize, &width, &height, &actual_components, 4); - Memory.Free(buffer); + std::shared_ptr image(stbi_load_from_memory(png, fileSize, &width, &height, &actual_components, 4)); if (!image) return CELL_PNGDEC_ERROR_STREAM_FORMAT; - u32 image_size = width * height * 4; - if (current_outParam.outputColorSpace == CELL_PNGDEC_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]; + uint image_size = width * height; + switch(current_outParam.outputColorSpace) + { + case CELL_PNGDEC_RGB: + case CELL_PNGDEC_RGBA: + image_size *= current_outParam.outputColorSpace == CELL_PNGDEC_RGBA ? 4 : 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){ - data += image[i+3]; - data += image[i+0]; - data += image[i+1]; - data += image[i+2]; - } - } - delete[] image; + + dataOutInfo->status = CELL_PNGDEC_DEC_STATUS_FINISH; 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 inParam, mem_struct_ptr_t outParam) { - CellPngDecInfo& current_info = ((CellPngDecSubHandle*)subHandle)->info; - CellPngDecOutParam& current_outParam = ((CellPngDecSubHandle*)subHandle)->outParam; + ID sub_handle_id_data; + if(!cellPngDec.CheckId(subHandle, sub_handle_id_data)) + return CELL_PNGDEC_ERROR_FATAL; - current_outParam.outputWidthByte = (current_info.imageWidth * current_info.numComponents * current_info.bitDepth)/8; + 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.outputWidth = current_info.imageWidth; current_outParam.outputHeight = current_info.imageHeight; - current_outParam.outputColorSpace = Memory.Read32(inParam_addr+8); + current_outParam.outputColorSpace = inParam->outputColorSpace; switch (current_outParam.outputColorSpace) { + case CELL_PNGDEC_PALETTE: case CELL_PNGDEC_GRAYSCALE: current_outParam.outputComponents = 1; 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_RGBA: current_outParam.outputComponents = 4; break; + + case CELL_PNGDEC_RGBA: 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 - outParam += current_outParam.outputWidthByte; - 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; + outParam = current_outParam; return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/SC_FUNC.h b/rpcs3/Emu/SysCalls/SC_FUNC.h index 9cee74bba0..a91f5c0f25 100644 --- a/rpcs3/Emu/SysCalls/SC_FUNC.h +++ b/rpcs3/Emu/SysCalls/SC_FUNC.h @@ -32,7 +32,7 @@ class binder_func_1 : public func_caller public: 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 @@ -43,7 +43,7 @@ class binder_func_1 : public func_caller public: 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 @@ -54,7 +54,7 @@ class binder_func_2 : public func_caller public: 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 @@ -65,7 +65,7 @@ class binder_func_2 : public func_caller public: 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 @@ -76,7 +76,7 @@ class binder_func_3 : public func_caller public: 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 @@ -87,7 +87,7 @@ class binder_func_3 : public func_caller public: 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 @@ -98,7 +98,7 @@ class binder_func_4 : public func_caller public: 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 @@ -109,7 +109,7 @@ class binder_func_4 : public func_caller public: 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 @@ -120,7 +120,7 @@ class binder_func_5 : public func_caller public: 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 @@ -131,7 +131,7 @@ class binder_func_5 : public func_caller public: 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 @@ -142,7 +142,7 @@ class binder_func_6 : public func_caller public: 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 @@ -153,7 +153,7 @@ class binder_func_6 : public func_caller public: 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 @@ -164,7 +164,7 @@ class binder_func_7 : public func_caller public: 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 @@ -175,7 +175,7 @@ class binder_func_7 : public func_caller public: 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 @@ -186,7 +186,7 @@ class binder_func_8 : public func_caller public: 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 @@ -197,7 +197,7 @@ class binder_func_8 : public func_caller public: 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 @@ -208,7 +208,7 @@ class binder_func_9 : public func_caller public: 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 @@ -219,7 +219,7 @@ class binder_func_9 : public func_call public: 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 @@ -230,7 +230,7 @@ class binder_func_10 : public func_caller public: 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 @@ -241,7 +241,7 @@ class binder_func_10 : public fun public: 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 @@ -252,7 +252,7 @@ class binder_func_11 : public func_caller public: 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 @@ -263,7 +263,7 @@ class binder_func_11 : publi public: 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 @@ -274,7 +274,7 @@ class binder_func_12 : public func_caller public: 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 @@ -285,7 +285,7 @@ class binder_func_12 : public: 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 diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index df23bcdf29..bb03c128e7 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -1,6 +1,6 @@ #pragma once #include "ErrorCodes.h" - +#include "lv2/SC_FileSystem.h" //#define SYSCALLS_DEBUG #define declCPU PPUThread& CPU = GetCurrentPPUThread @@ -176,14 +176,14 @@ extern int sys_mmapper_map_memory(u32 start_addr, u32 mem_id, u64 flags); //cellFs 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 cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite_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); extern int cellFsClose(u32 fd); extern int cellFsOpendir(u32 path_addr, mem32_t fd); extern int cellFsReaddir(u32 fd, u32 dir_addr, mem64_t nread); extern int cellFsClosedir(u32 fd); -extern int cellFsStat(u32 path_addr, mem_class_t sb); -extern int cellFsFstat(u32 fd, mem_class_t sb); +extern int cellFsStat(u32 path_addr, mem_struct_ptr_t sb); +extern int cellFsFstat(u32 fd, mem_struct_ptr_t sb); extern int cellFsMkdir(u32 path_addr, u32 mode); extern int cellFsRename(u32 from_addr, u32 to_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 SC_ARGS_1 CPU.GPR[3] -#define SC_ARGS_2 SC_ARGS_1,CPU.GPR[4] -#define SC_ARGS_3 SC_ARGS_2,CPU.GPR[5] -#define SC_ARGS_4 SC_ARGS_3,CPU.GPR[6] -#define SC_ARGS_5 SC_ARGS_4,CPU.GPR[7] -#define SC_ARGS_6 SC_ARGS_5,CPU.GPR[8] -#define SC_ARGS_7 SC_ARGS_6,CPU.GPR[9] -#define SC_ARGS_8 SC_ARGS_7,CPU.GPR[10] -#define SC_ARGS_9 SC_ARGS_8,CPU.GPR[11] -#define SC_ARGS_10 SC_ARGS_9,CPU.GPR[12] -#define SC_ARGS_11 SC_ARGS_10,CPU.GPR[13] -#define SC_ARGS_12 SC_ARGS_11,CPU.GPR[14] +#define SC_ARG_0 CPU.GPR[3] +#define SC_ARG_1 CPU.GPR[4] +#define SC_ARG_2 CPU.GPR[5] +#define SC_ARG_3 CPU.GPR[6] +#define SC_ARG_4 CPU.GPR[7] +#define SC_ARG_5 CPU.GPR[8] +#define SC_ARG_6 CPU.GPR[9] +#define SC_ARG_7 CPU.GPR[10] +#define SC_ARG_8 CPU.GPR[11] +#define SC_ARG_9 CPU.GPR[12] +#define SC_ARG_10 CPU.GPR[13] +#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; class PPUThread; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp index d4e78008da..bc0142de99 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp @@ -1,87 +1,7 @@ #include "stdafx.h" +#include "SC_FileSystem.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; 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); s32 _oflags = flags; - if(flags & LV2_O_CREAT) + if(flags & CELL_O_CREAT) { - _oflags &= ~LV2_O_CREAT; + _oflags &= ~CELL_O_CREAT; /* //create path for(uint p=1;p sb) { const wxString& path = Memory.ReadString(path_addr); 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; } - CellFsStat stat; - stat.st_mode = + sb->st_mode = CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR | CELL_FS_S_IRGRP | CELL_FS_S_IWGRP | CELL_FS_S_IXGRP | CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH; - stat.st_mode |= CELL_FS_S_IFREG; //TODO: dir CELL_FS_S_IFDIR - stat.st_uid = 0; - stat.st_gid = 0; - stat.st_atime = 0; //TODO - stat.st_mtime = 0; //TODO - stat.st_ctime = 0; //TODO - stat.st_size = f->GetSize(); - stat.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; + sb->st_mode |= CELL_FS_S_IFREG; //TODO: dir CELL_FS_S_IFDIR + sb->st_uid = 0; + sb->st_gid = 0; + sb->st_atime = 0; //TODO + sb->st_mtime = 0; //TODO + sb->st_ctime = 0; //TODO + sb->st_size = f->GetSize(); + sb->st_blksize = 4096; return CELL_OK; } -int cellFsFstat(u32 fd, mem_class_t sb) +int cellFsFstat(u32 fd, mem_struct_ptr_t sb) { sys_fs.Log("cellFsFstat(fd: %d, sb_addr: 0x%x)", fd, sb.GetAddr()); ID id; if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; vfsStream& file = *(vfsStream*)id.m_data; - CellFsStat stat; - stat.st_mode = + sb->st_mode = CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR | CELL_FS_S_IRGRP | CELL_FS_S_IWGRP | CELL_FS_S_IXGRP | CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH; - stat.st_mode |= CELL_FS_S_IFREG; //TODO: dir CELL_FS_S_IFDIR - stat.st_uid = 0; - stat.st_gid = 0; - stat.st_atime = 0; //TODO - stat.st_mtime = 0; //TODO - stat.st_ctime = 0; //TODO - stat.st_size = file.GetSize(); - stat.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; + sb->st_mode |= CELL_FS_S_IFREG; //TODO: dir CELL_FS_S_IFDIR + sb->st_uid = 0; + sb->st_gid = 0; + sb->st_atime = 0; //TODO + sb->st_mtime = 0; //TODO + sb->st_ctime = 0; //TODO + sb->st_size = file.GetSize(); + sb->st_blksize = 4096; 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()); switch(whence) { - case LV2_SEEK_SET: seek_mode = vfsSeekSet; break; - case LV2_SEEK_CUR: seek_mode = vfsSeekCur; break; - case LV2_SEEK_END: seek_mode = vfsSeekEnd; break; + case CELL_SEEK_SET: seek_mode = vfsSeekSet; break; + case CELL_SEEK_CUR: seek_mode = vfsSeekCur; break; + case CELL_SEEK_END: seek_mode = vfsSeekEnd; break; default: sys_fs.Error(fd, "Unknown seek whence! (%d)", whence); return CELL_EINVAL; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.h b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.h new file mode 100644 index 0000000000..a60e1e2e14 --- /dev/null +++ b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.h @@ -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 st_mode; + be_t st_uid; + be_t st_gid; + be_t st_atime; + be_t st_mtime; + be_t st_ctime; + be_t st_size; + be_t st_blksize; +}; + +struct CellFsUtimbuf +{ + be_t actime; + be_t modtime; +}; + +struct CellFsDirent +{ + u8 d_type; + u8 d_namlen; + char d_name[CELL_MAX_FS_FILE_NAME_LENGTH + 1]; +}; \ No newline at end of file diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 22105acae6..dac1680129 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -99,16 +99,21 @@ void Emulator::Load() } ConLog.SkipLn(); - const auto f = m_elf_path.Len() ? OpenFile(m_elf_path) : std::shared_ptr(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); return; } bool is_error; - Loader l(*f); + Loader l(f); try { diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 893c671409..306dd721e6 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -206,6 +206,7 @@ + @@ -291,6 +292,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index 1606f87a8a..8204d53309 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -307,6 +307,9 @@ Emu\SysCalls\lv2 + + Emu\FS + @@ -474,5 +477,8 @@ Include + + Utilities + \ No newline at end of file diff --git a/rpcs3/stdafx.h b/rpcs3/stdafx.h index 3a02d6b320..e16f2b9fbf 100644 --- a/rpcs3/stdafx.h +++ b/rpcs3/stdafx.h @@ -186,6 +186,7 @@ enum Status Ready, }; +#include "Utilities/BEType.h" #include "Utilities/Thread.h" #include "Utilities/Array.h" #include "Utilities/Timer.h" @@ -202,6 +203,7 @@ enum Status #include "Emu/FS/vfsFileBase.h" #include "Emu/FS/vfsLocalFile.h" +#include "Emu/FS/vfsFile.h" #include "Emu/FS/vfsStream.h" #include "Emu/FS/vfsStreamMemory.h" #include "rpcs3.h"