peter1138@3595: /* $Id$ */ peter1138@3595: peter1138@3595: #ifndef NEWGRF_SPRITEGROUP_H peter1138@3595: #define NEWGRF_SPRITEGROUP_H peter1138@3595: peter1138@3664: peter1138@3664: typedef struct SpriteGroup SpriteGroup; peter1138@3664: peter1138@3668: peter1138@3668: /* 'Real' sprite groups contain a list of other result or callback sprite peter1138@3668: * groups. */ peter1138@3664: typedef struct RealSpriteGroup { peter1138@3664: // Loaded = in motion, loading = not moving peter1138@3664: // Each group contains several spritesets, for various loading stages peter1138@3664: peter1138@3664: // XXX: For stations the meaning is different - loaded is for stations peter1138@3664: // with small amount of cargo whilst loading is for stations with a lot peter1138@3664: // 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) peter1138@3664: } RealSpriteGroup; peter1138@3664: peter1138@3664: /* Shared by deterministic and random groups. */ peter1138@3668: typedef enum VarSpriteGroupScopes { peter1138@3664: VSG_SCOPE_SELF, peter1138@3664: // Engine of consists for vehicles, city for stations. peter1138@3664: VSG_SCOPE_PARENT, peter1138@3664: } VarSpriteGroupScope; peter1138@3664: peter1138@3668: typedef enum DeterministicSpriteGroupSizes { peter1138@3668: DSG_SIZE_BYTE, peter1138@3668: DSG_SIZE_WORD, peter1138@3668: DSG_SIZE_DWORD, peter1138@3668: } DeterministicSpriteGroupSize; peter1138@3664: peter1138@3668: typedef enum DeterministicSpriteGroupAdjustTypes { peter1138@3668: DSGA_TYPE_NONE, peter1138@3668: DSGA_TYPE_DIV, peter1138@3668: DSGA_TYPE_MOD, peter1138@3668: } DeterministicSpriteGroupAdjustType; peter1138@3664: peter1138@3668: typedef enum DeterministicSpriteGroupAdjustOperations { peter1138@3668: DSGA_OP_ADD, // a + b peter1138@3668: DSGA_OP_SUB, // a - b peter1138@3668: DSGA_OP_SMIN, // (signed) min(a, b) peter1138@3668: DSGA_OP_SMAX, // (signed) max(a, b) peter1138@3668: DSGA_OP_UMIN, // (unsigned) min(a, b) peter1138@3668: DSGA_OP_UMAX, // (unsigned) max(a, b) peter1138@3668: DSGA_OP_SDIV, // (signed) a / b peter1138@3668: DSGA_OP_SMOD, // (signed) a % b peter1138@3668: DSGA_OP_UDIV, // (unsigned) a / b peter1138@3668: DSGA_OP_UMOD, // (unsigned) a & b peter1138@3668: DSGA_OP_MUL, // a * b peter1138@3668: DSGA_OP_AND, // a & b peter1138@3668: DSGA_OP_OR, // a | b peter1138@3668: DSGA_OP_XOR, // a ^ b peter1138@3668: } DeterministicSpriteGroupAdjustOperation; peter1138@3668: peter1138@3668: peter1138@3668: typedef 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; peter1138@3668: } DeterministicSpriteGroupAdjust; peter1138@3668: peter1138@3668: peter1138@3668: typedef struct DeterministicSpriteGroupRange { peter1138@4892: const SpriteGroup *group; peter1138@3668: uint32 low; peter1138@3668: uint32 high; peter1138@3668: } DeterministicSpriteGroupRange; peter1138@3668: peter1138@3664: peter1138@3664: typedef 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: peter1138@3664: // Dynamically allocated, this is the sole owner peter1138@4892: const SpriteGroup *default_group; peter1138@3664: } DeterministicSpriteGroup; peter1138@3664: peter1138@3668: typedef enum RandomizedSpriteGroupCompareModes { peter1138@3664: RSG_CMP_ANY, peter1138@3664: RSG_CMP_ALL, peter1138@3664: } RandomizedSpriteGroupCompareMode; peter1138@3664: peter1138@3664: typedef struct RandomizedSpriteGroup { peter1138@3664: // Take this object: peter1138@3664: VarSpriteGroupScope var_scope; peter1138@3664: peter1138@3664: // Check for these triggers: peter1138@3664: RandomizedSpriteGroupCompareMode cmp_mode; peter1138@3664: byte triggers; peter1138@3664: peter1138@3664: // Look for this in the per-object randomized bitmask: peter1138@3664: byte lowest_randbit; peter1138@3664: byte num_groups; // must be power of 2 peter1138@3664: peter1138@3664: // Take the group with appropriate index: peter1138@4892: const SpriteGroup **groups; peter1138@3664: } RandomizedSpriteGroup; peter1138@3664: peter1138@3668: peter1138@3668: /* This contains a callback result. A failed callback has a value of peter1138@3668: * CALLBACK_FAILED */ peter1138@3664: typedef struct CallbackResultSpriteGroup { peter1138@3664: uint16 result; peter1138@3664: } CallbackResultSpriteGroup; peter1138@3664: peter1138@3668: peter1138@3668: /* A result sprite group returns the first SpriteID and the number of peter1138@3668: * sprites in the set */ peter1138@3664: typedef struct ResultSpriteGroup { peter1138@3668: SpriteID sprite; peter1138@3668: byte num_sprites; peter1138@3664: } ResultSpriteGroup; peter1138@3664: peter1138@3668: /* List of different sprite group types */ peter1138@3664: typedef 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, peter1138@3664: } SpriteGroupType; 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; peter1138@3664: } g; peter1138@3664: }; peter1138@3664: peter1138@3664: peter1138@3595: SpriteGroup *AllocateSpriteGroup(void); peter1138@3595: void InitializeSpriteGroupPool(void); peter1138@3595: peter1138@3677: peter1138@3677: typedef 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; 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*); peter1138@3677: } ResolverObject; 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 */