This SDL patch merges fixes from bga and rogueeve into on patch. Further testing needs to be done, but early tests looks like this one is better than the previous ones. Still dome TODOs listed...

This commit is contained in:
Scott McCreary
2009-10-02 07:19:01 +00:00
parent 40061d5cec
commit d3471e9841

View File

@@ -0,0 +1,240 @@
Index: src/video/bwindow/SDL_BWin.h
===================================================================
--- src/video/bwindow/SDL_BWin.h (revision 4901)
+++ src/video/bwindow/SDL_BWin.h (working copy)
@@ -267,6 +267,8 @@
}
virtual void DispatchMessage(BMessage *msg, BHandler *target);
+
+ virtual void DirectConnected(direct_buffer_info *info);
private:
#if SDL_VIDEO_OPENGL
Index: src/video/bwindow/SDL_sysevents.cc
===================================================================
--- src/video/bwindow/SDL_sysevents.cc (revision 4901)
+++ src/video/bwindow/SDL_sysevents.cc (working copy)
@@ -379,3 +379,20 @@
}
BDirectWindow::DispatchMessage(msg, target);
}
+
+void SDL_BWin::DirectConnected(direct_buffer_info *info) {
+ switch (info->buffer_state & B_DIRECT_MODE_MASK) {
+ case B_DIRECT_START:
+ case B_DIRECT_MODIFY:
+ {
+ int32 width = info->window_bounds.right -
+ info->window_bounds.left + 1;
+ int32 height = info->window_bounds.bottom -
+ info->window_bounds.top + 1;
+ SDL_PrivateResize(width, height);
+ break;
+ }
+ default:
+ break;
+ }
+}
Index: src/video/bwindow/SDL_sysvideo.cc
===================================================================
--- src/video/bwindow/SDL_sysvideo.cc (revision 4901)
+++ src/video/bwindow/SDL_sysvideo.cc (working copy)
@@ -57,7 +57,7 @@
static void BE_FreeHWSurface(_THIS, SDL_Surface *surface);
static int BE_ToggleFullScreen(_THIS, int fullscreen);
-SDL_Overlay *BE_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display);
+static SDL_Overlay *BE_CreateYUVOverlay(_THIS, int width, int height, Uint32 format, SDL_Surface *display);
/* OpenGL functions */
#if SDL_VIDEO_OPENGL
@@ -358,16 +358,25 @@
(current.timing.h_total * current.timing.v_total);
modes = SDL_modelist[((bpp+7)/8)-1];
- for ( i=0; modes[i] && (modes[i]->w > width) &&
- (modes[i]->h > height); ++i ) {
- /* still looking */
+
+ // find end of list (lowest-resolution mode; modes are ordered
+ // highest-to-lowest).
+ i = 0; while(modes[i]) i++;
+ if (!i) return false; // what? no modes at all?
+
+ // find first mode with resolution >= requested in both dimensions
+ for (--i; i >= 0; --i)
+ {
+ if (modes[i]->w >= width && modes[i]->h >= height)
+ break;
}
- if ( ! modes[i] || (modes[i]->w < width) || (modes[i]->h < width) ) {
- --i; /* We went too far */
- }
-
+
+ // unable to find any mode with that high a resolution!
+ if (i < 0)
+ return false;
+
width = modes[i]->w;
- height = modes[i]->h;
+ height = modes[i]->h;
bscreen.GetModeList(&dmodes, &nmodes);
for ( i = 0; i < nmodes; ++i ) {
@@ -396,88 +405,88 @@
static int BE_SetFullScreen(_THIS, SDL_Surface *screen, int fullscreen)
{
- int was_fullscreen;
- bool needs_unlock;
+ // printf("SetFullScreen(%d)\n", fullscreen);
BScreen bscreen;
- BRect bounds;
- display_mode mode;
- int width, height, bpp;
- /* Set the fullscreen mode */
- was_fullscreen = SDL_Win->IsFullScreen();
- SDL_Win->SetFullScreen(fullscreen);
- fullscreen = SDL_Win->IsFullScreen();
+ // SetFullSscreen() does not work as expected if called in a window
+ // that was never shown. This is probably a bug in the Haiku Game Kit that needs
+ // to be investigated.
+ if (SDL_Win->Lock()) {
+ // Show our window.
+ SDL_Win->Show();
+ }
+
+ if (SDL_Win->IsLocked()) {
+ // Unlock the window if it was locked. This is needed as only the
+ // first call to Show() unlocks the looper. All other calls to it
+ // will not.
+ SDL_Win->Unlock();
+ }
- width = screen->w;
- height = screen->h;
+ int width = screen->w;
+ int height = screen->h;
+
+ if (fullscreen) {
+ // Set resolution to the closest available one that matches the
+ // current SDL resolution.
+ display_mode mode;
+ bscreen.GetMode(&mode);
- /* Set the appropriate video mode */
- if ( fullscreen ) {
- bpp = screen->format->BitsPerPixel;
- bscreen.GetMode(&mode);
- if ( (bpp != ColorSpaceToBitsPerPixel(mode.space)) ||
- (width != mode.virtual_width) ||
- (height != mode.virtual_height)) {
+ int bpp = screen->format->BitsPerPixel;
+ if (bpp != ColorSpaceToBitsPerPixel(mode.space) ||
+ width != mode.virtual_width || height != mode.virtual_height) {
if(BE_FindClosestFSMode(_this, width, height, bpp, &mode)) {
bscreen.SetMode(&mode);
- /* This simply stops the next resize event from being
- * sent to the SDL handler.
- */
- SDL_Win->InhibitResize();
} else {
- fullscreen = 0;
- SDL_Win->SetFullScreen(fullscreen);
- }
+ // printf("Could not set new mode.\n");
+ return(0);
+ }
}
+ } else {
+ // Reset to the previous known resolution as we are now in window
+ // mode.
+ bscreen.SetMode(&saved_mode);
}
- if ( was_fullscreen && ! fullscreen ) {
- bscreen.SetMode(&saved_mode);
- }
-
- if ( SDL_Win->Lock() ) {
- int cx, cy;
- if ( SDL_Win->Shown() ) {
- needs_unlock = 1;
- SDL_Win->Hide();
- } else {
- needs_unlock = 0;
- }
- /* This resizes the window and view area, but inhibits resizing
- * of the BBitmap due to the InhibitResize call above. Thus the
- * bitmap (pixel data) never changes.
- */
+
+ // Effectivelly set/reset full screen mode. If we are already in
+ // full screen mode, we reset back to windowed mode first so the
+ // window can resize when going fullscreen.
+ // if (fullscreen)
+ // printf("Going fullscreen\n");
+ // else
+ // printf("Going windowed\n");
+ SDL_Win->SetFullScreen(fullscreen);
+
+ // Calculate offsets for centering the window (in window mode) and for
+ // dentering the bitmap (in full screen mode).
+ BRect bounds = bscreen.Frame();
+ bounds.PrintToStream();
+ int32 cx = (bounds.IntegerWidth() - width)/2;
+ int32 cy = (bounds.IntegerHeight() - height)/2;
+
+ // printf ("cx = %d, cy = %d\n", cx, cy);
+ if (!SDL_Win->IsFullScreen()) {
+ // printf("Doing not fullscreen stuff.\n");
+ // We are not in full screen mode, so we want to change the window
+ // size to match the resolution in SDL.
SDL_Win->ResizeTo(width, height);
- bounds = bscreen.Frame();
- /* Calculate offsets - used either to center window
- * (windowed mode) or to set drawing offsets (fullscreen mode)
- */
- cx = (bounds.IntegerWidth() - width)/2;
- cy = (bounds.IntegerHeight() - height)/2;
-
- if ( fullscreen ) {
- /* Set offset for drawing */
- SDL_Win->SetXYOffset(cx, cy);
- } else {
- SDL_Win->SetXYOffset(0, 0);
- }
- if ( ! needs_unlock || was_fullscreen ) {
- /* Center the window the first time */
- SDL_Win->MoveTo(cx, cy);
- }
- SDL_Win->Show();
- /* Unlock the window manually after the first Show() */
- if ( needs_unlock ) {
- SDL_Win->Unlock();
- }
+ // And also center the window and reset the drawing offset.
+ SDL_Win->MoveTo(cx, cy);
+ SDL_Win->SetXYOffset(0, 0);
+ } else {
+ // printf("Doing fullscreen stuff.");
+ // Center the bitmap whenever we are in full screen mode.
+ SDL_Win->SetXYOffset(cx, cy);
}
-
- /* Set the fullscreen flag in the screen surface */
- if ( fullscreen ) {
+
+ // Set relevant internal SDL screen flags.
+ if (SDL_Win->IsFullScreen()) {
screen->flags |= SDL_FULLSCREEN;
} else {
screen->flags &= ~SDL_FULLSCREEN;
}
+
return(1);
}