diff --git a/rpcs3/Emu/Cell/PPUInterpreter.h b/rpcs3/Emu/Cell/PPUInterpreter.h index 421f7603a4..0f38781fa2 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.h +++ b/rpcs3/Emu/Cell/PPUInterpreter.h @@ -2084,9 +2084,10 @@ private: { if (CheckCondition(bo, bi)) { + const u64 nextLR = CPU.PC + 4; CPU.SetBranch(branchTarget((aa ? 0 : CPU.PC), bd), lk); + if(lk) CPU.LR = nextLR; } - if(lk) CPU.LR = CPU.PC + 4; } void SC(u32 sc_code) { @@ -2108,8 +2109,9 @@ private: } void B(s32 ll, u32 aa, u32 lk) { + const u64 nextLR = CPU.PC + 4; CPU.SetBranch(branchTarget(aa ? 0 : CPU.PC, ll), lk); - if(lk) CPU.LR = CPU.PC + 4; + if(lk) CPU.LR = nextLR; } void MCRF(u32 crfd, u32 crfs) { @@ -2119,9 +2121,10 @@ private: { if (CheckCondition(bo, bi)) { + const u64 nextLR = CPU.PC + 4; CPU.SetBranch(branchTarget(0, CPU.LR), true); + if(lk) CPU.LR = nextLR; } - if(lk) CPU.LR = CPU.PC + 4; } void CRNOR(u32 crbd, u32 crba, u32 crbb) { @@ -2171,9 +2174,10 @@ private: { if(bo & 0x10 || CPU.IsCR(bi) == (bo & 0x8)) { + const u64 nextLR = CPU.PC + 4; CPU.SetBranch(branchTarget(0, CPU.CTR), true); + if(lk) CPU.LR = nextLR; } - if(lk) CPU.LR = CPU.PC + 4; } void RLWIMI(u32 ra, u32 rs, u32 sh, u32 mb, u32 me, bool rc) { @@ -2816,7 +2820,6 @@ private: const u64 RA = CPU.GPR[ra]; const u64 RB = CPU.GPR[rb]; CPU.GPR[rd] = RA + RB; - CPU.XER.CA = CPU.IsCarry(RA, RB); if(oe) UNK("addo"); if(rc) CPU.UpdateCR0(CPU.GPR[rd]); } diff --git a/rpcs3/Emu/GS/GL/GLGSRender.cpp b/rpcs3/Emu/GS/GL/GLGSRender.cpp index 8a12c70c60..26df787b92 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.cpp +++ b/rpcs3/Emu/GS/GL/GLGSRender.cpp @@ -581,7 +581,7 @@ void GLGSRender::WriteColourBufferD() checkForGlError("glReadPixels(GL_RGBA, GL_UNSIGNED_INT_8_8_8_8)"); } -void GLGSRender::WriteBuffers() +void GLGSRender::WriteColorBuffers() { glPixelStorei(GL_PACK_ROW_LENGTH, 0); glPixelStorei(GL_PACK_ALIGNMENT, 4); @@ -641,7 +641,6 @@ void GLGSRender::OnInitThread() InitProcTable(); glEnable(GL_TEXTURE_2D); - glEnable(GL_SCISSOR_TEST); #ifdef _WIN32 glSwapInterval(Ini.GSVSyncEnable.GetValue() ? 1 : 0); @@ -719,6 +718,15 @@ void GLGSRender::ExecCMD() switch(m_surface_depth_format) { + // case 0 found in BLJM60410-[Suzukaze no Melt - Days in the Sanctuary] + // [E : RSXThread]: Bad depth format! (0) + // [E : RSXThread]: glEnable: opengl error 0x0506 + // [E : RSXThread]: glDrawArrays: opengl error 0x0506 + case 0: + m_rbo.Storage(GL_DEPTH_COMPONENT, RSXThread::m_width, RSXThread::m_height); + checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT)"); + break; + case 1: m_rbo.Storage(GL_DEPTH_COMPONENT16, RSXThread::m_width, RSXThread::m_height); checkForGlError("m_rbo.Storage(GL_DEPTH_COMPONENT16)"); @@ -764,8 +772,10 @@ void GLGSRender::ExecCMD() } m_fbo.Bind(); + if(Ini.GSDumpDepthBuffer.GetValue()) WriteDepthBuffer(); + static const GLenum draw_buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; switch(m_surface_colour_target) @@ -804,20 +814,12 @@ void GLGSRender::ExecCMD() checkForGlError("glColorMask"); } - //glFrontFace(m_front_face); - if(m_set_viewport_horizontal && m_set_viewport_vertical) { //glViewport(m_viewport_x, m_viewport_y, m_viewport_w, m_viewport_h); //checkForGlError("glViewport"); } - if(m_set_scissor_horizontal && m_set_scissor_vertical) - { - glScissor(m_scissor_x, m_scissor_y, m_scissor_w, m_scissor_h); - checkForGlError("glScissor"); - } - if(m_clear_surface_mask) { GLbitfield f = 0; @@ -850,12 +852,6 @@ void GLGSRender::ExecCMD() glClear(f); } - if(m_set_front_polygon_mode) - { - glPolygonMode(GL_FRONT, m_front_polygon_mode); - checkForGlError("glPolygonMode"); - } - Enable(m_depth_test_enable, GL_DEPTH_TEST); Enable(m_set_alpha_test, GL_ALPHA_TEST); Enable(m_set_depth_bounds_test, GL_DEPTH_BOUNDS_TEST_EXT); @@ -864,12 +860,13 @@ void GLGSRender::ExecCMD() Enable(m_set_cull_face_enable, GL_CULL_FACE); Enable(m_set_dither, GL_DITHER); Enable(m_set_stencil_test, GL_STENCIL_TEST); + Enable(m_set_scissor_horizontal && m_set_scissor_vertical, GL_SCISSOR_TEST); Enable(m_set_line_smooth, GL_LINE_SMOOTH); Enable(m_set_poly_smooth, GL_POLYGON_SMOOTH); Enable(m_set_poly_offset_fill, GL_POLYGON_OFFSET_FILL); Enable(m_set_poly_offset_line, GL_POLYGON_OFFSET_LINE); Enable(m_set_poly_offset_point, GL_POLYGON_OFFSET_POINT); - //Enable(m_set_restart_index, GL_PRIMITIVE_RESTART); //Requires OpenGL 3.1+ + //Enable(m_set_restart_index, GL_PRIMITIVE_RESTART); // Requires OpenGL 3.1+ if(m_set_clip_plane) { @@ -885,6 +882,37 @@ void GLGSRender::ExecCMD() checkForGlError("glEnable"); + + if (m_set_front_polygon_mode) + { + glPolygonMode(GL_FRONT, m_front_polygon_mode); + checkForGlError("glPolygonMode(Front)"); + } + + if (m_set_back_polygon_mode) + { + glPolygonMode(GL_BACK, m_back_polygon_mode); + checkForGlError("glPolygonMode(Back)"); + } + + if (m_set_poly_offset_scale_factor && m_set_poly_offset_bias) + { + glPolygonOffset(m_set_poly_offset_scale_factor, m_set_poly_offset_bias); + checkForGlError("glPolygonOffset"); + } + + if (m_set_logic_op) + { + glLogicOp(m_logic_op); + checkForGlError("glLogicOp"); + } + + if (m_set_scissor_horizontal && m_set_scissor_vertical) + { + glScissor(m_scissor_x, m_scissor_y, m_scissor_w, m_scissor_h); + checkForGlError("glScissor"); + } + if(m_set_two_sided_stencil_test_enable) { if(m_set_stencil_fail && m_set_stencil_zfail && m_set_stencil_zpass) @@ -1007,6 +1035,16 @@ void GLGSRender::ExecCMD() checkForGlError("glCullFace"); } + if (m_set_front_face) + { + // Sanity check . Disgaea 3 return 0x1d0 here and cause openGL 0x0500 + if (m_front_face == GL_CW || m_front_face == GL_CCW) + { + glFrontFace(m_front_face); + checkForGlError("glFrontFace"); + } + } + if(m_set_alpha_func && m_set_alpha_ref) { glAlphaFunc(m_alpha_func, m_alpha_ref/255.0f); @@ -1030,7 +1068,7 @@ void GLGSRender::ExecCMD() if(m_set_restart_index) { ConLog.Warning("m_set_restart_index requires glPrimitiveRestartIndex()"); - //glPrimitiveRestartIndex(m_restart_index); //Requires OpenGL 3.1+ + //glPrimitiveRestartIndex(m_restart_index); // Requires OpenGL 3.1+ //checkForGlError("glPrimitiveRestartIndex"); } @@ -1095,12 +1133,34 @@ void GLGSRender::ExecCMD() DisableVertexData(); } - if(Ini.GSDumpColorBuffers.GetValue()) - WriteBuffers(); + if (Ini.GSDumpColorBuffers.GetValue()) + WriteColorBuffers(); } void GLGSRender::Flip() { + // Fast path for non-MRT using glBlitFramebuffer + // TODO: check for MRT samples + if (m_fbo.IsCreated() && (m_surface_colour_target == CELL_GCM_SURFACE_TARGET_0 || m_surface_colour_target == CELL_GCM_SURFACE_TARGET_1)) + { + GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0); + // Renderbuffer is upside turn , swapped srcY0 and srcY1 + GLfbo::Blit(0, RSXThread::m_height, RSXThread::m_width, 0, 0, 0, RSXThread::m_width, RSXThread::m_height, GL_COLOR_BUFFER_BIT, GL_NEAREST); + + m_fbo.Bind(); + + for (uint i = 0; iFlip(m_context); + + m_fbo.Bind(); + + return; + } + if(m_set_scissor_horizontal && m_set_scissor_vertical) { glScissor(0, 0, RSXThread::m_width, RSXThread::m_height); @@ -1190,24 +1250,6 @@ void GLGSRender::Flip() glEnd(); } - /*GLfbo::Bind(GL_DRAW_FRAMEBUFFER, 0); - GLfbo::Blit( - m_surface_clip_x, m_surface_clip_y, m_surface_clip_x + m_surface_clip_w, m_surface_clip_y + m_surface_clip_h, - m_surface_clip_x, m_surface_clip_y, m_surface_clip_x + m_surface_clip_w, m_surface_clip_y + m_surface_clip_h, - GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);*/ - if(m_fbo.IsCreated()) - m_fbo.Bind(); - - for(uint i=0; iFlip(m_context); - - if(m_fbo.IsCreated()) - m_fbo.Bind(); - if(m_set_scissor_horizontal && m_set_scissor_vertical) { glScissor(m_scissor_x, m_scissor_y, m_scissor_w, m_scissor_h); diff --git a/rpcs3/Emu/GS/GL/GLGSRender.h b/rpcs3/Emu/GS/GL/GLGSRender.h index 1cb8869ab2..8839d578ea 100644 --- a/rpcs3/Emu/GS/GL/GLGSRender.h +++ b/rpcs3/Emu/GS/GL/GLGSRender.h @@ -258,19 +258,31 @@ public: case CELL_GCM_TEXTURE_X16: // A 16-bit fixed-point number { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RED, GL_SHORT, pixels); + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); + checkForGlError("GLTexture::Init() -> glPixelStorei"); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RED, GL_UNSIGNED_SHORT, pixels); checkForGlError("GLTexture::Init() -> glTexImage2D"); - static const GLint swizzleMaskX16[] = { GL_RED, GL_ONE, GL_ONE, GL_ONE }; + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + checkForGlError("GLTexture::Init() -> glPixelStorei"); + + static const GLint swizzleMaskX16[] = { GL_RED, GL_ONE, GL_RED, GL_ONE }; glRemap = swizzleMaskX16; } break; case CELL_GCM_TEXTURE_Y16_X16: // Two 16-bit fixed-point numbers { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RG, GL_SHORT, pixels); + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); + checkForGlError("GLTexture::Init() -> glPixelStorei"); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RG, GL_UNSIGNED_SHORT, pixels); checkForGlError("GLTexture::Init() -> glTexImage2D"); + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + checkForGlError("GLTexture::Init() -> glPixelStorei"); + static const GLint swizzleMaskX32_Y16_X16[] = { GL_GREEN, GL_RED, GL_GREEN, GL_RED }; glRemap = swizzleMaskX32_Y16_X16; } @@ -288,8 +300,14 @@ public: break; case CELL_GCM_TEXTURE_W16_Z16_Y16_X16_FLOAT: // Four fp16 values - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_BGRA, GL_HALF_FLOAT, pixels); + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); + checkForGlError("GLTexture::Init() -> glPixelStorei"); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RGBA, GL_HALF_FLOAT, pixels); checkForGlError("GLTexture::Init() -> glTexImage2D"); + + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + checkForGlError("GLTexture::Init() -> glPixelStorei"); break; case CELL_GCM_TEXTURE_W32_Z32_Y32_X32_FLOAT: // Four fp32 values @@ -336,17 +354,22 @@ public: case CELL_GCM_TEXTURE_Y16_X16_FLOAT: // Two fp16 values { + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_TRUE); + checkForGlError("GLTexture::Init() -> glPixelStorei"); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.GetWidth(), tex.GetHeight(), 0, GL_RG, GL_HALF_FLOAT, pixels); checkForGlError("GLTexture::Init() -> glTexImage2D"); - static const GLint swizzleMaskX32_Y16_X16_FLOAT[] = { GL_GREEN, GL_RED, GL_GREEN, GL_RED }; + glPixelStorei(GL_UNPACK_SWAP_BYTES, GL_FALSE); + checkForGlError("GLTexture::Init() -> glPixelStorei"); + + static const GLint swizzleMaskX32_Y16_X16_FLOAT[] = { GL_RED, GL_GREEN, GL_RED, GL_GREEN }; glRemap = swizzleMaskX32_Y16_X16_FLOAT; } break; - case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8: + case CELL_GCM_TEXTURE_COMPRESSED_B8R8_G8R8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN): { - // TODO: Probably need to actually unswizzle if is_swizzled. const u32 numPixels = tex.GetWidth() * tex.GetHeight(); unswizzledPixels = (u8 *)malloc(numPixels * 4); // TODO: Speed. @@ -370,9 +393,8 @@ public: } break; - case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8: + case CELL_GCM_TEXTURE_COMPRESSED_R8B8_R8G8 & ~(CELL_GCM_TEXTURE_LN | CELL_GCM_TEXTURE_UN): { - // TODO: Probably need to actually unswizzle if is_swizzled. const u32 numPixels = tex.GetWidth() * tex.GetHeight(); unswizzledPixels = (u8 *)malloc(numPixels * 4); // TODO: Speed. @@ -805,11 +827,11 @@ private: virtual void Close(); bool LoadProgram(); void WriteDepthBuffer(); + void WriteColorBuffers(); void WriteColourBufferA(); void WriteColourBufferB(); void WriteColourBufferC(); void WriteColourBufferD(); - void WriteBuffers(); void DrawObjects(); diff --git a/rpcs3/Emu/GS/RSXThread.cpp b/rpcs3/Emu/GS/RSXThread.cpp index c5a9233279..13115f43a6 100644 --- a/rpcs3/Emu/GS/RSXThread.cpp +++ b/rpcs3/Emu/GS/RSXThread.cpp @@ -11,7 +11,10 @@ u32 GetAddress(u32 offset, u8 location) switch(location) { case CELL_GCM_LOCATION_LOCAL: return Memory.RSXFBMem.GetStartAddr() + offset; - case CELL_GCM_LOCATION_MAIN: return Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + offset); + case CELL_GCM_LOCATION_MAIN: + u64 realAddr; + Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + offset, realAddr); // TODO: Error Check? + return realAddr; } ConLog.Error("GetAddress(offset=0x%x, location=0x%x)", location); @@ -477,6 +480,11 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3 m_front_polygon_mode = ARGS(0); break; + case NV4097_SET_BACK_POLYGON_MODE: + m_set_back_polygon_mode = true; + m_back_polygon_mode = ARGS(0); + break; + case NV4097_CLEAR_ZCULL_SURFACE: { u32 a0 = ARGS(0); @@ -757,6 +765,10 @@ void RSXThread::DoCmd(const u32 fcmd, const u32 cmd, mem32_ptr_t& args, const u3 m_set_logic_op = ARGS(0) ? true : false; break; + case NV4097_SET_LOGIC_OP: + m_logic_op = ARGS(0); + break; + case NV4097_SET_CULL_FACE_ENABLE: m_set_cull_face_enable = ARGS(0) ? true : false; break; diff --git a/rpcs3/Emu/GS/RSXThread.h b/rpcs3/Emu/GS/RSXThread.h index 7fd5e46bd3..1b2a675002 100644 --- a/rpcs3/Emu/GS/RSXThread.h +++ b/rpcs3/Emu/GS/RSXThread.h @@ -166,7 +166,6 @@ public: bool m_set_blend; bool m_set_depth_bounds_test; bool m_depth_test_enable; - bool m_set_logic_op; bool m_set_cull_face_enable; bool m_set_dither; bool m_set_stencil_test; @@ -176,6 +175,11 @@ public: bool m_set_poly_offset_line; bool m_set_poly_offset_point; + bool m_set_poly_offset_scale_factor; + u32 m_poly_offset_scale_factor; + bool m_set_poly_offset_bias; + u32 m_poly_offset_bias; + bool m_set_restart_index; u32 m_restart_index; @@ -195,7 +199,12 @@ public: bool m_set_front_polygon_mode; u32 m_front_polygon_mode; - + bool m_set_back_polygon_mode; + u32 m_back_polygon_mode; + + bool m_set_logic_op; + u32 m_logic_op; + u32 m_clear_surface_mask; u32 m_clear_surface_z; u8 m_clear_surface_s; @@ -380,6 +389,7 @@ public: u32 m_surface_colour_target; + bool m_set_front_face; u32 m_front_face; u8 m_begin_end; @@ -424,10 +434,16 @@ protected: m_clear_z = 0xffffff; m_clear_s = 0; + m_poly_offset_scale_factor = 0; + m_poly_offset_bias = 0; + m_depth_bounds_min = 0.0; m_depth_bounds_max = 1.0; m_restart_index = 0xffffffff; + m_front_polygon_mode = 0x1B02; // GL_FILL + m_back_polygon_mode = 0x1B02; // GL_FILL + m_point_x = 0; m_point_y = 0; @@ -455,6 +471,7 @@ protected: m_set_scissor_horizontal = false; m_set_scissor_vertical = false; m_set_front_polygon_mode = false; + m_set_back_polygon_mode = false; m_set_blend_sfactor = false; m_set_blend_dfactor = false; m_set_stencil_mask = false; @@ -492,6 +509,8 @@ protected: m_set_poly_offset_fill = false; m_set_poly_offset_line = false; m_set_poly_offset_point = false; + m_set_poly_offset_scale_factor = false; + m_set_poly_offset_bias = false; m_set_restart_index = false; m_clear_surface_mask = 0; diff --git a/rpcs3/Emu/GS/sysutil_video.h b/rpcs3/Emu/GS/sysutil_video.h index ce92847a29..3488427c25 100644 --- a/rpcs3/Emu/GS/sysutil_video.h +++ b/rpcs3/Emu/GS/sysutil_video.h @@ -232,6 +232,7 @@ static const CellVideoOutResolution ResolutionTable[] = {1440, 1080}, //11 - 6 {1280, 1080}, //12 - 7 {960, 1080}, //13 - 8 + {960, 540}, //14 - 9 }; inline static u32 ResolutionIdToNum(u32 id) @@ -252,9 +253,10 @@ inline static u32 ResolutionIdToNum(u32 id) 6, //11 7, //12 8, //13 + 9, //14 }; - return id <= 13 ? res[id] : 0; + return id <= 14 ? res[id] : 0; } inline static u32 ResolutionNumToId(u32 num) @@ -270,7 +272,8 @@ inline static u32 ResolutionNumToId(u32 num) 11, 12, 13, + 14, }; - return num <= 8 ? res[num] : 0; + return num <= 9 ? res[num] : 0; } diff --git a/rpcs3/Emu/Io/PadHandler.h b/rpcs3/Emu/Io/PadHandler.h index 207d2ae3aa..050a5fce3f 100644 --- a/rpcs3/Emu/Io/PadHandler.h +++ b/rpcs3/Emu/Io/PadHandler.h @@ -126,6 +126,7 @@ struct AnalogStick struct Pad { + bool m_buffer_cleared; u32 m_port_status; u32 m_port_setting; u32 m_device_capability; @@ -165,7 +166,8 @@ struct Pad u16 m_sensor_g; Pad(u32 port_status, u32 port_setting, u32 device_capability, u32 device_type) - : m_port_status(port_status) + : m_buffer_cleared(true) + , m_port_status(port_status) , m_port_setting(port_setting) , m_device_capability(device_capability) , m_device_type(device_type) diff --git a/rpcs3/Emu/Memory/Memory.cpp b/rpcs3/Emu/Memory/Memory.cpp index 755dd389f5..7a1ca1e8b2 100644 --- a/rpcs3/Emu/Memory/Memory.cpp +++ b/rpcs3/Emu/Memory/Memory.cpp @@ -87,7 +87,7 @@ MemoryBlock* MemoryBlock::SetRange(const u64 start, const u32 size) bool MemoryBlock::IsMyAddress(const u64 addr) { - return mem && addr >= GetStartAddr() && addr < GetEndAddr(); + return mem && addr >= GetStartAddr() && addr <= GetEndAddr(); } template @@ -614,21 +614,25 @@ u32 VirtualMemoryBlock::UnmapAddress(u64 addr) bool VirtualMemoryBlock::Read8(const u64 addr, u8* value) { u64 realAddr; - *value = Memory.Read8(realAddr = getRealAddr(addr)); - return realAddr != 0; + if(!getRealAddr(addr, realAddr)) + return false; + *value = Memory.Read8(realAddr); + return true; } bool VirtualMemoryBlock::Read16(const u64 addr, u16* value) { u64 realAddr; - *value = Memory.Read16(realAddr = getRealAddr(addr)); - return realAddr != 0; + if(!getRealAddr(addr, realAddr)) + return false; + *value = Memory.Read16(realAddr); + return true; } bool VirtualMemoryBlock::Read32(const u64 addr, u32* value) { - u64 realAddr = getRealAddr(addr); - if (realAddr == 0) + u64 realAddr; + if (!getRealAddr(addr, realAddr)) return false; *value = Memory.Read32(realAddr); return true; @@ -637,63 +641,78 @@ bool VirtualMemoryBlock::Read32(const u64 addr, u32* value) bool VirtualMemoryBlock::Read64(const u64 addr, u64* value) { u64 realAddr; - *value = Memory.Read64(realAddr = getRealAddr(addr)); - return realAddr != 0; + if(!getRealAddr(addr, realAddr)) + return false; + *value = Memory.Read64(realAddr); + return true; } bool VirtualMemoryBlock::Read128(const u64 addr, u128* value) { u64 realAddr; - *value = Memory.Read128(realAddr = getRealAddr(addr)); - return realAddr != 0; + if(!getRealAddr(addr, realAddr)) + return false; + *value = Memory.Read128(realAddr); + return true; } bool VirtualMemoryBlock::Write8(const u64 addr, const u8 value) { u64 realAddr; - Memory.Write8(realAddr = getRealAddr(addr), value); - return realAddr != 0; + if(!getRealAddr(addr, realAddr)) + return false; + Memory.Write8(realAddr, value); + return true; } bool VirtualMemoryBlock::Write16(const u64 addr, const u16 value) { u64 realAddr; - Memory.Write16(realAddr = getRealAddr(addr), value); - return realAddr != 0; + if(!getRealAddr(addr, realAddr)) + return false; + Memory.Write16(realAddr, value); + return true; } bool VirtualMemoryBlock::Write32(const u64 addr, const u32 value) { u64 realAddr; - Memory.Write32(realAddr = getRealAddr(addr), value); - return realAddr != 0; + if(!getRealAddr(addr, realAddr)) + return false; + Memory.Write32(realAddr, value); + return true; } bool VirtualMemoryBlock::Write64(const u64 addr, const u64 value) { u64 realAddr; - Memory.Write64(realAddr = getRealAddr(addr), value); - return realAddr != 0; + if(!getRealAddr(addr, realAddr)) + return false; + Memory.Write64(realAddr, value); + return true; } bool VirtualMemoryBlock::Write128(const u64 addr, const u128 value) { u64 realAddr; - Memory.Write128(realAddr = getRealAddr(addr), value); - return realAddr != 0; + if(!getRealAddr(addr, realAddr)) + return false; + Memory.Write128(realAddr, value); + return true; } -u64 VirtualMemoryBlock::getRealAddr(u64 addr) +bool VirtualMemoryBlock::getRealAddr(u64 addr, u64& result) { for(u32 i=0; i= m_mapped_memory[i].addr && addr < m_mapped_memory[i].addr + m_mapped_memory[i].size) { - return m_mapped_memory[i].realAddress + (addr - m_mapped_memory[i].addr); + result = m_mapped_memory[i].realAddress + (addr - m_mapped_memory[i].addr); + return true; } } - return 0; + return false; } u64 VirtualMemoryBlock::getMappedAddress(u64 realAddress) diff --git a/rpcs3/Emu/Memory/MemoryBlock.h b/rpcs3/Emu/Memory/MemoryBlock.h index 144055716c..1709214878 100644 --- a/rpcs3/Emu/Memory/MemoryBlock.h +++ b/rpcs3/Emu/Memory/MemoryBlock.h @@ -281,8 +281,9 @@ public: virtual bool Write64(const u64 addr, const u64 value); virtual bool Write128(const u64 addr, const u128 value); - // return the real address given a mapped address, if not mapped return 0 - u64 getRealAddr(u64 addr); + // try to get the real address given a mapped address + // return true for success + bool getRealAddr(u64 addr, u64& result); // return the mapped address given a real address, if not mapped return 0 u64 getMappedAddress(u64 realAddress); diff --git a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp index 2a463daa48..55a01b8af2 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellGcmSys.cpp @@ -339,16 +339,16 @@ int cellGcmSetPrepareFlip(mem_ptr_t ctxt, u32 id) { ConLog.Warning("bad flip!"); //cellGcmCallback(ctxt.GetAddr(), current + 8 - end); - //copied: + //copied: - CellGcmControl& ctrl = (CellGcmControl&)Memory[gcm_info.control_addr]; + CellGcmControl& ctrl = (CellGcmControl&)Memory[gcm_info.control_addr]; - const s32 res = ctxt->current - ctxt->begin - ctrl.put; + const s32 res = ctxt->current - ctxt->begin - ctrl.put; - if(res > 0) Memory.Copy(ctxt->begin, ctxt->current - res, res); - ctxt->current = ctxt->begin + res; - ctrl.put = res; - ctrl.get = 0; + if(res > 0) Memory.Copy(ctxt->begin, ctxt->current - res, res); + ctxt->current = ctxt->begin + res; + ctrl.put = res; + ctrl.get = 0; } current = ctxt->current; @@ -575,9 +575,7 @@ int32_t cellGcmIoOffsetToAddress(u32 ioOffset, u64 address) { u64 realAddr; - realAddr = Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + ioOffset); - - if (!realAddr) + if (!Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + ioOffset, realAddr)) return CELL_GCM_ERROR_FAILURE; Memory.Write64(address, realAddr); diff --git a/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp b/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp index 0d0b5de06e..617676d2aa 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellPamf.cpp @@ -112,6 +112,9 @@ int cellPamfGetHeaderSize(mem_ptr_t pAddr, u64 fileSize, mem64_t pSi cellPamf.Warning("cellPamfGetHeaderSize(pAddr=0x%x, fileSize=%d, pSize_addr=0x%x)", pAddr.GetAddr(), fileSize, pSize.GetAddr()); + if (!pAddr.IsGood() || !pSize.IsGood()) + return CELL_PAMF_ERROR_INVALID_ARG; + //if ((u32)pAddr->magic != 0x464d4150) //return CELL_PAMF_ERROR_UNKNOWN_TYPE; @@ -125,6 +128,9 @@ int cellPamfGetHeaderSize2(mem_ptr_t pAddr, u64 fileSize, u32 attrib cellPamf.Warning("cellPamfGetHeaderSize2(pAddr=0x%x, fileSize=%d, attribute=0x%x, pSize_addr=0x%x)", pAddr.GetAddr(), fileSize, attribute, pSize.GetAddr()); + if (!pAddr.IsGood() || !pSize.IsGood()) + return CELL_PAMF_ERROR_INVALID_ARG; + //if ((u32)pAddr->magic != 0x464d4150) //return CELL_PAMF_ERROR_UNKNOWN_TYPE; @@ -138,6 +144,9 @@ int cellPamfGetStreamOffsetAndSize(mem_ptr_t pAddr, u64 fileSize, me cellPamf.Warning("cellPamfGetStreamOffsetAndSize(pAddr=0x%x, fileSize=%d, pOffset_addr=0x%x, pSize_addr=0x%x)", pAddr.GetAddr(), fileSize, pOffset.GetAddr(), pSize.GetAddr()); + if (!pAddr.IsGood() || !pOffset.IsGood() || !pSize.IsGood()) + return CELL_PAMF_ERROR_INVALID_ARG; + //if ((u32)pAddr->magic != 0x464d4150) //return CELL_PAMF_ERROR_UNKNOWN_TYPE; @@ -151,6 +160,10 @@ int cellPamfGetStreamOffsetAndSize(mem_ptr_t pAddr, u64 fileSize, me int cellPamfVerify(mem_ptr_t pAddr, u64 fileSize) { cellPamf.Warning("cellPamfVerify(pAddr=0x%x, fileSize=%d)", pAddr.GetAddr(), fileSize); + + if (!pAddr.IsGood()) + return CELL_PAMF_ERROR_INVALID_ARG; + return CELL_OK; } @@ -159,6 +172,9 @@ int cellPamfReaderInitialize(mem_ptr_t pSelf, mem_ptr_tfileSize = fileSize; @@ -183,6 +199,9 @@ int cellPamfReaderGetPresentationStartTime(mem_ptr_t pSelf, mem_ cellPamf.Warning("cellPamfReaderGetPresentationStartTime(pSelf=0x%x, pTimeStamp_addr=0x%x)", pSelf.GetAddr(), pTimeStamp.GetAddr()); + if (!pSelf.IsGood() || !Memory.IsGoodAddr(pSelf->pAddr)) + return CELL_PAMF_ERROR_INVALID_ARG; + const mem_ptr_t pAddr(pSelf->pAddr); const u32 upper = (u16)pAddr->start_pts_high; pTimeStamp->upper = upper; @@ -195,6 +214,9 @@ int cellPamfReaderGetPresentationEndTime(mem_ptr_t pSelf, mem_pt cellPamf.Warning("cellPamfReaderGetPresentationEndTime(pSelf=0x%x, pTimeStamp_addr=0x%x)", pSelf.GetAddr(), pTimeStamp.GetAddr()); + if (!pSelf.IsGood() || !Memory.IsGoodAddr(pSelf->pAddr)) + return CELL_PAMF_ERROR_INVALID_ARG; + const mem_ptr_t pAddr(pSelf->pAddr); const u32 upper = (u16)pAddr->end_pts_high; pTimeStamp->upper = upper; @@ -206,6 +228,9 @@ int cellPamfReaderGetMuxRateBound(mem_ptr_t pSelf) { cellPamf.Warning("cellPamfReaderGetMuxRateBound(pSelf=0x%x)", pSelf.GetAddr()); + if (!pSelf.IsGood() || !Memory.IsGoodAddr(pSelf->pAddr)) + return CELL_PAMF_ERROR_INVALID_ARG; + const mem_ptr_t pAddr(pSelf->pAddr); return pAddr->mux_rate_max; } @@ -214,6 +239,9 @@ int cellPamfReaderGetNumberOfStreams(mem_ptr_t pSelf) { cellPamf.Warning("cellPamfReaderGetNumberOfStreams(pSelf=0x%x)", pSelf.GetAddr()); + if (!pSelf.IsGood() || !Memory.IsGoodAddr(pSelf->pAddr)) + return CELL_PAMF_ERROR_INVALID_ARG; + const mem_ptr_t pAddr(pSelf->pAddr); return pAddr->stream_count; } @@ -223,6 +251,9 @@ int cellPamfReaderGetNumberOfSpecificStreams(mem_ptr_t pSelf, u8 cellPamf.Warning("cellPamfReaderGetNumberOfSpecificStreams(pSelf=0x%x, streamType=%d)", pSelf.GetAddr(), streamType); + if (!pSelf.IsGood() || !Memory.IsGoodAddr(pSelf->pAddr)) + return CELL_PAMF_ERROR_INVALID_ARG; + const mem_ptr_t pAddr(pSelf->pAddr); int counts[6] = {0, 0, 0, 0, 0, 0}; @@ -256,6 +287,9 @@ int cellPamfReaderSetStreamWithIndex(mem_ptr_t pSelf, u8 streamI cellPamf.Warning("cellPamfReaderSetStreamWithIndex(pSelf=0x%x, streamIndex=%d)", pSelf.GetAddr(), streamIndex); + if (!pSelf.IsGood() || !Memory.IsGoodAddr(pSelf->pAddr)) + return CELL_PAMF_ERROR_INVALID_ARG; + const mem_ptr_t pAddr(pSelf->pAddr); if (streamIndex < pAddr->stream_count) @@ -274,6 +308,9 @@ int cellPamfReaderSetStreamWithTypeAndChannel(mem_ptr_t pSelf, u cellPamf.Warning("cellPamfReaderSetStreamWithTypeAndChannel(pSelf=0x%x, streamType=%d, ch=%d)", pSelf.GetAddr(), streamType, ch); + if (!pSelf.IsGood() || !Memory.IsGoodAddr(pSelf->pAddr)) + return CELL_PAMF_ERROR_INVALID_ARG; + const mem_ptr_t pAddr(pSelf->pAddr); if (streamType > 5) @@ -303,6 +340,9 @@ int cellPamfReaderSetStreamWithTypeAndIndex(mem_ptr_t pSelf, u8 cellPamf.Warning("cellPamfReaderSetStreamWithTypeAndIndex(pSelf=0x%x, streamType=%d, streamIndex=%d)", pSelf.GetAddr(), streamType, streamIndex); + if (!pSelf.IsGood() || !Memory.IsGoodAddr(pSelf->pAddr)) + return CELL_PAMF_ERROR_INVALID_ARG; + const mem_ptr_t pAddr(pSelf->pAddr); u32 found = 0; @@ -351,6 +391,9 @@ int cellPamfStreamTypeToEsFilterId(u8 type, u8 ch, mem_ptr_t pSelf) { cellPamf.Log("cellPamfReaderGetStreamIndex(pSelf=0x%x)", pSelf.GetAddr()); + if (!pSelf.IsGood()) + return CELL_PAMF_ERROR_INVALID_ARG; + return pSelf->stream; } @@ -366,6 +412,9 @@ int cellPamfReaderGetStreamTypeAndChannel(mem_ptr_t pSelf, mem8_ cellPamf.Warning("cellPamfReaderGetStreamTypeAndChannel(pSelf=0x%x (stream=%d), pType_addr=0x%x, pCh_addr=0x%x", pSelf.GetAddr(), pSelf->stream, pType.GetAddr(), pCh.GetAddr()); + if (!pSelf.IsGood() || !pCh.IsGood()) + return CELL_PAMF_ERROR_INVALID_ARG; + pType = pamfGetStreamType(pSelf, pSelf->stream); pCh = pamfGetStreamChannel(pSelf, pSelf->stream); return CELL_OK; @@ -376,6 +425,9 @@ int cellPamfReaderGetEsFilterId(mem_ptr_t pSelf, mem_ptr_tstream, pEsFilterId.GetAddr()); + if (!pSelf.IsGood() || !pEsFilterId.IsGood()) + return CELL_PAMF_ERROR_INVALID_ARG; + return pamfStreamTypeToEsFilterId(pamfGetStreamType(pSelf, pSelf->stream), pamfGetStreamChannel(pSelf, pSelf->stream), pEsFilterId); } @@ -385,6 +437,9 @@ int cellPamfReaderGetStreamInfo(mem_ptr_t pSelf, u32 pInfo_addr, cellPamf.Warning("cellPamfReaderGetStreamInfo(pSelf=0x%x (stream=%d), pInfo_addr=0x%x, size=%d)", pSelf.GetAddr(), pSelf->stream, pInfo_addr, size); + if (!pSelf.IsGood() || !Memory.IsGoodAddr(pSelf->pAddr)) + return CELL_PAMF_ERROR_INVALID_ARG; + const mem_ptr_t pAddr(pSelf->pAddr); memset(Memory + pInfo_addr, 0, size); @@ -493,6 +548,9 @@ int cellPamfReaderGetNumberOfEp(mem_ptr_t pSelf) cellPamf.Warning("cellPamfReaderGetNumberOfEp(pSelf=0x%x (stream=%d))", pSelf.GetAddr(), pSelf->stream); + if (!pSelf.IsGood() || !Memory.IsGoodAddr(pSelf->pAddr)) + return CELL_PAMF_ERROR_INVALID_ARG; + const mem_ptr_t pAddr(pSelf->pAddr); return pAddr->stream_headers[pSelf->stream].ep_num; } @@ -502,6 +560,9 @@ int cellPamfReaderGetEpIteratorWithIndex(mem_ptr_t pSelf, u32 ep cellPamf.Error("cellPamfReaderGetEpIteratorWithIndex(pSelf=0x%x (stream=%d), epIndex=%d, pIt_addr=0x%x)", pSelf.GetAddr(), pSelf->stream, epIndex, pIt.GetAddr()); + if (!pSelf.IsGood() || !Memory.IsGoodAddr(pSelf->pAddr)) + return CELL_PAMF_ERROR_INVALID_ARG; + const mem_ptr_t pAddr(pSelf->pAddr); //TODO: return CELL_OK; @@ -556,4 +617,4 @@ void cellPamf_init() cellPamf.AddFunc(0x439fba17, cellPamfReaderGetEpIteratorWithTimeStamp); cellPamf.AddFunc(0x1abeb9d6, cellPamfEpIteratorGetEp); cellPamf.AddFunc(0x50b83205, cellPamfEpIteratorMove); -} \ No newline at end of file +} diff --git a/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp b/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp index 088eaa1d1c..5fba6b71a0 100644 --- a/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp +++ b/rpcs3/Emu/SysCalls/Modules/cellUserInfo.cpp @@ -60,9 +60,17 @@ int cellUserInfoGetList(mem32_t listNum, mem_ptr_t listBuf cellUserInfo.Warning("cellUserInfoGetList(listNum_addr=0x%x, listBuf_addr=0x%x, currentUserId_addr=0x%x)", listNum.GetAddr(), listBuf.GetAddr(), currentUserId.GetAddr()); - listNum = 1; - listBuf->userId[0] = 1; - currentUserId = 1; + // If only listNum is NULL, an should will be returned + if (listBuf.IsGood() && !listNum.IsGood()) + return CELL_USERINFO_ERROR_PARAM; + if (listNum.IsGood()) + listNum = 1; + if (listBuf.IsGood()) + listBuf->userId[0] = 1; + + if (currentUserId.IsGood()) + currentUserId = 1; + return CELL_OK; } diff --git a/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp b/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp index f94653db1d..403fce0ca2 100644 --- a/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp +++ b/rpcs3/Emu/SysCalls/lv2/SC_Pad.cpp @@ -75,13 +75,13 @@ int cellPadClearBuf(u32 port_no) if (port_no >= rinfo.max_connect) return CELL_PAD_ERROR_INVALID_PARAMETER; if (port_no >= rinfo.now_connect) return CELL_PAD_ERROR_NO_DEVICE; - //It seems the system is supposed keeps track of previous values, and reports paddata with len 0 if - //nothing has changed. + //Set 'm_buffer_cleared' to force a resend of everything + //might as well also reset everything in our pad 'buffer' to nothing as well - //We can at least reset the pad back to its default values for now std::vector& pads = Emu.GetPadManager().GetPads(); Pad& pad = pads[port_no]; + pad.m_buffer_cleared = true; pad.m_analog_left_x = pad.m_analog_left_y = pad.m_analog_right_x = pad.m_analog_right_y = 128; pad.m_digital_1 = pad.m_digital_2 = 0; @@ -110,10 +110,14 @@ int cellPadGetData(u32 port_no, u32 data_addr) CellPadData data; memset(&data, 0, sizeof(CellPadData)); + u16 d1Initial, d2Initial; + d1Initial = pad.m_digital_1; + d2Initial = pad.m_digital_2; + bool btnChanged = false; for(Button& button : pad.m_buttons) { - //using an if/else here, not doing switch in switch - //plus side is this gives us the ability to check if anything changed eventually + //here we check btns, and set pad accordingly, + //if something changed, set btnChanged if (button.m_offset == CELL_PAD_BTN_OFFSET_DIGITAL1) { @@ -122,10 +126,22 @@ int cellPadGetData(u32 port_no, u32 data_addr) switch (button.m_outKeyCode) { - case CELL_PAD_CTRL_LEFT: pad.m_press_left = button.m_value; break; - case CELL_PAD_CTRL_DOWN: pad.m_press_down = button.m_value; break; - case CELL_PAD_CTRL_RIGHT: pad.m_press_right = button.m_value; break; - case CELL_PAD_CTRL_UP: pad.m_press_up = button.m_value; break; + case CELL_PAD_CTRL_LEFT: + if (pad.m_press_left != button.m_value) btnChanged = true; + pad.m_press_left = button.m_value; + break; + case CELL_PAD_CTRL_DOWN: + if (pad.m_press_down != button.m_value) btnChanged = true; + pad.m_press_down = button.m_value; + break; + case CELL_PAD_CTRL_RIGHT: + if (pad.m_press_right != button.m_value) btnChanged = true; + pad.m_press_right = button.m_value; + break; + case CELL_PAD_CTRL_UP: + if (pad.m_press_up != button.m_value) btnChanged = true; + pad.m_press_up = button.m_value; + break; //These arent pressure btns case CELL_PAD_CTRL_R3: case CELL_PAD_CTRL_L3: @@ -141,14 +157,38 @@ int cellPadGetData(u32 port_no, u32 data_addr) switch (button.m_outKeyCode) { - case CELL_PAD_CTRL_SQUARE: pad.m_press_square = button.m_value; break; - case CELL_PAD_CTRL_CROSS: pad.m_press_cross = button.m_value; break; - case CELL_PAD_CTRL_CIRCLE: pad.m_press_circle = button.m_value; break; - case CELL_PAD_CTRL_TRIANGLE: pad.m_press_triangle = button.m_value; break; - case CELL_PAD_CTRL_R1: pad.m_press_R1 = button.m_value; break; - case CELL_PAD_CTRL_L1: pad.m_press_L1 = button.m_value; break; - case CELL_PAD_CTRL_R2: pad.m_press_R2 = button.m_value; break; - case CELL_PAD_CTRL_L2: pad.m_press_L2 = button.m_value; break; + case CELL_PAD_CTRL_SQUARE: + if (pad.m_press_square != button.m_value) btnChanged = true; + pad.m_press_square = button.m_value; + break; + case CELL_PAD_CTRL_CROSS: + if (pad.m_press_cross != button.m_value) btnChanged = true; + pad.m_press_cross = button.m_value; + break; + case CELL_PAD_CTRL_CIRCLE: + if (pad.m_press_circle != button.m_value) btnChanged = true; + pad.m_press_circle = button.m_value; + break; + case CELL_PAD_CTRL_TRIANGLE: + if (pad.m_press_triangle != button.m_value) btnChanged = true; + pad.m_press_triangle = button.m_value; + break; + case CELL_PAD_CTRL_R1: + if (pad.m_press_R1 != button.m_value) btnChanged = true; + pad.m_press_R1 = button.m_value; + break; + case CELL_PAD_CTRL_L1: + if (pad.m_press_L1 != button.m_value) btnChanged = true; + pad.m_press_L1 = button.m_value; + break; + case CELL_PAD_CTRL_R2: + if (pad.m_press_R2 != button.m_value) btnChanged = true; + pad.m_press_R2 = button.m_value; + break; + case CELL_PAD_CTRL_L2: + if (pad.m_press_L2 != button.m_value) btnChanged = true; + pad.m_press_L2 = button.m_value; + break; default: break; } } @@ -165,15 +205,44 @@ int cellPadGetData(u32 port_no, u32 data_addr) { switch (stick.m_offset) { - case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: pad.m_analog_left_x = stick.m_value; break; - case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: pad.m_analog_left_y = stick.m_value; break; - case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: pad.m_analog_right_x = stick.m_value; break; - case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: pad.m_analog_right_y = stick.m_value; break; + case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_X: + if (pad.m_analog_left_x != stick.m_value) btnChanged = true; + pad.m_analog_left_x = stick.m_value; + break; + case CELL_PAD_BTN_OFFSET_ANALOG_LEFT_Y: + if (pad.m_analog_left_y != stick.m_value) btnChanged = true; + pad.m_analog_left_y = stick.m_value; + break; + case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X: + if (pad.m_analog_right_x != stick.m_value) btnChanged = true; + pad.m_analog_right_x = stick.m_value; + break; + case CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_Y: + if (pad.m_analog_right_y != stick.m_value) btnChanged = true; + pad.m_analog_right_y = stick.m_value; + break; default: break; } } - - data.len = pad.m_buttons.size(); + if (d1Initial != pad.m_digital_1 || d2Initial != pad.m_digital_2) + { + btnChanged = true; + } + + //not sure if this should officially change with capabilities/portsettings :( + data.len = CELL_PAD_MAX_CODES; + + //report len 0 if nothing changed and if we havent recently cleared buffer + if (pad.m_buffer_cleared) + { + pad.m_buffer_cleared = false; + } + else if (!btnChanged) + { + data.len = 0; + } + + //lets still send new data anyway, not sure whats expected still data.button[CELL_PAD_BTN_OFFSET_DIGITAL1] = pad.m_digital_1; data.button[CELL_PAD_BTN_OFFSET_DIGITAL2] = pad.m_digital_2; data.button[CELL_PAD_BTN_OFFSET_ANALOG_RIGHT_X] = pad.m_analog_right_x; @@ -353,9 +422,9 @@ int cellPadInfoSensorMode(u32 port_no) int cellPadSetPressMode(u32 port_no, u32 mode) { - sys_io.Log("cellPadSetPressMode(port_no=%d)", port_no); + sys_io.Log("cellPadSetPressMode(port_no=%u, mode=%u)", port_no, mode); if (!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; - if (mode != 0 || mode != 1) return CELL_PAD_ERROR_INVALID_PARAMETER; + if (mode != 0 && mode != 1) return CELL_PAD_ERROR_INVALID_PARAMETER; const PadInfo& rinfo = Emu.GetPadManager().GetInfo(); if (port_no >= rinfo.max_connect) return CELL_PAD_ERROR_INVALID_PARAMETER; if (port_no >= rinfo.now_connect) return CELL_PAD_ERROR_NO_DEVICE; @@ -372,9 +441,9 @@ int cellPadSetPressMode(u32 port_no, u32 mode) int cellPadSetSensorMode(u32 port_no, u32 mode) { - sys_io.Log("cellPadSetPressMode(port_no=%d)", port_no); + sys_io.Log("cellPadSetSensorMode(port_no=%u, mode=%u)", port_no, mode); if (!Emu.GetPadManager().IsInited()) return CELL_PAD_ERROR_UNINITIALIZED; - if (mode != 0 || mode != 1) return CELL_PAD_ERROR_INVALID_PARAMETER; + if (mode != 0 && mode != 1) return CELL_PAD_ERROR_INVALID_PARAMETER; const PadInfo& rinfo = Emu.GetPadManager().GetInfo(); if (port_no >= rinfo.max_connect) return CELL_PAD_ERROR_INVALID_PARAMETER; if (port_no >= rinfo.now_connect) return CELL_PAD_ERROR_NO_DEVICE; diff --git a/rpcs3/Gui/MemoryViewer.cpp b/rpcs3/Gui/MemoryViewer.cpp index ff56509bcf..db9a10901b 100644 --- a/rpcs3/Gui/MemoryViewer.cpp +++ b/rpcs3/Gui/MemoryViewer.cpp @@ -191,20 +191,26 @@ void MemoryViewerPanel::ShowMemory() t_mem_addr_str += wxString::Format("%08x ", addr); } - for(u32 addr = m_addr; addr != m_addr + m_rowcount * m_colcount; addr++) + for (int row = 0; row < m_rowcount; row++) { - if (Memory.IsGoodAddr(addr)) + for (int col = 0; col < m_colcount; col++) { - const u8 rmem = Memory.Read8(addr); - t_mem_hex_str += wxString::Format("%02x ", rmem); - const wxString c_rmem = wxString::Format("%c", rmem); - t_mem_ascii_str += c_rmem.IsEmpty() ? "." : c_rmem; - } - else - { - t_mem_hex_str += "?? "; - t_mem_ascii_str += "?"; + u32 addr = m_addr + row * m_colcount + col; + + if (Memory.IsGoodAddr(addr)) + { + const u8 rmem = Memory.Read8(addr); + t_mem_hex_str += wxString::Format("%02x ", rmem); + const bool isPrintable = rmem >= 32 && rmem <= 126; + t_mem_ascii_str += isPrintable ? std::string(1, rmem) : "."; + } + else + { + t_mem_hex_str += "?? "; + t_mem_ascii_str += "?"; + } } + t_mem_ascii_str += "\r\n"; } t_mem_addr->SetValue(t_mem_addr_str); diff --git a/rpcs3/Gui/RSXDebugger.cpp b/rpcs3/Gui/RSXDebugger.cpp index 505f67395e..cdc5b31e50 100644 --- a/rpcs3/Gui/RSXDebugger.cpp +++ b/rpcs3/Gui/RSXDebugger.cpp @@ -322,20 +322,28 @@ void RSXDebugger::GoToGet(wxCommandEvent& event) { if (!RSXReady()) return; CellGcmControl* ctrl = (CellGcmControl*)&Memory[Emu.GetGSManager().GetRender().m_ctrlAddress]; - m_addr = Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + ctrl->get); - t_addr->SetValue(wxString::Format("%08x", m_addr)); - UpdateInformation(); - event.Skip(); + u64 realAddr; + if (Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + ctrl->get, realAddr)) { + m_addr = realAddr; // WARNING: Potential Truncation? Cast from u64 to u32 + t_addr->SetValue(wxString::Format("%08x", m_addr)); + UpdateInformation(); + event.Skip(); + } + // TODO: We should probably throw something? } void RSXDebugger::GoToPut(wxCommandEvent& event) { if (!RSXReady()) return; CellGcmControl* ctrl = (CellGcmControl*)&Memory[Emu.GetGSManager().GetRender().m_ctrlAddress]; - m_addr = Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + ctrl->put); - t_addr->SetValue(wxString::Format("%08x", m_addr)); - UpdateInformation(); - event.Skip(); + u64 realAddr; + if (Memory.RSXIOMem.getRealAddr(Memory.RSXIOMem.GetStartAddr() + ctrl->put, realAddr)) { + m_addr = realAddr; // WARNING: Potential Truncation? Cast from u64 to u32 + t_addr->SetValue(wxString::Format("%08x", m_addr)); + UpdateInformation(); + event.Skip(); + } + // TODO: We should probably throw something? } void RSXDebugger::UpdateInformation()