diff --git a/rpcs3/Emu/Memory/Memory.h b/rpcs3/Emu/Memory/Memory.h index 34b1426e52..5a50c3a2c8 100644 --- a/rpcs3/Emu/Memory/Memory.h +++ b/rpcs3/Emu/Memory/Memory.h @@ -418,12 +418,27 @@ public: { } - u32 GetAddr() const { return m_addr; } + __forceinline u32 GetAddr() const { return m_addr; } - bool IsGood() const + __forceinline bool IsGood() const { return Memory.IsGoodAddr(m_addr, sizeof(T)); } + + __forceinline operator bool() const + { + return m_addr != 0; + } + + __forceinline bool operator != (nullptr_t) const + { + return m_addr != 0; + } + + __forceinline bool operator == (nullptr_t) const + { + return m_addr == 0; + } }; template @@ -434,6 +449,9 @@ public: { } + template operator mem_ptr_t&() { return (mem_ptr_t&)*this; } + template operator const mem_ptr_t&() const { return (const mem_ptr_t&)*this; } + T* operator -> () { return (T*)&Memory[this->m_addr]; @@ -512,8 +530,6 @@ public: return (const T&)Memory[this->m_addr + sizeof(T) * index]; } - operator bool() const { return this->m_addr == 0; } - bool operator == (mem_ptr_t right) const { return this->m_addr == right.m_addr; } bool operator != (mem_ptr_t right) const { return this->m_addr != right.m_addr; } bool operator > (mem_ptr_t right) const { return this->m_addr > right.m_addr; } @@ -529,6 +545,32 @@ public: bool operator <= (T* right) const { return (T*)&Memory[this->m_addr] <= right; } }; +template<> +class mem_ptr_t : public mem_base_t +{ +public: + mem_ptr_t(u32 addr) : mem_base_t(addr) + { + } + + template operator mem_ptr_t&() { return (mem_ptr_t&)*this; } + template operator const mem_ptr_t&() const { return (const mem_ptr_t&)*this; } + + bool operator == (mem_ptr_t right) const { return this->m_addr == right.m_addr; } + bool operator != (mem_ptr_t right) const { return this->m_addr != right.m_addr; } + bool operator > (mem_ptr_t right) const { return this->m_addr > right.m_addr; } + bool operator < (mem_ptr_t right) const { return this->m_addr < right.m_addr; } + bool operator >= (mem_ptr_t right) const { return this->m_addr >= right.m_addr; } + bool operator <= (mem_ptr_t right) const { return this->m_addr <= right.m_addr; } + + bool operator == (void* right) const { return (void*)&Memory[this->m_addr] == right; } + bool operator != (void* right) const { return (void*)&Memory[this->m_addr] != right; } + bool operator > (void* right) const { return (void*)&Memory[this->m_addr] > right; } + bool operator < (void* right) const { return (void*)&Memory[this->m_addr] < right; } + bool operator >= (void* right) const { return (void*)&Memory[this->m_addr] >= right; } + bool operator <= (void* right) const { return (void*)&Memory[this->m_addr] <= right; } +}; + template static bool operator == (T* left, mem_ptr_t right) { return left == (T*)&Memory[right.GetAddr()]; } template static bool operator != (T* left, mem_ptr_t right) { return left != (T*)&Memory[right.GetAddr()]; } template static bool operator > (T* left, mem_ptr_t right) { return left > (T*)&Memory[right.GetAddr()]; } @@ -638,6 +680,123 @@ public: void SetAddr(const u64 addr) { m_addr = addr; } }; +template class mem_func_ptr_t; + +template +class mem_func_ptr_t : public mem_base_t +{ + __forceinline void call_func(bool is_async) + { + Callback cb; + cb.SetAddr(m_addr); + cb.Branch(!is_async); + } + +public: + __forceinline void operator()() + { + call_func(false); + } + + __forceinline void async() + { + call_func(true); + } +}; + +template +class mem_func_ptr_t : public mem_base_t +{ + __forceinline void call_func(bool is_async, T1 a1) + { + Callback cb; + cb.SetAddr(m_addr); + cb.Handle(a1); + cb.Branch(!is_async); + } + +public: + __forceinline void operator()(T1 a1) + { + call_func(false, a1); + } + + __forceinline void async(T1 a1) + { + call_func(true, a1); + } +}; + +template +class mem_func_ptr_t : public mem_base_t +{ + __forceinline void call_func(bool is_async, T1 a1, T2 a2) + { + Callback cb; + cb.SetAddr(m_addr); + cb.Handle(a1, a2); + cb.Branch(!is_async); + } + +public: + __forceinline void operator()(T1 a1, T2 a2) + { + call_func(false, a1, a2); + } + + __forceinline void async(T1 a1, T2 a2) + { + call_func(true, a1, a2); + } +}; + +template +class mem_func_ptr_t : public mem_base_t +{ + __forceinline void call_func(bool is_async, T1 a1, T2 a2, T3 a3) + { + Callback cb; + cb.SetAddr(m_addr); + cb.Handle(a1, a2, a3); + cb.Branch(!is_async); + } + +public: + __forceinline void operator()(T1 a1, T2 a2, T3 a3) + { + call_func(false, a1, a2, a3); + } + + __forceinline void async(T1 a1, T2 a2, T3 a3) + { + call_func(true, a1, a2, a3); + } +}; + +template +class mem_func_ptr_t : public mem_base_t +{ + __forceinline void call_func(bool is_async, T1 a1, T2 a2, T3 a3, T4 a4) + { + Callback cb; + cb.SetAddr(m_addr); + cb.Handle(a1, a2, a3, a4); + cb.Branch(!is_async); + } + +public: + __forceinline void operator()(T1 a1, T2 a2, T3 a3, T4 a4) + { + call_func(false, a1, a2, a3, a4); + } + + __forceinline void async(T1 a1, T2 a2, T3 a3, T4 a4) + { + call_func(true, a1, a2, a3, a4); + } +}; + + template class MemoryAllocator { diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index 81a16f804c..1c2866b22b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -106,9 +106,6 @@ enum CELL_SYSUTIL_PAD_RUMBLE_ON = 1, }; -void cellSysutil_init(); -Module cellSysutil(0x0015, cellSysutil_init); - enum { @@ -132,6 +129,11 @@ enum CellMsgDialogType CELL_MSGDIALOG_DEFAULT_CURSOR_NO = 0x00000100, }; +typedef void (*CellMsgDialogCallback)(int buttonType, mem_ptr_t userData); + +void cellSysutil_init(); +Module cellSysutil(0x0015, cellSysutil_init); + int cellSysutilGetSystemParamInt(int id, mem32_t value) { cellSysutil.Log("cellSysutilGetSystemParamInt(id=0x%x, value_addr=0x%x)", id, value.GetAddr()); @@ -477,7 +479,7 @@ int cellSysutilUnregisterCallback(int slot) return CELL_OK; } -int cellMsgDialogOpen2(u32 type, char* msgString, u32 callback_addr, u32 userData, u32 extParam) +int cellMsgDialogOpen2(u32 type, char* msgString, mem_func_ptr_t callback, mem_ptr_t userData, u32 extParam) { long style = 0; @@ -520,17 +522,16 @@ int cellMsgDialogOpen2(u32 type, char* msgString, u32 callback_addr, u32 userDat break; } - Callback2 callback(0, callback_addr, userData); - callback.Handle(status); - callback.Branch(true); + if(callback) + callback(status, userData); return CELL_OK; } -int cellMsgDialogOpenErrorCode(u32 errorCode, u32 callback_addr, u32 userData, u32 extParam) +int cellMsgDialogOpenErrorCode(u32 errorCode, mem_func_ptr_t callback, mem_ptr_t userData, u32 extParam) { cellSysutil.Warning("cellMsgDialogOpenErrorCode(errorCode=0x%x, callback_addr=0x%x, userData=%d, extParam=%d)", - errorCode, callback_addr, userData, extParam); + errorCode, callback.GetAddr(), userData, extParam); std::string errorMessage; switch(errorCode) @@ -622,10 +623,8 @@ int cellMsgDialogOpenErrorCode(u32 errorCode, u32 callback_addr, u32 userData, u break; } - // TODO: The following lines produce an infinite loop of cellMsgDialogOpenErrorCode's - /*Callback2 callback(0, callback_addr, userData); - callback.Handle(status); - callback.Branch(true);*/ + if(callback) + callback(status, userData); return CELL_OK; } @@ -649,7 +648,7 @@ int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option) case CELL_AUDIO_OUT_FS_192KHZ: break; - default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE; + default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE; } switch(type) @@ -659,7 +658,7 @@ int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option) case CELL_AUDIO_OUT_CODING_TYPE_DTS: break; - default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE; + default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE; } switch(audioOut) @@ -668,8 +667,7 @@ int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option) case CELL_AUDIO_OUT_SECONDARY: return 0; } - CELL_AUDIO_OUT_ERROR_ILLEGAL_CONFIGURATION; - + return CELL_AUDIO_OUT_ERROR_ILLEGAL_CONFIGURATION; } int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u32 option) @@ -690,7 +688,7 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3 case CELL_AUDIO_OUT_FS_192KHZ: break; - default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE; + default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE; } switch(ch) @@ -700,7 +698,7 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3 case 8: break; - default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE; + default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE; } switch(type) @@ -710,7 +708,7 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3 case CELL_AUDIO_OUT_CODING_TYPE_DTS: break; - default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE; + default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_SOUND_MODE; } switch(audioOut) @@ -719,8 +717,7 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3 case CELL_AUDIO_OUT_SECONDARY: return 0; } - CELL_AUDIO_OUT_ERROR_ILLEGAL_CONFIGURATION; - + return CELL_AUDIO_OUT_ERROR_ILLEGAL_CONFIGURATION; } int cellAudioOutGetState(u32 audioOut, u32 deviceIndex, u32 state_addr) @@ -831,7 +828,7 @@ int cellAudioOutGetNumberOfDevice(u32 audioOut) case CELL_AUDIO_OUT_SECONDARY: return 0; } - CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT; + return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT; } int cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, mem_ptr_t info) @@ -863,7 +860,7 @@ int cellAudioOutSetCopyControl(u32 audioOut, u32 control) case CELL_AUDIO_OUT_SECONDARY: break; - default: CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT; + default: return CELL_AUDIO_OUT_ERROR_UNSUPPORTED_AUDIO_OUT; } switch(control) @@ -873,7 +870,7 @@ int cellAudioOutSetCopyControl(u32 audioOut, u32 control) case CELL_AUDIO_OUT_COPY_CONTROL_COPY_NEVER: break; - default: CELL_AUDIO_OUT_ERROR_ILLEGAL_PARAMETER; + default: return CELL_AUDIO_OUT_ERROR_ILLEGAL_PARAMETER; } return CELL_AUDIO_OUT_SUCCEEDED; diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index 297335e8e1..9819ef8fbd 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -135,76 +135,52 @@ int cellFsSdataOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) return CELL_OK; } -/*struct CellFsAio -{ - be_t fd; - be_t offset; - be_t buf_addr; - be_t size; - be_t user_data; -}; - -int cellFsAioRead(mem_ptr_t aio, mem32_t id, mem32_t func_addr) -{ - if(!aio.IsGood() || !id.IsGood() || !func_addr.IsGood()) - return CELL_EFAULT; - - //CellFsAio *xaio, CellFsErrno error, int xid, uint64_t size; - Callback callback; - callback.SetAddr(func_addr); - callback.SetName("cellFsAioReadCallback"); - MemoryAllocator> nread; - int error = cellFsRead(aio->fd, id.GetAddr(), aio->size, nread); - callback.Handle(aio.GetAddr(), error, id, *nread); - callback.Branch(true); - - return CELL_OK; -}*/ - std::atomic g_FsAioReadID = 0; -int cellFsAioRead(mem_ptr_t aio, mem32_t aio_id, u32 func_addr) +int cellFsAioRead(mem_ptr_t aio, mem32_t aio_id, mem_func_ptr_t xaio, u32 error, int xid, u64 size)> func) { ID id; u32 fd = (u32)aio->fd; if(!sys_fs.CheckId(fd, id)) return CELL_ESRCH; vfsFileBase& orig_file = *(vfsFileBase*)id.m_data; //open the file again (to prevent access conflicts roughly) - vfsStream& file = vfsLocalFile(orig_file.GetPath().AfterFirst('/'), vfsRead); u64 nbytes = (u64)aio->size; const u32 buf_addr = (u32)aio->buf_addr; - if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes)) - { - MemoryBlock& block = Memory.GetMemByAddr(buf_addr); - nbytes = block.GetSize() - (buf_addr - block.GetStartAddr()); - } - //read data immediately (actually it should be read in special thread) - file.Seek((u64)aio->offset); - const u64 res = nbytes ? file.Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0; - file.Close(); + u64 res; + u32 error; + + if(Memory.IsGoodAddr(buf_addr)) + { + vfsFile file(orig_file.GetPath().AfterFirst('/'), vfsRead); + if(!Memory.IsGoodAddr(buf_addr, nbytes)) + { + MemoryBlock& block = Memory.GetMemByAddr(buf_addr); + nbytes = block.GetSize() - (buf_addr - block.GetStartAddr()); + } + + //read data immediately (actually it should be read in special thread) + file.Seek((u64)aio->offset); + res = nbytes ? file.Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0; + error = CELL_OK; + } + else + { + res = 0; + error = CELL_EFAULT; + } //get a unique id for the callback const u32 xid = g_FsAioReadID++; aio_id = xid; sys_fs.Warning("cellFsAioRead(aio_addr: 0x%x[%s], id_addr: 0x%x, func_addr: 0x%x[res=%d, addr=0x%x])", aio.GetAddr(), - orig_file.GetPath().c_str(), aio_id.GetAddr(), func_addr, res, (u32)aio->buf_addr); + orig_file.GetPath().c_str(), aio_id.GetAddr(), func.GetAddr(), res, (u32)aio->buf_addr); + + if(func) + func(aio, error, xid, res); - //TODO: init the callback - CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_PPU); - new_thread.SetEntry(func_addr); - new_thread.SetPrio(1001); - new_thread.SetStackSize(0x10000); - new_thread.SetName("FsAioReadCallback"); - new_thread.SetArg(0, aio.GetAddr()); //xaio - new_thread.SetArg(1, CELL_OK); //error code - new_thread.SetArg(2, xid); //xid (unique id) - new_thread.SetArg(3, res); //size (bytes read) - new_thread.Run(); - new_thread.Exec(); - return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/SC_FUNC.h b/rpcs3/Emu/SysCalls/SC_FUNC.h index 0965ae90f1..832e0bf2b4 100644 --- a/rpcs3/Emu/SysCalls/SC_FUNC.h +++ b/rpcs3/Emu/SysCalls/SC_FUNC.h @@ -302,6 +302,8 @@ public: virtual void operator()() { declCPU(); m_call(ARG(1), ARG(2), ARG(3), ARG(4), ARG(5), ARG(6), ARG(7), ARG(8), ARG(9), ARG(10), ARG(11), ARG(12)); } }; +#undef ARG + template func_caller* bind_func(TR (*call)()) { @@ -379,5 +381,3 @@ func_caller* bind_func(TR (*call)(T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, { return new binder_func_12(call); } - -#undef ARG(n) diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index d9d1eab390..0342c60861 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -225,7 +225,6 @@ extern int cellFsLseek(u32 fd, s64 offset, u32 whence, mem64_t pos); extern int cellFsFtruncate(u32 fd, u64 size); extern int cellFsTruncate(u32 path_addr, u64 size); extern int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size); -extern int cellFsAioRead(mem_ptr_t aio, mem32_t id, u32 func_addr); //cellVideo extern int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, u32 state_addr);