From 438495b433f5b4d3ce81f8efc7d655d2337582fe Mon Sep 17 00:00:00 2001 From: alberth Date: Sat, 10 Nov 2012 20:37:31 +0000 Subject: [PATCH] (svn r24678) -Codechange: Introduce scope resolver base class and prepare for adding derived classes. --- src/newgrf_airport.cpp | 2 +- src/newgrf_airporttiles.cpp | 2 +- src/newgrf_canal.cpp | 2 +- src/newgrf_cargo.cpp | 2 +- src/newgrf_debug_gui.cpp | 2 +- src/newgrf_engine.cpp | 4 +- src/newgrf_generic.cpp | 2 +- src/newgrf_house.cpp | 2 +- src/newgrf_industries.cpp | 2 +- src/newgrf_industrytiles.cpp | 2 +- src/newgrf_object.cpp | 2 +- src/newgrf_railtype.cpp | 2 +- src/newgrf_spritegroup.cpp | 136 +++++++++++++++++++++++++++++++---- src/newgrf_spritegroup.h | 38 +++++++++- src/newgrf_station.cpp | 2 +- 15 files changed, 173 insertions(+), 29 deletions(-) diff --git a/src/newgrf_airport.cpp b/src/newgrf_airport.cpp index 2ece7cf0f1..e373e2ab57 100644 --- a/src/newgrf_airport.cpp +++ b/src/newgrf_airport.cpp @@ -217,7 +217,7 @@ static void NewAirportResolver(ResolverObject *res, TileIndex tile, Station *st, res->GetTriggers = AirportGetTriggers; res->SetTriggers = AirportSetTriggers; res->GetVariable = AirportGetVariable; - res->ResolveReal = AirportResolveReal; + res->ResolveRealMethod = AirportResolveReal; res->StorePSA = AirportStorePSA; res->u.airport.st = st; diff --git a/src/newgrf_airporttiles.cpp b/src/newgrf_airporttiles.cpp index 86840062d9..0c326920fb 100644 --- a/src/newgrf_airporttiles.cpp +++ b/src/newgrf_airporttiles.cpp @@ -226,7 +226,7 @@ static void AirportTileResolver(ResolverObject *res, const AirportTileSpec *ats, res->GetTriggers = NULL; res->SetTriggers = NULL; res->GetVariable = AirportTileGetVariable; - res->ResolveReal = AirportTileResolveReal; + res->ResolveRealMethod = AirportTileResolveReal; res->StorePSA = NULL; assert(st != NULL); diff --git a/src/newgrf_canal.cpp b/src/newgrf_canal.cpp index cea1cdbcef..135dce82c7 100644 --- a/src/newgrf_canal.cpp +++ b/src/newgrf_canal.cpp @@ -82,7 +82,7 @@ static void NewCanalResolver(ResolverObject *res, TileIndex tile, const GRFFile res->GetTriggers = &CanalGetTriggers; res->SetTriggers = &CanalSetTriggers; res->GetVariable = &CanalGetVariable; - res->ResolveReal = &CanalResolveReal; + res->ResolveRealMethod = &CanalResolveReal; res->u.canal.tile = tile; diff --git a/src/newgrf_cargo.cpp b/src/newgrf_cargo.cpp index 0c48273cca..1755af257f 100644 --- a/src/newgrf_cargo.cpp +++ b/src/newgrf_cargo.cpp @@ -57,7 +57,7 @@ static void NewCargoResolver(ResolverObject *res, const CargoSpec *cs) res->GetTriggers = &CargoGetTriggers; res->SetTriggers = &CargoSetTriggers; res->GetVariable = &CargoGetVariable; - res->ResolveReal = &CargoResolveReal; + res->ResolveRealMethod = &CargoResolveReal; res->u.cargo.cs = cs; diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index 1547671944..dbc9247f55 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.cpp @@ -162,7 +162,7 @@ public: ResolverObject ro; memset(&ro, 0, sizeof(ro)); this->Resolve(&ro, index); - return ro.GetVariable(&ro, var, param, avail); + return ro.GetScope(ro.scope)->GetVariable(var, param, avail); } /** diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 657adce3ee..373f7dd096 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.cpp @@ -938,7 +938,7 @@ static inline void NewVehicleResolver(ResolverObject *res, EngineID engine_type, res->GetTriggers = &VehicleGetTriggers; res->SetTriggers = &VehicleSetTriggers; res->GetVariable = &VehicleGetVariable; - res->ResolveReal = &VehicleResolveReal; + res->ResolveRealMethod = &VehicleResolveReal; res->u.vehicle.self = v; res->u.vehicle.parent = (v != NULL) ? v->First() : v; @@ -1330,7 +1330,7 @@ void FillNewGRFVehicleCache(const Vehicle *v) /* Only resolve when the cache isn't valid. */ if (HasBit(v->grf_cache.cache_valid, cache_entries[i][1])) continue; bool stub; - ro.GetVariable(&ro, cache_entries[i][0], 0, &stub); + ro.GetScope(ro.scope)->GetVariable(cache_entries[i][0], 0, &stub); } /* Make sure really all bits are set. */ diff --git a/src/newgrf_generic.cpp b/src/newgrf_generic.cpp index 6e2692899c..d53e7b7ce0 100644 --- a/src/newgrf_generic.cpp +++ b/src/newgrf_generic.cpp @@ -130,7 +130,7 @@ static inline void NewGenericResolver(ResolverObject *res, bool ai_callback) res->GetTriggers = &GenericCallbackGetTriggers; res->SetTriggers = &GenericCallbackSetTriggers; res->GetVariable = ai_callback ? &GenericAiCallbackGetVariable : &GenericCallbackGetVariable; - res->ResolveReal = &GenericCallbackResolveReal; + res->ResolveRealMethod = &GenericCallbackResolveReal; res->callback = CBID_NO_CALLBACK; res->callback_param1 = 0; diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp index 08f198c62b..a8f6578460 100644 --- a/src/newgrf_house.cpp +++ b/src/newgrf_house.cpp @@ -423,7 +423,7 @@ static void NewHouseResolver(ResolverObject *res, HouseID house_id, TileIndex ti res->GetTriggers = HouseGetTriggers; res->SetTriggers = HouseSetTriggers; res->GetVariable = HouseGetVariable; - res->ResolveReal = HouseResolveReal; + res->ResolveRealMethod = HouseResolveReal; res->StorePSA = HouseStorePSA; res->u.house.tile = tile; diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index aeba91f7f7..45c43c55b0 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -410,7 +410,7 @@ static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *i res->GetTriggers = IndustryGetTriggers; res->SetTriggers = IndustrySetTriggers; res->GetVariable = IndustryGetVariable; - res->ResolveReal = IndustryResolveReal; + res->ResolveRealMethod = IndustryResolveReal; res->StorePSA = IndustryStorePSA; res->u.industry.tile = tile; diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp index 1e9db96050..dcb96c48a8 100644 --- a/src/newgrf_industrytiles.cpp +++ b/src/newgrf_industrytiles.cpp @@ -176,7 +176,7 @@ static void NewIndustryTileResolver(ResolverObject *res, IndustryGfx gfx, TileIn res->GetTriggers = IndustryTileGetTriggers; res->SetTriggers = IndustryTileSetTriggers; res->GetVariable = IndustryTileGetVariable; - res->ResolveReal = IndustryTileResolveReal; + res->ResolveRealMethod = IndustryTileResolveReal; res->StorePSA = IndustryTileStorePSA; res->u.industry.tile = tile; diff --git a/src/newgrf_object.cpp b/src/newgrf_object.cpp index 19507c326d..ab4ac147e0 100644 --- a/src/newgrf_object.cpp +++ b/src/newgrf_object.cpp @@ -398,7 +398,7 @@ static void NewObjectResolver(ResolverObject *res, const ObjectSpec *spec, Objec res->GetTriggers = ObjectGetTriggers; res->SetTriggers = ObjectSetTriggers; res->GetVariable = ObjectGetVariable; - res->ResolveReal = ObjectResolveReal; + res->ResolveRealMethod = ObjectResolveReal; res->StorePSA = ObjectStorePSA; res->u.object.o = o; diff --git a/src/newgrf_railtype.cpp b/src/newgrf_railtype.cpp index 5f4c3d921d..73784c93ca 100644 --- a/src/newgrf_railtype.cpp +++ b/src/newgrf_railtype.cpp @@ -83,7 +83,7 @@ static inline void NewRailTypeResolver(ResolverObject *res, TileIndex tile, Tile res->GetTriggers = &RailTypeGetTriggers; res->SetTriggers = &RailTypeSetTriggers; res->GetVariable = &RailTypeGetVariable; - res->ResolveReal = &RailTypeResolveReal; + res->ResolveRealMethod = &RailTypeResolveReal; res->u.routes.tile = tile; res->u.routes.context = context; diff --git a/src/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp index 711b261099..75bd30337c 100644 --- a/src/newgrf_spritegroup.cpp +++ b/src/newgrf_spritegroup.cpp @@ -10,6 +10,7 @@ /** @file newgrf_spritegroup.cpp Handling of primarily NewGRF action 2. */ #include "stdafx.h" +#include "debug.h" #include "newgrf_spritegroup.h" #include "core/pool_func.hpp" @@ -36,7 +37,7 @@ RandomizedSpriteGroup::~RandomizedSpriteGroup() TemporaryStorageArray _temp_store; -static inline uint32 GetVariable(const ResolverObject *object, byte variable, uint32 parameter, bool *available) +static inline uint32 GetVariable(const ResolverObject *object, ScopeResolver *scope, byte variable, uint32 parameter, bool *available) { /* First handle variables common with Action7/9/D */ uint32 value; @@ -49,7 +50,7 @@ static inline uint32 GetVariable(const ResolverObject *object, byte variable, ui case 0x18: return object->callback_param2; case 0x1C: return object->last_value; - case 0x5F: return (object->GetRandomBits(object) << 8) | object->GetTriggers(object); + case 0x5F: return (scope->GetRandomBits() << 8) | scope->GetTriggers(); case 0x7D: return _temp_store.GetValue(parameter); @@ -58,10 +59,119 @@ static inline uint32 GetVariable(const ResolverObject *object, byte variable, ui return object->grffile->GetParam(parameter); /* Not a common variable, so evalute the feature specific variables */ - default: return object->GetVariable(object, variable, parameter, available); + default: return scope->GetVariable(variable, parameter, available); } } +ScopeResolver::ScopeResolver(ResolverObject *ro) +{ + this->ro = ro; +} + +ScopeResolver::~ScopeResolver() {} + +/** + * Get a few random bits. Default implementation has no random bits. + * @return Random bits. + */ +/* virtual */ uint32 ScopeResolver::GetRandomBits() const +{ + return 0; +} + +/** + * Get the triggers. Base class returns \c 0 to prevent trouble. + * @return The triggers. + */ +/* virtual */ uint32 ScopeResolver::GetTriggers() const +{ + return 0; +} + +/** + * Set the triggers. Base class implementation does nothing. + * @param triggers Triggers to set. + */ +/* virtual */ void ScopeResolver::SetTriggers(int triggers) const {} + +/** + * Get a variable value. Default implementation has no available variables. + * @param variable Variable to read + * @param parameter Parameter for 60+x variables + * @param[out] available Set to false, in case the variable does not exist. + * @return Value + */ +/* virtual */ uint32 ScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const +{ + DEBUG(grf, 1, "Unhandled scope variable 0x%X", variable); + *available = false; + return UINT_MAX; +} + +/** + * Store a value into the persistent storage area (PSA). Default implementation does nothing (for newgrf classes without storage). + * @param pos Position to store into. + * @param value Value to store. + */ +/* virtual */ void ScopeResolver::StorePSA(uint reg, int32 value) {} + + +TempScopeResolver::TempScopeResolver(ResolverObject *ro) : ScopeResolver(ro) {} + +/* virtual */ uint32 TempScopeResolver::GetRandomBits() const +{ + return this->ro->GetRandomBits(this->ro); +} + +/* virtual */ uint32 TempScopeResolver::GetTriggers() const +{ + return this->ro->GetTriggers(this->ro); +} + +/* virtual */ void TempScopeResolver::SetTriggers(int triggers) const +{ + this->ro->SetTriggers(this->ro, triggers); +} + +/* virtual */ uint32 TempScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const +{ + return this->ro->GetVariable(this->ro, variable, parameter, available); +} + +/* virtual */ void TempScopeResolver::StorePSA(uint reg, int32 value) +{ + if (this->ro->StorePSA != NULL) this->ro->StorePSA(this->ro, reg, value); +} + +ResolverObject::ResolverObject() : temp_scope(this) {} // XXX Temporary + +ResolverObject::ResolverObject(const GRFFile *grffile, CallbackID callback, uint32 callback_param1, uint32 callback_param2) : temp_scope(this) +{ + this->callback = callback; + this->callback_param1 = callback_param1; + this->callback_param2 = callback_param2; + this->ResetState(); + + this->grffile = grffile; +} + +ResolverObject::~ResolverObject() {} + +/* virtual */ const SpriteGroup *ResolverObject::ResolveReal(const RealSpriteGroup *group) const +{ + return this->ResolveRealMethod(this, group); +} + +/** + * Get a specific ScopeResolver. + * @param scope Scope to return. + * @param relative Additional parameter for #VSG_SCOPE_RELATIVE. + * @return ScopeResolver. + */ +/* virtual */ ScopeResolver *ResolverObject::GetScope(VarSpriteGroupScope scope, byte relative) +{ + return &this->temp_scope; +} /** * Rotate val rot times to the right @@ -111,7 +221,7 @@ static U EvalAdjustT(const DeterministicSpriteGroupAdjust *adjust, ResolverObjec case DSGA_OP_XOR: return last_value ^ value; case DSGA_OP_STO: _temp_store.StoreValue((U)value, (S)last_value); return last_value; case DSGA_OP_RST: return value; - case DSGA_OP_STOP: if (object->StorePSA != NULL) object->StorePSA(object, (U)value, (S)last_value); return last_value; + case DSGA_OP_STOP: object->GetScope(object->scope)->StorePSA((U)value, (S)last_value); return last_value; case DSGA_OP_ROR: return RotateRight(last_value, value); case DSGA_OP_SCMP: return ((S)last_value == (S)value) ? 1 : ((S)last_value < (S)value ? 0 : 2); case DSGA_OP_UCMP: return ((U)last_value == (U)value) ? 1 : ((U)last_value < (U)value ? 0 : 2); @@ -148,9 +258,9 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject *object) con * Note: 'last_value' and 'reseed' are shared between the main chain and the procedure */ object->scope = this->var_scope; } else if (adjust->variable == 0x7B) { - value = GetVariable(object, adjust->parameter, last_value, &available); + value = GetVariable(object, object->GetScope(this->var_scope), adjust->parameter, last_value, &available); } else { - value = GetVariable(object, adjust->variable, adjust->parameter, &available); + value = GetVariable(object, object->GetScope(this->var_scope), adjust->variable, adjust->parameter, &available); } if (!available) { @@ -190,16 +300,14 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject *object) con const SpriteGroup *RandomizedSpriteGroup::Resolve(ResolverObject *object) const { - uint32 mask; - byte index; - object->scope = this->var_scope; object->count = this->count; + ScopeResolver *scope = object->GetScope(this->var_scope, this->count); if (object->trigger != 0) { /* Handle triggers */ /* Magic code that may or may not do the right things... */ - byte waiting_triggers = object->GetTriggers(object); + byte waiting_triggers = scope->GetTriggers(); byte match = this->triggers & (waiting_triggers | object->trigger); bool res = (this->cmp_mode == RSG_CMP_ANY) ? (match != 0) : (match == this->triggers); @@ -210,11 +318,11 @@ const SpriteGroup *RandomizedSpriteGroup::Resolve(ResolverObject *object) const waiting_triggers |= object->trigger; } - object->SetTriggers(object, waiting_triggers); + scope->SetTriggers(waiting_triggers); } - mask = (this->num_groups - 1) << this->lowest_randbit; - index = (object->GetRandomBits(object) & mask) >> this->lowest_randbit; + uint32 mask = (this->num_groups - 1) << this->lowest_randbit; + byte index = (scope->GetRandomBits() & mask) >> this->lowest_randbit; return SpriteGroup::Resolve(this->groups[index], object); } @@ -222,7 +330,7 @@ const SpriteGroup *RandomizedSpriteGroup::Resolve(ResolverObject *object) const const SpriteGroup *RealSpriteGroup::Resolve(ResolverObject *object) const { - return object->ResolveReal(object, this); + return object->ResolveReal(this); } /** diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h index 12b51c05df..c709016229 100644 --- a/src/newgrf_spritegroup.h +++ b/src/newgrf_spritegroup.h @@ -301,8 +301,40 @@ struct IndustryProductionSpriteGroup : SpriteGroup { uint8 again; }; +struct ResolverObject; + +struct ScopeResolver { + ResolverObject *ro; + + ScopeResolver(ResolverObject *ro); + virtual ~ScopeResolver(); + + virtual uint32 GetRandomBits() const; + virtual uint32 GetTriggers() const; + virtual void SetTriggers(int triggers) const; + + virtual uint32 GetVariable(byte variable, uint32 parameter, bool *available) const; + virtual void StorePSA(uint reg, int32 value); +}; + +struct TempScopeResolver : public ScopeResolver { + TempScopeResolver(ResolverObject *ro); + + virtual uint32 GetRandomBits() const; + virtual uint32 GetTriggers() const; + virtual void SetTriggers(int triggers) const; + + virtual uint32 GetVariable(byte variable, uint32 parameter, bool *available) const; + virtual void StorePSA(uint reg, int32 value); +}; struct ResolverObject { + ResolverObject(); + ResolverObject(const GRFFile *grffile, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0); + virtual ~ResolverObject(); + + TempScopeResolver temp_scope; ///< Temporary scope resolver to refer back to the methods of #ResolverObject. + CallbackID callback; uint32 callback_param1; uint32 callback_param2; @@ -382,9 +414,13 @@ struct ResolverObject { uint32 (*GetTriggers)(const struct ResolverObject*); void (*SetTriggers)(const struct ResolverObject*, int); uint32 (*GetVariable)(const struct ResolverObject *object, byte variable, uint32 parameter, bool *available); - const SpriteGroup *(*ResolveReal)(const struct ResolverObject*, const RealSpriteGroup*); + const SpriteGroup *(*ResolveRealMethod)(const struct ResolverObject*, const RealSpriteGroup*); void (*StorePSA)(struct ResolverObject*, uint, int32); + virtual const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const; + + virtual ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0); + /** * Returns the OR-sum of all bits that need reseeding * independent of the scope they were accessed with. diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 08f8e79328..bbeb3dbb53 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -550,7 +550,7 @@ static void NewStationResolver(ResolverObject *res, const StationSpec *statspec, res->GetTriggers = StationGetTriggers; res->SetTriggers = StationSetTriggers; res->GetVariable = StationGetVariable; - res->ResolveReal = StationResolveReal; + res->ResolveRealMethod = StationResolveReal; res->StorePSA = StationStorePSA; res->u.station.st = st;