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;