diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 430694380a..84a3b735c6 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -136,6 +136,7 @@ struct CellAudioPortConfig struct AudioPortConfig { bool m_is_audio_port_started; + bool m_is_audio_port_stopped; CellAudioPortParam m_param; const u32 m_buffer; // 64 KB or 128 KB with 8x16 config @@ -414,6 +415,7 @@ int cellAudioPortStart(u32 portNum) } m_config.m_ports[portNum]->m_is_audio_port_started = true; + m_config.m_ports[portNum]->m_is_audio_port_stopped = false; std::string t_name = "AudioPort0"; t_name[9] += portNum; @@ -426,6 +428,7 @@ int cellAudioPortStart(u32 portNum) if (port.m_param.nChannel > 8) { ConLog.Error("Port aborted: invalid channel count (%d)", port.m_param.nChannel); + port.m_is_audio_port_stopped = true; return; } @@ -437,14 +440,15 @@ int cellAudioPortStart(u32 portNum) wxFile output(output_name, wxFile::write); // create output file if (!output.IsOpened()) { - ConLog.Error("Port aborted: cannot write %s", output_name.wx_str()); + ConLog.Error("Port aborted: cannot create %s", output_name.wx_str()); + port.m_is_audio_port_stopped = true; return; } ConLog.Write("Port started"); u64 start_time = get_system_time(); - u32 counter = 0; + u64 counter = 0; output.Write(&header, sizeof(header)); // write file header @@ -454,8 +458,16 @@ int cellAudioPortStart(u32 portNum) while (port.m_is_audio_port_started) { + if (Emu.IsStopped()) + { + ConLog.Warning("Port aborted"); + goto abort; + } + + // TODO: send beforemix event (in ~2,6 ms before mixing) + // Sleep(5); // precise time of sleeping: 5,(3) ms (or 256/48000 sec) - if ((u64)counter * 256000000 / 48000 >= get_system_time() - start_time) + if (counter * 256000000 / 48000 >= get_system_time() - start_time) { Sleep(1); continue; @@ -463,27 +475,34 @@ int cellAudioPortStart(u32 portNum) counter++; + if (Emu.IsPaused()) + { + continue; + } + u32 position = index.GetValue(); // get old value memcpy(buffer, Memory + port.m_buffer + position * block_size, block_size); + memset(Memory + port.m_buffer + position * block_size, 0, block_size); index = (position + 1) % port.m_param.nBlock; // write new value + // TODO: send aftermix event (normal audio event) + for (u32 i = 0; i < block_size; i++) { // reverse byte order (TODO: use port.m_param.level) buffer[i] = re(buffer[i]); } - output.Write(&buffer, block_size); // write file data - header.Size += block_size; // update file header - header.RIFF.Size += block_size; - - if (Emu.IsStopped()) + if (output.Write(&buffer, block_size) != (size_t)block_size) // write file data { - ConLog.Write("Port aborted"); + ConLog.Error("Port aborted: cannot write %s", output_name.wx_str()); goto abort; } + + header.Size += block_size; // update file header + header.RIFF.Size += block_size; } ConLog.Write("Port finished"); abort: @@ -491,6 +510,7 @@ int cellAudioPortStart(u32 portNum) output.Write(&header, sizeof(header)); // write fixed file header output.Close(); + port.m_is_audio_port_stopped = true; }); t.detach(); @@ -535,7 +555,16 @@ int cellAudioPortStop(u32 portNum) return CELL_AUDIO_ERROR_PORT_NOT_RUN; } - m_config.m_ports[portNum]->m_is_audio_port_started = false; + m_config.m_ports[portNum]->m_is_audio_port_started = false; + while (!m_config.m_ports[portNum]->m_is_audio_port_stopped) + { + Sleep(1); + if (Emu.IsStopped()) + { + ConLog.Warning("cellAudioPortStop(%d) aborted", portNum); + break; + } + } return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp index f26061e19f..650673abf9 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Condition.cpp @@ -26,6 +26,11 @@ int sys_cond_create(mem32_t cond_id, u32 mutex_id, mem_ptr_t return CELL_ESRCH; } + if (mutex->is_recursive) + { + sys_cond.Warning("Recursive mutex(%d)", mutex_id); + } + Cond* cond = new Cond(mutex, attr->name_u64); u32 id = sys_cond.GetNewId(cond); cond_id = id; diff --git a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp index 7ec0e6f3c8..fde9c0f339 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp @@ -216,6 +216,13 @@ int cellFsStat(const u32 path_addr, mem_ptr_t sb) } } + if (path == "/dev_bdvd/PS3_GAME/USRDIR") + { + sys_fs.Warning("cellFsStat: /dev_bdvd/PS3_GAME/USRDIR mount point hack"); + sb->st_mode |= CELL_FS_S_IFDIR; + return CELL_OK; + } + // TODO: Temporary solution until vfsDir is implemented wxString real_path; Emu.GetVFS().GetDevice(path, real_path); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp index 3c8af68051..89dd8c7409 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwcond.cpp @@ -20,10 +20,18 @@ int sys_lwcond_create(mem_ptr_t lwcond, mem_ptr_t l if (lwmutex.IsGood()) { - if (lwmutex->attribute.ToBE() == se32(SYS_SYNC_RETRY)) + if (lwmutex->attribute.ToBE() & se32(SYS_SYNC_RETRY)) { sys_lwcond.Warning("Unsupported SYS_SYNC_RETRY lwmutex protocol"); } + if (lwmutex->attribute.ToBE() & se32(SYS_SYNC_RECURSIVE)) + { + sys_lwcond.Warning("Recursive lwmutex(sq=%d)", (u32)lwmutex->sleep_queue); + } + } + else + { + sys_lwcond.Warning("Invalid lwmutex address(0x%x)", lwmutex.GetAddr()); } sys_lwcond.Warning("*** lwcond created [%s] (lwmutex_addr=0x%x): id = %d", diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp index 65dc341fa1..db07fbed3b 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Lwmutex.cpp @@ -67,6 +67,9 @@ int sys_lwmutex_lock(mem_ptr_t lwmutex, u64 timeout) if (!lwmutex.IsGood()) return CELL_EFAULT; + //ConLog.Write("*** lock mutex (addr=0x%x, attr=0x%x, Nrec=%d, owner=%d, waiter=%d)", + //lwmutex.GetAddr(), (u32)lwmutex->attribute, (u32)lwmutex->recursive_count, lwmutex->owner.GetOwner(), (u32)lwmutex->waiter); + return lwmutex->lock(GetCurrentPPUThread().GetId(), timeout ? ((timeout < 1000) ? 1 : (timeout / 1000)) : 0); } @@ -85,6 +88,9 @@ int sys_lwmutex_unlock(mem_ptr_t lwmutex) if (!lwmutex.IsGood()) return CELL_EFAULT; + //ConLog.Write("*** unlocking mutex (addr=0x%x, attr=0x%x, Nrec=%d, owner=%d, waiter=%d)", + //lwmutex.GetAddr(), (u32)lwmutex->attribute, (u32)lwmutex->recursive_count, (u32)lwmutex->owner.GetOwner(), (u32)lwmutex->waiter); + return lwmutex->unlock(GetCurrentPPUThread().GetId()); }