Index: src/gfxinit.cpp
===================================================================
--- src/gfxinit.cpp (revision 27730)
+++ src/gfxinit.cpp (working copy)
@@ -230,6 +230,14 @@
LoadNewGRF(SPR_NEWGRFS_BASE, i, 2);
+ uint total_extra_graphics = SPR_NEWGRFS_BASE - SPR_OPENTTD_BASE;
+ _missing_extra_graphics = GetSpriteCountForSlot(i, SPR_OPENTTD_BASE, SPR_NEWGRFS_BASE);
+ DEBUG(sprite, 1, "%u extra sprites, %u from baseset, %u from fallback", total_extra_graphics, total_extra_graphics - _missing_extra_graphics, _missing_extra_graphics);
+
+ /* The original baseset extra graphics intentionally make use of the fallback graphics.
+ * Let's say everything which provides less than 500 sprites misses the rest intentionally. */
+ if (500 + _missing_extra_graphics > total_extra_graphics) _missing_extra_graphics = 0;
+
/* Free and remove the top element. */
delete extra;
delete master;
Index: src/intro_gui.cpp
===================================================================
--- src/intro_gui.cpp (revision 27730)
+++ src/intro_gui.cpp (working copy)
@@ -60,13 +60,21 @@
virtual void OnInit()
{
- bool missing = _current_language->missing >= _settings_client.gui.missing_strings_threshold && !IsReleasedVersion();
- this->GetWidget<NWidgetStacked>(WID_SGI_TRANSLATION_SELECTION)->SetDisplayedPlane(missing ? 0 : SZSP_NONE);
+ bool missing_sprites = _missing_extra_graphics > 0 && !IsReleasedVersion();
+ this->GetWidget<NWidgetStacked>(WID_SGI_BASESET_SELECTION)->SetDisplayedPlane(missing_sprites ? 0 : SZSP_NONE);
+
+ bool missing_lang = _current_language->missing >= _settings_client.gui.missing_strings_threshold && !IsReleasedVersion();
+ this->GetWidget<NWidgetStacked>(WID_SGI_TRANSLATION_SELECTION)->SetDisplayedPlane(missing_lang ? 0 : SZSP_NONE);
}
virtual void DrawWidget(const Rect &r, int widget) const
{
switch (widget) {
+ case WID_SGI_BASESET:
+ SetDParam(0, _missing_extra_graphics);
+ DrawStringMultiLine(r.left, r.right, r.top, r.bottom, STR_INTRO_BASESET, TC_FROMSTRING, SA_CENTER);
+ break;
+
case WID_SGI_TRANSLATION:
SetDParam(0, _current_language->missing);
DrawStringMultiLine(r.left, r.right, r.top, r.bottom, STR_INTRO_TRANSLATION, TC_FROMSTRING, SA_CENTER);
@@ -76,20 +84,29 @@
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
{
+ StringID str = 0;
switch (widget) {
- case WID_SGI_TRANSLATION: {
+ case WID_SGI_BASESET:
+ SetDParam(0, _missing_extra_graphics);
+ str = STR_INTRO_BASESET;
+ break;
+
+ case WID_SGI_TRANSLATION:
SetDParam(0, _current_language->missing);
- int height = GetStringHeight(STR_INTRO_TRANSLATION, size->width);
- if (height > 3 * FONT_HEIGHT_NORMAL) {
- /* Don't let the window become too high. */
- Dimension textdim = GetStringBoundingBox(STR_INTRO_TRANSLATION);
- textdim.height *= 3;
- textdim.width -= textdim.width / 2;
- *size = maxdim(*size, textdim);
- } else {
- size->height = height + padding.height;
- }
+ str = STR_INTRO_TRANSLATION;
break;
+ }
+
+ if (str != 0) {
+ int height = GetStringHeight(str, size->width);
+ if (height > 3 * FONT_HEIGHT_NORMAL) {
+ /* Don't let the window become too high. */
+ Dimension textdim = GetStringBoundingBox(str);
+ textdim.height *= 3;
+ textdim.width -= textdim.width / 2;
+ *size = maxdim(*size, textdim);
+ } else {
+ size->height = height + padding.height;
}
}
}
@@ -199,6 +216,11 @@
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 7),
+ NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SGI_BASESET_SELECTION),
+ NWidget(NWID_VERTICAL),
+ NWidget(WWT_EMPTY, COLOUR_ORANGE, WID_SGI_BASESET), SetMinimalSize(316, 12), SetFill(1, 0), SetPadding(0, 10, 7, 10),
+ EndContainer(),
+ EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_SGI_TRANSLATION_SELECTION),
NWidget(NWID_VERTICAL),
NWidget(WWT_EMPTY, COLOUR_ORANGE, WID_SGI_TRANSLATION), SetMinimalSize(316, 12), SetFill(1, 0), SetPadding(0, 10, 7, 10),
Index: src/lang/english.txt
===================================================================
--- src/lang/english.txt (revision 27730)
+++ src/lang/english.txt (working copy)
@@ -1761,6 +1761,7 @@
STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Display AI/Game script settings
STR_INTRO_TOOLTIP_QUIT :{BLACK}Exit 'OpenTTD'
+STR_INTRO_BASESET :{BLACK}The currently selected base graphics set is missing {NUM} sprite{P "" s}. Please check for updates for the baseset.
STR_INTRO_TRANSLATION :{BLACK}This translation misses {NUM} string{P "" s}. Please help make OpenTTD better by signing up as translator. See readme.txt for details.
# Quit window
@@ -2907,8 +2908,6 @@
STR_NEWGRF_ERROR_CORRUPT_SPRITE :{YELLOW}{RAW_STRING} contains a corrupt sprite. All corrupt sprites will be shown as a red question mark (?)
STR_NEWGRF_ERROR_MULTIPLE_ACTION_8 :Contains multiple Action 8 entries (sprite {3:NUM})
STR_NEWGRF_ERROR_READ_BOUNDS :Read past end of pseudo-sprite (sprite {3:NUM})
-STR_NEWGRF_ERROR_MISSING_SPRITES :{WHITE}The currently used base graphics set is missing a number of sprites.{}Please update the base graphics set
-STR_NEWGRF_ERROR_MISSING_SPRITES_UNSTABLE :{WHITE}The currently used base graphics set is missing a number of sprites.{}Please update the base graphics set.{}Since you are playing a {YELLOW}development snapshot of OpenTTD{WHITE}, you might also need a {YELLOW}development snapshot of the base graphics{WHITE}
STR_NEWGRF_ERROR_GRM_FAILED :Requested GRF resources not available (sprite {3:NUM})
STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:RAW_STRING} was disabled by {2:RAW_STRING}
STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Invalid/unknown sprite layout format (sprite {3:NUM})
Index: src/newgrf.cpp
===================================================================
--- src/newgrf.cpp (revision 27730)
+++ src/newgrf.cpp (working copy)
@@ -5694,35 +5694,6 @@
}
/**
- * Check whether we are (obviously) missing some of the extra
- * (Action 0x05) sprites that we like to use.
- * When missing sprites are found a warning will be shown.
- */
-void CheckForMissingSprites()
-{
- /* Don't break out quickly, but allow to check the other
- * sprites as well, so we can give the best information. */
- bool missing = false;
- for (uint8 i = 0; i < lengthof(_action5_types); i++) {
- const Action5Type *type = &_action5_types[i];
- if (type->block_type == A5BLOCK_INVALID) continue;
-
- for (uint j = 0; j < type->max_sprites; j++) {
- if (!SpriteExists(type->sprite_base + j)) {
- DEBUG(grf, 0, "%s sprites are missing", type->name);
- missing = true;
- /* No need to log more of the same. */
- break;
- }
- }
- }
-
- if (missing) {
- ShowErrorMessage(IsReleasedVersion() ? STR_NEWGRF_ERROR_MISSING_SPRITES : STR_NEWGRF_ERROR_MISSING_SPRITES_UNSTABLE, INVALID_STRING_ID, WL_CRITICAL);
- }
-}
-
-/**
* Reads a variable common to VarAction2 and Action7/9/D.
*
* Returns VarAction2 variable 'param' resp. Action7/9/D variable '0x80 + param'.
Index: src/newgrf_config.cpp
===================================================================
--- src/newgrf_config.cpp (revision 27730)
+++ src/newgrf_config.cpp (working copy)
@@ -192,6 +192,7 @@
GRFConfig *_grfconfig;
GRFConfig *_grfconfig_newgame;
GRFConfig *_grfconfig_static;
+uint _missing_extra_graphics = 0;
/**
* Construct a new GRFError.
Index: src/newgrf_config.h
===================================================================
--- src/newgrf_config.h (revision 27730)
+++ src/newgrf_config.h (working copy)
@@ -202,6 +202,7 @@
extern GRFConfig *_grfconfig; ///< First item in list of current GRF set up
extern GRFConfig *_grfconfig_newgame; ///< First item in list of default GRF set up
extern GRFConfig *_grfconfig_static; ///< First item in list of static GRF set up
+extern uint _missing_extra_graphics; ///< Number of sprites provided by the fallback extra GRF, i.e. missing in the baseset.
/** Callback for NewGRF scanning. */
struct NewGRFScanCallback {
@@ -214,7 +215,6 @@
size_t GRFGetSizeOfDataSection(FILE *f);
void ScanNewGRFFiles(NewGRFScanCallback *callback);
-void CheckForMissingSprites();
const GRFConfig *FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const uint8 *md5sum = NULL, uint32 desired_version = 0);
GRFConfig *GetGRFConfig(uint32 grfid, uint32 mask = 0xFFFFFFFF);
GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src, bool init_only);
Index: src/openttd.cpp
===================================================================
--- src/openttd.cpp (revision 27730)
+++ src/openttd.cpp (working copy)
@@ -339,7 +339,6 @@
_pause_mode = PM_UNPAUSED;
_cursor.fix_at = false;
- if (load_newgrfs) CheckForMissingSprites();
CheckForMissingGlyphs();
/* Play main theme */
Index: src/script/api/game/game_window.hpp.sq
===================================================================
--- src/script/api/game/game_window.hpp.sq (revision 27730)
+++ src/script/api/game/game_window.hpp.sq (working copy)
@@ -582,6 +582,8 @@
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SGI_ARCTIC_LANDSCAPE, "WID_SGI_ARCTIC_LANDSCAPE");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SGI_TROPIC_LANDSCAPE, "WID_SGI_TROPIC_LANDSCAPE");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SGI_TOYLAND_LANDSCAPE, "WID_SGI_TOYLAND_LANDSCAPE");
+ SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SGI_BASESET_SELECTION, "WID_SGI_BASESET_SELECTION");
+ SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SGI_BASESET, "WID_SGI_BASESET");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SGI_TRANSLATION_SELECTION, "WID_SGI_TRANSLATION_SELECTION");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SGI_TRANSLATION, "WID_SGI_TRANSLATION");
SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SGI_OPTIONS, "WID_SGI_OPTIONS");
Index: src/script/api/script_window.hpp
===================================================================
--- src/script/api/script_window.hpp (revision 27730)
+++ src/script/api/script_window.hpp (working copy)
@@ -1497,8 +1497,10 @@
WID_SGI_ARCTIC_LANDSCAPE = ::WID_SGI_ARCTIC_LANDSCAPE, ///< Select arctic landscape button.
WID_SGI_TROPIC_LANDSCAPE = ::WID_SGI_TROPIC_LANDSCAPE, ///< Select tropic landscape button.
WID_SGI_TOYLAND_LANDSCAPE = ::WID_SGI_TOYLAND_LANDSCAPE, ///< Select toyland landscape button.
+ WID_SGI_BASESET_SELECTION = ::WID_SGI_BASESET_SELECTION, ///< Baseset selection.
+ WID_SGI_BASESET = ::WID_SGI_BASESET, ///< Baseset errors.
WID_SGI_TRANSLATION_SELECTION = ::WID_SGI_TRANSLATION_SELECTION, ///< Translation selection.
- WID_SGI_TRANSLATION = ::WID_SGI_TRANSLATION, ///< Translation.
+ WID_SGI_TRANSLATION = ::WID_SGI_TRANSLATION, ///< Translation errors.
WID_SGI_OPTIONS = ::WID_SGI_OPTIONS, ///< Options button.
WID_SGI_HIGHSCORE = ::WID_SGI_HIGHSCORE, ///< Highscore button.
WID_SGI_SETTINGS_OPTIONS = ::WID_SGI_SETTINGS_OPTIONS, ///< Settings button.
Index: src/spritecache.cpp
===================================================================
--- src/spritecache.cpp (revision 27730)
+++ src/spritecache.cpp (working copy)
@@ -150,6 +150,25 @@
}
/**
+ * Count the sprites which originate from a specific file slot in a range of SpriteIDs.
+ * @param file_slot FIOS file slot.
+ * @param begin First sprite in range.
+ * @param end First sprite not in range.
+ * @return Number of sprites.
+ */
+uint GetSpriteCountForSlot(uint file_slot, SpriteID begin, SpriteID end)
+{
+ uint count = 0;
+ for (SpriteID i = begin; i != end; i++) {
+ if (SpriteExists(i)) {
+ SpriteCache *sc = GetSpriteCache(i);
+ if (sc->file_slot == file_slot) count++;
+ }
+ }
+ return count;
+}
+
+/**
* Get a reasonable (upper bound) estimate of the maximum
* SpriteID used in OpenTTD; there will be no sprites with
* a higher SpriteID, although there might be up to roughly
Index: src/spritecache.h
===================================================================
--- src/spritecache.h (revision 27730)
+++ src/spritecache.h (working copy)
@@ -32,6 +32,7 @@
SpriteType GetSpriteType(SpriteID sprite);
uint GetOriginFileSlot(SpriteID sprite);
+uint GetSpriteCountForSlot(uint file_slot, SpriteID begin, SpriteID end);
uint GetMaxSpriteID();
Index: src/widgets/intro_widget.h
===================================================================
--- src/widgets/intro_widget.h (revision 27730)
+++ src/widgets/intro_widget.h (working copy)
@@ -24,8 +24,10 @@
WID_SGI_ARCTIC_LANDSCAPE, ///< Select arctic landscape button.
WID_SGI_TROPIC_LANDSCAPE, ///< Select tropic landscape button.
WID_SGI_TOYLAND_LANDSCAPE, ///< Select toyland landscape button.
+ WID_SGI_BASESET_SELECTION, ///< Baseset selection.
+ WID_SGI_BASESET, ///< Baseset errors.
WID_SGI_TRANSLATION_SELECTION, ///< Translation selection.
- WID_SGI_TRANSLATION, ///< Translation.
+ WID_SGI_TRANSLATION, ///< Translation errors.
WID_SGI_OPTIONS, ///< Options button.
WID_SGI_HIGHSCORE, ///< Highscore button.
WID_SGI_SETTINGS_OPTIONS, ///< Settings button.