# newgrf_spritegroup.h

Go to the documentation of this file.

    00001 /* $Id$ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * 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.
    00006  * 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.
    00007  * 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/>.
    00008  */
    00009
    00012 #ifndef NEWGRF_SPRITEGROUP_H
    00013 #define NEWGRF_SPRITEGROUP_H
    00014
    00015 #include "town_type.h"
    00016 #include "engine_type.h"
    00017 #include "house_type.h"
    00018
    00019 #include "newgrf_callbacks.h"
    00020 #include "newgrf_generic.h"
    00021 #include "newgrf_storage.h"
    00022 #include "newgrf_commons.h"
    00023
    00030 static inline uint32 GetRegister(uint i)
    00031 {
    00032   extern TemporaryStorageArray<int32, 0x110> _temp_store;
    00033   return _temp_store.GetValue(i);
    00034 }
    00035
    00041 static inline void ClearRegister(uint i)
    00042 {
    00043   extern TemporaryStorageArray<int32, 0x110> _temp_store;
    00044   _temp_store.StoreValue(i, 0);
    00045 }
    00046
    00047 /* List of different sprite group types */
    00048 enum SpriteGroupType {
    00049   SGT_REAL,
    00050   SGT_DETERMINISTIC,
    00051   SGT_RANDOMIZED,
    00052   SGT_CALLBACK,
    00053   SGT_RESULT,
    00054   SGT_TILELAYOUT,
    00055   SGT_INDUSTRY_PRODUCTION,
    00056 };
    00057
    00058 struct SpriteGroup;
    00059 typedef uint32 SpriteGroupID;
    00060
    00061 /* SPRITE_WIDTH is 24. ECS has roughly 30 sprite groups per real sprite.
    00062  * Adding an 'extra' margin would be assuming 64 sprite groups per real
    00063  * sprite. 64 = 2^6, so 2^30 should be enough (for now) */
    00064 typedef Pool<SpriteGroup, SpriteGroupID, 1024, 1 << 30, PT_DATA> SpriteGroupPool;
    00065 extern SpriteGroupPool _spritegroup_pool;
    00066
    00067 /* Common wrapper for all the different sprite group types */
    00068 struct SpriteGroup : SpriteGroupPool::PoolItem<&_spritegroup_pool> {
    00069 protected:
    00070   SpriteGroup(SpriteGroupType type) : type(type) {}
    00072   virtual const SpriteGroup *Resolve(struct ResolverObject *object) const { return this; };
    00073
    00074 public:
    00075   virtual ~SpriteGroup() {}
    00076
    00077   SpriteGroupType type;
    00078
    00079   virtual SpriteID GetResult() const { return 0; }
    00080   virtual byte GetNumResults() const { return 0; }
    00081   virtual uint16 GetCallbackResult() const { return CALLBACK_FAILED; }
    00082
    00092   static const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject *object)
    00093   {
    00094     return group == NULL ? NULL : group->Resolve(object);
    00095   }
    00096 };
    00097
    00098
    00099 /* 'Real' sprite groups contain a list of other result or callback sprite
    00100  * groups. */
    00101 struct RealSpriteGroup : SpriteGroup {
    00102   RealSpriteGroup() : SpriteGroup(SGT_REAL) {}
    00103   ~RealSpriteGroup();
    00104
    00105   /* Loaded = in motion, loading = not moving
    00106    * Each group contains several spritesets, for various loading stages */
    00107
    00108   /* XXX: For stations the meaning is different - loaded is for stations
    00109    * with small amount of cargo whilst loading is for stations with a lot
    00110    * of da stuff. */
    00111
    00112   byte num_loaded;
    00113   byte num_loading;
    00114   const SpriteGroup **loaded;
    00115   const SpriteGroup **loading;
    00116
    00117 protected:
    00118   const SpriteGroup *Resolve(ResolverObject *object) const;
    00119 };
    00120
    00121 /* Shared by deterministic and random groups. */
    00122 enum VarSpriteGroupScope {
    00123   VSG_BEGIN,
    00124
    00125   VSG_SCOPE_SELF = VSG_BEGIN,
    00126   VSG_SCOPE_PARENT,
    00127   VSG_SCOPE_RELATIVE,
    00128
    00129   VSG_END
    00130 };
    00131 DECLARE_POSTFIX_INCREMENT(VarSpriteGroupScope)
    00132
    00133 enum DeterministicSpriteGroupSize {
    00134   DSG_SIZE_BYTE,
    00135   DSG_SIZE_WORD,
    00136   DSG_SIZE_DWORD,
    00137 };
    00138
    00139 enum DeterministicSpriteGroupAdjustType {
    00140   DSGA_TYPE_NONE,
    00141   DSGA_TYPE_DIV,
    00142   DSGA_TYPE_MOD,
    00143 };
    00144
    00145 enum DeterministicSpriteGroupAdjustOperation {
    00146   DSGA_OP_ADD,
    00147   DSGA_OP_SUB,
    00148   DSGA_OP_SMIN,
    00149   DSGA_OP_SMAX,
    00150   DSGA_OP_UMIN,
    00151   DSGA_OP_UMAX,
    00152   DSGA_OP_SDIV,
    00153   DSGA_OP_SMOD,
    00154   DSGA_OP_UDIV,
    00155   DSGA_OP_UMOD,
    00156   DSGA_OP_MUL,
    00157   DSGA_OP_AND,
    00158   DSGA_OP_OR,
    00159   DSGA_OP_XOR,
    00160   DSGA_OP_STO,
    00161   DSGA_OP_RST,
    00162   DSGA_OP_STOP,
    00163   DSGA_OP_ROR,
    00164   DSGA_OP_SCMP,
    00165   DSGA_OP_UCMP,
    00166   DSGA_OP_SHL,
    00167   DSGA_OP_SHR,
    00168   DSGA_OP_SAR,
    00169 };
    00170
    00171
    00172 struct DeterministicSpriteGroupAdjust {
    00173   DeterministicSpriteGroupAdjustOperation operation;
    00174   DeterministicSpriteGroupAdjustType type;
    00175   byte variable;
    00176   byte parameter;
    00177   byte shift_num;
    00178   uint32 and_mask;
    00179   uint32 add_val;
    00180   uint32 divmod_val;
    00181   const SpriteGroup *subroutine;
    00182 };
    00183
    00184
    00185 struct DeterministicSpriteGroupRange {
    00186   const SpriteGroup *group;
    00187   uint32 low;
    00188   uint32 high;
    00189 };
    00190
    00191
    00192 struct DeterministicSpriteGroup : SpriteGroup {
    00193   DeterministicSpriteGroup() : SpriteGroup(SGT_DETERMINISTIC) {}
    00194   ~DeterministicSpriteGroup();
    00195
    00196   VarSpriteGroupScope var_scope;
    00197   DeterministicSpriteGroupSize size;
    00198   uint num_adjusts;
    00199   byte num_ranges;
    00200   DeterministicSpriteGroupAdjust *adjusts;
    00201   DeterministicSpriteGroupRange *ranges; // Dynamically allocated
    00202
    00203   /* Dynamically allocated, this is the sole owner */
    00204   const SpriteGroup *default_group;
    00205
    00206 protected:
    00207   const SpriteGroup *Resolve(ResolverObject *object) const;
    00208 };
    00209
    00210 enum RandomizedSpriteGroupCompareMode {
    00211   RSG_CMP_ANY,
    00212   RSG_CMP_ALL,
    00213 };
    00214
    00215 struct RandomizedSpriteGroup : SpriteGroup {
    00216   RandomizedSpriteGroup() : SpriteGroup(SGT_RANDOMIZED) {}
    00217   ~RandomizedSpriteGroup();
    00218
    00219   VarSpriteGroupScope var_scope;
    00220
    00221   RandomizedSpriteGroupCompareMode cmp_mode;
    00222   byte triggers;
    00223   byte count;
    00224
    00225   byte lowest_randbit;
    00226   byte num_groups;
    00227
    00228   const SpriteGroup **groups;
    00229
    00230 protected:
    00231   const SpriteGroup *Resolve(ResolverObject *object) const;
    00232 };
    00233
    00234
    00235 /* This contains a callback result. A failed callback has a value of
    00236  * CALLBACK_FAILED */
    00237 struct CallbackResultSpriteGroup : SpriteGroup {
    00243   CallbackResultSpriteGroup(uint16 value, bool grf_version8) :
    00244     SpriteGroup(SGT_CALLBACK),
    00245     result(value)
    00246   {
    00247     /* Old style callback results (only valid for version < 8) have the highest byte 0xFF so signify it is a callback result.
    00248      * New style ones only have the highest bit set (allows 15-bit results, instead of just 8) */
    00249     if (!grf_version8 && (this->result >> 8) == 0xFF) {
    00250       this->result &= ~0xFF00;
    00251     } else {
    00252       this->result &= ~0x8000;
    00253     }
    00254   }
    00255
    00256   uint16 result;
    00257   uint16 GetCallbackResult() const { return this->result; }
    00258 };
    00259
    00260
    00261 /* A result sprite group returns the first SpriteID and the number of
    00262  * sprites in the set */
    00263 struct ResultSpriteGroup : SpriteGroup {
    00270   ResultSpriteGroup(SpriteID sprite, byte num_sprites) :
    00271     SpriteGroup(SGT_RESULT),
    00272     sprite(sprite),
    00273     num_sprites(num_sprites)
    00274   {
    00275   }
    00276
    00277   SpriteID sprite;
    00278   byte num_sprites;
    00279   SpriteID GetResult() const { return this->sprite; }
    00280   byte GetNumResults() const { return this->num_sprites; }
    00281 };
    00282
    00286 struct TileLayoutSpriteGroup : SpriteGroup {
    00287   TileLayoutSpriteGroup() : SpriteGroup(SGT_TILELAYOUT) {}
    00288   ~TileLayoutSpriteGroup() {}
    00289
    00290   NewGRFSpriteLayout dts;
    00291
    00292   const DrawTileSprites *ProcessRegisters(uint8 *stage) const;
    00293 };
    00294
    00295 struct IndustryProductionSpriteGroup : SpriteGroup {
    00296   IndustryProductionSpriteGroup() : SpriteGroup(SGT_INDUSTRY_PRODUCTION) {}
    00297
    00298   uint8 version;
    00299   int16 subtract_input[3];  // signed
    00300   uint16 add_output[2];     // unsigned
    00301   uint8 again;
    00302 };
    00303
    00304 struct ResolverObject;
    00305
    00312 struct ScopeResolver {
    00313   ResolverObject *ro;
    00314
    00315   ScopeResolver(ResolverObject *ro);
    00316   virtual ~ScopeResolver();
    00317
    00318   virtual uint32 GetRandomBits() const;
    00319   virtual uint32 GetTriggers() const;
    00320   virtual void SetTriggers(int triggers) const;
    00321
    00322   virtual uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
    00323   virtual void StorePSA(uint reg, int32 value);
    00324 };
    00325
    00332 struct ResolverObject {
    00333   ResolverObject(const GRFFile *grffile, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0);
    00334   virtual ~ResolverObject();
    00335
    00336   ScopeResolver default_scope;
    00337
    00338   CallbackID callback;
    00339   uint32 callback_param1;
    00340   uint32 callback_param2;
    00341
    00342   byte trigger;
    00343
    00344   uint32 last_value;
    00345   uint32 reseed[VSG_END];
    00346
    00347   const GRFFile *grffile;
    00348
    00349   virtual const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const;
    00350
    00351   virtual ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0);
    00352
    00358   uint32 GetReseedSum() const
    00359   {
    00360     uint32 sum = 0;
    00361     for (VarSpriteGroupScope vsg = VSG_BEGIN; vsg < VSG_END; vsg++) {
    00362       sum |= this->reseed[vsg];
    00363     }
    00364     return sum;
    00365   }
    00366
    00371   void ResetState()
    00372   {
    00373     this->last_value = 0;
    00374     this->trigger    = 0;
    00375     memset(this->reseed, 0, sizeof(this->reseed));
    00376   }
    00377 };
    00378
    00379 #endif /* NEWGRF_SPRITEGROUP_H */