From a31160fe9933ccfbfb827d3231cb0d0c2a8d978d Mon Sep 17 00:00:00 2001 From: O1L Date: Tue, 11 Mar 2014 20:45:15 +0300 Subject: [PATCH 1/2] Fix converting audio data. Implemented some cellFsStRead functions. --- rpcs3/Emu/Audio/AL/OpenALThread.cpp | 2 +- rpcs3/Emu/Audio/AudioDumper.cpp | 2 - rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 4 +- rpcs3/Emu/SysCalls/Modules/sys_fs.cpp | 14 ++ rpcs3/Emu/SysCalls/SysCalls.h | 13 ++ rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp | 249 ++++++++++++++++++++++- rpcs3/Emu/SysCalls/lv2/SC_FileSystem.h | 31 ++- 7 files changed, 308 insertions(+), 7 deletions(-) diff --git a/rpcs3/Emu/Audio/AL/OpenALThread.cpp b/rpcs3/Emu/Audio/AL/OpenALThread.cpp index 4517f527c0..e4a461171a 100644 --- a/rpcs3/Emu/Audio/AL/OpenALThread.cpp +++ b/rpcs3/Emu/Audio/AL/OpenALThread.cpp @@ -69,7 +69,7 @@ void OpenALThread::Stop() void OpenALThread::Open(const void* src, ALsizei size) { - alGenSources(1, &mSource); // WARNING: Memory leaks! + alGenSources(1, &mSource); checkForAlError("alGenSources"); alSourcei(mSource, AL_LOOPING, AL_FALSE); diff --git a/rpcs3/Emu/Audio/AudioDumper.cpp b/rpcs3/Emu/Audio/AudioDumper.cpp index 95b83272c0..f906b3531a 100644 --- a/rpcs3/Emu/Audio/AudioDumper.cpp +++ b/rpcs3/Emu/Audio/AudioDumper.cpp @@ -24,8 +24,6 @@ void AudioDumper::WriteHeader() size_t AudioDumper::WriteData(const void* buffer, size_t size) { size_t ret = m_output.Write(buffer, size); - - return ret; } diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index 486b1720a4..145f3e7f10 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -120,7 +120,7 @@ int cellAudioInit() buffer[i] = buffer2[i]; // convert the data from float to u16 - oal_buffer[i] = (u16)((float)buffer[i] * (1 << 16)); + oal_buffer[i] = (u16)((float)buffer[i] * (1 << 15)); } first_mix = false; } @@ -131,7 +131,7 @@ int cellAudioInit() buffer[i] = (buffer[i] + buffer2[i]) * 0.5; // TODO: valid mixing // convert the data from float to u16 - oal_buffer[i] = (u16)((float)buffer[i] * (1 << 16)); + oal_buffer[i] = (u16)((float)buffer[i] * (1 << 15)); } } } diff --git a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp index cf05cbf3b7..6f9589b6c0 100644 --- a/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp +++ b/rpcs3/Emu/SysCalls/Modules/sys_fs.cpp @@ -295,5 +295,19 @@ void sys_fs_init() sys_fs.AddFunc(0x9f951810, cellFsAioFinish); sys_fs.AddFunc(0x1a108ab7, cellFsGetBlockSize); sys_fs.AddFunc(0xaa3b4bcd, cellFsGetFreeSize); + sys_fs.AddFunc(0x9b882495, cellFsGetDirectoryEntries); + sys_fs.AddFunc(0x2664c8ae, cellFsStReadInit); + sys_fs.AddFunc(0xd73938df, cellFsStReadFinish); + sys_fs.AddFunc(0xb3afee8b, cellFsStReadGetRingBuf); + sys_fs.AddFunc(0xcf34969c, cellFsStReadGetStatus); + sys_fs.AddFunc(0xbd273a88, cellFsStReadGetRegid); + sys_fs.AddFunc(0x8df28ff9, cellFsStReadStart); + sys_fs.AddFunc(0xf8e5d9a0, cellFsStReadStop); + sys_fs.AddFunc(0x27800c6b, cellFsStRead); + sys_fs.AddFunc(0x190912f6, cellFsStReadGetCurrentAddr); + sys_fs.AddFunc(0x81f33783, cellFsStReadPutCurrentAddr); + sys_fs.AddFunc(0x8f71c5b2, cellFsStReadWait); + sys_fs.AddFunc(0x866f6aec, cellFsStReadWaitCallback); + aio_init = false; } diff --git a/rpcs3/Emu/SysCalls/SysCalls.h b/rpcs3/Emu/SysCalls/SysCalls.h index c97518f7a4..9d75580371 100644 --- a/rpcs3/Emu/SysCalls/SysCalls.h +++ b/rpcs3/Emu/SysCalls/SysCalls.h @@ -262,6 +262,19 @@ extern int cellFsTruncate(u32 path_addr, u64 size); extern int cellFsFGetBlockSize(u32 fd, mem64_t sector_size, mem64_t block_size); extern int cellFsGetBlockSize(u32 path_addr, mem64_t sector_size, mem64_t block_size); extern int cellFsGetFreeSize(u32 path_addr, mem32_t block_size, mem64_t block_count); +extern int cellFsGetDirectoryEntries(u32 fd, mem_ptr_t entries, u32 entries_size, mem32_t data_count); +extern int cellFsStReadInit(u32 fd, mem_ptr_t ringbuf); +extern int cellFsStReadFinish(u32 fd); +extern int cellFsStReadGetRingBuf(u32 fd, mem_ptr_t ringbuf); +extern int cellFsStReadGetStatus(u32 fd, mem64_t status); +extern int cellFsStReadGetRegid(u32 fd, mem64_t regid); +extern int cellFsStReadStart(u32 fd, u64 offset, u64 size); +extern int cellFsStReadStop(u32 fd); +extern int cellFsStRead(u32 fd, u32 buf_addr, u64 size, mem64_t rsize); +extern int cellFsStReadGetCurrentAddr(u32 fd, mem32_t addr_addr, mem64_t size); +extern int cellFsStReadPutCurrentAddr(u32 fd, u32 addr_addr, u64 size); +extern int cellFsStReadWait(u32 fd, u64 size); +extern int cellFsStReadWaitCallback(u32 fd, u64 size, mem_func_ptr_t func); //cellVideo extern int cellVideoOutGetState(u32 videoOut, u32 deviceIndex, u32 state_addr); diff --git a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp index 80b425bf02..dfbe386ca0 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.cpp @@ -10,6 +10,39 @@ enum IDFlag_Dir = 2, }; +struct FsRingBuffer +{ + u64 m_ringbuf_size; + u64 m_block_size; + u64 m_transfer_rate; + u32 m_copy; +}; + +struct FsRingBufferConfig +{ + FsRingBuffer m_ring_buffer; + u32 m_buffer; + u64 m_fs_status; + u64 m_regid; + u32 m_alloc_mem_size; + u32 m_current_addr; + + FsRingBufferConfig() + : m_fs_status(CELL_FS_ST_NOT_INITIALIZED) + , m_regid(0) + , m_alloc_mem_size(0) + , m_current_addr(0) + { + memset(&m_ring_buffer, 0, sizeof(FsRingBufferConfig)); + } + + ~FsRingBufferConfig() + { + memset(&m_ring_buffer, 0, sizeof(FsRingBufferConfig)); + } +} m_fs_config; + + int cellFsOpen(u32 path_addr, int flags, mem32_t fd, mem32_t arg, u64 size) { const wxString& path = Memory.ReadString(path_addr); @@ -290,7 +323,7 @@ int cellFsMkdir(u32 path_addr, u32 mode) { const wxString& ps3_path = Memory.ReadString(path_addr); sys_fs.Log("cellFsMkdir(path=\"%s\", mode=0x%x)", ps3_path.wx_str(), mode); - + vfsDir dir; if(dir.IsExists(ps3_path)) return CELL_EEXIST; @@ -484,3 +517,217 @@ int cellFsGetFreeSize(u32 path_addr, mem32_t block_size, mem64_t block_count) return CELL_OK; } + +int cellFsGetDirectoryEntries(u32 fd, mem_ptr_t entries, u32 entries_size, mem32_t data_count) +{ + sys_fs.Log("cellFsGetDirectoryEntries(fd=%d, entries_addr=0x%x, entries_size = 0x%x, data_count_addr=0x%x)", fd, entries.GetAddr(), entries_size, data_count.GetAddr()); + + vfsDirBase* directory; + if(!sys_fs.CheckId(fd, directory)) + return CELL_ESRCH; + if(!entries.IsGood() || !data_count.IsGood()) + return CELL_EFAULT; + + const DirEntryInfo* info = directory->Read(); + if(info) + { + data_count = 1; + Memory.WriteString(entries.GetAddr()+2, info->name.wx_str()); + entries->entry_name.d_namlen = info->name.Length(); + entries->entry_name.d_type = (info->flags & DirEntry_TypeFile) ? CELL_FS_TYPE_REGULAR : CELL_FS_TYPE_DIRECTORY; + + entries->attribute.st_mode = + CELL_FS_S_IRUSR | CELL_FS_S_IWUSR | CELL_FS_S_IXUSR | + CELL_FS_S_IRGRP | CELL_FS_S_IWGRP | CELL_FS_S_IXGRP | + CELL_FS_S_IROTH | CELL_FS_S_IWOTH | CELL_FS_S_IXOTH; + + entries->attribute.st_uid = 0; + entries->attribute.st_gid = 0; + entries->attribute.st_atime_ = 0; //TODO + entries->attribute.st_mtime_ = 0; //TODO + entries->attribute.st_ctime_ = 0; //TODO + entries->attribute.st_blksize = 4096; + } + else + { + data_count = 0; + } + + return CELL_OK; +} + +int cellFsStReadInit(u32 fd, mem_ptr_t ringbuf) +{ + sys_fs.Warning("cellFsStReadInit(fd=%d, ringbuf_addr=0x%x)", fd, ringbuf.GetAddr()); + + vfsStream* file; + if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; + + if(!ringbuf.IsGood()) + return CELL_EFAULT; + + FsRingBuffer& buffer = m_fs_config.m_ring_buffer; + + buffer.m_block_size = ringbuf->block_size; + buffer.m_copy = ringbuf->copy; + buffer.m_ringbuf_size = ringbuf->ringbuf_size; + buffer.m_transfer_rate = ringbuf->transfer_rate; + + if(buffer.m_ringbuf_size < 0x40000000) // If the size is less than 1MB + m_fs_config.m_alloc_mem_size = ((ringbuf->ringbuf_size + 64 * 1024 - 1) / (64 * 1024)) * (64 * 1024); + m_fs_config.m_alloc_mem_size = ((ringbuf->ringbuf_size + 1024 * 1024 - 1) / (1024 * 1024)) * (1024 * 1024); + + // alloc memory + m_fs_config.m_buffer = Memory.Alloc(m_fs_config.m_alloc_mem_size, 1024); + memset(Memory + m_fs_config.m_buffer, 0, m_fs_config.m_alloc_mem_size); + + m_fs_config.m_fs_status = CELL_FS_ST_INITIALIZED; + + return CELL_OK; +} + +int cellFsStReadFinish(u32 fd) +{ + sys_fs.Warning("cellFsStReadFinish(fd=%d)", fd); + + vfsStream* file; + if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; + + Memory.Free(m_fs_config.m_buffer); + m_fs_config.m_fs_status = CELL_FS_ST_NOT_INITIALIZED; + + return CELL_OK; +} + +int cellFsStReadGetRingBuf(u32 fd, mem_ptr_t ringbuf) +{ + sys_fs.Warning("cellFsStReadGetRingBuf(fd=%d, ringbuf_addr=0x%x)", fd, ringbuf.GetAddr()); + + vfsStream* file; + if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; + + if(!ringbuf.IsGood()) + return CELL_EFAULT; + + FsRingBuffer& buffer = m_fs_config.m_ring_buffer; + + ringbuf->block_size = buffer.m_block_size; + ringbuf->copy = buffer.m_copy; + ringbuf->ringbuf_size = buffer.m_ringbuf_size; + ringbuf->transfer_rate = buffer.m_transfer_rate; + + sys_fs.Warning("*** fs stream config: block_size=0x%llx, copy=%d, ringbuf_size = 0x%llx, transfer_rate = 0x%llx", ringbuf->block_size, ringbuf->copy, + ringbuf->ringbuf_size, ringbuf->transfer_rate); + return CELL_OK; +} + +int cellFsStReadGetStatus(u32 fd, mem64_t status) +{ + sys_fs.Warning("cellFsStReadGetRingBuf(fd=%d, status_addr=0x%x)", fd, status.GetAddr()); + + vfsStream* file; + if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; + + status = m_fs_config.m_fs_status; + + return CELL_OK; +} + +int cellFsStReadGetRegid(u32 fd, mem64_t regid) +{ + sys_fs.Warning("cellFsStReadGetRingBuf(fd=%d, regid_addr=0x%x)", fd, regid.GetAddr()); + + vfsStream* file; + if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; + + regid = m_fs_config.m_regid; + + return CELL_OK; +} + +int cellFsStReadStart(u32 fd, u64 offset, u64 size) +{ + sys_fs.Warning("TODO: cellFsStReadStart(fd=%d, offset=0x%llx, size=0x%llx)", fd, offset, size); + + vfsStream* file; + if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; + + m_fs_config.m_current_addr = m_fs_config.m_buffer + (u32)offset; + m_fs_config.m_fs_status = CELL_FS_ST_PROGRESS; + + return CELL_OK; +} + +int cellFsStReadStop(u32 fd) +{ + sys_fs.Warning("cellFsStReadStop(fd=%d)", fd); + + vfsStream* file; + if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; + + m_fs_config.m_fs_status = CELL_FS_ST_STOP; + + return CELL_OK; +} + +int cellFsStRead(u32 fd, u32 buf_addr, u64 size, mem64_t rsize) +{ + sys_fs.Warning("TODO: cellFsStRead(fd=%d, buf_addr=0x%x, size=0x%llx, rsize_addr = 0x%x)", fd, buf_addr, size, rsize.GetAddr()); + + vfsStream* file; + if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; + + if (rsize.GetAddr() && !rsize.IsGood()) return CELL_EFAULT; + + m_fs_config.m_regid += size; + rsize = m_fs_config.m_regid; + + return CELL_OK; +} + +int cellFsStReadGetCurrentAddr(u32 fd, mem32_t addr_addr, mem64_t size) +{ + sys_fs.Warning("TODO: cellFsStReadGetCurrentAddr(fd=%d, addr_addr=0x%x, size_addr = 0x%x)", fd, addr_addr.GetAddr(), size.GetAddr()); + + vfsStream* file; + if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; + + if (!addr_addr.IsGood() && !size.IsGood()) return CELL_EFAULT; + + return CELL_OK; +} + +int cellFsStReadPutCurrentAddr(u32 fd, u32 addr_addr, u64 size) +{ + sys_fs.Warning("TODO: cellFsStReadPutCurrentAddr(fd=%d, addr_addr=0x%x, size = 0x%llx)", fd, addr_addr, size); + + vfsStream* file; + if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; + + if (!Memory.IsGoodAddr(addr_addr)) return CELL_EFAULT; + + return CELL_OK; +} + +int cellFsStReadWait(u32 fd, u64 size) +{ + sys_fs.Warning("TODO: cellFsStReadWait(fd=%d, size = 0x%llx)", fd, size); + + vfsStream* file; + if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; + + return CELL_OK; +} + +int cellFsStReadWaitCallback(u32 fd, u64 size, mem_func_ptr_t func) +{ + sys_fs.Warning("TODO: cellFsStReadWaitCallback(fd=%d, size = 0x%llx, func_addr = 0x%x)", fd, size, func.GetAddr()); + + if (!func.IsGood()) + return CELL_EFAULT; + + vfsStream* file; + if(!sys_fs.CheckId(fd, file)) return CELL_ESRCH; + + return CELL_OK; +} \ No newline at end of file diff --git a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.h b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.h index 58e0af41f8..4029d50201 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.h +++ b/rpcs3/Emu/SysCalls/lv2/SC_FileSystem.h @@ -56,6 +56,21 @@ enum FsDirentType CELL_FS_TYPE_SYMLINK = 3, }; +enum CellFsRingBufferCopy +{ + CELL_FS_ST_COPY = 0, + CELL_FS_ST_COPYLESS = 1, +}; + +enum cellFsStStatus +{ + CELL_FS_ST_INITIALIZED = 0x0001, + CELL_FS_ST_NOT_INITIALIZED = 0x0002, + CELL_FS_ST_STOP = 0x0100, + CELL_FS_ST_PROGRESS = 0x0200, +}; + + #pragma pack(4) struct CellFsStat @@ -92,4 +107,18 @@ struct CellFsAio be_t buf_addr; be_t size; be_t user_data; -}; \ No newline at end of file +}; + +struct CellFsDirectoryEntry +{ + CellFsStat attribute; + CellFsDirent entry_name; +}; + +struct CellFsRingBuffer +{ + be_t ringbuf_size; + be_t block_size; + be_t transfer_rate; + be_t copy; +}; From b0f6b03c38016a5534235f17a2d2c0d1456f5f11 Mon Sep 17 00:00:00 2001 From: O1L Date: Fri, 14 Mar 2014 17:53:37 +0300 Subject: [PATCH 2/2] Fixed crash on using NUll Audio Output, fixed possible crash in OpenAL exit and minor changes in cellAudioEventQueue functions. --- rpcs3/Emu/Audio/AL/OpenALThread.cpp | 2 ++ rpcs3/Emu/Audio/cellAudio.h | 2 +- rpcs3/Emu/SysCalls/Modules/cellAudio.cpp | 22 +++++++++++++--------- rpcs3/Gui/MainFrame.cpp | 2 +- 4 files changed, 17 insertions(+), 11 deletions(-) diff --git a/rpcs3/Emu/Audio/AL/OpenALThread.cpp b/rpcs3/Emu/Audio/AL/OpenALThread.cpp index c5255988b6..af49d5a01a 100644 --- a/rpcs3/Emu/Audio/AL/OpenALThread.cpp +++ b/rpcs3/Emu/Audio/AL/OpenALThread.cpp @@ -44,6 +44,8 @@ void OpenALThread::Init() void OpenALThread::Quit() { + m_context = alcGetCurrentContext(); + m_device = alcGetContextsDevice(m_context); alcMakeContextCurrent(nullptr); alcDestroyContext(m_context); alcCloseDevice(m_device); diff --git a/rpcs3/Emu/Audio/cellAudio.h b/rpcs3/Emu/Audio/cellAudio.h index e5ea8545fe..7d492b0ba9 100644 --- a/rpcs3/Emu/Audio/cellAudio.h +++ b/rpcs3/Emu/Audio/cellAudio.h @@ -139,7 +139,7 @@ struct AudioConfig //custom structure : m_is_audio_initialized(false) , m_is_audio_finalized(false) , m_port_in_use(0) - , event_key(0) + , event_key(0x80004d494f323221) , counter(0) { memset(&m_ports, 0, sizeof(AudioPortConfig) * AUDIO_PORT_COUNT); diff --git a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp index f0c1e38588..1fb6dc72ff 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellAudio.cpp @@ -60,7 +60,7 @@ int cellAudioInit() memset(buffer2, 0, sizeof(buffer2)); memset(oal_buffer.get(), 0, oal_buffer_size * sizeof(u16)); - if(Ini.AudioOutMode.GetValue() == 1) + if(m_audio_out) { m_audio_out->Init(); m_audio_out->Open(oal_buffer.get(), oal_buffer_size*sizeof(u16)); @@ -151,7 +151,10 @@ int cellAudioInit() if(oal_buffer_offset >= oal_buffer_size) { - m_audio_out->AddData(oal_buffer.get(), oal_buffer_offset * sizeof(u16)); + if(m_audio_out) + { + m_audio_out->AddData(oal_buffer.get(), oal_buffer_offset * sizeof(u16)); + } oal_buffer_offset = 0; } @@ -438,21 +441,22 @@ int cellAudioCreateNotifyEventQueue(mem32_t id, mem64_t key) { cellAudio.Warning("cellAudioCreateNotifyEventQueue(id_addr=0x%x, key_addr=0x%x)", id.GetAddr(), key.GetAddr()); - if (Emu.GetEventManager().CheckKey(0x80004d494f323221)) + while (Emu.GetEventManager().CheckKey(m_config.event_key)) { - return CELL_AUDIO_ERROR_EVENT_QUEUE; + m_config.event_key++; // experimental + //return CELL_AUDIO_ERROR_EVENT_QUEUE; } - EventQueue* eq = new EventQueue(SYS_SYNC_FIFO, SYS_PPU_QUEUE, 0x80004d494f323221, 0x80004d494f323221, 32); + EventQueue* eq = new EventQueue(SYS_SYNC_FIFO, SYS_PPU_QUEUE, m_config.event_key, m_config.event_key, 32); - if (!Emu.GetEventManager().RegisterKey(eq, 0x80004d494f323221)) + if (!Emu.GetEventManager().RegisterKey(eq, m_config.event_key)) { delete eq; return CELL_AUDIO_ERROR_EVENT_QUEUE; } id = cellAudio.GetNewId(eq); - key = 0x80004d494f323221; + key = m_config.event_key; return CELL_OK; } @@ -467,7 +471,7 @@ int cellAudioSetNotifyEventQueue(u64 key) { cellAudio.Warning("cellAudioSetNotifyEventQueue(key=0x%llx)", key); - m_config.event_key = key; + //m_config.event_key = key; /*EventQueue* eq; if (!Emu.GetEventManager().GetEventQueue(key, eq)) @@ -496,7 +500,7 @@ int cellAudioRemoveNotifyEventQueue(u64 key) return CELL_AUDIO_ERROR_PARAM; } - m_config.event_key = 0; + m_config.event_key = 0x80004d494f323221; // TODO: disconnect port diff --git a/rpcs3/Gui/MainFrame.cpp b/rpcs3/Gui/MainFrame.cpp index 653664072e..fc6ac9f582 100644 --- a/rpcs3/Gui/MainFrame.cpp +++ b/rpcs3/Gui/MainFrame.cpp @@ -416,7 +416,7 @@ void MainFrame::Config(wxCommandEvent& WXUNUSED(event)) chbox_hle_exitonstop->SetValue(Ini.HLEExitOnStop.GetValue()); chbox_audio_dump->Enable(Emu.IsStopped()); - cbox_audio_out->Enable(Emu.IsStopped()); + //cbox_audio_out->Enable(Emu.IsStopped()); chbox_hle_logging->Enable(Emu.IsStopped()); cbox_cpu_decoder->SetSelection(Ini.CPUDecoderMode.GetValue() ? Ini.CPUDecoderMode.GetValue() - 1 : 0);