peter1138@3595: /* $Id$ */ peter1138@3595: celestar@9906: /** @file newgrf_spritegroup.h */ celestar@9906: peter1138@3595: #ifndef NEWGRF_SPRITEGROUP_H peter1138@3595: #define NEWGRF_SPRITEGROUP_H peter1138@3595: celestar@9896: #include "town.h" peter1138@3664: celestar@9895: struct SpriteGroup; peter1138@3664: peter1138@3668: peter1138@3668: /* 'Real' sprite groups contain a list of other result or callback sprite peter1138@3668: * groups. */ celestar@9895: struct RealSpriteGroup { celestar@9906: /* Loaded = in motion, loading = not moving celestar@9906: * Each group contains several spritesets, for various loading stages */ peter1138@3664: celestar@9906: /* XXX: For stations the meaning is different - loaded is for stations celestar@9906: * with small amount of cargo whilst loading is for stations with a lot celestar@9906: * of da stuff. */ peter1138@3664: peter1138@3668: byte num_loaded; ///< Number of loaded groups peter1138@3668: byte num_loading; ///< Number of loading groups peter1138@4892: const SpriteGroup **loaded; ///< List of loaded groups (can be SpriteIDs or Callback results) peter1138@4892: const SpriteGroup **loading; ///< List of loading groups (can be SpriteIDs or Callback results) celestar@9895: }; peter1138@3664: peter1138@3664: /* Shared by deterministic and random groups. */ celestar@9895: enum VarSpriteGroupScope { peter1138@3664: VSG_SCOPE_SELF, celestar@9906: /* Engine of consists for vehicles, city for stations. */ peter1138@3664: VSG_SCOPE_PARENT, celestar@9895: }; peter1138@3664: celestar@9895: enum DeterministicSpriteGroupSize { peter1138@3668: DSG_SIZE_BYTE, peter1138@3668: DSG_SIZE_WORD, peter1138@3668: DSG_SIZE_DWORD, celestar@9895: }; peter1138@3664: celestar@9895: enum DeterministicSpriteGroupAdjustType { peter1138@3668: DSGA_TYPE_NONE, peter1138@3668: DSGA_TYPE_DIV, peter1138@3668: DSGA_TYPE_MOD, celestar@9895: }; peter1138@3664: celestar@9895: enum DeterministicSpriteGroupAdjustOperation { celestar@9906: DSGA_OP_ADD, ///< a + b celestar@9906: DSGA_OP_SUB, ///< a - b celestar@9906: DSGA_OP_SMIN, ///< (signed) min(a, b) celestar@9906: DSGA_OP_SMAX, ///< (signed) max(a, b) celestar@9906: DSGA_OP_UMIN, ///< (unsigned) min(a, b) celestar@9906: DSGA_OP_UMAX, ///< (unsigned) max(a, b) celestar@9906: DSGA_OP_SDIV, ///< (signed) a / b celestar@9906: DSGA_OP_SMOD, ///< (signed) a % b celestar@9906: DSGA_OP_UDIV, ///< (unsigned) a / b celestar@9906: DSGA_OP_UMOD, ///< (unsigned) a & b celestar@9906: DSGA_OP_MUL, ///< a * b celestar@9906: DSGA_OP_AND, ///< a & b celestar@9906: DSGA_OP_OR, ///< a | b celestar@9906: DSGA_OP_XOR, ///< a ^ b celestar@9895: }; peter1138@3668: peter1138@3668: celestar@9895: struct DeterministicSpriteGroupAdjust { peter1138@3668: DeterministicSpriteGroupAdjustOperation operation; peter1138@3668: DeterministicSpriteGroupAdjustType type; peter1138@3668: byte variable; peter1138@3668: byte parameter; ///< Used for variables between 0x60 and 0x7F inclusive. peter1138@3668: byte shift_num; peter1138@3668: uint32 and_mask; peter1138@3668: uint32 add_val; peter1138@3668: uint32 divmod_val; maedhros@5868: const SpriteGroup *subroutine; celestar@9895: }; peter1138@3668: peter1138@3668: celestar@9895: struct DeterministicSpriteGroupRange { peter1138@4892: const SpriteGroup *group; peter1138@3668: uint32 low; peter1138@3668: uint32 high; celestar@9895: }; peter1138@3668: peter1138@3664: celestar@9895: struct DeterministicSpriteGroup { peter1138@3664: VarSpriteGroupScope var_scope; peter1138@3668: DeterministicSpriteGroupSize size; peter1138@3668: byte num_adjusts; peter1138@3664: byte num_ranges; peter1138@3668: DeterministicSpriteGroupAdjust *adjusts; peter1138@3664: DeterministicSpriteGroupRange *ranges; // Dynamically allocated peter1138@3664: celestar@9906: /* Dynamically allocated, this is the sole owner */ peter1138@4892: const SpriteGroup *default_group; celestar@9895: }; peter1138@3664: celestar@9895: enum RandomizedSpriteGroupCompareMode { peter1138@3664: RSG_CMP_ANY, peter1138@3664: RSG_CMP_ALL, celestar@9895: }; peter1138@3664: celestar@9895: struct RandomizedSpriteGroup { celestar@9906: VarSpriteGroupScope var_scope; ///< Take this object: peter1138@3664: celestar@9906: RandomizedSpriteGroupCompareMode cmp_mode; ///< Check for these triggers: peter1138@3664: byte triggers; peter1138@3664: celestar@9906: byte lowest_randbit; ///< Look for this in the per-object randomized bitmask: celestar@9906: byte num_groups; ///< must be power of 2 peter1138@3664: celestar@9906: const SpriteGroup **groups; ///< Take the group with appropriate index: celestar@9895: }; peter1138@3664: peter1138@3668: peter1138@3668: /* This contains a callback result. A failed callback has a value of peter1138@3668: * CALLBACK_FAILED */ celestar@9895: struct CallbackResultSpriteGroup { peter1138@3664: uint16 result; celestar@9895: }; peter1138@3664: peter1138@3668: peter1138@3668: /* A result sprite group returns the first SpriteID and the number of peter1138@3668: * sprites in the set */ celestar@9895: struct ResultSpriteGroup { peter1138@3668: SpriteID sprite; peter1138@3668: byte num_sprites; celestar@9895: }; peter1138@3664: celestar@9896: struct TileLayoutSpriteGroup { celestar@9906: byte num_sprites; ///< Number of sprites in the spriteset, used for loading stages celestar@9896: struct DrawTileSprites *dts; celestar@9896: }; celestar@9896: peter1138@3668: /* List of different sprite group types */ celestar@9895: enum SpriteGroupType { peter1138@3664: SGT_INVALID, peter1138@3664: SGT_REAL, peter1138@3664: SGT_DETERMINISTIC, peter1138@3664: SGT_RANDOMIZED, peter1138@3664: SGT_CALLBACK, peter1138@3664: SGT_RESULT, celestar@9896: SGT_TILELAYOUT, celestar@9895: }; peter1138@3664: peter1138@3668: /* Common wrapper for all the different sprite group types */ peter1138@3664: struct SpriteGroup { peter1138@3664: SpriteGroupType type; peter1138@3664: peter1138@3664: union { peter1138@3664: RealSpriteGroup real; peter1138@3664: DeterministicSpriteGroup determ; peter1138@3664: RandomizedSpriteGroup random; peter1138@3664: CallbackResultSpriteGroup callback; peter1138@3664: ResultSpriteGroup result; celestar@9896: TileLayoutSpriteGroup layout; peter1138@3664: } g; peter1138@3664: }; peter1138@3664: peter1138@3664: celestar@9895: SpriteGroup *AllocateSpriteGroup(); celestar@9895: void InitializeSpriteGroupPool(); peter1138@3595: peter1138@3677: celestar@9895: struct ResolverObject { peter1138@3724: uint16 callback; peter1138@3677: uint32 callback_param1; peter1138@3677: uint32 callback_param2; peter1138@3677: peter1138@3677: byte trigger; peter1138@3677: uint32 last_value; peter1138@3677: uint32 reseed; peter1138@3677: VarSpriteGroupScope scope; peter1138@3677: peter1138@4056: bool info_view; ///< Indicates if the item is being drawn in an info window peter1138@4056: peter1138@3677: union { peter1138@3677: struct { peter1138@3677: const struct Vehicle *self; peter1138@3677: const struct Vehicle *parent; peter1138@4057: EngineID self_type; peter1138@3677: } vehicle; peter1138@3677: struct { peter1138@3677: TileIndex tile; peter1138@3677: const struct Station *st; peter1138@3677: const struct StationSpec *statspec; peter1138@4817: CargoID cargo_type; peter1138@3677: } station; celestar@9896: struct { celestar@9896: TileIndex tile; celestar@9896: Town *town; celestar@9896: HouseID house_id; celestar@9896: } house; celestar@9906: struct { celestar@9906: const struct CargoSpec *cs; celestar@9906: } cargo; peter1138@3720: } u; peter1138@3677: peter1138@3677: uint32 (*GetRandomBits)(const struct ResolverObject*); peter1138@3677: uint32 (*GetTriggers)(const struct ResolverObject*); peter1138@3677: void (*SetTriggers)(const struct ResolverObject*, int); peter1138@3893: uint32 (*GetVariable)(const struct ResolverObject*, byte, byte, bool*); peter1138@3734: const SpriteGroup *(*ResolveReal)(const struct ResolverObject*, const SpriteGroup*); celestar@9895: }; peter1138@3677: peter1138@3677: peter1138@3677: /* Base sprite group resolver */ peter1138@3677: const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject *object); peter1138@3677: peter1138@3677: peter1138@3595: #endif /* NEWGRF_SPRITEGROUP_H */