summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gfxinit.cpp53
1 files changed, 40 insertions, 13 deletions
diff --git a/src/gfxinit.cpp b/src/gfxinit.cpp
index 06326ab3f..4a830d7a8 100644
--- a/src/gfxinit.cpp
+++ b/src/gfxinit.cpp
@@ -228,25 +228,52 @@ static void LoadSpriteTables()
*/
static void SwitchNewGRFBlitter()
{
- /* Get blitter of base set. */
- bool is_32bpp = BaseGraphics::GetUsedSet()->blitter == BLT_32BPP;
+ /* Never switch if the blitter was specified by the user. */
+ if (!_blitter_autodetected) return;
- /* Get combined blitter mode of all NewGRFs. */
+ /* Null driver => dedicated server => do nothing. */
+ if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) return;
+
+ /* Get preferred depth. */
+ uint depth_wanted_by_base = BaseGraphics::GetUsedSet()->blitter == BLT_32BPP ? 32 : 8;
+ uint depth_wanted_by_grf = 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;
+ }
- if (c->palette & GRFP_BLT_32BPP) is_32bpp = true;
+ /* Search the best blitter. */
+ struct {
+ const char *name;
+ uint min_base_depth, max_base_depth, min_grf_depth, max_grf_depth;
+ } replacement_blitters[] = {
+#ifdef WITH_SSE
+ { "32bpp-sse4-anim", 32, 32, 8, 32 },
+#endif
+ { "8bpp-optimized", 8, 8, 8, 8 },
+ { "32bpp-anim", 8, 32, 8, 32 },
+ };
+
+ const char *cur_blitter = BlitterFactory::GetCurrentBlitter()->GetName();
+
+ for (uint i = 0; i < lengthof(replacement_blitters); i++) {
+ if (!IsInsideMM(depth_wanted_by_base, replacement_blitters[i].min_base_depth, replacement_blitters[i].max_base_depth + 1)) continue;
+ if (!IsInsideMM(depth_wanted_by_grf, replacement_blitters[i].min_grf_depth, replacement_blitters[i].max_grf_depth + 1)) continue;
+ const char *repl_blitter = replacement_blitters[i].name;
+
+ if (strcmp(repl_blitter, cur_blitter) == 0) return;
+ if (BlitterFactory::GetBlitterFactory(repl_blitter) == NULL) continue;
+
+ DEBUG(misc, 1, "Switching blitter from '%s' to '%s'... ", cur_blitter, repl_blitter);
+ Blitter *new_blitter = BlitterFactory::SelectBlitter(repl_blitter);
+ if (new_blitter == NULL) NOT_REACHED();
+ DEBUG(misc, 1, "Successfully switched to %s.", repl_blitter);
+ break;
}
- /* A GRF would like a 32 bpp blitter, switch blitter if needed. Never switch if the blitter was specified by the user. */
- if (_blitter_autodetected && is_32bpp && BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 0 && BlitterFactory::GetCurrentBlitter()->GetScreenDepth() < 16) {
- const char *cur_blitter = BlitterFactory::GetCurrentBlitter()->GetName();
- if (BlitterFactory::SelectBlitter("32bpp-anim") != NULL) {
- if (!_video_driver->AfterBlitterChange()) {
- /* Failed to switch blitter, let's hope we can return to the old one. */
- if (BlitterFactory::SelectBlitter(cur_blitter) == NULL || !_video_driver->AfterBlitterChange()) usererror("Failed to reinitialize video driver for 32 bpp blitter. Specify a fixed blitter in the config");
- }
- }
+ if (!_video_driver->AfterBlitterChange()) {
+ /* Failed to switch blitter, let's hope we can return to the old one. */
+ if (BlitterFactory::SelectBlitter(cur_blitter) == NULL || !_video_driver->AfterBlitterChange()) usererror("Failed to reinitialize video driver. Specify a fixed blitter in the config");
}
}