ref: b03de59700f80c75308849ac5f89310d010af066
parent: 167d4df40b55f2e8b559a797bb93b09554a871d0
author: Simon Howard <[email protected]>
date: Sun Nov 21 10:44:43 EST 2010
Add -8in32 command line parameter to make the game run in 32-bit color mode, scaling up into an intermediate 8-bit buffer first. This should help with the palette problems experienced by Windows Vista/7 users. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2164
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -93,6 +93,12 @@
static SDL_Surface *screen;
+// Intermediate 8-bit buffer that we draw to instead of 'screen'.
+// This is used when we are rendering in 32-bit screen mode.
+// When in a real 8-bit screen mode, screenbuffer == screen.
+
+static SDL_Surface *screenbuffer;
+
// palette
static SDL_Color palette[256];
@@ -750,17 +756,18 @@
return true;
}
- x_offset = (screen->w - screen_mode->width) / 2;
- y_offset = (screen->h - screen_mode->height) / 2;
+ x_offset = (screenbuffer->w - screen_mode->width) / 2;
+ y_offset = (screenbuffer->h - screen_mode->height) / 2;
- if (SDL_LockSurface(screen) >= 0)
+ if (SDL_LockSurface(screenbuffer) >= 0)
{
- I_InitScale(screens[0],
- (byte *) screen->pixels + (y_offset * screen->pitch)
- + x_offset,
- screen->pitch);
+ I_InitScale(screens[0],
+ (byte *) screenbuffer->pixels
+ + (y_offset * screenbuffer->pitch)
+ + x_offset,
+ screenbuffer->pitch);
result = screen_mode->DrawScreen(x1, y1, x2, y2);
- SDL_UnlockSurface(screen);
+ SDL_UnlockSurface(screenbuffer);
}
else
{
@@ -895,19 +902,30 @@
// draw to screen
BlitArea(0, 0, SCREENWIDTH, SCREENHEIGHT);
-
- // If we have a palette to set, the act of setting the palette
- // updates the screen
if (palette_to_set)
{
- SDL_SetColors(screen, palette, 0, 256);
+ SDL_SetColors(screenbuffer, palette, 0, 256);
palette_to_set = false;
+
+ // In native 8-bit mode, if we have a palette to set, the act
+ // of setting the palette updates the screen
+
+ if (screenbuffer == screen)
+ {
+ return;
+ }
}
- else
+
+ // In 8in32 mode, we must blit from the fake 8-bit screen buffer
+ // to the real screen before doing a screen flip.
+
+ if (screenbuffer != screen)
{
- SDL_Flip(screen);
+ SDL_BlitSurface(screenbuffer, NULL, screen, NULL);
}
+
+ SDL_Flip(screen);
}
@@ -1540,6 +1558,7 @@
{
byte *doompal;
int flags = 0;
+ int bpp = 8;
doompal = W_CacheLumpName(DEH_String("PLAYPAL"), PU_CACHE);
@@ -1552,8 +1571,17 @@
// Set the video mode.
- flags |= SDL_SWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF;
+ flags |= SDL_SWSURFACE;
+ if (M_CheckParm("-8in32"))
+ {
+ bpp = 32;
+ }
+ else
+ {
+ flags |= SDL_HWPALETTE | SDL_DOUBLEBUF;
+ }
+
if (fullscreen)
{
flags |= SDL_FULLSCREEN;
@@ -1563,13 +1591,25 @@
flags |= SDL_RESIZABLE;
}
- screen = SDL_SetVideoMode(w, h, 8, flags);
+ screen = SDL_SetVideoMode(w, h, bpp, flags);
if (screen == NULL)
{
- I_Error("Error setting video mode: %s\n", SDL_GetError());
+ I_Error("Error setting video mode %ix%ix%ibpp: %s\n",
+ w, h, bpp, SDL_GetError());
}
+ if (screen->format->BitsPerPixel == 8)
+ {
+ screenbuffer = screen;
+ }
+ else
+ {
+ screenbuffer = SDL_CreateRGBSurface(SDL_SWSURFACE,
+ screen->w, screen->h, 8,
+ 0, 0, 0, 0);
+ }
+
// If mode was not set, it must be set now that we know the
// screen size.
@@ -1708,25 +1748,20 @@
// Start with a clear black screen
// (screen will be flipped after we set the palette)
- if (SDL_LockSurface(screen) >= 0)
- {
- byte *screenpixels;
- int y;
+ SDL_FillRect(screenbuffer, NULL, 0);
- screenpixels = (byte *) screen->pixels;
-
- for (y=0; y<screen->h; ++y)
- memset(screenpixels + screen->pitch * y, 0, screen->w);
-
- SDL_UnlockSurface(screen);
- }
-
// Set the palette
doompal = W_CacheLumpName(DEH_String("PLAYPAL"), PU_CACHE);
I_SetPalette(doompal);
- SDL_SetColors(screen, palette, 0, 256);
+ SDL_SetColors(screenbuffer, palette, 0, 256);
+ if (screen != screenbuffer)
+ {
+ SDL_BlitSurface(screenbuffer, NULL, screen, NULL);
+ SDL_Flip(screen);
+ }
+
CreateCursors();
UpdateFocus();
@@ -1747,7 +1782,8 @@
// Likewise if the screen pitch is not the same as the width
// If we have to multiply, drawing is done to a separate 320x200 buf
- native_surface = !SDL_MUSTLOCK(screen)
+ native_surface = screen == screenbuffer
+ && !SDL_MUSTLOCK(screen)
&& screen_mode == &mode_scale_1x
&& screen->pitch == SCREENWIDTH
&& aspect_ratio_correct;