diff --git a/src/sys/sdl3/sdl3_backend.cpp b/src/sys/sdl3/sdl3_backend.cpp index c9b871e46..44885842c 100644 --- a/src/sys/sdl3/sdl3_backend.cpp +++ b/src/sys/sdl3/sdl3_backend.cpp @@ -1038,7 +1038,7 @@ static bool SDL3_MapWindowMouseToRoutedCursor(float windowMouseX, float windowMo return false; } -static bool SDL3_UpdateRoutedMouseDelta(float menuMouseX, float menuMouseY, int &dx, int &dy) { +[[maybe_unused]] static bool SDL3_UpdateRoutedMouseDelta(float menuMouseX, float menuMouseY, int &dx, int &dy) { float previousX = 0.0f; float previousY = 0.0f; @@ -1106,17 +1106,24 @@ static bool SDL3_SetRoutedCursorFromWindowPosition(float windowMouseX, float win return false; } + idUserInterface *activeGui = SDL3_GetActiveMenuGui(); + if (activeGui != NULL) { + activeGui->SetCursor(cursorX, cursorY); + } if (console != NULL && console->Active()) { console->SetMousePosition(cursorX, cursorY); - } else { - idUserInterface *activeGui = SDL3_GetActiveMenuGui(); - if (activeGui != NULL) { - activeGui->SetCursor(cursorX, cursorY); - } } s_menuMouseInsideWindow = true; - return SDL3_UpdateRoutedMouseDelta(cursorX, cursorY, dx, dy); + s_menuMouseX = cursorX; + s_menuMouseY = cursorY; + s_haveMenuMousePosition = true; + s_menuMouseRemainderX = 0.0f; + s_menuMouseRemainderY = 0.0f; + s_haveAbsoluteMousePosition = false; + dx = 0; + dy = 0; + return true; } static void SDL3_SyncSystemMouseToActiveCursor(void) { @@ -1128,66 +1135,55 @@ static void SDL3_SyncSystemMouseToActiveCursor(void) { return; } - if (console != NULL && console->Active()) { - float windowMouseX = 0.0f; - float windowMouseY = 0.0f; - (void)SDL_GetMouseState(&windowMouseX, &windowMouseY); - - float cursorX = 0.0f; - float cursorY = 0.0f; - if (!SDL3_MapWindowMouseToConsoleCursor(windowMouseX, windowMouseY, cursorX, cursorY)) { - return; - } - - console->SetMousePosition(cursorX, cursorY); - s_ignoreNextMenuWarpMotion = false; - s_menuMouseInsideWindow = true; - SDL3_SetMenuMouseTrackingPosition(cursorX, cursorY); - return; - } + float windowMouseX = 0.0f; + float windowMouseY = 0.0f; + (void)SDL_GetMouseState(&windowMouseX, &windowMouseY); idUserInterface *activeGui = SDL3_GetActiveMenuGui(); if (activeGui != NULL) { #if defined(OPENQ4_SDL3_POSIX_HOST) - float windowMouseX = 0.0f; - float windowMouseY = 0.0f; - (void)SDL_GetMouseState(&windowMouseX, &windowMouseY); - float cursorX = 0.0f; float cursorY = 0.0f; - if (!SDL3_MapWindowMouseToGuiCursor(windowMouseX, windowMouseY, cursorX, cursorY)) { - return; + if (SDL3_MapWindowMouseToGuiCursor(windowMouseX, windowMouseY, cursorX, cursorY)) { + activeGui->SetCursor(cursorX, cursorY); + s_ignoreNextMenuWarpMotion = false; + s_menuMouseInsideWindow = true; + SDL3_SetMenuMouseTrackingPosition(cursorX, cursorY); } - - activeGui->SetCursor(cursorX, cursorY); - s_ignoreNextMenuWarpMotion = false; - s_menuMouseInsideWindow = true; - SDL3_SetMenuMouseTrackingPosition(cursorX, cursorY); - return; #else sdl3GuiMouseTransform_t transform; - if (!SDL3_BuildGuiMouseTransform(transform)) { - return; + if (SDL3_BuildGuiMouseTransform(transform)) { + const float cursorX = activeGui->CursorX(); + const float cursorY = activeGui->CursorY(); + const float drawX = (cursorX * transform.xScale) + transform.xOffset; + const float drawY = (cursorY * transform.yScale) + transform.yOffset; + const float pixelMouseX = transform.drawAreaX + drawX * (transform.drawAreaWidth / transform.guiWidth); + const float pixelMouseY = transform.drawAreaY + drawY * (transform.drawAreaHeight / transform.guiHeight); + const float windowMouseX = pixelMouseX * transform.pixelToWindowX; + const float windowMouseY = pixelMouseY * transform.pixelToWindowY; + + SDL_WarpMouseInWindow(s_sdlWindow, windowMouseX, windowMouseY); + s_ignoreNextMenuWarpMotion = true; + s_menuWarpWindowX = windowMouseX; + s_menuWarpWindowY = windowMouseY; + s_menuMouseInsideWindow = true; + SDL3_SetMenuMouseTrackingPosition(cursorX, cursorY); } - - const float cursorX = activeGui->CursorX(); - const float cursorY = activeGui->CursorY(); - const float drawX = (cursorX * transform.xScale) + transform.xOffset; - const float drawY = (cursorY * transform.yScale) + transform.yOffset; - const float pixelMouseX = transform.drawAreaX + drawX * (transform.drawAreaWidth / transform.guiWidth); - const float pixelMouseY = transform.drawAreaY + drawY * (transform.drawAreaHeight / transform.guiHeight); - const float windowMouseX = pixelMouseX * transform.pixelToWindowX; - const float windowMouseY = pixelMouseY * transform.pixelToWindowY; - - SDL_WarpMouseInWindow(s_sdlWindow, windowMouseX, windowMouseY); - s_ignoreNextMenuWarpMotion = true; - s_menuWarpWindowX = windowMouseX; - s_menuWarpWindowY = windowMouseY; - s_menuMouseInsideWindow = true; - SDL3_SetMenuMouseTrackingPosition(cursorX, cursorY); - return; #endif } + + if (console != NULL && console->Active()) { + float cursorX = 0.0f; + float cursorY = 0.0f; + if (SDL3_MapWindowMouseToConsoleCursor(windowMouseX, windowMouseY, cursorX, cursorY)) { + console->SetMousePosition(cursorX, cursorY); + s_ignoreNextMenuWarpMotion = false; + s_menuMouseInsideWindow = true; + if (activeGui == NULL) { + SDL3_SetMenuMouseTrackingPosition(cursorX, cursorY); + } + } + } } static int SDL3_ClampJoystickValue(int value) { @@ -4783,7 +4779,21 @@ bool Sys_SDL_PumpEvents(void) { } if (SDL3_MapWindowMouseToRoutedCursor(event.motion.x, event.motion.y, menuMouseX, menuMouseY)) { - (void)SDL3_UpdateRoutedMouseDelta(menuMouseX, menuMouseY, dx, dy); + idUserInterface *activeGui = SDL3_GetActiveMenuGui(); + if ( activeGui ) { + activeGui->SetCursor( menuMouseX, menuMouseY ); + } + if ( console != NULL && console->Active() ) { + console->SetMousePosition( menuMouseX, menuMouseY ); + } + s_menuMouseX = menuMouseX; + s_menuMouseY = menuMouseY; + s_haveMenuMousePosition = true; + s_menuMouseRemainderX = 0.0f; + s_menuMouseRemainderY = 0.0f; + s_haveAbsoluteMousePosition = false; + s_menuMouseInsideWindow = true; + Sys_QueEvent( eventTime, SE_MOUSE, 0, 0, 0, NULL ); } else { SDL3_ResetMenuMouseTracking(); } diff --git a/src/ui/DeviceContext.cpp b/src/ui/DeviceContext.cpp index 7d9fb2342..aad4be60a 100644 --- a/src/ui/DeviceContext.cpp +++ b/src/ui/DeviceContext.cpp @@ -33,6 +33,8 @@ If you have questions concerning this license or the applicable additional terms #include "UserInterface.h" #include "../framework/KeyInput.h" +extern idCVar ui_aspectCorrection; + idVec4 idDeviceContext::colorPurple; idVec4 idDeviceContext::colorOrange; idVec4 idDeviceContext::colorYellow; @@ -2525,11 +2527,33 @@ void idDeviceContext::CalcVirtualScaleOffset( float width, float height, float & outYOffset = transform.yOffset; } -void idDeviceContext::GetVirtualScreenExpansion( float width, float height, float &xExpand, float &yExpand ) const { +bool idDeviceContext::GetVirtualScreenExpansion( float width, float height, float &xExpand, float &yExpand, bool forceAspectCorrect ) const { + xExpand = 0.0f; + yExpand = 0.0f; + + const bool effectiveAspectCorrect = ( forceAspectCorrect || aspectCorrect ) && ui_aspectCorrection.GetBool(); + if ( !effectiveAspectCorrect ) { + return false; + } + float windowWidth = 0.0f; float windowHeight = 0.0f; openQ4_GetCurrentViewportSize( windowWidth, windowHeight ); - openQ4_CalcVirtualScreenExpansion( width, height, windowWidth, windowHeight, aspectCorrect, xExpand, yExpand ); + openQ4_CalcVirtualScreenExpansion( width, height, windowWidth, windowHeight, effectiveAspectCorrect, xExpand, yExpand ); + return true; +} + +bool idDeviceContext::GetVirtualScreenExpansion( float *xExpand, float *yExpand, bool forceAspectCorrect ) const { + float localX = 0.0f; + float localY = 0.0f; + const bool active = GetVirtualScreenExpansion( static_cast( VIRTUAL_WIDTH ), static_cast( VIRTUAL_HEIGHT ), localX, localY, forceAspectCorrect ); + if ( xExpand != NULL ) { + *xExpand = localX; + } + if ( yExpand != NULL ) { + *yExpand = localY; + } + return active; } void idDeviceContext::GetCinematic16x9Bars( float width, float height, idRectangle &topBar, idRectangle &bottomBar, idRectangle &leftBar, idRectangle &rightBar, idRectangle &visibleArea ) const { diff --git a/src/ui/DeviceContext.h b/src/ui/DeviceContext.h index 280b2460a..7a5cb4642 100644 --- a/src/ui/DeviceContext.h +++ b/src/ui/DeviceContext.h @@ -82,7 +82,8 @@ class idDeviceContext { void SetSize(float width, float height); void SetAspectCorrection( bool enabled ); float GetCanvasAspect() const; - void GetVirtualScreenExpansion( float width, float height, float &xExpand, float &yExpand ) const; + bool GetVirtualScreenExpansion( float width, float height, float &xExpand, float &yExpand, bool forceAspectCorrect = false ) const; + bool GetVirtualScreenExpansion( float *xExpand, float *yExpand, bool forceAspectCorrect = false ) const; void GetCinematic16x9Bars( float width, float height, idRectangle &topBar, idRectangle &bottomBar, idRectangle &leftBar, idRectangle &rightBar, idRectangle &visibleArea ) const; const idMaterial *GetScrollBarImage(int index); diff --git a/src/ui/UserInterface.cpp b/src/ui/UserInterface.cpp index a7e459377..117ace7e3 100644 --- a/src/ui/UserInterface.cpp +++ b/src/ui/UserInterface.cpp @@ -465,8 +465,12 @@ const char *idUserInterfaceLocal::HandleEvent( const sysEvent_t *event, int _tim } if ( event->evType == SE_MOUSE ) { - SetCursor( cursorX + static_cast( event->evValue ), - cursorY + static_cast( event->evValue2 ) ); + if ( event->evValue != 0 || event->evValue2 != 0 ) { + SetCursor( cursorX + static_cast( event->evValue ), + cursorY + static_cast( event->evValue2 ) ); + } else { + ClampCursor(); + } } if ( desktop ) { @@ -1056,7 +1060,7 @@ void idUserInterfaceLocal::ClampCursor( void ) { if ( ( desktop->GetFlags() & WIN_MENUGUI ) && ui_aspectCorrection.GetBool() ) { float xExpand = 0.0f; float yExpand = 0.0f; - uiManagerLocal.dc.GetVirtualScreenExpansion( maxX, maxY, xExpand, yExpand ); + uiManagerLocal.dc.GetVirtualScreenExpansion( &xExpand, &yExpand, ui_aspectCorrection.GetBool() ); if ( std::isfinite( xExpand ) && xExpand >= 0.0f ) { minX -= xExpand; maxX += xExpand;