From f8ccc78e3122b06179ae3a1b35a95c9d2f671209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 29 Jul 2026 14:40:01 +0200 Subject: [PATCH 1/4] OpenGL on Android: Don't try to detect version too early --- Common/GPU/OpenGL/OpenGLGraphicsContext.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Common/GPU/OpenGL/OpenGLGraphicsContext.cpp b/Common/GPU/OpenGL/OpenGLGraphicsContext.cpp index 6ae331c739..ae18492576 100644 --- a/Common/GPU/OpenGL/OpenGLGraphicsContext.cpp +++ b/Common/GPU/OpenGL/OpenGLGraphicsContext.cpp @@ -8,16 +8,19 @@ OpenGLGraphicsContext::OpenGLGraphicsContext() { SetGPUBackend(GPUBackend::OPENGL); - CheckGLExtensions(); + // NOTE: On some Android devices, OpenGL is not yet available here so calling CheckGLExtension here + // doesn't work. // OpenGL handles rotated rendering in the driver. g_display.rotation = DisplayRotation::ROTATE_0; g_display.rot_matrix.setIdentity(); } bool OpenGLGraphicsContext::InitSurface(WindowSystem winsys, void *data1, void *data2, std::string *errorMessage) { + CheckGLExtensions(); INFO_LOG(Log::G3D, "OpenGLGraphicsContext::InitSurface"); draw_ = Draw::T3DCreateGLContext(false); // Can't fail renderManager_ = (GLRenderManager *)draw_->GetNativeObject(Draw::NativeObject::RENDER_MANAGER); + // TODO: In VR mode, we don't want a lot of inflight frames. renderManager_->SetInflightFrames(g_Config.iInflightFrames); const bool result = draw_->CreatePresets(); _dbg_assert_(result); From 6bdaf7caee1dcf288572e78c5bd5091c50c71b72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 29 Jul 2026 14:40:53 +0200 Subject: [PATCH 2/4] Fix null pointer access in InfraredHelper.java --- android/src/org/ppsspp/ppsspp/InfraredHelper.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/android/src/org/ppsspp/ppsspp/InfraredHelper.java b/android/src/org/ppsspp/ppsspp/InfraredHelper.java index 660932717c..cef1fda031 100644 --- a/android/src/org/ppsspp/ppsspp/InfraredHelper.java +++ b/android/src/org/ppsspp/ppsspp/InfraredHelper.java @@ -10,12 +10,16 @@ import java.util.Arrays; import java.util.List; class InfraredHelper { - private static final String TAG = InfraredHelper.class.getSimpleName(); + private static final String TAG = "PPSSPPActivity"; private static final int SIRC_FREQ = 40000; private final ConsumerIrManager mConsumerIrManager; InfraredHelper(Context context) throws Exception { mConsumerIrManager = (ConsumerIrManager) context.getSystemService(Context.CONSUMER_IR_SERVICE); + if (mConsumerIrManager == null) { + Log.i(TAG, "No IR manager detected."); + return; + } Log.d(TAG, "HasIrEmitter: " + mConsumerIrManager.hasIrEmitter()); if (!mConsumerIrManager.hasIrEmitter()) { throw new Exception("No Ir Emitter"); From b46566adc2cf8795bcde5dfa1cbfb4af0717c283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 29 Jul 2026 14:42:24 +0200 Subject: [PATCH 3/4] Logging improvements --- Common/GPU/OpenGL/GLRenderManager.cpp | 2 +- Common/GPU/Vulkan/VulkanRenderManager.cpp | 2 +- Common/GPU/thin3d.cpp | 1 + Common/LogReporting.cpp | 18 +++++++++--------- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Common/GPU/OpenGL/GLRenderManager.cpp b/Common/GPU/OpenGL/GLRenderManager.cpp index 8a0960f425..426b344b21 100644 --- a/Common/GPU/OpenGL/GLRenderManager.cpp +++ b/Common/GPU/OpenGL/GLRenderManager.cpp @@ -54,7 +54,7 @@ void GLRenderManager::ThreadStart(Draw::DrawContext *draw) { renderThreadId = std::this_thread::get_id(); if (newInflightFrames_ != -1) { - INFO_LOG(Log::G3D, "Updating inflight frames to %d", newInflightFrames_); + INFO_LOG(Log::G3D, "OpenGL: Updating inflight frames to %d", newInflightFrames_); inflightFrames_ = newInflightFrames_; newInflightFrames_ = -1; } diff --git a/Common/GPU/Vulkan/VulkanRenderManager.cpp b/Common/GPU/Vulkan/VulkanRenderManager.cpp index 4f580d5f26..fbe280c569 100644 --- a/Common/GPU/Vulkan/VulkanRenderManager.cpp +++ b/Common/GPU/Vulkan/VulkanRenderManager.cpp @@ -333,7 +333,7 @@ bool VulkanRenderManager::CreateBackbuffers() { curHeightRaw_ = -1; if (newInflightFrames_ != -1) { - INFO_LOG(Log::G3D, "Updating inflight frames to %d", newInflightFrames_); + INFO_LOG(Log::G3D, "Vulkan: Updating inflight frames to %d", newInflightFrames_); vulkan_->UpdateInflightFrames(newInflightFrames_); newInflightFrames_ = -1; } diff --git a/Common/GPU/thin3d.cpp b/Common/GPU/thin3d.cpp index 5a8bc6f22a..224a26507f 100644 --- a/Common/GPU/thin3d.cpp +++ b/Common/GPU/thin3d.cpp @@ -289,6 +289,7 @@ static ShaderModule *GenerateFShader(DrawContext *draw, FragmentShaderPreset pre } bool DrawContext::CreatePresets() { + INFO_LOG(Log::G3D, "Creating thin3d preset shaders..."); bool tintSupported = !bugs_.Has(Bugs::RASPBERRY_SHADER_COMP_HANG); for (int i = 0; i < VS_MAX_PRESET; i++) { diff --git a/Common/LogReporting.cpp b/Common/LogReporting.cpp index 9f41875aa0..b5909be304 100644 --- a/Common/LogReporting.cpp +++ b/Common/LogReporting.cpp @@ -58,14 +58,6 @@ void SetupCallbacks(AllowedCallback allowed, MessageCallback message) { } void ReportMessage(const char *message, ...) { - if (!allowedCallback || !messageCallback) { - ERROR_LOG(Log::System, "Reporting not initialized, skipping: %s", message); - return; - } - - if (!allowedCallback()) - return; - const int MESSAGE_BUFFER_SIZE = 65536; char *temp = new char [MESSAGE_BUFFER_SIZE]; @@ -75,6 +67,14 @@ void ReportMessage(const char *message, ...) { temp[MESSAGE_BUFFER_SIZE - 1] = '\0'; va_end(args); + if (!allowedCallback || !messageCallback) { + ERROR_LOG(Log::System, "Reporting not initialized, skipping: %s", temp); + return; + } + + if (!allowedCallback()) + return; + messageCallback(message, temp); delete[] temp; @@ -82,7 +82,7 @@ void ReportMessage(const char *message, ...) { void ReportMessageFormatted(const char *message, const char *formatted) { if (!allowedCallback || !messageCallback) { - ERROR_LOG(Log::System, "Reporting not initialized, skipping: %s", message); + ERROR_LOG(Log::System, "Reporting not initialized, skipping: %s", formatted); return; } From baf200acecdb214417ca7f6478f0c152137db34d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 29 Jul 2026 15:20:11 +0200 Subject: [PATCH 4/4] OpenXR: Improve mouse emulation, fix scrolling --- Common/VR/PPSSPPVR.cpp | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) diff --git a/Common/VR/PPSSPPVR.cpp b/Common/VR/PPSSPPVR.cpp index ef4fd3cf68..49f0786456 100644 --- a/Common/VR/PPSSPPVR.cpp +++ b/Common/VR/PPSSPPVR.cpp @@ -289,14 +289,14 @@ void UpdateVRInput(bool haptics, float dp_xscale, float dp_yscale) { } } - //enable or disable mouse + //enable or disable mouse for each controller. Only one can be the mouse at a time. for (int j = 0; j < 2; j++) { bool pressed = IN_VRGetButtonState(j) & ovrButton_Trigger; if (pressed) { - int lastController = mouseController; + const int lastController = mouseController; mouseController = j; - //prevent misclicks when changing the left/right controller + // prevent misclicks when changing the left/right controller if (lastController != mouseController) { mousePressed = true; } @@ -332,25 +332,39 @@ void UpdateVRInput(bool haptics, float dp_xscale, float dp_yscale) { bool pressed = IN_VRGetButtonState(mouseController) & ovrButton_Trigger; if (mousePressed != pressed) { if (pressed) { - touch.flags = TouchInputFlags::DOWN; + touch.flags = TouchInputFlags::DOWN | TouchInputFlags::MOUSE; + touch.buttons = 1; cbNativeTouch(touch); - touch.flags = TouchInputFlags::UP; + } else { + touch.flags = TouchInputFlags::UP | TouchInputFlags::MOUSE; + touch.buttons = 1; cbNativeTouch(touch); } mousePressed = pressed; + } else { + // Simulate mouse move. This allows for dragging stuff in the UI and scrolling without using the mousewheel emulation. + touch.flags = TouchInputFlags::MOVE | TouchInputFlags::MOUSE; + touch.buttons = mousePressed ? 1 : 0; + cbNativeTouch(touch); } // mouse wheel emulation - // TODO: Spams key-up events if nothing changed! + // No longer spams events when scrolling isn't happening. for (int j = 0; j < 2; j++) { keyInput.deviceId = controllerIds[j]; float scroll = -IN_VRGetJoystickState(j).y; - keyInput.flags = scroll < -0.5f ? KeyInputFlags::DOWN : KeyInputFlags::UP; - keyInput.keyCode = NKCODE_EXT_MOUSEWHEEL_UP; - cbNativeKey(keyInput); - keyInput.flags = scroll > 0.5f ? KeyInputFlags::DOWN : KeyInputFlags::UP; - keyInput.keyCode = NKCODE_EXT_MOUSEWHEEL_DOWN; - cbNativeKey(keyInput); + int wheelDelta = (int)(std::min(fabsf(scroll) * 30.0f, 500.0f)); + if (scroll < -0.5f) { + // Scroll upwards + keyInput.flags = (KeyInputFlags)((int)(KeyInputFlags::DOWN | KeyInputFlags::UP) | (wheelDelta << 16)); + keyInput.keyCode = NKCODE_EXT_MOUSEWHEEL_UP; + cbNativeKey(keyInput); + } else if (scroll > 0.5f) { + // Scroll downwards + keyInput.flags = (KeyInputFlags)((int)(KeyInputFlags::DOWN | KeyInputFlags::UP) | (wheelDelta << 16)); + keyInput.keyCode = NKCODE_EXT_MOUSEWHEEL_DOWN; + cbNativeKey(keyInput); + } } } else { VR_SetConfig(VR_CONFIG_MOUSE_SIZE, 0);