diff --git a/include/SDL_render.h b/include/SDL_render.h index a74fc129e..97ccac5c6 100644 --- a/include/SDL_render.h +++ b/include/SDL_render.h @@ -979,6 +979,48 @@ extern DECLSPEC int SDLCALL SDL_RenderSetScale(SDL_Renderer * renderer, extern DECLSPEC void SDLCALL SDL_RenderGetScale(SDL_Renderer * renderer, float *scaleX, float *scaleY); +/** + * Get logical coordinates of point in renderer when given real coordinates of point in window. + * Logical coordinates will differ from real coordinates when render is scaled and logical renderer size set + * + * \param renderer the renderer from which the logical coordinates should be calcualted + * \param windowX the real X coordinate in the window + * \param windowY the real Y coordinate in the window + * \param logicalX the pointer filled with the logical x coordinate + * \param logicalY the pointer filled with the logical y coordinate + * + * \since This function is available since SDL 2.0.20. + * + * \sa SDL_RenderGetScale + * \sa SDL_RenderSetScale + * \sa SDL_RenderGetLogicalSize + * \sa SDL_RenderSetLogicalSize + */ +extern DECLSPEC void SDLCALL SDL_RenderWindowToLogical(SDL_Renderer * renderer, + int windowX, int windowY, + float *logicalX, float *logicalY); + + /** + * Get real coordinates of point in window when given logical coordinates of point in renderer. + * Logical coordinates will differ from real coordinates when render is scaled and logical renderer size set + * + * \param renderer the renderer from which the window coordinates should be calculated + * \param logicalX the logical x coordinate + * \param logicalY the logical y coordinate + * \param windowX the pointer filled with the real X coordinate in the window + * \param windowY the pointer filled with the real Y coordinate in the window + + * + * \since This function is available since SDL 2.0.20. + * + * \sa SDL_RenderGetScale + * \sa SDL_RenderSetScale + * \sa SDL_RenderGetLogicalSize + * \sa SDL_RenderSetLogicalSize + */ +extern DECLSPEC void SDLCALL SDL_RenderLogicalToWindow(SDL_Renderer * renderer, + float logicalX, float logicalY, + int *windowX, int *windowY); /** * Set the color used for drawing operations (Rect, Line and Clear). * diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 20d9e702e..9077bb00c 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -844,3 +844,5 @@ #define SDL_hid_get_indexed_string SDL_hid_get_indexed_string_REAL #define SDL_SetWindowMouseRect SDL_SetWindowMouseRect_REAL #define SDL_GetWindowMouseRect SDL_GetWindowMouseRect_REAL +#define SDL_RenderWindowToLogical SDL_RenderWindowToLogical_REAL +#define SDL_RenderLogicalToWindow SDL_RenderLogicalToWindow_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index d2c1d13d2..93be9fbb2 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -913,3 +913,5 @@ SDL_DYNAPI_PROC(int,SDL_hid_get_serial_number_string,(SDL_hid_device *a, wchar_t SDL_DYNAPI_PROC(int,SDL_hid_get_indexed_string,(SDL_hid_device *a, int b, wchar_t *c, size_t d),(a,b,c,d),return) SDL_DYNAPI_PROC(int,SDL_SetWindowMouseRect,(SDL_Window *a, const SDL_Rect *b),(a,b),return) SDL_DYNAPI_PROC(const SDL_Rect*,SDL_GetWindowMouseRect,(SDL_Window *a),(a),return) +SDL_DYNAPI_PROC(void,SDL_RenderWindowToLogical,(SDL_Renderer *a, int b, int c, float *d, float *e),(a,b,c,d,e),) +SDL_DYNAPI_PROC(void,SDL_RenderLogicalToWindow,(SDL_Renderer *a, float b, float c, int *d, int *e),(a,b,c,d,e),) diff --git a/src/render/SDL_render.c b/src/render/SDL_render.c index 1a0add99f..5bca652fd 100644 --- a/src/render/SDL_render.c +++ b/src/render/SDL_render.c @@ -2491,6 +2491,42 @@ SDL_RenderGetScale(SDL_Renderer * renderer, float *scaleX, float *scaleY) } } +void +SDL_RenderWindowToLogical(SDL_Renderer * renderer, int windowX, int windowY, float *logicalX, float *logicalY) +{ + float window_physical_x, window_physical_y; + + CHECK_RENDERER_MAGIC(renderer, ); + + window_physical_x = ((float) windowX) / renderer->dpi_scale.x; + window_physical_y = ((float) windowY) / renderer->dpi_scale.y; + + if (logicalX) { + *logicalX = (window_physical_x - renderer->viewport.x) / renderer->scale.x; + } + if (logicalY) { + *logicalY = (window_physical_y - renderer->viewport.y) / renderer->scale.y; + } +} + +void +SDL_RenderLogicalToWindow(SDL_Renderer * renderer, float logicalX, float logicalY, int *windowX, int *windowY) +{ + float window_physical_x, window_physical_y; + + CHECK_RENDERER_MAGIC(renderer, ); + + window_physical_x = (logicalX * renderer->scale.x) + renderer->viewport.x; + window_physical_y = (logicalY * renderer->scale.y) + renderer->viewport.y; + + if (windowX) { + *windowX = (int)(window_physical_x * renderer->dpi_scale.x); + } + if (windowY) { + *windowY = (int)(window_physical_y * renderer->dpi_scale.y); + } +} + int SDL_SetRenderDrawColor(SDL_Renderer * renderer, Uint8 r, Uint8 g, Uint8 b, Uint8 a) diff --git a/src/test/SDL_test_common.c b/src/test/SDL_test_common.c index 6dcbee022..3b6effbb9 100644 --- a/src/test/SDL_test_common.c +++ b/src/test/SDL_test_common.c @@ -2234,6 +2234,7 @@ SDLTest_CommonDrawWindowInfo(SDL_Renderer * renderer, SDL_Window * window, int * SDL_Rect rect; SDL_DisplayMode mode; float ddpi, hdpi, vdpi; + float scaleX, scaleY; Uint32 flags; const int windowDisplayIndex = SDL_GetWindowDisplayIndex(window); SDL_RendererInfo info; @@ -2276,6 +2277,17 @@ SDLTest_CommonDrawWindowInfo(SDL_Renderer * renderer, SDL_Window * window, int * SDLTest_DrawString(renderer, 0, textY, text); textY += lineHeight; + SDL_RenderGetScale(renderer, &scaleX, &scaleY); + SDL_snprintf(text, sizeof(text), "SDL_RenderGetScale: %f,%f", + scaleX, scaleY); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + + SDL_RenderGetLogicalSize(renderer, &w, &h); + SDL_snprintf(text, sizeof(text), "SDL_RenderGetLogicalSize: %dx%d", w, h); + SDLTest_DrawString(renderer, 0, textY, text); + textY += lineHeight; + /* Window */ SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255); diff --git a/test/testwm2.c b/test/testwm2.c index 03530e586..86b89a95a 100644 --- a/test/testwm2.c +++ b/test/testwm2.c @@ -52,7 +52,7 @@ quit(int rc) /* Draws the modes menu, and stores the mode index under the mouse in highlighted_mode */ static void -draw_modes_menu(SDL_Window* window, SDL_Renderer* renderer, SDL_Rect viewport) +draw_modes_menu(SDL_Window *window, SDL_Renderer *renderer, SDL_Rect viewport) { SDL_DisplayMode mode; char text[1024]; @@ -68,7 +68,14 @@ draw_modes_menu(SDL_Window* window, SDL_Renderer* renderer, SDL_Rect viewport) /* Get mouse position */ if (SDL_GetMouseFocus() == window) { - SDL_GetMouseState(&mouse_pos.x, &mouse_pos.y); + int window_x, window_y; + float logical_x, logical_y; + + SDL_GetMouseState(&window_x, &window_y); + SDL_RenderWindowToLogical(renderer, window_x, window_y, &logical_x, &logical_y); + + mouse_pos.x = (int)logical_x; + mouse_pos.y = (int)logical_y; } x = 0;