Major rewrite of SwapBuffers routines.

This rewrite abstracts out all screen compositing code into sdl_common.c 
and treats pure and OpenGL modes as backends.  This should make fixing 
compositor bugs easier in the future, as well as providing alternate 
rendering forms for weaker cards if necessary.



git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@2653 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
mcmartin
2007-01-11 00:45:48 +00:00
parent 7a3037e48c
commit 43eb06dd28
7 changed files with 390 additions and 290 deletions
+4
View File
@@ -1,4 +1,8 @@
Changes towards version 0.7: Changes towards version 0.7:
- Major rewrite of the SwapBuffers commands -- screen compositing logic
has all been abstracted out into sdl_common.c instead of being
nearly-duplicated in opengl.c and pure.c - Michael
- --- 0.6.1 maintenance release occurred at this point ---
- The Unicode Private Use Area is no longer considered printable. This - The Unicode Private Use Area is no longer considered printable. This
is a stopgap to handle unusual behavior with text entry under OS X. is a stopgap to handle unusual behavior with text entry under OS X.
See bug #942 for more details - Michael See bug #942 for more details - Michael
+207 -160
View File
@@ -23,15 +23,19 @@
#include "scalers.h" #include "scalers.h"
#include "libs/log.h" #include "libs/log.h"
static SDL_Surface *scaled_display = NULL; typedef struct _gl_screeninfo {
static SDL_Surface *scaled_transition = NULL; SDL_Surface *scaled;
GLuint texture;
BOOLEAN dirty, active;
SDL_Rect updated;
} TFB_GL_SCREENINFO;
static TFB_GL_SCREENINFO GL_Screens[TFB_GFX_NUMSCREENS];
static int ScreenFilterMode; static int ScreenFilterMode;
static GLuint DisplayTexture;
static GLuint TransitionTexture;
static BOOLEAN upload_transitiontexture = FALSE;
static TFB_ScaleFunc scaler = NULL; static TFB_ScaleFunc scaler = NULL;
static BOOLEAN first_init = TRUE;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN #if SDL_BYTEORDER == SDL_BIG_ENDIAN
#define R_MASK 0xff000000 #define R_MASK 0xff000000
@@ -45,6 +49,24 @@ static TFB_ScaleFunc scaler = NULL;
#define A_MASK 0xff000000 #define A_MASK 0xff000000
#endif #endif
static void TFB_GL_Preprocess (int force_full_redraw, int transition_amount, int fade_amount);
static void TFB_GL_Postprocess (void);
static void TFB_GL_Scaled_ScreenLayer (SCREEN screen, Uint8 a, SDL_Rect *rect);
static void TFB_GL_Unscaled_ScreenLayer (SCREEN screen, Uint8 a, SDL_Rect *rect);
static void TFB_GL_ColorLayer (Uint8 r, Uint8 g, Uint8 b, Uint8 a, SDL_Rect *rect);
static TFB_GRAPHICS_BACKEND opengl_scaled_backend = {
TFB_GL_Preprocess,
TFB_GL_Postprocess,
TFB_GL_Scaled_ScreenLayer,
TFB_GL_ColorLayer };
static TFB_GRAPHICS_BACKEND opengl_unscaled_backend = {
TFB_GL_Preprocess,
TFB_GL_Postprocess,
TFB_GL_Unscaled_ScreenLayer,
TFB_GL_ColorLayer };
static SDL_Surface * static SDL_Surface *
Create_Screen (SDL_Surface *template, int w, int h) Create_Screen (SDL_Surface *template, int w, int h)
@@ -173,20 +195,34 @@ TFB_GL_ConfigureVideo (int driver, int flags, int width, int height)
SDL_Screen = SDL_Screens[0]; SDL_Screen = SDL_Screens[0];
TransitionScreen = SDL_Screens[2]; TransitionScreen = SDL_Screens[2];
if (first_init)
{
for (i = 0; i < TFB_GFX_NUMSCREENS; i++)
{
GL_Screens[i].scaled = NULL;
GL_Screens[i].dirty = TRUE;
GL_Screens[i].active = TRUE;
}
GL_Screens[1].active = FALSE;
first_init = FALSE;
}
if (GfxFlags & TFB_GFXFLAGS_SCALE_SOFT_ONLY) if (GfxFlags & TFB_GFXFLAGS_SCALE_SOFT_ONLY)
{ {
if (0 != ReInit_Screen (&scaled_display, format_conv_surf, for (i = 0; i < TFB_GFX_NUMSCREENS; i++)
ScreenWidth * 2, ScreenHeight * 2)) {
return -1; if (!GL_Screens[i].active)
continue;
if (0 != ReInit_Screen (&scaled_transition, format_conv_surf, if (0 != ReInit_Screen (&GL_Screens[i].scaled, format_conv_surf,
ScreenWidth * 2, ScreenHeight * 2)) ScreenWidth * 2, ScreenHeight * 2))
return -1; return -1;
}
texture_width = 1024; texture_width = 1024;
texture_height = 512; texture_height = 512;
scaler = Scale_PrepPlatform (flags, SDL_Screen->format); scaler = Scale_PrepPlatform (flags, SDL_Screen->format);
graphics_backend = &opengl_scaled_backend;
} }
else else
{ {
@@ -194,6 +230,7 @@ TFB_GL_ConfigureVideo (int driver, int flags, int width, int height)
texture_height = 256; texture_height = 256;
scaler = NULL; scaler = NULL;
graphics_backend = &opengl_unscaled_backend;
} }
if (GfxFlags & TFB_GFXFLAGS_SCALE_ANY) if (GfxFlags & TFB_GFXFLAGS_SCALE_ANY)
@@ -209,21 +246,18 @@ TFB_GL_ConfigureVideo (int driver, int flags, int width, int height)
glDisable (GL_DITHER); glDisable (GL_DITHER);
glDepthMask(GL_FALSE); glDepthMask(GL_FALSE);
glGenTextures (1, &DisplayTexture); for (i = 0; i < TFB_GFX_NUMSCREENS; i++)
glBindTexture (GL_TEXTURE_2D, DisplayTexture); {
glPixelStorei (GL_UNPACK_ALIGNMENT, 1); if (!GL_Screens[i].active)
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); continue;
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glGenTextures (1, &GL_Screens[i].texture);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, texture_width, texture_height, glBindTexture (GL_TEXTURE_2D, GL_Screens[i].texture);
0, GL_RGBA, GL_UNSIGNED_BYTE, 0); glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glGenTextures (1, &TransitionTexture); glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glBindTexture (GL_TEXTURE_2D, TransitionTexture); glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, texture_width, texture_height,
glPixelStorei (GL_UNPACK_ALIGNMENT, 1); 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); }
glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, texture_width, texture_height,
0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
return 0; return 0;
} }
@@ -258,7 +292,11 @@ TFB_GL_InitGraphics (int driver, int flags, int width, int height)
void TFB_GL_UploadTransitionScreen (void) void TFB_GL_UploadTransitionScreen (void)
{ {
upload_transitiontexture = TRUE; GL_Screens[TFB_SCREEN_TRANSITION].updated.x = 0;
GL_Screens[TFB_SCREEN_TRANSITION].updated.y = 0;
GL_Screens[TFB_SCREEN_TRANSITION].updated.w = ScreenWidth;
GL_Screens[TFB_SCREEN_TRANSITION].updated.h = ScreenHeight;
GL_Screens[TFB_SCREEN_TRANSITION].dirty = TRUE;
} }
void void
@@ -289,9 +327,22 @@ TFB_GL_ScanLines (void)
} }
} }
void static void
TFB_GL_DrawQuad (void) TFB_GL_DrawQuad (SDL_Rect *r)
{ {
if (r != NULL)
{
float scale_x = (ScreenWidthActual / (float)ScreenWidth);
float scale_y = (ScreenHeightActual / (float)ScreenHeight);
glScissor (
(GLint) (r->x * scale_x),
(GLint) ((ScreenHeight - (r->y + r->h)) * scale_y),
(GLsizei) (r->w * scale_x),
(GLsizei) (r->h * scale_y)
);
glEnable (GL_SCISSOR_TEST);
}
glBegin (GL_TRIANGLE_FAN); glBegin (GL_TRIANGLE_FAN);
glTexCoord2f (0, 0); glTexCoord2f (0, 0);
glVertex2i (0, 0); glVertex2i (0, 0);
@@ -302,157 +353,153 @@ TFB_GL_DrawQuad (void)
glTexCoord2f (0, ScreenHeight / 256.0f); glTexCoord2f (0, ScreenHeight / 256.0f);
glVertex2i (0, ScreenHeightActual); glVertex2i (0, ScreenHeightActual);
glEnd (); glEnd ();
if (r != NULL)
{
glDisable (GL_SCISSOR_TEST);
}
} }
void static void
TFB_GL_SwapBuffers (int force_full_redraw) TFB_GL_Preprocess (int force_full_redraw, int transition_amount, int fade_amount)
{ {
int fade_amount = FadeAmount;
int transition_amount = TransitionAmount;
if (!force_full_redraw && !TFB_BBox.valid &&
fade_amount == 255 && transition_amount == 255)
return;
glMatrixMode (GL_PROJECTION); glMatrixMode (GL_PROJECTION);
glLoadIdentity (); glLoadIdentity ();
glOrtho (0,ScreenWidthActual,ScreenHeightActual, 0, -1, 1); glOrtho (0,ScreenWidthActual,ScreenHeightActual, 0, -1, 1);
glMatrixMode (GL_MODELVIEW); glMatrixMode (GL_MODELVIEW);
glLoadIdentity (); glLoadIdentity ();
glBindTexture (GL_TEXTURE_2D, DisplayTexture); (void) force_full_redraw;
(void) transition_amount;
(void) fade_amount;
if (TFB_BBox.valid)
{
GL_Screens[TFB_SCREEN_MAIN].updated.x = TFB_BBox.region.corner.x;
GL_Screens[TFB_SCREEN_MAIN].updated.y = TFB_BBox.region.corner.y;
GL_Screens[TFB_SCREEN_MAIN].updated.w = TFB_BBox.region.extent.width;
GL_Screens[TFB_SCREEN_MAIN].updated.h = TFB_BBox.region.extent.height;
GL_Screens[TFB_SCREEN_MAIN].dirty = TRUE;
}
}
static void
TFB_GL_Unscaled_ScreenLayer (SCREEN screen, Uint8 a, SDL_Rect *rect)
{
glBindTexture (GL_TEXTURE_2D, GL_Screens[screen].texture);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
if (GL_Screens[screen].dirty)
{
glPixelStorei (GL_UNPACK_ROW_LENGTH, ScreenWidth);
/* Matrox OpenGL drivers do not handle GL_UNPACK_SKIP_*
correctly */
glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
SDL_LockSurface (SDL_Screens[screen]);
glTexSubImage2D (GL_TEXTURE_2D, 0, GL_Screens[screen].updated.x,
GL_Screens[screen].updated.y,
GL_Screens[screen].updated.w,
GL_Screens[screen].updated.h,
GL_RGBA, GL_UNSIGNED_BYTE,
(Uint32 *)SDL_Screens[screen]->pixels +
(GL_Screens[screen].updated.y * ScreenWidth +
GL_Screens[screen].updated.x));
SDL_UnlockSurface (SDL_Screens[screen]);
GL_Screens[screen].dirty = FALSE;
}
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ScreenFilterMode); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ScreenFilterMode);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ScreenFilterMode); glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ScreenFilterMode);
glEnable (GL_TEXTURE_2D); glEnable (GL_TEXTURE_2D);
glDisable (GL_BLEND);
glColor4f (1, 1, 1, 1);
if (TFB_BBox.valid) if (a == 255)
{ {
SDL_Rect updated; glDisable (GL_BLEND);
glColor4f (1, 1, 1, 1);
updated.x = TFB_BBox.region.corner.x;
updated.y = TFB_BBox.region.corner.y;
updated.w = TFB_BBox.region.extent.width;
updated.h = TFB_BBox.region.extent.height;
if (scaler)
{
scaler (SDL_Screen, scaled_display, &updated);
glPixelStorei (GL_UNPACK_ROW_LENGTH, ScreenWidth * 2);
/* Matrox OpenGL drivers do not handle GL_UNPACK_SKIP_*
correctly */
glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
SDL_LockSurface (scaled_display);
glTexSubImage2D (GL_TEXTURE_2D, 0, updated.x * 2, updated.y * 2,
updated.w * 2, updated.h * 2, GL_RGBA, GL_UNSIGNED_BYTE,
(Uint32*)scaled_display->pixels +
(updated.y * 4 * ScreenWidth + updated.x * 2));
SDL_UnlockSurface (scaled_display);
}
else
{
glPixelStorei (GL_UNPACK_ROW_LENGTH, ScreenWidth);
/* Matrox OpenGL drivers do not handle GL_UNPACK_SKIP_*
correctly */
glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
SDL_LockSurface (SDL_Screen);
glTexSubImage2D (GL_TEXTURE_2D, 0, updated.x, updated.y,
updated.w, updated.h, GL_RGBA, GL_UNSIGNED_BYTE,
(Uint32*)SDL_Screen->pixels +
(updated.y * ScreenWidth + updated.x));
SDL_UnlockSurface (SDL_Screen);
}
} }
else
TFB_GL_DrawQuad ();
if (transition_amount != 255)
{ {
float scale_x = (ScreenWidthActual / (float)ScreenWidth); float a_f = a / 255.0f;
float scale_y = (ScreenHeightActual / (float)ScreenHeight);
glBindTexture(GL_TEXTURE_2D, TransitionTexture);
if (upload_transitiontexture)
{
if (scaler)
{
SDL_Rect r;
r.x = r.y = 0;
r.w = ScreenWidth;
r.h = ScreenHeight;
scaler (TransitionScreen, scaled_transition, &r);
glPixelStorei (GL_UNPACK_ROW_LENGTH, ScreenWidth * 2);
glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
SDL_LockSurface (scaled_transition);
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, ScreenWidth * 2,
ScreenHeight * 2, GL_RGBA, GL_UNSIGNED_BYTE,
scaled_transition->pixels);
SDL_UnlockSurface (scaled_transition);
}
else
{
glPixelStorei (GL_UNPACK_ROW_LENGTH, ScreenWidth);
glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
SDL_LockSurface (TransitionScreen);
glTexSubImage2D (GL_TEXTURE_2D, 0, 0, 0, ScreenWidth,
ScreenHeight, GL_RGBA, GL_UNSIGNED_BYTE,
TransitionScreen->pixels);
SDL_UnlockSurface (TransitionScreen);
}
upload_transitiontexture = FALSE;
}
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
ScreenFilterMode);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
ScreenFilterMode);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glColor4f (1, 1, 1, (255 - transition_amount) / 255.0f);
glScissor (
(GLint) (TransitionClipRect.x * scale_x),
(GLint) ((ScreenHeight - (TransitionClipRect.y +
TransitionClipRect.h)) * scale_y),
(GLsizei) (TransitionClipRect.w * scale_x),
(GLsizei) (TransitionClipRect.h * scale_y)
);
glEnable (GL_SCISSOR_TEST);
TFB_GL_DrawQuad ();
glDisable (GL_SCISSOR_TEST);
}
if (fade_amount != 255)
{
float c;
if (fade_amount < 255)
{
c = (255 - fade_amount) / 255.0f;
glColor4f (0, 0, 0, c);
}
else
{
c = (fade_amount - 255) / 255.0f;
glColor4f (1, 1, 1, c);
}
glDisable (GL_TEXTURE_2D);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable (GL_BLEND); glEnable (GL_BLEND);
glColor4f (1, 1, 1, a_f);
TFB_GL_DrawQuad ();
} }
TFB_GL_DrawQuad (rect);
}
static void
TFB_GL_Scaled_ScreenLayer (SCREEN screen, Uint8 a, SDL_Rect *rect)
{
glBindTexture (GL_TEXTURE_2D, GL_Screens[screen].texture);
glTexEnvf (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
if (GL_Screens[screen].dirty)
{
scaler (SDL_Screens[screen], GL_Screens[screen].scaled, &GL_Screens[screen].updated);
glPixelStorei (GL_UNPACK_ROW_LENGTH, ScreenWidth * 2);
/* Matrox OpenGL drivers do not handle GL_UNPACK_SKIP_*
correctly */
glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
SDL_LockSurface (GL_Screens[screen].scaled);
glTexSubImage2D (GL_TEXTURE_2D, 0, GL_Screens[screen].updated.x * 2,
GL_Screens[screen].updated.y * 2,
GL_Screens[screen].updated.w * 2,
GL_Screens[screen].updated.h * 2,
GL_RGBA, GL_UNSIGNED_BYTE,
(Uint32 *)GL_Screens[screen].scaled->pixels +
(GL_Screens[screen].updated.y * 4 * ScreenWidth +
GL_Screens[screen].updated.x * 2));
SDL_UnlockSurface (GL_Screens[screen].scaled);
GL_Screens[screen].dirty = FALSE;
}
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, ScreenFilterMode);
glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, ScreenFilterMode);
glEnable (GL_TEXTURE_2D);
if (a == 255)
{
glDisable (GL_BLEND);
glColor4f (1, 1, 1, 1);
}
else
{
float a_f = a / 255.0f;
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable (GL_BLEND);
glColor4f (1, 1, 1, a_f);
}
TFB_GL_DrawQuad (rect);
}
static void
TFB_GL_ColorLayer (Uint8 r, Uint8 g, Uint8 b, Uint8 a, SDL_Rect *rect)
{
float r_f = r / 255.0f;
float g_f = g / 255.0f;
float b_f = b / 255.0f;
float a_f = a / 255.0f;
glColor4f(r_f, g_f, b_f, a_f);
glDisable (GL_TEXTURE_2D);
if (a != 255)
{
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable (GL_BLEND);
}
else
{
glDisable (GL_BLEND);
}
TFB_GL_DrawQuad (rect);
}
static void
TFB_GL_Postprocess (void)
{
if (GfxFlags & TFB_GFXFLAGS_SCANLINES) if (GfxFlags & TFB_GFXFLAGS_SCANLINES)
TFB_GL_ScanLines (); TFB_GL_ScanLines ();
@@ -24,8 +24,6 @@
int TFB_GL_InitGraphics (int driver, int flags, int width, int height); int TFB_GL_InitGraphics (int driver, int flags, int width, int height);
int TFB_GL_ConfigureVideo (int driver, int flags, int width, int height); int TFB_GL_ConfigureVideo (int driver, int flags, int width, int height);
void TFB_GL_UploadTransitionScreen (void); void TFB_GL_UploadTransitionScreen (void);
void TFB_GL_SwapBuffers (int force_full_redraw);
#ifdef HAVE_OPENGL #ifdef HAVE_OPENGL
#ifdef WIN32 #ifdef WIN32
+115 -116
View File
@@ -22,13 +22,33 @@
#include "scalers.h" #include "scalers.h"
#include "libs/log.h" #include "libs/log.h"
static SDL_Surface *fade_black = NULL; static SDL_Surface *fade_color_surface = NULL;
static SDL_Surface *fade_white = NULL;
static SDL_Surface *fade_temp = NULL; static SDL_Surface *fade_temp = NULL;
static SDL_Surface *scaled_display = NULL; static SDL_Surface *scaled_display = NULL;
static TFB_ScaleFunc scaler = NULL; static TFB_ScaleFunc scaler = NULL;
static Uint32 fade_color;
static void TFB_Pure_Scaled_Preprocess (int force_full_redraw, int transition_amount, int fade_amount);
static void TFB_Pure_Scaled_Postprocess (void);
static void TFB_Pure_Unscaled_Preprocess (int force_full_redraw, int transition_amount, int fade_amount);
static void TFB_Pure_Unscaled_Postprocess (void);
static void TFB_Pure_ScreenLayer (SCREEN screen, Uint8 a, SDL_Rect *rect);
static void TFB_Pure_ColorLayer (Uint8 r, Uint8 g, Uint8 b, Uint8 a, SDL_Rect *rect);
static TFB_GRAPHICS_BACKEND pure_scaled_backend = {
TFB_Pure_Scaled_Preprocess,
TFB_Pure_Scaled_Postprocess,
TFB_Pure_ScreenLayer,
TFB_Pure_ColorLayer };
static TFB_GRAPHICS_BACKEND pure_unscaled_backend = {
TFB_Pure_Unscaled_Preprocess,
TFB_Pure_Unscaled_Postprocess,
TFB_Pure_ScreenLayer,
TFB_Pure_ColorLayer };
static SDL_Surface * static SDL_Surface *
Create_Screen (SDL_Surface *template, int w, int h) Create_Screen (SDL_Surface *template, int w, int h)
{ {
@@ -68,12 +88,14 @@ TFB_Pure_ConfigureVideo (int driver, int flags, int width, int height)
videomode_flags = SDL_SWSURFACE; videomode_flags = SDL_SWSURFACE;
ScreenWidthActual = 320; ScreenWidthActual = 320;
ScreenHeightActual = 240; ScreenHeightActual = 240;
graphics_backend = &pure_unscaled_backend;
} }
else else
{ {
videomode_flags = SDL_SWSURFACE; videomode_flags = SDL_SWSURFACE;
ScreenWidthActual = 640; ScreenWidthActual = 640;
ScreenHeightActual = 480; ScreenHeightActual = 480;
graphics_backend = &pure_scaled_backend;
if (width != 640 || height != 480) if (width != 640 || height != 480)
log_add (log_Error, "Screen resolution of %dx%d not supported " log_add (log_Error, "Screen resolution of %dx%d not supported "
@@ -142,17 +164,11 @@ TFB_Pure_ConfigureVideo (int driver, int flags, int width, int height)
SDL_Screen = SDL_Screens[0]; SDL_Screen = SDL_Screens[0];
TransitionScreen = SDL_Screens[2]; TransitionScreen = SDL_Screens[2];
if (0 != ReInit_Screen (&fade_white, format_conv_surf, if (0 != ReInit_Screen (&fade_color_surface, format_conv_surf,
ScreenWidth, ScreenHeight)) ScreenWidth, ScreenHeight))
return -1; return -1;
SDL_FillRect (fade_white, NULL, fade_color = SDL_MapRGB (fade_color_surface->format, 0, 0, 0);
SDL_MapRGB (fade_white->format, 255, 255, 255)); SDL_FillRect (fade_color_surface, NULL, fade_color);
if (0 != ReInit_Screen (&fade_black, format_conv_surf,
ScreenWidth, ScreenHeight))
return -1;
SDL_FillRect (fade_black, NULL,
SDL_MapRGB (fade_black->format, 0, 0, 0));
if (0 != ReInit_Screen (&fade_temp, format_conv_surf, if (0 != ReInit_Screen (&fade_temp, format_conv_surf,
ScreenWidth, ScreenHeight)) ScreenWidth, ScreenHeight))
@@ -233,17 +249,13 @@ ScanLines (SDL_Surface *dst, SDL_Rect *r)
} }
} }
void static SDL_Surface *backbuffer = NULL, *scalebuffer = NULL;
TFB_Pure_SwapBuffers (int force_full_redraw) static SDL_Rect updated;
{
static int last_fade_amount = 255, last_transition_amount = 255;
int fade_amount = FadeAmount;
int transition_amount = TransitionAmount;
SDL_Rect updated;
if (force_full_redraw || static void
fade_amount != 255 || transition_amount != 255 || TFB_Pure_Scaled_Preprocess (int force_full_redraw, int transition_amount, int fade_amount)
last_fade_amount != 255 || last_transition_amount != 255) {
if (force_full_redraw)
{ {
updated.x = updated.y = 0; updated.x = updated.y = 0;
updated.w = ScreenWidth; updated.w = ScreenWidth;
@@ -251,113 +263,100 @@ TFB_Pure_SwapBuffers (int force_full_redraw)
} }
else else
{ {
if (!TFB_BBox.valid)
return;
updated.x = TFB_BBox.region.corner.x; updated.x = TFB_BBox.region.corner.x;
updated.y = TFB_BBox.region.corner.y; updated.y = TFB_BBox.region.corner.y;
updated.w = TFB_BBox.region.extent.width; updated.w = TFB_BBox.region.extent.width;
updated.h = TFB_BBox.region.extent.height; updated.h = TFB_BBox.region.extent.height;
} }
last_fade_amount = fade_amount; if (transition_amount == 255 && fade_amount == 255)
last_transition_amount = transition_amount; backbuffer = SDL_Screens[TFB_SCREEN_MAIN];
else
backbuffer = fade_temp;
if (ScreenWidthActual == ScreenWidth * 2 && // we can scale directly onto SDL_Video if video is compatible
ScreenHeightActual == ScreenHeight * 2) if (SDL_Video->format->BitsPerPixel ==
SDL_Screen->format->BitsPerPixel)
scalebuffer = SDL_Video;
else
scalebuffer = scaled_display;
}
static void
TFB_Pure_Unscaled_Preprocess (int force_full_redraw, int transition_amount, int fade_amount)
{
if (force_full_redraw)
{ {
// scales 320x240 backbuffer to 640x480 updated.x = updated.y = 0;
updated.w = ScreenWidth;
SDL_Surface *backbuffer = SDL_Screen; updated.h = ScreenHeight;
SDL_Surface *scalebuffer = scaled_display;
// we can scale directly onto SDL_Video if video is compatible
if (SDL_Video->format->BitsPerPixel ==
SDL_Screen->format->BitsPerPixel)
scalebuffer = SDL_Video;
if (transition_amount != 255)
{
backbuffer = fade_temp;
SDL_BlitSurface (SDL_Screen, NULL, backbuffer, NULL);
SDL_SetAlpha (TransitionScreen, SDL_SRCALPHA,
255 - transition_amount);
SDL_BlitSurface (TransitionScreen, &TransitionClipRect,
backbuffer, &TransitionClipRect);
}
if (fade_amount != 255)
{
if (transition_amount == 255)
{
backbuffer = fade_temp;
SDL_BlitSurface (SDL_Screen, NULL, backbuffer, NULL);
}
if (fade_amount < 255)
{
SDL_SetAlpha (fade_black, SDL_SRCALPHA, 255 - fade_amount);
SDL_BlitSurface (fade_black, NULL, backbuffer, NULL);
}
else
{
SDL_SetAlpha (fade_white, SDL_SRCALPHA, fade_amount - 255);
SDL_BlitSurface (fade_white, NULL, backbuffer, NULL);
}
}
SDL_LockSurface (scalebuffer);
SDL_LockSurface (backbuffer);
if (scaler)
scaler (backbuffer, scalebuffer, &updated);
if (GfxFlags & TFB_GFXFLAGS_SCANLINES)
ScanLines (scalebuffer, &updated);
SDL_UnlockSurface (backbuffer);
SDL_UnlockSurface (scalebuffer);
updated.x *= 2;
updated.y *= 2;
updated.w *= 2;
updated.h *= 2;
if (scalebuffer != SDL_Video)
SDL_BlitSurface (scalebuffer, &updated, SDL_Video, &updated);
SDL_UpdateRects (SDL_Video, 1, &updated);
} }
else else
{ {
// resolution is 320x240 so we can blit directly updated.x = TFB_BBox.region.corner.x;
updated.y = TFB_BBox.region.corner.y;
SDL_BlitSurface (SDL_Screen, &updated, SDL_Video, &updated); updated.w = TFB_BBox.region.extent.width;
updated.h = TFB_BBox.region.extent.height;
if (transition_amount != 255)
{
SDL_SetAlpha (TransitionScreen, SDL_SRCALPHA,
255 - transition_amount);
SDL_BlitSurface (TransitionScreen, &TransitionClipRect,
SDL_Video, &TransitionClipRect);
}
if (fade_amount != 255)
{
if (fade_amount < 255)
{
SDL_SetAlpha (fade_black, SDL_SRCALPHA, 255 - fade_amount);
SDL_BlitSurface (fade_black, NULL, SDL_Video, NULL);
}
else
{
SDL_SetAlpha (fade_white, SDL_SRCALPHA, fade_amount - 255);
SDL_BlitSurface (fade_white, NULL, SDL_Video, NULL);
}
}
SDL_UpdateRect (SDL_Video, updated.x, updated.y,
updated.w, updated.h);
} }
backbuffer = SDL_Video;
(void)transition_amount;
(void)fade_amount;
}
static void
TFB_Pure_Scaled_Postprocess (void)
{
SDL_LockSurface (scalebuffer);
SDL_LockSurface (backbuffer);
if (scaler)
scaler (backbuffer, scalebuffer, &updated);
if (GfxFlags & TFB_GFXFLAGS_SCANLINES)
ScanLines (scalebuffer, &updated);
SDL_UnlockSurface (backbuffer);
SDL_UnlockSurface (scalebuffer);
updated.x *= 2;
updated.y *= 2;
updated.w *= 2;
updated.h *= 2;
if (scalebuffer != SDL_Video)
SDL_BlitSurface (scalebuffer, &updated, SDL_Video, &updated);
SDL_UpdateRects (SDL_Video, 1, &updated);
}
static void
TFB_Pure_Unscaled_Postprocess (void)
{
SDL_UpdateRect (SDL_Video, updated.x, updated.y,
updated.w, updated.h);
}
static void
TFB_Pure_ScreenLayer (SCREEN screen, Uint8 a, SDL_Rect *rect)
{
if (SDL_Screens[screen] == backbuffer)
return;
SDL_SetAlpha (SDL_Screens[screen], SDL_SRCALPHA, a);
SDL_BlitSurface (SDL_Screens[screen], rect, backbuffer, rect);
}
static void
TFB_Pure_ColorLayer (Uint8 r, Uint8 g, Uint8 b, Uint8 a, SDL_Rect *rect)
{
Uint32 col = SDL_MapRGB (fade_color_surface->format, r, g, b);
if (col != fade_color)
{
fade_color = col;
SDL_FillRect (fade_color_surface, NULL, fade_color);
}
SDL_SetAlpha (fade_color_surface, SDL_SRCALPHA, a);
SDL_BlitSurface (fade_color_surface, rect, backbuffer, rect);
} }
void void
-1
View File
@@ -23,6 +23,5 @@
int TFB_Pure_InitGraphics (int driver, int flags, int width, int height); int TFB_Pure_InitGraphics (int driver, int flags, int width, int height);
int TFB_Pure_ConfigureVideo (int driver, int flags, int width, int height); int TFB_Pure_ConfigureVideo (int driver, int flags, int width, int height);
void TFB_Pure_SwapBuffers (int force_full_redraw);
#endif #endif
+52 -9
View File
@@ -52,6 +52,8 @@ int GfxFlags = 0;
static TFB_Palette palette[256]; static TFB_Palette palette[256];
TFB_GRAPHICS_BACKEND *graphics_backend = NULL;
#define FPS_PERIOD 100 #define FPS_PERIOD 100
int RenderedFrames = 0; int RenderedFrames = 0;
@@ -116,9 +118,15 @@ TFB_ReInitGraphics (int driver, int flags, int width, int height)
int int
TFB_InitGraphics (int driver, int flags, int width, int height) TFB_InitGraphics (int driver, int flags, int width, int height)
{ {
int result; int result, i;
char caption[200]; char caption[200];
/* Null out screen pointers the first time */
for (i = 0; i < TFB_GFX_NUMSCREENS; i++)
{
SDL_Screens[i] = NULL;
}
GfxFlags = flags; GfxFlags = flags;
if (driver == TFB_GFXDRIVER_SDL_OPENGL) if (driver == TFB_GFXDRIVER_SDL_OPENGL)
@@ -209,14 +217,49 @@ TFB_ProcessEvents ()
void void
TFB_SwapBuffers (int force_full_redraw) TFB_SwapBuffers (int force_full_redraw)
{ {
#ifdef HAVE_OPENGL static int last_fade_amount = 255, last_transition_amount = 255;
if (GraphicsDriver == TFB_GFXDRIVER_SDL_OPENGL) static int fade_amount = 255, transition_amount = 255;
TFB_GL_SwapBuffers (force_full_redraw);
else fade_amount = FadeAmount;
TFB_Pure_SwapBuffers (force_full_redraw); transition_amount = TransitionAmount;
#else
TFB_Pure_SwapBuffers (force_full_redraw); if (!force_full_redraw && !TFB_BBox.valid &&
#endif fade_amount == 255 && transition_amount == 255 &&
last_fade_amount == 255 && last_transition_amount == 255)
return;
if (fade_amount != 255 || transition_amount != 255 ||
last_fade_amount != 255 || last_transition_amount != 255)
{
force_full_redraw = 1;
}
last_fade_amount = fade_amount;
last_transition_amount = transition_amount;
graphics_backend->preprocess (force_full_redraw, transition_amount, fade_amount);
graphics_backend->screen (TFB_SCREEN_MAIN, 255, NULL);
if (transition_amount != 255)
{
graphics_backend->screen (TFB_SCREEN_TRANSITION,
255 - transition_amount, &TransitionClipRect);
}
if (fade_amount != 255)
{
if (fade_amount < 255)
{
graphics_backend->color (0, 0, 0, 255 - fade_amount, NULL);
}
else
{
graphics_backend->color (255, 255, 255,
fade_amount - 255, NULL);
}
}
graphics_backend->postprocess ();
} }
/* Probably ought to clean this away at some point. */ /* Probably ought to clean this away at some point. */
@@ -31,6 +31,16 @@
#include "libs/input/sdl/input.h" #include "libs/input/sdl/input.h"
#include "libs/threadlib.h" #include "libs/threadlib.h"
// The Graphics Backend vtable
typedef struct _tfb_graphics_backend {
void (*preprocess) (int force_redraw, int transition_amount, int fade_amount);
void (*postprocess) (void);
void (*screen) (SCREEN screen, Uint8 alpha, SDL_Rect *rect);
void (*color) (Uint8 r, Uint8 g, Uint8 b, Uint8 a, SDL_Rect *rect);
} TFB_GRAPHICS_BACKEND;
extern TFB_GRAPHICS_BACKEND *graphics_backend;
// constants for TFB_InitGraphics // constants for TFB_InitGraphics
extern SDL_Surface *SDL_Video; extern SDL_Surface *SDL_Video;