/** * Handle all procedures for bootstrapping OpenTTD without a base graphics set. * This requires all kinds of trickery that is needed to avoid the use of * sprites from the base graphics set which are pretty interwoven. * @return True if a base set exists, otherwise false. */ bool HandleBootstrap() { if (BaseGraphics::GetUsedSet() != NULL) return true; /* No user interface, bail out with an error. */ if (BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth() == 0) goto failure; /* If there is no network or no freetype, then there is nothing we can do. Go straight to failure. */ #if defined(ENABLE_NETWORK) && defined(WITH_FREETYPE) && !defined(__APPLE__) && (defined(WITH_FONTCONFIG) || defined(WIN32)) if (!_network_available) goto failure; /* First tell the game we're bootstrapping. */ _game_mode = GM_BOOTSTRAP; /* Initialise the freetype font code. */ InitializeUnicodeGlyphMap(); /* Next "force" finding a suitable freetype font as the local font is missing. */ CheckForMissingGlyphs(false); /* Initialise the palette. The biggest step is 'faking' some recolour sprites. * This way the mauve and gray colours work and we can show the user interface. */ GfxInitPalettes(); static const int offsets[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x80, 0, 0, 0, 0x04, 0x08 }; for (uint i = 0; i != 16; i++) { for (int j = 0; j < 8; j++) { _colour_gradient[i][j] = offsets[i] + j; } } /* Finally ask the question. */ new BootstrapBackground(); new BootstrapAskForDownloadWindow(); /* Process the user events. */ _video_driver->MainLoop(); /* _exit_game is used to get out of the video driver's main loop. * In case GM_BOOTSTRAP is still set we did not exit it via the * "download complete" event, so it was a manual exit. Obey it. */ _exit_game = _game_mode == GM_BOOTSTRAP; if (_exit_game) return false; /* Try to probe the graphics. Should work this time. */ if (!BaseGraphics::SetSet(NULL)) goto failure; /* Finally we can continue heading for the menu. */ _game_mode = GM_MENU; return true; #endif /* Failure to get enough working to get a graphics set. */ failure: usererror("Failed to find a graphics set. Please acquire a graphics set for OpenTTD. See section 4.1 of readme.txt."); return false; }
/** Actually load the sprite tables. */ static void LoadSpriteTables() { memset(_palette_remap_grf, 0, sizeof(_palette_remap_grf)); uint i = FIRST_GRF_SLOT; const GraphicsSet *used_set = BaseGraphics::GetUsedSet(); _palette_remap_grf[i] = (PAL_DOS != used_set->palette); LoadGrfFile(used_set->files[GFT_BASE].filename, 0, i++); /* * The second basic file always starts at the given location and does * contain a different amount of sprites depending on the "type"; DOS * has a few sprites less. However, we do not care about those missing * sprites as they are not shown anyway (logos in intro game). */ _palette_remap_grf[i] = (PAL_DOS != used_set->palette); LoadGrfFile(used_set->files[GFT_LOGOS].filename, 4793, i++); /* * Load additional sprites for climates other than temperate. * This overwrites some of the temperate sprites, such as foundations * and the ground sprites. */ if (_settings_game.game_creation.landscape != LT_TEMPERATE) { _palette_remap_grf[i] = (PAL_DOS != used_set->palette); LoadGrfFileIndexed( used_set->files[GFT_ARCTIC + _settings_game.game_creation.landscape - 1].filename, _landscape_spriteindexes[_settings_game.game_creation.landscape - 1], i++ ); } /* Initialize the unicode to sprite mapping table */ InitializeUnicodeGlyphMap(); /* * Load the base NewGRF with OTTD required graphics as first NewGRF. * However, we do not want it to show up in the list of used NewGRFs, * so we have to manually add it, and then remove it later. */ GRFConfig *top = _grfconfig; GRFConfig *master = new GRFConfig(used_set->files[GFT_EXTRA].filename); /* We know the palette of the base set, so if the base NewGRF is not * setting one, use the palette of the base set and not the global * one which might be the wrong palette for this base NewGRF. * The value set here might be overridden via action14 later. */ switch (used_set->palette) { case PAL_DOS: master->palette |= GRFP_GRF_DOS; break; case PAL_WINDOWS: master->palette |= GRFP_GRF_WINDOWS; break; default: break; } FillGRFDetails(master, false, BASESET_DIR); ClrBit(master->flags, GCF_INIT_ONLY); master->next = top; _grfconfig = master; LoadNewGRF(SPR_NEWGRFS_BASE, i); /* Free and remove the top element. */ delete master; _grfconfig = top; }