newgrf_spritegroup.h

Go to the documentation of this file.
00001 /* $Id: newgrf_spritegroup.h 23735 2012-01-03 20:26:05Z 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 "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 
00305 struct ResolverObject {
00306   CallbackID callback;
00307   uint32 callback_param1;
00308   uint32 callback_param2;
00309 
00310   byte trigger;
00311 
00312   uint32 last_value;          
00313   uint32 reseed[VSG_END];     
00314 
00315   VarSpriteGroupScope scope;  
00316   byte count;                 
00317 
00318   const GRFFile *grffile;     
00319 
00320   union {
00321     struct {
00322       const struct Vehicle *self;
00323       const struct Vehicle *parent;
00324       EngineID self_type;
00325       bool info_view;                
00326     } vehicle;
00327     struct {
00328       TileIndex tile;
00329     } canal;
00330     struct {
00331       TileIndex tile;
00332       struct BaseStation *st;
00333       const struct StationSpec *statspec;
00334       CargoID cargo_type;
00335       Axis axis;                     
00336     } station;
00337     struct {
00338       TileIndex tile;
00339       Town *town;                    
00340       HouseID house_id;
00341       uint16 initial_random_bits;    
00342       bool not_yet_constructed;      
00343       uint32 watched_cargo_triggers; 
00344     } house;
00345     struct {
00346       TileIndex tile;
00347       Industry *ind;
00348       IndustryGfx gfx;
00349       IndustryType type;
00350     } industry;
00351     struct {
00352       const struct CargoSpec *cs;
00353     } cargo;
00354     struct {
00355       CargoID cargo_type;
00356       uint8 default_selection;
00357       uint8 src_industry;            
00358       uint8 dst_industry;            
00359       uint8 distance;
00360       AIConstructionEvent event;
00361       uint8 count;
00362       uint8 station_size;
00363     } generic;
00364     struct {
00365       TileIndex tile;                
00366       TileContext context;           
00367     } routes;
00368     struct {
00369       struct Station *st;            
00370       byte airport_id;               
00371       byte layout;                   
00372       TileIndex tile;                
00373     } airport;
00374     struct {
00375       struct Object *o;              
00376       TileIndex tile;                
00377       uint8 view;                    
00378     } object;
00379   } u;
00380 
00381   uint32 (*GetRandomBits)(const struct ResolverObject*);
00382   uint32 (*GetTriggers)(const struct ResolverObject*);
00383   void (*SetTriggers)(const struct ResolverObject*, int);
00384   uint32 (*GetVariable)(const struct ResolverObject *object, byte variable, uint32 parameter, bool *available);
00385   const SpriteGroup *(*ResolveReal)(const struct ResolverObject*, const RealSpriteGroup*);
00386   void (*StorePSA)(struct ResolverObject*, uint, int32);
00387 
00393   uint32 GetReseedSum() const
00394   {
00395     uint32 sum = 0;
00396     for (VarSpriteGroupScope vsg = VSG_BEGIN; vsg < VSG_END; vsg++) {
00397       sum |= this->reseed[vsg];
00398     }
00399     return sum;
00400   }
00401 
00406   void ResetState()
00407   {
00408     this->last_value = 0;
00409     this->trigger    = 0;
00410     memset(this->reseed, 0, sizeof(this->reseed));
00411   }
00412 };
00413 
00414 #endif /* NEWGRF_SPRITEGROUP_H */