Commit 72cdb910 authored by Sam Lantinga's avatar Sam Lantinga

Center the old SDL 1.2 screen in the window if we can't get the size we wanted.

parent 98f09208
...@@ -32,11 +32,13 @@ ...@@ -32,11 +32,13 @@
static SDL_Window *SDL_VideoWindow = NULL; static SDL_Window *SDL_VideoWindow = NULL;
static SDL_Surface *SDL_WindowSurface = NULL;
static SDL_Surface *SDL_VideoSurface = NULL; static SDL_Surface *SDL_VideoSurface = NULL;
static SDL_Surface *SDL_ShadowSurface = NULL; static SDL_Surface *SDL_ShadowSurface = NULL;
static SDL_Surface *SDL_PublicSurface = NULL; static SDL_Surface *SDL_PublicSurface = NULL;
static SDL_GLContext *SDL_VideoContext = NULL; static SDL_GLContext *SDL_VideoContext = NULL;
static Uint32 SDL_VideoFlags = 0; static Uint32 SDL_VideoFlags = 0;
static SDL_Rect SDL_VideoViewport;
static char *wm_title = NULL; static char *wm_title = NULL;
static SDL_Surface *SDL_VideoIcon; static SDL_Surface *SDL_VideoIcon;
static int SDL_enabled_UNICODE = 0; static int SDL_enabled_UNICODE = 0;
...@@ -211,10 +213,15 @@ SDL_CompatEventFilter(void *userdata, SDL_Event * event) ...@@ -211,10 +213,15 @@ SDL_CompatEventFilter(void *userdata, SDL_Event * event)
break; break;
case SDL_WINDOWEVENT_RESIZED: case SDL_WINDOWEVENT_RESIZED:
SDL_FlushEvent(SDL_VIDEORESIZE); SDL_FlushEvent(SDL_VIDEORESIZE);
fake.type = SDL_VIDEORESIZE; /* We don't want to expose that the window width and height will
fake.resize.w = event->window.data1; be different if we don't get the desired fullscreen mode.
fake.resize.h = event->window.data2; */
SDL_PushEvent(&fake); 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; break;
case SDL_WINDOWEVENT_MINIMIZED: case SDL_WINDOWEVENT_MINIMIZED:
fake.type = SDL_ACTIVEEVENT; fake.type = SDL_ACTIVEEVENT;
...@@ -282,6 +289,19 @@ SDL_CompatEventFilter(void *userdata, SDL_Event * event) ...@@ -282,6 +289,19 @@ SDL_CompatEventFilter(void *userdata, SDL_Event * event)
//printf("TEXTINPUT: '%s'\n", event->text.text); //printf("TEXTINPUT: '%s'\n", event->text.text);
break; 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: case SDL_MOUSEWHEEL:
{ {
Uint8 button; Uint8 button;
...@@ -321,6 +341,7 @@ SDL_CompatEventFilter(void *userdata, SDL_Event * event) ...@@ -321,6 +341,7 @@ SDL_CompatEventFilter(void *userdata, SDL_Event * event)
static void static void
GetEnvironmentWindowPosition(int w, int h, int *x, int *y) GetEnvironmentWindowPosition(int w, int h, int *x, int *y)
{ {
int display = GetVideoDisplay();
const char *window = SDL_getenv("SDL_VIDEO_WINDOW_POS"); const char *window = SDL_getenv("SDL_VIDEO_WINDOW_POS");
const char *center = SDL_getenv("SDL_VIDEO_CENTERED"); const char *center = SDL_getenv("SDL_VIDEO_CENTERED");
if (window) { if (window) {
...@@ -332,22 +353,20 @@ GetEnvironmentWindowPosition(int w, int h, int *x, int *y) ...@@ -332,22 +353,20 @@ GetEnvironmentWindowPosition(int w, int h, int *x, int *y)
} }
} }
if (center) { if (center) {
SDL_DisplayMode mode; *x = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
SDL_GetDesktopDisplayMode(GetVideoDisplay(), &mode); *y = SDL_WINDOWPOS_CENTERED_DISPLAY(display);
*x = (mode.w - w) / 2;
*y = (mode.h - h) / 2;
} }
} }
static void static void
ClearVideoSurface() ClearVideoSurface()
{ {
Uint32 black; if (SDL_ShadowSurface) {
SDL_FillRect(SDL_ShadowSurface, NULL,
/* Clear the surface for display */ SDL_MapRGB(SDL_ShadowSurface->format, 0, 0, 0));
black = SDL_MapRGB(SDL_PublicSurface->format, 0, 0, 0); }
SDL_FillRect(SDL_PublicSurface, NULL, black); SDL_FillRect(SDL_WindowSurface, NULL, 0);
SDL_UpdateRect(SDL_PublicSurface, 0, 0, 0, 0); SDL_UpdateWindowSurface(SDL_VideoWindow);
} }
static void static void
...@@ -408,11 +427,18 @@ SDL_ResizeVideoMode(int width, int height, int bpp, Uint32 flags) ...@@ -408,11 +427,18 @@ SDL_ResizeVideoMode(int width, int height, int bpp, Uint32 flags)
return 0; return 0;
} }
/* Destroy the screen texture and recreate it */ SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow);
SDL_VideoSurface = SDL_GetWindowSurface(SDL_VideoWindow); if (!SDL_WindowSurface) {
if (!SDL_VideoSurface) { return -1;
}
if (SDL_VideoSurface->format != SDL_WindowSurface->format) {
return -1; 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) { if (SDL_ShadowSurface) {
SDL_ShadowSurface->w = width; SDL_ShadowSurface->w = width;
...@@ -436,8 +462,11 @@ SDL_Surface * ...@@ -436,8 +462,11 @@ SDL_Surface *
SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
{ {
SDL_DisplayMode desktop_mode; SDL_DisplayMode desktop_mode;
int window_x = SDL_WINDOWPOS_UNDEFINED; int display = GetVideoDisplay();
int window_y = SDL_WINDOWPOS_UNDEFINED; 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 window_flags;
Uint32 surface_flags; Uint32 surface_flags;
...@@ -447,7 +476,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) ...@@ -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) { if (width == 0) {
width = desktop_mode.w; width = desktop_mode.w;
...@@ -472,6 +501,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) ...@@ -472,6 +501,7 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
SDL_ShadowSurface = NULL; SDL_ShadowSurface = NULL;
} }
if (SDL_VideoSurface) { if (SDL_VideoSurface) {
SDL_VideoSurface->flags &= ~SDL_DONTFREE;
SDL_FreeSurface(SDL_VideoSurface); SDL_FreeSurface(SDL_VideoSurface);
SDL_VideoSurface = NULL; SDL_VideoSurface = NULL;
} }
...@@ -548,11 +578,31 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) ...@@ -548,11 +578,31 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
} }
/* Create the screen surface */ /* Create the screen surface */
SDL_VideoSurface = SDL_GetWindowSurface(SDL_VideoWindow); SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow);
if (!SDL_VideoSurface) { if (!SDL_WindowSurface) {
return NULL; 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 |= 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 */ /* Create a shadow surface if necessary */
if ((bpp != SDL_VideoSurface->format->BitsPerPixel) if ((bpp != SDL_VideoSurface->format->BitsPerPixel)
...@@ -571,6 +621,8 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) ...@@ -571,6 +621,8 @@ SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags)
SDL_DitherColors(SDL_ShadowSurface->format->palette->colors, SDL_DitherColors(SDL_ShadowSurface->format->palette->colors,
SDL_ShadowSurface->format->BitsPerPixel); SDL_ShadowSurface->format->BitsPerPixel);
} }
SDL_FillRect(SDL_ShadowSurface, NULL,
SDL_MapRGB(SDL_ShadowSurface->format, 0, 0, 0));
} }
SDL_PublicSurface = SDL_PublicSurface =
(SDL_ShadowSurface ? SDL_ShadowSurface : SDL_VideoSurface); (SDL_ShadowSurface ? SDL_ShadowSurface : SDL_VideoSurface);
...@@ -719,7 +771,25 @@ SDL_UpdateRects(SDL_Surface * screen, int numrects, SDL_Rect * rects) ...@@ -719,7 +771,25 @@ SDL_UpdateRects(SDL_Surface * screen, int numrects, SDL_Rect * rects)
screen = SDL_VideoSurface; screen = SDL_VideoSurface;
} }
if (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);
}
} }
} }
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "SDL_rect.h" #include "SDL_rect.h"
SDL_bool SDL_bool
SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B) SDL_HasIntersection(const SDL_Rect * A, const SDL_Rect * B)
{ {
...@@ -339,4 +340,42 @@ SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2, ...@@ -339,4 +340,42 @@ SDL_IntersectRectAndLine(const SDL_Rect * rect, int *X1, int *Y1, int *X2,
return SDL_TRUE; 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: */ /* vi: set ts=4 sw=4 expandtab: */
/*
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: */
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include "SDL_sysvideo.h" #include "SDL_sysvideo.h"
#include "SDL_blit.h" #include "SDL_blit.h"
#include "SDL_pixels_c.h" #include "SDL_pixels_c.h"
#include "SDL_rect_c.h"
#include "../events/SDL_events_c.h" #include "../events/SDL_events_c.h"
#if SDL_VIDEO_OPENGL #if SDL_VIDEO_OPENGL
...@@ -306,12 +307,8 @@ static int ...@@ -306,12 +307,8 @@ static int
SDL_UpdateWindowTexture(_THIS, SDL_Window * window, int numrects, SDL_Rect * rects) SDL_UpdateWindowTexture(_THIS, SDL_Window * window, int numrects, SDL_Rect * rects)
{ {
SDL_WindowTextureData *data; SDL_WindowTextureData *data;
#ifdef UPDATE_TEXTURE_SUBRECTS SDL_Rect rect;
void *src, *dst; void *src;
int src_pitch;
int dst_pitch;
int i, row, length;
#endif
data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA); data = SDL_GetWindowData(window, SDL_WINDOWTEXTUREDATA);
if (!data || !data->texture) { if (!data || !data->texture) {
...@@ -319,34 +316,21 @@ SDL_UpdateWindowTexture(_THIS, SDL_Window * window, int numrects, SDL_Rect * rec ...@@ -319,34 +316,21 @@ SDL_UpdateWindowTexture(_THIS, SDL_Window * window, int numrects, SDL_Rect * rec
return -1; return -1;
} }
#ifdef UPDATE_TEXTURE_SUBRECTS /* Update a single rect that contains subrects for best DMA performance */
src_pitch = data->pitch; if (SDL_GetSpanEnclosingRect(window->w, window->h, numrects, rects, &rect)) {
for (i = 0; i < numrects; ++i) {
src = (void *)((Uint8 *)data->pixels + src = (void *)((Uint8 *)data->pixels +
rects[i].y * src_pitch + rect.y * data->pitch +
rects[i].x * data->bytes_per_pixel); rect.x * data->bytes_per_pixel);
if (SDL_LockTexture(data->texture, &rects[i], &dst, &dst_pitch) < 0) { if (SDL_UpdateTexture(data->texture, &rect, src, data->pitch) < 0) {
return -1; return -1;
} }
length = rects[i].w * data->bytes_per_pixel;
for (row = rects[i].h; row--; ) { if (SDL_RenderCopy(data->renderer, data->texture, NULL, NULL) < 0) {
SDL_memcpy(dst, src, length); return -1;
src = (Uint8*)src + src_pitch;
dst = (Uint8*)dst + dst_pitch;
} }
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) { SDL_RenderPresent(data->renderer);
return -1;
} }
SDL_RenderPresent(data->renderer);
return 0; return 0;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment