diff --git a/rpcs3/Emu/RSX/GCM.h b/rpcs3/Emu/RSX/GCM.h index af6d412e9..ac37e04a8 100644 --- a/rpcs3/Emu/RSX/GCM.h +++ b/rpcs3/Emu/RSX/GCM.h @@ -238,17 +238,17 @@ struct CellGcmSurface u8 colorFormat; u8 colorTarget; u8 colorLocation[4]; - u32 colorOffset[4]; - u32 colorPitch[4]; + be_t colorOffset[4]; + be_t colorPitch[4]; u8 depthFormat; u8 depthLocation; u8 _padding[2]; - u32 depthOffset; - u32 depthPitch; - u16 width; - u16 height; - u16 x; - u16 y; + be_t depthOffset; + be_t depthPitch; + be_t width; + be_t height; + be_t x; + be_t y; }; struct CellGcmReportData @@ -268,6 +268,14 @@ struct CellGcmZcullInfo u32 status1; }; +struct CellGcmDisplayInfo +{ + be_t offset; + be_t pitch; + be_t width; + be_t height; +}; + struct CellGcmTileInfo { be_t tile; diff --git a/rpcs3/Emu/RSX/GL/GLGSRender.cpp b/rpcs3/Emu/RSX/GL/GLGSRender.cpp index 24e7fb790..ac5af7e6c 100644 --- a/rpcs3/Emu/RSX/GL/GLGSRender.cpp +++ b/rpcs3/Emu/RSX/GL/GLGSRender.cpp @@ -14,7 +14,6 @@ #define CMD_LOG(...) #endif -gcmBuffer gcmBuffers[8]; GLuint g_flip_tex, g_depth_tex, g_pbo[6]; int last_width = 0, last_height = 0, last_depth_format = 0; @@ -1272,13 +1271,13 @@ void GLGSRender::Flip() if (m_read_buffer) { format = GL_BGRA; - gcmBuffer* buffers = (gcmBuffer*)Memory.GetMemFromAddr(m_gcm_buffers_addr); - u32 addr = GetAddress(re(buffers[m_gcm_current_buffer].offset), CELL_GCM_LOCATION_LOCAL); + CellGcmDisplayInfo* buffers = (CellGcmDisplayInfo*)Memory.GetMemFromAddr(m_gcm_buffers_addr); + u32 addr = GetAddress(buffers[m_gcm_current_buffer].offset, CELL_GCM_LOCATION_LOCAL); if (Memory.IsGoodAddr(addr)) { - width = re(buffers[m_gcm_current_buffer].width); - height = re(buffers[m_gcm_current_buffer].height); + width = buffers[m_gcm_current_buffer].width; + height = buffers[m_gcm_current_buffer].height; src_buffer = (u8*)Memory.VirtualToRealAddr(addr); } else diff --git a/rpcs3/Emu/RSX/GSManager.h b/rpcs3/Emu/RSX/GSManager.h index 08f424a9a..11f7b3917 100644 --- a/rpcs3/Emu/RSX/GSManager.h +++ b/rpcs3/Emu/RSX/GSManager.h @@ -33,14 +33,6 @@ struct GSInfo } }; -struct gcmBuffer -{ - u32 offset; - u32 pitch; - u32 width; - u32 height; -}; - class GSManager { GSInfo m_info; diff --git a/rpcs3/Emu/RSX/RSXThread.cpp b/rpcs3/Emu/RSX/RSXThread.cpp index 295768b92..ea267f5ad 100644 --- a/rpcs3/Emu/RSX/RSXThread.cpp +++ b/rpcs3/Emu/RSX/RSXThread.cpp @@ -1320,9 +1320,9 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t args, const u32 case 2: m_surface_pitch_a = ARGS(1); } - gcmBuffer* buffers = (gcmBuffer*)Memory.GetMemFromAddr(m_gcm_buffers_addr); - m_width = re(buffers[m_gcm_current_buffer].width); - m_height = re(buffers[m_gcm_current_buffer].height); + CellGcmDisplayInfo* buffers = (CellGcmDisplayInfo*)Memory.GetMemFromAddr(m_gcm_buffers_addr); + m_width = buffers[m_gcm_current_buffer].width; + m_height = buffers[m_gcm_current_buffer].height; // Rescale native resolution to fit 1080p/720p/480p/576p window size nativeRescale((float)m_width, (float)m_height); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index a8310a7bc..9abe15a9b 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -5,6 +5,7 @@ #include "Emu/SysCalls/Modules.h" #include "Emu/SysCalls/SysCalls.h" #include "Emu/RSX/GCM.h" +#include "Emu/SysCalls/lv2/sys_process.h" #include "sysPrxForUser.h" #include "cellGcmSys.h" @@ -37,6 +38,29 @@ gcmInfo gcm_info; u32 map_offset_addr = 0; u32 map_offset_pos = 0; +// Auxiliary functions + +/* + * Get usable local memory size for a specific game SDK version + * Example: For 0x00446000 (FW 4.46) we get a localSize of 0x0F900000 (249MB) + */ +u32 gcmGetLocalMemorySize(u32 sdk_version) +{ + if (sdk_version >= 0x00220000) { + return 0x0F900000; // 249MB + } + if (sdk_version >= 0x00200000) { + return 0x0F200000; // 242MB + } + if (sdk_version >= 0x00190000) { + return 0x0EA00000; // 234MB + } + if (sdk_version >= 0x00180000) { + return 0x0E800000; // 232MB + } + return 0x0E000000; // 224MB +} + //---------------------------------------------------------------------------- // Data Retrieval //---------------------------------------------------------------------------- @@ -267,16 +291,29 @@ u32 cellGcmGetTiledPitchSize(u32 size) return 0; } -int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress) +void _cellGcmFunc1() { - cellGcmSys->Warning("cellGcmInit(context_addr=0x%x,cmdSize=0x%x,ioSize=0x%x,ioAddress=0x%x)", context_addr, cmdSize, ioSize, ioAddress); + cellGcmSys->Todo("_cellGcmFunc1()"); + return; +} + +void _cellGcmFunc15(mem_ptr_t context) +{ + cellGcmSys->Todo("_cellGcmFunc15(context_addr=0x%x)", context.GetAddr()); + return; +} + +// Called by cellGcmInit +s32 _cellGcmInitBody(mem_ptr_t context, u32 cmdSize, u32 ioSize, u32 ioAddress) +{ + cellGcmSys->Warning("_cellGcmInitBody(context_addr=0x%x, cmdSize=0x%x, ioSize=0x%x, ioAddress=0x%x)", context.GetAddr(), cmdSize, ioSize, ioAddress); if(!cellGcmSys->IsLoaded()) cellGcmSys->Load(); if(!local_size && !local_addr) { - local_size = 0xf900000; //TODO + local_size = 0xf900000; // TODO: Get sdk_version in _cellGcmFunc15 and pass it to gcmGetLocalMemorySize local_addr = Memory.RSXFBMem.GetStartAddr(); Memory.RSXFBMem.AllocAlign(local_size); } @@ -323,7 +360,7 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress) gcm_info.control_addr = gcm_info.context_addr + 0x40; Memory.WriteData(gcm_info.context_addr, current_context); - Memory.Write32(context_addr, gcm_info.context_addr); + Memory.Write32(context.GetAddr(), gcm_info.context_addr); CellGcmControl& ctrl = (CellGcmControl&)Memory[gcm_info.control_addr]; ctrl.put = 0; @@ -331,8 +368,8 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress) ctrl.ref = -1; auto& render = Emu.GetGSManager().GetRender(); - render.m_ctxt_addr = context_addr; - render.m_gcm_buffers_addr = Memory.Alloc(sizeof(gcmBuffer) * 8, sizeof(gcmBuffer)); + render.m_ctxt_addr = context.GetAddr(); + render.m_gcm_buffers_addr = Memory.Alloc(sizeof(CellGcmDisplayInfo) * 8, sizeof(CellGcmDisplayInfo)); render.m_zculls_addr = Memory.Alloc(sizeof(CellGcmZcullInfo) * 8, sizeof(CellGcmZcullInfo)); render.m_tiles_addr = Memory.Alloc(sizeof(CellGcmTileInfo) * 15, sizeof(CellGcmTileInfo)); render.m_gcm_buffers_count = 0; @@ -374,21 +411,19 @@ int cellGcmSetDisplayBuffer(u32 id, u32 offset, u32 pitch, u32 width, u32 height { cellGcmSys->Log("cellGcmSetDisplayBuffer(id=0x%x,offset=0x%x,pitch=%d,width=%d,height=%d)", id, offset, width ? pitch / width : pitch, width, height); - if (id > 7) - { + if (id > 7) { cellGcmSys->Error("cellGcmSetDisplayBuffer : CELL_EINVAL"); return CELL_EINVAL; } - gcmBuffer* buffers = (gcmBuffer*)Memory.GetMemFromAddr(Emu.GetGSManager().GetRender().m_gcm_buffers_addr); + CellGcmDisplayInfo* buffers = (CellGcmDisplayInfo*)Memory.GetMemFromAddr(Emu.GetGSManager().GetRender().m_gcm_buffers_addr); - buffers[id].offset = re(offset); - buffers[id].pitch = re(pitch); - buffers[id].width = re(width); - buffers[id].height = re(height); + buffers[id].offset = offset; + buffers[id].pitch = pitch; + buffers[id].width = width; + buffers[id].height = height; - if(id + 1 > Emu.GetGSManager().GetRender().m_gcm_buffers_count) - { + if (id + 1 > Emu.GetGSManager().GetRender().m_gcm_buffers_count) { Emu.GetGSManager().GetRender().m_gcm_buffers_count = id + 1; } @@ -1066,18 +1101,6 @@ int cellGcmSetFlipCommand(u32 ctx, u32 id) return cellGcmSetPrepareFlip(ctx, id); } -s64 cellGcmFunc15(u32 unk_addr) -{ - cellGcmSys->Todo("cellGcmFunc15(unk_addr=0x%x)", unk_addr); - - if (0/*TODO: If what?*/) { - _sys_memset(unk_addr, 0, 0x84); - } - - // TODO - return 0; -} - int cellGcmSetFlipCommandWithWaitLabel(u32 ctx, u32 id, u32 label_index, u32 label_value) { cellGcmSys->Log("cellGcmSetFlipCommandWithWaitLabel(ctx=0x%x, id=0x%x, label_index=0x%x, label_value=0x%x)", @@ -1196,7 +1219,9 @@ void cellGcmSys_init() cellGcmSys->AddFunc(0x23ae55a3, cellGcmGetLastSecondVTime); cellGcmSys->AddFunc(0x055bd74d, cellGcmGetTiledPitchSize); cellGcmSys->AddFunc(0x723bbc7e, cellGcmGetVBlankCount); - cellGcmSys->AddFunc(0x15bae46b, cellGcmInit); + cellGcmSys->AddFunc(0x5f909b17, _cellGcmFunc1); + cellGcmSys->AddFunc(0x3a33c1fd, _cellGcmFunc15); + cellGcmSys->AddFunc(0x15bae46b, _cellGcmInitBody); cellGcmSys->AddFunc(0xfce9e764, cellGcmInitSystemMode); cellGcmSys->AddFunc(0xb2e761d4, cellGcmResetFlipStatus); cellGcmSys->AddFunc(0x51c9d62b, cellGcmSetDebugOutputLevel); @@ -1258,7 +1283,6 @@ void cellGcmSys_init() // Other cellGcmSys->AddFunc(0x21397818, cellGcmSetFlipCommand); - cellGcmSys->AddFunc(0x3a33c1fd, cellGcmFunc15); cellGcmSys->AddFunc(0xd8f88e1a, cellGcmSetFlipCommandWithWaitLabel); cellGcmSys->AddFunc(0xd0b1d189, cellGcmSetTile); } diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h index 610b177ed..0ae68c345 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.h @@ -7,7 +7,7 @@ enum CELL_GCM_ERROR_INVALID_ENUM = 0x80210002, CELL_GCM_ERROR_INVALID_VALUE = 0x80210003, CELL_GCM_ERROR_INVALID_ALIGNMENT = 0x80210004, - CELL_GCM_ERROR_ADDRESS_OVERWRAP = 0x80210005 + CELL_GCM_ERROR_ADDRESS_OVERWRAP = 0x80210005, }; struct gcm_offset @@ -18,6 +18,8 @@ struct gcm_offset // Auxiliary functions void InitOffsetTable(); +u32 gcmGetLocalMemorySize(); + // SysCalls s32 cellGcmSetPrepareFlip(mem_ptr_t ctxt, u32 id); diff --git a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp index eccd0861e..3809643ad 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellResc.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellResc.cpp @@ -904,10 +904,10 @@ int cellRescGcmSurface2RescSrc(mem_ptr_t gcmSurface, mem_ptr_tformat = textureFormat; - rescSrc->pitch = re(gcmSurface->colorPitch[0]); - rescSrc->width = re(gcmSurface->width) * xW; - rescSrc->height = re(gcmSurface->height) * xH; - rescSrc->offset = re(gcmSurface->colorOffset[0]); + rescSrc->pitch = gcmSurface->colorPitch[0]; + rescSrc->width = gcmSurface->width * xW; + rescSrc->height = gcmSurface->height * xH; + rescSrc->offset = gcmSurface->colorOffset[0]; return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp b/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp index 5d92f4205..b1350270c 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp +++ b/rpcs3/Emu/SysCalls/lv2/sys_rsx.cpp @@ -19,27 +19,57 @@ s32 sys_rsx_device_close() return CELL_OK; } -s32 sys_rsx_memory_allocate() +/* + * lv2 SysCall 668 (0x29C): sys_rsx_memory_allocate + * @param mem_handle (OUT): Context / ID, which is used by sys_rsx_memory_free to free allocated memory. + * @param mem_addr (OUT): Returns the local memory base address, usually 0xC0000000. + * @param size (IN): Local memory size. E.g. 0x0F900000 (249 MB). + * @param flags (IN): E.g. Immediate value passed in cellGcmSys is 8. + * @param a5 (IN): E.g. Immediate value passed in cellGcmSys is 0x00300000 (3 MB?). + * @param a6 (IN): E.g. Immediate value passed in cellGcmSys is 16. + * @param a7 (IN): E.g. Immediate value passed in cellGcmSys is 8. + */ +s32 sys_rsx_memory_allocate(mem32_t mem_handle, mem32_t mem_addr, u32 size, u64 flags, u64 a5, u64 a6, u64 a7) { - sys_rsx.Todo("sys_rsx_memory_allocate()"); + sys_rsx.Todo("sys_rsx_memory_allocate(mem_handle_addr=0x%x, local_mem_addr=0x%x, size=0x%x, flags=0x%x, a5=%d, a6=%d, a7=%d)", + mem_handle.GetAddr(), mem_addr.GetAddr(), size, flags, a5, a6, a7); return CELL_OK; } -s32 sys_rsx_memory_free() +/* + * lv2 SysCall 669 (0x29D): sys_rsx_memory_free + * @param mem_handle (OUT): Context / ID, for allocated local memory generated by sys_rsx_memory_allocate + */ +s32 sys_rsx_memory_free(u32 mem_handle) { - sys_rsx.Todo("sys_rsx_memory_free()"); + sys_rsx.Todo("sys_rsx_memory_free(mem_handle=%d)", mem_handle); return CELL_OK; } -s32 sys_rsx_context_allocate() +/* + * lv2 SysCall 670 (0x29E): sys_rsx_context_allocate + * @param context_id (OUT): RSX_context, E.g. 0x55555555 (in vsh.self) + * @param lpar_dma_control (OUT): Control register area. E.g. 0x60100000 (in vsh.self) + * @param lpar_driver_info (OUT): RSX data like frequencies, sizes, version... E.g. 0x60200000 (in vsh.self) + * @param lpar_reports (OUT): Report data area. E.g. 0x60300000 (in vsh.self) + * @param mem_ctx (IN): mem_ctx given by sys_rsx_memory_allocate + * @param system_mode (IN): + */ +s32 sys_rsx_context_allocate(mem32_t context_id, mem32_t lpar_dma_control, mem32_t lpar_driver_info, mem32_t lpar_reports, u64 mem_ctx, u64 system_mode) { - sys_rsx.Todo("sys_rsx_context_allocate()"); + sys_rsx.Todo("sys_rsx_context_allocate(context_id_addr=0x%x, lpar_dma_control_addr=0x%x, lpar_driver_info_addr=0x%x, lpar_reports_addr=0x%x, mem_ctx=0x%x, system_mode=0x%x)", + context_id.GetAddr(), lpar_dma_control.GetAddr(), lpar_driver_info.GetAddr(), lpar_reports.GetAddr(), mem_ctx, system_mode); + return CELL_OK; } -s32 sys_rsx_context_free() +/* + * lv2 SysCall 671 (0x29F): sys_rsx_context_free + * @param a1 (IN): RSX_context generated by sys_rsx_context_allocate to free the context. + */ +s32 sys_rsx_context_free(u32 context_id) { - sys_rsx.Todo("sys_rsx_context_free()"); + sys_rsx.Todo("sys_rsx_context_free(context_id=%d)", context_id); return CELL_OK; } @@ -55,21 +85,76 @@ s32 sys_rsx_context_iounmap() return CELL_OK; } -s32 sys_rsx_context_attribute(s32 context_id, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6) +/* + * lv2 SysCall 674 (0x2A2): sys_rsx_context_attribute + * @param context_id (IN): RSX context, e.g. 0x55555555 + * @param package_id (IN): + * @param a3 (IN): + * @param a4 (IN): + * @param a5 (IN): + * @param a6 (IN): + */ +s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u64 a5, u64 a6) { - sys_rsx.Todo("sys_rsx_context_attribute(context_id=%d, a2=%llu, a3=%llu, a4=%llu, a5=%llu, a6=%llu)", context_id, a2, a3, a4, a5, a6); + sys_rsx.Todo("sys_rsx_context_attribute(context_id=0x%x, package_id=0x%x, a3=%llu, a4=%llu, a5=%llu, a6=%llu)", + context_id, package_id, a3, a4, a5, a6); + + switch(package_id) + { + case 0x001: // ? + break; + + case 0x101: // ? + break; + + case 0x104: // Display buffer + break; + + case 0x10a: // ? + break; + + case 0x300: // Tiles + break; + + case 0x301: // Depth-buffer (Z-cull) + break; + + default: + break; + } return CELL_OK; } -s32 sys_rsx_device_map(mem32_t a1, mem32_t a2, u32 a3) +/* + * lv2 SysCall 675 (0x2A3): sys_rsx_device_map + * @param a1 (OUT): For example: In vsh.self it is 0x60000000, global semaphore. For a game it is 0x40000000. + * @param a2 (OUT): Unused? + * @param dev_id (IN): An immediate value and always 8. + */ +s32 sys_rsx_device_map(mem32_t a1, mem32_t a2, u32 dev_id) { - sys_rsx.Todo("sys_rsx_device_map(a1_addr=0x%x, a2_addr=0x%x, a3=%d)", a1.GetAddr(), a2.GetAddr(), a3); + sys_rsx.Todo("sys_rsx_device_map(a1_addr=0x%x, a2_addr=0x%x, a3=%d)", a1.GetAddr(), a2.GetAddr(), dev_id); + + if (dev_id > 15) { + // TODO: Throw RSX error + return CELL_EINVAL; + } + + if (dev_id == 0 || dev_id > 8) { + // TODO: lv1 related so we may ignore it. + // if (something) { return CELL_EPERM; } + } + return CELL_OK; } -s32 sys_rsx_device_unmap() +/* + * lv2 SysCall 676 (0x2A4): sys_rsx_device_unmap + * @param dev_id (IN): An immediate value and always 8. + */ +s32 sys_rsx_device_unmap(u32 dev_id) { - sys_rsx.Todo("sys_rsx_device_unmap()"); + sys_rsx.Todo("sys_rsx_device_unmap(a1=%d)", dev_id); return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/sys_rsx.h b/rpcs3/Emu/SysCalls/lv2/sys_rsx.h index f51043315..995aa2995 100644 --- a/rpcs3/Emu/SysCalls/lv2/sys_rsx.h +++ b/rpcs3/Emu/SysCalls/lv2/sys_rsx.h @@ -3,13 +3,13 @@ // SysCalls s32 sys_rsx_device_open(); s32 sys_rsx_device_close(); -s32 sys_rsx_memory_allocate(); -s32 sys_rsx_memory_free(); -s32 sys_rsx_context_allocate(); -s32 sys_rsx_context_free(); +s32 sys_rsx_memory_allocate(mem32_t mem_handle, mem32_t mem_addr, u32 size, u64 flags, u64 a5, u64 a6, u64 a7); +s32 sys_rsx_memory_free(u32 mem_handle); +s32 sys_rsx_context_allocate(mem32_t context_id, mem32_t lpar_dma_control, mem32_t lpar_driver_info, mem32_t lpar_reports, u64 mem_ctx, u64 system_mode); +s32 sys_rsx_context_free(u32 context_id); s32 sys_rsx_context_iomap(); s32 sys_rsx_context_iounmap(); -s32 sys_rsx_context_attribute(s32 context_id, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6); -s32 sys_rsx_device_map(mem32_t a1, mem32_t a2, u32 a3); -s32 sys_rsx_device_unmap(); +s32 sys_rsx_context_attribute(s32 context_id, u32 package_id, u64 a3, u64 a4, u64 a5, u64 a6); +s32 sys_rsx_device_map(mem32_t a1, mem32_t a2, u32 dev_id); +s32 sys_rsx_device_unmap(u32 dev_id); s32 sys_rsx_attribute(); diff --git a/rpcs3/Gui/RSXDebugger.cpp b/rpcs3/Gui/RSXDebugger.cpp index d3aeb017a..0a437560b 100644 --- a/rpcs3/Gui/RSXDebugger.cpp +++ b/rpcs3/Gui/RSXDebugger.cpp @@ -292,7 +292,7 @@ void RSXDebugger::OnClickBuffer(wxMouseEvent& event) { if (!RSXReady()) return; const GSRender& render = Emu.GetGSManager().GetRender(); - const mem_ptr_t buffers = render.m_gcm_buffers_addr; + const mem_ptr_t buffers = render.m_gcm_buffers_addr; if(!buffers.IsGood()) return; @@ -300,9 +300,9 @@ void RSXDebugger::OnClickBuffer(wxMouseEvent& event) // TODO: Is there any better way to choose the color buffers #define SHOW_BUFFER(id) \ { \ - u32 addr = render.m_local_mem_addr + re(buffers[id].offset); \ - if(Memory.IsGoodAddr(addr) && buffers[id].width && buffers[id].height) \ - MemoryViewerPanel::ShowImage(this, addr, 3, re(buffers[id].width), re(buffers[id].height), true); \ + u32 addr = render.m_local_mem_addr + buffers[id].offset; \ + if (Memory.IsGoodAddr(addr) && buffers[id].width && buffers[id].height) \ + MemoryViewerPanel::ShowImage(this, addr, 3, buffers[id].width, buffers[id].height, true); \ return; \ } \ @@ -409,16 +409,16 @@ void RSXDebugger::GetBuffers() if(!Memory.IsGoodAddr(render.m_gcm_buffers_addr)) continue; - gcmBuffer* buffers = (gcmBuffer*)Memory.GetMemFromAddr(render.m_gcm_buffers_addr); - u32 RSXbuffer_addr = render.m_local_mem_addr + re(buffers[bufferId].offset); + CellGcmDisplayInfo* buffers = (CellGcmDisplayInfo*)Memory.GetMemFromAddr(render.m_gcm_buffers_addr); + u32 RSXbuffer_addr = render.m_local_mem_addr + buffers[bufferId].offset; if(!Memory.IsGoodAddr(RSXbuffer_addr)) continue; unsigned char* RSXbuffer = (unsigned char*)Memory.VirtualToRealAddr(RSXbuffer_addr); - u32 width = re(buffers[bufferId].width); - u32 height = re(buffers[bufferId].height); + u32 width = buffers[bufferId].width; + u32 height = buffers[bufferId].height; unsigned char* buffer = (unsigned char*)malloc(width * height * 3); // ABGR to RGB and flip vertically