mirror of
https://github.com/yawut/SDL.git
synced 2026-09-08 17:16:19 -05:00
Added SDL_RenderSetLogicalSize() and SDL_RenderGetLogicalSize()
This commit is contained in:
@@ -70,6 +70,8 @@ static const SDL_RenderDriver *render_drivers[] = {
|
||||
static char renderer_magic;
|
||||
static char texture_magic;
|
||||
|
||||
static int UpdateLogicalSize(SDL_Renderer *renderer);
|
||||
|
||||
int
|
||||
SDL_GetNumRenderDrivers(void)
|
||||
{
|
||||
@@ -101,21 +103,27 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
|
||||
}
|
||||
|
||||
if (event->window.event == SDL_WINDOWEVENT_RESIZED) {
|
||||
/* Try to keep the previous viewport centered */
|
||||
int w, h;
|
||||
|
||||
SDL_GetWindowSize(window, &w, &h);
|
||||
if (renderer->target) {
|
||||
renderer->viewport_backup.x = (w - renderer->viewport_backup.w) / 2;
|
||||
renderer->viewport_backup.y = (h - renderer->viewport_backup.h) / 2;
|
||||
if (renderer->logical_w) {
|
||||
/* We'll update the renderer in the SIZE_CHANGED event */
|
||||
} else {
|
||||
renderer->viewport.x = (w - renderer->viewport.w) / 2;
|
||||
renderer->viewport.y = (h - renderer->viewport.h) / 2;
|
||||
renderer->UpdateViewport(renderer);
|
||||
/* Try to keep the previous viewport centered */
|
||||
int w, h;
|
||||
|
||||
SDL_GetWindowSize(window, &w, &h);
|
||||
if (renderer->target) {
|
||||
renderer->viewport_backup.x = (w - renderer->viewport_backup.w) / 2;
|
||||
renderer->viewport_backup.y = (h - renderer->viewport_backup.h) / 2;
|
||||
} else {
|
||||
renderer->viewport.x = (w - renderer->viewport.w) / 2;
|
||||
renderer->viewport.y = (h - renderer->viewport.h) / 2;
|
||||
renderer->UpdateViewport(renderer);
|
||||
}
|
||||
}
|
||||
renderer->resized = SDL_TRUE;
|
||||
} else if (event->window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||
if (!renderer->resized) {
|
||||
if (renderer->logical_w) {
|
||||
UpdateLogicalSize(renderer);
|
||||
} else if (!renderer->resized) {
|
||||
/* Window was programmatically resized, reset viewport */
|
||||
int w, h;
|
||||
|
||||
@@ -148,6 +156,21 @@ SDL_RendererEventWatch(void *userdata, SDL_Event *event)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (event->type == SDL_MOUSEMOTION) {
|
||||
if (renderer->logical_w) {
|
||||
event->motion.x -= renderer->viewport.x;
|
||||
event->motion.y -= renderer->viewport.y;
|
||||
event->motion.x = (int)(event->motion.x / renderer->scale.x);
|
||||
event->motion.y = (int)(event->motion.y / renderer->scale.y);
|
||||
}
|
||||
} else if (event->type == SDL_MOUSEBUTTONDOWN ||
|
||||
event->type == SDL_MOUSEBUTTONUP) {
|
||||
if (renderer->logical_w) {
|
||||
event->button.x -= renderer->viewport.x;
|
||||
event->button.y -= renderer->viewport.y;
|
||||
event->button.x = (int)(event->button.x / renderer->scale.x);
|
||||
event->button.y = (int)(event->button.y / renderer->scale.y);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -245,6 +268,8 @@ SDL_CreateRenderer(SDL_Window * window, int index, Uint32 flags)
|
||||
renderer->window = window;
|
||||
renderer->scale.x = 1.0f;
|
||||
renderer->scale.y = 1.0f;
|
||||
renderer->logical_w = 0;
|
||||
renderer->logical_h = 0;
|
||||
|
||||
if (SDL_GetWindowFlags(window) & (SDL_WINDOW_HIDDEN|SDL_WINDOW_MINIMIZED)) {
|
||||
renderer->hidden = SDL_TRUE;
|
||||
@@ -921,6 +946,88 @@ SDL_SetRenderTarget(SDL_Renderer *renderer, SDL_Texture *texture)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
UpdateLogicalSize(SDL_Renderer *renderer)
|
||||
{
|
||||
int w, h;
|
||||
float want_aspect;
|
||||
float real_aspect;
|
||||
float scale;
|
||||
SDL_Rect viewport;
|
||||
|
||||
if (renderer->window) {
|
||||
SDL_GetWindowSize(renderer->window, &w, &h);
|
||||
} else {
|
||||
/* FIXME */
|
||||
SDL_SetError("Internal error: No way to get output resolution");
|
||||
return -1;
|
||||
}
|
||||
|
||||
want_aspect = (float)renderer->logical_w / renderer->logical_h;
|
||||
real_aspect = (float)w / h;
|
||||
|
||||
/* Clear the scale because we're setting viewport in output coordinates */
|
||||
SDL_RenderSetScale(renderer, 1.0f, 1.0f);
|
||||
|
||||
if (SDL_fabs(want_aspect-real_aspect) < 0.0001) {
|
||||
/* The aspect ratios are the same, just scale appropriately */
|
||||
scale = (float)w / renderer->logical_w;
|
||||
SDL_RenderSetViewport(renderer, NULL);
|
||||
} else if (want_aspect > real_aspect) {
|
||||
/* We want a wider aspect ratio than is available - letterbox it */
|
||||
scale = (float)w / renderer->logical_w;
|
||||
viewport.x = 0;
|
||||
viewport.w = w;
|
||||
viewport.h = (int)SDL_ceil(renderer->logical_h * scale);
|
||||
viewport.y = (h - viewport.h) / 2;
|
||||
SDL_RenderSetViewport(renderer, &viewport);
|
||||
} else {
|
||||
/* We want a narrower aspect ratio than is available - use side-bars */
|
||||
scale = (float)h / renderer->logical_h;
|
||||
viewport.y = 0;
|
||||
viewport.h = h;
|
||||
viewport.w = (int)SDL_ceil(renderer->logical_w * scale);
|
||||
viewport.x = (w - viewport.w) / 2;
|
||||
SDL_RenderSetViewport(renderer, &viewport);
|
||||
}
|
||||
|
||||
/* Set the new scale */
|
||||
SDL_RenderSetScale(renderer, scale, scale);
|
||||
}
|
||||
|
||||
int
|
||||
SDL_RenderSetLogicalSize(SDL_Renderer * renderer, int w, int h)
|
||||
{
|
||||
CHECK_RENDERER_MAGIC(renderer, -1);
|
||||
|
||||
if (!w || !h) {
|
||||
/* Clear any previous logical resolution */
|
||||
renderer->logical_w = 0;
|
||||
renderer->logical_h = 0;
|
||||
SDL_RenderSetViewport(renderer, NULL);
|
||||
SDL_RenderSetScale(renderer, 1.0f, 1.0f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
renderer->logical_w = w;
|
||||
renderer->logical_h = h;
|
||||
|
||||
return UpdateLogicalSize(renderer);
|
||||
}
|
||||
|
||||
void
|
||||
SDL_RenderGetLogicalSize(SDL_Renderer * renderer, int *w, int *h)
|
||||
{
|
||||
CHECK_RENDERER_MAGIC(renderer, );
|
||||
|
||||
if (w) {
|
||||
*w = renderer->logical_w;
|
||||
}
|
||||
if (h) {
|
||||
*h = renderer->logical_h;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
SDL_RenderSetViewport(SDL_Renderer * renderer, const SDL_Rect * rect)
|
||||
{
|
||||
|
||||
@@ -123,6 +123,10 @@ struct SDL_Renderer
|
||||
SDL_bool hidden;
|
||||
SDL_bool resized;
|
||||
|
||||
/* The logical resolution for rendering */
|
||||
int logical_w;
|
||||
int logical_h;
|
||||
|
||||
/* The drawable area within the window */
|
||||
SDL_Rect viewport;
|
||||
SDL_Rect viewport_backup;
|
||||
|
||||
Reference in New Issue
Block a user