# newgrf_spritegroup.h

Go to the documentation of this file.

    00001 /* $Id: newgrf_spritegroup.h 26172 2013-12-23 18:08:16Z frosch $ */
    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 struct ResolverObject;
    00061
    00062 /* SPRITE_WIDTH is 24. ECS has roughly 30 sprite groups per real sprite.
    00063  * Adding an 'extra' margin would be assuming 64 sprite groups per real
    00064  * sprite. 64 = 2^6, so 2^30 should be enough (for now) */
    00065 typedef Pool<SpriteGroup, SpriteGroupID, 1024, 1 << 30, PT_DATA> SpriteGroupPool;
    00066 extern SpriteGroupPool _spritegroup_pool;
    00067
    00068 /* Common wrapper for all the different sprite group types */
    00069 struct SpriteGroup : SpriteGroupPool::PoolItem<&_spritegroup_pool> {
    00070 protected:
    00071   SpriteGroup(SpriteGroupType type) : type(type) {}
    00073   virtual const SpriteGroup *Resolve(ResolverObject &object) const { return this; };
    00074
    00075 public:
    00076   virtual ~SpriteGroup() {}
    00077
    00078   SpriteGroupType type;
    00079
    00080   virtual SpriteID GetResult() const { return 0; }
    00081   virtual byte GetNumResults() const { return 0; }
    00082   virtual uint16 GetCallbackResult() const { return CALLBACK_FAILED; }
    00083
    00084   static const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject &object, bool top_level = true);
    00085 };
    00086
    00087
    00088 /* 'Real' sprite groups contain a list of other result or callback sprite
    00089  * groups. */
    00090 struct RealSpriteGroup : SpriteGroup {
    00091   RealSpriteGroup() : SpriteGroup(SGT_REAL) {}
    00092   ~RealSpriteGroup();
    00093
    00094   /* Loaded = in motion, loading = not moving
    00095    * Each group contains several spritesets, for various loading stages */
    00096
    00097   /* XXX: For stations the meaning is different - loaded is for stations
    00098    * with small amount of cargo whilst loading is for stations with a lot
    00099    * of da stuff. */
    00100
    00101   byte num_loaded;
    00102   byte num_loading;
    00103   const SpriteGroup **loaded;
    00104   const SpriteGroup **loading;
    00105
    00106 protected:
    00107   const SpriteGroup *Resolve(ResolverObject &object) const;
    00108 };
    00109
    00110 /* Shared by deterministic and random groups. */
    00111 enum VarSpriteGroupScope {
    00112   VSG_BEGIN,
    00113
    00114   VSG_SCOPE_SELF = VSG_BEGIN,
    00115   VSG_SCOPE_PARENT,
    00116   VSG_SCOPE_RELATIVE,
    00117
    00118   VSG_END
    00119 };
    00120 DECLARE_POSTFIX_INCREMENT(VarSpriteGroupScope)
    00121
    00122 enum DeterministicSpriteGroupSize {
    00123   DSG_SIZE_BYTE,
    00124   DSG_SIZE_WORD,
    00125   DSG_SIZE_DWORD,
    00126 };
    00127
    00128 enum DeterministicSpriteGroupAdjustType {
    00129   DSGA_TYPE_NONE,
    00130   DSGA_TYPE_DIV,
    00131   DSGA_TYPE_MOD,
    00132 };
    00133
    00134 enum DeterministicSpriteGroupAdjustOperation {
    00135   DSGA_OP_ADD,
    00136   DSGA_OP_SUB,
    00137   DSGA_OP_SMIN,
    00138   DSGA_OP_SMAX,
    00139   DSGA_OP_UMIN,
    00140   DSGA_OP_UMAX,
    00141   DSGA_OP_SDIV,
    00142   DSGA_OP_SMOD,
    00143   DSGA_OP_UDIV,
    00144   DSGA_OP_UMOD,
    00145   DSGA_OP_MUL,
    00146   DSGA_OP_AND,
    00147   DSGA_OP_OR,
    00148   DSGA_OP_XOR,
    00149   DSGA_OP_STO,
    00150   DSGA_OP_RST,
    00151   DSGA_OP_STOP,
    00152   DSGA_OP_ROR,
    00153   DSGA_OP_SCMP,
    00154   DSGA_OP_UCMP,
    00155   DSGA_OP_SHL,
    00156   DSGA_OP_SHR,
    00157   DSGA_OP_SAR,
    00158 };
    00159
    00160
    00161 struct DeterministicSpriteGroupAdjust {
    00162   DeterministicSpriteGroupAdjustOperation operation;
    00163   DeterministicSpriteGroupAdjustType type;
    00164   byte variable;
    00165   byte parameter;
    00166   byte shift_num;
    00167   uint32 and_mask;
    00168   uint32 add_val;
    00169   uint32 divmod_val;
    00170   const SpriteGroup *subroutine;
    00171 };
    00172
    00173
    00174 struct DeterministicSpriteGroupRange {
    00175   const SpriteGroup *group;
    00176   uint32 low;
    00177   uint32 high;
    00178 };
    00179
    00180
    00181 struct DeterministicSpriteGroup : SpriteGroup {
    00182   DeterministicSpriteGroup() : SpriteGroup(SGT_DETERMINISTIC) {}
    00183   ~DeterministicSpriteGroup();
    00184
    00185   VarSpriteGroupScope var_scope;
    00186   DeterministicSpriteGroupSize size;
    00187   uint num_adjusts;
    00188   byte num_ranges;
    00189   DeterministicSpriteGroupAdjust *adjusts;
    00190   DeterministicSpriteGroupRange *ranges; // Dynamically allocated
    00191
    00192   /* Dynamically allocated, this is the sole owner */
    00193   const SpriteGroup *default_group;
    00194
    00195 protected:
    00196   const SpriteGroup *Resolve(ResolverObject &object) const;
    00197 };
    00198
    00199 enum RandomizedSpriteGroupCompareMode {
    00200   RSG_CMP_ANY,
    00201   RSG_CMP_ALL,
    00202 };
    00203
    00204 struct RandomizedSpriteGroup : SpriteGroup {
    00205   RandomizedSpriteGroup() : SpriteGroup(SGT_RANDOMIZED) {}
    00206   ~RandomizedSpriteGroup();
    00207
    00208   VarSpriteGroupScope var_scope;
    00209
    00210   RandomizedSpriteGroupCompareMode cmp_mode;
    00211   byte triggers;
    00212   byte count;
    00213
    00214   byte lowest_randbit;
    00215   byte num_groups;
    00216
    00217   const SpriteGroup **groups;
    00218
    00219 protected:
    00220   const SpriteGroup *Resolve(ResolverObject &object) const;
    00221 };
    00222
    00223
    00224 /* This contains a callback result. A failed callback has a value of
    00225  * CALLBACK_FAILED */
    00226 struct CallbackResultSpriteGroup : SpriteGroup {
    00232   CallbackResultSpriteGroup(uint16 value, bool grf_version8) :
    00233     SpriteGroup(SGT_CALLBACK),
    00234     result(value)
    00235   {
    00236     /* Old style callback results (only valid for version < 8) have the highest byte 0xFF so signify it is a callback result.
    00237      * New style ones only have the highest bit set (allows 15-bit results, instead of just 8) */
    00238     if (!grf_version8 && (this->result >> 8) == 0xFF) {
    00239       this->result &= ~0xFF00;
    00240     } else {
    00241       this->result &= ~0x8000;
    00242     }
    00243   }
    00244
    00245   uint16 result;
    00246   uint16 GetCallbackResult() const { return this->result; }
    00247 };
    00248
    00249
    00250 /* A result sprite group returns the first SpriteID and the number of
    00251  * sprites in the set */
    00252 struct ResultSpriteGroup : SpriteGroup {
    00259   ResultSpriteGroup(SpriteID sprite, byte num_sprites) :
    00260     SpriteGroup(SGT_RESULT),
    00261     sprite(sprite),
    00262     num_sprites(num_sprites)
    00263   {
    00264   }
    00265
    00266   SpriteID sprite;
    00267   byte num_sprites;
    00268   SpriteID GetResult() const { return this->sprite; }
    00269   byte GetNumResults() const { return this->num_sprites; }
    00270 };
    00271
    00275 struct TileLayoutSpriteGroup : SpriteGroup {
    00276   TileLayoutSpriteGroup() : SpriteGroup(SGT_TILELAYOUT) {}
    00277   ~TileLayoutSpriteGroup() {}
    00278
    00279   NewGRFSpriteLayout dts;
    00280
    00281   const DrawTileSprites *ProcessRegisters(uint8 *stage) const;
    00282 };
    00283
    00284 struct IndustryProductionSpriteGroup : SpriteGroup {
    00285   IndustryProductionSpriteGroup() : SpriteGroup(SGT_INDUSTRY_PRODUCTION) {}
    00286
    00287   uint8 version;
    00288   int16 subtract_input[3];  // signed
    00289   uint16 add_output[2];     // unsigned
    00290   uint8 again;
    00291 };
    00292
    00299 struct ScopeResolver {
    00300   ResolverObject &ro;
    00301
    00302   ScopeResolver(ResolverObject &ro);
    00303   virtual ~ScopeResolver();
    00304
    00305   virtual uint32 GetRandomBits() const;
    00306   virtual uint32 GetTriggers() const;
    00307   virtual void SetTriggers(int triggers) const;
    00308
    00309   virtual uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
    00310   virtual void StorePSA(uint reg, int32 value);
    00311 };
    00312
    00319 struct ResolverObject {
    00320   ResolverObject(const GRFFile *grffile, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0);
    00321   virtual ~ResolverObject();
    00322
    00323   ScopeResolver default_scope;
    00324
    00325   CallbackID callback;
    00326   uint32 callback_param1;
    00327   uint32 callback_param2;
    00328
    00329   byte trigger;
    00330
    00331   uint32 last_value;
    00332   uint32 reseed[VSG_END];
    00333
    00334   const GRFFile *grffile;
    00335
    00336   virtual const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const;
    00337
    00338   virtual ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0);
    00339
    00345   uint32 GetReseedSum() const
    00346   {
    00347     uint32 sum = 0;
    00348     for (VarSpriteGroupScope vsg = VSG_BEGIN; vsg < VSG_END; vsg++) {
    00349       sum |= this->reseed[vsg];
    00350     }
    00351     return sum;
    00352   }
    00353
    00358   void ResetState()
    00359   {
    00360     this->last_value = 0;
    00361     this->trigger    = 0;
    00362     memset(this->reseed, 0, sizeof(this->reseed));
    00363   }
    00364 };
    00365
    00366 #endif /* NEWGRF_SPRITEGROUP_H */