Hi all,

Well I've done some more testing and it turns out that although resizing
the window as done in my latest patch is enough to get resizing to work
properly with opengl, a call to SDL_SetVideoMode() really is needed for
software rendering to things like recreate the underlying XImage, update
the size and pitch of the SDL surface, etc.

This version of the patch fixes things by calling SDL_SetVideoMode()
from the resize function as needed, and includes code to take into
account the fact(?) that the GLcontext gets recreated when
SDL_SetVideoMode() is called for other OS. Since I'm not so sure that
this is correct (the fact that the GLcontext gets recreated) otherwise
people on macOS-X should have been seeing crashes, because
SDL_SetVideoMode does get called under certain conditions already
without the texture cache being cleared. So maybe people have been
seeing crashes / problems when switching between Fullscreen and window
for example, in which case this pathc is not only correct but needs to
be expanded to also reinit the opengl stuff on fullscreen toggle.

Or more likely my source for the GLcontext recreating is wrong. I'm
currently thinking its the latter, but I'm not sure. I also don't know
if the SDL_SetVideoMode call on user resize is needed by any other
platforms. So I'll post a much cleaned up patch shortly which simply
fixes things for Linux only, trying not todo any crystal ball stuff for
any other platforms. Still I wanted to share this in case it is usefull
for other platforms.

Regards,

Hans

diff -ur sdlmame0108u1.orig/src/sdl/drawsdl.c sdlmame0108u1/src/sdl/drawsdl.c
--- sdlmame0108u1.orig/src/sdl/drawsdl.c	2006-08-18 04:42:02.000000000 +0200
+++ sdlmame0108u1/src/sdl/drawsdl.c	2006-09-02 16:33:42.000000000 +0200
@@ -380,7 +380,8 @@
 		hofs = (window->wind_rect.right - sdl->blitwidth) / 2;
 	}
 
-	surfptr += ((vofs * window->sdlsurf->pitch) + hofs*4);
+	surfptr += vofs * window->sdlsurf->pitch +
+        	hofs * window->sdlsurf->format->BytesPerPixel;
 
 	// render to it
 	osd_lock_acquire(window->primlist->lock);
@@ -1331,6 +1332,22 @@
 		texture->texinfo.seqid = prim->texture.seqid;
 	}
 }
+
+void drawsdl_destroy_all_textures(sdl_info *sdl)
+{
+	texture_info *next_texture, *texture = sdl->texlist;
+
+	while(texture)
+	{
+		next_texture = texture->next;
+		glDeleteTextures(1, &texture->texturename);
+		if (texture->data);
+			free(texture->data);
+		free(texture);
+		texture = next_texture;
+        }
+        sdl->texlist = NULL;
+}
 #endif
 
 //============================================================
diff -ur sdlmame0108u1.orig/src/sdl/window.c sdlmame0108u1/src/sdl/window.c
--- sdlmame0108u1.orig/src/sdl/window.c	2006-08-18 04:42:02.000000000 +0200
+++ sdlmame0108u1/src/sdl/window.c	2006-09-02 16:02:15.000000000 +0200
@@ -92,6 +93,7 @@
 static void sdlwindow_exit(void);
 static void sdlwindow_video_window_destroy(sdl_window_info *window);
 static void draw_video_contents(sdl_window_info *window, UINT32 dc, int update);
+static void sdlwindow_init_ogl_context(void);
 
 int complete_create(sdl_window_info *window);
 static void set_starting_view(int index, sdl_window_info *window, const char *view);
@@ -160,11 +162,40 @@
 //============================================================
 
 void compute_blit_surface_size(sdl_window_info *window);
+void drawsdl_destroy_all_textures(sdl_info *sdl);
 
 void sdlwindow_resize(INT32 width, INT32 height)
 {
 	sdl_window_info *window = sdl_window_list;
-	
+
+/* According to the SDL documentation this function should call
+   SDL_SetVideoMode() with the new width and height, see here:
+   http://www.libsdl.org/cgi/docwiki.cgi/SDL_5fResizeEvent
+   However on MacOS-X and on windows this destroys and recreates the OpenGL
+   content (or so I've heared), requiring us to recreate all our cached
+   textures and redo the OpenGL context initialisation.
+   
+   Under X11 not calling SDL_SetVideoMode() causes various problems both in
+   OpenGL and in software rendering mode. Under X11 however the OpenGL context
+   doesn't get destroyed, so we do not need to recreate our textures and
+   reinit our OpenGL context. Thus currently this gets skipped if we are under
+   X11. Perhaps the reinit of the OpenGL stuff or the SDL_SetVideoMode() can
+   be skipped under Windows / MacOS-X, this needs to be tested by people with
+   access to these platforms. According to this:
+   http://www.libsdl.org/pipermail/sdl/2006-June/075062.html
+   The SDL_SetVideoMode() is needed under windows, but can be hacked around.
+   If you test this under other platforms please test both the OpenGL and
+   software rendering modes. */
+#ifndef SDLMAME_LINUX
+	drawsdl_destroy_all_textures(window->dxdata);
+#endif
+	SDL_SetVideoMode(width, height, 0, SDL_SWSURFACE |
+		SDL_DOUBLEBUF | SDL_ANYFORMAT | window->extra_flags);
+
+#ifndef SDLMAME_LINUX
+	if (window->opengl)
+		sdlwindow_init_ogl_context();
+#endif
 	window->wind_rect.right = width;
 	window->wind_rect.bottom = height;
 
@@ -540,6 +571,17 @@
 	return 0;
 }
 
+static void sdlwindow_init_ogl_context(void)
+{
+	// do some one-time OpenGL setup
+	glShadeModel(GL_SMOOTH);
+	glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+	glClearDepth(1.0f);
+	glEnable(GL_DEPTH_TEST);
+	glDepthFunc(GL_LEQUAL);
+	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+}
+
 //============================================================
 //  complete_create
 //  (window thread)
@@ -637,13 +679,7 @@
 		glGetIntegerv(GL_MAX_TEXTURE_SIZE, &sdl->texture_max_height);
 		printf("OpenGL: max texture size %d x %d\n", sdl->texture_max_width, sdl->texture_max_height);
 
-		// do some one-time OpenGL setup
-		glShadeModel(GL_SMOOTH);
-		glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-		glClearDepth(1.0f);
-		glEnable(GL_DEPTH_TEST);
-		glDepthFunc(GL_LEQUAL);
-		glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
+		sdlwindow_init_ogl_context();
 	}
 
 	// maximum or minimize as appropriate

Reply via email to