1
0
Fork 0

Compare commits

...

3 Commits

Author SHA1 Message Date
Peter Nelson e683e2910e
Merge 944f791863 into a8650c6b06 2025-07-19 22:51:25 +00:00
Peter Nelson a8650c6b06
Codechange: Make SpriteCacheCtrlFlags an enum bit set. (#14462)
Due to header dependencies, this requires types to split from the spritecache header.
2025-07-19 23:49:15 +01:00
Charles Pigott 944f791863 Update: Changelog for 15.0-beta3 2025-07-17 07:20:01 +01:00
12 changed files with 171 additions and 33 deletions

View File

@ -1,5 +1,123 @@
## 15.x
### 15.0-beta3 (2025-07-17)
- Feature: New company face definition system and UI (#14319)
- Feature: Rework intro screen menu (#14220, #14233)
- Feature: Scrollbar for infrastructure window (#14056)
- Feature: Double-Ctrl+Click on default size box to clear saved size (#14055)
- Feature: Configure badges in build vehicle and picker windows (#13993, #14021)
- Feature: Player configuration of badge display (#13993, #14021)
- Feature: Merge Game Options and Game Settings together (#13242, #14088)
- Add: Buttons to change picker preview image height (#14373)
- Add: Show and sort online content version in list (#14355)
- Add: Allow separate expansion of town buildings and roads in scenario editor (#14341)
- Add: Hover on graph legend to highlight line (#14314)
- Add: [Script] Ability to clone ScriptList objects (#14305)
- Add: [NewGRF] All callbacks returning D0xx strings, have now the option to return any string id via register 0x100 (#14224)
- Add: [BaseSet] Allow basesets to set minor and patch versions in obg/obs/obm files (#14169)
- Add: "Many random towns" button in scenario editor now prompts for the number of towns, with defaults based on new game settings (#14158)
- Add: [NewGRF] Special value 0x7FFE for VarAction2 results specifying 'return calculated result' (#14149)
- Add: [NewGRF] Special value 0x7FFF for Action2 references specifying explicit 'callback/sprite-resolving failed' (#14149)
- Add: [NewGRF] Add purchase list Action3 CID for houses, industries, industry tiles, airports and airport tiles (#14121)
- Add: [NewGRF] Provide random bits in var10 of house callback 1C 'construction stage changed' (#14095)
- Add: [NewGRF] Station/roadstop animation-triggers 'tile loop' (bit 7) and 'path reservation' (bit 8) (#14080)
- Add: [Script] ScriptVehicleList_Waypoint (#13456)
- Change: Improve sprite ellipsis appearance (#14404)
- Change: [Script] Don't allow scripts to instantiate ScriptEvent (#14276)
- Change: [Script] ScriptVehicleList_Station accepts an optional VehicleType parameter (#14260)
- Change: Remove Apply button from NewGRF config window when unneeded (#14254)
- Change: [NewGRF] Increase the textstack for all callbacks to 16 registers (#14224)
- Change: Remove button to toggle showing advanced signal types (#14219)
- Change: [Script] Remove the limit of 20 parameters to a Text string (#14193)
- Change: [NewGRF] If Action123 does not resolve in a valid SpriteSet, prefer drawing the default sprite instead of an invalid sprite (#14143)
- Change: Remove extra close buttons from some windows (#14124)
- Change: Limit height of settings description, and add scrollbar (#14102)
- Change: [NewGRF] Provide shared random bits in multi-tile animation-triggers of airport tiles and objects, just like for other features (#14090)
- Change: [NewGRF] Animation-trigger 'construction stage changed' of houses and industries now also triggers at construction start (#14089)
- Change: "setting" console command now shows default value (#14061)
- Change: Include dragged train in depot tile length display (#14060)
- Change: Don't select content when toggling its download status (#14059)
- Change: Draw boolean settings toggles as a slider widget (#14051, #14071)
- Change: Don't replace stripped control codes with '?' for scripts (#14028)
- Change: [Script] Move GSStation::GetOwner to GSBaseStation::GetOwner (#13406)
- Fix #8167: No error sub-message when trying to clear protected buildings (#14444)
- Fix #14433: [NewGRF] Road tile for drive-through stops was not drawn (#14434)
- Fix: [Win32] Build failure with newer Windows SDK version due to WinRT changes (#14432)
- Fix #14396: Industry production graph showed zero when data was unavailable (#14416)
- Fix #14385: Crash in industry view due to incorrect string parameter calculations (#14413)
- Fix #14360: Stop reusing strings for Low/Medium/High setting values to improve translations (#14409)
- Fix #14377: Make house picker window remember house protection state when closed (#14406)
- Fix #14375: When loading config, validate timekeeping mode and minutes per year (#14405)
- Fix: Include sort button width in content list header minimal size (#14402)
- Fix: Don't draw truncation ellipsis if it's too wide (#14401)
- Fix: Don't include ellipsis width in RTL truncation offset (#14400)
- Fix: Buildings with non-zero subtile offsets broken in house picker (#14390)
- Fix: Allow object picker to resize if there are no classes (#14372)
- Fix #14081: Only allow "rm" & "del" console commands to remove savegames (#14371)
- Fix: Train path reservations on different railtypes could join leading to train crashes (#14366)
- Fix #14356: Incorrect sprite group chosen for stations and road stops (#14359)
- Fix: Wrong error message about script Save() returned value (#14334)
- Fix: Hidden-by-facility station signs were not ignored when handling clicks (#14326)
- Fix: [Script] SQOpsLimiter had no effect for native valuator/filter (#14322)
- Fix: Crash if loading compatibility scripts fails (#14318)
- Fix #14277: Aircraft could land when a zeppelin was on the runway (#14317)
- Fix: Drag drop line position when dragging NewGRF from file to active panel (#14316)
- Fix: Upgrade button in NewGRF window no longer worked (#14315)
- Fix: [NewGRF] Clear rail vehicle flipped flag if reverse probability callback returns false (#14281)
- Fix: [Script] Conversion from ScriptEvent to ScriptEventCompanyTown subclasses (#14274)
- Fix: Empty first parameter of EncodedString was skipped (#14273)
- Fix #14271: Crash due to incorrect parameter index in string (#14272)
- Fix: Restore the behaviour when entering numbers in query windows: clamp integers out of range to the maximum valid value (#14268)
- Fix: Replacing a dropdown list could reposition it partially off-screen (#14261)
- Fix: Click+Dragging of selected order was not possible (#14259)
- Fix #14256: Company finance windows not updated when paused (#14258)
- Fix: Incorrect tile colour in smallmap for snowy clear tiles in vegetation mode (#14257)
- Fix #14241: Invalid string parameters in subsidies list window (#14243)
- Fix #13854: 40bpp-anim blitter recolouring failed for 32bpp pixels without mask channel (#14242)
- Fix #14234: Crash due to broken invalid string parameter handling (#14235, #14236)
- Fix: Closing the Game Options window closes all textfile windows (#14210)
- Fix: Zoom-scroll extra viewports only if the mouse cursor is over the viewport (#14209)
- Fix: Changing monospace font didn't refresh the monospace width cache, causing wrapping issues (#14185)
- Fix: Crash/Undefined behaviour in station view window (#14183)
- Fix: Handle tab characters when loading GS strings from savegame (#14180)
- Fix: [Script] Access to enum/consts defined outside of main.nut (#14176)
- Fix: Small order list arrow was wrong direction for RTL text (#14174)
- Fix #14170: Missing spaces for timetabled order strings (#14172)
- Fix #14166: Loan was no longer invalidated when refreshing finance window (#14168)
- Fix #14098: Ability to play MIDI tracks over 7 minutes long (#14144)
- Fix: [NewGRF] AI station construction callback did not work for stations with ID >= 0x100 (#14142)
- Fix: Out-of-bounds read, if NewGRF stations provided no spritesets (#14140)
- Fix: [NewGRF] The result of Action123 evaluation affected rerandomisation in a weird corner case (#14139)
- Fix: [NewGRF] Computed VarAction2 callback results were not always properly masked to 15 bit results (#14138)
- Fix #14125: NewGRF sounds were not loaded (#14130)
- Fix: List Ctrl+Click behaviour for vehicle details tooltip (#14127)
- Fix: Road vehicle blocking and train collisions used slightly inconsistent distance thresholds (#14114)
- Fix #14107: Mark the company value in the company view window dirty when it changes (#14112)
- Fix #14107: Invalidate all shared vehicle windows when changing group (#14110)
- Fix #14104: Don't base timetable timing decisions on client settings (#14105)
- Fix: Focus settings filter box (only) when the tab becomes active (#14100)
- Fix: [Script] Reject scripts using negative version (#14096)
- Fix: Map size column in server list could be too wide (#14094)
- Fix: [NewGRF] Cargo-types for airport-tile animation-triggers were not properly translated (#14092)
- Fix: [NewGRF] For animation-triggers which do not supply a cargo-type in var18, the var18 bits should remain empty (#14091)
- Fix: Changing language or interface scale could hang (#14087)
- Fix: [NewGRF] For roadstop multi-tile-animation-triggers, the upper 16 bits were not the same for all tiles (#14084)
- Fix: Town view caption lost "(City)" flag (#14082)
- Fix: [NewGRF] Randomisation-trigger 'path reservation' did not work for waypoints (#14076)
- Fix: Incorrect test of object flags allowed HQ to be removed (#14062)
- Fix: Odd drawing and crash if scrollbar is not tall enough (#14052)
- Fix: Incorrect string display for autoreplace wagon removal status (#14038)
- Fix: House picker crashes if selection is not available (#14030)
- Fix: [NewGRF] PrepareLayout worked on a copy of the data resulting in bad sprite layouts (#14013)
- Fix: [NewGRF] Strange things happened, when using the synchronised tile loop animation trigger for houses (#14011)
- Fix: [NewGRF] Animation speed properties of houses and stations had wrong default (#14005)
- Fix: [NewGRF] Roadstop animation/randomisation was not triggered on vehicle arrival (#14003)
- Fix: Don't display badges if the class has no name (#13994)
- Fix #13954: Plotting graphs with limited data to the right (#13956)
- Fix: [Script] Make ScriptOrder functions aware of road waypoints (#13419)
- Fix: Scale graph gridlines and axes with GUI scale (#12131)
### 15.0-beta2 (2025-04-13)
- Feature: Snow-covered rocks are now visible (#13627)

View File

@ -454,6 +454,7 @@ add_files(
spritecache.cpp
spritecache.h
spritecache_internal.h
spritecache_type.h
station.cpp
station_base.h
station_cmd.cpp

View File

@ -535,7 +535,7 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty
struct GrfSpriteOffset {
size_t file_pos;
uint8_t control_flags;
SpriteCacheCtrlFlags control_flags{};
};
/** Map from sprite numbers to position in the GRF file. */
@ -565,7 +565,7 @@ void ReadGRFSpriteOffsets(SpriteFile &file)
size_t old_pos = file.GetPos();
file.SeekTo(data_offset, SEEK_CUR);
GrfSpriteOffset offset = { 0, 0 };
GrfSpriteOffset offset{0};
/* Loop over all sprite section entries and store the file
* offset for each newly encountered ID. */
@ -574,7 +574,6 @@ void ReadGRFSpriteOffsets(SpriteFile &file)
if (id != prev_id) {
_grf_sprite_offsets[prev_id] = offset;
offset.file_pos = file.GetPos() - 4;
offset.control_flags = 0;
}
prev_id = id;
uint length = file.ReadDword();
@ -585,11 +584,11 @@ void ReadGRFSpriteOffsets(SpriteFile &file)
uint8_t zoom = file.ReadByte();
length--;
if (colour.Any() && zoom == 0) { // ZoomLevel::Normal (normal zoom)
SetBit(offset.control_flags, (colour != SpriteComponent::Palette) ? SCCF_ALLOW_ZOOM_MIN_1X_32BPP : SCCF_ALLOW_ZOOM_MIN_1X_PAL);
SetBit(offset.control_flags, (colour != SpriteComponent::Palette) ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL);
offset.control_flags.Set((colour != SpriteComponent::Palette) ? SpriteCacheCtrlFlag::AllowZoomMin1x32bpp : SpriteCacheCtrlFlag::AllowZoomMin1xPal);
offset.control_flags.Set((colour != SpriteComponent::Palette) ? SpriteCacheCtrlFlag::AllowZoomMin2x32bpp : SpriteCacheCtrlFlag::AllowZoomMin2xPal);
}
if (colour.Any() && zoom == 2) { // ZoomLevel::In2x (2x zoomed in)
SetBit(offset.control_flags, (colour != SpriteComponent::Palette) ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL);
offset.control_flags.Set((colour != SpriteComponent::Palette) ? SpriteCacheCtrlFlag::AllowZoomMin2x32bpp : SpriteCacheCtrlFlag::AllowZoomMin2xPal);
}
}
}
@ -621,7 +620,7 @@ bool LoadNextSprite(SpriteID load_index, SpriteFile &file, uint file_sprite_id)
uint8_t grf_type = file.ReadByte();
SpriteType type;
uint8_t control_flags = 0;
SpriteCacheCtrlFlags control_flags;
if (grf_type == 0xFF) {
/* Some NewGRF files have "empty" pseudo-sprites which are 1
* byte long. Catch these so the sprites won't be displayed. */

View File

@ -11,24 +11,9 @@
#define SPRITECACHE_H
#include "gfx_type.h"
#include "spritecache_type.h"
#include "spriteloader/spriteloader.hpp"
/** Data structure describing a sprite. */
struct Sprite {
uint16_t height; ///< Height of the sprite.
uint16_t width; ///< Width of the sprite.
int16_t x_offs; ///< Number of pixels to shift the sprite to the right.
int16_t y_offs; ///< Number of pixels to shift the sprite downwards.
std::byte data[]; ///< Sprite data.
};
enum SpriteCacheCtrlFlags : uint8_t {
SCCF_ALLOW_ZOOM_MIN_1X_PAL = 0, ///< Allow use of sprite min zoom setting at 1x in palette mode.
SCCF_ALLOW_ZOOM_MIN_1X_32BPP = 1, ///< Allow use of sprite min zoom setting at 1x in 32bpp mode.
SCCF_ALLOW_ZOOM_MIN_2X_PAL = 2, ///< Allow use of sprite min zoom setting at 2x in palette mode.
SCCF_ALLOW_ZOOM_MIN_2X_32BPP = 3, ///< Allow use of sprite min zoom setting at 2x in 32bpp mode.
};
extern uint _sprite_cache_size;
/** SpriteAllocator that allocates memory via a unique_ptr array. */

View File

@ -12,6 +12,7 @@
#include "core/math_func.hpp"
#include "gfx_type.h"
#include "spritecache_type.h"
#include "spriteloader/spriteloader.hpp"
#include "table/sprites.h"
@ -27,7 +28,7 @@ struct SpriteCache {
uint32_t lru = 0;
SpriteType type = SpriteType::Invalid; ///< In some cases a single sprite is misused by two NewGRFs. Once as real sprite and once as recolour sprite. If the recolour sprite gets into the cache it might be drawn as real sprite which causes enormous trouble.
bool warned = false; ///< True iff the user has been warned about incorrect use of this sprite
uint8_t control_flags = 0; ///< Control flags, see SpriteCacheCtrlFlags
SpriteCacheCtrlFlags control_flags{}; ///< Control flags, see SpriteCacheCtrlFlags
void ClearSpriteData();
};

View File

@ -0,0 +1,33 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file spritecache_type.h Types related to the sprite cache. */
#ifndef SPRITECACHE_TYPE_H
#define SPRITECACHE_TYPE_H
#include "core/enum_type.hpp"
/** Data structure describing a sprite. */
struct Sprite {
uint16_t height; ///< Height of the sprite.
uint16_t width; ///< Width of the sprite.
int16_t x_offs; ///< Number of pixels to shift the sprite to the right.
int16_t y_offs; ///< Number of pixels to shift the sprite downwards.
std::byte data[]; ///< Sprite data.
};
enum class SpriteCacheCtrlFlag : uint8_t {
AllowZoomMin1xPal, ///< Allow use of sprite min zoom setting at 1x in palette mode.
AllowZoomMin1x32bpp, ///< Allow use of sprite min zoom setting at 1x in 32bpp mode.
AllowZoomMin2xPal, ///< Allow use of sprite min zoom setting at 2x in palette mode.
AllowZoomMin2x32bpp, ///< Allow use of sprite min zoom setting at 2x in 32bpp mode.
};
using SpriteCacheCtrlFlags = EnumBitSet<SpriteCacheCtrlFlag, uint8_t>;
#endif /* SPRITECACHE_TYPE_H */

View File

@ -256,7 +256,7 @@ static ZoomLevels LoadSpriteV1(SpriteLoader::SpriteCollection &sprite, SpriteFil
return {};
}
static ZoomLevels LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
static ZoomLevels LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
{
static const ZoomLevel zoom_lvl_map[6] = {ZoomLevel::Normal, ZoomLevel::In4x, ZoomLevel::In2x, ZoomLevel::Out2x, ZoomLevel::Out4x, ZoomLevel::Out8x};
@ -295,11 +295,11 @@ static ZoomLevels LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFil
is_wanted_zoom_lvl = true;
ZoomLevel zoom_min = sprite_type == SpriteType::Font ? ZoomLevel::Min : _settings_client.gui.sprite_zoom_min;
if (zoom_min >= ZoomLevel::In2x &&
HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL) && zoom_lvl < ZoomLevel::In2x) {
control_flags.Test(load_32bpp ? SpriteCacheCtrlFlag::AllowZoomMin2x32bpp : SpriteCacheCtrlFlag::AllowZoomMin2xPal) && zoom_lvl < ZoomLevel::In2x) {
is_wanted_zoom_lvl = false;
}
if (zoom_min >= ZoomLevel::Normal &&
HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_1X_32BPP : SCCF_ALLOW_ZOOM_MIN_1X_PAL) && zoom_lvl < ZoomLevel::Normal) {
control_flags.Test(load_32bpp ? SpriteCacheCtrlFlag::AllowZoomMin1x32bpp : SpriteCacheCtrlFlag::AllowZoomMin1xPal) && zoom_lvl < ZoomLevel::Normal) {
is_wanted_zoom_lvl = false;
}
} else {
@ -359,7 +359,7 @@ static ZoomLevels LoadSpriteV2(SpriteLoader::SpriteCollection &sprite, SpriteFil
return loaded_sprites;
}
ZoomLevels SpriteLoaderGrf::LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
ZoomLevels SpriteLoaderGrf::LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
{
if (this->container_ver >= 2) {
return LoadSpriteV2(sprite, file, file_pos, sprite_type, load_32bpp, control_flags, avail_8bpp, avail_32bpp);

View File

@ -17,7 +17,7 @@ class SpriteLoaderGrf : public SpriteLoader {
uint8_t container_ver;
public:
SpriteLoaderGrf(uint8_t container_ver) : container_ver(container_ver) {}
ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) override;
ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) override;
};
#endif /* SPRITELOADER_GRF_HPP */

View File

@ -48,7 +48,7 @@ static void Convert32bppTo8bpp(SpriteLoader::Sprite &sprite)
}
}
ZoomLevels SpriteLoaderMakeIndexed::LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
ZoomLevels SpriteLoaderMakeIndexed::LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp)
{
ZoomLevels avail = this->baseloader.LoadSprite(sprite, file, file_pos, sprite_type, true, control_flags, avail_8bpp, avail_32bpp);

View File

@ -17,7 +17,7 @@ class SpriteLoaderMakeIndexed : public SpriteLoader {
SpriteLoader &baseloader;
public:
SpriteLoaderMakeIndexed(SpriteLoader &baseloader) : baseloader(baseloader) {}
ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) override;
ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) override;
};
#endif /* SPRITELOADER_MAKEINDEXED_H */

View File

@ -13,6 +13,7 @@
#include "../core/alloc_type.hpp"
#include "../core/enum_type.hpp"
#include "../gfx_type.h"
#include "../spritecache_type.h"
#include "sprite_file_type.hpp"
struct Sprite;
@ -94,7 +95,7 @@ public:
* @param[out] avail_32bpp Available 32bpp sprites.
* @return Available sprites matching \a load_32bpp.
*/
virtual ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint8_t control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) = 0;
virtual ZoomLevels LoadSprite(SpriteLoader::SpriteCollection &sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, SpriteCacheCtrlFlags control_flags, ZoomLevels &avail_8bpp, ZoomLevels &avail_32bpp) = 0;
virtual ~SpriteLoader() = default;
};

View File

@ -33,7 +33,7 @@ static bool MockLoadNextSprite(SpriteID load_index)
sc->id = 0;
sc->type = is_mapgen ? SpriteType::MapGen : SpriteType::Normal;
sc->warned = false;
sc->control_flags = 0;
sc->control_flags = {};
/* Fill with empty sprites up until the default sprite count. */
return load_index < SPR_OPENTTD_BASE + OPENTTD_SPRITE_COUNT;