mirror of
https://github.com/RPCS3/rpcs3.git
synced 2024-12-27 06:21:02 +00:00
cellAudio: Move and partially fix _mxr000 hack
This commit is contained in:
parent
e410841f10
commit
730badd378
@ -10,6 +10,8 @@
|
||||
|
||||
LOG_CHANNEL(cellAudio);
|
||||
|
||||
extern void lv2_sleep(u64 timeout, ppu_thread* ppu = nullptr);
|
||||
|
||||
vm::gvar<char, AUDIO_PORT_OFFSET * AUDIO_PORT_COUNT> g_audio_buffer;
|
||||
|
||||
struct alignas(16) aligned_index_t
|
||||
@ -1252,8 +1254,6 @@ error_code cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32
|
||||
|
||||
auto& g_audio = g_fxo->get<cell_audio>();
|
||||
|
||||
std::lock_guard lock(g_audio.mutex);
|
||||
|
||||
if (!g_audio.init)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_NOT_INIT;
|
||||
@ -1319,6 +1319,16 @@ error_code cellAudioPortOpen(vm::ptr<CellAudioPortParam> audioParam, vm::ptr<u32
|
||||
cellAudio.todo("cellAudioPortOpen(): unknown attributes (0x%llx)", attr);
|
||||
}
|
||||
|
||||
// Waiting for VSH and doing some more things
|
||||
lv2_sleep(200);
|
||||
|
||||
std::lock_guard lock(g_audio.mutex);
|
||||
|
||||
if (!g_audio.init)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
// Open audio port
|
||||
audio_port* port = g_audio.open_port();
|
||||
|
||||
@ -1410,8 +1420,6 @@ error_code cellAudioPortStart(u32 portNum)
|
||||
|
||||
auto& g_audio = g_fxo->get<cell_audio>();
|
||||
|
||||
std::lock_guard lock(g_audio.mutex);
|
||||
|
||||
if (!g_audio.init)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_NOT_INIT;
|
||||
@ -1422,6 +1430,16 @@ error_code cellAudioPortStart(u32 portNum)
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
// Waiting for VSH
|
||||
lv2_sleep(30);
|
||||
|
||||
std::lock_guard lock(g_audio.mutex);
|
||||
|
||||
if (!g_audio.init)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
switch (audio_port_state state = g_audio.ports[portNum].state.compare_and_swap(audio_port_state::opened, audio_port_state::started))
|
||||
{
|
||||
case audio_port_state::closed: return CELL_AUDIO_ERROR_PORT_NOT_OPEN;
|
||||
@ -1650,10 +1668,69 @@ error_code cellAudioCreateNotifyEventQueueEx(ppu_thread& ppu, vm::ptr<u32> id, v
|
||||
return AudioCreateNotifyEventQueue(ppu, id, key, queue_type);
|
||||
}
|
||||
|
||||
error_code AudioSetNotifyEventQueue(u64 key, u32 iFlags)
|
||||
error_code AudioSetNotifyEventQueue(ppu_thread& ppu, u64 key, u32 iFlags)
|
||||
{
|
||||
auto& g_audio = g_fxo->get<cell_audio>();
|
||||
|
||||
if (!g_audio.init)
|
||||
{
|
||||
return CELL_AUDIO_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
// Waiting for VSH
|
||||
lv2_sleep(20, &ppu);
|
||||
|
||||
// Dirty hack for sound: confirm the creation of _mxr000 event queue by _cellsurMixerMain thread
|
||||
constexpr u64 c_mxr000 = 0x8000cafe0246030;
|
||||
|
||||
if (key == c_mxr000 || key == 0)
|
||||
{
|
||||
bool has_sur_mixer_thread = false;
|
||||
|
||||
for (usz count = 0; !lv2_event_queue::find(c_mxr000) && count < 100; count++)
|
||||
{
|
||||
if (has_sur_mixer_thread || idm::select<named_thread<ppu_thread>>([&](u32 id, named_thread<ppu_thread>& test_ppu)
|
||||
{
|
||||
// Confirm thread existence
|
||||
if (id == ppu.id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto ptr = test_ppu.ppu_tname.load();
|
||||
|
||||
if (!ptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return *ptr == "_cellsurMixerMain"sv;
|
||||
}).ret)
|
||||
{
|
||||
has_sur_mixer_thread = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (ppu.is_stopped())
|
||||
{
|
||||
ppu.state += cpu_flag::again;
|
||||
return {};
|
||||
}
|
||||
|
||||
cellAudio.error("AudioSetNotifyEventQueue(): Waiting for _mxr000. x%d", count);
|
||||
|
||||
lv2_sleep(50'000, &ppu);
|
||||
}
|
||||
|
||||
if (has_sur_mixer_thread && lv2_event_queue::find(c_mxr000))
|
||||
{
|
||||
key = c_mxr000;
|
||||
}
|
||||
}
|
||||
|
||||
std::lock_guard lock(g_audio.mutex);
|
||||
|
||||
if (!g_audio.init)
|
||||
@ -1687,27 +1764,33 @@ error_code AudioSetNotifyEventQueue(u64 key, u32 iFlags)
|
||||
}
|
||||
|
||||
// Set unique source associated with the key
|
||||
g_audio.keys.push_back({
|
||||
g_audio.keys.push_back
|
||||
({
|
||||
.start_period = g_audio.event_period,
|
||||
.flags = iFlags,
|
||||
.source = ((process_getpid() + u64{}) << 32) + lv2_event_port::id_base + (g_audio.key_count++ * lv2_event_port::id_step),
|
||||
.ack_timestamp = 0,
|
||||
.port = std::move(q)
|
||||
});
|
||||
|
||||
g_audio.key_count %= lv2_event_port::id_count;
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
error_code cellAudioSetNotifyEventQueue(u64 key)
|
||||
error_code cellAudioSetNotifyEventQueue(ppu_thread& ppu, u64 key)
|
||||
{
|
||||
ppu.state += cpu_flag::wait;
|
||||
|
||||
cellAudio.warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key);
|
||||
|
||||
return AudioSetNotifyEventQueue(key, 0);
|
||||
return AudioSetNotifyEventQueue(ppu, key, 0);
|
||||
}
|
||||
|
||||
error_code cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
|
||||
error_code cellAudioSetNotifyEventQueueEx(ppu_thread& ppu, u64 key, u32 iFlags)
|
||||
{
|
||||
ppu.state += cpu_flag::wait;
|
||||
|
||||
cellAudio.todo("cellAudioSetNotifyEventQueueEx(key=0x%llx, iFlags=0x%x)", key, iFlags);
|
||||
|
||||
if (iFlags & (~0u >> 5))
|
||||
@ -1715,7 +1798,7 @@ error_code cellAudioSetNotifyEventQueueEx(u64 key, u32 iFlags)
|
||||
return CELL_AUDIO_ERROR_PARAM;
|
||||
}
|
||||
|
||||
return AudioSetNotifyEventQueue(key, iFlags);
|
||||
return AudioSetNotifyEventQueue(ppu, key, iFlags);
|
||||
}
|
||||
|
||||
error_code AudioRemoveNotifyEventQueue(u64 key, u32 iFlags)
|
||||
|
@ -349,7 +349,7 @@ void disc_change_manager::insert_disc(u32 disc_type, std::string title_id)
|
||||
});
|
||||
}
|
||||
|
||||
void lv2_sleep(u64 timeout, ppu_thread* ppu = nullptr)
|
||||
extern void lv2_sleep(u64 timeout, ppu_thread* ppu = nullptr)
|
||||
{
|
||||
if (!ppu)
|
||||
{
|
||||
|
@ -591,32 +591,6 @@ error_code sys_ppu_thread_start(ppu_thread& ppu, u32 thread_id)
|
||||
{
|
||||
thread->cmd_notify++;
|
||||
thread->cmd_notify.notify_one();
|
||||
|
||||
// Dirty hack for sound: confirm the creation of _mxr000 event queue
|
||||
if (*thread->ppu_tname.load() == "_cellsurMixerMain"sv)
|
||||
{
|
||||
ppu.check_state();
|
||||
lv2_obj::sleep(ppu);
|
||||
|
||||
while (!idm::select<lv2_obj, lv2_event_queue>([](u32, lv2_event_queue& eq)
|
||||
{
|
||||
//some games do not set event queue name, though key seems constant for them
|
||||
return (eq.name == "_mxr000\0"_u64) || (eq.key == 0x8000cafe02460300);
|
||||
}))
|
||||
{
|
||||
if (ppu.is_stopped())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
thread_ctrl::wait_for(50000);
|
||||
}
|
||||
|
||||
if (ppu.test_stopped())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
|
Loading…
Reference in New Issue
Block a user