OpenTTD
newgrf_spritegroup.h
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * 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.
4  * 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.
5  * 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/>.
6  */
7 
10 #ifndef NEWGRF_SPRITEGROUP_H
11 #define NEWGRF_SPRITEGROUP_H
12 
13 #include "town_type.h"
14 #include "engine_type.h"
15 #include "house_type.h"
16 #include "industry_type.h"
17 
18 #include "newgrf_callbacks.h"
19 #include "newgrf_generic.h"
20 #include "newgrf_storage.h"
21 #include "newgrf_commons.h"
22 
29 static inline uint32 GetRegister(uint i)
30 {
31  extern TemporaryStorageArray<int32, 0x110> _temp_store;
32  return _temp_store.GetValue(i);
33 }
34 
35 /* List of different sprite group types */
36 enum SpriteGroupType {
37  SGT_REAL,
38  SGT_DETERMINISTIC,
39  SGT_RANDOMIZED,
40  SGT_CALLBACK,
41  SGT_RESULT,
42  SGT_TILELAYOUT,
43  SGT_INDUSTRY_PRODUCTION,
44 };
45 
46 struct SpriteGroup;
47 typedef uint32 SpriteGroupID;
48 struct ResolverObject;
49 
50 /* SPRITE_WIDTH is 24. ECS has roughly 30 sprite groups per real sprite.
51  * Adding an 'extra' margin would be assuming 64 sprite groups per real
52  * sprite. 64 = 2^6, so 2^30 should be enough (for now) */
54 extern SpriteGroupPool _spritegroup_pool;
55 
56 /* Common wrapper for all the different sprite group types */
57 struct SpriteGroup : SpriteGroupPool::PoolItem<&_spritegroup_pool> {
58 protected:
59  SpriteGroup(SpriteGroupType type) : type(type) {}
61  virtual const SpriteGroup *Resolve(ResolverObject &object) const { return this; };
62 
63 public:
64  virtual ~SpriteGroup() {}
65 
66  SpriteGroupType type;
67 
68  virtual SpriteID GetResult() const { return 0; }
69  virtual byte GetNumResults() const { return 0; }
70  virtual uint16 GetCallbackResult() const { return CALLBACK_FAILED; }
71 
72  static const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject &object, bool top_level = true);
73 };
74 
75 
76 /* 'Real' sprite groups contain a list of other result or callback sprite
77  * groups. */
79  RealSpriteGroup() : SpriteGroup(SGT_REAL) {}
80  ~RealSpriteGroup();
81 
82  /* Loaded = in motion, loading = not moving
83  * Each group contains several spritesets, for various loading stages */
84 
85  /* XXX: For stations the meaning is different - loaded is for stations
86  * with small amount of cargo whilst loading is for stations with a lot
87  * of da stuff. */
88 
89  byte num_loaded;
90  byte num_loading;
91  const SpriteGroup **loaded;
92  const SpriteGroup **loading;
93 
94 protected:
95  const SpriteGroup *Resolve(ResolverObject &object) const;
96 };
97 
98 /* Shared by deterministic and random groups. */
100  VSG_BEGIN,
101 
102  VSG_SCOPE_SELF = VSG_BEGIN,
105 
106  VSG_END
107 };
109 
110 enum DeterministicSpriteGroupSize {
111  DSG_SIZE_BYTE,
112  DSG_SIZE_WORD,
113  DSG_SIZE_DWORD,
114 };
115 
116 enum DeterministicSpriteGroupAdjustType {
117  DSGA_TYPE_NONE,
118  DSGA_TYPE_DIV,
119  DSGA_TYPE_MOD,
120 };
121 
146 };
147 
148 
151  DeterministicSpriteGroupAdjustType type;
152  byte variable;
153  byte parameter;
154  byte shift_num;
155  uint32 and_mask;
156  uint32 add_val;
157  uint32 divmod_val;
158  const SpriteGroup *subroutine;
159 };
160 
161 
163  const SpriteGroup *group;
164  uint32 low;
165  uint32 high;
166 };
167 
168 
170  DeterministicSpriteGroup() : SpriteGroup(SGT_DETERMINISTIC) {}
172 
173  VarSpriteGroupScope var_scope;
174  DeterministicSpriteGroupSize size;
175  uint num_adjusts;
176  uint num_ranges;
177  bool calculated_result;
179  DeterministicSpriteGroupRange *ranges; // Dynamically allocated
180 
181  /* Dynamically allocated, this is the sole owner */
182  const SpriteGroup *default_group;
183 
184  const SpriteGroup *error_group; // was first range, before sorting ranges
185 
186 protected:
187  const SpriteGroup *Resolve(ResolverObject &object) const;
188 };
189 
190 enum RandomizedSpriteGroupCompareMode {
191  RSG_CMP_ANY,
192  RSG_CMP_ALL,
193 };
194 
196  RandomizedSpriteGroup() : SpriteGroup(SGT_RANDOMIZED) {}
198 
200 
201  RandomizedSpriteGroupCompareMode cmp_mode;
202  byte triggers;
203  byte count;
204 
206  byte num_groups;
207 
208  const SpriteGroup **groups;
209 
210 protected:
211  const SpriteGroup *Resolve(ResolverObject &object) const;
212 };
213 
214 
215 /* This contains a callback result. A failed callback has a value of
216  * CALLBACK_FAILED */
223  CallbackResultSpriteGroup(uint16 value, bool grf_version8) :
224  SpriteGroup(SGT_CALLBACK),
225  result(value)
226  {
227  /* Old style callback results (only valid for version < 8) have the highest byte 0xFF so signify it is a callback result.
228  * New style ones only have the highest bit set (allows 15-bit results, instead of just 8) */
229  if (!grf_version8 && (this->result >> 8) == 0xFF) {
230  this->result &= ~0xFF00;
231  } else {
232  this->result &= ~0x8000;
233  }
234  }
235 
236  uint16 result;
237  uint16 GetCallbackResult() const { return this->result; }
238 };
239 
240 
241 /* A result sprite group returns the first SpriteID and the number of
242  * sprites in the set */
250  ResultSpriteGroup(SpriteID sprite, byte num_sprites) :
251  SpriteGroup(SGT_RESULT),
252  sprite(sprite),
253  num_sprites(num_sprites)
254  {
255  }
256 
257  SpriteID sprite;
258  byte num_sprites;
259  SpriteID GetResult() const { return this->sprite; }
260  byte GetNumResults() const { return this->num_sprites; }
261 };
262 
267  TileLayoutSpriteGroup() : SpriteGroup(SGT_TILELAYOUT) {}
269 
270  NewGRFSpriteLayout dts;
271 
272  const DrawTileSprites *ProcessRegisters(uint8 *stage) const;
273 };
274 
276  IndustryProductionSpriteGroup() : SpriteGroup(SGT_INDUSTRY_PRODUCTION) {}
277 
278  uint8 version;
279  uint8 num_input;
280  int16 subtract_input[INDUSTRY_NUM_INPUTS];
282  uint8 num_output;
283  uint16 add_output[INDUSTRY_NUM_OUTPUTS];
285  uint8 again;
286 
287 };
288 
297 
298  ScopeResolver(ResolverObject &ro) : ro(ro) {}
299  virtual ~ScopeResolver() {}
300 
301  virtual uint32 GetRandomBits() const;
302  virtual uint32 GetTriggers() const;
303 
304  virtual uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
305  virtual void StorePSA(uint reg, int32 value);
306 };
307 
322  ResolverObject(const GRFFile *grffile, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0)
323  : default_scope(*this), callback(callback), callback_param1(callback_param1), callback_param2(callback_param2), grffile(grffile), root_spritegroup(nullptr)
324  {
325  this->ResetState();
326  }
327 
328  virtual ~ResolverObject() {}
329 
331 
335 
336  uint32 last_value;
337 
339  uint32 used_triggers;
340  uint32 reseed[VSG_END];
341 
342  const GRFFile *grffile;
344 
350  {
351  return SpriteGroup::Resolve(this->root_spritegroup, *this);
352  }
353 
359  {
360  const SpriteGroup *result = Resolve();
361  return result != nullptr ? result->GetCallbackResult() : CALLBACK_FAILED;
362  }
363 
364  virtual const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const;
365 
366  virtual ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0);
367 
371  uint32 GetRemainingTriggers() const
372  {
373  return this->waiting_triggers & ~this->used_triggers;
374  }
375 
381  uint32 GetReseedSum() const
382  {
383  uint32 sum = 0;
384  for (VarSpriteGroupScope vsg = VSG_BEGIN; vsg < VSG_END; vsg++) {
385  sum |= this->reseed[vsg];
386  }
387  return sum;
388  }
389 
394  void ResetState()
395  {
396  this->last_value = 0;
397  this->waiting_triggers = 0;
398  this->used_triggers = 0;
399  memset(this->reseed, 0, sizeof(this->reseed));
400  }
401 };
402 
403 #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:38
(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:39
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:58
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:188
uint32 last_value
Result of most recent DeterministicSpriteGroup (including procedure calls)
Base class for all pools.
Definition: pool_type.hpp:82
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:17
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:14
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:20
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:105