OpenTTD
newgrf_spritegroup.h
Go to the documentation of this file.
1 /* $Id$ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #ifndef NEWGRF_SPRITEGROUP_H
13 #define NEWGRF_SPRITEGROUP_H
14 
15 #include "town_type.h"
16 #include "engine_type.h"
17 #include "house_type.h"
18 #include "industry_type.h"
19 
20 #include "newgrf_callbacks.h"
21 #include "newgrf_generic.h"
22 #include "newgrf_storage.h"
23 #include "newgrf_commons.h"
24 
31 static inline uint32 GetRegister(uint i)
32 {
33  extern TemporaryStorageArray<int32, 0x110> _temp_store;
34  return _temp_store.GetValue(i);
35 }
36 
37 /* List of different sprite group types */
38 enum SpriteGroupType {
39  SGT_REAL,
40  SGT_DETERMINISTIC,
41  SGT_RANDOMIZED,
42  SGT_CALLBACK,
43  SGT_RESULT,
44  SGT_TILELAYOUT,
45  SGT_INDUSTRY_PRODUCTION,
46 };
47 
48 struct SpriteGroup;
49 typedef uint32 SpriteGroupID;
50 struct ResolverObject;
51 
52 /* SPRITE_WIDTH is 24. ECS has roughly 30 sprite groups per real sprite.
53  * Adding an 'extra' margin would be assuming 64 sprite groups per real
54  * sprite. 64 = 2^6, so 2^30 should be enough (for now) */
56 extern SpriteGroupPool _spritegroup_pool;
57 
58 /* Common wrapper for all the different sprite group types */
59 struct SpriteGroup : SpriteGroupPool::PoolItem<&_spritegroup_pool> {
60 protected:
61  SpriteGroup(SpriteGroupType type) : type(type) {}
63  virtual const SpriteGroup *Resolve(ResolverObject &object) const { return this; };
64 
65 public:
66  virtual ~SpriteGroup() {}
67 
68  SpriteGroupType type;
69 
70  virtual SpriteID GetResult() const { return 0; }
71  virtual byte GetNumResults() const { return 0; }
72  virtual uint16 GetCallbackResult() const { return CALLBACK_FAILED; }
73 
74  static const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject &object, bool top_level = true);
75 };
76 
77 
78 /* 'Real' sprite groups contain a list of other result or callback sprite
79  * groups. */
81  RealSpriteGroup() : SpriteGroup(SGT_REAL) {}
82  ~RealSpriteGroup();
83 
84  /* Loaded = in motion, loading = not moving
85  * Each group contains several spritesets, for various loading stages */
86 
87  /* XXX: For stations the meaning is different - loaded is for stations
88  * with small amount of cargo whilst loading is for stations with a lot
89  * of da stuff. */
90 
91  byte num_loaded;
92  byte num_loading;
93  const SpriteGroup **loaded;
94  const SpriteGroup **loading;
95 
96 protected:
97  const SpriteGroup *Resolve(ResolverObject &object) const;
98 };
99 
100 /* Shared by deterministic and random groups. */
102  VSG_BEGIN,
103 
104  VSG_SCOPE_SELF = VSG_BEGIN,
107 
108  VSG_END
109 };
111 
112 enum DeterministicSpriteGroupSize {
113  DSG_SIZE_BYTE,
114  DSG_SIZE_WORD,
115  DSG_SIZE_DWORD,
116 };
117 
118 enum DeterministicSpriteGroupAdjustType {
119  DSGA_TYPE_NONE,
120  DSGA_TYPE_DIV,
121  DSGA_TYPE_MOD,
122 };
123 
148 };
149 
150 
153  DeterministicSpriteGroupAdjustType type;
154  byte variable;
155  byte parameter;
156  byte shift_num;
157  uint32 and_mask;
158  uint32 add_val;
159  uint32 divmod_val;
160  const SpriteGroup *subroutine;
161 };
162 
163 
165  const SpriteGroup *group;
166  uint32 low;
167  uint32 high;
168 };
169 
170 
172  DeterministicSpriteGroup() : SpriteGroup(SGT_DETERMINISTIC) {}
174 
175  VarSpriteGroupScope var_scope;
176  DeterministicSpriteGroupSize size;
177  uint num_adjusts;
178  uint num_ranges;
179  bool calculated_result;
181  DeterministicSpriteGroupRange *ranges; // Dynamically allocated
182 
183  /* Dynamically allocated, this is the sole owner */
184  const SpriteGroup *default_group;
185 
186  const SpriteGroup *error_group; // was first range, before sorting ranges
187 
188 protected:
189  const SpriteGroup *Resolve(ResolverObject &object) const;
190 };
191 
192 enum RandomizedSpriteGroupCompareMode {
193  RSG_CMP_ANY,
194  RSG_CMP_ALL,
195 };
196 
198  RandomizedSpriteGroup() : SpriteGroup(SGT_RANDOMIZED) {}
200 
202 
203  RandomizedSpriteGroupCompareMode cmp_mode;
204  byte triggers;
205  byte count;
206 
208  byte num_groups;
209 
210  const SpriteGroup **groups;
211 
212 protected:
213  const SpriteGroup *Resolve(ResolverObject &object) const;
214 };
215 
216 
217 /* This contains a callback result. A failed callback has a value of
218  * CALLBACK_FAILED */
225  CallbackResultSpriteGroup(uint16 value, bool grf_version8) :
226  SpriteGroup(SGT_CALLBACK),
227  result(value)
228  {
229  /* Old style callback results (only valid for version < 8) have the highest byte 0xFF so signify it is a callback result.
230  * New style ones only have the highest bit set (allows 15-bit results, instead of just 8) */
231  if (!grf_version8 && (this->result >> 8) == 0xFF) {
232  this->result &= ~0xFF00;
233  } else {
234  this->result &= ~0x8000;
235  }
236  }
237 
238  uint16 result;
239  uint16 GetCallbackResult() const { return this->result; }
240 };
241 
242 
243 /* A result sprite group returns the first SpriteID and the number of
244  * sprites in the set */
252  ResultSpriteGroup(SpriteID sprite, byte num_sprites) :
253  SpriteGroup(SGT_RESULT),
254  sprite(sprite),
255  num_sprites(num_sprites)
256  {
257  }
258 
259  SpriteID sprite;
260  byte num_sprites;
261  SpriteID GetResult() const { return this->sprite; }
262  byte GetNumResults() const { return this->num_sprites; }
263 };
264 
269  TileLayoutSpriteGroup() : SpriteGroup(SGT_TILELAYOUT) {}
271 
272  NewGRFSpriteLayout dts;
273 
274  const DrawTileSprites *ProcessRegisters(uint8 *stage) const;
275 };
276 
278  IndustryProductionSpriteGroup() : SpriteGroup(SGT_INDUSTRY_PRODUCTION) {}
279 
280  uint8 version;
281  uint8 num_input;
282  int16 subtract_input[INDUSTRY_NUM_INPUTS];
284  uint8 num_output;
285  uint16 add_output[INDUSTRY_NUM_OUTPUTS];
287  uint8 again;
288 
289 };
290 
299 
300  ScopeResolver(ResolverObject &ro) : ro(ro) {}
301  virtual ~ScopeResolver() {}
302 
303  virtual uint32 GetRandomBits() const;
304  virtual uint32 GetTriggers() const;
305 
306  virtual uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
307  virtual void StorePSA(uint reg, int32 value);
308 };
309 
324  ResolverObject(const GRFFile *grffile, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0)
325  : default_scope(*this), callback(callback), callback_param1(callback_param1), callback_param2(callback_param2), grffile(grffile), root_spritegroup(NULL)
326  {
327  this->ResetState();
328  }
329 
330  virtual ~ResolverObject() {}
331 
333 
337 
338  uint32 last_value;
339 
341  uint32 used_triggers;
342  uint32 reseed[VSG_END];
343 
344  const GRFFile *grffile;
346 
352  {
353  return SpriteGroup::Resolve(this->root_spritegroup, *this);
354  }
355 
361  {
362  const SpriteGroup *result = Resolve();
363  return result != NULL ? result->GetCallbackResult() : CALLBACK_FAILED;
364  }
365 
366  virtual const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const;
367 
368  virtual ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0);
369 
373  uint32 GetRemainingTriggers() const
374  {
375  return this->waiting_triggers & ~this->used_triggers;
376  }
377 
383  uint32 GetReseedSum() const
384  {
385  uint32 sum = 0;
386  for (VarSpriteGroupScope vsg = VSG_BEGIN; vsg < VSG_END; vsg++) {
387  sum |= this->reseed[vsg];
388  }
389  return sum;
390  }
391 
396  void ResetState()
397  {
398  this->last_value = 0;
399  this->waiting_triggers = 0;
400  this->used_triggers = 0;
401  memset(this->reseed, 0, sizeof(this->reseed));
402  }
403 };
404 
405 #endif /* NEWGRF_SPRITEGROUP_H */
rotate a b positions to the right
Interface to query and set values specific to a single VarSpriteGroupScope (action 2 scope)...
const SpriteGroup ** groups
Take the group with appropriate index:
static const uint CALLBACK_FAILED
Different values for Callback result evaluations.
Types related to the industry.
static const int INDUSTRY_NUM_INPUTS
Number of cargo types an industry can accept.
Definition: industry_type.h:40
(unsigned) a & b
ResolverObject & ro
Surrounding resolver object.
Types related to towns.
VarSpriteGroupScope
ScopeResolver default_scope
Default implementation of the grf scope.
ResultSpriteGroup(SpriteID sprite, byte num_sprites)
Creates a spritegroup representing a sprite number result.
Functionality related to the temporary and persistent storage arrays for NewGRFs. ...
Class for temporary storage of data.
Interface for SpriteGroup-s to access the gamestate.
Types related to engines.
declaration of basic house types and enums
Set when using the callback resolve system, but not to resolve a callback.
(unsigned) comparison (a < b -> 0, a == b = 1, a > b = 2)
(signed) a / b
Relative position (vehicles only)
byte num_loaded
Number of loaded groups.
const SpriteGroup * Resolve()
Resolve SpriteGroup.
static const int INDUSTRY_NUM_OUTPUTS
Number of cargo types an industry can produce.
Definition: industry_type.h:41
Callbacks that NewGRFs could implement.
byte lowest_randbit
Look for this in the per-object randomized bitmask:
(signed) a >> b
uint32 callback_param1
First parameter (var 10) of the callback.
const SpriteGroup * root_spritegroup
Root SpriteGroup to use for resolving.
uint8 num_output
How many add_output values are valid.
uint32 callback_param2
Second parameter (var 18) of the callback.
static uint32 GetRegister(uint i)
Gets the value of a so-called newgrf "register".
virtual const SpriteGroup * Resolve(ResolverObject &object) const
Base sprite group resolver.
const SpriteGroup ** loaded
List of loaded groups (can be SpriteIDs or Callback results)
Ground palette sprite of a tile, together with its sprite layout.
Definition: sprite.h:60
CallbackResultSpriteGroup(uint16 value, bool grf_version8)
Creates a spritegroup representing a callback result.
(signed) a % b
DeterministicSpriteGroupAdjustOperation
uint32 waiting_triggers
Waiting triggers to be used by any rerandomisation. (scope independent)
ResolverObject(const GRFFile *grffile, CallbackID callback=CBID_NO_CALLBACK, uint32 callback_param1=0, uint32 callback_param2=0)
Resolver constructor.
uint32 used_triggers
Subset of cur_triggers, which actually triggered some rerandomisation. (scope independent) ...
(signed) min(a, b)
const SpriteGroup ** loading
List of loading groups (can be SpriteIDs or Callback results)
store a into temporary storage, indexed by b. return a
Resolved object itself.
uint32 GetReseedSum() const
Returns the OR-sum of all bits that need reseeding independent of the scope they were accessed with...
(unsigned) min(a, b)
NewGRF supplied spritelayout.
Base class for all PoolItems.
Definition: pool_type.hpp:146
uint32 last_value
Result of most recent DeterministicSpriteGroup (including procedure calls)
Base class for all pools.
Definition: pool_type.hpp:83
byte num_loading
Number of loading groups.
const GRFFile * grffile
GRFFile the resolved SpriteGroup belongs to.
Functions related to generic callbacks.
(unsigned) a / b
uint32 SpriteID
The number of a sprite, without mapping bits and colourtables.
Definition: gfx_type.h:19
RandomizedSpriteGroupCompareMode cmp_mode
Check for these triggers:
uint32 GetRemainingTriggers() const
Returns the waiting triggers that did not trigger any rerandomisation.
Related object of the resolved one.
CallbackID callback
Callback being resolved.
uint8 version
Production callback version used, or 0xFF if marked invalid.
(signed) comparison (a < b -> 0, a == b = 1, a > b = 2)
store a into persistent storage, indexed by b, return a
(unsigned) a >> b
(signed) max(a, b)
This file simplyfies and embeds a common mechanism of loading/saving and mapping of grf entities...
VarSpriteGroupScope var_scope
Take this object:
CallbackID
List of implemented NewGRF callbacks.
(unsigned) max(a, b)
byte num_groups
must be power of 2
void ResetState()
Resets the dynamic state of the resolver object.
#define DECLARE_POSTFIX_INCREMENT(enum_type)
Some enums need to have allowed incrementing (i.e.
Definition: enum_type.hpp:18
TYPE GetValue(uint pos) const
Gets the value from a given position.
byte CargoID
Cargo slots to indicate a cargo type within a game.
Definition: cargo_type.h:22
byte parameter
Used for variables between 0x60 and 0x7F inclusive.
uint8 num_input
How many subtract_input values are valid.
Action 2 sprite layout for houses, industry tiles, objects and airport tiles.
uint16 ResolveCallback()
Resolve callback.
Dynamic data of a loaded NewGRF.
Definition: newgrf.h:104