# newgrf_spritegroup.h

Go to the documentation of this file.

    00001 /* $Id: newgrf_spritegroup.h 20432 2010-08-09 21:58:52Z 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 "tile_type.h"
    00019 #include "core/pool_type.hpp"
    00020 #include "house_type.h"
    00021
    00022 #include "newgrf_callbacks.h"
    00023 #include "newgrf_generic.h"
    00024 #include "newgrf_storage.h"
    00025 #include "newgrf_commons.h"
    00026
    00033 static inline uint32 GetRegister(uint i)
    00034 {
    00035   extern TemporaryStorageArray<int32, 0x110> _temp_store;
    00036   return _temp_store.Get(i);
    00037 }
    00038
    00039 /* List of different sprite group types */
    00040 enum SpriteGroupType {
    00041   SGT_REAL,
    00042   SGT_DETERMINISTIC,
    00043   SGT_RANDOMIZED,
    00044   SGT_CALLBACK,
    00045   SGT_RESULT,
    00046   SGT_TILELAYOUT,
    00047   SGT_INDUSTRY_PRODUCTION,
    00048 };
    00049
    00050 struct SpriteGroup;
    00051 typedef uint32 SpriteGroupID;
    00052
    00053 /* SPRITE_WIDTH is 24. ECS has roughly 30 sprite groups per real sprite.
    00054  * Adding an 'extra' margin would be assuming 64 sprite groups per real
    00055  * sprite. 64 = 2^6, so 2^30 should be enough (for now) */
    00056 typedef Pool<SpriteGroup, SpriteGroupID, 1024, 1 << 30> SpriteGroupPool;
    00057 extern SpriteGroupPool _spritegroup_pool;
    00058
    00059 /* Common wrapper for all the different sprite group types */
    00060 struct SpriteGroup : SpriteGroupPool::PoolItem<&_spritegroup_pool> {
    00061 protected:
    00062   SpriteGroup(SpriteGroupType type) : type(type) {}
    00064   virtual const SpriteGroup *Resolve(struct ResolverObject *object) const { return this; };
    00065
    00066 public:
    00067   virtual ~SpriteGroup() {}
    00068
    00069   SpriteGroupType type;
    00070
    00071   virtual SpriteID GetResult() const { return 0; }
    00072   virtual byte GetNumResults() const { return 0; }
    00073   virtual uint16 GetCallbackResult() const { return CALLBACK_FAILED; }
    00074
    00084   static const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject *object)
    00085   {
    00086     return group == NULL ? NULL : group->Resolve(object);
    00087   }
    00088 };
    00089
    00090
    00091 /* 'Real' sprite groups contain a list of other result or callback sprite
    00092  * groups. */
    00093 struct RealSpriteGroup : SpriteGroup {
    00094   RealSpriteGroup() : SpriteGroup(SGT_REAL) {}
    00095   ~RealSpriteGroup();
    00096
    00097   /* Loaded = in motion, loading = not moving
    00098    * Each group contains several spritesets, for various loading stages */
    00099
    00100   /* XXX: For stations the meaning is different - loaded is for stations
    00101    * with small amount of cargo whilst loading is for stations with a lot
    00102    * of da stuff. */
    00103
    00104   byte num_loaded;
    00105   byte num_loading;
    00106   const SpriteGroup **loaded;
    00107   const SpriteGroup **loading;
    00108
    00109 protected:
    00110   const SpriteGroup *Resolve(ResolverObject *object) const;
    00111 };
    00112
    00113 /* Shared by deterministic and random groups. */
    00114 enum VarSpriteGroupScope {
    00115   VSG_SCOPE_SELF,
    00116   /* Engine of consists for vehicles, city for stations. */
    00117   VSG_SCOPE_PARENT,
    00118   /* Any vehicle in the consist (vehicles only) */
    00119   VSG_SCOPE_RELATIVE,
    00120 };
    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 };
    00156
    00157
    00158 struct DeterministicSpriteGroupAdjust {
    00159   DeterministicSpriteGroupAdjustOperation operation;
    00160   DeterministicSpriteGroupAdjustType type;
    00161   byte variable;
    00162   byte parameter;
    00163   byte shift_num;
    00164   uint32 and_mask;
    00165   uint32 add_val;
    00166   uint32 divmod_val;
    00167   const SpriteGroup *subroutine;
    00168 };
    00169
    00170
    00171 struct DeterministicSpriteGroupRange {
    00172   const SpriteGroup *group;
    00173   uint32 low;
    00174   uint32 high;
    00175 };
    00176
    00177
    00178 struct DeterministicSpriteGroup : SpriteGroup {
    00179   DeterministicSpriteGroup() : SpriteGroup(SGT_DETERMINISTIC) {}
    00180   ~DeterministicSpriteGroup();
    00181
    00182   VarSpriteGroupScope var_scope;
    00183   DeterministicSpriteGroupSize size;
    00184   byte num_adjusts;
    00185   byte num_ranges;
    00186   DeterministicSpriteGroupAdjust *adjusts;
    00187   DeterministicSpriteGroupRange *ranges; // Dynamically allocated
    00188
    00189   /* Dynamically allocated, this is the sole owner */
    00190   const SpriteGroup *default_group;
    00191
    00192 protected:
    00193   const SpriteGroup *Resolve(ResolverObject *object) const;
    00194 };
    00195
    00196 enum RandomizedSpriteGroupCompareMode {
    00197   RSG_CMP_ANY,
    00198   RSG_CMP_ALL,
    00199 };
    00200
    00201 struct RandomizedSpriteGroup : SpriteGroup {
    00202   RandomizedSpriteGroup() : SpriteGroup(SGT_RANDOMIZED) {}
    00203   ~RandomizedSpriteGroup();
    00204
    00205   VarSpriteGroupScope var_scope;
    00206
    00207   RandomizedSpriteGroupCompareMode cmp_mode;
    00208   byte triggers;
    00209   byte count;
    00210
    00211   byte lowest_randbit;
    00212   byte num_groups;
    00213
    00214   const SpriteGroup **groups;
    00215
    00216 protected:
    00217   const SpriteGroup *Resolve(ResolverObject *object) const;
    00218 };
    00219
    00220
    00221 /* This contains a callback result. A failed callback has a value of
    00222  * CALLBACK_FAILED */
    00223 struct CallbackResultSpriteGroup : SpriteGroup {
    00228   CallbackResultSpriteGroup(uint16 value) :
    00229     SpriteGroup(SGT_CALLBACK),
    00230     result(value)
    00231   {
    00232     /* Old style callback results have the highest byte 0xFF so signify it is a callback result
    00233      * New style ones only have the highest bit set (allows 15-bit results, instead of just 8) */
    00234     if ((this->result >> 8) == 0xFF) {
    00235       this->result &= ~0xFF00;
    00236     } else {
    00237       this->result &= ~0x8000;
    00238     }
    00239   }
    00240
    00241   uint16 result;
    00242   uint16 GetCallbackResult() const { return this->result; }
    00243 };
    00244
    00245
    00246 /* A result sprite group returns the first SpriteID and the number of
    00247  * sprites in the set */
    00248 struct ResultSpriteGroup : SpriteGroup {
    00255   ResultSpriteGroup(SpriteID sprite, byte num_sprites) :
    00256     SpriteGroup(SGT_RESULT),
    00257     sprite(sprite),
    00258     num_sprites(num_sprites)
    00259   {
    00260   }
    00261
    00262   SpriteID sprite;
    00263   byte num_sprites;
    00264   SpriteID GetResult() const { return this->sprite; }
    00265   byte GetNumResults() const { return this->num_sprites; }
    00266 };
    00267
    00268 struct TileLayoutSpriteGroup : SpriteGroup {
    00269   TileLayoutSpriteGroup() : SpriteGroup(SGT_TILELAYOUT) {}
    00270   ~TileLayoutSpriteGroup();
    00271
    00272   byte num_building_stages;
    00273   struct DrawTileSprites *dts;
    00274 };
    00275
    00276 struct IndustryProductionSpriteGroup : SpriteGroup {
    00277   IndustryProductionSpriteGroup() : SpriteGroup(SGT_INDUSTRY_PRODUCTION) {}
    00278
    00279   uint8 version;
    00280   int16 subtract_input[3];  // signed
    00281   uint16 add_output[2];     // unsigned
    00282   uint8 again;
    00283 };
    00284
    00285
    00286 struct ResolverObject {
    00287   CallbackID callback;
    00288   uint32 callback_param1;
    00289   uint32 callback_param2;
    00290
    00291   byte trigger;
    00292
    00293   uint32 last_value;
    00294   uint32 reseed;
    00295
    00296   VarSpriteGroupScope scope;
    00297   byte count;
    00298
    00299   BaseStorageArray *psa;
    00300
    00301   const GRFFile *grffile;
    00302
    00303   union {
    00304     struct {
    00305       const struct Vehicle *self;
    00306       const struct Vehicle *parent;
    00307       EngineID self_type;
    00308       bool info_view;
    00309     } vehicle;
    00310     struct {
    00311       TileIndex tile;
    00312     } canal;
    00313     struct {
    00314       TileIndex tile;
    00315       const struct BaseStation *st;
    00316       const struct StationSpec *statspec;
    00317       CargoID cargo_type;
    00318     } station;
    00319     struct {
    00320       TileIndex tile;
    00321       Town *town;
    00322       HouseID house_id;
    00323       bool not_yet_constructed;
    00324     } house;
    00325     struct {
    00326       TileIndex tile;
    00327       Industry *ind;
    00328       IndustryGfx gfx;
    00329       IndustryType type;
    00330     } industry;
    00331     struct {
    00332       const struct CargoSpec *cs;
    00333     } cargo;
    00334     struct {
    00335       CargoID cargo_type;
    00336       uint8 default_selection;
    00337       IndustryType src_industry;
    00338       IndustryType dst_industry;
    00339       uint8 distance;
    00340       AIConstructionEvent event;
    00341       uint8 count;
    00342       uint8 station_size;
    00343     } generic;
    00344     struct {
    00345       TileIndex tile;
    00346       TileContext context;
    00347     } routes;
    00348   } u;
    00349
    00350   uint32 (*GetRandomBits)(const struct ResolverObject*);
    00351   uint32 (*GetTriggers)(const struct ResolverObject*);
    00352   void (*SetTriggers)(const struct ResolverObject*, int);
    00353   uint32 (*GetVariable)(const struct ResolverObject*, byte, byte, bool*);
    00354   const SpriteGroup *(*ResolveReal)(const struct ResolverObject*, const RealSpriteGroup*);
    00355 };
    00356
    00357 #endif /* NEWGRF_SPRITEGROUP_H */