Skip to content
This repository has been archived by the owner on Feb 11, 2021. It is now read-only.

Commit

Permalink
Center the old SDL 1.2 screen in the window if we can't get the size …
Browse files Browse the repository at this point in the history
…we wanted.
  • Loading branch information
slouken committed Feb 14, 2011
1 parent 3f5776a commit 3c6de0d
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 51 deletions.
116 changes: 93 additions & 23 deletions src/SDL_compat.c
Expand Up @@ -32,11 +32,13 @@


static SDL_Window *SDL_VideoWindow = NULL;
static SDL_Surface *SDL_WindowSurface = NULL;
static SDL_Surface *SDL_VideoSurface = NULL;
static SDL_Surface *SDL_ShadowSurface = NULL;
static SDL_Surface *SDL_PublicSurface = NULL;
static SDL_GLContext *SDL_VideoContext = NULL;
static Uint32 SDL_VideoFlags = 0;
static SDL_Rect SDL_VideoViewport;
static char *wm_title = NULL;
static SDL_Surface *SDL_VideoIcon;
static int SDL_enabled_UNICODE = 0;
Expand Down Expand Up @@ -211,10 +213,15 @@ SDL_CompatEventFilter(void *userdata, SDL_Event * event)
break;
case SDL_WINDOWEVENT_RESIZED:
SDL_FlushEvent(SDL_VIDEORESIZE);
fake.type = SDL_VIDEORESIZE;
fake.resize.w = event->window.data1;
fake.resize.h = event->window.data2;
SDL_PushEvent(&fake);
/* We don't want to expose that the window width and height will
be different if we don't get the desired fullscreen mode.
*/
if (SDL_VideoWindow && !(SDL_GetWindowFlags(SDL_VideoWindow) & SDL_WINDOW_FULLSCREEN)) {
fake.type = SDL_VIDEORESIZE;
fake.resize.w = event->window.data1;
fake.resize.h = event->window.data2;
SDL_PushEvent(&fake);
}
break;
case SDL_WINDOWEVENT_MINIMIZED:
fake.type = SDL_ACTIVEEVENT;
Expand Down Expand Up @@ -282,6 +289,19 @@ SDL_CompatEventFilter(void *userdata, SDL_Event * event)
//printf("TEXTINPUT: '%s'\n", event->text.text);
break;
}
case SDL_MOUSEMOTION:
{
event->motion.x -= SDL_VideoViewport.x;
event->motion.y -= SDL_VideoViewport.y;
break;
}
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
{
event->button.x -= SDL_VideoViewport.x;
event->button.y -= SDL_VideoViewport.y;
break;
}
case SDL_MOUSEWHEEL:
{
Uint8 button;
Expand Down Expand Up @@ -321,6 +341,7 @@ SDL_CompatEventFilter(void *userdata, SDL_Event * event)
static void
GetEnvironmentWindowPosition(int w, int h, int *x, int *y)
{
int display = GetVideoDisplay();
const char *window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
const char *center = SDL_getenv("SDL_VIDEO_CENTERED");
if (window) {
Expand All @@ -332,22 +353,20 @@ GetEnvironmentWindowPosition(int w, int h, int *x, int *y)
}
}
if (center) {
SDL_DisplayMode mode;
SDL_GetDesktopDisplayMode(GetVideoDisplay(), &mode);
*x = (mode.w - w) / 2;
*y = (mode.h - h) / 2;
*x = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
*y = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
}
}

static void
ClearVideoSurface()
{
Uint32 black;

/* Clear the surface for display */
black = SDL_MapRGB(SDL_PublicSurface->format, 0, 0, 0);
SDL_FillRect(SDL_PublicSurface, NULL, black);
SDL_UpdateRect(SDL_PublicSurface, 0, 0, 0, 0);
if (SDL_ShadowSurface) {
SDL_FillRect(SDL_ShadowSurface, NULL,
SDL_MapRGB(SDL_ShadowSurface->format, 0, 0, 0));
}
SDL_FillRect(SDL_WindowSurface, NULL, 0);
SDL_UpdateWindowSurface(SDL_VideoWindow);
}

static void
Expand Down Expand Up @@ -408,11 +427,18 @@ SDL_ResizeVideoMode(int width, int height, int bpp, Uint32 flags)
return 0;
}

/* Destroy the screen texture and recreate it */
SDL_VideoSurface = SDL_GetWindowSurface(SDL_VideoWindow);
if (!SDL_VideoSurface) {
SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow);
if (!SDL_WindowSurface) {
return -1;
}
if (SDL_VideoSurface->format != SDL_WindowSurface->format) {
return -1;
}
SDL_VideoSurface->w = width;
SDL_VideoSurface->h = height;
SDL_VideoSurface->pixels = SDL_WindowSurface->pixels;
SDL_VideoSurface->pitch = SDL_WindowSurface->pitch;
SDL_SetClipRect(SDL_VideoSurface, NULL);

if (SDL_ShadowSurface) {
SDL_ShadowSurface->w = width;
Expand All @@ -436,8 +462,11 @@ SDL_Surface *
SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
{
SDL_DisplayMode desktop_mode;
int window_x = SDL_WINDOWPOS_UNDEFINED;
int window_y = SDL_WINDOWPOS_UNDEFINED;
int display = GetVideoDisplay();
int window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display);
int window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display);
int window_w;
int window_h;
Uint32 window_flags;
Uint32 surface_flags;

Expand All @@ -447,7 +476,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
}
}

SDL_GetDesktopDisplayMode(GetVideoDisplay(), &desktop_mode);
SDL_GetDesktopDisplayMode(display, &desktop_mode);

if (width == 0) {
width = desktop_mode.w;
Expand All @@ -472,6 +501,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
SDL_ShadowSurface = NULL;
}
if (SDL_VideoSurface) {
SDL_VideoSurface->flags &= ~SDL_DONTFREE;
SDL_FreeSurface(SDL_VideoSurface);
SDL_VideoSurface = NULL;
}
Expand Down Expand Up @@ -548,11 +578,31 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
}

/* Create the screen surface */
SDL_VideoSurface = SDL_GetWindowSurface(SDL_VideoWindow);
if (!SDL_VideoSurface) {
SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow);
if (!SDL_WindowSurface) {
return NULL;
}

/* Center the public surface in the window surface */
SDL_GetWindowSize(SDL_VideoWindow, &window_w, &window_h);
SDL_VideoViewport.x = (window_w - width)/2;
SDL_VideoViewport.y = (window_h - height)/2;
SDL_VideoViewport.w = width;
SDL_VideoViewport.h = height;

SDL_VideoSurface = SDL_CreateRGBSurfaceFrom(NULL, 0, 0, 32, 0, 0, 0, 0, 0);
SDL_VideoSurface->flags |= surface_flags;
SDL_VideoSurface->flags |= SDL_DONTFREE;
SDL_FreeFormat(SDL_VideoSurface->format);
SDL_VideoSurface->format = SDL_WindowSurface->format;
SDL_VideoSurface->format->refcount++;
SDL_VideoSurface->w = width;
SDL_VideoSurface->h = height;
SDL_VideoSurface->pitch = SDL_WindowSurface->pitch;
SDL_VideoSurface->pixels = (void *)((Uint8 *)SDL_WindowSurface->pixels +
SDL_VideoViewport.y * SDL_VideoSurface->pitch +
SDL_VideoViewport.x * SDL_VideoSurface->format->BytesPerPixel);
SDL_SetClipRect(SDL_VideoSurface, NULL);

/* Create a shadow surface if necessary */
if ((bpp != SDL_VideoSurface->format->BitsPerPixel)
Expand All @@ -571,6 +621,8 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
SDL_DitherColors(SDL_ShadowSurface->format->palette->colors,
SDL_ShadowSurface->format->BitsPerPixel);
}
SDL_FillRect(SDL_ShadowSurface, NULL,
SDL_MapRGB(SDL_ShadowSurface->format, 0, 0, 0));
}
SDL_PublicSurface =
(SDL_ShadowSurface ? SDL_ShadowSurface : SDL_VideoSurface);
Expand Down Expand Up @@ -719,7 +771,25 @@ SDL_UpdateRects(SDL_Surface * screen, int numrects, SDL_Rect * rects)
screen = SDL_VideoSurface;
}
if (screen == SDL_VideoSurface) {
SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, numrects, rects);
if (SDL_VideoViewport.x || SDL_VideoViewport.y) {
SDL_Rect *stackrects = SDL_stack_alloc(SDL_Rect, numrects);
SDL_Rect *stackrect;
const SDL_Rect *rect;

/* Offset all the rectangles before updating */
for (i = 0; i < numrects; ++i) {
rect = &rects[i];
stackrect = &stackrects[i];
stackrect->x = SDL_VideoViewport.x + rect->x;
stackrect->y = SDL_VideoViewport.y + rect->y;
stackrect->w = rect->w;
stackrect->h = rect->h;
}
SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, numrects, stackrects);
SDL_stack_free(stackrects);
} else {
SDL_UpdateWindowSurfaceRects(SDL_VideoWindow, numrects, rects);
}
}
}

Expand Down
39 changes: 39 additions & 0 deletions src/video/SDL_rect.c
Expand Up @@ -23,6 +23,7 @@

#include "SDL_rect.h"


SDL_bool
SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B)
{
Expand Down Expand Up @@ -339,4 +340,42 @@ SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2,
return SDL_TRUE;
}

SDL_bool
SDL_GetSpanEnclosingRect(int width, int height,
int numrects, SDL_Rect * rects, SDL_Rect *span)
{
int i;
int span_y1, span_y2;
int rect_y1, rect_y2;

/* Initialize to empty rect */
span_y1 = height;
span_y2 = 0;

for (i = 0; i < numrects; ++i) {
rect_y1 = rects[i].y;
rect_y2 = rect_y1 + rects[i].h;

/* Clip out of bounds rectangles, and expand span rect */
if (rect_y1 < 0) {
span_y1 = 0;
} else if (rect_y1 < span_y1) {
span_y1 = rect_y1;
}
if (rect_y2 > height) {
span_y2 = height;
} else if (rect_y2 > span_y2) {
span_y2 = rect_y2;
}
}
if (span_y2 > span_y1) {
span->x = 0;
span->y = span_y1;
span->w = width;
span->h = (span_y2 - span_y1);
return SDL_TRUE;
}
return SDL_FALSE;
}

/* vi: set ts=4 sw=4 expandtab: */
26 changes: 26 additions & 0 deletions src/video/SDL_rect_c.h
@@ -0,0 +1,26 @@
/*
SDL - Simple DirectMedia Layer
Copyright (C) 1997-2011 Sam Lantinga
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Sam Lantinga
slouken@libsdl.org
*/
#include "SDL_config.h"

extern SDL_bool SDL_GetSpanEnclosingRect(int width, int height, int numrects, SDL_Rect * rects, SDL_Rect *span);

/* vi: set ts=4 sw=4 expandtab: */
40 changes: 12 additions & 28 deletions src/video/SDL_video.c
Expand Up @@ -28,6 +28,7 @@
#include "SDL_sysvideo.h"
#include "SDL_blit.h"
#include "SDL_pixels_c.h"
#include "SDL_rect_c.h"
#include "../events/SDL_events_c.h"

#if SDL_VIDEO_OPENGL
Expand Down Expand Up @@ -306,47 +307,30 @@ static int
SDL_UpdateWindowTexture(_THIS, SDL_Window * window, int numrects, SDL_Rect * rects)
{
SDL_WindowTextureData *data;
#ifdef UPDATE_TEXTURE_SUBRECTS
void *src, *dst;
int src_pitch;
int dst_pitch;
int i, row, length;
#endif
SDL_Rect rect;
void *src;

data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA);
if (!data || !data->texture) {
SDL_SetError("No window texture data");
return -1;
}

#ifdef UPDATE_TEXTURE_SUBRECTS
src_pitch = data->pitch;
for (i = 0; i < numrects; ++i) {
/* Update a single rect that contains subrects for best DMA performance */
if (SDL_GetSpanEnclosingRect(window->w, window->h, numrects, rects, &rect)) {
src = (void *)((Uint8 *)data->pixels +
rects[i].y * src_pitch +
rects[i].x * data->bytes_per_pixel);
if (SDL_LockTexture(data->texture, &rects[i], &dst, &dst_pitch) < 0) {
rect.y * data->pitch +
rect.x * data->bytes_per_pixel);
if (SDL_UpdateTexture(data->texture, &rect, src, data->pitch) < 0) {
return -1;
}
length = rects[i].w * data->bytes_per_pixel;
for (row = rects[i].h; row--; ) {
SDL_memcpy(dst, src, length);
src = (Uint8*)src + src_pitch;
dst = (Uint8*)dst + dst_pitch;

if (SDL_RenderCopy(data->renderer, data->texture, NULL, NULL) < 0) {
return -1;
}
SDL_UnlockTexture(data->texture);
}
#else
if (SDL_UpdateTexture(data->texture, NULL, data->pixels, data->pitch) < 0) {
return -1;
}
#endif

if (SDL_RenderCopy(data->renderer, data->texture, NULL, NULL) < 0) {
return -1;
SDL_RenderPresent(data->renderer);
}

SDL_RenderPresent(data->renderer);
return 0;
}

Expand Down

0 comments on commit 3c6de0d

Please sign in to comment.