# newgrf_spritegroup.h

Go to the documentation of this file.

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