summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gfx.cpp1
-rw-r--r--src/gfx_func.h1
-rw-r--r--src/gfx_type.h7
-rw-r--r--src/gfxinit.cpp11
-rw-r--r--src/openttd.cpp11
-rw-r--r--src/table/misc_settings.ini12
-rw-r--r--src/table/win32_settings.ini11
-rw-r--r--src/video/sdl_v.cpp2
-rw-r--r--src/video/win32_v.cpp16
9 files changed, 48 insertions, 24 deletions
diff --git a/src/gfx.cpp b/src/gfx.cpp
index 021863451..a288ee0f4 100644
--- a/src/gfx.cpp
+++ b/src/gfx.cpp
@@ -30,6 +30,7 @@
byte _dirkeys; ///< 1 = left, 2 = up, 4 = right, 8 = down
bool _fullscreen;
+byte _support8bpp;
CursorVars _cursor;
bool _ctrl_pressed; ///< Is Ctrl pressed?
bool _shift_pressed; ///< Is Shift pressed?
diff --git a/src/gfx_func.h b/src/gfx_func.h
index 38c9ea5e3..6576dee4f 100644
--- a/src/gfx_func.h
+++ b/src/gfx_func.h
@@ -52,6 +52,7 @@ void CreateConsole();
extern byte _dirkeys; ///< 1 = left, 2 = up, 4 = right, 8 = down
extern bool _fullscreen;
+extern byte _support8bpp;
extern CursorVars _cursor;
extern bool _ctrl_pressed; ///< Is Ctrl pressed?
extern bool _shift_pressed; ///< Is Shift pressed?
diff --git a/src/gfx_type.h b/src/gfx_type.h
index 2b792d090..0633bdd52 100644
--- a/src/gfx_type.h
+++ b/src/gfx_type.h
@@ -300,4 +300,11 @@ struct Palette {
int count_dirty; ///< The number of dirty elements.
};
+/** Modes for 8bpp support */
+enum Support8bpp {
+ S8BPP_NONE = 0, ///< No support for 8bpp by OS or hardware, force 32bpp blitters.
+ S8BPP_SYSTEM, ///< No 8bpp support by hardware, do not try to use 8bpp video modes or hardware palettes.
+ S8BPP_HARDWARE, ///< Full 8bpp support by OS and hardware.
+};
+
#endif /* GFX_TYPE_H */
diff --git a/src/gfxinit.cpp b/src/gfxinit.cpp
index 30ff37998..ac116bf4a 100644
--- a/src/gfxinit.cpp
+++ b/src/gfxinit.cpp
@@ -238,16 +238,21 @@ static bool SwitchNewGRFBlitter()
/* Null driver => dedicated server => do nothing. */
if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) return false;
- /* Get preferred depth. */
+ /* Get preferred depth.
+ * - depth_wanted_by_base: Depth required by the baseset, i.e. the majority of the sprites.
+ * - depth_wanted_by_grf: Depth required by some NewGRF.
+ * Both can force using a 32bpp blitter. depth_wanted_by_base is used to select
+ * between multiple 32bpp blitters, which perform differently with 8bpp sprites.
+ */
uint depth_wanted_by_base = BaseGraphics::GetUsedSet()->blitter == BLT_32BPP ? 32 : 8;
- uint depth_wanted_by_grf = 8;
+ uint depth_wanted_by_grf = _support8bpp == S8BPP_NONE ? 32 : 8;
for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND || HasBit(c->flags, GCF_INIT_ONLY)) continue;
if (c->palette & GRFP_BLT_32BPP) depth_wanted_by_grf = 32;
}
/* Search the best blitter. */
- struct {
+ static const struct {
const char *name;
uint animation; ///< 0: no support, 1: do support, 2: both
uint min_base_depth, max_base_depth, min_grf_depth, max_grf_depth;
diff --git a/src/openttd.cpp b/src/openttd.cpp
index 5f8ecc9ff..2d5b06e73 100644
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -757,8 +757,15 @@ int openttd_main(int argc, char *argv[])
DEBUG(misc, 1, "Loading blitter...");
if (blitter == NULL && _ini_blitter != NULL) blitter = stredup(_ini_blitter);
_blitter_autodetected = StrEmpty(blitter);
- /* If we have a 32 bpp base set, try to select the 32 bpp blitter first, but only if we autoprobe the blitter. */
- if (!_blitter_autodetected || BaseGraphics::GetUsedSet() == NULL || BaseGraphics::GetUsedSet()->blitter == BLT_8BPP || BlitterFactory::SelectBlitter("32bpp-anim") == NULL) {
+ /* Activate the initial blitter.
+ * This is only some initial guess, after NewGRFs have been loaded SwitchNewGRFBlitter may switch to a different one.
+ * - Never guess anything, if the user specified a blitter. (_blitter_autodetected)
+ * - Use 32bpp blitter if baseset or 8bpp-support settings says so.
+ * - Use 8bpp blitter otherwise.
+ */
+ if (!_blitter_autodetected ||
+ (_support8bpp != S8BPP_NONE && (BaseGraphics::GetUsedSet() == NULL || BaseGraphics::GetUsedSet()->blitter == BLT_8BPP)) ||
+ BlitterFactory::SelectBlitter("32bpp-anim") == NULL) {
if (BlitterFactory::SelectBlitter(blitter) == NULL) {
StrEmpty(blitter) ?
usererror("Failed to autoprobe blitter") :
diff --git a/src/table/misc_settings.ini b/src/table/misc_settings.ini
index 1a2b5ef6b..474c9b981 100644
--- a/src/table/misc_settings.ini
+++ b/src/table/misc_settings.ini
@@ -9,12 +9,15 @@
[pre-amble]
extern char _config_language_file[MAX_PATH];
+static const char *_support8bppmodes = "no|system|hardware";
+
static const SettingDescGlobVarList _misc_settings[] = {
[post-amble]
};
[templates]
SDTG_LIST = SDTG_LIST($name, $type, $length, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat),
SDTG_MMANY = SDTG_MMANY($name, $type, $flags, $guiflags, $var, $def, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat),
+SDTG_OMANY = SDTG_OMANY($name, $type, $flags, $guiflags, $var, $def, $max, $full, $str, $strhelp, $strval, $proc, $from, $to, $cat),
SDTG_STR = SDTG_STR($name, $type, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat),
SDTG_BOOL = SDTG_BOOL($name, $flags, $guiflags, $var, $def, $str, $strhelp, $strval, $proc, $from, $to, $cat),
SDTG_VAR = SDTG_VAR($name, $type, $flags, $guiflags, $var, $def, $min, $max, $interval, $str, $strhelp, $strval, $proc, $from, $to, $cat),
@@ -48,6 +51,15 @@ var = _fullscreen
def = false
cat = SC_BASIC
+[SDTG_OMANY]
+name = ""support8bpp""
+type = SLE_UINT8
+var = _support8bpp
+def = 0
+max = 2
+full = _support8bppmodes
+cat = SC_BASIC
+
[SDTG_STR]
name = ""graphicsset""
type = SLE_STRQ
diff --git a/src/table/win32_settings.ini b/src/table/win32_settings.ini
index 282c13272..1e0c9ad02 100644
--- a/src/table/win32_settings.ini
+++ b/src/table/win32_settings.ini
@@ -10,7 +10,7 @@
/* win32_v.cpp only settings */
#if defined(WIN32) && !defined(DEDICATED)
extern bool _force_full_redraw, _window_maximize;
-extern uint _display_hz, _fullscreen_bpp;
+extern uint _display_hz;
static const SettingDescGlobVarList _win32_settings[] = {
[post-amble]
@@ -51,15 +51,6 @@ var = _force_full_redraw
def = false
cat = SC_EXPERT
-[SDTG_VAR]
-name = ""fullscreen_bpp""
-type = SLE_UINT
-var = _fullscreen_bpp
-def = 8
-min = 8
-max = 32
-cat = SC_EXPERT
-
[SDTG_BOOL]
name = ""window_maximize""
var = _window_maximize
diff --git a/src/video/sdl_v.cpp b/src/video/sdl_v.cpp
index 9b1dd727f..d34f5e6db 100644
--- a/src/video/sdl_v.cpp
+++ b/src/video/sdl_v.cpp
@@ -317,7 +317,7 @@ bool VideoDriver_SDL::CreateMainSurface(uint w, uint h)
* (which we can't force in 8bpp on 8bpp mode,
* unfortunately).
*/
- want_hwpalette = (bpp == 8 && _fullscreen);
+ want_hwpalette = bpp == 8 && _fullscreen && _support8bpp == S8BPP_HARDWARE;
} else {
/* User specified a value manually */
want_hwpalette = _use_hwpalette;
diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp
index 989a2f1a2..3774f3c0f 100644
--- a/src/video/win32_v.cpp
+++ b/src/video/win32_v.cpp
@@ -52,7 +52,6 @@ static struct {
bool _force_full_redraw;
bool _window_maximize;
uint _display_hz;
-uint _fullscreen_bpp;
static Dimension _bck_resolution;
#if !defined(WINCE) || _WIN32_WCE >= 0x400
DWORD _imm_props;
@@ -272,23 +271,21 @@ bool VideoDriver_Win32::MakeWindow(bool full_screen)
if (full_screen) {
DEVMODE settings;
- /* Make sure we are always at least the screen-depth of the blitter */
- if (_fullscreen_bpp < BlitterFactory::GetCurrentBlitter()->GetScreenDepth()) _fullscreen_bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
-
memset(&settings, 0, sizeof(settings));
settings.dmSize = sizeof(settings);
settings.dmFields =
- (_fullscreen_bpp != 0 ? DM_BITSPERPEL : 0) |
+ DM_BITSPERPEL |
DM_PELSWIDTH |
DM_PELSHEIGHT |
(_display_hz != 0 ? DM_DISPLAYFREQUENCY : 0);
- settings.dmBitsPerPel = _fullscreen_bpp;
+ settings.dmBitsPerPel = BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
settings.dmPelsWidth = _wnd.width_org;
settings.dmPelsHeight = _wnd.height_org;
settings.dmDisplayFrequency = _display_hz;
/* Check for 8 bpp support. */
- if (settings.dmBitsPerPel != 32 && ChangeDisplaySettings(&settings, CDS_FULLSCREEN | CDS_TEST) != DISP_CHANGE_SUCCESSFUL) {
+ if (settings.dmBitsPerPel == 8 &&
+ (_support8bpp != S8BPP_HARDWARE || ChangeDisplaySettings(&settings, CDS_FULLSCREEN | CDS_TEST) != DISP_CHANGE_SUCCESSFUL)) {
settings.dmBitsPerPel = 32;
}
@@ -1107,11 +1104,14 @@ static void FindResolutions()
uint i;
DEVMODEA dm;
+ /* Check modes for the relevant fullscreen bpp */
+ int bpp = _support8bpp != S8BPP_HARDWARE ? 32 : BlitterFactory::GetCurrentBlitter()->GetScreenDepth();
+
/* XXX - EnumDisplaySettingsW crashes with unicows.dll on Windows95
* Doesn't really matter since we don't pass a string anyways, but still
* a letdown */
for (i = 0; EnumDisplaySettingsA(NULL, i, &dm) != 0; i++) {
- if (dm.dmBitsPerPel == BlitterFactory::GetCurrentBlitter()->GetScreenDepth() &&
+ if (dm.dmBitsPerPel == bpp &&
dm.dmPelsWidth >= 640 && dm.dmPelsHeight >= 480) {
uint j;