summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Howard2010-11-21 15:44:43 +0000
committerSimon Howard2010-11-21 15:44:43 +0000
commitb03de59700f80c75308849ac5f89310d010af066 (patch)
tree5a8d503041c6327588fcab988a7cb3ff6296ec7b
parent167d4df40b55f2e8b559a797bb93b09554a871d0 (diff)
downloadchocolate-doom-b03de59700f80c75308849ac5f89310d010af066.tar.gz
chocolate-doom-b03de59700f80c75308849ac5f89310d010af066.tar.bz2
chocolate-doom-b03de59700f80c75308849ac5f89310d010af066.zip
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
-rw-r--r--src/i_video.c98
1 files changed, 67 insertions, 31 deletions
diff --git a/src/i_video.c b/src/i_video.c
index ee10a12e..1139157d 100644
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -93,6 +93,12 @@ char *video_driver = "";
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 @@ static boolean BlitArea(int x1, int y1, int x2, int y2)
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 @@ void I_FinishUpdate (void)
// 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 @@ static void SetVideoMode(screen_mode_t *mode, int w, int h)
{
byte *doompal;
int flags = 0;
+ int bpp = 8;
doompal = W_CacheLumpName(DEH_String("PLAYPAL"), PU_CACHE);
@@ -1552,7 +1571,16 @@ static void SetVideoMode(screen_mode_t *mode, int w, int h)
// 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)
{
@@ -1563,11 +1591,23 @@ static void SetVideoMode(screen_mode_t *mode, int w, int h)
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
@@ -1708,24 +1748,19 @@ void I_InitGraphics(void)
// Start with a clear black screen
// (screen will be flipped after we set the palette)
- if (SDL_LockSurface(screen) >= 0)
- {
- byte *screenpixels;
- int y;
-
- screenpixels = (byte *) screen->pixels;
-
- for (y=0; y<screen->h; ++y)
- memset(screenpixels + screen->pitch * y, 0, screen->w);
-
- SDL_UnlockSurface(screen);
- }
+ SDL_FillRect(screenbuffer, NULL, 0);
// 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();
@@ -1747,7 +1782,8 @@ void I_InitGraphics(void)
// 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;