Merge road stop removal cases in BuildRoadToolbarWindow
[openttd/fttd.git] / src / newgrf_spritegroup.h
blob7f52125eaff48301f25e09ff7e65d79b068b60d1
1 /* $Id$ */
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 */
10 /** @file newgrf_spritegroup.h Action 2 handling. */
12 #ifndef NEWGRF_SPRITEGROUP_H
13 #define NEWGRF_SPRITEGROUP_H
15 #include <deque>
17 #include "core/align.h"
18 #include "core/pointer.h"
19 #include "core/flexarray.h"
21 #include "town_type.h"
22 #include "engine_type.h"
23 #include "house_type.h"
25 #include "newgrf_callbacks.h"
26 #include "newgrf_generic.h"
27 #include "newgrf_storage.h"
28 #include "newgrf_commons.h"
30 /**
31 * Gets the value of a so-called newgrf "register".
32 * @param i index of the register
33 * @pre i < 0x110
34 * @return the value of the register
36 static inline uint32 GetRegister(uint i)
38 extern TemporaryStorageArray<int32, 0x110> _temp_store;
39 return _temp_store.GetValue(i);
42 /* List of different sprite group types */
43 enum SpriteGroupType {
44 SGT_REAL,
45 SGT_DETERMINISTIC,
46 SGT_RANDOMIZED,
47 SGT_CALLBACK,
48 SGT_RESULT,
49 SGT_TILELAYOUT,
50 SGT_INDUSTRY_PRODUCTION,
53 struct SpriteGroup;
54 typedef uint32 SpriteGroupID;
55 struct ResolverObject;
57 /* SPRITE_WIDTH is 24. ECS has roughly 30 sprite groups per real sprite.
58 * Adding an 'extra' margin would be assuming 64 sprite groups per real
59 * sprite. 64 = 2^6, so 2^30 should be enough (for now) */
61 /* Common wrapper for all the different sprite group types */
62 struct SpriteGroup {
63 protected:
64 static const size_t MAX_SIZE = 1 << 30;
66 static std::deque <ttd_unique_ptr <SpriteGroup> > pool;
68 /**
69 * Append a new sprite group to the pool.
70 * @param group The sprite group to append.
71 * @return The sprite group itself, for the convenience of our callers.
73 template <typename T>
74 static T *append (T *group)
76 assert (pool.size() < MAX_SIZE);
77 pool.push_back (ttd_unique_ptr <SpriteGroup> (group));
78 return group;
81 const SpriteGroupType type; ///< Type of the sprite group
83 CONSTEXPR SpriteGroup (SpriteGroupType type) : type (type)
87 /** Base sprite group resolver */
88 virtual const SpriteGroup *Resolve (ResolverObject &object) const
90 return this;
93 public:
94 virtual ~SpriteGroup()
98 bool IsType (SpriteGroupType type) const
100 return this->type == type;
103 virtual SpriteID GetResult (void) const
105 return 0;
108 virtual byte GetNumResults (void) const
110 return 0;
113 virtual uint16 GetCallbackResult (void) const
115 return CALLBACK_FAILED;
118 static const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject &object, bool top_level = true);
121 * Get a callback result from a SpriteGroup.
122 * @return Callback result.
124 static uint16 CallbackResult (const SpriteGroup *result)
126 return result != NULL ? result->GetCallbackResult() : CALLBACK_FAILED;
129 /** Clear the sprite group pool. */
130 static void clear (void)
132 pool.clear();
137 /* 'Real' sprite groups contain a list of other result or callback sprite
138 * groups. */
139 struct RealSpriteGroup : SpriteGroup, FlexArray <SpriteGroup *> {
140 private:
141 /* Loaded = in motion, loading = not moving
142 * Each group contains several spritesets, for various loading stages */
144 /* XXX: For stations the meaning is different - loaded is for stations
145 * with small amount of cargo whilst loading is for stations with a lot
146 * of da stuff. */
148 const uint16 n; ///< Total number of groups
149 const byte n1; ///< Number of loaded groups
150 const byte n2; ///< Number of loading groups
151 const SpriteGroup *groups[]; ///< List of groups (can be SpriteIDs or Callback results)
153 RealSpriteGroup (uint16 n, byte n1, byte n2)
154 : SpriteGroup (SGT_REAL), n (n), n1 (n1), n2 (n2)
156 memset (this->groups, 0, n * sizeof(SpriteGroup *));
159 protected:
160 const SpriteGroup *Resolve (ResolverObject &object) const OVERRIDE;
162 public:
163 static RealSpriteGroup *create (byte n1, byte n2)
165 uint16 total = (uint16)n1 + (uint16)n2;
166 return SpriteGroup::append (new (total) RealSpriteGroup (total, n1, n2));
169 void set (uint i, const SpriteGroup *group)
171 this->groups[i] = group;
175 * Get the count of sprite groups.
176 * @param alt Count the groups in the second (loading) set.
177 * @return The count of sprite groups in the set.
179 uint get_count (bool alt) const
181 return alt ? this->n2 : this->n1;
185 * Get a particular sprite group.
186 * @param alt Look for the group in the second (loading) set.
187 * @param i Index of the sprite group to get.
188 * @return The requested sprite group.
190 const SpriteGroup *get_group (bool alt, uint i) const
192 if (alt) i += this->n1;
193 return this->groups[i];
197 * Get the first available sprite group from the first set.
198 * @return The first sprite group, or NULL if there isn't any.
200 const SpriteGroup *get_first (void) const
202 return (this->n1 != 0) ? this->groups[0] : NULL;
206 * Get the first available sprite group from either set.
207 * @param alt Try the second (loading) set of groups first.
208 * @return The first sprite group, or NULL if there isn't any.
210 const SpriteGroup *get_first (bool alt) const
212 return (alt && (this->n2 != 0)) ? this->groups[this->n1] :
213 (this->n != 0) ? this->groups[0] : NULL;
217 /* Shared by deterministic and random groups. */
218 enum VarSpriteGroupScope {
219 VSG_BEGIN,
221 VSG_SCOPE_SELF = VSG_BEGIN, ///< Resolved object itself
222 VSG_SCOPE_PARENT, ///< Related object of the resolved one
223 VSG_SCOPE_RELATIVE, ///< Relative position (vehicles only)
225 VSG_END
227 DECLARE_POSTFIX_INCREMENT(VarSpriteGroupScope)
230 struct DeterministicSpriteGroup : SpriteGroup, FlexArrayBase {
231 public:
232 struct Adjust {
233 byte operation;
234 byte type;
235 byte variable;
236 byte shift_num;
237 uint32 and_mask;
238 uint32 add_val;
239 uint32 divmod_val;
240 union {
241 byte parameter; ///< Used for variables between 0x60 and 0x7F inclusive, except 0x7E.
242 const SpriteGroup *subroutine; ///< Used for variable 0x7E.
246 struct Range {
247 const SpriteGroup *group;
248 uint32 low;
249 uint32 high;
252 private:
253 template <typename T>
254 static CONSTEXPR T *offset_pointer (void *ptr, size_t offset)
256 return (T*) (((char*)ptr) + offset);
259 const VarSpriteGroupScope var_scope; ///< Scope.
260 const byte size; ///< Logarithmic size of accumulator (0 for int8, 1 for int16, 2 for int32).
261 const SpriteGroup *default_group; ///< Default result group.
262 Adjust *const adjusts; ///< Vector of adjusts.
263 Range *const ranges; ///< Vector of result ranges.
264 const uint num_adjusts; ///< Adjust count.
265 const byte num_ranges; ///< Result range count.
267 static CONSTEXPR size_t adjusts_offset (void)
269 return ttd_align_up<Adjust> (sizeof(DeterministicSpriteGroup));
272 DeterministicSpriteGroup (bool parent_scope,
273 byte size, uint num_adjusts,
274 byte num_ranges, size_t ranges_offset)
275 : SpriteGroup (SGT_DETERMINISTIC),
276 var_scope (parent_scope ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF),
277 size (size), default_group (NULL),
278 adjusts (offset_pointer<Adjust> (this, adjusts_offset())),
279 ranges (offset_pointer<Range> (this, ranges_offset)),
280 num_adjusts (num_adjusts), num_ranges (num_ranges)
282 memset (this->adjusts, 0, num_adjusts * sizeof(Adjust));
283 memset (this->ranges, 0, num_ranges * sizeof(Range));
286 /** Custom operator new to account for the extra storage. */
287 void *operator new (size_t size, size_t total, size_t = 1)
289 assert (total >= size);
290 return ::operator new (total);
293 protected:
294 const SpriteGroup *Resolve(ResolverObject &object) const;
296 public:
297 static DeterministicSpriteGroup *create (bool parent_scope, byte size,
298 uint num_adjusts, byte num_ranges)
300 size_t adjusts_end = adjusts_offset() + num_adjusts * sizeof(Adjust);
301 size_t ranges_offset = ttd_align_up<Range> (adjusts_end);
302 size_t ranges_end = ranges_offset + num_ranges * sizeof(Range);
303 size_t total_size = ttd_align_up<DeterministicSpriteGroup> (ranges_end);
304 DeterministicSpriteGroup *group = new (total_size)
305 DeterministicSpriteGroup (parent_scope, size,
306 num_adjusts, num_ranges,
307 ranges_offset);
308 return SpriteGroup::append (group);
311 Adjust *get_adjust (uint i)
313 return &this->adjusts[i];
316 void set_range (byte i, const SpriteGroup *group, uint32 low, uint32 high)
318 Range *range = &this->ranges[i];
319 range->group = group;
320 range->low = low;
321 range->high = high;
324 void set_default (const SpriteGroup *group)
326 this->default_group = group;
331 struct RandomizedSpriteGroup : SpriteGroup, FlexArray <SpriteGroup *> {
332 private:
333 const VarSpriteGroupScope var_scope; ///< Take this object.
334 const bool cmp_mode; ///< Match all triggers, else any.
335 const byte triggers; ///< Check for these triggers.
336 const byte count;
337 const byte lowest_randbit; ///< Look for this in the per-object randomized bitmask.
338 const byte num_groups; ///< Group count; must be power of 2.
339 const SpriteGroup *groups[]; ///< Take the group with appropriate index.
341 RandomizedSpriteGroup (VarSpriteGroupScope scope, bool cmp_mode,
342 byte triggers, byte count, byte bit, byte num)
343 : SpriteGroup (SGT_RANDOMIZED), var_scope (scope),
344 cmp_mode (cmp_mode), triggers (triggers), count (count),
345 lowest_randbit (bit), num_groups (num)
347 memset (this->groups, 0, num * sizeof(SpriteGroup *));
350 protected:
351 const SpriteGroup *Resolve (ResolverObject &object) const OVERRIDE;
353 public:
355 static RandomizedSpriteGroup *create (VarSpriteGroupScope scope,
356 bool cmp_mode, byte triggers, byte count, byte bit, byte num)
358 return SpriteGroup::append (new (num)
359 RandomizedSpriteGroup (scope, cmp_mode,
360 triggers, count, bit, num));
363 void set_group (uint i, const SpriteGroup *group)
365 this->groups[i] = group;
370 /* This contains a callback result. A failed callback has a value of
371 * CALLBACK_FAILED */
372 struct CallbackResultSpriteGroup : SpriteGroup {
373 uint16 result;
375 /** Compute the result value to store based on GRF version. */
376 static CONSTEXPR uint16 compute_result (uint16 value, bool grf_version8)
378 /* Old style callback results (only valid for version < 8)
379 * have the highest byte 0xFF to signify it is a callback
380 * result. New style ones only have the highest bit set
381 * (allows 15-bit results, instead of just 8). */
382 return (!grf_version8 && (value >> 8) == 0xFF) ?
383 (value & 0xFF) : (value & 0x7FFF);
387 * Creates a spritegroup representing a callback result
388 * @param value The value that was used to represent this callback result
389 * @param grf_version8 True, if we are dealing with a new NewGRF which uses GRF version >= 8.
391 CONSTEXPR CallbackResultSpriteGroup (uint16 value, bool grf_version8)
392 : SpriteGroup (SGT_CALLBACK),
393 result (compute_result (value, grf_version8))
397 uint16 GetCallbackResult (void) const
399 return this->result;
402 static CallbackResultSpriteGroup *create (uint16 value, bool v8)
404 return SpriteGroup::append (new CallbackResultSpriteGroup (value, v8));
409 /* A result sprite group returns the first SpriteID and the number of
410 * sprites in the set */
411 struct ResultSpriteGroup : SpriteGroup {
413 * Creates a spritegroup representing a sprite number result.
414 * @param sprite The sprite number.
415 * @param num_sprites The number of sprites per set.
416 * @return A spritegroup representing the sprite number result.
418 ResultSpriteGroup(SpriteID sprite, byte num_sprites) :
419 SpriteGroup(SGT_RESULT),
420 sprite(sprite),
421 num_sprites(num_sprites)
425 SpriteID sprite;
426 byte num_sprites;
427 SpriteID GetResult() const { return this->sprite; }
428 byte GetNumResults() const { return this->num_sprites; }
430 static ResultSpriteGroup *create (SpriteID sprite, byte num_sprites)
432 return SpriteGroup::append (new ResultSpriteGroup (sprite, num_sprites));
437 * Action 2 sprite layout for houses, industry tiles, objects and airport tiles.
439 struct TileLayoutSpriteGroup : SpriteGroup, FlexArrayBase {
440 private:
441 NewGRFSpriteLayout dts;
443 template <typename T>
444 static CONSTEXPR T *offset_pointer (void *ptr, size_t offset)
446 return (T*) (((char*)ptr) + offset);
449 static CONSTEXPR size_t seq_offset (void)
451 return ttd_align_up<DrawTileSeqStruct> (sizeof(TileLayoutSpriteGroup));
454 TileLayoutSpriteGroup (const PalSpriteID &ground, uint n,
455 const DrawTileSeqStruct *seq, size_t regs_offset,
456 const TileLayoutRegisters *regs,
457 uint consistent_max_offset)
458 : SpriteGroup (SGT_TILELAYOUT)
460 this->dts.ground = ground;
462 DrawTileSeqStruct *q = offset_pointer<DrawTileSeqStruct> (this, seq_offset());
463 memcpy (q, seq, n * sizeof(DrawTileSeqStruct));
464 q[n].MakeTerminator();
465 this->dts.seq = q;
467 if (regs != NULL) {
468 TileLayoutRegisters *r = offset_pointer<TileLayoutRegisters> (this, regs_offset);
469 memcpy (r, regs, (n + 1) * sizeof(TileLayoutRegisters));
470 this->dts.registers = r;
471 } else {
472 this->dts.registers = NULL;
475 this->dts.consistent_max_offset = consistent_max_offset;
478 /** Custom operator new to account for the extra storage. */
479 void *operator new (size_t size, size_t total, size_t = 1)
481 assert (total >= size);
482 return ::operator new (total);
485 public:
486 static TileLayoutSpriteGroup *create (const PalSpriteID &ground,
487 uint n, const DrawTileSeqStruct *seq,
488 const TileLayoutRegisters *regs, uint consistent_max_offset)
490 /* Make room for terminator. */
491 size_t seq_end = seq_offset() + (n + 1) * sizeof(DrawTileSeqStruct);
493 size_t regs_offset, regs_end;
494 if (regs != NULL) {
495 regs_offset = ttd_align_up<TileLayoutRegisters> (seq_end);
496 regs_end = regs_offset + (n + 1) * sizeof(TileLayoutRegisters);
497 } else {
498 regs_offset = 0;
499 regs_end = seq_end;
502 size_t total_size = ttd_align_up<TileLayoutSpriteGroup> (regs_end);
503 TileLayoutSpriteGroup *group = new (total_size)
504 TileLayoutSpriteGroup (ground, n,
505 seq, regs_offset, regs,
506 consistent_max_offset);
507 return SpriteGroup::append (group);
510 /** Struct for resolving layouts that may need preprocessing. */
511 struct Result : private NewGRFSpriteLayout::Result {
512 const DrawTileSeqStruct *seq; ///< Array of child sprites.
513 PalSpriteID ground; ///< Ground sprite and palette.
514 byte stage; ///< Stage offset for sprites.
516 Result (const TileLayoutSpriteGroup *group, byte stage = 0);
520 struct IndustryProductionSpriteGroup : SpriteGroup {
521 int16 subtract_input[3]; // signed
522 uint16 add_output[2]; // unsigned
523 const uint8 version;
524 uint8 again;
526 IndustryProductionSpriteGroup (uint8 version)
527 : SpriteGroup (SGT_INDUSTRY_PRODUCTION),
528 version (version), again (0)
530 memset (this->subtract_input, 0, sizeof(this->subtract_input));
531 memset (this->add_output, 0, sizeof(this->add_output));
534 static IndustryProductionSpriteGroup *create (uint8 version)
536 return SpriteGroup::append (new IndustryProductionSpriteGroup (version));
541 * Interface to query and set values specific to a single #VarSpriteGroupScope (action 2 scope).
543 * Multiple of these interfaces are combined into a #ResolverObject to allow access
544 * to different game entities from a #SpriteGroup-chain (action 1-2-3 chain).
546 struct ScopeResolver {
547 virtual ~ScopeResolver()
551 virtual uint32 GetRandomBits() const;
552 virtual uint32 GetTriggers() const;
554 virtual uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
555 virtual void StorePSA(uint reg, int32 value);
559 * Interface for #SpriteGroup-s to access the gamestate.
561 * Using this interface #SpriteGroup-chains (action 1-2-3 chains) can be resolved,
562 * to get the results of callbacks, rerandomisations or normal sprite lookups.
564 struct ResolverObject {
565 const GRFFile *const grffile; ///< GRFFile the resolved SpriteGroup belongs to
567 ResolverObject(const GRFFile *grffile, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0);
568 virtual ~ResolverObject();
570 ScopeResolver default_scope; ///< Default implementation of the grf scope.
572 CallbackID callback; ///< Callback being resolved.
573 uint32 callback_param1; ///< First parameter (var 10) of the callback.
574 uint32 callback_param2; ///< Second parameter (var 18) of the callback.
576 uint32 last_value; ///< Result of most recent DeterministicSpriteGroup (including procedure calls)
578 uint32 waiting_triggers; ///< Waiting triggers to be used by any rerandomisation. (scope independent)
579 uint32 used_triggers; ///< Subset of cur_triggers, which actually triggered some rerandomisation. (scope independent)
580 uint32 reseed[VSG_END]; ///< Collects bits to rerandomise while triggering triggers.
582 virtual const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const;
584 virtual ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0);
587 * Returns the waiting triggers that did not trigger any rerandomisation.
589 uint32 GetRemainingTriggers() const
591 return this->waiting_triggers & ~this->used_triggers;
595 * Returns the OR-sum of all bits that need reseeding
596 * independent of the scope they were accessed with.
597 * @return OR-sum of the bits.
599 uint32 GetReseedSum() const
601 uint32 sum = 0;
602 for (VarSpriteGroupScope vsg = VSG_BEGIN; vsg < VSG_END; vsg++) {
603 sum |= this->reseed[vsg];
605 return sum;
609 * Resets the dynamic state of the resolver object.
610 * To be called before resolving an Action-1-2-3 chain.
612 void ResetState()
614 this->last_value = 0;
615 this->waiting_triggers = 0;
616 this->used_triggers = 0;
617 memset(this->reseed, 0, sizeof(this->reseed));
621 #endif /* NEWGRF_SPRITEGROUP_H */