diff --git a/src/newgrf_airport.cpp b/src/newgrf_airport.cpp index 01b0e06662..0abb4a7cbc 100644 --- a/src/newgrf_airport.cpp +++ b/src/newgrf_airport.cpp @@ -258,7 +258,7 @@ AirportResolverObject::AirportResolverObject(TileIndex tile, Station *st, const SpriteID GetCustomAirportSprite(const AirportSpec *as, uint8_t layout) { AirportResolverObject object(INVALID_TILE, nullptr, as, layout); - const SpriteGroup *group = object.Resolve(); + const auto *group = object.Resolve(); if (group == nullptr || group->GetNumResults() == 0) return as->preview_sprite; return group->GetResult(); diff --git a/src/newgrf_airporttiles.cpp b/src/newgrf_airporttiles.cpp index f5815e3abf..2fe3cfe1bc 100644 --- a/src/newgrf_airporttiles.cpp +++ b/src/newgrf_airporttiles.cpp @@ -273,13 +273,12 @@ bool DrawNewAirportTile(TileInfo *ti, Station *st, const AirportTileSpec *airts) } AirportTileResolverObject object(airts, ti->tile, st); - const SpriteGroup *group = object.Resolve(); - if (group == nullptr || group->type != SGT_TILELAYOUT) { + const auto *group = object.Resolve(); + if (group == nullptr) { return false; } - const TileLayoutSpriteGroup *tlgroup = (const TileLayoutSpriteGroup *)group; - AirportDrawTileLayout(ti, tlgroup, Company::Get(st->owner)->colour); + AirportDrawTileLayout(ti, group, Company::Get(st->owner)->colour); return true; } diff --git a/src/newgrf_badge.cpp b/src/newgrf_badge.cpp index 36bb994d35..cebd3ecaa4 100644 --- a/src/newgrf_badge.cpp +++ b/src/newgrf_badge.cpp @@ -275,7 +275,7 @@ void ApplyBadgeFeaturesToClassBadges() PalSpriteID GetBadgeSprite(const Badge &badge, GrfSpecFeature feature, std::optional introduction_date, PaletteID remap) { BadgeResolverObject object(badge, feature, introduction_date); - const SpriteGroup *group = object.Resolve(); + const auto *group = object.Resolve(); if (group == nullptr || group->GetNumResults() == 0) return {0, PAL_NONE}; PaletteID pal = badge.flags.Test(BadgeFlag::UseCompanyColour) ? remap : PAL_NONE; diff --git a/src/newgrf_canal.cpp b/src/newgrf_canal.cpp index d228ee210d..f0b9a644d0 100644 --- a/src/newgrf_canal.cpp +++ b/src/newgrf_canal.cpp @@ -140,7 +140,7 @@ CanalResolverObject::CanalResolverObject(CanalFeature feature, TileIndex tile, SpriteID GetCanalSprite(CanalFeature feature, TileIndex tile) { CanalResolverObject object(feature, tile); - const SpriteGroup *group = object.Resolve(); + const auto *group = object.Resolve(); if (group == nullptr || group->GetNumResults() == 0) return 0; return group->GetResult(); diff --git a/src/newgrf_cargo.cpp b/src/newgrf_cargo.cpp index 2c581c26e9..38bdbeaf67 100644 --- a/src/newgrf_cargo.cpp +++ b/src/newgrf_cargo.cpp @@ -55,7 +55,7 @@ CargoResolverObject::CargoResolverObject(const CargoSpec *cs, CallbackID callbac SpriteID GetCustomCargoSprite(const CargoSpec *cs) { CargoResolverObject object(cs); - const SpriteGroup *group = object.Resolve(); + const auto *group = object.Resolve(); if (group == nullptr || group->GetNumResults() == 0) return 0; return group->GetResult(); diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 8ea7af4a34..ebbbc1c4b4 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -1101,7 +1101,7 @@ static void GetCustomEngineSprite(EngineID engine, const Vehicle *v, Direction d for (uint stack = 0; stack < max_stack; ++stack) { object.ResetState(); object.callback_param1 = image_type | (stack << 8); - const SpriteGroup *group = object.Resolve(); + const auto *group = object.Resolve(); uint32_t reg100 = sprite_stack ? GetRegister(0x100) : 0; if (group != nullptr && group->GetNumResults() != 0) { result->seq[result->count].sprite = group->GetResult() + (direction % group->GetNumResults()); @@ -1144,7 +1144,7 @@ static void GetRotorOverrideSprite(EngineID engine, const struct Aircraft *v, En for (uint stack = 0; stack < max_stack; ++stack) { object.ResetState(); object.callback_param1 = image_type | (stack << 8); - const SpriteGroup *group = object.Resolve(); + const auto *group = object.Resolve(); uint32_t reg100 = sprite_stack ? GetRegister(0x100) : 0; if (group != nullptr && group->GetNumResults() != 0) { result->seq[result->count].sprite = group->GetResult() + (rotor_pos % group->GetNumResults()); diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp index 9390dc2bd8..6ad8c0f3ad 100644 --- a/src/newgrf_house.cpp +++ b/src/newgrf_house.cpp @@ -505,12 +505,11 @@ void DrawNewHouseTile(TileInfo *ti, HouseID house_id) HouseResolverObject object(house_id, ti->tile, Town::GetByTile(ti->tile)); - const SpriteGroup *group = object.Resolve(); - if (group != nullptr && group->type == SGT_TILELAYOUT) { + const auto *group = object.Resolve(); + if (group != nullptr) { /* Limit the building stage to the number of stages supplied. */ - const TileLayoutSpriteGroup *tlgroup = (const TileLayoutSpriteGroup *)group; uint8_t stage = GetHouseBuildingStage(ti->tile); - DrawTileLayout(ti, tlgroup, stage, house_id); + DrawTileLayout(ti, group, stage, house_id); } } @@ -525,11 +524,11 @@ void DrawNewHouseTile(TileInfo *ti, HouseID house_id) void DrawNewHouseTileInGUI(int x, int y, const HouseSpec *spec, HouseID house_id, int view) { HouseResolverObject object(house_id, INVALID_TILE, nullptr, CBID_NO_CALLBACK, 0, 0, true, view); - const SpriteGroup *group = object.Resolve(); - if (group == nullptr || group->type != SGT_TILELAYOUT) return; + const auto *group = object.Resolve(); + if (group == nullptr) return; uint8_t stage = TOWN_HOUSE_COMPLETED; - const DrawTileSprites *dts = reinterpret_cast(group)->ProcessRegisters(&stage); + const DrawTileSprites *dts = group->ProcessRegisters(&stage); PaletteID palette = GetColourPalette(spec->random_colour[0]); if (spec->callback_mask.Test(HouseCallbackMask::Colour)) { diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index 9bf1b99ea7..3386af5ee6 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -629,9 +629,8 @@ void IndustryProductionCallback(Industry *ind, int reason) } SB(object.callback_param2, 8, 16, loop); - const SpriteGroup *tgroup = object.Resolve(); - if (tgroup == nullptr || tgroup->type != SGT_INDUSTRY_PRODUCTION) break; - const IndustryProductionSpriteGroup *group = (const IndustryProductionSpriteGroup *)tgroup; + const auto *group = object.Resolve(); + if (group == nullptr) break; if (group->version == 0xFF) { /* Result was marked invalid on load, display error message */ diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp index bd078ac977..c631080cc4 100644 --- a/src/newgrf_industrytiles.cpp +++ b/src/newgrf_industrytiles.cpp @@ -205,13 +205,12 @@ bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const Indus IndustryTileResolverObject object(gfx, ti->tile, i); - const SpriteGroup *group = object.Resolve(); - if (group == nullptr || group->type != SGT_TILELAYOUT) return false; + const auto *group = object.Resolve(); + if (group == nullptr) return false; /* Limit the building stage to the number of stages supplied. */ - const TileLayoutSpriteGroup *tlgroup = (const TileLayoutSpriteGroup *)group; uint8_t stage = GetIndustryConstructionStage(ti->tile); - IndustryDrawTileLayout(ti, tlgroup, i->random_colour, stage); + IndustryDrawTileLayout(ti, group, i->random_colour, stage); return true; } diff --git a/src/newgrf_object.cpp b/src/newgrf_object.cpp index ff059e33fb..b4c271e8c6 100644 --- a/src/newgrf_object.cpp +++ b/src/newgrf_object.cpp @@ -473,10 +473,10 @@ void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec) Object *o = Object::GetByTile(ti->tile); ObjectResolverObject object(spec, o, ti->tile); - const SpriteGroup *group = object.Resolve(); - if (group == nullptr || group->type != SGT_TILELAYOUT) return; + const auto *group = object.Resolve(); + if (group == nullptr) return; - DrawTileLayout(ti, (const TileLayoutSpriteGroup *)group, spec); + DrawTileLayout(ti, group, spec); } /** @@ -489,10 +489,10 @@ void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec) void DrawNewObjectTileInGUI(int x, int y, const ObjectSpec *spec, uint8_t view) { ObjectResolverObject object(spec, nullptr, INVALID_TILE, view); - const SpriteGroup *group = object.Resolve(); - if (group == nullptr || group->type != SGT_TILELAYOUT) return; + const auto *group = object.Resolve(); + if (group == nullptr) return; - const DrawTileSprites *dts = ((const TileLayoutSpriteGroup *)group)->ProcessRegisters(nullptr); + const DrawTileSprites *dts = group->ProcessRegisters(nullptr); PaletteID palette; if (Company::IsValidID(_local_company)) { diff --git a/src/newgrf_railtype.cpp b/src/newgrf_railtype.cpp index 89d06952ef..1555bd2472 100644 --- a/src/newgrf_railtype.cpp +++ b/src/newgrf_railtype.cpp @@ -110,7 +110,7 @@ SpriteID GetCustomRailSprite(const RailTypeInfo *rti, TileIndex tile, RailTypeSp if (rti->group[rtsg] == nullptr) return 0; RailTypeResolverObject object(rti, tile, context, rtsg); - const SpriteGroup *group = object.Resolve(); + const auto *group = object.Resolve(); if (group == nullptr || group->GetNumResults() == 0) return 0; if (num_results) *num_results = group->GetNumResults(); @@ -136,7 +136,7 @@ SpriteID GetCustomSignalSprite(const RailTypeInfo *rti, TileIndex tile, SignalTy uint32_t param2 = (type << 16) | (var << 8) | state; RailTypeResolverObject object(rti, tile, TCX_NORMAL, RTSG_SIGNALS, param1, param2); - const SpriteGroup *group = object.Resolve(); + const auto *group = object.Resolve(); if (group == nullptr || group->GetNumResults() == 0) return 0; return group->GetResult(); diff --git a/src/newgrf_roadstop.cpp b/src/newgrf_roadstop.cpp index 75fad616e9..05dec4f4bc 100644 --- a/src/newgrf_roadstop.cpp +++ b/src/newgrf_roadstop.cpp @@ -291,9 +291,9 @@ void DrawRoadStopTile(int x, int y, RoadType roadtype, const RoadStopSpec *spec, const RoadTypeInfo *rti = GetRoadTypeInfo(roadtype); RoadStopResolverObject object(spec, nullptr, INVALID_TILE, roadtype, type, view); - const SpriteGroup *group = object.Resolve(); - if (group == nullptr || group->type != SGT_TILELAYOUT) return; - const DrawTileSprites *dts = ((const TileLayoutSpriteGroup *)group)->ProcessRegisters(nullptr); + const auto *group = object.Resolve(); + if (group == nullptr) return; + const DrawTileSprites *dts = group->ProcessRegisters(nullptr); PaletteID palette = GetCompanyPalette(_local_company); @@ -346,9 +346,7 @@ void DrawRoadStopTile(int x, int y, RoadType roadtype, const RoadStopSpec *spec, const TileLayoutSpriteGroup *GetRoadStopLayout(TileInfo *ti, const RoadStopSpec *spec, BaseStation *st, StationType type, int view) { RoadStopResolverObject object(spec, st, ti->tile, INVALID_ROADTYPE, type, view); - const SpriteGroup *group = object.Resolve(); - if (group == nullptr || group->type != SGT_TILELAYOUT) return nullptr; - return static_cast(group); + return object.Resolve(); } /** Wrapper for animation control, see GetRoadStopCallback. */ diff --git a/src/newgrf_roadtype.cpp b/src/newgrf_roadtype.cpp index afd8fa05f3..a3c423f431 100644 --- a/src/newgrf_roadtype.cpp +++ b/src/newgrf_roadtype.cpp @@ -153,7 +153,7 @@ SpriteID GetCustomRoadSprite(const RoadTypeInfo *rti, TileIndex tile, RoadTypeSp if (rti->group[rtsg] == nullptr) return 0; RoadTypeResolverObject object(rti, tile, context, rtsg); - const SpriteGroup *group = object.Resolve(); + const auto *group = object.Resolve(); if (group == nullptr || group->GetNumResults() == 0) return 0; if (num_results) *num_results = group->GetNumResults(); diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h index 45a4abd00b..1c23f4cabd 100644 --- a/src/newgrf_spritegroup.h +++ b/src/newgrf_spritegroup.h @@ -223,6 +223,8 @@ struct CallbackResultSpriteGroup : SpriteGroup { /* A result sprite group returns the first SpriteID and the number of * sprites in the set */ struct ResultSpriteGroup : SpriteGroup { + static constexpr SpriteGroupType TYPE = SGT_RESULT; + /** * Creates a spritegroup representing a sprite number result. * @param sprite The sprite number. @@ -230,7 +232,7 @@ struct ResultSpriteGroup : SpriteGroup { * @return A spritegroup representing the sprite number result. */ ResultSpriteGroup(SpriteID sprite, uint8_t num_sprites) : - SpriteGroup(SGT_RESULT), + SpriteGroup(TYPE), num_sprites(num_sprites), sprite(sprite) { @@ -247,7 +249,9 @@ struct ResultSpriteGroup : SpriteGroup { * Action 2 sprite layout for houses, industry tiles, objects and airport tiles. */ struct TileLayoutSpriteGroup : SpriteGroup { - TileLayoutSpriteGroup() : SpriteGroup(SGT_TILELAYOUT) {} + static constexpr SpriteGroupType TYPE = SGT_TILELAYOUT; + + TileLayoutSpriteGroup() : SpriteGroup(TYPE) {} ~TileLayoutSpriteGroup() {} NewGRFSpriteLayout dts{}; @@ -256,7 +260,9 @@ struct TileLayoutSpriteGroup : SpriteGroup { }; struct IndustryProductionSpriteGroup : SpriteGroup { - IndustryProductionSpriteGroup() : SpriteGroup(SGT_INDUSTRY_PRODUCTION) {} + static constexpr SpriteGroupType TYPE = SGT_INDUSTRY_PRODUCTION; + + IndustryProductionSpriteGroup() : SpriteGroup(TYPE) {} uint8_t version = 0; ///< Production callback version used, or 0xFF if marked invalid uint8_t num_input = 0; ///< How many subtract_input values are valid @@ -310,6 +316,11 @@ struct ResolverObject { virtual ~ResolverObject() = default; + const SpriteGroup *DoResolve() + { + return SpriteGroup::Resolve(this->root_spritegroup, *this); + } + ScopeResolver default_scope; ///< Default implementation of the grf scope. CallbackID callback{}; ///< Callback being resolved. @@ -330,10 +341,14 @@ public: /** * Resolve SpriteGroup. * @return Result spritegroup. + * @tparam TSpriteGroup Sprite group type */ - const SpriteGroup *Resolve() + template + inline const TSpriteGroup *Resolve() { - return SpriteGroup::Resolve(this->root_spritegroup, *this); + auto result = this->DoResolve(); + if (result == nullptr || result->type != TSpriteGroup::TYPE) return nullptr; + return static_cast(result); } /** @@ -343,20 +358,20 @@ public: * - GetReseedSum: Bits to rerandomise for SELF scope, for features with broken-by-design PARENT randomisation. (all but industry tiles) * - GetUsedRandomTriggers: Consumed random triggers to be reset. */ - void ResolveRerandomisation() + inline void ResolveRerandomisation() { /* The Resolve result has no meaning. * It can be a SpriteSet, a callback result, or even an invalid SpriteGroup reference (nullptr). */ - this->Resolve(); + this->DoResolve(); } /** * Resolve callback. * @return Callback result. */ - uint16_t ResolveCallback() + inline uint16_t ResolveCallback() { - const SpriteGroup *result = this->Resolve(); + const SpriteGroup *result = this->DoResolve(); return result != nullptr ? result->GetCallbackResult() : CALLBACK_FAILED; } diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 524e73290c..d5c12a62df 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -640,7 +640,7 @@ StationResolverObject::StationResolverObject(const StationSpec *statspec, BaseSt SpriteID GetCustomStationRelocation(const StationSpec *statspec, BaseStation *st, TileIndex tile, uint32_t var10) { StationResolverObject object(statspec, st, tile, CBID_NO_CALLBACK, var10); - const SpriteGroup *group = object.Resolve(); + const auto *group = object.Resolve(); if (group == nullptr || group->GetNumResults() == 0) return 0; return group->GetResult() - SPR_RAIL_PLATFORM_Y_FRONT; } @@ -659,7 +659,7 @@ SpriteID GetCustomStationFoundationRelocation(const StationSpec *statspec, BaseS /* callback_param1 == 2 means we are resolving the foundation sprites. */ StationResolverObject object(statspec, st, tile, CBID_NO_CALLBACK, 2, layout | (edge_info << 16)); - const SpriteGroup *group = object.Resolve(); + const auto *group = object.Resolve(); /* Note: SpriteGroup::Resolve zeroes all registers, so register 0x100 is initialised to 0. (compatibility) */ auto offset = GetRegister(0x100); if (group == nullptr || group->GetNumResults() <= offset) return 0;