diff options
author | Simon Howard | 2014-04-12 16:31:31 -0400 |
---|---|---|
committer | Simon Howard | 2014-04-12 16:31:31 -0400 |
commit | 32803819a07859675b1d95b6aafd1674fe7835d8 (patch) | |
tree | 451e2d67d775ffad2ca8abe3d0b6b2c56361c2bf | |
parent | a1b066a0eb0d2cf5d17ad68ca833fcdd21f80725 (diff) | |
download | chocolate-doom-32803819a07859675b1d95b6aafd1674fe7835d8.tar.gz chocolate-doom-32803819a07859675b1d95b6aafd1674fe7835d8.tar.bz2 chocolate-doom-32803819a07859675b1d95b6aafd1674fe7835d8.zip |
textscreen: Init screen at native bit depth.
Always call SDL_SetVideoMode with bpp=0 to use the desktop's native
bit depth, and instead draw into an intermediate 8-bit screenbuffer
surface. This ensures that we do not encounter any palette mess-ups
as on some systems true 8-bit screen modes are poorly supported.
-rw-r--r-- | textscreen/txt_sdl.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/textscreen/txt_sdl.c b/textscreen/txt_sdl.c index 984a2e75..26b4a361 100644 --- a/textscreen/txt_sdl.c +++ b/textscreen/txt_sdl.c @@ -58,6 +58,7 @@ typedef struct #define BLINK_PERIOD 250 static SDL_Surface *screen; +static SDL_Surface *screenbuffer; static unsigned char *screendata; static int key_mapping = 1; @@ -246,24 +247,29 @@ static void ChooseFont(void) int TXT_Init(void) { - int flags; - if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0) { return 0; } - flags = SDL_SWSURFACE | SDL_HWPALETTE | SDL_DOUBLEBUF; - ChooseFont(); + // Always create the screen at the native screen depth (bpp=0); + // some systems nowadays don't seem to support true 8-bit palettized + // screen modes very well and we end up with screwed up colors. screen = SDL_SetVideoMode(TXT_SCREEN_W * font->w, - TXT_SCREEN_H * font->h, 8, flags); + TXT_SCREEN_H * font->h, 0, 0); if (screen == NULL) return 0; - SDL_SetColors(screen, ega_colors, 0, 16); + // Instead, we draw everything into an intermediate 8-bit surface + // the same dimensions as the screen. SDL then takes care of all the + // 8->32 bit (or whatever depth) color conversions for us. + screenbuffer = SDL_CreateRGBSurface(0, TXT_SCREEN_W * font->w, + TXT_SCREEN_H * font->h, + 8, 0, 0, 0, 0); + SDL_SetColors(screenbuffer, ega_colors, 0, 16); SDL_EnableUNICODE(1); screendata = malloc(TXT_SCREEN_W * TXT_SCREEN_H * 2); @@ -285,6 +291,8 @@ void TXT_Shutdown(void) { free(screendata); screendata = NULL; + SDL_FreeSurface(screenbuffer); + screenbuffer = NULL; SDL_QuitSubSystem(SDL_INIT_VIDEO); } @@ -324,8 +332,8 @@ static inline void UpdateCharacter(int x, int y) bytes = (font->w + 7) / 8; p = &font->data[character * font->h * bytes]; - s = ((unsigned char *) screen->pixels) - + (y * font->h * screen->pitch) + s = ((unsigned char *) screenbuffer->pixels) + + (y * font->h * screenbuffer->pitch) + (x * font->w); for (y1=0; y1<font->h; ++y1) @@ -357,7 +365,7 @@ static inline void UpdateCharacter(int x, int y) ++p; } - s += screen->pitch; + s += screenbuffer->pitch; } } @@ -379,6 +387,7 @@ static int LimitToRange(int val, int min, int max) void TXT_UpdateScreenArea(int x, int y, int w, int h) { + SDL_Rect rect; int x1, y1; int x_end; int y_end; @@ -396,9 +405,13 @@ void TXT_UpdateScreenArea(int x, int y, int w, int h) } } - SDL_UpdateRect(screen, - x * font->w, y * font->h, - (x_end - x) * font->w, (y_end - y) * font->h); + rect.x = x * font->w; + rect.y = y * font->h; + rect.w = (x_end - x) * font->w; + rect.h = (y_end - y) * font->h; + + SDL_BlitSurface(screenbuffer, &rect, screen, &rect); + SDL_UpdateRects(screen, 1, &rect); } void TXT_UpdateScreen(void) |