shithub: choc

Download patch

ref: df5be3d8c12bda4f22a8500240765fefe5ccf21c
parent: 32803819a07859675b1d95b6aafd1674fe7835d8
author: Simon Howard <fraggle@gmail.com>
date: Sat Apr 12 12:39:32 EDT 2014

hexen: Create HR (startup) screen at native bpp.

Always call SDL_SetVideoMode() with bpp=0 to use the native pixel
depth of the display. This avoids problems with some systems that
don't properly support 8-bit screen modes any more. Draw into an
intermediate buffer and let SDL take care of the pixel depth
conversion for us.

--- a/src/i_videohr.c
+++ b/src/i_videohr.c
@@ -37,13 +37,12 @@
 #define HR_SCREENWIDTH 640
 #define HR_SCREENHEIGHT 480
 
+static SDL_Surface *hr_screen = NULL;
 static SDL_Surface *hr_surface = NULL;
 static char *window_title = "";
 
 boolean I_SetVideoModeHR(void)
 {
-    Uint32 flags;
-
     if (SDL_Init(SDL_INIT_VIDEO) < 0)
     {
         return false;
@@ -51,16 +50,20 @@
 
     SDL_WM_SetCaption(window_title,  NULL);
 
-    flags = SDL_SWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF;
+    // Create screen surface at the native desktop pixel depth (bpp=0),
+    // as we cannot trust true 8-bit to reliably work nowadays.
+    hr_screen = SDL_SetVideoMode(HR_SCREENWIDTH, HR_SCREENHEIGHT, 0, 0);
 
-    hr_surface = SDL_SetVideoMode(HR_SCREENWIDTH, HR_SCREENHEIGHT, 8, flags);
-
-    if (hr_surface == NULL)
+    if (hr_screen == NULL)
     {
         SDL_QuitSubSystem(SDL_INIT_VIDEO);
         return false;
     }
 
+    // We do all actual drawing into an intermediate surface.
+    hr_surface = SDL_CreateRGBSurface(0, HR_SCREENWIDTH, HR_SCREENHEIGHT,
+                                      8, 0, 0, 0, 0);
+
     return true;
 }
 
@@ -71,9 +74,11 @@
 
 void I_UnsetVideoModeHR(void)
 {
-    if (hr_surface != NULL)
+    if (hr_screen != NULL)
     {
         SDL_QuitSubSystem(SDL_INIT_VIDEO);
+        hr_screen = NULL;
+        SDL_FreeSurface(hr_surface);
         hr_surface = NULL;
     }
 }
@@ -87,6 +92,7 @@
 
 void I_SlamBlockHR(int x, int y, int w, int h, const byte *src)
 {
+    SDL_Rect blit_rect;
     const byte *srcptrs[4];
     byte srcbits[4];
     byte *dest;
@@ -143,9 +149,12 @@
     SDL_UnlockSurface(hr_surface);
 
     // Update the region we drew.
-
-    //SDL_UpdateRect(hr_surface, x, y, w, h);
-    SDL_Flip(hr_surface);
+    blit_rect.x = x;
+    blit_rect.y = y;
+    blit_rect.w = w;
+    blit_rect.h = h;
+    SDL_BlitSurface(hr_surface, &blit_rect, hr_screen, &blit_rect);
+    SDL_UpdateRects(hr_screen, 1, &blit_rect);
 }
 
 void I_SlamHR(const byte *buffer)
@@ -160,6 +169,7 @@
 
 void I_SetPaletteHR(const byte *palette)
 {
+    SDL_Rect screen_rect = {0, 0, HR_SCREENWIDTH, HR_SCREENHEIGHT};
     SDL_Color sdlpal[16];
     int i;
 
@@ -170,7 +180,10 @@
         sdlpal[i].b = palette[i * 3 + 2] * 4;
     }
 
+    // After setting colors, update the screen.
     SDL_SetColors(hr_surface, sdlpal, 0, 16);
+    SDL_BlitSurface(hr_surface, &screen_rect, hr_screen, &screen_rect);
+    SDL_UpdateRects(hr_screen, 1, &screen_rect);
 }
 
 void I_FadeToPaletteHR(const byte *palette)