From 7bab42455b1c857a7a150be6e9a4e54199619796 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 23 Mar 2014 23:43:37 +0400 Subject: [PATCH 01/14] Minor fixes cellAtrac faked --- rpcs3/Emu/Cell/SPUThread.h | 2 + rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp | 157 +++++++++++++------ rpcs3/Emu/SysCalls/Modules/cellAtrac.h | 31 ++++ rpcs3/Emu/SysCalls/Modules/cellL10n.cpp | 7 +- rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp | 4 + rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp | 6 +- rpcs3/Emu/System.cpp | 2 +- 7 files changed, 155 insertions(+), 54 deletions(-) diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index ba260eb360..c898783979 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -586,6 +586,8 @@ public: } } + Sleep(1); + switch(cmd & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK | MFC_LIST_MASK | MFC_RESULT_MASK)) { case MFC_PUT_CMD: diff --git a/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp b/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp index a73ab793d2..34ffeb5eff 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAtrac.cpp @@ -7,141 +7,200 @@ Module cellAtrac(0x0013, cellAtrac_init); #include "cellAtrac.h" -int cellAtracSetDataAndGetMemSize() +int cellAtracSetDataAndGetMemSize(mem_ptr_t pHandle, u32 pucBufferAddr, u32 uiReadByte, u32 uiBufferByte, mem32_t puiWorkMemByte) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracSetDataAndGetMemSize(pHandle=0x%x, pucBufferAddr=0x%x, uiReadByte=0x%x, uiBufferByte=0x%x, puiWorkMemByte_addr=0x%x)", + pHandle.GetAddr(), pucBufferAddr, uiReadByte, uiBufferByte, puiWorkMemByte.GetAddr()); + + puiWorkMemByte = 0x1000; // unproved return CELL_OK; } -int cellAtracCreateDecoder() +int cellAtracCreateDecoder(mem_ptr_t pHandle, u32 pucWorkMem_addr, u32 uiPpuThreadPriority, u32 uiSpuThreadPriority) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracCreateDecoder(pHandle=0x%x, pucWorkMem_addr=0x%x, uiPpuThreadPriority=%d, uiSpuThreadPriority=%d)", + pHandle.GetAddr(), pucWorkMem_addr, uiPpuThreadPriority, uiSpuThreadPriority); + + pHandle->data.pucWorkMem_addr = pucWorkMem_addr; return CELL_OK; } -int cellAtracCreateDecoderExt() +int cellAtracCreateDecoderExt(mem_ptr_t pHandle, u32 pucWorkMem_addr, u32 uiPpuThreadPriority, mem_ptr_t pExtRes) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracCreateDecoderExt(pHandle=0x%x, pucWorkMem_addr=0x%x, uiPpuThreadPriority=%d, pExtRes_addr=0x%x)", + pHandle.GetAddr(), pucWorkMem_addr, uiPpuThreadPriority, pExtRes.GetAddr()); + + pHandle->data.pucWorkMem_addr = pucWorkMem_addr; return CELL_OK; } -int cellAtracDeleteDecoder() +int cellAtracDeleteDecoder(mem_ptr_t pHandle) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracDeleteDecoder(pHandle=0x%x)", pHandle.GetAddr()); return CELL_OK; } -int cellAtracDecode() +int cellAtracDecode(mem_ptr_t pHandle, u32 pfOutAddr, mem32_t puiSamples, mem32_t puiFinishflag, mem32_t piRemainFrame) { - //UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracDecode(pHandle=0x%x, pfOutAddr=0x%x, puiSamples_addr=0x%x, puiFinishFlag_addr=0x%x, piRemainFrame_addr=0x%x)", + pHandle.GetAddr(), pfOutAddr, puiSamples.GetAddr(), puiFinishflag.GetAddr(), piRemainFrame.GetAddr()); + + puiSamples = 0; + puiFinishflag = 1; + piRemainFrame = CELL_ATRAC_ALLDATA_IS_ON_MEMORY; return CELL_OK; } -int cellAtracGetStreamDataInfo() +int cellAtracGetStreamDataInfo(mem_ptr_t pHandle, mem32_t ppucWritePointer, mem32_t puiWritableByte, mem32_t puiReadPosition) { - //UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracGetStreamDataInfo(pHandle=0x%x, ppucWritePointer_addr=0x%x, puiWritableByte_addr=0x%x, puiReadPosition_addr=0x%x)", + pHandle.GetAddr(), ppucWritePointer.GetAddr(), puiWritableByte.GetAddr(), puiReadPosition.GetAddr()); + + ppucWritePointer = pHandle->data.pucWorkMem_addr; + puiWritableByte = 0x1000; + puiReadPosition = 0; return CELL_OK; } -int cellAtracAddStreamData() +int cellAtracAddStreamData(mem_ptr_t pHandle, u32 uiAddByte) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracAddStreamData(pHandle=0x%x, uiAddByte=0x%x)", pHandle.GetAddr(), uiAddByte); return CELL_OK; } -int cellAtracGetRemainFrame() +int cellAtracGetRemainFrame(mem_ptr_t pHandle, mem32_t piRemainFrame) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracGetRemainFrame(pHandle=0x%x, piRemainFrame_addr=0x%x)", pHandle.GetAddr(), piRemainFrame.GetAddr()); + + piRemainFrame = CELL_ATRAC_ALLDATA_IS_ON_MEMORY; return CELL_OK; } -int cellAtracGetVacantSize() +int cellAtracGetVacantSize(mem_ptr_t pHandle, mem32_t puiVacantSize) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracGetVacantSize(pHandle=0x%x, puiVacantSize_addr=0x%x)", pHandle.GetAddr(), puiVacantSize.GetAddr()); + + puiVacantSize = 0x1000; return CELL_OK; } -int cellAtracIsSecondBufferNeeded() +int cellAtracIsSecondBufferNeeded(mem_ptr_t pHandle) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracIsSecondBufferNeeded(pHandle=0x%x)", pHandle.GetAddr()); return CELL_OK; } -int cellAtracGetSecondBufferInfo() +int cellAtracGetSecondBufferInfo(mem_ptr_t pHandle, mem32_t puiReadPosition, mem32_t puiDataByte) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracGetSecondBufferInfo(pHandle=0x%x, puiReadPosition_addr=0x%x, puiDataByte_addr=0x%x)", + pHandle.GetAddr(), puiReadPosition.GetAddr(), puiDataByte.GetAddr()); + + puiReadPosition = 0; + puiDataByte = 0; // write to null block will occur return CELL_OK; } -int cellAtracSetSecondBuffer() +int cellAtracSetSecondBuffer(mem_ptr_t pHandle, u32 pucSecondBufferAddr, u32 uiSecondBufferByte) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracSetSecondBuffer(pHandle=0x%x, pucSecondBufferAddr=0x%x, uiSecondBufferByte=0x%x)", + pHandle.GetAddr(), pucSecondBufferAddr, uiSecondBufferByte); return CELL_OK; } -int cellAtracGetChannel() +int cellAtracGetChannel(mem_ptr_t pHandle, mem32_t puiChannel) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracGetChannel(pHandle=0x%x, puiChannel_addr=0x%x)", pHandle.GetAddr(), puiChannel.GetAddr()); + + puiChannel = 2; return CELL_OK; } -int cellAtracGetMaxSample() +int cellAtracGetMaxSample(mem_ptr_t pHandle, mem32_t puiMaxSample) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracGetMaxSample(pHandle=0x%x, puiMaxSample_addr=0x%x)", pHandle.GetAddr(), puiMaxSample.GetAddr()); + + puiMaxSample = 512; return CELL_OK; } -int cellAtracGetNextSample() +int cellAtracGetNextSample(mem_ptr_t pHandle, mem32_t puiNextSample) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracGetNextSample(pHandle=0x%x, puiNextSample_addr=0x%x)", pHandle.GetAddr(), puiNextSample.GetAddr()); + + puiNextSample = 0; return CELL_OK; } -int cellAtracGetSoundInfo() +int cellAtracGetSoundInfo(mem_ptr_t pHandle, mem32_t piEndSample, mem32_t piLoopStartSample, mem32_t piLoopEndSample) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracGetSoundInfo(pHandle=0x%x, piEndSample_addr=0x%x, piLoopStartSample_addr=0x%x, piLoopEndSample_addr=0x%x)", + pHandle.GetAddr(), piEndSample.GetAddr(), piLoopStartSample.GetAddr(), piLoopEndSample.GetAddr()); + + piEndSample = 0; + piLoopStartSample = 0; + piLoopEndSample = 0; return CELL_OK; } -int cellAtracGetNextDecodePosition() +int cellAtracGetNextDecodePosition(mem_ptr_t pHandle, mem32_t puiSamplePosition) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracGetNextDecodePosition(pHandle=0x%x, puiSamplePosition_addr=0x%x)", + pHandle.GetAddr(), puiSamplePosition.GetAddr()); + + puiSamplePosition = 0; + return CELL_ATRAC_ERROR_ALLDATA_WAS_DECODED; +} + +int cellAtracGetBitrate(mem_ptr_t pHandle, mem32_t puiBitrate) +{ + cellAtrac.Error("cellAtracGetBitrate(pHandle=0x%x, puiBitrate_addr=0x%x)", + pHandle.GetAddr(), puiBitrate.GetAddr()); + + puiBitrate = 128; return CELL_OK; } -int cellAtracGetBitrate() +int cellAtracGetLoopInfo(mem_ptr_t pHandle, mem32_t piLoopNum, mem32_t puiLoopStatus) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracGetLoopInfo(pHandle=0x%x, piLoopNum_addr=0x%x, puiLoopStatus_addr=0x%x)", + pHandle.GetAddr(), piLoopNum.GetAddr(), puiLoopStatus.GetAddr()); + + piLoopNum = 0; + puiLoopStatus = 0; return CELL_OK; } -int cellAtracGetLoopInfo() +int cellAtracSetLoopNum(mem_ptr_t pHandle, int iLoopNum) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracSetLoopNum(pHandle=0x%x, iLoopNum=0x%x)", pHandle.GetAddr(), iLoopNum); return CELL_OK; } -int cellAtracSetLoopNum() +int cellAtracGetBufferInfoForResetting(mem_ptr_t pHandle, u32 uiSample, mem_ptr_t pBufferInfo) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracGetBufferInfoForResetting(pHandle=0x%x, uiSample=0x%x, pBufferInfo_addr=0x%x)", + pHandle.GetAddr(), uiSample, pBufferInfo.GetAddr()); + + pBufferInfo->pucWriteAddr = pHandle->data.pucWorkMem_addr; + pBufferInfo->uiWritableByte = 0x1000; + pBufferInfo->uiMinWriteByte = 0; + pBufferInfo->uiReadPosition = 0; return CELL_OK; } -int cellAtracGetBufferInfoForResetting() +int cellAtracResetPlayPosition(mem_ptr_t pHandle, u32 uiSample, u32 uiWriteByte) { - UNIMPLEMENTED_FUNC(cellAtrac); + cellAtrac.Error("cellAtracResetPlayPosition(pHandle=0x%x, uiSample=0x%x, uiWriteByte=0x%x)", + pHandle.GetAddr(), uiSample, uiWriteByte); return CELL_OK; } -int cellAtracResetPlayPosition() +int cellAtracGetInternalErrorInfo(mem_ptr_t pHandle, mem32_t piResult) { - UNIMPLEMENTED_FUNC(cellAtrac); - return CELL_OK; -} + cellAtrac.Error("cellAtracGetInternalErrorInfo(pHandle=0x%x, piResult_addr=0x%x)", + pHandle.GetAddr(), piResult.GetAddr()); -int cellAtracGetInternalErrorInfo() -{ - UNIMPLEMENTED_FUNC(cellAtrac); + piResult = 0; return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellAtrac.h b/rpcs3/Emu/SysCalls/Modules/cellAtrac.h index 3d1d652644..5a95c32b97 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAtrac.h +++ b/rpcs3/Emu/SysCalls/Modules/cellAtrac.h @@ -25,4 +25,35 @@ enum CELL_ATRAC_ERROR_ILLEGAL_RESET_BYTE = 0x80610372, CELL_ATRAC_ERROR_ILLEGAL_PPU_THREAD_PRIORITY = 0x80610381, CELL_ATRAC_ERROR_ILLEGAL_SPU_THREAD_PRIORITY = 0x80610382, +}; + +// Remain Frame +enum +{ + CELL_ATRAC_ALLDATA_IS_ON_MEMORY = -1, + CELL_ATRAC_NONLOOP_STREAM_DATA_IS_ON_MEMORY = -2, + CELL_ATRAC_LOOP_STREAM_DATA_IS_ON_MEMORY = -3, +}; + +union CellAtracHandle +{ + u8 uiWorkMem[512]; + struct AtracHandle + { + u32 pucWorkMem_addr; + } data; +}; + +struct CellAtracBufferInfo +{ + be_t pucWriteAddr; + be_t uiWritableByte; + be_t uiMinWriteByte; + be_t uiReadPosition; +}; + +struct CellAtracExtRes +{ + be_t pSpurs_addr; + u8 priority[8]; }; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp b/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp index b783b58727..ae9c22e0f9 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellL10n.cpp @@ -58,7 +58,12 @@ int UTF16stoUTF8s(mem16_ptr_t utf16, mem64_t utf16_len, mem8_ptr_t utf8, mem64_t int jstrchk(mem8_ptr_t jstr) { - cellL10n.Log("jstrchk(jstr_addr=0x%x [%s])", jstr.GetAddr(), "omitted" /*Memory.ReadString(jstr.GetAddr()).wx_str()*/); + if (!jstr.IsGood()) + cellL10n.Error("jstrchk(jstr_addr=0x%x): invalid address", jstr.GetAddr()); + else if (jstr[0]) + cellL10n.Log("jstrchk(jstr_addr=0x%x): utf-8: [%s]", jstr.GetAddr(), Memory.ReadString(jstr.GetAddr()).wx_str()); + else + cellL10n.Log("jstrchk(jstr_addr=0x%x): empty string", jstr.GetAddr()); return L10N_STR_UTF8; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp index 38b4ad53db..a1874ebf97 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysmodule.cpp @@ -158,6 +158,10 @@ int cellSysmoduleSetMemcontainer(u32 ct_id) int cellSysmoduleLoadModule(u16 id) { + if (id == 0xf054) + { + cellSysmodule.Error("cellSysmoduleLoadModule: TODO: CELL_SYSMODULE_LIBATRAC3MULTI"); + } cellSysmodule.Warning("cellSysmoduleLoadModule(%s)", wxString(getModuleName(id)).wx_str()); Module* m = GetModuleById(id); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp index 31fedbd349..05b9058fdd 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp @@ -211,7 +211,7 @@ int sys_lwmutex_t::trylock(be_t tid) if (mutex.unlock(owner_tid, owner_tid) != SMR_OK) // check free value { owner_tid = mutex.GetOwner(); - if (CPUThread* tt = Emu.GetCPU().GetThread(owner_tid)) + /*if (CPUThread* tt = Emu.GetCPU().GetThread(owner_tid)) { if (!tt->IsAlive()) { @@ -227,7 +227,7 @@ int sys_lwmutex_t::trylock(be_t tid) mutex.unlock(owner_tid, tid); recursive_count = 1; return CELL_OK; - } + }*/ } /*while ((attribute.ToBE() & se32(SYS_SYNC_ATTR_RECURSIVE_MASK)) == 0) @@ -272,7 +272,7 @@ int sys_lwmutex_t::unlock(be_t tid) { if (!recursive_count || (recursive_count.ToBE() != se32(1) && (attribute.ToBE() & se32(SYS_SYNC_NOT_RECURSIVE)))) { - sc_lwmutex.Error("sys_lwmutex_t::unlock(%d): wrong recursive value (%d)", (u32)sleep_queue, (u32)recursive_count); + sc_lwmutex.Error("sys_lwmutex_t::unlock(%d): wrong recursive value fixed (%d)", (u32)sleep_queue, (u32)recursive_count); recursive_count = 1; } recursive_count -= 1; diff --git a/rpcs3/Emu/System.cpp b/rpcs3/Emu/System.cpp index 7c92cb7e3d..3f32054def 100644 --- a/rpcs3/Emu/System.cpp +++ b/rpcs3/Emu/System.cpp @@ -358,7 +358,7 @@ void Emulator::Resume() m_status = Running; CheckStatus(); - if(IsRunning() && Ini.CPUDecoderMode.GetValue() != 1) GetCPU().Exec(); + //if(IsRunning() && Ini.CPUDecoderMode.GetValue() != 1) GetCPU().Exec(); #ifndef QT_UI wxGetApp().SendDbgCommand(DID_RESUMED_EMU); #endif From 21d19ccd5935e90a049d9bc142f2ca4dd3f5e817 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 24 Mar 2014 21:51:20 +0400 Subject: [PATCH 02/14] Small RSX fix --- rpcs3/Emu/GS/RSXThread.cpp | 61 ++++++++++++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index 66277aee02..063a6116a2 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -651,7 +651,8 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3 case NV4097_SET_SHADER_PROGRAM: { - m_cur_shader_prog = &m_shader_progs[/*m_cur_shader_prog_num++*/0]; + m_cur_shader_prog = &m_shader_progs[m_cur_shader_prog_num]; + //m_cur_shader_prog_num = (m_cur_shader_prog_num + 1) % 16; u32 a0 = ARGS(0); m_cur_shader_prog->offset = a0 & ~0x3; m_cur_shader_prog->addr = GetAddress(m_cur_shader_prog->offset, (a0 & 0x3) - 1); @@ -1369,10 +1370,58 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3 case 0x000002f8: break; - case NV0039_SET_CONTEXT_DMA_BUFFER_IN: - case NV0039_OFFSET_IN: - case NV0039_OFFSET_OUT: - //TODO + case NV0039_SET_CONTEXT_DMA_BUFFER_IN: // [E : RSXThread]: TODO: unknown/illegal method [0x00002184](0xfeed0000, 0xfeed0000) + { + const u32 srcContext = ARGS(0); + const u32 dstContext = ARGS(1); + + if (srcContext == 0xfeed0000 && dstContext == 0xfeed0000) + { + } + else + { + ConLog.Warning("NV0039_SET_CONTEXT_DMA_BUFFER_IN: TODO: srcContext=0x%x, dstContext=0x%x", srcContext, dstContext); + } + } + break; + + case NV0039_OFFSET_IN: // [E : RSXThread]: TODO: unknown/illegal method [0x0000230c](0x0, 0xb00400, 0x0, 0x0, 0x384000, 0x1, 0x101, 0x0) + { + const u32 inOffset = ARGS(0); + const u32 outOffset = ARGS(1); + const u32 inPitch = ARGS(2); + const u32 outPitch = ARGS(3); + const u32 lineLength = ARGS(4); + const u32 lineCount = ARGS(5); + const u32 format = ARGS(6); + const u8 outFormat = (format >> 8); + const u8 inFormat = (format >> 0); + const u32 notify = ARGS(7); + + if (lineCount == 1 && !inPitch && !outPitch && !notify && format == 0x101) + { + memcpy(&Memory[GetAddress(outOffset, 0)], &Memory[GetAddress(inOffset, 0)], lineLength); + } + else + { + ConLog.Warning("NV0039_OFFSET_IN: TODO: offset(in=0x%x, out=0x%x), pitch(in=0x%x, out=0x%x), line(len=0x%x, cnt=0x%x), fmt(in=0x%x, out=0x%x), notify=0x%x", + inOffset, outOffset, inPitch, outPitch, lineLength, lineCount, inFormat, outFormat, notify); + } + } + break; + + case NV0039_OFFSET_OUT: // [E : RSXThread]: TODO: unknown/illegal method [0x00002310](0x0) + { + const u32 offset = ARGS(0); + + if (!offset) + { + } + else + { + ConLog.Warning("NV0039_OFFSET_OUT: TODO: offset=0x%x", offset); + } + } break; case NV4097_SET_SURFACE_COLOR_AOFFSET: @@ -1531,7 +1580,7 @@ void RSXThread::Task() continue; } - for(int i=0; i Date: Tue, 25 Mar 2014 17:05:07 +0400 Subject: [PATCH 03/14] Reservation improved --- .gitignore | 1 + rpcs3/Emu/CPU/CPUThread.h | 12 ++--- rpcs3/Emu/Cell/SPUThread.h | 90 ++++++++++++++++++++++++++++++-------- rpcs3/Emu/GS/RSXThread.cpp | 2 +- 4 files changed, 79 insertions(+), 26 deletions(-) diff --git a/.gitignore b/.gitignore index cea62cad43..07c7bb0da1 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,4 @@ rpcs3/git-version.h # Ignore other system generated files bin/dev_hdd0/home/00000001/trophy +bin/dev_hdd0/log.txt diff --git a/rpcs3/Emu/CPU/CPUThread.h b/rpcs3/Emu/CPU/CPUThread.h index 3c2bbafd3e..10348c5c20 100644 --- a/rpcs3/Emu/CPU/CPUThread.h +++ b/rpcs3/Emu/CPU/CPUThread.h @@ -6,12 +6,12 @@ struct reservation_struct { SMutex mutex; // mutex for updating reservation_owner and data - volatile u32 owner; // id of thread that got reservation - volatile u32 addr; - volatile u32 size; - volatile u32 data32; - volatile u64 data64; - // atm, PPU can't break SPU MFC reservation correctly + u32 owner; // id of thread that got reservation + u32 addr; + u32 size; + u32 data32; + u64 data64; + u128 data[8]; __forceinline void clear() { diff --git a/rpcs3/Emu/Cell/SPUThread.h b/rpcs3/Emu/Cell/SPUThread.h index c898783979..d4e0028784 100644 --- a/rpcs3/Emu/Cell/SPUThread.h +++ b/rpcs3/Emu/Cell/SPUThread.h @@ -586,7 +586,7 @@ public: } } - Sleep(1); + Sleep(1); // hack switch(cmd & ~(MFC_BARRIER_MASK | MFC_FENCE_MASK | MFC_LIST_MASK | MFC_RESULT_MASK)) { @@ -704,20 +704,8 @@ public: wxString(op & MFC_BARRIER_MASK ? "B" : "").wx_str(), wxString(op & MFC_FENCE_MASK ? "F" : "").wx_str(), lsa, ea, tag, size, cmd); - if (op & MFC_PUT_CMD) - { - SMutexLocker lock(reservation.mutex); // should be removed - MFCArgs.CMDStatus.SetValue(dmacCmd(cmd, tag, lsa, ea, size)); - if ((reservation.addr + reservation.size > ea && reservation.addr <= ea + size) || - (ea + size > reservation.addr && ea <= reservation.addr + reservation.size)) - { - reservation.clear(); - } - } - else - { - MFCArgs.CMDStatus.SetValue(dmacCmd(cmd, tag, lsa, ea, size)); - } + + MFCArgs.CMDStatus.SetValue(dmacCmd(cmd, tag, lsa, ea, size)); } break; @@ -741,7 +729,7 @@ public: case MFC_PUTLLUC_CMD: case MFC_PUTQLLUC_CMD: { - if (Ini.HLELogging.GetValue()) ConLog.Write("DMA %s: lsa=0x%x, ea = 0x%llx, (tag) = 0x%x, (size) = 0x%x, cmd = 0x%x", + if (Ini.HLELogging.GetValue() || size != 128) ConLog.Write("DMA %s: lsa=0x%x, ea = 0x%llx, (tag) = 0x%x, (size) = 0x%x, cmd = 0x%x", wxString(op == MFC_GETLLAR_CMD ? "GETLLAR" : op == MFC_PUTLLC_CMD ? "PUTLLC" : op == MFC_PUTLLUC_CMD ? "PUTLLUC" : "PUTQLLUC").wx_str(), @@ -753,7 +741,11 @@ public: reservation.owner = lock.tid; reservation.addr = ea; reservation.size = 128; - ProcessCmd(MFC_GET_CMD, tag, lsa, ea, 128); + for (u32 i = 0; i < 8; i++) + { + reservation.data[i] = *(u128*)&Memory[(u32)ea + i * 16]; + *(u128*)&Memory[dmac.ls_offset + lsa + i * 16] = reservation.data[i]; + } Prxy.AtomicStat.PushUncond(MFC_GETLLAR_SUCCESS); } else if (op == MFC_PUTLLC_CMD) // store conditional @@ -763,8 +755,68 @@ public: { if (reservation.addr == ea && reservation.size == 128) { - ProcessCmd(MFC_PUT_CMD, tag, lsa, ea, 128); - Prxy.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + u128 buf[8]; // data being written newly + u32 changed = 0, mask = 0, last = 0; + for (u32 i = 0; i < 8; i++) + { + buf[i] = *(u128*)&Memory[dmac.ls_offset + lsa + i * 16]; + if (buf[i] != reservation.data[i]) + { + changed++; + last = i; + mask |= (0xf << (i * 4)); + } + } + if (changed == 0) // nothing changed? + { + Prxy.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + } + else if (changed == 1) + { + if (buf[last].hi != reservation.data[last].hi && buf[last].lo != reservation.data[last].lo) + { + ConLog.Error("MFC_PUTLLC_CMD: TODO: 128bit compare and swap"); + Emu.Pause(); + Prxy.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + } + else + { + const u32 last_q = (buf[last].hi == reservation.data[last].hi); + + if (InterlockedCompareExchange64((volatile long long*)(Memory + (u32)ea + last * 16 + last_q * 8), + buf[last]._u64[last_q], reservation.data[last]._u64[last_q]) == reservation.data[last]._u64[last_q]) + { + Prxy.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + } + else + { + Prxy.AtomicStat.PushUncond(MFC_PUTLLC_FAILURE); + } + /*u32 last_d = last_q * 2; + if (buf[last]._u32[last_d] == reservation.data[last]._u32[last_d] && buf[last]._u32[last_d+1] != reservation.data[last]._u32[last_d+1]) + { + last_d++; + } + else if (buf[last]._u32[last_d+1] == reservation.data[last]._u32[last_d+1]) + { + last_d; + } + else // full 64 bit + { + ConLog.Error("MFC_PUTLLC_CMD: TODO: 64bit compare and swap"); + Emu.Pause(); + Prxy.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + }*/ + } + } + else + { + ProcessCmd(MFC_PUT_CMD, tag, lsa, ea, 128); + ConLog.Error("MFC_PUTLLC_CMD: Reservation Error: impossibru (~ 16x%d (mask=0x%x)) (opcode=0x%x, cmd=0x%x, lsa = 0x%x, ea = 0x%llx, tag = 0x%x, size = 0x%x)", + changed, mask, op, cmd, lsa, ea, tag, size); + Emu.Pause(); + Prxy.AtomicStat.PushUncond(MFC_PUTLLC_SUCCESS); + } } else { diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index 063a6116a2..b161d8f0a7 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -652,7 +652,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3 case NV4097_SET_SHADER_PROGRAM: { m_cur_shader_prog = &m_shader_progs[m_cur_shader_prog_num]; - //m_cur_shader_prog_num = (m_cur_shader_prog_num + 1) % 16; + m_cur_shader_prog_num = (m_cur_shader_prog_num + 1) % 16; u32 a0 = ARGS(0); m_cur_shader_prog->offset = a0 & ~0x3; m_cur_shader_prog->addr = GetAddress(m_cur_shader_prog->offset, (a0 & 0x3) - 1); From 994ce50392831426af55f5542b6897d186a7ab62 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 27 Mar 2014 02:45:58 +0400 Subject: [PATCH 04/14] Experimental libmixer adec, vdec improved fixed sound --- Utilities/SQueue.h | 5 + rpcs3/Emu/Audio/AudioDumper.cpp | 4 +- rpcs3/Emu/Audio/cellAudio.h | 18 +-- rpcs3/Emu/SysCalls/Modules.h | 10 +- rpcs3/Emu/SysCalls/Modules/cellAdec.cpp | 24 +++- rpcs3/Emu/SysCalls/Modules/cellAdec.h | 2 +- rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 125 +++++++++++++----- rpcs3/Emu/SysCalls/Modules/cellVdec.cpp | 46 +++++-- rpcs3/Emu/SysCalls/Modules/cellVdec.h | 3 +- rpcs3/Emu/SysCalls/Modules/libmixer.cpp | 156 +++++++++++++++++++---- rpcs3/Emu/SysCalls/Modules/libmixer.h | 12 ++ rpcs3/Emu/SysCalls/Static.cpp | 90 ++++++++++++- 12 files changed, 406 insertions(+), 89 deletions(-) diff --git a/Utilities/SQueue.h b/Utilities/SQueue.h index d98f13d793..7b52644771 100644 --- a/Utilities/SQueue.h +++ b/Utilities/SQueue.h @@ -15,6 +15,11 @@ public: { } + const u32 GetSize() const + { + return SQSize; + } + bool Push(const T& data) { while (true) diff --git a/rpcs3/Emu/Audio/AudioDumper.cpp b/rpcs3/Emu/Audio/AudioDumper.cpp index dbd282e7ae..118ffd6623 100644 --- a/rpcs3/Emu/Audio/AudioDumper.cpp +++ b/rpcs3/Emu/Audio/AudioDumper.cpp @@ -23,7 +23,7 @@ void AudioDumper::WriteHeader() size_t AudioDumper::WriteData(const void* buffer, size_t size) { - for (u32 i = 0; i < size / 8; i++) + /*for (u32 i = 0; i < size / 8; i++) { if (((u64*)buffer)[i]) goto process; } @@ -32,7 +32,7 @@ size_t AudioDumper::WriteData(const void* buffer, size_t size) if (((u8*)buffer)[i + (size & ~7)]) goto process; } return size; // ignore empty data -process: +process:*/ size_t ret = m_output.Write(buffer, size); m_header.Size += ret; m_header.RIFF.Size += ret; diff --git a/rpcs3/Emu/Audio/cellAudio.h b/rpcs3/Emu/Audio/cellAudio.h index dc371c9c67..c0fe570980 100644 --- a/rpcs3/Emu/Audio/cellAudio.h +++ b/rpcs3/Emu/Audio/cellAudio.h @@ -1,5 +1,7 @@ #pragma once +extern u64 get_system_time(); + // Error codes enum { @@ -20,16 +22,6 @@ enum CELL_AUDIO_ERROR_AUDIOSYSTEM_NOT_FOUND = 0x8031070e, CELL_AUDIO_ERROR_TAG_NOT_FOUND = 0x8031070f, - //libmixer Error Codes - CELL_LIBMIXER_ERROR_NOT_INITIALIZED = 0x80310002, - CELL_LIBMIXER_ERROR_INVALID_PARAMATER = 0x80310003, - CELL_LIBMIXER_ERROR_NO_MEMORY = 0x80310005, - CELL_LIBMIXER_ERROR_ALREADY_EXIST = 0x80310006, - CELL_LIBMIXER_ERROR_FULL = 0x80310007, - CELL_LIBMIXER_ERROR_NOT_EXIST = 0x80310008, - CELL_LIBMIXER_ERROR_TYPE_MISMATCH = 0x80310009, - CELL_LIBMIXER_ERROR_NOT_FOUND = 0x8031000a, - //libsnd3 Error Codes CELL_SND3_ERROR_PARAM = 0x80310301, CELL_SND3_ERROR_CREATE_MUTEX = 0x80310302, @@ -108,7 +100,6 @@ struct CellAudioPortConfig struct AudioPortConfig { - SMutexGeneral m_mutex; bool m_is_audio_port_opened; bool m_is_audio_port_started; u8 channel; @@ -121,7 +112,6 @@ struct AudioPortConfig struct AudioConfig //custom structure { - std::mutex m_mutex; enum { AUDIO_PORT_COUNT = 8, @@ -150,7 +140,9 @@ struct AudioConfig //custom structure memset(&m_ports, 0, sizeof(AudioPortConfig) * AUDIO_PORT_COUNT); m_port_in_use = 0; } -} m_config; +}; + +extern AudioConfig m_config; //libsnd3 datatypes struct CellSnd3DataCtx diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index 165f59a49d..ffaefb64d4 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -34,8 +34,11 @@ struct SFuncOp struct SFunc { func_caller* func; + void* ptr; char* name; Array ops; + u64 group; + u32 found; }; extern ArrayF g_static_funcs_list; @@ -110,7 +113,7 @@ public: template __forceinline void AddFunc(u32 id, T func); - template __forceinline void AddFuncSub(const u64 ops[], char* name, T func); + template __forceinline void AddFuncSub(const char group[8], const u64 ops[], char* name, T func); }; template @@ -120,13 +123,16 @@ __forceinline void Module::AddFunc(u32 id, T func) } template -__forceinline void Module::AddFuncSub(const u64 ops[], char* name, T func) +__forceinline void Module::AddFuncSub(const char group[8], const u64 ops[], char* name, T func) { if (!ops[0]) return; SFunc* sf = new SFunc; + sf->ptr = func; sf->func = bind_func(func); sf->name = name; + sf->group = *(u64*)group; + sf->found = 0; // TODO: check for self-inclusions, use CRC diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp index fec5d753be..61f4f27d56 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp @@ -63,8 +63,6 @@ next: adec.reader.addr = adec.task.au.addr; adec.reader.size = adec.task.au.size; //ConLog.Write("Audio AU: size = 0x%x, pts = 0x%llx", adec.task.au.size, adec.task.au.pts); - - //if (adec.last_pts > adec.task.au.pts) adec.last_pts = adec.task.au.pts; } break; default: @@ -266,8 +264,11 @@ u32 adecOpen(AudioDecoder* data) adec.reader.size = task.au.size; //ConLog.Write("Audio AU: size = 0x%x, pts = 0x%llx", task.au.size, task.au.pts); - //if (adec.last_pts > task.au.pts || adec.just_started) adec.last_pts = task.au.pts; - if (adec.just_started) adec.last_pts = task.au.pts; + if (adec.just_started) + { + adec.first_pts = task.au.pts; + adec.last_pts = task.au.pts /*- 3816*8*/; // hack + } struct AVPacketHolder : AVPacket { @@ -433,8 +434,19 @@ u32 adecOpen(AudioDecoder* data) if (got_frame) { - frame.pts = adec.last_pts; - adec.last_pts += ((u64)frame.data->nb_samples) * 90000 / 48000; // ??? + u64 ts = av_frame_get_best_effort_timestamp(frame.data); + if (ts != AV_NOPTS_VALUE) + { + frame.pts = ts/* - adec.first_pts*/; + adec.last_pts = frame.pts; + } + else + { + adec.last_pts += ((u64)frame.data->nb_samples) * 90000 / 48000; + frame.pts = adec.last_pts; + } + //frame.pts = adec.last_pts; + //adec.last_pts += ((u64)frame.data->nb_samples) * 90000 / 48000; // ??? frame.auAddr = task.au.addr; frame.auSize = task.au.size; frame.userdata = task.au.userdata; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.h b/rpcs3/Emu/SysCalls/Modules/cellAdec.h index 66364a6084..3e29c92b1a 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.h @@ -1114,7 +1114,7 @@ public: u32 memBias; AdecTask task; - u64 last_pts; + u64 last_pts, first_pts; CPUThread* adecCb; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 59fc40a276..9813fe763f 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" +#include "Utilities/SQueue.h" #include "Emu/Audio/cellAudio.h" #include "Emu/Audio/AudioManager.h" #include "Emu/Audio/AudioDumper.h" @@ -9,7 +10,9 @@ void cellAudio_init(); void cellAudio_unload(); Module cellAudio(0x0011, cellAudio_init, nullptr, cellAudio_unload); -extern u64 get_system_time(); +static SMutexGeneral audioMutex; + +AudioConfig m_config; // libaudio Functions @@ -23,6 +26,7 @@ int cellAudioInit() } m_config.m_is_audio_initialized = true; + m_config.start_time = 0; m_config.counter = 0; // alloc memory @@ -43,31 +47,57 @@ int cellAudioInit() ConLog.Write("Audio started"); - m_config.start_time = get_system_time(); - if (Ini.AudioDumpToFile.GetValue()) m_dump.WriteHeader(); float buffer[2*256]; // buffer for 2 channels be_t buffer2[8*256]; // buffer for 8 channels (max count) //u16 oal_buffer[2*256]; // buffer for OpenAL + memset(buffer, 0, sizeof(buffer)); + memset(buffer2, 0, sizeof(buffer2)); uint oal_buffer_offset = 0; uint oal_buffer_size = 2 * 256; - std::unique_ptr oal_buffer(new u16[oal_buffer_size]); - - memset(buffer, 0, sizeof(buffer)); - memset(buffer2, 0, sizeof(buffer2)); - memset(oal_buffer.get(), 0, oal_buffer_size * sizeof(u16)); + std::unique_ptr oal_buffer[32]; + SQueue queue; + for (u32 i = 0; i < queue.GetSize(); i++) + { + oal_buffer[i] = std::unique_ptr(new u16[oal_buffer_size]); + memset(oal_buffer[i].get(), 0, oal_buffer_size * sizeof(u16)); + } + queue.Clear(); + //std::unique_ptr oal_buf(new u16[oal_buffer_size]); + //memset(oal_buffer.get(), 0, oal_buffer_size * sizeof(u16)); Array keys; if(m_audio_out) { m_audio_out->Init(); - m_audio_out->Open(oal_buffer.get(), oal_buffer_size*sizeof(u16)); + m_audio_out->Open(oal_buffer[0].get(), oal_buffer_size * sizeof(u16)); } + m_config.start_time = get_system_time(); + + thread iat("Internal Audio Thread", [oal_buffer_size, &queue]() + { + while (true) + { + u16* oal_buffer = nullptr; + queue.Pop(oal_buffer); + + if (oal_buffer) + { + m_audio_out->AddData(oal_buffer, oal_buffer_size * sizeof(u16)); + } + else + { + break; + } + } + }); + iat.detach(); + while (m_config.m_is_audio_initialized) { if (Emu.IsStopped()) @@ -76,10 +106,12 @@ int cellAudioInit() goto abort; } + const u64 stamp0 = get_system_time(); + // TODO: send beforemix event (in ~2,6 ms before mixing) - // Sleep(5); // precise time of sleeping: 5,(3) ms (or 256/48000 sec) - if (m_config.counter * 256000000 / 48000 >= get_system_time() - m_config.start_time) + // precise time of sleeping: 5,(3) ms (or 256/48000 sec) + if (m_config.counter * 256000000 / 48000 >= stamp0 - m_config.start_time) { Sleep(1); continue; @@ -87,6 +119,8 @@ int cellAudioInit() m_config.counter++; + const u32 oal_pos = m_config.counter % queue.GetSize(); + if (Emu.IsPaused()) { continue; @@ -112,13 +146,13 @@ int cellAudioInit() memset(Memory + buf_addr, 0, block_size * sizeof(float)); { - SMutexGeneralLocker lock(port.m_mutex); + SMutexGeneralLocker lock(audioMutex); port.counter = m_config.counter; port.tag++; // absolute index of block that will be read index = (position + 1) % port.block; // write new value } - u32 k = port.channel / 2; + const u32 k = port.channel / 2; if (first_mix) { @@ -129,10 +163,10 @@ int cellAudioInit() buffer[i+1] = buffer2[i*k+1]; // convert the data from float to u16 - assert(buffer[i] >= -4.0f && buffer[i] <= 4.0f); - assert(buffer[i+1] >= -4.0f && buffer[i+1] <= 4.0f); - oal_buffer[oal_buffer_offset + i] = (u16)(buffer[i] * ((1 << 13) - 1)); - oal_buffer[oal_buffer_offset + i + 1] = (u16)(buffer[i+1] * ((1 << 13) - 1)); + //assert(buffer[i] >= -1.0f && buffer[i] <= 1.0f); + //assert(buffer[i+1] >= -1.0f && buffer[i+1] <= 1.0f); + oal_buffer[oal_pos][oal_buffer_offset + i] = (u16)(buffer[i] * ((1 << 14) - 1)); + oal_buffer[oal_pos][oal_buffer_offset + i + 1] = (u16)(buffer[i+1] * ((1 << 14) - 1)); } first_mix = false; @@ -145,17 +179,19 @@ int cellAudioInit() buffer[i+1] = (buffer[i+1] + buffer2[i*k+1]) * 0.5; // convert the data from float to u16 - assert(buffer[i] >= -4.0f && buffer[i] <= 4.0f); - assert(buffer[i+1] >= -4.0f && buffer[i+1] <= 4.0f); - oal_buffer[oal_buffer_offset + i] = (u16)(buffer[i] * ((1 << 13) - 1)); - oal_buffer[oal_buffer_offset + i + 1] = (u16)(buffer[i+1] * ((1 << 13) - 1)); + //assert(buffer[i] >= -1.0f && buffer[i] <= 1.0f); + //assert(buffer[i+1] >= -1.0f && buffer[i+1] <= 1.0f); + oal_buffer[oal_pos][oal_buffer_offset + i] = (u16)(buffer[i] * ((1 << 14) - 1)); + oal_buffer[oal_pos][oal_buffer_offset + i + 1] = (u16)(buffer[i+1] * ((1 << 14) - 1)); } } } + const u64 stamp1 = get_system_time(); + // send aftermix event (normal audio event) { - std::lock_guard lock(m_config.m_mutex); + SMutexGeneralLocker lock(audioMutex); keys.SetCount(m_config.m_keys.GetCount()); memcpy(keys.GetPtr(), m_config.m_keys.GetPtr(), sizeof(u64) * keys.GetCount()); } @@ -165,18 +201,22 @@ int cellAudioInit() Emu.GetEventManager().SendEvent(keys[i], 0x10103000e010e07, 0, 0, 0); } + const u64 stamp2 = get_system_time(); + oal_buffer_offset += sizeof(buffer) / sizeof(float); if(oal_buffer_offset >= oal_buffer_size) { if(m_audio_out) { - m_audio_out->AddData(oal_buffer.get(), oal_buffer_offset * sizeof(u16)); + queue.Push(&oal_buffer[oal_pos][0]); } oal_buffer_offset = 0; } + const u64 stamp3 = get_system_time(); + if(Ini.AudioDumpToFile.GetValue()) { if (m_dump.WriteData(&buffer, sizeof(buffer)) != sizeof(buffer)) // write file data @@ -185,16 +225,37 @@ int cellAudioInit() goto abort; } } + + const u64 stamp4 = get_system_time(); + + //ConLog.Write("Audio perf: start=%d (access=%d, event=%d, AddData=%d, dump=%d)", + //stamp0 - m_config.start_time, stamp1-stamp0, stamp2-stamp1, stamp3-stamp2, stamp4-stamp3); } ConLog.Write("Audio finished"); abort: + queue.Push(nullptr); + while (queue.GetCount()) + { + Sleep(1); + } if(Ini.AudioDumpToFile.GetValue()) m_dump.Finalize(); m_config.m_is_audio_finalized = true; + m_config.m_is_audio_initialized = false; }); t.detach(); + while (!m_config.start_time) // waiting for initialization + { + if (Emu.IsStopped()) + { + ConLog.Warning("cellAudioInit() aborted"); + return CELL_OK; + } + Sleep(1); + } + return CELL_OK; } @@ -395,7 +456,7 @@ int cellAudioGetPortTimestamp(u32 portNum, u64 tag, mem64_t stamp) AudioPortConfig& port = m_config.m_ports[portNum]; - SMutexGeneralLocker lock(port.m_mutex); + SMutexGeneralLocker lock(audioMutex); stamp = m_config.start_time + (port.counter + (tag - port.tag)) * 256000000 / 48000; @@ -429,7 +490,7 @@ int cellAudioGetPortBlockTag(u32 portNum, u64 blockNo, mem64_t tag) return CELL_AUDIO_ERROR_PARAM; } - SMutexGeneralLocker lock(port.m_mutex); + SMutexGeneralLocker lock(audioMutex); u64 tag_base = port.tag; if (tag_base % port.block > blockNo) @@ -457,7 +518,7 @@ int cellAudioCreateNotifyEventQueue(mem32_t id, mem64_t key) { cellAudio.Warning("cellAudioCreateNotifyEventQueue(id_addr=0x%x, key_addr=0x%x)", id.GetAddr(), key.GetAddr()); - std::lock_guard lock(m_config.m_mutex); + SMutexGeneralLocker lock(audioMutex); u64 event_key = 0; while (Emu.GetEventManager().CheckKey((event_key << 48) | 0x80004d494f323221)) @@ -475,7 +536,6 @@ int cellAudioCreateNotifyEventQueue(mem32_t id, mem64_t key) return CELL_AUDIO_ERROR_EVENT_QUEUE; } - m_config.m_keys.AddCpy(event_key); id = cellAudio.GetNewId(eq); key = event_key; @@ -492,8 +552,15 @@ int cellAudioSetNotifyEventQueue(u64 key) { cellAudio.Warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key); - std::lock_guard lock(m_config.m_mutex); + SMutexGeneralLocker lock(audioMutex); + for (u32 i = 0; i < m_config.m_keys.GetCount(); i++) // check for duplicates + { + if (m_config.m_keys[i] == key) + { + return CELL_AUDIO_ERROR_PARAM; + } + } m_config.m_keys.AddCpy(key); /*EventQueue* eq; @@ -517,7 +584,7 @@ int cellAudioRemoveNotifyEventQueue(u64 key) { cellAudio.Warning("cellAudioRemoveNotifyEventQueue(key=0x%llx)", key); - std::lock_guard lock(m_config.m_mutex); + SMutexGeneralLocker lock(audioMutex); bool found = false; for (u32 i = 0; i < m_config.m_keys.GetCount(); i++) diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp index 1e49e653d5..32581f3567 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.cpp @@ -67,9 +67,6 @@ next: vdec.reader.addr = vdec.task.addr; vdec.reader.size = vdec.task.size; //ConLog.Write("Video AU: size = 0x%x, pts = 0x%llx, dts = 0x%llx", vdec.task.size, vdec.task.pts, vdec.task.dts); - - //if (vdec.last_pts > vdec.task.pts) vdec.last_pts = vdec.task.pts; - //if (vdec.last_dts > vdec.task.dts) vdec.last_dts = vdec.task.dts; } break; default: @@ -208,12 +205,11 @@ u32 vdecOpen(VideoDecoder* data) vdec.reader.size = task.size; //ConLog.Write("Video AU: size = 0x%x, pts = 0x%llx, dts = 0x%llx", task.size, task.pts, task.dts); - //if (vdec.last_pts > task.pts || vdec.just_started) vdec.last_pts = task.pts; - //if (vdec.last_dts > task.dts || vdec.just_started) vdec.last_dts = task.dts; if (vdec.just_started) { + vdec.first_pts = task.pts; vdec.last_pts = task.pts; - vdec.last_dts = task.dts; + vdec.first_dts = task.dts; } struct AVPacketHolder : AVPacket @@ -357,8 +353,20 @@ u32 vdecOpen(VideoDecoder* data) if (got_picture) { - frame.dts = vdec.last_dts; vdec.last_dts += 3003; // + duration??? - frame.pts = vdec.last_pts; vdec.last_pts += 3003; + u64 ts = av_frame_get_best_effort_timestamp(frame.data); + if (ts != AV_NOPTS_VALUE) + { + frame.pts = ts/* - vdec.first_pts*/; // ??? + vdec.last_pts = frame.pts; + } + else + { + vdec.last_pts += vdec.ctx->time_base.num * 90000 / (vdec.ctx->time_base.den / vdec.ctx->ticks_per_frame); + frame.pts = vdec.last_pts; + } + //frame.pts = vdec.last_pts; + //vdec.last_pts += 3754; + frame.dts = (frame.pts - vdec.first_pts) + vdec.first_dts; frame.userdata = task.userData; //ConLog.Write("got picture (pts=0x%llx, dts=0x%llx)", frame.pts, frame.dts); @@ -726,7 +734,27 @@ int cellVdecGetPicItem(u32 handle, mem32_t picItem_ptr) avc->transfer_characteristics = CELL_VDEC_AVC_TC_ITU_R_BT_709_5; avc->matrix_coefficients = CELL_VDEC_AVC_MXC_ITU_R_BT_709_5; // important avc->timing_info_present_flag = true; - avc->frameRateCode = CELL_VDEC_AVC_FRC_30000DIV1001; // important (!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!) + if (vdec->ctx->time_base.num == 1001) + { + if (vdec->ctx->time_base.den == 48000 && vdec->ctx->ticks_per_frame == 2) + { + avc->frameRateCode = CELL_VDEC_AVC_FRC_24000DIV1001; + } + else if (vdec->ctx->time_base.den == 60000 && vdec->ctx->ticks_per_frame == 2) + { + avc->frameRateCode = CELL_VDEC_AVC_FRC_30000DIV1001; + } + else + { + ConLog.Error("cellVdecGetPicItem: unsupported time_base.den (%d)", vdec->ctx->time_base.den); + Emu.Pause(); + } + } + else + { + ConLog.Error("cellVdecGetPicItem: unsupported time_base.num (%d)", vdec->ctx->time_base.num); + Emu.Pause(); + } avc->fixed_frame_rate_flag = true; avc->low_delay_hrd_flag = true; // ??? avc->entropy_coding_mode_flag = true; // ??? diff --git a/rpcs3/Emu/SysCalls/Modules/cellVdec.h b/rpcs3/Emu/SysCalls/Modules/cellVdec.h index 96534cdbe2..65adee08e0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellVdec.h +++ b/rpcs3/Emu/SysCalls/Modules/cellVdec.h @@ -719,7 +719,8 @@ public: u32 memBias; VdecTask task; // current task variable - u64 last_pts, last_dts; + u64 last_pts, first_pts, first_dts; + AVRational rfr, afr; CPUThread* vdecCb; diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp index cb2b3bb547..53ec449bfd 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -1,15 +1,47 @@ #include "stdafx.h" #include "Emu/SysCalls/SysCalls.h" #include "Emu/SysCalls/SC_FUNC.h" +#include "Emu/Audio/cellAudio.h" #include "libmixer.h" void libmixer_init(); Module libmixer("libmixer", libmixer_init); -int cellAANAddData(u32 handle, u32 port, u32 offset, u32 addr, u32 samples) +CellSurMixerConfig surMixer; + +#define SUR_PORT (7) +u32 surMixerCb = 0; +u32 surMixerCbArg = 0; +u64 mixcount = 0, stamp1 = 0, stamp2 = 0; + +int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 samples) { - libmixer.Error("cellAANAddData(handle=0x%x, port=0x%x, offset=0x%x, addr=0x%x, samples=0x%x)", - handle, port, offset, addr, samples); + stamp1 = get_system_time(); + + if (aan_handle == 0x11111111 && aan_port == (2 << 16)) + { + libmixer.Log("cellAANAddData(handle=0x%x, port=0x%x, offset=0x%x, addr=0x%x, samples=0x%x)", + aan_handle, aan_port, offset, addr, samples); + } + else + { + libmixer.Error("cellAANAddData(handle=0x%x, port=0x%x, offset=0x%x, addr=0x%x, samples=0x%x)", + aan_handle, aan_port, offset, addr, samples); + Emu.Pause(); + return CELL_OK; + } + + AudioPortConfig& port = m_config.m_ports[SUR_PORT]; + + u32 to = m_config.m_buffer + (128 * 1024 * SUR_PORT) + ((mixcount + 12) % 16) * 2 * 256 * sizeof(float) + offset; + + if (!Memory.Copy(to, addr, 2 * samples * sizeof(float))) + { + return CELL_LIBMIXER_ERROR_NO_MEMORY; + } + + stamp2 = get_system_time(); + return CELL_OK; } @@ -71,49 +103,127 @@ s32 cellSSPlayerGetState() //CellAANHandle handle int cellSurMixerCreate(const mem_ptr_t config) { - libmixer.Error("cellSurMixerCreate(config_addr=0x%x)", config.GetAddr()); + libmixer.Warning("cellSurMixerCreate(config_addr=0x%x)", config.GetAddr()); + surMixer = *config; + libmixer.Warning("*** surMixer created (ch1=%d, ch2=%d, ch6=%d, ch8=%d)", + (u32)surMixer.chStrips1, (u32)surMixer.chStrips2, (u32)surMixer.chStrips6, (u32)surMixer.chStrips8); return CELL_OK; } int cellSurMixerGetAANHandle(mem32_t handle) { - libmixer.Error("cellSurMixerGetAANHandle(handle_addr=0x%x)", handle.GetAddr()); + libmixer.Warning("cellSurMixerGetAANHandle(handle_addr=0x%x) -> 0x11111111", handle.GetAddr()); + handle = 0x11111111; return CELL_OK; } int cellSurMixerChStripGetAANPortNo(mem32_t port, u32 type, u32 index) { - libmixer.Error("cellSurMixerChStripGetAANPortNo(port_addr=0x%x, type=0x%x, index=0x%x)", port.GetAddr(), type, index); + libmixer.Warning("cellSurMixerChStripGetAANPortNo(port_addr=0x%x, type=0x%x, index=0x%x) -> 0", port.GetAddr(), type, index); + port = (type << 16) | index; return CELL_OK; } int cellSurMixerSetNotifyCallback(u32 func, u32 arg) { - libmixer.Error("cellSurMixerSetNotifyCallback(func_addr=0x%x, arg=0x%x)", func, arg); + libmixer.Warning("cellSurMixerSetNotifyCallback(func_addr=0x%x, arg=0x%x)", func, arg); + surMixerCb = func; + surMixerCbArg = arg; return CELL_OK; } int cellSurMixerRemoveNotifyCallback(u32 func) { - libmixer.Error("cellSurMixerSetNotifyCallback(func_addr=0x%x)", func); + libmixer.Warning("cellSurMixerSetNotifyCallback(func_addr=0x%x)", func); + surMixerCb = 0; + surMixerCbArg = 0; return CELL_OK; } int cellSurMixerStart() { - libmixer.Error("cellSurMixerStart()"); + libmixer.Warning("cellSurMixerStart()"); + + AudioPortConfig& port = m_config.m_ports[SUR_PORT]; + + if (port.m_is_audio_port_opened) + { + return CELL_LIBMIXER_ERROR_FULL; + } + + port.channel = 2; + port.block = 16; + port.attr = 0; + port.level = 1.0f; + + libmixer.Warning("*** audio port opened(default, port 7)"); + + port.m_is_audio_port_opened = true; + port.tag = 0; + m_config.m_port_in_use++; + port.m_is_audio_port_started = true; + + thread t("Libmixer Thread", []() + { + AudioPortConfig& port = m_config.m_ports[SUR_PORT]; + + CPUThread* mixerCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU); + + mixerCb->SetName("Libmixer Callback"); + + mixcount = 0; + + while (port.m_is_audio_port_started) + { + if (Emu.IsStopped()) + { + ConLog.Warning("Libmixer aborted"); + return; + } + + if (mixcount > port.tag) + { + Sleep(1); + continue; + } + + u64 stamp0 = get_system_time(); + stamp1 = 0; + stamp2 = 0; + + mixerCb->ExecAsCallback(surMixerCb, true, surMixerCbArg, mixcount, 256); + + u64 stamp3 = get_system_time(); + + //ConLog.Write("Libmixer perf: start=%d (cb_before=%d, cb=%d, cb_after=%d)", + //stamp0 - m_config.start_time, stamp1-stamp0, stamp2-stamp1, stamp3-stamp2); + + mixcount++; + } + + Emu.GetCPU().RemoveThread(mixerCb->GetId()); + }); + t.detach(); + return CELL_OK; } int cellSurMixerSetParameter(u32 param, float value) { - libmixer.Error("cellSurMixerSetParameter(param=0x%x, value=%f)", param, value); + libmixer.Warning("cellSurMixerSetParameter(param=0x%x, value=%f)", param, value); return CELL_OK; } int cellSurMixerFinalize() { - libmixer.Error("cellSurMixerFinalize()"); + libmixer.Warning("cellSurMixerFinalize()"); + + AudioPortConfig& port = m_config.m_ports[SUR_PORT]; + + port.m_is_audio_port_started = false; + port.m_is_audio_port_opened = false; + m_config.m_port_in_use--; + return CELL_OK; } @@ -198,7 +308,7 @@ void libmixer_init() 0xffffffff4e800020, 0 }; - libmixer.AddFuncSub(cellAANAddData_table, "cellAANAddData", cellAANAddData); + libmixer.AddFuncSub("mixerAAN", cellAANAddData_table, "cellAANAddData", cellAANAddData); u64 cellAANConnect_table[39] = { 0xfffffffff821ff71, @@ -241,9 +351,9 @@ void libmixer_init() 0xffffffff4e800020, 0, // [38] }; - libmixer.AddFuncSub(cellAANConnect_table, "cellAANConnect", cellAANConnect); + libmixer.AddFuncSub("mixerAAN", cellAANConnect_table, "cellAANConnect", cellAANConnect); cellAANConnect_table[24] = 0xffffffff812b001c; - libmixer.AddFuncSub(cellAANConnect_table, "cellAANDisconnect", cellAANDisconnect); + libmixer.AddFuncSub("mixerAAN", cellAANConnect_table, "cellAANDisconnect", cellAANDisconnect); static const u64 cellAANAddData_table1[] = { // TODO @@ -272,7 +382,7 @@ void libmixer_init() 0xffffffff4e800020, 0 }; - libmixer.AddFuncSub(cellAANAddData_table1, "cellAANAddData(1)", cellAANAddData); + libmixer.AddFuncSub("mixerAAN", cellAANAddData_table1, "cellAANAddData(1)", cellAANAddData); static const u64 cellSurMixerCreate_table[] = { 0xffffffff2f830000, @@ -303,7 +413,7 @@ void libmixer_init() 0xffffffff382100b0, 0 }; - libmixer.AddFuncSub(cellSurMixerCreate_table, "cellSurMixerCreate", cellSurMixerCreate); + libmixer.AddFuncSub("surMixer", cellSurMixerCreate_table, "cellSurMixerCreate", cellSurMixerCreate); static const u64 cellSurMixerGetAANHandle_table[] = { // first instruction ignored @@ -322,7 +432,7 @@ void libmixer_init() 0xffffffff4e800020, 0 }; - libmixer.AddFuncSub(cellSurMixerGetAANHandle_table, "cellSurMixerGetAANHandle", cellSurMixerGetAANHandle); + libmixer.AddFuncSub("surMixer", cellSurMixerGetAANHandle_table, "cellSurMixerGetAANHandle", cellSurMixerGetAANHandle); static const u64 cellSurMixerChStripGetAANPortNo_table[] = { // first instruction ignored @@ -339,7 +449,7 @@ void libmixer_init() 0xf000000040000000, // b 0 }; - libmixer.AddFuncSub(cellSurMixerChStripGetAANPortNo_table, "cellSurMixerChStripGetAANPortNo", cellSurMixerChStripGetAANPortNo); + libmixer.AddFuncSub("surMixer", cellSurMixerChStripGetAANPortNo_table, "cellSurMixerChStripGetAANPortNo", cellSurMixerChStripGetAANPortNo); static const u64 cellSurMixerSetNotifyCallback_table[] = { // first instruction ignored @@ -369,7 +479,7 @@ void libmixer_init() 0xffffffff7d234b78, 0 }; - libmixer.AddFuncSub(cellSurMixerSetNotifyCallback_table, "cellSurMixerSetNotifyCallback", cellSurMixerSetNotifyCallback); + libmixer.AddFuncSub("surMixer", cellSurMixerSetNotifyCallback_table, "cellSurMixerSetNotifyCallback", cellSurMixerSetNotifyCallback); static const u64 cellSurMixerRemoveNotifyCallback_table[] = { // first instruction ignored @@ -389,7 +499,7 @@ void libmixer_init() 0xffffffff4e800020, 0 }; - libmixer.AddFuncSub(cellSurMixerRemoveNotifyCallback_table, "cellSurMixerRemoveNotifyCallback", cellSurMixerRemoveNotifyCallback); + libmixer.AddFuncSub("surMixer", cellSurMixerRemoveNotifyCallback_table, "cellSurMixerRemoveNotifyCallback", cellSurMixerRemoveNotifyCallback); static const u64 cellSurMixerStart_table[] = { 0xfffffffff821ff71, @@ -414,7 +524,7 @@ void libmixer_init() 0xffffffff4e800020, 0 }; - libmixer.AddFuncSub(cellSurMixerStart_table, "cellSurMixerStart", cellSurMixerStart); + libmixer.AddFuncSub("surMixer", cellSurMixerStart_table, "cellSurMixerStart", cellSurMixerStart); static const u64 cellSurMixerSetParameter_table[] = { 0xfffffffff821ff81, @@ -446,7 +556,7 @@ void libmixer_init() 0xffff0000409d0054, // ble 0 }; - libmixer.AddFuncSub(cellSurMixerSetParameter_table, "cellSurMixerSetParameter", cellSurMixerSetParameter); + libmixer.AddFuncSub("surMixer", cellSurMixerSetParameter_table, "cellSurMixerSetParameter", cellSurMixerSetParameter); static const u64 cellSurMixerFinalize_table[] = { 0xfffffffff821ff91, @@ -474,5 +584,5 @@ void libmixer_init() 0xffffffff4e800421, 0 }; - libmixer.AddFuncSub(cellSurMixerFinalize_table, "cellSurMixerFinalize", cellSurMixerFinalize); + libmixer.AddFuncSub("surMixer", cellSurMixerFinalize_table, "cellSurMixerFinalize", cellSurMixerFinalize); } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.h b/rpcs3/Emu/SysCalls/Modules/libmixer.h index 24c30c7b70..fe56a85ab6 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.h +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.h @@ -1,5 +1,17 @@ #pragma once +enum +{ + //libmixer Error Codes + CELL_LIBMIXER_ERROR_NOT_INITIALIZED = 0x80310002, + CELL_LIBMIXER_ERROR_INVALID_PARAMATER = 0x80310003, + CELL_LIBMIXER_ERROR_NO_MEMORY = 0x80310005, + CELL_LIBMIXER_ERROR_ALREADY_EXIST = 0x80310006, + CELL_LIBMIXER_ERROR_FULL = 0x80310007, + CELL_LIBMIXER_ERROR_NOT_EXIST = 0x80310008, + CELL_LIBMIXER_ERROR_TYPE_MISMATCH = 0x80310009, + CELL_LIBMIXER_ERROR_NOT_FOUND = 0x8031000a, +}; //Callback Functions typedef int (*CellSurMixerNotifyCallbackFunction)(void *arg, u32 counter, u32 samples); //Currently unused. diff --git a/rpcs3/Emu/SysCalls/Static.cpp b/rpcs3/Emu/SysCalls/Static.cpp index 2628a77272..6a8369b701 100644 --- a/rpcs3/Emu/SysCalls/Static.cpp +++ b/rpcs3/Emu/SysCalls/Static.cpp @@ -9,8 +9,6 @@ void StaticAnalyse(void* ptr, u32 size) { u32* data = (u32*)ptr; size /= 4; - return; // disabled - // TODO: optimize search for (u32 i = 0; i < size; i++) { @@ -36,7 +34,8 @@ void StaticAnalyse(void* ptr, u32 size) } if (found) { - ConLog.Success("Function '%s' hooked", wxString(g_static_funcs_list[j].name).wx_str()); + //ConLog.Success("Function '%s' hooked", wxString(g_static_funcs_list[j].name).wx_str()); + g_static_funcs_list[j].found++; data[i] = re(0x39600000 | j); // li r11, j data[i+1] = se32(0x44000003); // sc 3 data[i+2] = se32(0x4e800020); // blr @@ -45,6 +44,91 @@ void StaticAnalyse(void* ptr, u32 size) } } } + + // check function groups + for (u32 i = 0; i < g_static_funcs_list.GetCount(); i++) + { + if (g_static_funcs_list[i].found) // start from some group + { + const u64 group = g_static_funcs_list[i].group; + + enum GroupSearchResult : u32 + { + GSR_SUCCESS = 0, // every function from this group has been found + GSR_MISSING = 1, // (error) not every function found + GSR_EXCESS = 2, // (error) some function found twice or more + }; + u32 res = GSR_SUCCESS; + + // analyse + for (u32 j = i; j < g_static_funcs_list.GetCount(); j++) if (g_static_funcs_list[j].group == group) + { + u32 count = g_static_funcs_list[j].found; + + if (count == 0) // not found + { + // check if this function has been found with different pattern + for (u32 k = i; k < g_static_funcs_list.GetCount(); k++) if (g_static_funcs_list[k].group == group) + { + if (k != j && g_static_funcs_list[k].ptr == g_static_funcs_list[j].ptr) + { + count += g_static_funcs_list[k].found; + } + } + if (count == 0) + { + res |= GSR_MISSING; + ConLog.Error("Function '%s' not found", wxString(g_static_funcs_list[j].name).wx_str()); + } + else if (count > 1) + { + res |= GSR_EXCESS; + } + } + else if (count == 1) // found + { + // ensure that this function has NOT been found with different pattern + for (u32 k = i; k < g_static_funcs_list.GetCount(); k++) if (g_static_funcs_list[k].group == group) + { + if (k != j && g_static_funcs_list[k].ptr == g_static_funcs_list[j].ptr) + { + if (g_static_funcs_list[k].found) + { + res |= GSR_EXCESS; + ConLog.Error("Function '%s' hooked twice", wxString(g_static_funcs_list[j].name).wx_str()); + } + } + } + } + else + { + res |= GSR_EXCESS; + ConLog.Error("Function '%s' hooked twice", wxString(g_static_funcs_list[j].name).wx_str()); + } + } + + // clear data + for (u32 j = i; j < g_static_funcs_list.GetCount(); j++) + { + if (g_static_funcs_list[j].group == group) g_static_funcs_list[j].found = 0; + } + + char name[9] = "????????"; + + *(u64*)name = group; + + if (res == GSR_SUCCESS) + { + ConLog.Success("Function group [%s] successfully hooked", wxString(name, 9).wx_str()); + } + else + { + ConLog.Error("Function group [%s] failed: %s%s", wxString(name, 9).wx_str(), + wxString(res & GSR_MISSING ? "missing;" : "").wx_str(), + wxString(res & GSR_EXCESS ? "excess;" : "").wx_str()); + } + } + } } void StaticExecute(u32 code) From 70cc2494aa16d6cc170bb7a5ba486a594e480713 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 28 Mar 2014 12:47:32 +0400 Subject: [PATCH 05/14] bad_flip issue fix --- rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp | 12 ++++++++- rpcs3/Gui/ConLog.cpp | 33 ++++++++++------------- rpcs3/Gui/ConLog.h | 10 +++---- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 877075b86f..a00b49d4ff 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -181,7 +181,17 @@ int cellGcmSetPrepareFlip(mem_ptr_t ctxt, u32 id) if(current + 8 >= end) { ConLog.Warning("bad flip!"); - cellGcmCallback(ctxt.GetAddr(), current + 8 - end); + //cellGcmCallback(ctxt.GetAddr(), current + 8 - end); + //copied: + + CellGcmControl& ctrl = (CellGcmControl&)Memory[gcm_info.control_addr]; + + const s32 res = ctxt->current - ctxt->begin - ctrl.put; + + if(res > 0) Memory.Copy(ctxt->begin, ctxt->current - res, res); + ctxt->current = ctxt->begin + res; + ctrl.put = res; + ctrl.get = 0; } current = ctxt->current; diff --git a/rpcs3/Gui/ConLog.cpp b/rpcs3/Gui/ConLog.cpp index 4895d74113..8047c3fbd5 100644 --- a/rpcs3/Gui/ConLog.cpp +++ b/rpcs3/Gui/ConLog.cpp @@ -32,10 +32,6 @@ struct LogPacket { } - - LogPacket() - { - } }; struct _LogBuffer : public MTPacketBuffer @@ -78,29 +74,27 @@ struct _LogBuffer : public MTPacketBuffer LogPacket _pop() { - LogPacket ret; - u32 c_get = m_get; const u32& sprefix = *(u32*)&m_buffer[c_get]; c_get += sizeof(u32); - ret.m_prefix = wxString((wxChar*)&m_buffer[c_get], sprefix / sizeof(wxChar)); + const wxString& prefix = wxString((wxChar*)&m_buffer[c_get], sprefix / sizeof(wxChar)); c_get += sprefix; const u32& stext = *(u32*)&m_buffer[c_get]; c_get += sizeof(u32); - ret.m_text = wxString((wxChar*)&m_buffer[c_get], stext / sizeof(wxChar)); + const wxString& text = wxString((wxChar*)&m_buffer[c_get], stext / sizeof(wxChar)); c_get += stext; const u32& scolour = *(u32*)&m_buffer[c_get]; c_get += sizeof(u32); - ret.m_colour = wxString((wxChar*)&m_buffer[c_get], scolour / sizeof(wxChar)); + const wxString& colour = wxString((wxChar*)&m_buffer[c_get], scolour / sizeof(wxChar)); c_get += scolour; m_get = c_get; if(!HasNewPacket()) Flush(); - return ret; + return LogPacket(prefix, text, colour); } } LogBuffer; @@ -114,18 +108,19 @@ LogWriter::LogWriter() } } -void LogWriter::WriteToLog(wxString prefix, wxString value, u8 lvl/*, wxColour bgcolour*/) +void LogWriter::WriteToLog(const wxString& prefix, const wxString& value, u8 lvl/*, wxColour bgcolour*/) { + wxString new_prefix = prefix; if(!prefix.empty()) { if(NamedThreadBase* thr = GetCurrentNamedThread()) { - prefix += " : " + thr->GetThreadName(); + new_prefix += " : " + thr->GetThreadName(); } } - if(m_logfile.IsOpened() && !prefix.empty()) - m_logfile.Write(wxString("[") + prefix + "]: " + value + "\n"); + if(m_logfile.IsOpened() && !new_prefix.empty()) + m_logfile.Write(wxString("[") + new_prefix + "]: " + value + "\n"); if(!ConLogFrame || Ini.HLELogLvl.GetValue() == 4 || (lvl != 0 && lvl <= Ini.HLELogLvl.GetValue())) return; @@ -159,10 +154,10 @@ void LogWriter::WriteToLog(wxString prefix, wxString value, u8 lvl/*, wxColour b //if(LogBuffer.put == LogBuffer.get) LogBuffer.Flush(); - LogBuffer.Push(LogPacket(prefix, value, g_log_colors[lvl])); + LogBuffer.Push(LogPacket(new_prefix, value, g_log_colors[lvl])); } -void LogWriter::Write(const wxString fmt, ...) +void LogWriter::Write(const wxString& fmt, ...) { va_list list; va_start(list, fmt); @@ -175,7 +170,7 @@ void LogWriter::Write(const wxString fmt, ...) WriteToLog("!", frmt, 2); } -void LogWriter::Error(const wxString fmt, ...) +void LogWriter::Error(const wxString& fmt, ...) { va_list list; va_start(list, fmt); @@ -188,7 +183,7 @@ void LogWriter::Error(const wxString fmt, ...) WriteToLog("E", frmt, 4); } -void LogWriter::Warning(const wxString fmt, ...) +void LogWriter::Warning(const wxString& fmt, ...) { va_list list; va_start(list, fmt); @@ -201,7 +196,7 @@ void LogWriter::Warning(const wxString fmt, ...) WriteToLog("W", frmt, 3); } -void LogWriter::Success(const wxString fmt, ...) +void LogWriter::Success(const wxString& fmt, ...) { va_list list; va_start(list, fmt); diff --git a/rpcs3/Gui/ConLog.h b/rpcs3/Gui/ConLog.h index 79aec07cf1..dd44054c89 100644 --- a/rpcs3/Gui/ConLog.h +++ b/rpcs3/Gui/ConLog.h @@ -11,15 +11,15 @@ class LogWriter //wxString m_prefix; //wxString m_value; - virtual void WriteToLog(wxString prefix, wxString value, u8 lvl); + virtual void WriteToLog(const wxString& prefix, const wxString& value, u8 lvl); public: LogWriter(); - virtual void Write(const wxString fmt, ...); - virtual void Error(const wxString fmt, ...); - virtual void Warning(const wxString fmt, ...); - virtual void Success(const wxString fmt, ...); + virtual void Write(const wxString& fmt, ...); + virtual void Error(const wxString& fmt, ...); + virtual void Warning(const wxString& fmt, ...); + virtual void Success(const wxString& fmt, ...); virtual void SkipLn(); }; From 689c41ccb32b3772488c6abe9fa9d588a8eeaf16 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sat, 29 Mar 2014 02:50:05 +0400 Subject: [PATCH 06/14] Minor fixes Libmixer: additional patterns --- Utilities/SMutex.cpp | 10 +- Utilities/SMutex.h | 6 +- Utilities/SQueue.h | 10 +- rpcs3/Emu/SysCalls/Modules.h | 3 +- rpcs3/Emu/SysCalls/Modules/libmixer.cpp | 299 ++++++++++++++++++------ rpcs3/Emu/SysCalls/Static.cpp | 84 +++++-- rpcs3/Emu/SysCalls/SysCalls.h | 2 +- rpcs3/Gui/ConLog.cpp | 2 +- rpcs3/Loader/ELF64.cpp | 2 +- 9 files changed, 316 insertions(+), 102 deletions(-) diff --git a/Utilities/SMutex.cpp b/Utilities/SMutex.cpp index 1d9bcb03f2..541d20b276 100644 --- a/Utilities/SMutex.cpp +++ b/Utilities/SMutex.cpp @@ -1,15 +1,21 @@ #include #include - __forceinline void SM_Sleep() { Sleep(1); } +#ifdef _WIN32 +__declspec(thread) +#else +thread_local +#endif +size_t g_this_thread_id = 0; + __forceinline size_t SM_GetCurrentThreadId() { - return std::hash()(std::this_thread::get_id()); + return g_this_thread_id ? g_this_thread_id : g_this_thread_id = std::hash()(std::this_thread::get_id()); } __forceinline u32 SM_GetCurrentCPUThreadId() diff --git a/Utilities/SMutex.h b/Utilities/SMutex.h index 5aa9a98f07..fe856f501e 100644 --- a/Utilities/SMutex.h +++ b/Utilities/SMutex.h @@ -21,7 +21,7 @@ template < typename T, u64 free_value = 0, - u64 dead_value = ~0, + u64 dead_value = 0xffffffff, void (*wait)() = SM_Sleep > class SMutexBase @@ -139,7 +139,7 @@ class SMutexLockerBase public: const T tid; - SMutexLockerBase(SMutexBase& _sm) + __forceinline SMutexLockerBase(SMutexBase& _sm) : sm(_sm) , tid(get_tid()) { @@ -155,7 +155,7 @@ public: sm.lock(tid); } - ~SMutexLockerBase() + __forceinline ~SMutexLockerBase() { if (tid) sm.unlock(tid); } diff --git a/Utilities/SQueue.h b/Utilities/SQueue.h index 7b52644771..dd0b7787fc 100644 --- a/Utilities/SQueue.h +++ b/Utilities/SQueue.h @@ -3,7 +3,7 @@ template class SQueue { - SMutex m_mutex; + SMutexGeneral m_mutex; u32 m_pos; u32 m_count; T m_data[SQSize]; @@ -40,7 +40,7 @@ public: } { - SMutexLocker lock(m_mutex); + SMutexGeneralLocker lock(m_mutex); if (m_count >= SQSize) continue; @@ -71,7 +71,7 @@ public: } { - SMutexLocker lock(m_mutex); + SMutexGeneralLocker lock(m_mutex); if (!m_count) continue; @@ -96,7 +96,7 @@ public: void Clear() { - SMutexLocker lock(m_mutex); + SMutexGeneralLocker lock(m_mutex); m_count = 0; } @@ -120,7 +120,7 @@ public: } { - SMutexLocker lock(m_mutex); + SMutexGeneralLocker lock(m_mutex); if (m_count) break; } } diff --git a/rpcs3/Emu/SysCalls/Modules.h b/rpcs3/Emu/SysCalls/Modules.h index ffaefb64d4..16323dd8e6 100644 --- a/rpcs3/Emu/SysCalls/Modules.h +++ b/rpcs3/Emu/SysCalls/Modules.h @@ -140,7 +140,8 @@ __forceinline void Module::AddFuncSub(const char group[8], const u64 ops[], char { SFuncOp op; op.mask = ops[i] >> 32; - op.crc = ops[i] & op.mask; + op.crc = ops[i]; + if (op.mask) op.crc &= op.mask; op.mask = re(op.mask); op.crc = re(op.crc); sf->ops.AddCpy(op); diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp index 53ec449bfd..12d7728f42 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -156,20 +156,20 @@ int cellSurMixerStart() port.attr = 0; port.level = 1.0f; - libmixer.Warning("*** audio port opened(default, port 7)"); + libmixer.Warning("*** audio port opened(default)"); port.m_is_audio_port_opened = true; port.tag = 0; m_config.m_port_in_use++; port.m_is_audio_port_started = true; - thread t("Libmixer Thread", []() + thread t("Surmixer Thread", []() { AudioPortConfig& port = m_config.m_ports[SUR_PORT]; CPUThread* mixerCb = &Emu.GetCPU().AddThread(CPU_THREAD_PPU); - mixerCb->SetName("Libmixer Callback"); + mixerCb->SetName("Surmixer Callback"); mixcount = 0; @@ -177,7 +177,7 @@ int cellSurMixerStart() { if (Emu.IsStopped()) { - ConLog.Warning("Libmixer aborted"); + ConLog.Warning("Surmixer aborted"); return; } @@ -227,63 +227,69 @@ int cellSurMixerFinalize() return CELL_OK; } -/*int cellSurMixerSurBusAddData() //u32 busNo, u32 offset, float *addr, u32 samples +int cellSurMixerSurBusAddData(u32 busNo, u32 offset, u32 addr, u32 samples) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; + libmixer.Error("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, samples); + return CELL_OK; } -int cellSurMixerChStripSetParameter() //u32 type, u32 index, CellSurMixerChStripParam *param +int cellSurMixerChStripSetParameter(u32 type, u32 index, mem_ptr_t param) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; + libmixer.Error("cellSurMixerChStripSetParameter(type=%d, index=%d, param_addr=0x%x)", type, index, param.GetAddr()); + return CELL_OK; } -int cellSurMixerPause() //u32 switch +int cellSurMixerPause(u32 type) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; + libmixer.Error("cellSurMixerPause(type=%d)", type); + return CELL_OK; } -int cellSurMixerGetCurrentBlockTag() //u64 *tag +int cellSurMixerGetCurrentBlockTag(mem64_t tag) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; + libmixer.Error("cellSurMixerGetCurrentBlockTag(tag_addr=0x%x)", tag.GetAddr()); + return CELL_OK; } -int cellSurMixerGetTimestamp() //u64 tag, u64 *stamp +int cellSurMixerGetTimestamp(u64 tag, mem64_t stamp) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; + libmixer.Error("cellSurMixerGetTimestamp(tag=0x%llx, stamp_addr=0x%x)", tag, stamp.GetAddr()); + return CELL_OK; } -void cellSurMixerBeep(); //void *arg - -float cellSurMixerUtilGetLevelFromDB() //float dB +void cellSurMixerBeep(u32 arg) { - UNIMPLEMENTED_FUNC(libmixer); - return CELL_OK; //it's NOT real value - //TODO; + libmixer.Error("cellSurMixerBeep(arg=%d)", arg); + return; } -float cellSurMixerUtilGetLevelFromDBIndex() //int index +void cellSurMixerUtilGetLevelFromDB(float dB) { - UNIMPLEMENTED_FUNC(libmixer); - return CELL_OK; //it's NOT real value - //TODO; + // not hooked, probably unnecessary + libmixer.Error("cellSurMixerUtilGetLevelFromDB(dB=%f)", dB); + declCPU(); + (float&)CPU.FPR[0] = 0.0f; } -float cellSurMixerUtilNoteToRatio() //unsigned char refNote, unsigned char note +void cellSurMixerUtilGetLevelFromDBIndex(int index) { - UNIMPLEMENTED_FUNC(libmixer); - return CELL_OK; //it's NOT real value - //TODO -}*/ + // not hooked, probably unnecessary + libmixer.Error("cellSurMixerUtilGetLevelFromDBIndex(index=%d)", index); + declCPU(); + (float&)CPU.FPR[0] = 0.0f; +} + +void cellSurMixerUtilNoteToRatio(u8 refNote, u8 note) +{ + // not hooked, probably unnecessary + libmixer.Error("cellSurMixerUtilNoteToRatio(refNote=%d, note=%d)", refNote, note); + declCPU(); + (float&)CPU.FPR[0] = 0.0f; +} void libmixer_init() { static const u64 cellAANAddData_table[] = { - // TODO 0xffffffff7c691b78, 0xffffffff7c0802a6, 0xfffffffff821ff91, @@ -293,6 +299,7 @@ void libmixer_init() 0xffffffff81690000, 0xffffffff7c050378, 0xffffffff7cc43378, + 0x78630020, // clrldi r3,r3,32 0xffffffff7d465378, 0xffffffff812b0030, 0xffffffff80090000, @@ -308,9 +315,9 @@ void libmixer_init() 0xffffffff4e800020, 0 }; - libmixer.AddFuncSub("mixerAAN", cellAANAddData_table, "cellAANAddData", cellAANAddData); + libmixer.AddFuncSub("surmxAAN", cellAANAddData_table, "cellAANAddData", cellAANAddData); - u64 cellAANConnect_table[39] = { + static const u64 cellAANConnect_table[] = { 0xfffffffff821ff71, 0xffffffff7c0802a6, 0xffffffff2f830000, @@ -335,7 +342,7 @@ void libmixer_init() 0xffffffff90a10070, 0xffffffff90c10078, 0xffffffff9141007c, - 0xffffffff812b0018, // [24] + 0xffffffff812b0018, // difference 0xffffffff90010080, 0xffffffff80090000, 0xfffffffff8410028, @@ -349,40 +356,52 @@ void libmixer_init() 0xffffffff38210090, 0xffffffff7c0803a6, 0xffffffff4e800020, - 0, // [38] + 0, }; - libmixer.AddFuncSub("mixerAAN", cellAANConnect_table, "cellAANConnect", cellAANConnect); - cellAANConnect_table[24] = 0xffffffff812b001c; - libmixer.AddFuncSub("mixerAAN", cellAANConnect_table, "cellAANDisconnect", cellAANDisconnect); + libmixer.AddFuncSub("surmxAAN", cellAANConnect_table, "cellAANConnect", cellAANConnect); - static const u64 cellAANAddData_table1[] = { - // TODO - 0xffffffff7c691b78, + static const u64 cellAANDisconnect_table[] = { + 0xfffffffff821ff71, 0xffffffff7c0802a6, - 0xfffffffff821ff91, - 0xfffffffff8010080, - 0xffffffff7c802378, - 0xffffffff7caa2b78, + 0xffffffff2f830000, + 0xfffffffff80100a0, + 0xffffffff3c008031, + 0xffffffff7c691b78, + 0xffffffff7c8a2378, + 0xffffffff60000003, + 0xffffff00409e0018, // bne + 0xffffffff7c0307b4, + 0xffffffffe80100a0, + 0xffffffff38210090, + 0xffffffff7c0803a6, + 0xffffffff4e800020, + 0xffffffff2f850000, + 0xffffffff78630020, + 0xffffffff38810070, + 0xffffff00419effe0, // beq 0xffffffff81690000, - 0xffffffff7c050378, - 0xffffffff7cc43378, - 0xffffffff78630020, // clrldi r3,r3,32 - 0xffffffff7d465378, - 0xffffffff812b0030, + 0xffffffff38000001, + 0xffffffff91210074, + 0xffffffff90a10070, + 0xffffffff90c10078, + 0xffffffff9141007c, + 0xffffffff812b001c, // difference + 0xffffffff90010080, 0xffffffff80090000, 0xfffffffff8410028, 0xffffffff7c0903a6, 0xffffffff80490004, 0xffffffff4e800421, 0xffffffffe8410028, - 0xffffffffe8010080, - 0xffffffff7c6307b4, + 0xffffffff7c601b78, + 0xffffffff7c0307b4, + 0xffffffffe80100a0, + 0xffffffff38210090, 0xffffffff7c0803a6, - 0xffffffff38210070, 0xffffffff4e800020, - 0 + 0, }; - libmixer.AddFuncSub("mixerAAN", cellAANAddData_table1, "cellAANAddData(1)", cellAANAddData); + libmixer.AddFuncSub("surmxAAN", cellAANDisconnect_table, "cellAANDisconnect", cellAANDisconnect); static const u64 cellSurMixerCreate_table[] = { 0xffffffff2f830000, @@ -413,7 +432,7 @@ void libmixer_init() 0xffffffff382100b0, 0 }; - libmixer.AddFuncSub("surMixer", cellSurMixerCreate_table, "cellSurMixerCreate", cellSurMixerCreate); + libmixer.AddFuncSub("surmx___", cellSurMixerCreate_table, "cellSurMixerCreate", cellSurMixerCreate); static const u64 cellSurMixerGetAANHandle_table[] = { // first instruction ignored @@ -432,7 +451,7 @@ void libmixer_init() 0xffffffff4e800020, 0 }; - libmixer.AddFuncSub("surMixer", cellSurMixerGetAANHandle_table, "cellSurMixerGetAANHandle", cellSurMixerGetAANHandle); + libmixer.AddFuncSub("surmx___", cellSurMixerGetAANHandle_table, "cellSurMixerGetAANHandle", cellSurMixerGetAANHandle); static const u64 cellSurMixerChStripGetAANPortNo_table[] = { // first instruction ignored @@ -449,7 +468,7 @@ void libmixer_init() 0xf000000040000000, // b 0 }; - libmixer.AddFuncSub("surMixer", cellSurMixerChStripGetAANPortNo_table, "cellSurMixerChStripGetAANPortNo", cellSurMixerChStripGetAANPortNo); + libmixer.AddFuncSub("surmx___", cellSurMixerChStripGetAANPortNo_table, "cellSurMixerChStripGetAANPortNo", cellSurMixerChStripGetAANPortNo); static const u64 cellSurMixerSetNotifyCallback_table[] = { // first instruction ignored @@ -479,7 +498,7 @@ void libmixer_init() 0xffffffff7d234b78, 0 }; - libmixer.AddFuncSub("surMixer", cellSurMixerSetNotifyCallback_table, "cellSurMixerSetNotifyCallback", cellSurMixerSetNotifyCallback); + libmixer.AddFuncSub("surmx___", cellSurMixerSetNotifyCallback_table, "cellSurMixerSetNotifyCallback", cellSurMixerSetNotifyCallback); static const u64 cellSurMixerRemoveNotifyCallback_table[] = { // first instruction ignored @@ -489,9 +508,9 @@ void libmixer_init() 0xffffffff7c6a1b78, 0xffffffff3d208031, 0xffffffff806b0018, - 0xffffffff61290002, + 0xffffffff61290002, // ori 0xffffffff2f830000, - 0xf0000000409e0018, // bne + 0xffff0000409e0018, // bne 0xffffffffe8010090, 0xffffffff7d2307b4, 0xffffffff38210080, @@ -499,7 +518,7 @@ void libmixer_init() 0xffffffff4e800020, 0 }; - libmixer.AddFuncSub("surMixer", cellSurMixerRemoveNotifyCallback_table, "cellSurMixerRemoveNotifyCallback", cellSurMixerRemoveNotifyCallback); + libmixer.AddFuncSub("surmx___", cellSurMixerRemoveNotifyCallback_table, "cellSurMixerRemoveNotifyCallback", cellSurMixerRemoveNotifyCallback); static const u64 cellSurMixerStart_table[] = { 0xfffffffff821ff71, @@ -524,7 +543,7 @@ void libmixer_init() 0xffffffff4e800020, 0 }; - libmixer.AddFuncSub("surMixer", cellSurMixerStart_table, "cellSurMixerStart", cellSurMixerStart); + libmixer.AddFuncSub("surmx___", cellSurMixerStart_table, "cellSurMixerStart", cellSurMixerStart); static const u64 cellSurMixerSetParameter_table[] = { 0xfffffffff821ff81, @@ -556,7 +575,7 @@ void libmixer_init() 0xffff0000409d0054, // ble 0 }; - libmixer.AddFuncSub("surMixer", cellSurMixerSetParameter_table, "cellSurMixerSetParameter", cellSurMixerSetParameter); + libmixer.AddFuncSub("surmx___", cellSurMixerSetParameter_table, "cellSurMixerSetParameter", cellSurMixerSetParameter); static const u64 cellSurMixerFinalize_table[] = { 0xfffffffff821ff91, @@ -584,5 +603,147 @@ void libmixer_init() 0xffffffff4e800421, 0 }; - libmixer.AddFuncSub("surMixer", cellSurMixerFinalize_table, "cellSurMixerFinalize", cellSurMixerFinalize); + libmixer.AddFuncSub("surmx___", cellSurMixerFinalize_table, "cellSurMixerFinalize", cellSurMixerFinalize); + + static const u64 cellSurMixerSurBusAddData_table[] = { + // first instruction ignored + 0xffffffff7c0802a6, + 0xfffffffff821ff91, + 0xfffffffff8010080, + 0xffffffff7c601b78, + 0xffffffff3d208031, + 0xffffffff806a0018, + 0xffffffff7c8b2378, + 0xffffffff7cc73378, + 0xffffffff2f830000, + 0xffffffff61290002, + 0xffff0000409e0018, // bne + 0xffffffffe8010080, + 0xffffffff7d2307b4, + 0xffffffff38210070, + 0xffffffff7c0803a6, + 0xffffffff4e800020, + 0xffffffff78a40020, + 0xffffffff78050020, + 0xffffffff800a001c, + 0xffffffff78680020, + 0xffffffff2f800000, + 0xffffffff7d034378, + 0xffffffff79660020, + 0xffffffff78e70020, + 0xffff0000419cffcc, // blt + 0 + }; + libmixer.AddFuncSub("surmx___", cellSurMixerSurBusAddData_table, "cellSurMixerSurBusAddData", cellSurMixerSurBusAddData); + + static const u64 cellSurMixerChStripSetParameter_table[] = { + // first instruction ignored + 0xffffffff7c6b1b78, + 0xffffffff3c608031, + 0xffffffff7c8a2378, + 0xffffffff7ca62b78, + 0xffffffff60630002, + 0xffffffff81280018, + 0xffffffff2f890000, + 0xffff00004d9e0020, // beqlr + 0xffffffff8008001c, + 0xffffffff79640020, + 0xffffffff79450020, + 0xffffffff2f800000, + 0xffffffff78c60020, + 0xffffffff4d9c0020, + 0xffffffff79230020, + 0xf000000048000000, // b + 0 + }; + libmixer.AddFuncSub("surmx___", cellSurMixerChStripSetParameter_table, "cellSurMixerChStripSetParameter", cellSurMixerChStripSetParameter); + + static const u64 cellSurMixerPause_table[] = { + // first instruction ignored + 0xffffffff7c0802a6, + 0xfffffffff821ff81, + 0xfffffffff8010090, + 0xffffffff3d208031, + 0xfffffffffbe10078, + 0xffffffff800a0018, + 0xffffffff7c7f1b78, + 0xfffffffffbc10070, + 0xffffffff2f800000, + 0xffffffff61290002, + 0xffff0000409e0020, // bne + 0xffffffffe8010090, + 0xffffffff7d2307b4, + 0xffffffffebc10070, + 0xffffffffebe10078, + 0xffffffff7c0803a6, + 0xffffffff38210080, + 0xffffffff4e800020, + 0xffffffff800a001c, + 0xffffffff2b030002, + 0xffffffff2f800000, + 0 + }; + libmixer.AddFuncSub("surmx___", cellSurMixerPause_table, "cellSurMixerPause", cellSurMixerPause); + + static const u64 cellSurMixerGetCurrentBlockTag_table[] = { + // first instruction ignored + 0xffffffff3d208031, + 0xffffffff61290002, + 0xffffffff880b0020, + 0xffffffff2f800000, + 0xffff0000419e0010, // beq + 0xffffffffe80b0028, + 0xffffffff39200000, + 0xfffffffff8030000, + 0xffffffff7d2307b4, + 0xffffffff4e800020, + 0 + }; + libmixer.AddFuncSub("surmx___", cellSurMixerGetCurrentBlockTag_table, "cellSurMixerGetCurrentBlockTag", cellSurMixerGetCurrentBlockTag); + + static const u64 cellSurMixerGetTimestamp_table[] = { + // first instruction ignored + 0xffffffff7c0802a6, + 0xfffffffff821ff91, + 0xfffffffff8010080, + 0xffffffff7c852378, + 0xffffffff3d208031, + 0xffffffff880b0020, + 0xffffffff7c641b78, + 0xffffffff78a50020, + 0xffffffff2f800000, + 0xffffffff61290002, + 0xffff000040de0018, // bne- + 0xffffffffe8010080, + 0xffffffff7d2307b4, + 0xffffffff38210070, + 0xffffffff7c0803a6, + 0xffffffff4e800020, + 0xffffffff806b04d8, + 0xf000000048000001, // bl + 0 + }; + libmixer.AddFuncSub("surmx___", cellSurMixerGetTimestamp_table, "cellSurMixerGetTimestamp", cellSurMixerGetTimestamp); + + static const u64 cellSurMixerBeep_table[] = { + // first instruction ignored + 0xffffffff7c641b78, + 0xffffffff80690018, + 0xffffffff2f830000, + 0xffff00004d9e0020, // beqlr + 0xffffffff8009001c, + 0xffffffff78630020, + 0xffffffff78840020, + 0xffffffff2f800000, + 0xffffffff4d9c0020, + 0xf000000048000000, // b + 0 + }; + libmixer.AddFuncSub("surmx___", cellSurMixerBeep_table, "cellSurMixerBeep", cellSurMixerBeep); + + // TODO: SSPlayer functions + /*static const u64 cell_table[] = { + 0 + }; + libmixer.AddFuncSub("surmxSSP", cell_table, "cell", nullptr);*/ } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Static.cpp b/rpcs3/Emu/SysCalls/Static.cpp index 6a8369b701..d13bfa5273 100644 --- a/rpcs3/Emu/SysCalls/Static.cpp +++ b/rpcs3/Emu/SysCalls/Static.cpp @@ -5,7 +5,7 @@ extern ArrayF g_static_funcs_list; -void StaticAnalyse(void* ptr, u32 size) +void StaticAnalyse(void* ptr, u32 size, u32 base) { u32* data = (u32*)ptr; size /= 4; @@ -14,32 +14,78 @@ void StaticAnalyse(void* ptr, u32 size) { for (u32 j = 0; j < g_static_funcs_list.GetCount(); j++) { - if ((data[i] & g_static_funcs_list[j].ops[0].mask) == g_static_funcs_list[j].ops[0].crc && (i + g_static_funcs_list[j].ops.GetCount()) < size) + if ((data[i] & g_static_funcs_list[j].ops[0].mask) == g_static_funcs_list[j].ops[0].crc) { bool found = true; - for (u32 k = i + 1, x = 1; x < g_static_funcs_list[j].ops.GetCount(); k++, x++) + u32 can_skip = 0; + for (u32 k = i, x = 0; x + 1 <= g_static_funcs_list[j].ops.GetCount(); k++, x++) { - // skip NOP - if (data[k] == se32(0x60000000)) - { - k++; - continue; - } - - if ((data[k] & g_static_funcs_list[j].ops[x].mask) != g_static_funcs_list[j].ops[x].crc) + if (k >= size) { found = false; break; } + + // skip NOP + if (data[k] == se32(0x60000000)) + { + x--; + continue; + } + + const u32 mask = g_static_funcs_list[j].ops[x].mask; + const u32 crc = g_static_funcs_list[j].ops[x].crc; + + if (!mask) + { + // TODO: define syntax + if (crc < 4) // skip various number of instructions that don't match next pattern entry + { + can_skip += crc; + k--; // process this position again + } + else if (data[k] != crc) // skippable pattern ("optional" instruction), no mask allowed + { + k--; + if (can_skip) // cannot define this behaviour properly + { + ConLog.Warning("StaticAnalyse(): can_skip = %d (unchanged)", can_skip); + } + } + else + { + if (can_skip) // cannot define this behaviour properly + { + ConLog.Warning("StaticAnalyse(): can_skip = %d (set to 0)", can_skip); + can_skip = 0; + } + } + } + else if ((data[k] & mask) != crc) // masked pattern + { + if (can_skip) + { + can_skip--; + } + else + { + found = false; + break; + } + } + else + { + can_skip = 0; + } } if (found) { - //ConLog.Success("Function '%s' hooked", wxString(g_static_funcs_list[j].name).wx_str()); + ConLog.Write("Function '%s' hooked (addr=0x%x)", wxString(g_static_funcs_list[j].name).wx_str(), i * 4 + base); g_static_funcs_list[j].found++; - data[i] = re(0x39600000 | j); // li r11, j + data[i+0] = re32(0x39600000 | j); // li r11, j data[i+1] = se32(0x44000003); // sc 3 data[i+2] = se32(0x4e800020); // blr - i += 2; // ??? + i += 2; // skip modified code } } } @@ -54,8 +100,8 @@ void StaticAnalyse(void* ptr, u32 size) enum GroupSearchResult : u32 { - GSR_SUCCESS = 0, // every function from this group has been found - GSR_MISSING = 1, // (error) not every function found + GSR_SUCCESS = 0, // every function from this group has been found once + GSR_MISSING = 1, // (error) some function not found GSR_EXCESS = 2, // (error) some function found twice or more }; u32 res = GSR_SUCCESS; @@ -123,9 +169,9 @@ void StaticAnalyse(void* ptr, u32 size) } else { - ConLog.Error("Function group [%s] failed: %s%s", wxString(name, 9).wx_str(), - wxString(res & GSR_MISSING ? "missing;" : "").wx_str(), - wxString(res & GSR_EXCESS ? "excess;" : "").wx_str()); + ConLog.Error("Function group [%s] failed:%s%s", wxString(name, 9).wx_str(), + wxString(res & GSR_MISSING ? " missing;" : "").wx_str(), + wxString(res & GSR_EXCESS ? " excess;" : "").wx_str()); } } } diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index d182be1dc6..1050d00892 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -464,6 +464,6 @@ public: //extern SysCalls SysCallsManager; -void StaticAnalyse(void* ptr, u32 size); +void StaticAnalyse(void* ptr, u32 size, u32 base); void StaticExecute(u32 code); void StaticFinalize(); diff --git a/rpcs3/Gui/ConLog.cpp b/rpcs3/Gui/ConLog.cpp index 8047c3fbd5..e648652a7b 100644 --- a/rpcs3/Gui/ConLog.cpp +++ b/rpcs3/Gui/ConLog.cpp @@ -12,7 +12,7 @@ LogFrame* ConLogFrame; std::mutex g_cs_conlog; static const uint max_item_count = 500; -static const uint buffer_size = 1024 * 64; +static const uint buffer_size = 1024 * 64 * sizeof(wxChar); static const wxString g_log_colors[] = { diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index 6604d86d64..3cdbfd3d41 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -246,7 +246,7 @@ bool ELF64Loader::LoadPhdrData(u64 offset) { elf64_f.Seek(phdr_arr[i].p_offset); elf64_f.Read(&Memory[offset + phdr_arr[i].p_vaddr], phdr_arr[i].p_filesz); - StaticAnalyse(&Memory[offset + phdr_arr[i].p_vaddr], phdr_arr[i].p_filesz); + StaticAnalyse(&Memory[offset + phdr_arr[i].p_vaddr], phdr_arr[i].p_filesz, phdr_arr[i].p_vaddr); } } break; From fce074d812b87836dea43861619ab78ea541e8de Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 30 Mar 2014 15:59:55 +0400 Subject: [PATCH 07/14] Audio mixing fixed Libmixer reseen Some bugs fixed --- .gitignore | 1 - rpcs3/Emu/GS/GL/GLGSRender.h | 3 +- rpcs3/Emu/GS/RSXThread.cpp | 10 ++ rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 106 ++++++++++---------- rpcs3/Emu/SysCalls/Modules/libmixer.cpp | 117 +++++++++++++++++++---- rpcs3/Emu/SysCalls/Modules/libmixer.h | 6 +- rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp | 2 +- rpcs3/Loader/ELF32.cpp | 7 +- rpcs3/Loader/ELF64.cpp | 8 +- 9 files changed, 178 insertions(+), 82 deletions(-) diff --git a/.gitignore b/.gitignore index 07c7bb0da1..2e4c753253 100644 --- a/.gitignore +++ b/.gitignore @@ -57,5 +57,4 @@ rpcs3/git-version.h !/bin/dev_hdd0/game/TEST12345/ # Ignore other system generated files -bin/dev_hdd0/home/00000001/trophy bin/dev_hdd0/log.txt diff --git a/rpcs3/Emu/GS/GL/GLGSRender.h b/rpcs3/Emu/GS/GL/GLGSRender.h index e3ed1c35f8..37f8d8e41a 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.h +++ b/rpcs3/Emu/GS/GL/GLGSRender.h @@ -170,7 +170,8 @@ public: } break; - default: ConLog.Error("Init tex error: Bad tex format (0x%x | %s | 0x%x)", format, is_swizzled ? "swizzled" : "linear", tex.GetFormat() & 0x40); break; + default: ConLog.Error("Init tex error: Bad tex format (0x%x | %s | 0x%x)", format, + wxString(is_swizzled ? "swizzled" : "linear").wx_str(), tex.GetFormat() & 0x40); break; } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, tex.GetMipmap() - 1); diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index b161d8f0a7..43ff7272fe 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -949,7 +949,17 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3 case NV4097_SET_VIEWPORT_OFFSET: { + /*const u32 offset0 = ARGS(0); + const u32 offset1 = ARGS(1); + const u32 offset2 = ARGS(2); + const u32 offset3 = ARGS(3); + const u32 scale0 = ARGS(4); + const u32 scale1 = ARGS(5); + const u32 scale2 = ARGS(6); + const u32 scale3 = ARGS(7);*/ //TODO + //ConLog.Warning("NV4097_SET_VIEWPORT_OFFSET: offset (%d, %d, %d, %d), scale (%d, %d, %d, %d)", + //offset0, offset1, offset2, offset3, scale0, scale1, scale2, scale3); } break; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 9813fe763f..73f3d17984 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -38,8 +38,10 @@ int cellAudioInit() thread t("Audio Thread", []() { AudioDumper m_dump(2); // WAV file header (stereo) + + bool do_dump = Ini.AudioDumpToFile.GetValue(); - if (Ini.AudioDumpToFile.GetValue() && !m_dump.Init()) + if (do_dump && !m_dump.Init()) { ConLog.Error("Audio aborted: cannot create file!"); return; @@ -50,7 +52,7 @@ int cellAudioInit() if (Ini.AudioDumpToFile.GetValue()) m_dump.WriteHeader(); - float buffer[2*256]; // buffer for 2 channels + float buffer[2*256]; // intermediate buffer for 2 channels be_t buffer2[8*256]; // buffer for 8 channels (max count) //u16 oal_buffer[2*256]; // buffer for OpenAL memset(buffer, 0, sizeof(buffer)); @@ -79,7 +81,9 @@ int cellAudioInit() m_config.start_time = get_system_time(); - thread iat("Internal Audio Thread", [oal_buffer_size, &queue]() + volatile bool internal_finished = false; + + thread iat("Internal Audio Thread", [oal_buffer_size, &queue, &internal_finished]() { while (true) { @@ -92,7 +96,8 @@ int cellAudioInit() } else { - break; + internal_finished = true; + return; } } }); @@ -128,13 +133,12 @@ int cellAudioInit() bool first_mix = true; - // MIX: + // mixing: for (u32 i = 0; i < m_config.AUDIO_PORT_COUNT; i++) { if (!m_config.m_ports[i].m_is_audio_port_started) continue; AudioPortConfig& port = m_config.m_ports[i]; - mem64_t index(m_config.m_indexes + i * sizeof(u64)); const u32 block_size = port.channel * 256; @@ -145,28 +149,17 @@ int cellAudioInit() memcpy(buffer2, Memory + buf_addr, block_size * sizeof(float)); memset(Memory + buf_addr, 0, block_size * sizeof(float)); - { - SMutexGeneralLocker lock(audioMutex); - port.counter = m_config.counter; - port.tag++; // absolute index of block that will be read - index = (position + 1) % port.block; // write new value - } - const u32 k = port.channel / 2; if (first_mix) { for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) { - // reverse byte order (TODO: use port.m_param.level) + // reverse byte order buffer[i] = buffer2[i*k]; buffer[i+1] = buffer2[i*k+1]; - - // convert the data from float to u16 - //assert(buffer[i] >= -1.0f && buffer[i] <= 1.0f); - //assert(buffer[i+1] >= -1.0f && buffer[i+1] <= 1.0f); - oal_buffer[oal_pos][oal_buffer_offset + i] = (u16)(buffer[i] * ((1 << 14) - 1)); - oal_buffer[oal_pos][oal_buffer_offset + i + 1] = (u16)(buffer[i+1] * ((1 << 14) - 1)); + // TODO: use port.m_param.level + // TODO: downmix channels that are ignored (?) or implement surround sound } first_mix = false; @@ -175,34 +168,20 @@ int cellAudioInit() { for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) { - buffer[i] = (buffer[i] + buffer2[i*k]) * 0.5; // TODO: valid mixing - buffer[i+1] = (buffer[i+1] + buffer2[i*k+1]) * 0.5; - - // convert the data from float to u16 - //assert(buffer[i] >= -1.0f && buffer[i] <= 1.0f); - //assert(buffer[i+1] >= -1.0f && buffer[i+1] <= 1.0f); - oal_buffer[oal_pos][oal_buffer_offset + i] = (u16)(buffer[i] * ((1 << 14) - 1)); - oal_buffer[oal_pos][oal_buffer_offset + i + 1] = (u16)(buffer[i+1] * ((1 << 14) - 1)); + buffer[i] += buffer2[i*k]; + buffer[i+1] += buffer2[i*k+1]; } } } + // convert the data from float to u16 and clip: + for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) + { + oal_buffer[oal_pos][oal_buffer_offset + i] = (s16)(min(max(buffer[i] * 0x8000, -0x8000), 0x7fff)); + } + const u64 stamp1 = get_system_time(); - // send aftermix event (normal audio event) - { - SMutexGeneralLocker lock(audioMutex); - keys.SetCount(m_config.m_keys.GetCount()); - memcpy(keys.GetPtr(), m_config.m_keys.GetPtr(), sizeof(u64) * keys.GetCount()); - } - for (u32 i = 0; i < keys.GetCount(); i++) - { - // TODO: check event source - Emu.GetEventManager().SendEvent(keys[i], 0x10103000e010e07, 0, 0, 0); - } - - const u64 stamp2 = get_system_time(); - oal_buffer_offset += sizeof(buffer) / sizeof(float); if(oal_buffer_offset >= oal_buffer_size) @@ -215,9 +194,37 @@ int cellAudioInit() oal_buffer_offset = 0; } + const u64 stamp2 = get_system_time(); + + // send aftermix event (normal audio event) + { + SMutexGeneralLocker lock(audioMutex); + // update indexes: + for (u32 i = 0; i < m_config.AUDIO_PORT_COUNT; i++) + { + if (!m_config.m_ports[i].m_is_audio_port_started) continue; + + AudioPortConfig& port = m_config.m_ports[i]; + mem64_t index(m_config.m_indexes + i * sizeof(u64)); + + u32 position = port.tag % port.block; // old value + port.counter = m_config.counter; + port.tag++; // absolute index of block that will be read + index = (position + 1) % port.block; // write new value + } + // load keys: + keys.SetCount(m_config.m_keys.GetCount()); + memcpy(keys.GetPtr(), m_config.m_keys.GetPtr(), sizeof(u64) * keys.GetCount()); + } + for (u32 i = 0; i < keys.GetCount(); i++) + { + // TODO: check event source + Emu.GetEventManager().SendEvent(keys[i], 0x10103000e010e07, 0, 0, 0); + } + const u64 stamp3 = get_system_time(); - if(Ini.AudioDumpToFile.GetValue()) + if(do_dump) { if (m_dump.WriteData(&buffer, sizeof(buffer)) != sizeof(buffer)) // write file data { @@ -228,21 +235,24 @@ int cellAudioInit() const u64 stamp4 = get_system_time(); - //ConLog.Write("Audio perf: start=%d (access=%d, event=%d, AddData=%d, dump=%d)", + //ConLog.Write("Audio perf: start=%d (access=%d, AddData=%d, events=%d, dump=%d)", //stamp0 - m_config.start_time, stamp1-stamp0, stamp2-stamp1, stamp3-stamp2, stamp4-stamp3); } ConLog.Write("Audio finished"); abort: queue.Push(nullptr); - while (queue.GetCount()) + + if(do_dump) + m_dump.Finalize(); + + m_config.m_is_audio_initialized = false; + + while (!internal_finished) { Sleep(1); } - if(Ini.AudioDumpToFile.GetValue()) - m_dump.Finalize(); m_config.m_is_audio_finalized = true; - m_config.m_is_audio_initialized = false; }); t.detach(); diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp index 12d7728f42..d74d6b2bbf 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -12,13 +12,30 @@ CellSurMixerConfig surMixer; #define SUR_PORT (7) u32 surMixerCb = 0; u32 surMixerCbArg = 0; -u64 mixcount = 0, stamp1 = 0, stamp2 = 0; +SMutex mixer_mutex; +bool mixfirst; +float mixdata[2*256]; +u64 mixcount = 0; int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 samples) { - stamp1 = get_system_time(); + u32 ch = aan_port >> 16; + u32 port = aan_port & 0xffff; + switch (ch) + { + case 1: + if (port >= surMixer.chStrips1) ch = 0; break; + case 2: + if (port >= surMixer.chStrips2) ch = 0; break; + case 6: + if (port >= surMixer.chStrips6) ch = 0; break; + case 8: + if (port >= surMixer.chStrips8) ch = 0; break; + default: + ch = 0; + } - if (aan_handle == 0x11111111 && aan_port == (2 << 16)) + if (aan_handle == 0x11111111 && samples == 256 && ch && offset == 0) { libmixer.Log("cellAANAddData(handle=0x%x, port=0x%x, offset=0x%x, addr=0x%x, samples=0x%x)", aan_handle, aan_port, offset, addr, samples); @@ -31,16 +48,28 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl return CELL_OK; } - AudioPortConfig& port = m_config.m_ports[SUR_PORT]; + SMutexLocker lock(mixer_mutex); - u32 to = m_config.m_buffer + (128 * 1024 * SUR_PORT) + ((mixcount + 12) % 16) * 2 * 256 * sizeof(float) + offset; + const u32 k = ch / 2; - if (!Memory.Copy(to, addr, 2 * samples * sizeof(float))) + if (mixfirst) { - return CELL_LIBMIXER_ERROR_NO_MEMORY; + for (u32 i = 0; i < (sizeof(mixdata) / sizeof(float)); i += 2) + { + // reverse byte order and mix + mixdata[i] = *(be_t*)&Memory[addr + i * k * sizeof(float)]; + mixdata[i + 1] = *(be_t*)&Memory[addr + (i * k + 1) * sizeof(float)]; + } + mixfirst = false; + } + else + { + for (u32 i = 0; i < (sizeof(mixdata) / sizeof(float)); i += 2) + { + mixdata[i] += *(be_t*)&Memory[addr + i * k * sizeof(float)]; + mixdata[i + 1] += *(be_t*)&Memory[addr + (i * k + 1) * sizeof(float)]; + } } - - stamp2 = get_system_time(); return CELL_OK; } @@ -119,14 +148,14 @@ int cellSurMixerGetAANHandle(mem32_t handle) int cellSurMixerChStripGetAANPortNo(mem32_t port, u32 type, u32 index) { - libmixer.Warning("cellSurMixerChStripGetAANPortNo(port_addr=0x%x, type=0x%x, index=0x%x) -> 0", port.GetAddr(), type, index); + libmixer.Warning("cellSurMixerChStripGetAANPortNo(port_addr=0x%x, type=0x%x, index=0x%x) -> 0x%x", port.GetAddr(), type, index, (type << 16) | index); port = (type << 16) | index; return CELL_OK; } int cellSurMixerSetNotifyCallback(u32 func, u32 arg) { - libmixer.Warning("cellSurMixerSetNotifyCallback(func_addr=0x%x, arg=0x%x)", func, arg); + libmixer.Warning("cellSurMixerSetNotifyCallback(func_addr=0x%x, arg=0x%x) (surMixerCb=0x%x)", func, arg, surMixerCb); surMixerCb = func; surMixerCbArg = arg; return CELL_OK; @@ -134,7 +163,7 @@ int cellSurMixerSetNotifyCallback(u32 func, u32 arg) int cellSurMixerRemoveNotifyCallback(u32 func) { - libmixer.Warning("cellSurMixerSetNotifyCallback(func_addr=0x%x)", func); + libmixer.Warning("cellSurMixerSetNotifyCallback(func_addr=0x%x) (surMixerCb=0x%x)", func, surMixerCb); surMixerCb = 0; surMixerCbArg = 0; return CELL_OK; @@ -181,22 +210,38 @@ int cellSurMixerStart() return; } - if (mixcount > port.tag) + if (mixcount > (port.tag + 15)) // preemptive buffer filling (probably hack) { Sleep(1); continue; } u64 stamp0 = get_system_time(); - stamp1 = 0; - stamp2 = 0; + mixfirst = true; mixerCb->ExecAsCallback(surMixerCb, true, surMixerCbArg, mixcount, 256); - u64 stamp3 = get_system_time(); + u64 stamp1 = get_system_time(); - //ConLog.Write("Libmixer perf: start=%d (cb_before=%d, cb=%d, cb_after=%d)", - //stamp0 - m_config.start_time, stamp1-stamp0, stamp2-stamp1, stamp3-stamp2); + auto buf = (be_t*)&Memory[m_config.m_buffer + (128 * 1024 * SUR_PORT) + (mixcount % 16) * 2 * 256 * sizeof(float)]; + + if (!mixfirst) + { + for (u32 i = 0; i < (sizeof(mixdata) / sizeof(float)); i++) + { + // reverse byte order + buf[i] = mixdata[i]; + } + } + else + { + // no data? + } + + u64 stamp2 = get_system_time(); + + //ConLog.Write("Libmixer perf: start=%d (cb=%d, finalize=%d)", + //stamp0 - m_config.start_time, stamp1-stamp0, stamp2-stamp1); mixcount++; } @@ -229,7 +274,41 @@ int cellSurMixerFinalize() int cellSurMixerSurBusAddData(u32 busNo, u32 offset, u32 addr, u32 samples) { - libmixer.Error("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, samples); + if (busNo < 8 && samples == 256 && offset == 0) + { + libmixer.Log("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, samples); + } + else + { + libmixer.Error("cellSurMixerSurBusAddData(busNo=%d, offset=0x%x, addr=0x%x, samples=%d)", busNo, offset, addr, samples); + Emu.Pause(); + return CELL_OK; + } + + if (busNo > 1) // channels from 3 to 8 ignored (TODO) + { + return CELL_OK; + } + + SMutexLocker lock(mixer_mutex); + + if (mixfirst) + { + for (u32 i = 0; i < samples; i++) + { + // reverse byte order and mix + mixdata[i * 2 + busNo] = *(be_t*)&Memory[addr + i * sizeof(float)]; + } + mixfirst = false; + } + else + { + for (u32 i = 0; i < samples; i++) + { + mixdata[i * 2 + busNo] += *(be_t*)&Memory[addr + i * sizeof(float)]; + } + } + return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.h b/rpcs3/Emu/SysCalls/Modules/libmixer.h index fe56a85ab6..590e6e2110 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.h +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.h @@ -13,11 +13,7 @@ enum CELL_LIBMIXER_ERROR_NOT_FOUND = 0x8031000a, }; -//Callback Functions -typedef int (*CellSurMixerNotifyCallbackFunction)(void *arg, u32 counter, u32 samples); //Currently unused. - -//libmixer datatypes -typedef void * CellAANHandle; +typedef int (*CellSurMixerNotifyCallbackFunction)(void *arg, u32 counter, u32 samples); struct CellSSPlayerConfig { diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp index 99eb240644..0049df7810 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp @@ -28,7 +28,7 @@ int sys_lwmutex_create(mem_ptr_t lwmutex, mem_ptr_tattribute = attr->attr_protocol | attr->attr_recursive; - lwmutex->all_info() = ~0; + lwmutex->waiter = 0; lwmutex->mutex.initialize(); //lwmutex->waiter = lwmutex->owner.GetOwner(); lwmutex->pad = 0; diff --git a/rpcs3/Loader/ELF32.cpp b/rpcs3/Loader/ELF32.cpp index 10018c839d..9d7b3b84f2 100644 --- a/rpcs3/Loader/ELF32.cpp +++ b/rpcs3/Loader/ELF32.cpp @@ -175,15 +175,16 @@ bool ELF32Loader::LoadShdrInfo() for(u32 i=0; i name; while(!elf32_f.Eof()) { char c; elf32_f.Read(&c, 1); if(c == 0) break; - name += c; + name.AddCpy(c); } - shdr_name_arr.Add(name); + name.AddCpy('\0'); + shdr_name_arr.Add(wxString(name.GetPtr(), wxConvUTF8)); } return true; diff --git a/rpcs3/Loader/ELF64.cpp b/rpcs3/Loader/ELF64.cpp index 3cdbfd3d41..321e3723ed 100644 --- a/rpcs3/Loader/ELF64.cpp +++ b/rpcs3/Loader/ELF64.cpp @@ -176,16 +176,16 @@ bool ELF64Loader::LoadShdrInfo(s64 offset) for(u32 i=0; i name; while(!elf64_f.Eof()) { char c; elf64_f.Read(&c, 1); if(c == 0) break; - name += c; + name.AddCpy(c); } - - shdr_name_arr.Add(name); + name.AddCpy('\0'); + shdr_name_arr.Add(wxString(name.GetPtr(), wxConvUTF8)); } return true; From 9e2561d12175c8297cca7e3bf74d32c1d1a1514a Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Sun, 30 Mar 2014 22:53:43 +0400 Subject: [PATCH 08/14] Downmixing/upmixing --- rpcs3/Emu/GS/RSXThread.cpp | 2 +- rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 132 ++++++++++++++++------- rpcs3/Emu/SysCalls/Modules/libmixer.cpp | 118 ++++++++++---------- 3 files changed, 155 insertions(+), 97 deletions(-) diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index 43ff7272fe..af7402cab9 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -652,7 +652,7 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3 case NV4097_SET_SHADER_PROGRAM: { m_cur_shader_prog = &m_shader_progs[m_cur_shader_prog_num]; - m_cur_shader_prog_num = (m_cur_shader_prog_num + 1) % 16; + //m_cur_shader_prog_num = (m_cur_shader_prog_num + 1) % 16; u32 a0 = ARGS(0); m_cur_shader_prog->offset = a0 & ~0x3; m_cur_shader_prog->addr = GetAddress(m_cur_shader_prog->offset, (a0 & 0x3) - 1); diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 73f3d17984..ddd8fb6079 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -53,13 +53,9 @@ int cellAudioInit() m_dump.WriteHeader(); float buffer[2*256]; // intermediate buffer for 2 channels - be_t buffer2[8*256]; // buffer for 8 channels (max count) - //u16 oal_buffer[2*256]; // buffer for OpenAL - memset(buffer, 0, sizeof(buffer)); - memset(buffer2, 0, sizeof(buffer2)); uint oal_buffer_offset = 0; - uint oal_buffer_size = 2 * 256; + uint oal_buffer_size = sizeof(buffer) / sizeof(float); std::unique_ptr oal_buffer[32]; SQueue queue; for (u32 i = 0; i < queue.GetSize(); i++) @@ -68,8 +64,6 @@ int cellAudioInit() memset(oal_buffer[i].get(), 0, oal_buffer_size * sizeof(u16)); } queue.Clear(); - //std::unique_ptr oal_buf(new u16[oal_buffer_size]); - //memset(oal_buffer.get(), 0, oal_buffer_size * sizeof(u16)); Array keys; @@ -141,57 +135,103 @@ int cellAudioInit() AudioPortConfig& port = m_config.m_ports[i]; const u32 block_size = port.channel * 256; + const u32 position = port.tag % port.block; // old value + const u32 buf_addr = m_config.m_buffer + (i * 128 * 1024) + (position * block_size * sizeof(float)); - u32 position = port.tag % port.block; // old value + auto buf = (be_t*)&Memory[buf_addr]; - u32 buf_addr = m_config.m_buffer + (i * 128 * 1024) + (position * block_size * sizeof(float)); - - memcpy(buffer2, Memory + buf_addr, block_size * sizeof(float)); - memset(Memory + buf_addr, 0, block_size * sizeof(float)); - - const u32 k = port.channel / 2; - - if (first_mix) + if (port.channel == 2) { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + if (first_mix) { - // reverse byte order - buffer[i] = buffer2[i*k]; - buffer[i+1] = buffer2[i*k+1]; - // TODO: use port.m_param.level - // TODO: downmix channels that are ignored (?) or implement surround sound + for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) + { + // reverse byte order + buffer[i] = buf[i]; + // TODO: use port.m_param.level + } + first_mix = false; } - - first_mix = false; - } - else - { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + else { - buffer[i] += buffer2[i*k]; - buffer[i+1] += buffer2[i*k+1]; + for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) + { + buffer[i] += buf[i]; + } } } + else if (port.channel == 6) + { + if (first_mix) + { + for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + { + const float center = (buf[i*3+2] + buf[i*3+3]) * 0.708f; + buffer[i] = (buf[i*3] + buf[i*3+4] + center) * 0.5f; + buffer[i+1] = (buf[i*3+1] + buf[i*3+5] + center) * 0.5f; + } + first_mix = false; + } + else + { + for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + { + const float center = (buf[i*3+2] + buf[i*3+3]) * 0.708f; + buffer[i] += (buf[i*3] + buf[i*3+4] + center) * 0.5f; + buffer[i+1] += (buf[i*3+1] + buf[i*3+5] + center) * 0.5f; + } + } + } + else if (port.channel == 8) + { + if (first_mix) + { + for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + { + const float center = (buf[i*4+2] + buf[i*4+3]) * 0.708f; + buffer[i] = (buf[i*4] + buf[i*4+4] + buf[i*4+6] + center) * 0.5f; + buffer[i+1] = (buf[i*4+1] + buf[i*4+5] + buf[i*4+7] + center) * 0.5f; + } + first_mix = false; + } + else + { + for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + { + const float center = (buf[i*4+2] + buf[i*4+3]) * 0.708f; + buffer[i] += (buf[i*4] + buf[i*4+4] + buf[i*4+6] + center) * 0.5f; + buffer[i+1] += (buf[i*4+1] + buf[i*4+5] + buf[i*4+7] + center) * 0.5f; + } + } + } + + memset(buf, 0, block_size * sizeof(float)); } // convert the data from float to u16 and clip: - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) + if (!first_mix) { - oal_buffer[oal_pos][oal_buffer_offset + i] = (s16)(min(max(buffer[i] * 0x8000, -0x8000), 0x7fff)); + for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) + { + oal_buffer[oal_pos][oal_buffer_offset + i] = (s16)(min(max(buffer[i] * 0x8000, -0x8000), 0x7fff)); + } } const u64 stamp1 = get_system_time(); - oal_buffer_offset += sizeof(buffer) / sizeof(float); - - if(oal_buffer_offset >= oal_buffer_size) + if (!first_mix) { - if(m_audio_out) - { - queue.Push(&oal_buffer[oal_pos][0]); - } + oal_buffer_offset += sizeof(buffer) / sizeof(float); - oal_buffer_offset = 0; + if(oal_buffer_offset >= oal_buffer_size) + { + if(m_audio_out) + { + queue.Push(&oal_buffer[oal_pos][0]); + } + + oal_buffer_offset = 0; + } } const u64 stamp2 = get_system_time(); @@ -224,7 +264,7 @@ int cellAudioInit() const u64 stamp3 = get_system_time(); - if(do_dump) + if (do_dump && !first_mix) { if (m_dump.WriteData(&buffer, sizeof(buffer)) != sizeof(buffer)) // write file data { @@ -247,6 +287,15 @@ abort: m_config.m_is_audio_initialized = false; + m_config.m_keys.Clear(); + for (u32 i = 0; i < m_config.AUDIO_PORT_COUNT; i++) + { + AudioPortConfig& port = m_config.m_ports[i]; + port.m_is_audio_port_opened = false; + port.m_is_audio_port_started = false; + } + m_config.m_port_in_use = 0; + while (!internal_finished) { Sleep(1); @@ -418,6 +467,7 @@ int cellAudioPortClose(u32 portNum) } m_config.m_ports[portNum].m_is_audio_port_started = false; + m_config.m_ports[portNum].m_is_audio_port_opened = false; m_config.m_port_in_use--; return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp index d74d6b2bbf..10b8037b59 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -13,8 +13,7 @@ CellSurMixerConfig surMixer; u32 surMixerCb = 0; u32 surMixerCbArg = 0; SMutex mixer_mutex; -bool mixfirst; -float mixdata[2*256]; +float mixdata[8*256]; u64 mixcount = 0; int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 samples) @@ -28,11 +27,11 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl case 2: if (port >= surMixer.chStrips2) ch = 0; break; case 6: - if (port >= surMixer.chStrips6) ch = 0; break; + /*if (port >= surMixer.chStrips6)*/ ch = 0; break; case 8: if (port >= surMixer.chStrips8) ch = 0; break; default: - ch = 0; + ch = 0; break; } if (aan_handle == 0x11111111 && samples == 256 && ch && offset == 0) @@ -50,24 +49,52 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl SMutexLocker lock(mixer_mutex); - const u32 k = ch / 2; - - if (mixfirst) + if (ch == 1) { - for (u32 i = 0; i < (sizeof(mixdata) / sizeof(float)); i += 2) + // mono upmixing + for (u32 i = 0; i < samples; i++) { - // reverse byte order and mix - mixdata[i] = *(be_t*)&Memory[addr + i * k * sizeof(float)]; - mixdata[i + 1] = *(be_t*)&Memory[addr + (i * k + 1) * sizeof(float)]; - } - mixfirst = false; + const float center = *(be_t*)&Memory[addr + i * sizeof(float)]; + mixdata[i*8+0] += center * 2; + mixdata[i*8+1] += center * 2; + } } - else + else if (ch == 2) { - for (u32 i = 0; i < (sizeof(mixdata) / sizeof(float)); i += 2) + // stereo upmixing + for (u32 i = 0; i < samples; i++) { - mixdata[i] += *(be_t*)&Memory[addr + i * k * sizeof(float)]; - mixdata[i + 1] += *(be_t*)&Memory[addr + (i * k + 1) * sizeof(float)]; + const float left = *(be_t*)&Memory[addr + i * 2 * sizeof(float)]; + const float right = *(be_t*)&Memory[addr + (i * 2 + 1) * sizeof(float)]; + mixdata[i*8+0] += left * 2; + mixdata[i*8+1] += right * 2; + } + } + else if (ch == 6) + { + // 5.1 upmixing + for (u32 i = 0; i < samples; i++) + { + const float left = *(be_t*)&Memory[addr + i * 6 * sizeof(float)]; + const float right = *(be_t*)&Memory[addr + (i * 6 + 1) * sizeof(float)]; + const float center = *(be_t*)&Memory[addr + (i * 6 + 2) * sizeof(float)]; + const float low_freq = *(be_t*)&Memory[addr + (i * 6 + 3) * sizeof(float)]; + const float rear_left = *(be_t*)&Memory[addr + (i * 6 + 4) * sizeof(float)]; + const float rear_right = *(be_t*)&Memory[addr + (i * 6 + 5) * sizeof(float)]; + mixdata[i*8+0] += left; + mixdata[i*8+1] += right; + mixdata[i*8+2] += center; + mixdata[i*8+3] += low_freq; + mixdata[i*8+4] += rear_left; + mixdata[i*8+5] += rear_right; + } + } + else if (ch == 8) + { + // 7.1 + for (u32 i = 0; i < samples * 8; i++) + { + mixdata[i] += *(be_t*)&Memory[addr + i * sizeof(float)]; } } @@ -180,7 +207,7 @@ int cellSurMixerStart() return CELL_LIBMIXER_ERROR_FULL; } - port.channel = 2; + port.channel = 8; port.block = 16; port.attr = 0; port.level = 1.0f; @@ -218,24 +245,17 @@ int cellSurMixerStart() u64 stamp0 = get_system_time(); - mixfirst = true; + memset(mixdata, 0, sizeof(mixdata)); mixerCb->ExecAsCallback(surMixerCb, true, surMixerCbArg, mixcount, 256); u64 stamp1 = get_system_time(); - auto buf = (be_t*)&Memory[m_config.m_buffer + (128 * 1024 * SUR_PORT) + (mixcount % 16) * 2 * 256 * sizeof(float)]; + auto buf = (be_t*)&Memory[m_config.m_buffer + (128 * 1024 * SUR_PORT) + (mixcount % port.block) * port.channel * 256 * sizeof(float)]; - if (!mixfirst) + for (u32 i = 0; i < (sizeof(mixdata) / sizeof(float)); i++) { - for (u32 i = 0; i < (sizeof(mixdata) / sizeof(float)); i++) - { - // reverse byte order - buf[i] = mixdata[i]; - } - } - else - { - // no data? + // reverse byte order + buf[i] = mixdata[i]; } u64 stamp2 = get_system_time(); @@ -255,7 +275,7 @@ int cellSurMixerStart() int cellSurMixerSetParameter(u32 param, float value) { - libmixer.Warning("cellSurMixerSetParameter(param=0x%x, value=%f)", param, value); + libmixer.Error("cellSurMixerSetParameter(param=0x%x, value=%f)", param, value); return CELL_OK; } @@ -265,9 +285,12 @@ int cellSurMixerFinalize() AudioPortConfig& port = m_config.m_ports[SUR_PORT]; - port.m_is_audio_port_started = false; - port.m_is_audio_port_opened = false; - m_config.m_port_in_use--; + if (port.m_is_audio_port_opened) + { + port.m_is_audio_port_started = false; + port.m_is_audio_port_opened = false; + m_config.m_port_in_use--; + } return CELL_OK; } @@ -284,29 +307,14 @@ int cellSurMixerSurBusAddData(u32 busNo, u32 offset, u32 addr, u32 samples) Emu.Pause(); return CELL_OK; } - - if (busNo > 1) // channels from 3 to 8 ignored (TODO) - { - return CELL_OK; - } SMutexLocker lock(mixer_mutex); - if (mixfirst) + for (u32 i = 0; i < samples; i++) { - for (u32 i = 0; i < samples; i++) - { - // reverse byte order and mix - mixdata[i * 2 + busNo] = *(be_t*)&Memory[addr + i * sizeof(float)]; - } - mixfirst = false; - } - else - { - for (u32 i = 0; i < samples; i++) - { - mixdata[i * 2 + busNo] += *(be_t*)&Memory[addr + i * sizeof(float)]; - } + // reverse byte order and mix + u32 v = Memory.Read32(addr + i * sizeof(float)); + mixdata[i*8+busNo] += (float&)v; } return CELL_OK; @@ -685,7 +693,7 @@ void libmixer_init() libmixer.AddFuncSub("surmx___", cellSurMixerFinalize_table, "cellSurMixerFinalize", cellSurMixerFinalize); static const u64 cellSurMixerSurBusAddData_table[] = { - // first instruction ignored + 0xff00000081428250, 0xffffffff7c0802a6, 0xfffffffff821ff91, 0xfffffffff8010080, @@ -716,7 +724,7 @@ void libmixer_init() libmixer.AddFuncSub("surmx___", cellSurMixerSurBusAddData_table, "cellSurMixerSurBusAddData", cellSurMixerSurBusAddData); static const u64 cellSurMixerChStripSetParameter_table[] = { - // first instruction ignored + 0xff00000081028250, 0xffffffff7c6b1b78, 0xffffffff3c608031, 0xffffffff7c8a2378, From 9afbbfad0a04f89eb85bff623f6c60f3bf338460 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Mon, 31 Mar 2014 10:19:51 +0400 Subject: [PATCH 09/14] Little fix --- rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 24 +- rpcs3/Emu/SysCalls/Modules/cellSpurs.h | 482 +++++++++++------------ rpcs3/Emu/SysCalls/Modules/libmixer.cpp | 8 +- 3 files changed, 258 insertions(+), 256 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index ddd8fb6079..25c9f7c41c 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -140,6 +140,9 @@ int cellAudioInit() auto buf = (be_t*)&Memory[buf_addr]; + static const float k = 1.0f; + const float m = (port.level == 0.0f) ? 1.0f : port.level; + if (port.channel == 2) { if (first_mix) @@ -147,8 +150,7 @@ int cellAudioInit() for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) { // reverse byte order - buffer[i] = buf[i]; - // TODO: use port.m_param.level + buffer[i] = buf[i] * m; } first_mix = false; } @@ -156,7 +158,7 @@ int cellAudioInit() { for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) { - buffer[i] += buf[i]; + buffer[i] += buf[i] * m; } } } @@ -167,8 +169,8 @@ int cellAudioInit() for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) { const float center = (buf[i*3+2] + buf[i*3+3]) * 0.708f; - buffer[i] = (buf[i*3] + buf[i*3+4] + center) * 0.5f; - buffer[i+1] = (buf[i*3+1] + buf[i*3+5] + center) * 0.5f; + buffer[i] = (buf[i*3] + buf[i*3+4] + center) * k * m; + buffer[i+1] = (buf[i*3+1] + buf[i*3+5] + center) * k * m; } first_mix = false; } @@ -177,8 +179,8 @@ int cellAudioInit() for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) { const float center = (buf[i*3+2] + buf[i*3+3]) * 0.708f; - buffer[i] += (buf[i*3] + buf[i*3+4] + center) * 0.5f; - buffer[i+1] += (buf[i*3+1] + buf[i*3+5] + center) * 0.5f; + buffer[i] += (buf[i*3] + buf[i*3+4] + center) * k * m; + buffer[i+1] += (buf[i*3+1] + buf[i*3+5] + center) * k * m; } } } @@ -189,8 +191,8 @@ int cellAudioInit() for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) { const float center = (buf[i*4+2] + buf[i*4+3]) * 0.708f; - buffer[i] = (buf[i*4] + buf[i*4+4] + buf[i*4+6] + center) * 0.5f; - buffer[i+1] = (buf[i*4+1] + buf[i*4+5] + buf[i*4+7] + center) * 0.5f; + buffer[i] = (buf[i*4] + buf[i*4+4] + buf[i*4+6] + center) * k * m; + buffer[i+1] = (buf[i*4+1] + buf[i*4+5] + buf[i*4+7] + center) * k * m; } first_mix = false; } @@ -199,8 +201,8 @@ int cellAudioInit() for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) { const float center = (buf[i*4+2] + buf[i*4+3]) * 0.708f; - buffer[i] += (buf[i*4] + buf[i*4+4] + buf[i*4+6] + center) * 0.5f; - buffer[i+1] += (buf[i*4+1] + buf[i*4+5] + buf[i*4+7] + center) * 0.5f; + buffer[i] += (buf[i*4] + buf[i*4+4] + buf[i*4+6] + center) * k * m; + buffer[i+1] += (buf[i*4+1] + buf[i*4+5] + buf[i*4+7] + center) * k * m; } } } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h index a72e3f2816..c18732669e 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSpurs.h +++ b/rpcs3/Emu/SysCalls/Modules/cellSpurs.h @@ -1,244 +1,244 @@ -#pragma once -#include "Emu/Cell/SPURSManager.h" - -// Core return codes. -enum -{ - CELL_SPURS_CORE_ERROR_AGAIN = 0x80410701, - CELL_SPURS_CORE_ERROR_INVAL = 0x80410702, - CELL_SPURS_CORE_ERROR_NOMEM = 0x80410704, - CELL_SPURS_CORE_ERROR_SRCH = 0x80410705, - CELL_SPURS_CORE_ERROR_PERM = 0x80410709, - CELL_SPURS_CORE_ERROR_BUSY = 0x8041070A, - CELL_SPURS_CORE_ERROR_STAT = 0x8041070F, - CELL_SPURS_CORE_ERROR_ALIGN = 0x80410710, - CELL_SPURS_CORE_ERROR_NULL_POINTER = 0x80410711, -}; - -// Task return codes. -enum -{ - CELL_SPURS_TASK_ERROR_AGAIN = 0x80410901, - CELL_SPURS_TASK_ERROR_INVAL = 0x80410902, - CELL_SPURS_TASK_ERROR_NOMEM = 0x80410904, - CELL_SPURS_TASK_ERROR_SRCH = 0x80410905, - CELL_SPURS_TASK_ERROR_NOEXEC = 0x80410907, - CELL_SPURS_TASK_ERROR_PERM = 0x80410909, - CELL_SPURS_TASK_ERROR_BUSY = 0x8041090A, - CELL_SPURS_TASK_ERROR_FAULT = 0x8041090D, - CELL_SPURS_TASK_ERROR_STAT = 0x8041090F, - CELL_SPURS_TASK_ERROR_ALIGN = 0x80410910, - CELL_SPURS_TASK_ERROR_NULL_POINTER = 0x80410911, - CELL_SPURS_TASK_ERROR_FATAL = 0x80410914, - CELL_SPURS_TASK_ERROR_SHUTDOWN = 0x80410920, -}; - -// Core CellSpurs structures. -struct CellSpurs -{ - SPURSManager *spurs; -}; - -struct CellSpurs2 -{ - SPURSManager *spurs; -}; - -struct CellSpursAttribute -{ - SPURSManagerAttribute *attr; -}; - -struct CellSpursInfo -{ - be_t nSpus; - be_t spuThreadGroupPriority; - be_t ppuThreadPriority; - bool exitIfNoWork; - bool spurs2; - be_t traceBuffer_addr; //void *traceBuffer; - be_t traceBufferSize; - be_t traceMode; - be_t spuThreadGroup; //typedef u32 sys_spu_thread_group_t; - be_t spuThreads[8]; //typedef u32 sys_spu_thread_t; - be_t spursHandlerThread0; - be_t spursHandlerThread1; - char namePrefix[CELL_SPURS_NAME_MAX_LENGTH+1]; - be_t namePrefixLength; - be_t deadlineMissCounter; - be_t deadlineMeetCounter; - //u8 padding[]; -}; - -struct CellSpursExceptionInfo -{ - be_t spu_thread; - be_t spu_npc; - be_t cause; - be_t option; -}; - -struct CellSpursTraceInfo -{ - be_t spu_thread[8]; - be_t count[8]; - be_t spu_thread_grp; - be_t nspu; - //u8 padding[]; -}; - -struct CellTraceHeader -{ - u8 tag; - u8 length; - u8 cpu; - u8 thread; - be_t time; -}; - -struct CellSpursTracePacket -{ - struct header_struct - { - u8 tag; - u8 length; - u8 spu; - u8 workload; - be_t time; - } header; - - struct data_struct - { - struct load_struct - { - be_t ea; - be_t ls; - be_t size; - } load; - - struct map_struct - { - be_t offset; - be_t ls; - be_t size; - } map; - - struct start_struct - { - char module[4]; - be_t level; - be_t ls; - } start; - - be_t user; - be_t guid; - } data; -}; - -// cellSpurs taskset structures. -struct CellSpursTaskset -{ - u8 skip[6400]; -}; - -// Exception handlers. -typedef void (*CellSpursGlobalExceptionEventHandler)(mem_ptr_t spurs, const mem_ptr_t info, - uint id, mem_ptr_t arg); - -typedef void (*CellSpursTasksetExceptionEventHandler)(mem_ptr_t spurs, mem_ptr_t taskset, - uint idTask, const mem_ptr_t info, mem_ptr_t arg); - -struct CellSpursTasksetInfo -{ - //CellSpursTaskInfo taskInfo[CELL_SPURS_MAX_TASK]; - be_t argument; - be_t idWorkload; - be_t idLastScheduledTask; //typedef unsigned CellSpursTaskId - be_t name_addr; - CellSpursTasksetExceptionEventHandler exceptionEventHandler; - be_t exceptionEventHandlerArgument_addr; //void *exceptionEventHandlerArgument - be_t sizeTaskset; - //be_t reserved[]; -}; - -struct CellSpursTaskset2 -{ - be_t skip[10496]; -}; - -struct CellSpursTasksetAttribute2 -{ - be_t revision; - be_t name_addr; - be_t argTaskset; - u8 priority[8]; - be_t maxContention; - be_t enableClearLs; - be_t CellSpursTaskNameBuffer_addr; //??? *taskNameBuffer - //be_t __reserved__[]; -}; - -// cellSpurs task structures. -struct CellSpursTaskNameBuffer -{ - char taskName[CELL_SPURS_MAX_TASK][CELL_SPURS_MAX_TASK_NAME_LENGTH]; -}; - -struct CellSpursTraceTaskData -{ - be_t incident; - be_t task; -}; - -struct CellSpursTaskArgument -{ - be_t u32[4]; - be_t u64[2]; -}; - -struct CellSpursTaskLsPattern -{ - be_t u32[4]; - be_t u64[2]; -}; - -struct CellSpursTaskAttribute2 -{ - be_t revision; - be_t sizeContext; - be_t eaContext; - CellSpursTaskLsPattern lsPattern; //??? - be_t name_addr; - //be_t __reserved__[]; -}; - -struct CellSpursTaskExitCode -{ - unsigned char skip[128]; -}; - -struct CellSpursTaskInfo -{ - CellSpursTaskLsPattern lsPattern; - CellSpursTaskArgument argument; - const be_t eaElf_addr; //void *eaElf - const be_t eaContext_addr; //void *eaContext - be_t sizeContext; - be_t state; - be_t hasSignal; - const be_t CellSpursTaskExitCode_addr; - u8 guid[8]; - //be_t reserved[]; -}; - -struct CellSpursTaskBinInfo -{ - be_t eaElf; - be_t sizeContext; - be_t __reserved__; - CellSpursTaskLsPattern lsPattern; -}; - +#pragma once +#include "Emu/Cell/SPURSManager.h" + +// Core return codes. +enum +{ + CELL_SPURS_CORE_ERROR_AGAIN = 0x80410701, + CELL_SPURS_CORE_ERROR_INVAL = 0x80410702, + CELL_SPURS_CORE_ERROR_NOMEM = 0x80410704, + CELL_SPURS_CORE_ERROR_SRCH = 0x80410705, + CELL_SPURS_CORE_ERROR_PERM = 0x80410709, + CELL_SPURS_CORE_ERROR_BUSY = 0x8041070A, + CELL_SPURS_CORE_ERROR_STAT = 0x8041070F, + CELL_SPURS_CORE_ERROR_ALIGN = 0x80410710, + CELL_SPURS_CORE_ERROR_NULL_POINTER = 0x80410711, +}; + +// Task return codes. +enum +{ + CELL_SPURS_TASK_ERROR_AGAIN = 0x80410901, + CELL_SPURS_TASK_ERROR_INVAL = 0x80410902, + CELL_SPURS_TASK_ERROR_NOMEM = 0x80410904, + CELL_SPURS_TASK_ERROR_SRCH = 0x80410905, + CELL_SPURS_TASK_ERROR_NOEXEC = 0x80410907, + CELL_SPURS_TASK_ERROR_PERM = 0x80410909, + CELL_SPURS_TASK_ERROR_BUSY = 0x8041090A, + CELL_SPURS_TASK_ERROR_FAULT = 0x8041090D, + CELL_SPURS_TASK_ERROR_STAT = 0x8041090F, + CELL_SPURS_TASK_ERROR_ALIGN = 0x80410910, + CELL_SPURS_TASK_ERROR_NULL_POINTER = 0x80410911, + CELL_SPURS_TASK_ERROR_FATAL = 0x80410914, + CELL_SPURS_TASK_ERROR_SHUTDOWN = 0x80410920, +}; + +// Core CellSpurs structures. +struct CellSpurs +{ + SPURSManager *spurs; +}; + +struct CellSpurs2 +{ + SPURSManager *spurs; +}; + +struct CellSpursAttribute +{ + SPURSManagerAttribute *attr; +}; + +struct CellSpursInfo +{ + be_t nSpus; + be_t spuThreadGroupPriority; + be_t ppuThreadPriority; + bool exitIfNoWork; + bool spurs2; + be_t traceBuffer_addr; //void *traceBuffer; + be_t traceBufferSize; + be_t traceMode; + be_t spuThreadGroup; //typedef u32 sys_spu_thread_group_t; + be_t spuThreads[8]; //typedef u32 sys_spu_thread_t; + be_t spursHandlerThread0; + be_t spursHandlerThread1; + char namePrefix[CELL_SPURS_NAME_MAX_LENGTH+1]; + be_t namePrefixLength; + be_t deadlineMissCounter; + be_t deadlineMeetCounter; + //u8 padding[]; +}; + +struct CellSpursExceptionInfo +{ + be_t spu_thread; + be_t spu_npc; + be_t cause; + be_t option; +}; + +struct CellSpursTraceInfo +{ + be_t spu_thread[8]; + be_t count[8]; + be_t spu_thread_grp; + be_t nspu; + //u8 padding[]; +}; + +struct CellTraceHeader +{ + u8 tag; + u8 length; + u8 cpu; + u8 thread; + be_t time; +}; + +struct CellSpursTracePacket +{ + struct header_struct + { + u8 tag; + u8 length; + u8 spu; + u8 workload; + be_t time; + } header; + + struct data_struct + { + struct load_struct + { + be_t ea; + be_t ls; + be_t size; + } load; + + struct map_struct + { + be_t offset; + be_t ls; + be_t size; + } map; + + struct start_struct + { + char module[4]; + be_t level; + be_t ls; + } start; + + be_t user; + be_t guid; + } data; +}; + +// cellSpurs taskset structures. +struct CellSpursTaskset +{ + u8 skip[6400]; +}; + +// Exception handlers. +typedef void (*CellSpursGlobalExceptionEventHandler)(mem_ptr_t spurs, const mem_ptr_t info, + uint id, mem_ptr_t arg); + +typedef void (*CellSpursTasksetExceptionEventHandler)(mem_ptr_t spurs, mem_ptr_t taskset, + uint idTask, const mem_ptr_t info, mem_ptr_t arg); + +struct CellSpursTasksetInfo +{ + //CellSpursTaskInfo taskInfo[CELL_SPURS_MAX_TASK]; + be_t argument; + be_t idWorkload; + be_t idLastScheduledTask; //typedef unsigned CellSpursTaskId + be_t name_addr; + CellSpursTasksetExceptionEventHandler exceptionEventHandler; + be_t exceptionEventHandlerArgument_addr; //void *exceptionEventHandlerArgument + be_t sizeTaskset; + //be_t reserved[]; +}; + +struct CellSpursTaskset2 +{ + be_t skip[10496]; +}; + +struct CellSpursTasksetAttribute2 +{ + be_t revision; + be_t name_addr; + be_t argTaskset; + u8 priority[8]; + be_t maxContention; + be_t enableClearLs; + be_t CellSpursTaskNameBuffer_addr; //??? *taskNameBuffer + //be_t __reserved__[]; +}; + +// cellSpurs task structures. +struct CellSpursTaskNameBuffer +{ + char taskName[CELL_SPURS_MAX_TASK][CELL_SPURS_MAX_TASK_NAME_LENGTH]; +}; + +struct CellSpursTraceTaskData +{ + be_t incident; + be_t task; +}; + +struct CellSpursTaskArgument +{ + be_t u32[4]; + be_t u64[2]; +}; + +struct CellSpursTaskLsPattern +{ + be_t u32[4]; + be_t u64[2]; +}; + +struct CellSpursTaskAttribute2 +{ + be_t revision; + be_t sizeContext; + be_t eaContext; + CellSpursTaskLsPattern lsPattern; //??? + be_t name_addr; + //be_t __reserved__[]; +}; + +struct CellSpursTaskExitCode +{ + unsigned char skip[128]; +}; + +struct CellSpursTaskInfo +{ + CellSpursTaskLsPattern lsPattern; + CellSpursTaskArgument argument; + const be_t eaElf_addr; //void *eaElf + const be_t eaContext_addr; //void *eaContext + be_t sizeContext; + be_t state; + be_t hasSignal; + const be_t CellSpursTaskExitCode_addr; + u8 guid[8]; + //be_t reserved[]; +}; + +struct CellSpursTaskBinInfo +{ + be_t eaElf; + be_t sizeContext; + be_t __reserved__; + CellSpursTaskLsPattern lsPattern; +}; + // cellSpurs event flag. struct CellSpursEventFlag { u8 skip[128]; diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp index 10b8037b59..48487f52ad 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -55,8 +55,8 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl for (u32 i = 0; i < samples; i++) { const float center = *(be_t*)&Memory[addr + i * sizeof(float)]; - mixdata[i*8+0] += center * 2; - mixdata[i*8+1] += center * 2; + mixdata[i*8+0] += center; + mixdata[i*8+1] += center; } } else if (ch == 2) @@ -66,8 +66,8 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl { const float left = *(be_t*)&Memory[addr + i * 2 * sizeof(float)]; const float right = *(be_t*)&Memory[addr + (i * 2 + 1) * sizeof(float)]; - mixdata[i*8+0] += left * 2; - mixdata[i*8+1] += right * 2; + mixdata[i*8+0] += left; + mixdata[i*8+1] += right; } } else if (ch == 6) From d2ca1cc25a2593f05a072e7cf816bb28457f45dc Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 2 Apr 2014 00:04:56 +0400 Subject: [PATCH 10/14] Audio sync fix Libmixer: SSPlayer draft Detection fixed Macros for function substitute registration --- rpcs3/Emu/SysCalls/Modules/cellAdec.cpp | 2 +- rpcs3/Emu/SysCalls/Modules/libmixer.cpp | 357 +++++++++++++++--------- rpcs3/Emu/SysCalls/Modules/libmixer.h | 97 +++++++ rpcs3/Emu/SysCalls/Static.cpp | 8 +- rpcs3/Emu/SysCalls/SysCalls.h | 4 + 5 files changed, 338 insertions(+), 130 deletions(-) diff --git a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp index 4181430a47..8028b923a8 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAdec.cpp @@ -267,7 +267,7 @@ u32 adecOpen(AudioDecoder* data) if (adec.just_started) { adec.first_pts = task.au.pts; - adec.last_pts = task.au.pts /*- 3816*8*/; // hack + adec.last_pts = task.au.pts - 0x10000; // hack } struct AVPacketHolder : AVPacket diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp index 48487f52ad..d57ce38a0f 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -18,23 +18,24 @@ u64 mixcount = 0; int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 samples) { - u32 ch = aan_port >> 16; + u32 type = aan_port >> 16; u32 port = aan_port & 0xffff; - switch (ch) + + switch (type) { - case 1: - if (port >= surMixer.chStrips1) ch = 0; break; - case 2: - if (port >= surMixer.chStrips2) ch = 0; break; - case 6: - /*if (port >= surMixer.chStrips6)*/ ch = 0; break; - case 8: - if (port >= surMixer.chStrips8) ch = 0; break; + case CELL_SURMIXER_CHSTRIP_TYPE1A: + if (port >= surMixer.chStrips1) type = 0; break; + case CELL_SURMIXER_CHSTRIP_TYPE2A: + if (port >= surMixer.chStrips2) type = 0; break; + case CELL_SURMIXER_CHSTRIP_TYPE6A: + if (port >= surMixer.chStrips6) type = 0; break; + case CELL_SURMIXER_CHSTRIP_TYPE8A: + if (port >= surMixer.chStrips8) type = 0; break; default: - ch = 0; break; + type = 0; break; } - if (aan_handle == 0x11111111 && samples == 256 && ch && offset == 0) + if (aan_handle == 0x11111111 && samples == 256 && type && offset == 0) { libmixer.Log("cellAANAddData(handle=0x%x, port=0x%x, offset=0x%x, addr=0x%x, samples=0x%x)", aan_handle, aan_port, offset, addr, samples); @@ -49,7 +50,7 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl SMutexLocker lock(mixer_mutex); - if (ch == 1) + if (type == CELL_SURMIXER_CHSTRIP_TYPE1A) { // mono upmixing for (u32 i = 0; i < samples; i++) @@ -59,7 +60,7 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl mixdata[i*8+1] += center; } } - else if (ch == 2) + else if (type == CELL_SURMIXER_CHSTRIP_TYPE2A) { // stereo upmixing for (u32 i = 0; i < samples; i++) @@ -70,7 +71,7 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl mixdata[i*8+1] += right; } } - else if (ch == 6) + else if (type == CELL_SURMIXER_CHSTRIP_TYPE6A) { // 5.1 upmixing for (u32 i = 0; i < samples; i++) @@ -89,7 +90,7 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl mixdata[i*8+5] += rear_right; } } - else if (ch == 8) + else if (type == CELL_SURMIXER_CHSTRIP_TYPE8A) { // 7.1 for (u32 i = 0; i < samples * 8; i++) @@ -103,59 +104,61 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl int cellAANConnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) { - libmixer.Error("cellAANConnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcrPortNo=0x%x)", + libmixer.Error("cellAANConnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcePortNo=0x%x)", receive, receivePortNo, source, sourcePortNo); - return 0; + return CELL_OK; } int cellAANDisconnect(u32 receive, u32 receivePortNo, u32 source, u32 sourcePortNo) { - libmixer.Error("cellAANDisconnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcrPortNo=0x%x)", + libmixer.Error("cellAANDisconnect(receive=0x%x, receivePortNo=0x%x, source=0x%x, sourcePortNo=0x%x)", receive, receivePortNo, source, sourcePortNo); - return 0; + return CELL_OK; } -/*int cellSSPlayerCreate(CellAANHandle *handle, CellSSPlayerConfig *config) +int cellSSPlayerCreate(mem32_t handle, mem_ptr_t config) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; + libmixer.Error("cellSSPlayerCreate(handle_addr=0x%x, config_addr=0x%x)", + handle.GetAddr(), config.GetAddr()); + return CELL_OK; } -int cellSSPlayerRemove(CellAANHandle handle) +int cellSSPlayerRemove(u32 handle) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; + libmixer.Error("cellSSPlayerRemove(handle=%d)", handle); + return CELL_OK; } -int cellSSPlayerSetWave() //CellAANHandle handle, CellSSPlayerWaveParam *waveInfo, CellSSPlayerCommonParam *commonInfo //mem_class_t waveInfo +int cellSSPlayerSetWave(u32 handle, mem_ptr_t waveInfo, mem_ptr_t commonInfo) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; + libmixer.Error("cellSSPlayerSetWave(handle=%d, waveInfo_addr=0x%x, commonInfo_addr=0x%x)", + handle, waveInfo.GetAddr(), commonInfo.GetAddr()); + return CELL_OK; } -int cellSSPlayerPlay() //CellAANHandle handle, CellSSPlayerRuntimeInfo *info +int cellSSPlayerPlay(u32 handle, mem_ptr_t info) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; + libmixer.Error("cellSSPlayerPlay(handle=%d, info_addr=0x%x)", handle, info.GetAddr()); + return CELL_OK; } -int cellSSPlayerStop() //CellAANHandle handle, u32 mode +int cellSSPlayerStop(u32 handle, u32 mode) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; + libmixer.Error("cellSSPlayerStop(handle=%d, mode=0x%x)", handle, mode); + return CELL_OK; } -int cellSSPlayerSetParam() //CellAANHandle handle, CellSSPlayerRuntimeInfo *info +int cellSSPlayerSetParam(u32 handle, mem_ptr_t info) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; + libmixer.Error("cellSSPlayerSetParam(handle=%d, info_addr=0x%x)", handle, info.GetAddr()); + return CELL_OK; } -s32 cellSSPlayerGetState() //CellAANHandle handle +s32 cellSSPlayerGetState(u32 handle) { - UNIMPLEMENTED_FUNC(libmixer); - return 0; -}*/ + libmixer.Error("cellSSPlayerGetState(handle=%d) -> OFF", handle); + return CELL_SSPLAYER_STATE_OFF; +} int cellSurMixerCreate(const mem_ptr_t config) { @@ -376,7 +379,7 @@ void cellSurMixerUtilNoteToRatio(u8 refNote, u8 note) void libmixer_init() { - static const u64 cellAANAddData_table[] = { + REG_SUB(libmixer, "surmxAAN", cellAANAddData, 0xffffffff7c691b78, 0xffffffff7c0802a6, 0xfffffffff821ff91, @@ -400,11 +403,9 @@ void libmixer_init() 0xffffffff7c0803a6, 0xffffffff38210070, 0xffffffff4e800020, - 0 - }; - libmixer.AddFuncSub("surmxAAN", cellAANAddData_table, "cellAANAddData", cellAANAddData); + ); - static const u64 cellAANConnect_table[] = { + REG_SUB(libmixer, "surmxAAN", cellAANConnect, 0xfffffffff821ff71, 0xffffffff7c0802a6, 0xffffffff2f830000, @@ -443,11 +444,9 @@ void libmixer_init() 0xffffffff38210090, 0xffffffff7c0803a6, 0xffffffff4e800020, - 0, - }; - libmixer.AddFuncSub("surmxAAN", cellAANConnect_table, "cellAANConnect", cellAANConnect); + ); - static const u64 cellAANDisconnect_table[] = { + REG_SUB(libmixer, "surmxAAN", cellAANDisconnect, 0xfffffffff821ff71, 0xffffffff7c0802a6, 0xffffffff2f830000, @@ -486,11 +485,9 @@ void libmixer_init() 0xffffffff38210090, 0xffffffff7c0803a6, 0xffffffff4e800020, - 0, - }; - libmixer.AddFuncSub("surmxAAN", cellAANDisconnect_table, "cellAANDisconnect", cellAANDisconnect); + ); - static const u64 cellSurMixerCreate_table[] = { + REG_SUB(libmixer, "surmixer", cellSurMixerCreate, 0xffffffff2f830000, 0xffffffff7c0802a6, 0xfffffffff821ff51, @@ -517,12 +514,10 @@ void libmixer_init() 0xffffffffebc100a0, 0xffffffffebe100a8, 0xffffffff382100b0, - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerCreate_table, "cellSurMixerCreate", cellSurMixerCreate); + ); - static const u64 cellSurMixerGetAANHandle_table[] = { - // first instruction ignored + REG_SUB(libmixer, "surmixer", cellSurMixerGetAANHandle, + 0xff00000081428250, // lwz 0xffffffff3d607fce, 0xffffffff616bfffe, 0xffffffff812a0018, @@ -536,12 +531,10 @@ void libmixer_init() 0xffffffff38630002, 0xffffffff7c6307b4, 0xffffffff4e800020, - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerGetAANHandle_table, "cellSurMixerGetAANHandle", cellSurMixerGetAANHandle); + ); - static const u64 cellSurMixerChStripGetAANPortNo_table[] = { - // first instruction ignored + REG_SUB(libmixer, "surmixer", cellSurMixerChStripGetAANPortNo, + 0xff00000081228250, // lwz 0xffffffff7c661b78, 0xffffffff3c608031, 0xffffffff78c60020, @@ -553,12 +546,10 @@ void libmixer_init() 0xffffffff4d9e0020, 0xffffffff78030020, 0xf000000040000000, // b - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerChStripGetAANPortNo_table, "cellSurMixerChStripGetAANPortNo", cellSurMixerChStripGetAANPortNo); + ); - static const u64 cellSurMixerSetNotifyCallback_table[] = { - // first instruction ignored + REG_SUB(libmixer, "surmixer", cellSurMixerSetNotifyCallback, + 0xff00000081428250, // lwz 0xffffffff7c0802a6, 0xfffffffff821ff81, 0xfffffffff8010090, @@ -583,12 +574,10 @@ void libmixer_init() 0xffffffff38810070, 0xffffffff2f800000, 0xffffffff7d234b78, - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerSetNotifyCallback_table, "cellSurMixerSetNotifyCallback", cellSurMixerSetNotifyCallback); + ); - static const u64 cellSurMixerRemoveNotifyCallback_table[] = { - // first instruction ignored + REG_SUB(libmixer, "surmixer", cellSurMixerRemoveNotifyCallback, + 0xff00000081628250, // lwz 0xffffffff7c0802a6, 0xfffffffff821ff81, 0xfffffffff8010090, @@ -603,11 +592,9 @@ void libmixer_init() 0xffffffff38210080, 0xffffffff7c0803a6, 0xffffffff4e800020, - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerRemoveNotifyCallback_table, "cellSurMixerRemoveNotifyCallback", cellSurMixerRemoveNotifyCallback); + ); - static const u64 cellSurMixerStart_table[] = { + REG_SUB(libmixer, "surmixer", cellSurMixerStart, 0xfffffffff821ff71, 0xffffffff7c0802a6, 0xfffffffffbc10080, @@ -628,11 +615,9 @@ void libmixer_init() 0xffffffffebe10088, 0xffffffff38210090, 0xffffffff4e800020, - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerStart_table, "cellSurMixerStart", cellSurMixerStart); + ); - static const u64 cellSurMixerSetParameter_table[] = { + REG_SUB(libmixer, "surmixer", cellSurMixerSetParameter, 0xfffffffff821ff81, 0xffffffff7c0802a6, 0xfffffffffbc10070, @@ -660,11 +645,9 @@ void libmixer_init() 0xffffffff2b83002b, 0xffff000040990008, // ble 0xffff0000409d0054, // ble - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerSetParameter_table, "cellSurMixerSetParameter", cellSurMixerSetParameter); + ); - static const u64 cellSurMixerFinalize_table[] = { + REG_SUB(libmixer, "surmixer", cellSurMixerFinalize, 0xfffffffff821ff91, 0xffffffff7c0802a6, 0xfffffffff8010080, @@ -688,12 +671,10 @@ void libmixer_init() 0xffffffff7c0903a6, 0xffffffff804a0004, 0xffffffff4e800421, - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerFinalize_table, "cellSurMixerFinalize", cellSurMixerFinalize); + ); - static const u64 cellSurMixerSurBusAddData_table[] = { - 0xff00000081428250, + REG_SUB(libmixer, "surmixer", cellSurMixerSurBusAddData, + 0xff00000081428250, // lwz 0xffffffff7c0802a6, 0xfffffffff821ff91, 0xfffffffff8010080, @@ -719,12 +700,10 @@ void libmixer_init() 0xffffffff79660020, 0xffffffff78e70020, 0xffff0000419cffcc, // blt - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerSurBusAddData_table, "cellSurMixerSurBusAddData", cellSurMixerSurBusAddData); + ); - static const u64 cellSurMixerChStripSetParameter_table[] = { - 0xff00000081028250, + REG_SUB(libmixer, "surmixer", cellSurMixerChStripSetParameter, + 0xff00000081028250, // lwz 0xffffffff7c6b1b78, 0xffffffff3c608031, 0xffffffff7c8a2378, @@ -741,12 +720,10 @@ void libmixer_init() 0xffffffff4d9c0020, 0xffffffff79230020, 0xf000000048000000, // b - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerChStripSetParameter_table, "cellSurMixerChStripSetParameter", cellSurMixerChStripSetParameter); + ); - static const u64 cellSurMixerPause_table[] = { - // first instruction ignored + REG_SUB(libmixer, "surmixer", cellSurMixerPause, + 0xff00000081428250, // lwz 0xffffffff7c0802a6, 0xfffffffff821ff81, 0xfffffffff8010090, @@ -768,12 +745,10 @@ void libmixer_init() 0xffffffff800a001c, 0xffffffff2b030002, 0xffffffff2f800000, - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerPause_table, "cellSurMixerPause", cellSurMixerPause); + ); - static const u64 cellSurMixerGetCurrentBlockTag_table[] = { - // first instruction ignored + REG_SUB(libmixer, "surmixer", cellSurMixerGetCurrentBlockTag, + 0xff00000081628250, // lwz 0xffffffff3d208031, 0xffffffff61290002, 0xffffffff880b0020, @@ -784,12 +759,10 @@ void libmixer_init() 0xfffffffff8030000, 0xffffffff7d2307b4, 0xffffffff4e800020, - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerGetCurrentBlockTag_table, "cellSurMixerGetCurrentBlockTag", cellSurMixerGetCurrentBlockTag); + ); - static const u64 cellSurMixerGetTimestamp_table[] = { - // first instruction ignored + REG_SUB(libmixer, "surmixer", cellSurMixerGetTimestamp, + 0xff00000081628250, // lwz 0xffffffff7c0802a6, 0xfffffffff821ff91, 0xfffffffff8010080, @@ -808,12 +781,10 @@ void libmixer_init() 0xffffffff4e800020, 0xffffffff806b04d8, 0xf000000048000001, // bl - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerGetTimestamp_table, "cellSurMixerGetTimestamp", cellSurMixerGetTimestamp); + ); - static const u64 cellSurMixerBeep_table[] = { - // first instruction ignored + REG_SUB(libmixer, "surmixer", cellSurMixerBeep, + 0xff00000081228250, // lwz 0xffffffff7c641b78, 0xffffffff80690018, 0xffffffff2f830000, @@ -824,13 +795,149 @@ void libmixer_init() 0xffffffff2f800000, 0xffffffff4d9c0020, 0xf000000048000000, // b - 0 - }; - libmixer.AddFuncSub("surmx___", cellSurMixerBeep_table, "cellSurMixerBeep", cellSurMixerBeep); + ); - // TODO: SSPlayer functions - /*static const u64 cell_table[] = { - 0 - }; - libmixer.AddFuncSub("surmxSSP", cell_table, "cell", nullptr);*/ + REG_SUB(libmixer, "surmxSSP", cellSSPlayerCreate, + 0xfffffffff821ff51, + 0xffffffff7c0802a6, + 0xffffffff2f840000, + 0xfffffffff80100c0, + 0xffffffff3c008031, + 0xfffffffffb210078, + 0xfffffffffb410080, + 0xfffffffffb610088, + 0xfffffffffb810090, + 0xfffffffffba10098, + 0xfffffffffbc100a0, + 0xfffffffffbe100a8, + 0xffffffff7c9a2378, + 0xffffffff7c791b78, + 0xffffffff60000003, + 0xffff0000419e0068, // beq + 0xff00000083620000, // lwz + 0xffffffff3b800000, + 0xffffffff381b0064, + 0xffffffff901b0018, + 0xffffffff5780103a, + 0xffffffff38800010, + 0xffffffff7c0007b4, + 0xffffffff38a01c70, + 0xffffffff7fc0da14, + 0xffffffff38c00000, + 0xffffffff83be0024, + 0xffffffff2f9d0000, + 0xffffffff7ba30020, + 0xffff000041de00c0, // beq- + 0xf000000048000001, // bl + ); + + REG_SUB(libmixer, "surmxSSP", cellSSPlayerRemove, + 0xffffffff7c641b78, + 0xffffffff7c0802a6, + 0xffffffff3c608031, + 0xffffffff2f840000, + 0xfffffffff821ff51, + 0xfffffffffb010070, + 0xfffffffffb210078, + 0xfffffffffb410080, + 0xfffffffffb610088, + 0xfffffffffb810090, + 0xfffffffffba10098, + 0xfffffffffbc100a0, + 0xfffffffffbe100a8, + 0xfffffffff80100c0, + 0xffffffff60630003, + 0xffff0000419e0074, // beq + 0xffffffff81240000, + 0xffffffff78830020, + 0xffffffff83440004, + 0xffffffff83240008, + 0xffffffff7b5b0020, + 0xffffffff81690000, + 0xffffffff800b0000, + 0xfffffffff8410028, + 0xffffffff7c0903a6, + 0xffffffff804b0004, + 0xffffffff4e800421, + ); + + REG_SUB(libmixer, "surmxSSP", cellSSPlayerSetWave, + 0xffffffff7c601b78, + 0xffffffff78840020, + 0xffffffff2f800000, + 0xffffffff3c608031, + 0xffffffff78a50020, + 0xffff0000419e000c, // beq + 0xffffffff78030020, + 0xf000000048000000, // b + 0xffffffff60630003, + 0xffffffff4e800020, + ); + + REG_SUB(libmixer, "surmxSSP", cellSSPlayerPlay, + 0xffffffff7c601b78, + 0xffffffff3c608031, + 0xffffffff2f800000, + 0xffffffff60630003, + 0xffffffff78840020, + 0xffffffff4d9e0020, + 0xffffffff78030020, + 0xf000000048000000, // b + 0xfffffffff821ff81, // next func + 0xffffffff7c0802a6, + 0xfffffffffbe10078, + 0xffffffff7c7f1b78, + 0xff00000081620028, // lwz + 0xfffffffff8010090, + 0xffffffff39400000, + 0xffffffff38630010, + ); + + REG_SUB(libmixer, "surmxSSP", cellSSPlayerStop, + 0xfffffffff821ff91, + 0xffffffff7c0802a6, + 0xffffffff2f830000, + 0xfffffffff8010080, + 0xffffffff3c008031, + 0xffffffff78630020, + 0xffffffff60000003, + 0xffff0000419e0010, // beq + 0xffffffff78840020, + 0xf000000048000001, // bl + 0xffffffff38000000, + 0xffffffff7c0307b4, + 0xffffffffe8010080, + 0xffffffff38210070, + 0xffffffff7c0803a6, + 0xffffffff4e800020, + ); + + REG_SUB(libmixer, "surmxSSP", cellSSPlayerSetParam, + 0xffffffff7c601b78, + 0xffffffff3c608031, + 0xffffffff2f800000, + 0xffffffff60630003, + 0xffffffff78840020, + 0xffffffff4d9e0020, + 0xffffffff78030020, + 0xf000000048000000, // b + 0xfffffffff821ff71, // next func + 0xffffffff7c0802a6, + 0xffffffff3d608031, + 0xfffffffff80100a0, + 0xffffffff80030068, + 0xffffffff616b0002, + 0xfffffffffbc10080, + 0xffffffff2f800000, + ); + + REG_SUB(libmixer, "surmxSSP", cellSSPlayerGetState, + 0xffffffff7c601b78, + 0xffffffff3c608031, + 0xffffffff2f800000, + 0xffffffff60630003, + 0xffffffff4d9e0020, + 0xffffffff78030020, + 0xf000000048000000, // b + ); } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.h b/rpcs3/Emu/SysCalls/Modules/libmixer.h index 590e6e2110..3512634e0d 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.h +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.h @@ -13,6 +13,103 @@ enum CELL_LIBMIXER_ERROR_NOT_FOUND = 0x8031000a, }; +enum +{ + CELL_SURBUS_LEFT = 0, + CELL_SURBUS_RIGHT = 1, + CELL_SURBUS_CENTER = 2, + CELL_SURBUS_LFE = 3, + CELL_SURBUS_LEFT_SUR = 4, + CELL_SURBUS_RIGHT_SUR = 5, + CELL_SURBUS_LEFT_EXT = 6, + CELL_SURBUS_RIGHT_EXT = 7, + CELL_SURBUS_REVERB_LEFT = 8, + CELL_SURBUS_REVERB_RIGHT = 9, + CELL_SURBUS_REVERB_LEFT_SUR = 10, + CELL_SURBUS_REVERB_RIGHT_SUR = 11, +}; + +enum +{ + CELL_SURMIXER_PARAM_TOTALLEVEL_LINEAR = 8, + CELL_SURMIXER_PARAM_REVERBLEVEL_LINEAR = 9, + CELL_SURMIXER_PARAM_TOTALMUTE = 12, + + CELL_SURMIXER_PARAM_TOTALLEVEL = 40, // in dB + CELL_SURMIXER_PARAM_REVERBLEVEL = 41, // in dB +}; + +static const float CELL_SURMIXER_CONT_MUTEON = 1.0; +static const float CELL_SURMIXER_CONT_MUTEOFF = 0.0; + +enum +{ + CELL_SURMIXER_CONT_DBSWITCHON = 1, + CELL_SURMIXER_CONT_DBSWITCHOFF = 0, + CELL_SURMIXER_CONT_PAUSE_OFF = 0, + CELL_SURMIXER_CONT_PAUSE_ON = 1, + CELL_SURMIXER_CONT_PAUSE_ON_IMMEDIATE = 2, +}; + +enum +{ + CELL_SURMIXER_CHSTRIP_TYPE1A = 1, + CELL_SURMIXER_CHSTRIP_TYPE2A = 2, + CELL_SURMIXER_CHSTRIP_TYPE6A = 3, + CELL_SURMIXER_CHSTRIP_TYPE8A = 4, + + CELL_SURMIXER_CH1PARAM_LEVEL = 0, + CELL_SURMIXER_CH1PARAM_EXPRESSIONLEVEL = 1, + CELL_SURMIXER_CH1PARAM_CENTERLEVEL = 2, + CELL_SURMIXER_CH1PARAM_REVERBSENDLEVEL = 3, + CELL_SURMIXER_CH1PARAM_MUTE = 4, + CELL_SURMIXER_CH1PARAM_REVSENDPOSITION = 5, + CELL_SURMIXER_CH1PARAM_POSITION = 6, + + CELL_SURMIXER_CH2PARAM_LEVEL = 0, + CELL_SURMIXER_CH2PARAM_EXPRESSIONLEVEL = 1, + CELL_SURMIXER_CH2PARAM_CENTERLEVEL = 2, + CELL_SURMIXER_CH2PARAM_REVERBSENDLEVEL = 3, + CELL_SURMIXER_CH2PARAM_MUTE = 4, + CELL_SURMIXER_CH2PARAM_REVSENDPOSITION = 5, + CELL_SURMIXER_CH2PARAM_POSITION = 6, + + CELL_SURMIXER_CH6PARAM_LEVEL = 0, + CELL_SURMIXER_CH6PARAM_EXPRESSIONLEVEL = 1, + CELL_SURMIXER_CH6PARAM_REVERBSENDLEVEL = 2, + CELL_SURMIXER_CH6PARAM_CENTER_REVERBSENDLEVEL = 3, + CELL_SURMIXER_CH6PARAM_MUTE = 4, + + CELL_SURMIXER_CH8PARAM_LEVEL = 0, + CELL_SURMIXER_CH8PARAM_EXPRESSIONLEVEL = 1, + CELL_SURMIXER_CH8PARAM_REVERBSENDLEVEL = 2, + CELL_SURMIXER_CH8PARAM_CENTER_REVERBSENDLEVEL = 3, + CELL_SURMIXER_CH8PARAM_MUTE = 4, + + CELL_SURMIXER_CH1CONT_MUTE_OFF = 0, + CELL_SURMIXER_CH1CONT_MUTE_ON = 1, + CELL_SURMIXER_CH2CONT_MUTE_OFF = 0, + CELL_SURMIXER_CH2CONT_MUTE_ON = 1, + CELL_SURMIXER_CH6CONT_MUTE_OFF = 0, + CELL_SURMIXER_CH6CONT_MUTE_ON = 1, + CELL_SURMIXER_CH8CONT_MUTE_OFF = 0, + CELL_SURMIXER_CH8CONT_MUTE_ON = 1, +}; + +enum +{ + CELL_SSPLAYER_ONESHOT = 0, + CELL_SSPLAYER_ONESHOT_CONT = 2, + CELL_SSPLAYER_LOOP_ON = 16, + + CELL_SSPLAYER_STATE_ERROR = 0xffffffff, + CELL_SSPLAYER_STATE_NOTREADY = 0x88888888, + CELL_SSPLAYER_STATE_OFF = 0x00, + CELL_SSPLAYER_STATE_PAUSE = 0x01, + CELL_SSPLAYER_STATE_CLOSING = 0x08, + CELL_SSPLAYER_STATE_ON = 0x20, +}; + typedef int (*CellSurMixerNotifyCallbackFunction)(void *arg, u32 counter, u32 samples); struct CellSSPlayerConfig diff --git a/rpcs3/Emu/SysCalls/Static.cpp b/rpcs3/Emu/SysCalls/Static.cpp index 073bf0dad5..7a26f9255e 100644 --- a/rpcs3/Emu/SysCalls/Static.cpp +++ b/rpcs3/Emu/SysCalls/Static.cpp @@ -110,14 +110,14 @@ void StaticAnalyse(void* ptr, u32 size, u32 base) u32 res = GSR_SUCCESS; // analyse - for (u32 j = i; j < g_static_funcs_list.GetCount(); j++) if (g_static_funcs_list[j].group == group) + for (u32 j = 0; j < g_static_funcs_list.GetCount(); j++) if (g_static_funcs_list[j].group == group) { u32 count = g_static_funcs_list[j].found; if (count == 0) // not found { // check if this function has been found with different pattern - for (u32 k = i; k < g_static_funcs_list.GetCount(); k++) if (g_static_funcs_list[k].group == group) + for (u32 k = 0; k < g_static_funcs_list.GetCount(); k++) if (g_static_funcs_list[k].group == group) { if (k != j && g_static_funcs_list[k].ptr == g_static_funcs_list[j].ptr) { @@ -137,7 +137,7 @@ void StaticAnalyse(void* ptr, u32 size, u32 base) else if (count == 1) // found { // ensure that this function has NOT been found with different pattern - for (u32 k = i; k < g_static_funcs_list.GetCount(); k++) if (g_static_funcs_list[k].group == group) + for (u32 k = 0; k < g_static_funcs_list.GetCount(); k++) if (g_static_funcs_list[k].group == group) { if (k != j && g_static_funcs_list[k].ptr == g_static_funcs_list[j].ptr) { @@ -157,7 +157,7 @@ void StaticAnalyse(void* ptr, u32 size, u32 base) } // clear data - for (u32 j = i; j < g_static_funcs_list.GetCount(); j++) + for (u32 j = 0; j < g_static_funcs_list.GetCount(); j++) { if (g_static_funcs_list[j].group == group) g_static_funcs_list[j].found = 0; } diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index 1050d00892..8148074d83 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -467,3 +467,7 @@ public: void StaticAnalyse(void* ptr, u32 size, u32 base); void StaticExecute(u32 code); void StaticFinalize(); + +#define REG_SUB(module, group, name,...) \ + static const u64 name ## _table[] = {__VA_ARGS__ ## 0}; \ + module.AddFuncSub(group, name ## _table, #name, name) \ No newline at end of file From b6d8f1e0280b8592e8c0cbc56c09be3e53d044a1 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Wed, 2 Apr 2014 19:17:43 +0400 Subject: [PATCH 11/14] Small fix (cellAudio, fsAioRead) libsynth2 draft --- rpcs3/Emu/Audio/cellAudio.h | 16 --- rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 120 +---------------- rpcs3/Emu/SysCalls/Modules/libmixer.cpp | 4 + rpcs3/Emu/SysCalls/Modules/libsynth2.cpp | 159 +++++++++++++++++++++++ rpcs3/Emu/SysCalls/Modules/libsynth2.h | 19 +++ rpcs3/Emu/SysCalls/Modules/sys_fs.cpp | 9 -- rpcs3/rpcs3.vcxproj | 1 + rpcs3/rpcs3.vcxproj.filters | 3 + 8 files changed, 190 insertions(+), 141 deletions(-) create mode 100644 rpcs3/Emu/SysCalls/Modules/libsynth2.cpp create mode 100644 rpcs3/Emu/SysCalls/Modules/libsynth2.h diff --git a/rpcs3/Emu/Audio/cellAudio.h b/rpcs3/Emu/Audio/cellAudio.h index c0fe570980..2823dcab50 100644 --- a/rpcs3/Emu/Audio/cellAudio.h +++ b/rpcs3/Emu/Audio/cellAudio.h @@ -39,11 +39,6 @@ enum CELL_SND3_ERROR_RESERVEDVOICE = 0x8031030e, CELL_SND3_ERROR_REQUESTQUEFULL = 0x8031030f, CELL_SND3_ERROR_OUTPUTMODE = 0x80310310, - - //libsynt2 Error Codes - CELL_SOUND_SYNTH2_ERROR_FATAL = 0x80310201, - CELL_SOUND_SYNTH2_ERROR_INVALID_PARAMETER = 0x80310202, - CELL_SOUND_SYNTH2_ERROR_ALREADY_INITIALIZED = 0x80310203, }; // constants @@ -175,14 +170,3 @@ struct CellSnd3RequestQueueCtx void *rearQueue; be_t rearQueueSize; }; - -//libsynt2 datatypes -struct CellSoundSynth2EffectAttr -{ - be_t core; - be_t mode; - be_t depth_L; - be_t depth_R; - be_t delay; - be_t feedback; -}; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 25c9f7c41c..aa4a09cd86 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -7,8 +7,7 @@ #include "Emu/Audio/AudioDumper.h" void cellAudio_init(); -void cellAudio_unload(); -Module cellAudio(0x0011, cellAudio_init, nullptr, cellAudio_unload); +Module cellAudio(0x0011, cellAudio_init); static SMutexGeneral audioMutex; @@ -57,8 +56,8 @@ int cellAudioInit() uint oal_buffer_offset = 0; uint oal_buffer_size = sizeof(buffer) / sizeof(float); std::unique_ptr oal_buffer[32]; - SQueue queue; - for (u32 i = 0; i < queue.GetSize(); i++) + SQueue queue; + for (u32 i = 0; i < sizeof(oal_buffer) / sizeof(oal_buffer[0]); i++) { oal_buffer[i] = std::unique_ptr(new u16[oal_buffer_size]); memset(oal_buffer[i].get(), 0, oal_buffer_size * sizeof(u16)); @@ -118,7 +117,7 @@ int cellAudioInit() m_config.counter++; - const u32 oal_pos = m_config.counter % queue.GetSize(); + const u32 oal_pos = m_config.counter % (sizeof(oal_buffer) / sizeof(oal_buffer[0])); if (Emu.IsPaused()) { @@ -1039,110 +1038,6 @@ s32 cellSnd3SMFGetKeyOnID() //u32 smfID, u32 midiChannel, u32 *keyOnID return CELL_OK; } - //*libsynth2 Functions, NON active in this moment*// - -s32 cellSoundSynth2Config(s16 param, s32 value) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -s32 cellSoundSynth2Init( s16 flag) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -s32 cellSoundSynth2Exit() -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -void cellSoundSynth2SetParam(u16 register, u16 value) -{ - UNIMPLEMENTED_FUNC(cellAudio); - //TODO -} - -u16 cellSoundSynth2GetParam() //u16 register -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -void cellSoundSynth2SetSwitch(u16 register, u32 value) -{ - UNIMPLEMENTED_FUNC(cellAudio); - //TODO -} - -u32 cellSoundSynth2GetSwitch() //u16 register -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -u32 cellSoundSynth2SetAddr(u16 register, u32 value) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -u32 cellSoundSynth2GetAddr() //u16 register -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSoundSynth2SetEffectAttr() //s16 bus, CellSoundSynth2EffectAttr *attr -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -s32 cellSoundSynth2SetEffectMode() //s16 bus, CellSoundSynth2EffectAttr *attr -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -void cellSoundSynth2SetCoreAttr(u16 entry, u16 value) -{ - UNIMPLEMENTED_FUNC(cellAudio); - //TODO -} - -s32 cellSoundSynth2Generate() //u16 samples, float *left_buffer, float *right_buffer, float *left_rear, float *right_rear -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -s32 cellSoundSynth2VoiceTrans() //s16 channel, u16 mode, u8 *m_addr, u32 s_addr, u32 size -{ - UNIMPLEMENTED_FUNC(cellAudio); - return 0; -} - -u16 cellSoundSynth2Note2Pitch() //u16 center_note, u16 center_fine, u16 note, s16 fine -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -u16 cellSoundSynth2Pitch2Note() //u16 center_note, u16 center_fine, u16 pitch -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - - void cellAudio_init() { cellAudio.AddFunc(0x0b168f92, cellAudioInit); @@ -1161,11 +1056,4 @@ void cellAudio_init() cellAudio.AddFunc(0xdab029aa, cellAudioAddData); cellAudio.AddFunc(0xe4046afe, cellAudioGetPortBlockTag); cellAudio.AddFunc(0xff3626fd, cellAudioRemoveNotifyEventQueue); - - //TODO: Find addresses for libmixer, libsnd3 and libsynth2 functions -} - -void cellAudio_unload() -{ - //StaticFinalize(); } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp index d57ce38a0f..f441922fa7 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -940,4 +940,8 @@ void libmixer_init() 0xffffffff78030020, 0xf000000048000000, // b ); + + REG_SUB(libmixer, "surmxUti", cellSurMixerUtilGetLevelFromDB); + REG_SUB(libmixer, "surmxUti", cellSurMixerUtilGetLevelFromDBIndex); + REG_SUB(libmixer, "surmxUti", cellSurMixerUtilNoteToRatio); } \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/libsynth2.cpp b/rpcs3/Emu/SysCalls/Modules/libsynth2.cpp new file mode 100644 index 0000000000..7262ddc67b --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/libsynth2.cpp @@ -0,0 +1,159 @@ +#include "stdafx.h" +#include "Emu/SysCalls/SysCalls.h" +#include "Emu/SysCalls/SC_FUNC.h" + +void libsynth2_init(); +Module libsynth2("libsynth2", libsynth2_init); + +#include "libsynth2.h" + +int cellSoundSynth2Config(s16 param, int value) +{ + libsynth2.Error("cellSoundSynth2Config(param=%d, value=%d)", param, value); + return CELL_OK; +} + +int cellSoundSynth2Init(s16 flag) +{ + libsynth2.Error("cellSoundSynth2Init(flag=%d)", flag); + return CELL_OK; +} + +int cellSoundSynth2Exit() +{ + libsynth2.Error("cellSoundSynth2Exit()"); + return CELL_OK; +} + +void cellSoundSynth2SetParam(u16 reg, u16 value) +{ + libsynth2.Error("cellSoundSynth2SetParam(register=0x%x, value=0x%x)", reg, value); +} + +u16 cellSoundSynth2GetParam(u16 reg) +{ + libsynth2.Error("cellSoundSynth2GetParam(register=0x%x) -> 0", reg); + return 0; +} + +void cellSoundSynth2SetSwitch(u16 reg, u32 value) +{ + libsynth2.Error("cellSoundSynth2SetSwitch(register=0x%x, value=0x%x)", reg, value); +} + +u32 cellSoundSynth2GetSwitch(u16 reg) +{ + libsynth2.Error("cellSoundSynth2GetSwitch(register=0x%x) -> 0", reg); + return 0; +} + +int cellSoundSynth2SetAddr(u16 reg, u32 value) +{ + libsynth2.Error("cellSoundSynth2SetAddr(register=0x%x, value=0x%x)", reg, value); + return CELL_OK; +} + +u32 cellSoundSynth2GetAddr(u16 reg) +{ + libsynth2.Error("cellSoundSynth2GetAddr(register=0x%x) -> 0", reg); + return 0; +} + +int cellSoundSynth2SetEffectAttr(s16 bus, mem_ptr_t attr) +{ + libsynth2.Error("cellSoundSynth2SetEffectAttr(bus=%d, attr_addr=0x%x)", bus, attr.GetAddr()); + return CELL_OK; +} + +int cellSoundSynth2SetEffectMode(s16 bus, mem_ptr_t attr) +{ + libsynth2.Error("cellSoundSynth2SetEffectMode(bus=%d, attr_addr=0x%x)", bus, attr.GetAddr()); + return CELL_OK; +} + +void cellSoundSynth2SetCoreAttr(u16 entry, u16 value) +{ + libsynth2.Error("cellSoundSynth2SetCoreAttr(entry=0x%x, value=0x%x)", entry, value); +} + +int cellSoundSynth2Generate(u16 samples, u32 L_addr, u32 R_addr, u32 Lr_addr, u32 Rr_addr) +{ + libsynth2.Error("cellSoundSynth2Generate(samples=0x%x, left=0x%x, right=0x%x, left_rear=0x%x, right_rear=0x%x)", + samples, L_addr, R_addr, Lr_addr, Rr_addr); + return CELL_OK; +} + +int cellSoundSynth2VoiceTrans(s16 channel, u16 mode, u32 mem_side_addr, u32 lib_side_addr, u32 size) +{ + libsynth2.Error("cellSoundSynth2VoiceTrans(channel=%d, mode=0x%x, m_addr=0x%x, s_addr=0x%x, size=0x%x)", + channel, mode, mem_side_addr, lib_side_addr, size); + return CELL_OK; +} + +int cellSoundSynth2VoiceTransStatus(s16 channel, s16 flag) +{ + libsynth2.Error("cellSoundSynth2VoiceTransStatus(channel=%d, flag=%d)", channel, flag); + return CELL_OK; +} + +u16 cellSoundSynth2Note2Pitch(u16 center_note, u16 center_fine, u16 note, s16 fine) +{ + libsynth2.Error("cellSoundSynth2Note2Pitch(center_note=0x%x, center_fine=0x%x, note=0x%x, fine=%d) -> 0", + center_note, center_fine, note, fine); + return 0; +} + +u16 cellSoundSynth2Pitch2Note(u16 center_note, u16 center_fine, u16 pitch) +{ + libsynth2.Error("cellSoundSynth2Pitch2Note(center_note=0x%x, center_fine=0x%x, pitch=0x%x) -> 0", + center_note, center_fine, pitch); + return 0; +} + +void libsynth2_init() +{ + REG_SUB(libsynth2, "synth2", cellSoundSynth2Init, + /* + 0xffffffff7d800026, + 0xfffffffff821ff41, + 0xfffffffffb610098, + 0xff0000008362001c, // lwz + 0xfffffffffb8100a0, + 0xffffffff3f9b0008, + 0xfffffffffba100a8, + 0xffffffff3fa08031, + 0xfffffffffbe100b8, + 0xfffffffffb010080, + 0xfffffffffb210088, + 0xfffffffffb410090, + 0xfffffffffbc100b0, + 0xffffffff7c7f1b78, + 0xffffffff63bd0203, + 0xffffffff918100c8, + 0xffffffff7c0802a6, + 0xfffffffff80100d0, + 0xffffffff897c7688, + 0xffffffff2f8b0000, + 0xffffff00409e01fc, // bne + 0xffffffff38000002, + 0xffffffff39200020, + 0xffffffff3ba00000, + */ + ); + REG_SUB(libsynth2, "synth2", cellSoundSynth2Exit); + REG_SUB(libsynth2, "synth2", cellSoundSynth2Config); + REG_SUB(libsynth2, "synth2", cellSoundSynth2GetAddr); + REG_SUB(libsynth2, "synth2", cellSoundSynth2GetParam); + REG_SUB(libsynth2, "synth2", cellSoundSynth2GetSwitch); + REG_SUB(libsynth2, "synth2", cellSoundSynth2SetAddr); + REG_SUB(libsynth2, "synth2", cellSoundSynth2SetParam); + REG_SUB(libsynth2, "synth2", cellSoundSynth2SetSwitch); + REG_SUB(libsynth2, "synth2", cellSoundSynth2SetEffectMode); + REG_SUB(libsynth2, "synth2", cellSoundSynth2SetEffectAttr); + REG_SUB(libsynth2, "synth2", cellSoundSynth2Note2Pitch); + REG_SUB(libsynth2, "synth2", cellSoundSynth2Pitch2Note); + REG_SUB(libsynth2, "synth2", cellSoundSynth2VoiceTrans); + REG_SUB(libsynth2, "synth2", cellSoundSynth2VoiceTransStatus); + REG_SUB(libsynth2, "synth2", cellSoundSynth2SetCoreAttr); + REG_SUB(libsynth2, "synth2", cellSoundSynth2Generate); +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/libsynth2.h b/rpcs3/Emu/SysCalls/Modules/libsynth2.h new file mode 100644 index 0000000000..8b1c428855 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/libsynth2.h @@ -0,0 +1,19 @@ +#pragma once + +enum +{ + //libsynt2 Error Codes + CELL_SOUND_SYNTH2_ERROR_FATAL = 0x80310201, + CELL_SOUND_SYNTH2_ERROR_INVALID_PARAMETER = 0x80310202, + CELL_SOUND_SYNTH2_ERROR_ALREADY_INITIALIZED = 0x80310203, +}; + +struct CellSoundSynth2EffectAttr +{ + be_t core; + be_t mode; + be_t depth_L; + be_t depth_R; + be_t delay; + be_t feedback; +}; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index 5cfd8acccb..107cf36520 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -153,15 +153,6 @@ void fsAioRead(u32 fd, mem_ptr_t aio, int xid, mem_func_ptr_tGetPath(); - std::string::size_type first_slash = path.find('/'); - if (first_slash == std::string::npos) - { - path = ""; - } - else - { - path = path.substr(first_slash+1,std::string::npos); - } u64 nbytes = aio->size; u32 buf_addr = aio->buf_addr; diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 5aa56519bc..db1fa9e1d4 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -314,6 +314,7 @@ + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index 1c1ed0a365..d3e2c7f3d1 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -487,6 +487,9 @@ Utilities + + Emu\SysCalls\Modules + From 1e0259890316ffe7ebbc78e4db6c7528d7fc73fa Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Thu, 3 Apr 2014 15:01:14 +0400 Subject: [PATCH 12/14] cellSync: global mutex avoided cellAudio: level bug fixed --- rpcs3/Emu/Audio/cellAudio.h | 52 +--- rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 346 ++--------------------- rpcs3/Emu/SysCalls/Modules/cellSync.cpp | 89 +++--- rpcs3/Emu/SysCalls/Modules/libsnd3.cpp | 327 +++++++++++++++++++++ rpcs3/Emu/SysCalls/Modules/libsnd3.h | 54 ++++ rpcs3/rpcs3.vcxproj | 1 - rpcs3/rpcs3.vcxproj.filters | 3 - 7 files changed, 450 insertions(+), 422 deletions(-) create mode 100644 rpcs3/Emu/SysCalls/Modules/libsnd3.cpp create mode 100644 rpcs3/Emu/SysCalls/Modules/libsnd3.h diff --git a/rpcs3/Emu/Audio/cellAudio.h b/rpcs3/Emu/Audio/cellAudio.h index 2823dcab50..501146443c 100644 --- a/rpcs3/Emu/Audio/cellAudio.h +++ b/rpcs3/Emu/Audio/cellAudio.h @@ -21,24 +21,6 @@ enum CELL_AUDIO_ERROR_EVENT_QUEUE = 0x8031070d, CELL_AUDIO_ERROR_AUDIOSYSTEM_NOT_FOUND = 0x8031070e, CELL_AUDIO_ERROR_TAG_NOT_FOUND = 0x8031070f, - - //libsnd3 Error Codes - CELL_SND3_ERROR_PARAM = 0x80310301, - CELL_SND3_ERROR_CREATE_MUTEX = 0x80310302, - CELL_SND3_ERROR_SYNTH = 0x80310303, - CELL_SND3_ERROR_ALREADY = 0x80310304, - CELL_SND3_ERROR_NOTINIT = 0x80310305, - CELL_SND3_ERROR_SMFFULL = 0x80310306, - CELL_SND3_ERROR_HD3ID = 0x80310307, - CELL_SND3_ERROR_SMF = 0x80310308, - CELL_SND3_ERROR_SMFCTX = 0x80310309, - CELL_SND3_ERROR_FORMAT = 0x8031030a, - CELL_SND3_ERROR_SMFID = 0x8031030b, - CELL_SND3_ERROR_SOUNDDATAFULL = 0x8031030c, - CELL_SND3_ERROR_VOICENUM = 0x8031030d, - CELL_SND3_ERROR_RESERVEDVOICE = 0x8031030e, - CELL_SND3_ERROR_REQUESTQUEFULL = 0x8031030f, - CELL_SND3_ERROR_OUTPUTMODE = 0x80310310, }; // constants @@ -137,36 +119,4 @@ struct AudioConfig //custom structure } }; -extern AudioConfig m_config; - -//libsnd3 datatypes -struct CellSnd3DataCtx -{ - s8 system; //[CELL_SND3_DATA_CTX_SIZE], unknown identifier -}; - -struct CellSnd3SmfCtx -{ - s8 system; //[CELL_SND3_SMF_CTX_SIZE], unknown identifier -}; - -struct CellSnd3KeyOnParam -{ - u8 vel; - u8 pan; - u8 panEx; - be_t addPitch; -}; - -struct CellSnd3VoiceBitCtx -{ - be_t core; //[CELL_SND3_MAX_CORE], unknown identifier -}; - -struct CellSnd3RequestQueueCtx -{ - void *frontQueue; - be_t frontQueueSize; - void *rearQueue; - be_t rearQueueSize; -}; +extern AudioConfig m_config; \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index aa4a09cd86..aacc9ea3ff 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -140,7 +140,7 @@ int cellAudioInit() auto buf = (be_t*)&Memory[buf_addr]; static const float k = 1.0f; - const float m = (port.level == 0.0f) ? 1.0f : port.level; + const float m = port.level; if (port.channel == 2) { @@ -209,12 +209,24 @@ int cellAudioInit() memset(buf, 0, block_size * sizeof(float)); } - // convert the data from float to u16 and clip: + // convert the data from float to u16 with clipping: if (!first_mix) { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) + /*for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) { oal_buffer[oal_pos][oal_buffer_offset + i] = (s16)(min(max(buffer[i] * 0x8000, -0x8000), 0x7fff)); + }*/ + // 2x MULPS + // 2x MAXPS (optional) + // 2x MINPS (optional) + // 2x CVTPS2DQ (converts float to s32) + // PACKSSDW (converts s32 to s16 with clipping) + for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 8) + { + static const __m128 float2u16 = { 0x8000, 0x8000, 0x8000, 0x8000 }; + (__m128i&)(oal_buffer[oal_pos][oal_buffer_offset + i]) = _mm_packs_epi32( + _mm_cvtps_epi32(_mm_mul_ps((__m128&)(buffer[i]), float2u16)), + _mm_cvtps_epi32(_mm_mul_ps((__m128&)(buffer[i + 4]), float2u16))); } } @@ -274,10 +286,8 @@ int cellAudioInit() } } - const u64 stamp4 = get_system_time(); - //ConLog.Write("Audio perf: start=%d (access=%d, AddData=%d, events=%d, dump=%d)", - //stamp0 - m_config.start_time, stamp1-stamp0, stamp2-stamp1, stamp3-stamp2, stamp4-stamp3); + //stamp0 - m_config.start_time, stamp1 - stamp0, stamp2 - stamp1, stamp3 - stamp2, get_system_time() - stamp3); } ConLog.Write("Audio finished"); abort: @@ -374,7 +384,14 @@ int cellAudioPortOpen(mem_ptr_t audioParam, mem32_t portNum) port.channel = audioParam->nChannel; port.block = audioParam->nBlock; port.attr = audioParam->attr; - port.level = audioParam->level; + if (port.attr & CELL_AUDIO_PORTATTR_INITLEVEL) + { + port.level = audioParam->level; + } + else + { + port.level = 1.0f; + } portNum = i; cellAudio.Warning("*** audio port opened(nChannel=%d, nBlock=%d, attr=0x%llx, level=%f): port = %d", @@ -723,321 +740,6 @@ int cellAudioUnsetPersonalDevice(int iPersonalStream) return CELL_OK; } -//*libsnd3 Functions, NOT active in this moment -s32 cellSnd3Init() //u32 maxVoice, u32 samples, CellSnd3RequestQueueCtx *queue -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3Exit() -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SetOutputMode() //u32 mode -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3Synthesis() //float *pOutL, float *pOutR -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SynthesisEx() //float *pOutL, float *pOutR, float *pOutRL, float *pOutRR -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceSetReserveMode() //u32 voiceNum, u32 reserveMode -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3BindSoundData() //CellSnd3DataCtx *snd3Ctx, void *hd3, u32 synthMemOffset -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3UnbindSoundData(u32 hd3ID) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3NoteOnByTone() //u32 hd3ID, u32 toneIndex, u32 note, u32 keyOnID, CellSnd3KeyOnParam *keyOnParam -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3KeyOnByTone() //u32 hd3ID, u32 toneIndex, u32 pitch,u32 keyOnID,CellSnd3KeyOnParam *keyOnParam -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3VoiceNoteOnByTone() //u32 hd3ID, u32 voiceNum, u32 toneIndex, u32 note, u32 keyOnID, CellSnd3KeyOnParam *keyOnParam -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3VoiceKeyOnByTone() //u32 hd3ID, u32 voiceNum, u32 toneIndex, u32 pitch, u32 keyOnID, CellSnd3KeyOnParam *keyOnParam -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3VoiceSetSustainHold(u32 voiceNum, u32 sustainHold) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceKeyOff(u32 voiceNum) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceSetPitch(u32 voiceNum, s32 addPitch) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceSetVelocity(u32 voiceNum, u32 velocity) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceSetPanpot(u32 voiceNum, u32 panpot) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceSetPanpotEx(u32 voiceNum, u32 panpotEx) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceSetPitchBend(u32 voiceNum, u32 bendValue) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceAllKeyOff() -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceGetEnvelope(u32 voiceNum) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3VoiceGetStatus() //u32 voiceNum -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -u32 cellSnd3KeyOffByID(u32 keyOnID) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3GetVoice() //u32 midiChannel, u32 keyOnID, CellSnd3VoiceBitCtx *voiceBit -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3GetVoiceByID() //u32 keyOnID, CellSnd3VoiceBitCtx *voiceBit -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3NoteOn() //u32 hd3ID, u32 midiChannel, u32 midiProgram, u32 midiNote, u32 sustain,CellSnd3KeyOnParam *keyOnParam, u32 keyOnID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3NoteOff(u32 midiChannel, u32 midiNote, u32 keyOnID) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SetSustainHold(u32 midiChannel, u32 sustainHold, u32 ID) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SetEffectType(u16 effectType, s16 returnVol, u16 delay, u16 feedback) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -u16 cellSnd3Note2Pitch() //u16 center_note, u16 center_fine, u16 note, s16 fine -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -u16 cellSnd3Pitch2Note() //u16 center_note, u16 center_fine, u16 pitch -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3SMFBind() //CellSnd3SmfCtx *smfCtx, void *smf, u32 hd3ID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3SMFUnbind() //u32 smfID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3SMFPlay(u32 smfID, u32 playVelocity, u32 playPan, u32 playCount) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFPlayEx(u32 smfID, u32 playVelocity, u32 playPan, u32 playPanEx, u32 playCount) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFPause(u32 smfID) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFResume(u32 smfID) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFStop(u32 smfID) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFAddTempo(u32 smfID, s32 addTempo) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFGetTempo() //u32 smfID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3SMFSetPlayVelocity(u32 smfID, u32 playVelocity) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFGetPlayVelocity() //u32 smfID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3SMFSetPlayPanpot(u32 smfID, u32 playPanpot) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFSetPlayPanpotEx(u32 smfID, u32 playPanpotEx) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFGetPlayPanpot() //u32 smfID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3SMFGetPlayPanpotEx() //u32 smfID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3SMFGetPlayStatus() //u32 smfID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; //it's NOT real value - //TODO -} - -s32 cellSnd3SMFSetPlayChannel(u32 smfID, u32 playChannelBit) -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFGetPlayChannel() //u32 smfID, u32 *playChannelBit -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - -s32 cellSnd3SMFGetKeyOnID() //u32 smfID, u32 midiChannel, u32 *keyOnID -{ - UNIMPLEMENTED_FUNC(cellAudio); - return CELL_OK; -} - void cellAudio_init() { cellAudio.AddFunc(0x0b168f92, cellAudioInit); diff --git a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp index ba812cb2cb..abfd40b825 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSync.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSync.cpp @@ -25,11 +25,13 @@ enum #pragma pack(push, 1) struct CellSyncMutex { - be_t m_freed; - be_t m_order; - volatile u32& m_data(){ - return *reinterpret_cast(this); - }; + be_t m_freed; + be_t m_order; + + volatile u32& m_data() + { + return *reinterpret_cast(this); + }; /* (???) Initialize: set zeros (???) Lock: increase m_order and wait until m_freed == old m_order @@ -52,16 +54,8 @@ int cellSyncMutexInitialize(mem_ptr_t mutex) return CELL_SYNC_ERROR_ALIGN; } - { - SMutexLocker lock(reservation.mutex); - if ((reservation.addr + reservation.size > mutex.GetAddr() && reservation.addr <= mutex.GetAddr() + 4) || - (mutex.GetAddr() + 4 > reservation.addr && mutex.GetAddr() <= reservation.addr + reservation.size)) - { - reservation.clear(); - } - mutex->m_data() = 0; - return CELL_OK; - } + mutex->m_data() = 0; + return CELL_OK; } int cellSyncMutexLock(mem_ptr_t mutex) @@ -78,22 +72,18 @@ int cellSyncMutexLock(mem_ptr_t mutex) } be_t old_order; + while (true) { - SMutexLocker lock(reservation.mutex); - if ((reservation.addr + reservation.size > mutex.GetAddr() && reservation.addr <= mutex.GetAddr() + 4) || - (mutex.GetAddr() + 4 > reservation.addr && mutex.GetAddr() <= reservation.addr + reservation.size)) - { - reservation.clear(); - } - old_order = mutex->m_order; - mutex->m_order = mutex->m_order + 1; - if (old_order == mutex->m_freed) - { - return CELL_OK; - } + const u32 old_data = mutex->m_data(); + CellSyncMutex new_mutex; + new_mutex.m_data() = old_data; + + old_order = new_mutex.m_order; + new_mutex.m_order++; + if (InterlockedCompareExchange(&mutex->m_data(), new_mutex.m_data(), old_data) == old_data) break; } - while (old_order != Memory.Read16(mutex.GetAddr())) + while (old_order != mutex->m_freed) { Sleep(1); if (Emu.IsStopped()) @@ -118,20 +108,28 @@ int cellSyncMutexTryLock(mem_ptr_t mutex) { return CELL_SYNC_ERROR_ALIGN; } + + int res; + + while (true) { - SMutexLocker lock(reservation.mutex); - if ((reservation.addr + reservation.size > mutex.GetAddr() && reservation.addr <= mutex.GetAddr() + 4) || - (mutex.GetAddr() + 4 > reservation.addr && mutex.GetAddr() <= reservation.addr + reservation.size)) + const u32 old_data = mutex->m_data(); + CellSyncMutex new_mutex; + new_mutex.m_data() = old_data; + + if (new_mutex.m_order != new_mutex.m_freed) { - reservation.clear(); + res = CELL_SYNC_ERROR_BUSY; } - if (mutex->m_order != mutex->m_freed) + else { - return CELL_SYNC_ERROR_BUSY; + new_mutex.m_order++; + res = CELL_OK; } - mutex->m_order = mutex->m_order + 1; - return CELL_OK; + if (InterlockedCompareExchange(&mutex->m_data(), new_mutex.m_data(), old_data) == old_data) break; } + + return res; } int cellSyncMutexUnlock(mem_ptr_t mutex) @@ -147,16 +145,17 @@ int cellSyncMutexUnlock(mem_ptr_t mutex) return CELL_SYNC_ERROR_ALIGN; } - { /* global mutex */ - SMutexLocker lock(reservation.mutex); - if ((reservation.addr + reservation.size > mutex.GetAddr() && reservation.addr <= mutex.GetAddr() + 4) || - (mutex.GetAddr() + 4 > reservation.addr && mutex.GetAddr() <= reservation.addr + reservation.size)) - { - reservation.clear(); - } - mutex->m_freed = mutex->m_freed + 1; - return CELL_OK; + while (true) + { + const u32 old_data = mutex->m_data(); + CellSyncMutex new_mutex; + new_mutex.m_data() = old_data; + + new_mutex.m_freed++; + if (InterlockedCompareExchange(&mutex->m_data(), new_mutex.m_data(), old_data) == old_data) break; } + + return CELL_OK; } void cellSync_init() diff --git a/rpcs3/Emu/SysCalls/Modules/libsnd3.cpp b/rpcs3/Emu/SysCalls/Modules/libsnd3.cpp new file mode 100644 index 0000000000..758a22b620 --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/libsnd3.cpp @@ -0,0 +1,327 @@ +#include "stdafx.h" +#include "Emu/SysCalls/SysCalls.h" +#include "Emu/SysCalls/SC_FUNC.h" + +void libsnd3_init(); +Module libsnd3("libsnd3", libsnd3_init); + +#include "libsnd3.h" + +s32 cellSnd3Init() //u32 maxVoice, u32 samples, CellSnd3RequestQueueCtx *queue +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3Exit() +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SetOutputMode() //u32 mode +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3Synthesis() //float *pOutL, float *pOutR +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SynthesisEx() //float *pOutL, float *pOutR, float *pOutRL, float *pOutRR +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceSetReserveMode() //u32 voiceNum, u32 reserveMode +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3BindSoundData() //CellSnd3DataCtx *snd3Ctx, void *hd3, u32 synthMemOffset +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3UnbindSoundData(u32 hd3ID) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3NoteOnByTone() //u32 hd3ID, u32 toneIndex, u32 note, u32 keyOnID, CellSnd3KeyOnParam *keyOnParam +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3KeyOnByTone() //u32 hd3ID, u32 toneIndex, u32 pitch,u32 keyOnID,CellSnd3KeyOnParam *keyOnParam +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3VoiceNoteOnByTone() //u32 hd3ID, u32 voiceNum, u32 toneIndex, u32 note, u32 keyOnID, CellSnd3KeyOnParam *keyOnParam +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3VoiceKeyOnByTone() //u32 hd3ID, u32 voiceNum, u32 toneIndex, u32 pitch, u32 keyOnID, CellSnd3KeyOnParam *keyOnParam +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3VoiceSetSustainHold(u32 voiceNum, u32 sustainHold) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceKeyOff(u32 voiceNum) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceSetPitch(u32 voiceNum, s32 addPitch) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceSetVelocity(u32 voiceNum, u32 velocity) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceSetPanpot(u32 voiceNum, u32 panpot) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceSetPanpotEx(u32 voiceNum, u32 panpotEx) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceSetPitchBend(u32 voiceNum, u32 bendValue) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceAllKeyOff() +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceGetEnvelope(u32 voiceNum) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3VoiceGetStatus() //u32 voiceNum +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +u32 cellSnd3KeyOffByID(u32 keyOnID) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3GetVoice() //u32 midiChannel, u32 keyOnID, CellSnd3VoiceBitCtx *voiceBit +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3GetVoiceByID() //u32 keyOnID, CellSnd3VoiceBitCtx *voiceBit +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3NoteOn() //u32 hd3ID, u32 midiChannel, u32 midiProgram, u32 midiNote, u32 sustain,CellSnd3KeyOnParam *keyOnParam, u32 keyOnID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3NoteOff(u32 midiChannel, u32 midiNote, u32 keyOnID) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SetSustainHold(u32 midiChannel, u32 sustainHold, u32 ID) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SetEffectType(u16 effectType, s16 returnVol, u16 delay, u16 feedback) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +u16 cellSnd3Note2Pitch() //u16 center_note, u16 center_fine, u16 note, s16 fine +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +u16 cellSnd3Pitch2Note() //u16 center_note, u16 center_fine, u16 pitch +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3SMFBind() //CellSnd3SmfCtx *smfCtx, void *smf, u32 hd3ID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3SMFUnbind() //u32 smfID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3SMFPlay(u32 smfID, u32 playVelocity, u32 playPan, u32 playCount) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFPlayEx(u32 smfID, u32 playVelocity, u32 playPan, u32 playPanEx, u32 playCount) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFPause(u32 smfID) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFResume(u32 smfID) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFStop(u32 smfID) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFAddTempo(u32 smfID, s32 addTempo) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFGetTempo() //u32 smfID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3SMFSetPlayVelocity(u32 smfID, u32 playVelocity) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFGetPlayVelocity() //u32 smfID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3SMFSetPlayPanpot(u32 smfID, u32 playPanpot) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFSetPlayPanpotEx(u32 smfID, u32 playPanpotEx) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFGetPlayPanpot() //u32 smfID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3SMFGetPlayPanpotEx() //u32 smfID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3SMFGetPlayStatus() //u32 smfID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; //it's NOT real value + //TODO +} + +s32 cellSnd3SMFSetPlayChannel(u32 smfID, u32 playChannelBit) +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFGetPlayChannel() //u32 smfID, u32 *playChannelBit +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +s32 cellSnd3SMFGetKeyOnID() //u32 smfID, u32 midiChannel, u32 *keyOnID +{ + UNIMPLEMENTED_FUNC(libsnd3); + return CELL_OK; +} + +void libsnd3_init() +{ + +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/Modules/libsnd3.h b/rpcs3/Emu/SysCalls/Modules/libsnd3.h new file mode 100644 index 0000000000..a3a49c7a0e --- /dev/null +++ b/rpcs3/Emu/SysCalls/Modules/libsnd3.h @@ -0,0 +1,54 @@ +#pragma once + +//libsnd3 Error Codes +enum +{ + CELL_SND3_ERROR_PARAM = 0x80310301, + CELL_SND3_ERROR_CREATE_MUTEX = 0x80310302, + CELL_SND3_ERROR_SYNTH = 0x80310303, + CELL_SND3_ERROR_ALREADY = 0x80310304, + CELL_SND3_ERROR_NOTINIT = 0x80310305, + CELL_SND3_ERROR_SMFFULL = 0x80310306, + CELL_SND3_ERROR_HD3ID = 0x80310307, + CELL_SND3_ERROR_SMF = 0x80310308, + CELL_SND3_ERROR_SMFCTX = 0x80310309, + CELL_SND3_ERROR_FORMAT = 0x8031030a, + CELL_SND3_ERROR_SMFID = 0x8031030b, + CELL_SND3_ERROR_SOUNDDATAFULL = 0x8031030c, + CELL_SND3_ERROR_VOICENUM = 0x8031030d, + CELL_SND3_ERROR_RESERVEDVOICE = 0x8031030e, + CELL_SND3_ERROR_REQUESTQUEFULL = 0x8031030f, + CELL_SND3_ERROR_OUTPUTMODE = 0x80310310, +}; + +//libsnd3 datatypes +struct CellSnd3DataCtx +{ + s8 system; //[CELL_SND3_DATA_CTX_SIZE], unknown identifier +}; + +struct CellSnd3SmfCtx +{ + s8 system; //[CELL_SND3_SMF_CTX_SIZE], unknown identifier +}; + +struct CellSnd3KeyOnParam +{ + u8 vel; + u8 pan; + u8 panEx; + be_t addPitch; +}; + +struct CellSnd3VoiceBitCtx +{ + be_t core; //[CELL_SND3_MAX_CORE], unknown identifier +}; + +struct CellSnd3RequestQueueCtx +{ + void *frontQueue; + be_t frontQueueSize; + void *rearQueue; + be_t rearQueueSize; +}; \ No newline at end of file diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index db1fa9e1d4..5aa56519bc 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -314,7 +314,6 @@ - diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index d3e2c7f3d1..1c1ed0a365 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -487,9 +487,6 @@ Utilities - - Emu\SysCalls\Modules - From 24eb97f28712b9bed50f5227e6f1a78f1856cd35 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 4 Apr 2014 00:46:40 +0400 Subject: [PATCH 13/14] AudioDumper: 8ch output --- rpcs3/Emu/Audio/AudioDumper.cpp | 16 +- rpcs3/Emu/Audio/AudioDumper.h | 1 + rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 165 +++++++++++++++++---- rpcs3/Emu/SysCalls/Modules/cellDmux.cpp | 22 ++- rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp | 4 +- rpcs3/Emu/SysCalls/Modules/libmixer.cpp | 20 +-- 6 files changed, 169 insertions(+), 59 deletions(-) diff --git a/rpcs3/Emu/Audio/AudioDumper.cpp b/rpcs3/Emu/Audio/AudioDumper.cpp index 118ffd6623..1a2e61fea2 100644 --- a/rpcs3/Emu/Audio/AudioDumper.cpp +++ b/rpcs3/Emu/Audio/AudioDumper.cpp @@ -11,9 +11,7 @@ AudioDumper::~AudioDumper() bool AudioDumper::Init() { - if(m_output.Open("audio.wav", wxFile::write)) - return true; - return false; + return m_output.Open("audio.wav", wxFile::write); } void AudioDumper::WriteHeader() @@ -23,16 +21,18 @@ void AudioDumper::WriteHeader() size_t AudioDumper::WriteData(const void* buffer, size_t size) { - /*for (u32 i = 0; i < size / 8; i++) +#ifdef SKIP_EMPTY_AUDIO + bool do_save = false; + for (u32 i = 0; i < size / 8; i++) { - if (((u64*)buffer)[i]) goto process; + if (((u64*)buffer)[i]) do_save = true; } for (u32 i = 0; i < size % 8; i++) { - if (((u8*)buffer)[i + (size & ~7)]) goto process; + if (((u8*)buffer)[i + (size & ~7)]) do_save = true; } - return size; // ignore empty data -process:*/ + if (!do_save) return size; // ignore empty data +#endif size_t ret = m_output.Write(buffer, size); m_header.Size += ret; m_header.RIFF.Size += ret; diff --git a/rpcs3/Emu/Audio/AudioDumper.h b/rpcs3/Emu/Audio/AudioDumper.h index f9ac030476..11a2f6e7e9 100644 --- a/rpcs3/Emu/Audio/AudioDumper.h +++ b/rpcs3/Emu/Audio/AudioDumper.h @@ -65,4 +65,5 @@ public: void WriteHeader(); size_t WriteData(const void* buffer, size_t size); void Finalize(); + const u8 GetCh() const { return m_header.FMT.NumChannels; } }; diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index aacc9ea3ff..310cd9ec9d 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -36,13 +36,13 @@ int cellAudioInit() thread t("Audio Thread", []() { - AudioDumper m_dump(2); // WAV file header (stereo) + AudioDumper m_dump(8); // WAV file header (8 ch) bool do_dump = Ini.AudioDumpToFile.GetValue(); if (do_dump && !m_dump.Init()) { - ConLog.Error("Audio aborted: cannot create file!"); + ConLog.Error("Audio aborted: AudioDumper::Init() failed"); return; } @@ -51,10 +51,11 @@ int cellAudioInit() if (Ini.AudioDumpToFile.GetValue()) m_dump.WriteHeader(); - float buffer[2*256]; // intermediate buffer for 2 channels + float buf2ch[2 * 256]; // intermediate buffer for 2 channels + float buf8ch[8 * 256]; // intermediate buffer for 8 channels uint oal_buffer_offset = 0; - uint oal_buffer_size = sizeof(buffer) / sizeof(float); + uint oal_buffer_size = sizeof(buf2ch) / sizeof(float); std::unique_ptr oal_buffer[32]; SQueue queue; for (u32 i = 0; i < sizeof(oal_buffer) / sizeof(oal_buffer[0]); i++) @@ -139,25 +140,45 @@ int cellAudioInit() auto buf = (be_t*)&Memory[buf_addr]; - static const float k = 1.0f; + static const float k = 1.0f; // may be 0.5f const float m = port.level; if (port.channel == 2) { if (first_mix) { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { // reverse byte order - buffer[i] = buf[i] * m; + const float left = buf[i + 0] * m; + const float right = buf[i + 1] * m; + + buf2ch[i + 0] = left; + buf2ch[i + 1] = right; + + buf8ch[i * 4 + 0] = left; + buf8ch[i * 4 + 1] = right; + buf8ch[i * 4 + 2] = 0.0f; + buf8ch[i * 4 + 3] = 0.0f; + buf8ch[i * 4 + 4] = 0.0f; + buf8ch[i * 4 + 5] = 0.0f; + buf8ch[i * 4 + 6] = 0.0f; + buf8ch[i * 4 + 7] = 0.0f; } first_mix = false; } else { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i++) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { - buffer[i] += buf[i] * m; + const float left = buf[i + 0] * m; + const float right = buf[i + 1] * m; + + buf2ch[i + 0] += left; + buf2ch[i + 1] += right; + + buf8ch[i * 4 + 0] += left; + buf8ch[i * 4 + 1] += right; } } } @@ -165,21 +186,51 @@ int cellAudioInit() { if (first_mix) { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { - const float center = (buf[i*3+2] + buf[i*3+3]) * 0.708f; - buffer[i] = (buf[i*3] + buf[i*3+4] + center) * k * m; - buffer[i+1] = (buf[i*3+1] + buf[i*3+5] + center) * k * m; + const float left = buf[i * 3 + 0] * m; + const float right = buf[i * 3 + 1] * m; + const float center = buf[i * 3 + 2] * m; + const float low_freq = buf[i * 3 + 3] * m; + const float rear_left = buf[i * 3 + 4] * m; + const float rear_right = buf[i * 3 + 5] * m; + + const float mid = (center + low_freq) * 0.708f; + buf2ch[i + 0] = (left + rear_left + mid) * k; + buf2ch[i + 1] = (right + rear_right + mid) * k; + + buf8ch[i * 4 + 0] = left; + buf8ch[i * 4 + 1] = right; + buf8ch[i * 4 + 2] = center; + buf8ch[i * 4 + 3] = low_freq; + buf8ch[i * 4 + 4] = rear_left; + buf8ch[i * 4 + 5] = rear_right; + buf8ch[i * 4 + 6] = 0.0f; + buf8ch[i * 4 + 7] = 0.0f; } first_mix = false; } else { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { - const float center = (buf[i*3+2] + buf[i*3+3]) * 0.708f; - buffer[i] += (buf[i*3] + buf[i*3+4] + center) * k * m; - buffer[i+1] += (buf[i*3+1] + buf[i*3+5] + center) * k * m; + const float left = buf[i * 3 + 0] * m; + const float right = buf[i * 3 + 1] * m; + const float center = buf[i * 3 + 2] * m; + const float low_freq = buf[i * 3 + 3] * m; + const float rear_left = buf[i * 3 + 4] * m; + const float rear_right = buf[i * 3 + 5] * m; + + const float mid = (center + low_freq) * 0.708f; + buf2ch[i + 0] += (left + rear_left + mid) * k; + buf2ch[i + 1] += (right + rear_right + mid) * k; + + buf8ch[i * 4 + 0] += left; + buf8ch[i * 4 + 1] += right; + buf8ch[i * 4 + 2] += center; + buf8ch[i * 4 + 3] += low_freq; + buf8ch[i * 4 + 4] += rear_left; + buf8ch[i * 4 + 5] += rear_right; } } } @@ -187,21 +238,57 @@ int cellAudioInit() { if (first_mix) { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { - const float center = (buf[i*4+2] + buf[i*4+3]) * 0.708f; - buffer[i] = (buf[i*4] + buf[i*4+4] + buf[i*4+6] + center) * k * m; - buffer[i+1] = (buf[i*4+1] + buf[i*4+5] + buf[i*4+7] + center) * k * m; + const float left = buf[i * 4 + 0] * m; + const float right = buf[i * 4 + 1] * m; + const float center = buf[i * 4 + 2] * m; + const float low_freq = buf[i * 4 + 3] * m; + const float rear_left = buf[i * 4 + 4] * m; + const float rear_right = buf[i * 4 + 5] * m; + const float side_left = buf[i * 4 + 6] * m; + const float side_right = buf[i * 4 + 7] * m; + + const float mid = (center + low_freq) * 0.708f; + buf2ch[i + 0] = (left + rear_left + side_left + mid) * k; + buf2ch[i + 1] = (right + rear_right + side_right + mid) * k; + + buf8ch[i * 4 + 0] = left; + buf8ch[i * 4 + 1] = right; + buf8ch[i * 4 + 2] = center; + buf8ch[i * 4 + 3] = low_freq; + buf8ch[i * 4 + 4] = rear_left; + buf8ch[i * 4 + 5] = rear_right; + buf8ch[i * 4 + 6] = side_left; + buf8ch[i * 4 + 7] = side_right; } first_mix = false; } else { - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 2) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 2) { - const float center = (buf[i*4+2] + buf[i*4+3]) * 0.708f; - buffer[i] += (buf[i*4] + buf[i*4+4] + buf[i*4+6] + center) * k * m; - buffer[i+1] += (buf[i*4+1] + buf[i*4+5] + buf[i*4+7] + center) * k * m; + const float left = buf[i * 4 + 0] * m; + const float right = buf[i * 4 + 1] * m; + const float center = buf[i * 4 + 2] * m; + const float low_freq = buf[i * 4 + 3] * m; + const float rear_left = buf[i * 4 + 4] * m; + const float rear_right = buf[i * 4 + 5] * m; + const float side_left = buf[i * 4 + 6] * m; + const float side_right = buf[i * 4 + 7] * m; + + const float mid = (center + low_freq) * 0.708f; + buf2ch[i + 0] += (left + rear_left + side_left + mid) * k; + buf2ch[i + 1] += (right + rear_right + side_right + mid) * k; + + buf8ch[i * 4 + 0] += left; + buf8ch[i * 4 + 1] += right; + buf8ch[i * 4 + 2] += center; + buf8ch[i * 4 + 3] += low_freq; + buf8ch[i * 4 + 4] += rear_left; + buf8ch[i * 4 + 5] += rear_right; + buf8ch[i * 4 + 6] += side_left; + buf8ch[i * 4 + 7] += side_right; } } } @@ -221,12 +308,12 @@ int cellAudioInit() // 2x MINPS (optional) // 2x CVTPS2DQ (converts float to s32) // PACKSSDW (converts s32 to s16 with clipping) - for (u32 i = 0; i < (sizeof(buffer) / sizeof(float)); i += 8) + for (u32 i = 0; i < (sizeof(buf2ch) / sizeof(float)); i += 8) { static const __m128 float2u16 = { 0x8000, 0x8000, 0x8000, 0x8000 }; (__m128i&)(oal_buffer[oal_pos][oal_buffer_offset + i]) = _mm_packs_epi32( - _mm_cvtps_epi32(_mm_mul_ps((__m128&)(buffer[i]), float2u16)), - _mm_cvtps_epi32(_mm_mul_ps((__m128&)(buffer[i + 4]), float2u16))); + _mm_cvtps_epi32(_mm_mul_ps((__m128&)(buf2ch[i]), float2u16)), + _mm_cvtps_epi32(_mm_mul_ps((__m128&)(buf2ch[i + 4]), float2u16))); } } @@ -234,7 +321,7 @@ int cellAudioInit() if (!first_mix) { - oal_buffer_offset += sizeof(buffer) / sizeof(float); + oal_buffer_offset += sizeof(buf2ch) / sizeof(float); if(oal_buffer_offset >= oal_buffer_size) { @@ -279,9 +366,25 @@ int cellAudioInit() if (do_dump && !first_mix) { - if (m_dump.WriteData(&buffer, sizeof(buffer)) != sizeof(buffer)) // write file data + if (m_dump.GetCh() == 8) { - ConLog.Error("Port aborted: cannot write file!"); + if (m_dump.WriteData(&buf8ch, sizeof(buf8ch)) != sizeof(buf8ch)) // write file data + { + ConLog.Error("Audio aborted: AudioDumper::WriteData() failed"); + goto abort; + } + } + else if (m_dump.GetCh() == 2) + { + if (m_dump.WriteData(&buf2ch, sizeof(buf2ch)) != sizeof(buf2ch)) // write file data + { + ConLog.Error("Audio aborted: AudioDumper::WriteData() failed"); + goto abort; + } + } + else + { + ConLog.Error("Audio aborted: unknown AudioDumper::GetCh() value (%d)", m_dump.GetCh()); goto abort; } } diff --git a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp index 2fac7e0bae..4b9aef7444 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellDmux.cpp @@ -337,8 +337,13 @@ u32 dmuxOpen(Demuxer* data) cb.Branch(task.type == dmuxResetStreamAndWaitDone);*/ dmux.dmuxCb->ExecAsCallback(dmux.cbFunc, task.type == dmuxResetStreamAndWaitDone, dmux.id, dmuxMsg.GetAddr(), dmux.cbArg); + updates_signaled++; dmux.is_running = false; + if (task.type == dmuxResetStreamAndWaitDone) + { + dmux.fbSetStream.Push(0); + } } break; @@ -675,16 +680,17 @@ int cellDmuxResetStreamAndWaitDone(u32 demuxerHandle) dmux->job.Push(DemuxerTask(dmuxResetStreamAndWaitDone)); - while (dmux->is_running) + u32 addr; + if (!dmux->fbSetStream.Pop(addr)) { - if (Emu.IsStopped()) - { - ConLog.Warning("cellDmuxResetStreamAndWaitDone(%d) aborted", demuxerHandle); - break; - } - Sleep(1); + ConLog.Warning("cellDmuxResetStreamAndWaitDone(%d) aborted (fbSetStream.Pop())", demuxerHandle); + return CELL_OK; + } + if (addr != 0) + { + ConLog.Error("cellDmuxResetStreamAndWaitDone(%d): wrong stream queued (0x%x)", demuxerHandle, addr); + Emu.Pause(); } - return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp index c261d848e9..ec9ac69f31 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellSysutil.cpp @@ -532,7 +532,7 @@ int cellAudioOutGetSoundAvailability(u32 audioOut, u32 type, u32 fs, u32 option) option = 0; - int available = 2; // should be at least 2 + int available = 8; // should be at least 2 switch(fs) { @@ -573,7 +573,7 @@ int cellAudioOutGetSoundAvailability2(u32 audioOut, u32 type, u32 fs, u32 ch, u3 option = 0; - int available = 2; // should be at least 2 + int available = 8; // should be at least 2 switch(fs) { diff --git a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp index f441922fa7..e49ac699b0 100644 --- a/rpcs3/Emu/SysCalls/Modules/libmixer.cpp +++ b/rpcs3/Emu/SysCalls/Modules/libmixer.cpp @@ -56,8 +56,8 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl for (u32 i = 0; i < samples; i++) { const float center = *(be_t*)&Memory[addr + i * sizeof(float)]; - mixdata[i*8+0] += center; - mixdata[i*8+1] += center; + mixdata[i * 8 + 0] += center; + mixdata[i * 8 + 1] += center; } } else if (type == CELL_SURMIXER_CHSTRIP_TYPE2A) @@ -67,8 +67,8 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl { const float left = *(be_t*)&Memory[addr + i * 2 * sizeof(float)]; const float right = *(be_t*)&Memory[addr + (i * 2 + 1) * sizeof(float)]; - mixdata[i*8+0] += left; - mixdata[i*8+1] += right; + mixdata[i * 8 + 0] += left; + mixdata[i * 8 + 1] += right; } } else if (type == CELL_SURMIXER_CHSTRIP_TYPE6A) @@ -82,12 +82,12 @@ int cellAANAddData(u32 aan_handle, u32 aan_port, u32 offset, u32 addr, u32 sampl const float low_freq = *(be_t*)&Memory[addr + (i * 6 + 3) * sizeof(float)]; const float rear_left = *(be_t*)&Memory[addr + (i * 6 + 4) * sizeof(float)]; const float rear_right = *(be_t*)&Memory[addr + (i * 6 + 5) * sizeof(float)]; - mixdata[i*8+0] += left; - mixdata[i*8+1] += right; - mixdata[i*8+2] += center; - mixdata[i*8+3] += low_freq; - mixdata[i*8+4] += rear_left; - mixdata[i*8+5] += rear_right; + mixdata[i * 8 + 0] += left; + mixdata[i * 8 + 1] += right; + mixdata[i * 8 + 2] += center; + mixdata[i * 8 + 3] += low_freq; + mixdata[i * 8 + 4] += rear_left; + mixdata[i * 8 + 5] += rear_right; } } else if (type == CELL_SURMIXER_CHSTRIP_TYPE8A) From 82edd111e93e7d2db7f7f8b658715e60ee5c4089 Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 4 Apr 2014 19:36:53 +0400 Subject: [PATCH 14/14] asmjit submodule added --- .gitmodules | 3 +++ asmjit | 1 + 2 files changed, 4 insertions(+) create mode 160000 asmjit diff --git a/.gitmodules b/.gitmodules index c0d4ac8d2d..a45f065200 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,3 +5,6 @@ [submodule "rpcs3-ffmpeg"] path = ffmpeg url = https://github.com/hrydgard/ppsspp-ffmpeg +[submodule "asmjit"] + path = asmjit + url = https://github.com/kobalicekp/asmjit diff --git a/asmjit b/asmjit new file mode 160000 index 0000000000..5ac69447dc --- /dev/null +++ b/asmjit @@ -0,0 +1 @@ +Subproject commit 5ac69447dc2b7bca332be552cbe747051641f9e9