https://github.com/libsdl-org/Maelstrom/commit/0c2d978df971500b6e004ed733dc6bf17f6e825d
From 0c2d978df971500b6e004ed733dc6bf17f6e825d Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Thu, 21 Jun 2012 10:26:55 -0400
Subject: [PATCH] Render to texture to adapt to any physical screen resolution.
---
screenlib/SDL_FrameBuf.cpp | 72 +++++++++++++++++++------------
screenlib/SDL_FrameBuf.h | 86 ++++++--------------------------------
2 files changed, 58 insertions(+), 100 deletions(-)
diff --git a/screenlib/SDL_FrameBuf.cpp b/screenlib/SDL_FrameBuf.cpp
index 3f519b28..ab47ff58 100644
--- a/screenlib/SDL_FrameBuf.cpp
+++ b/screenlib/SDL_FrameBuf.cpp
@@ -37,6 +37,7 @@ FrameBuf:: FrameBuf() : ErrorBase()
/* Initialize various variables to null state */
window = NULL;
renderer = NULL;
+ texture = NULL;
faded = 0;
}
@@ -46,11 +47,6 @@ FrameBuf:: Init(int width, int height, Uint32 window_flags, Uint32 render_flags,
{
int w, h;
-#ifdef HACK_RESOLUTION
- SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
-#endif
- AdjustCoordinates(width, height);
-
#ifdef FAST_ITERATION
window_flags &= ~SDL_WINDOW_FULLSCREEN;
#endif
@@ -67,24 +63,35 @@ FrameBuf:: Init(int width, int height, Uint32 window_flags, Uint32 render_flags,
return(-1);
}
+ texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_TARGET, width, height);
+ if (!texture) {
+ SetError("Couldn't create target texture: %s", SDL_GetError());
+ return(-1);
+ }
+
+ if (SDL_SetRenderTarget(renderer, texture) < 0) {
+ SetError("Couldn't set render target: %s", SDL_GetError());
+ return(-1);
+ }
+
+ SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
+
/* Set the icon, if any */
if ( icon ) {
SDL_SetWindowIcon(window, icon);
}
- /* Set the UI area */
+ /* Set the output area */
SDL_GetWindowSize(window, &w, &h);
- rect.x = (w - width) / 2;
- rect.y = (h - height) / 2;
- rect.w = width;
- rect.h = height;
- SDL_RenderSetViewport(renderer, &rect);
-
- /* Set the blit clipping rectangle */
- clip.x = 0;
- clip.y = 0;
- clip.w = AdjustCoordinateX(width, true);
- clip.h = AdjustCoordinateY(height, true);
+ output.w = w;
+ output.h = (height * w)/width;
+ output.x = (w - output.w) / 2;
+ output.y = (h - output.h) / 2;
+
+ clip.x = rect.x = 0;
+ clip.y = rect.y = 0;
+ clip.w = rect.w = width;
+ clip.h = rect.h = height;
/* Copy the image colormap */
if ( colors ) {
@@ -96,6 +103,9 @@ FrameBuf:: Init(int width, int height, Uint32 window_flags, Uint32 render_flags,
FrameBuf:: ~FrameBuf()
{
+ if (texture) {
+ SDL_DestroyTexture(texture);
+ }
if (renderer) {
SDL_DestroyRenderer(renderer);
}
@@ -118,16 +128,15 @@ FrameBuf:: SetPalette(SDL_Color *colors)
bool
FrameBuf::ConvertTouchCoordinates(const SDL_TouchFingerEvent &finger, int *x, int *y)
{
- int w, h;
SDL_Touch* inTouch = SDL_GetTouch(finger.touchId);
if (inTouch == NULL) {
return false;
}
- SDL_GetWindowSize(window, &w, &h);
- *x = (int)((((float)finger.x)/inTouch->xres)*w) - rect.x;
- *y = (int)((((float)finger.y)/inTouch->yres)*h) - rect.y;
- AdjustCoordinates(*x, *y, true);
+ *x = (int)((((float)finger.x)/inTouch->xres)*output.w) - output.x;
+ *y = (int)((((float)finger.y)/inTouch->yres)*output.h) - output.y;
+ *x = (*x * rect.w) / output.w;
+ *y = (*y * rect.h) / output.h;
return true;
}
@@ -184,11 +193,22 @@ FrameBuf:: QueueBlit(int dstx, int dsty, SDL_Texture *src,
srcrect.w = dstrect.w;
srcrect.h = dstrect.h;
}
- AdjustCoordinates(dstrect.x, dstrect.y);
- AdjustCoordinates(dstrect.w, dstrect.h);
SDL_RenderCopy(renderer, src, &srcrect, &dstrect);
}
+void
+FrameBuf:: Update(void)
+{
+ /* Copy from our render texture to the screen and show it! */
+ SDL_SetRenderTarget(renderer, NULL);
+ SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
+ SDL_RenderClear(renderer);
+ SDL_RenderCopy(renderer, texture, NULL, &output);
+ SDL_RenderPresent(renderer);
+
+ SDL_SetRenderTarget(renderer, texture);
+}
+
void
FrameBuf:: Fade(void)
{
@@ -208,7 +228,7 @@ FrameBuf:: Fade(void)
}
faded = !faded;
- if ( faded ) {
+ if ( faded ) {
for ( int i = 0; i < 256; i++ ) {
ramp[i] = 0;
}
@@ -245,8 +265,6 @@ FrameBuf:: ScreenDump(const char *prefix, int x, int y, int w, int h)
if (!h) {
h = Height();
}
- AdjustCoordinates(x, y);
- AdjustCoordinates(w, h);
rect.x = x;
rect.y = y;
rect.w = w;
diff --git a/screenlib/SDL_FrameBuf.h b/screenlib/SDL_FrameBuf.h
index 508c3824..6fc827b5 100644
--- a/screenlib/SDL_FrameBuf.h
+++ b/screenlib/SDL_FrameBuf.h
@@ -31,25 +31,6 @@
// Define this if you're rapidly iterating on UI screens
//#define FAST_ITERATION
-// Define these if you want to try out the quick resolution hacks
-//#define HACK_1024x768
-//#define HACK_400x300
-
-#ifdef HACK_1024x768
-#define HACK_RESOLUTION
-#define HACK_RESOLUTION_X 1024
-#define HACK_RESOLUTION_Y 768
-#endif
-#ifdef HACK_400x300
-#define HACK_RESOLUTION
-#define HACK_RESOLUTION_X 400
-#define HACK_RESOLUTION_Y 300
-#endif
-#ifdef HACK_RESOLUTION
-#define ORIG_RESOLUTION_X 640
-#define ORIG_RESOLUTION_Y 480
-#endif
-
#include <stdio.h>
#include "SDL.h"
@@ -68,31 +49,6 @@ class FrameBuf : public ErrorBase {
SDL_Color *colors = NULL, SDL_Surface *icon = NULL);
virtual ~FrameBuf();
- int AdjustCoordinateX(int &x, bool invert = false) const {
-#ifdef HACK_RESOLUTION
- if (invert) {
- x = (x*ORIG_RESOLUTION_X)/HACK_RESOLUTION_X;
- } else {
- x = (x*HACK_RESOLUTION_X)/ORIG_RESOLUTION_X;
- }
-#endif
- return x;
- }
- int AdjustCoordinateY(int &y, bool invert = false) const {
-#ifdef HACK_RESOLUTION
- if (invert) {
- y = (y*ORIG_RESOLUTION_Y)/HACK_RESOLUTION_Y;
- } else {
- y = (y*HACK_RESOLUTION_Y)/ORIG_RESOLUTION_Y;
- }
-#endif
- return y;
- }
- void AdjustCoordinates(int &x, int &y, bool invert = false) const {
- AdjustCoordinateX(x, invert);
- AdjustCoordinateY(y, invert);
- }
-
/* Setup routines */
/* Set the image palette -- 256 entries */
void SetPalette(SDL_Color *colors);
@@ -128,17 +84,17 @@ class FrameBuf : public ErrorBase {
void ProcessEvent(SDL_Event *event) {
switch (event->type) {
case SDL_MOUSEMOTION:
- event->motion.x -= rect.x;
- event->motion.y -= rect.y;
- AdjustCoordinates(event->motion.x,
- event->motion.y, true);
+ event->motion.x -= output.x;
+ event->motion.y -= output.y;
+ event->motion.x = (event->motion.x * rect.w) / output.w;
+ event->motion.y = (event->motion.y * rect.h) / output.h;
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
- event->button.x -= rect.x;
- event->button.y -= rect.y;
- AdjustCoordinates(event->button.x,
- event->button.y, true);
+ event->button.x -= output.x;
+ event->button.y -= output.y;
+ event->motion.x = (event->motion.x * rect.w) / output.w;
+ event->motion.y = (event->motion.y * rect.h) / output.h;
break;
}
}
@@ -157,12 +113,10 @@ class FrameBuf : public ErrorBase {
/* Information routines */
int Width() const {
- int w = rect.w;
- return AdjustCoordinateX(w, true);
+ return rect.w;
}
int Height() const {
- int h = rect.h;
- return AdjustCoordinateY(h, true);
+ return rect.h;
}
/* Blit and update routines */
@@ -173,9 +127,7 @@ class FrameBuf : public ErrorBase {
SDL_QueryTexture(src, NULL, NULL, &w, &h);
QueueBlit(x, y, src, 0, 0, w, h, do_clip);
}
- void Update() {
- SDL_RenderPresent(renderer);
- }
+ void Update(void);
void FadeOut(void) {
if (!faded) {
Fade();
@@ -190,9 +142,6 @@ class FrameBuf : public ErrorBase {
/* Drawing routines */
void Clear(int x, int y, int w, int h) {
- AdjustCoordinates(x, y);
- AdjustCoordinates(w, h);
-
FillRect(x, y, w, h, 0);
}
void Clear(void) {
@@ -200,24 +149,16 @@ class FrameBuf : public ErrorBase {
SDL_RenderClear(renderer);
}
void DrawPoint(int x, int y, Uint32 color) {
- AdjustCoordinates(x, y);
-
UpdateDrawColor(color);
SDL_RenderDrawPoint(renderer, x, y);
}
void DrawLine(int x1, int y1, int x2, int y2, Uint32 color) {
- AdjustCoordinates(x1, y1);
- AdjustCoordinates(x2, y2);
-
UpdateDrawColor(color);
SDL_RenderDrawLine(renderer, x1, y1, x2, y2);
}
void DrawRect(int x1, int y1, int w, int h, Uint32 color) {
UpdateDrawColor(color);
- AdjustCoordinates(x1, y1);
- AdjustCoordinates(w, h);
-
SDL_Rect rect;
rect.x = x1;
rect.y = y1;
@@ -228,9 +169,6 @@ class FrameBuf : public ErrorBase {
void FillRect(int x1, int y1, int w, int h, Uint32 color) {
UpdateDrawColor(color);
- AdjustCoordinates(x1, y1);
- AdjustCoordinates(w, h);
-
SDL_Rect rect;
rect.x = x1;
rect.y = y1;
@@ -273,10 +211,12 @@ class FrameBuf : public ErrorBase {
/* The current display */
SDL_Window *window;
SDL_Renderer *renderer;
+ SDL_Texture *texture;
Uint32 image_map[256];
int faded;
SDL_Rect rect;
SDL_Rect clip;
+ SDL_Rect output;
void UpdateDrawColor(Uint32 color) {
Uint8 r, g, b;