OpenTTD Source  1.10.0-RC1
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) : nfo_line(0), type(type) {}
61  virtual const SpriteGroup *Resolve(ResolverObject &object) const { return this; };
62 
63 public:
64  virtual ~SpriteGroup() {}
65 
66  uint32 nfo_line;
67  SpriteGroupType type;
68 
69  virtual SpriteID GetResult() const { return 0; }
70  virtual byte GetNumResults() const { return 0; }
71  virtual uint16 GetCallbackResult() const { return CALLBACK_FAILED; }
72 
73  static const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject &object, bool top_level = true);
74 };
75 
76 
77 /* 'Real' sprite groups contain a list of other result or callback sprite
78  * groups. */
80  RealSpriteGroup() : SpriteGroup(SGT_REAL) {}
81  ~RealSpriteGroup();
82 
83  /* Loaded = in motion, loading = not moving
84  * Each group contains several spritesets, for various loading stages */
85 
86  /* XXX: For stations the meaning is different - loaded is for stations
87  * with small amount of cargo whilst loading is for stations with a lot
88  * of da stuff. */
89 
90  byte num_loaded;
91  byte num_loading;
92  const SpriteGroup **loaded;
93  const SpriteGroup **loading;
94 
95 protected:
96  const SpriteGroup *Resolve(ResolverObject &object) const;
97 };
98 
99 /* Shared by deterministic and random groups. */
101  VSG_BEGIN,
102 
103  VSG_SCOPE_SELF = VSG_BEGIN,
106 
107  VSG_END
108 };
110 
111 enum DeterministicSpriteGroupSize {
112  DSG_SIZE_BYTE,
113  DSG_SIZE_WORD,
114  DSG_SIZE_DWORD,
115 };
116 
117 enum DeterministicSpriteGroupAdjustType {
118  DSGA_TYPE_NONE,
119  DSGA_TYPE_DIV,
120  DSGA_TYPE_MOD,
121 };
122 
147 };
148 
149 
152  DeterministicSpriteGroupAdjustType type;
153  byte variable;
154  byte parameter;
155  byte shift_num;
156  uint32 and_mask;
157  uint32 add_val;
158  uint32 divmod_val;
159  const SpriteGroup *subroutine;
160 };
161 
162 
164  const SpriteGroup *group;
165  uint32 low;
166  uint32 high;
167 };
168 
169 
171  DeterministicSpriteGroup() : SpriteGroup(SGT_DETERMINISTIC) {}
173 
174  VarSpriteGroupScope var_scope;
175  DeterministicSpriteGroupSize size;
176  uint num_adjusts;
177  uint num_ranges;
178  bool calculated_result;
180  DeterministicSpriteGroupRange *ranges; // Dynamically allocated
181 
182  /* Dynamically allocated, this is the sole owner */
183  const SpriteGroup *default_group;
184 
185  const SpriteGroup *error_group; // was first range, before sorting ranges
186 
187 protected:
188  const SpriteGroup *Resolve(ResolverObject &object) const;
189 };
190 
191 enum RandomizedSpriteGroupCompareMode {
192  RSG_CMP_ANY,
193  RSG_CMP_ALL,
194 };
195 
197  RandomizedSpriteGroup() : SpriteGroup(SGT_RANDOMIZED) {}
199 
201 
202  RandomizedSpriteGroupCompareMode cmp_mode;
203  byte triggers;
204  byte count;
205 
207  byte num_groups;
208 
209  const SpriteGroup **groups;
210 
211 protected:
212  const SpriteGroup *Resolve(ResolverObject &object) const;
213 };
214 
215 
216 /* This contains a callback result. A failed callback has a value of
217  * CALLBACK_FAILED */
224  CallbackResultSpriteGroup(uint16 value, bool grf_version8) :
225  SpriteGroup(SGT_CALLBACK),
226  result(value)
227  {
228  /* Old style callback results (only valid for version < 8) have the highest byte 0xFF so signify it is a callback result.
229  * New style ones only have the highest bit set (allows 15-bit results, instead of just 8) */
230  if (!grf_version8 && (this->result >> 8) == 0xFF) {
231  this->result &= ~0xFF00;
232  } else {
233  this->result &= ~0x8000;
234  }
235  }
236 
237  uint16 result;
238  uint16 GetCallbackResult() const { return this->result; }
239 };
240 
241 
242 /* A result sprite group returns the first SpriteID and the number of
243  * sprites in the set */
251  ResultSpriteGroup(SpriteID sprite, byte num_sprites) :
252  SpriteGroup(SGT_RESULT),
253  sprite(sprite),
254  num_sprites(num_sprites)
255  {
256  }
257 
258  SpriteID sprite;
259  byte num_sprites;
260  SpriteID GetResult() const { return this->sprite; }
261  byte GetNumResults() const { return this->num_sprites; }
262 };
263 
268  TileLayoutSpriteGroup() : SpriteGroup(SGT_TILELAYOUT) {}
270 
271  NewGRFSpriteLayout dts;
272 
273  const DrawTileSprites *ProcessRegisters(uint8 *stage) const;
274 };
275 
277  IndustryProductionSpriteGroup() : SpriteGroup(SGT_INDUSTRY_PRODUCTION) {}
278 
279  uint8 version;
280  uint8 num_input;
281  int16 subtract_input[INDUSTRY_NUM_INPUTS];
283  uint8 num_output;
284  uint16 add_output[INDUSTRY_NUM_OUTPUTS];
286  uint8 again;
287 
288 };
289 
298 
299  ScopeResolver(ResolverObject &ro) : ro(ro) {}
300  virtual ~ScopeResolver() {}
301 
302  virtual uint32 GetRandomBits() const;
303  virtual uint32 GetTriggers() const;
304 
305  virtual uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
306  virtual void StorePSA(uint reg, int32 value);
307 };
308 
323  ResolverObject(const GRFFile *grffile, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0)
324  : default_scope(*this), callback(callback), callback_param1(callback_param1), callback_param2(callback_param2), grffile(grffile), root_spritegroup(nullptr)
325  {
326  this->ResetState();
327  }
328 
329  virtual ~ResolverObject() {}
330 
332 
336 
337  uint32 last_value;
338 
340  uint32 used_triggers;
341  uint32 reseed[VSG_END];
342 
343  const GRFFile *grffile;
345 
351  {
352  return SpriteGroup::Resolve(this->root_spritegroup, *this);
353  }
354 
360  {
361  const SpriteGroup *result = Resolve();
362  return result != nullptr ? result->GetCallbackResult() : CALLBACK_FAILED;
363  }
364 
365  virtual const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const;
366 
367  virtual ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0);
368 
372  uint32 GetRemainingTriggers() const
373  {
374  return this->waiting_triggers & ~this->used_triggers;
375  }
376 
382  uint32 GetReseedSum() const
383  {
384  uint32 sum = 0;
385  for (VarSpriteGroupScope vsg = VSG_BEGIN; vsg < VSG_END; vsg++) {
386  sum |= this->reseed[vsg];
387  }
388  return sum;
389  }
390 
395  void ResetState()
396  {
397  this->last_value = 0;
398  this->waiting_triggers = 0;
399  this->used_triggers = 0;
400  memset(this->reseed, 0, sizeof(this->reseed));
401  }
402 
407  virtual GrfSpecFeature GetFeature() const { return GSF_INVALID; }
413  virtual uint32 GetDebugID() const { return 0; }
414 };
415 
416 #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
An invalid spec feature.
Definition: newgrf.h:92
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.
GrfSpecFeature
Definition: newgrf.h:66
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:226
uint32 last_value
Result of most recent DeterministicSpriteGroup (including procedure calls)
Base class for all pools.
Definition: pool_type.hpp:81
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.
virtual GrfSpecFeature GetFeature() const
Get the feature number being resolved for.
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
virtual uint32 GetDebugID() const
Get an identifier for the item being resolved.
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