# newgrf_spritegroup.h

Go to the documentation of this file.

    00001 /* $Id: newgrf_spritegroup.h 22838 2011-08-25 13:24:32Z rubidium $ */
    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 "gfx_type.h"
    00017 #include "engine_type.h"
    00018 #include "core/pool_type.hpp"
    00019 #include "house_type.h"
    00020
    00021 #include "newgrf_callbacks.h"
    00022 #include "newgrf_generic.h"
    00023 #include "newgrf_storage.h"
    00024 #include "newgrf_commons.h"
    00025
    00032 static inline uint32 GetRegister(uint i)
    00033 {
    00034   extern TemporaryStorageArray<int32, 0x110> _temp_store;
    00035   return _temp_store.Get(i);
    00036 }
    00037
    00043 static inline void ClearRegister(uint i)
    00044 {
    00045   extern TemporaryStorageArray<int32, 0x110> _temp_store;
    00046   _temp_store.Store(i, 0);
    00047 }
    00048
    00049 /* List of different sprite group types */
    00050 enum SpriteGroupType {
    00051   SGT_REAL,
    00052   SGT_DETERMINISTIC,
    00053   SGT_RANDOMIZED,
    00054   SGT_CALLBACK,
    00055   SGT_RESULT,
    00056   SGT_TILELAYOUT,
    00057   SGT_INDUSTRY_PRODUCTION,
    00058 };
    00059
    00060 struct SpriteGroup;
    00061 typedef uint32 SpriteGroupID;
    00062
    00063 /* SPRITE_WIDTH is 24. ECS has roughly 30 sprite groups per real sprite.
    00064  * Adding an 'extra' margin would be assuming 64 sprite groups per real
    00065  * sprite. 64 = 2^6, so 2^30 should be enough (for now) */
    00066 typedef Pool<SpriteGroup, SpriteGroupID, 1024, 1 << 30> SpriteGroupPool;
    00067 extern SpriteGroupPool _spritegroup_pool;
    00068
    00069 /* Common wrapper for all the different sprite group types */
    00070 struct SpriteGroup : SpriteGroupPool::PoolItem<&_spritegroup_pool> {
    00071 protected:
    00072   SpriteGroup(SpriteGroupType type) : type(type) {}
    00074   virtual const SpriteGroup *Resolve(struct ResolverObject *object) const { return this; };
    00075
    00076 public:
    00077   virtual ~SpriteGroup() {}
    00078
    00079   SpriteGroupType type;
    00080
    00081   virtual SpriteID GetResult() const { return 0; }
    00082   virtual byte GetNumResults() const { return 0; }
    00083   virtual uint16 GetCallbackResult() const { return CALLBACK_FAILED; }
    00084
    00094   static const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject *object)
    00095   {
    00096     return group == NULL ? NULL : group->Resolve(object);
    00097   }
    00098 };
    00099
    00100
    00101 /* 'Real' sprite groups contain a list of other result or callback sprite
    00102  * groups. */
    00103 struct RealSpriteGroup : SpriteGroup {
    00104   RealSpriteGroup() : SpriteGroup(SGT_REAL) {}
    00105   ~RealSpriteGroup();
    00106
    00107   /* Loaded = in motion, loading = not moving
    00108    * Each group contains several spritesets, for various loading stages */
    00109
    00110   /* XXX: For stations the meaning is different - loaded is for stations
    00111    * with small amount of cargo whilst loading is for stations with a lot
    00112    * of da stuff. */
    00113
    00114   byte num_loaded;
    00115   byte num_loading;
    00116   const SpriteGroup **loaded;
    00117   const SpriteGroup **loading;
    00118
    00119 protected:
    00120   const SpriteGroup *Resolve(ResolverObject *object) const;
    00121 };
    00122
    00123 /* Shared by deterministic and random groups. */
    00124 enum VarSpriteGroupScope {
    00125   VSG_BEGIN,
    00126
    00127   VSG_SCOPE_SELF = VSG_BEGIN,
    00128   VSG_SCOPE_PARENT,
    00129   VSG_SCOPE_RELATIVE,
    00130
    00131   VSG_END
    00132 };
    00133 DECLARE_POSTFIX_INCREMENT(VarSpriteGroupScope)
    00134
    00135 enum DeterministicSpriteGroupSize {
    00136   DSG_SIZE_BYTE,
    00137   DSG_SIZE_WORD,
    00138   DSG_SIZE_DWORD,
    00139 };
    00140
    00141 enum DeterministicSpriteGroupAdjustType {
    00142   DSGA_TYPE_NONE,
    00143   DSGA_TYPE_DIV,
    00144   DSGA_TYPE_MOD,
    00145 };
    00146
    00147 enum DeterministicSpriteGroupAdjustOperation {
    00148   DSGA_OP_ADD,
    00149   DSGA_OP_SUB,
    00150   DSGA_OP_SMIN,
    00151   DSGA_OP_SMAX,
    00152   DSGA_OP_UMIN,
    00153   DSGA_OP_UMAX,
    00154   DSGA_OP_SDIV,
    00155   DSGA_OP_SMOD,
    00156   DSGA_OP_UDIV,
    00157   DSGA_OP_UMOD,
    00158   DSGA_OP_MUL,
    00159   DSGA_OP_AND,
    00160   DSGA_OP_OR,
    00161   DSGA_OP_XOR,
    00162   DSGA_OP_STO,
    00163   DSGA_OP_RST,
    00164   DSGA_OP_STOP,
    00165   DSGA_OP_ROR,
    00166   DSGA_OP_SCMP,
    00167   DSGA_OP_UCMP,
    00168   DSGA_OP_SHL,
    00169   DSGA_OP_SHR,
    00170   DSGA_OP_SAR,
    00171 };
    00172
    00173
    00174 struct DeterministicSpriteGroupAdjust {
    00175   DeterministicSpriteGroupAdjustOperation operation;
    00176   DeterministicSpriteGroupAdjustType type;
    00177   byte variable;
    00178   byte parameter;
    00179   byte shift_num;
    00180   uint32 and_mask;
    00181   uint32 add_val;
    00182   uint32 divmod_val;
    00183   const SpriteGroup *subroutine;
    00184 };
    00185
    00186
    00187 struct DeterministicSpriteGroupRange {
    00188   const SpriteGroup *group;
    00189   uint32 low;
    00190   uint32 high;
    00191 };
    00192
    00193
    00194 struct DeterministicSpriteGroup : SpriteGroup {
    00195   DeterministicSpriteGroup() : SpriteGroup(SGT_DETERMINISTIC) {}
    00196   ~DeterministicSpriteGroup();
    00197
    00198   VarSpriteGroupScope var_scope;
    00199   DeterministicSpriteGroupSize size;
    00200   uint num_adjusts;
    00201   byte num_ranges;
    00202   DeterministicSpriteGroupAdjust *adjusts;
    00203   DeterministicSpriteGroupRange *ranges; // Dynamically allocated
    00204
    00205   /* Dynamically allocated, this is the sole owner */
    00206   const SpriteGroup *default_group;
    00207
    00208 protected:
    00209   const SpriteGroup *Resolve(ResolverObject *object) const;
    00210 };
    00211
    00212 enum RandomizedSpriteGroupCompareMode {
    00213   RSG_CMP_ANY,
    00214   RSG_CMP_ALL,
    00215 };
    00216
    00217 struct RandomizedSpriteGroup : SpriteGroup {
    00218   RandomizedSpriteGroup() : SpriteGroup(SGT_RANDOMIZED) {}
    00219   ~RandomizedSpriteGroup();
    00220
    00221   VarSpriteGroupScope var_scope;
    00222
    00223   RandomizedSpriteGroupCompareMode cmp_mode;
    00224   byte triggers;
    00225   byte count;
    00226
    00227   byte lowest_randbit;
    00228   byte num_groups;
    00229
    00230   const SpriteGroup **groups;
    00231
    00232 protected:
    00233   const SpriteGroup *Resolve(ResolverObject *object) const;
    00234 };
    00235
    00236
    00237 /* This contains a callback result. A failed callback has a value of
    00238  * CALLBACK_FAILED */
    00239 struct CallbackResultSpriteGroup : SpriteGroup {
    00244   CallbackResultSpriteGroup(uint16 value) :
    00245     SpriteGroup(SGT_CALLBACK),
    00246     result(value)
    00247   {
    00248     /* Old style callback results have the highest byte 0xFF so signify it is a callback result
    00249      * New style ones only have the highest bit set (allows 15-bit results, instead of just 8) */
    00250     if ((this->result >> 8) == 0xFF) {
    00251       this->result &= ~0xFF00;
    00252     } else {
    00253       this->result &= ~0x8000;
    00254     }
    00255   }
    00256
    00257   uint16 result;
    00258   uint16 GetCallbackResult() const { return this->result; }
    00259 };
    00260
    00261
    00262 /* A result sprite group returns the first SpriteID and the number of
    00263  * sprites in the set */
    00264 struct ResultSpriteGroup : SpriteGroup {
    00271   ResultSpriteGroup(SpriteID sprite, byte num_sprites) :
    00272     SpriteGroup(SGT_RESULT),
    00273     sprite(sprite),
    00274     num_sprites(num_sprites)
    00275   {
    00276   }
    00277
    00278   SpriteID sprite;
    00279   byte num_sprites;
    00280   SpriteID GetResult() const { return this->sprite; }
    00281   byte GetNumResults() const { return this->num_sprites; }
    00282 };
    00283
    00284 struct TileLayoutSpriteGroup : SpriteGroup {
    00285   TileLayoutSpriteGroup() : SpriteGroup(SGT_TILELAYOUT) {}
    00286   ~TileLayoutSpriteGroup();
    00287
    00288   byte num_building_stages;
    00289   struct DrawTileSprites *dts;
    00290
    00296   uint GetConstructionStageOffset(uint construction_stage) const
    00297   {
    00298     uint num_sprites = this->num_building_stages;
    00299     assert(num_sprites > 0);
    00300     if (num_sprites > 4) num_sprites = 4;
    00301     switch (construction_stage) {
    00302       case 0: return 0;
    00303       case 1: return num_sprites > 2 ? 1 : 0;
    00304       case 2: return num_sprites > 2 ? num_sprites - 2 : 0;
    00305       case 3: return num_sprites - 1;
    00306       default: NOT_REACHED();
    00307     }
    00308   }
    00309 };
    00310
    00311 struct IndustryProductionSpriteGroup : SpriteGroup {
    00312   IndustryProductionSpriteGroup() : SpriteGroup(SGT_INDUSTRY_PRODUCTION) {}
    00313
    00314   uint8 version;
    00315   int16 subtract_input[3];  // signed
    00316   uint16 add_output[2];     // unsigned
    00317   uint8 again;
    00318 };
    00319
    00320
    00321 struct ResolverObject {
    00322   CallbackID callback;
    00323   uint32 callback_param1;
    00324   uint32 callback_param2;
    00325
    00326   byte trigger;
    00327
    00328   uint32 last_value;
    00329   uint32 reseed[VSG_END];
    00330
    00331   VarSpriteGroupScope scope;
    00332   byte count;
    00333
    00334   BaseStorageArray *psa;
    00335
    00336   const GRFFile *grffile;
    00337
    00338   union {
    00339     struct {
    00340       const struct Vehicle *self;
    00341       const struct Vehicle *parent;
    00342       EngineID self_type;
    00343       bool info_view;
    00344     } vehicle;
    00345     struct {
    00346       TileIndex tile;
    00347     } canal;
    00348     struct {
    00349       TileIndex tile;
    00350       const struct BaseStation *st;
    00351       const struct StationSpec *statspec;
    00352       CargoID cargo_type;
    00353     } station;
    00354     struct {
    00355       TileIndex tile;
    00356       const Town *town;
    00357       HouseID house_id;
    00358       uint16 initial_random_bits;
    00359       bool not_yet_constructed;
    00360     } house;
    00361     struct {
    00362       TileIndex tile;
    00363       Industry *ind;
    00364       IndustryGfx gfx;
    00365       IndustryType type;
    00366     } industry;
    00367     struct {
    00368       const struct CargoSpec *cs;
    00369     } cargo;
    00370     struct {
    00371       CargoID cargo_type;
    00372       uint8 default_selection;
    00373       uint8 src_industry;
    00374       uint8 dst_industry;
    00375       uint8 distance;
    00376       AIConstructionEvent event;
    00377       uint8 count;
    00378       uint8 station_size;
    00379     } generic;
    00380     struct {
    00381       TileIndex tile;
    00382       TileContext context;
    00383     } routes;
    00384     struct {
    00385       const struct Station *st;
    00386       byte airport_id;
    00387       byte layout;
    00388       TileIndex tile;
    00389     } airport;
    00390     struct {
    00391       const struct Object *o;
    00392       TileIndex tile;
    00393       uint8 view;
    00394     } object;
    00395   } u;
    00396
    00397   uint32 (*GetRandomBits)(const struct ResolverObject*);
    00398   uint32 (*GetTriggers)(const struct ResolverObject*);
    00399   void (*SetTriggers)(const struct ResolverObject*, int);
    00400   uint32 (*GetVariable)(const struct ResolverObject*, byte, byte, bool*);
    00401   const SpriteGroup *(*ResolveReal)(const struct ResolverObject*, const RealSpriteGroup*);
    00402
    00408   uint32 GetReseedSum() const
    00409   {
    00410     uint32 sum = 0;
    00411     for (VarSpriteGroupScope vsg = VSG_BEGIN; vsg < VSG_END; vsg++) {
    00412       sum |= this->reseed[vsg];
    00413     }
    00414     return sum;
    00415   }
    00416
    00421   void ResetState()
    00422   {
    00423     this->last_value = 0;
    00424     this->trigger    = 0;
    00425     memset(this->reseed, 0, sizeof(this->reseed));
    00426   }
    00427 };
    00428
    00429 #endif /* NEWGRF_SPRITEGROUP_H */