00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef NEWGRF_SPRITEGROUP_H
00013 #define NEWGRF_SPRITEGROUP_H
00014
00015 #include "town_type.h"
00016 #include "engine_type.h"
00017 #include "house_type.h"
00018
00019 #include "newgrf_callbacks.h"
00020 #include "newgrf_generic.h"
00021 #include "newgrf_storage.h"
00022 #include "newgrf_commons.h"
00023
00030 static inline uint32 GetRegister(uint i)
00031 {
00032 extern TemporaryStorageArray<int32, 0x110> _temp_store;
00033 return _temp_store.GetValue(i);
00034 }
00035
00036
00037 enum SpriteGroupType {
00038 SGT_REAL,
00039 SGT_DETERMINISTIC,
00040 SGT_RANDOMIZED,
00041 SGT_CALLBACK,
00042 SGT_RESULT,
00043 SGT_TILELAYOUT,
00044 SGT_INDUSTRY_PRODUCTION,
00045 };
00046
00047 struct SpriteGroup;
00048 typedef uint32 SpriteGroupID;
00049 struct ResolverObject;
00050
00051
00052
00053
00054 typedef Pool<SpriteGroup, SpriteGroupID, 1024, 1 << 30, PT_DATA> SpriteGroupPool;
00055 extern SpriteGroupPool _spritegroup_pool;
00056
00057
00058 struct SpriteGroup : SpriteGroupPool::PoolItem<&_spritegroup_pool> {
00059 protected:
00060 SpriteGroup(SpriteGroupType type) : type(type) {}
00062 virtual const SpriteGroup *Resolve(ResolverObject &object) const { return this; };
00063
00064 public:
00065 virtual ~SpriteGroup() {}
00066
00067 SpriteGroupType type;
00068
00069 virtual SpriteID GetResult() const { return 0; }
00070 virtual byte GetNumResults() const { return 0; }
00071 virtual uint16 GetCallbackResult() const { return CALLBACK_FAILED; }
00072
00073 static const SpriteGroup *Resolve(const SpriteGroup *group, ResolverObject &object, bool top_level = true);
00074 };
00075
00076
00077
00078
00079 struct RealSpriteGroup : SpriteGroup {
00080 RealSpriteGroup() : SpriteGroup(SGT_REAL) {}
00081 ~RealSpriteGroup();
00082
00083
00084
00085
00086
00087
00088
00089
00090 byte num_loaded;
00091 byte num_loading;
00092 const SpriteGroup **loaded;
00093 const SpriteGroup **loading;
00094
00095 protected:
00096 const SpriteGroup *Resolve(ResolverObject &object) const;
00097 };
00098
00099
00100 enum VarSpriteGroupScope {
00101 VSG_BEGIN,
00102
00103 VSG_SCOPE_SELF = VSG_BEGIN,
00104 VSG_SCOPE_PARENT,
00105 VSG_SCOPE_RELATIVE,
00106
00107 VSG_END
00108 };
00109 DECLARE_POSTFIX_INCREMENT(VarSpriteGroupScope)
00110
00111 enum DeterministicSpriteGroupSize {
00112 DSG_SIZE_BYTE,
00113 DSG_SIZE_WORD,
00114 DSG_SIZE_DWORD,
00115 };
00116
00117 enum DeterministicSpriteGroupAdjustType {
00118 DSGA_TYPE_NONE,
00119 DSGA_TYPE_DIV,
00120 DSGA_TYPE_MOD,
00121 };
00122
00123 enum DeterministicSpriteGroupAdjustOperation {
00124 DSGA_OP_ADD,
00125 DSGA_OP_SUB,
00126 DSGA_OP_SMIN,
00127 DSGA_OP_SMAX,
00128 DSGA_OP_UMIN,
00129 DSGA_OP_UMAX,
00130 DSGA_OP_SDIV,
00131 DSGA_OP_SMOD,
00132 DSGA_OP_UDIV,
00133 DSGA_OP_UMOD,
00134 DSGA_OP_MUL,
00135 DSGA_OP_AND,
00136 DSGA_OP_OR,
00137 DSGA_OP_XOR,
00138 DSGA_OP_STO,
00139 DSGA_OP_RST,
00140 DSGA_OP_STOP,
00141 DSGA_OP_ROR,
00142 DSGA_OP_SCMP,
00143 DSGA_OP_UCMP,
00144 DSGA_OP_SHL,
00145 DSGA_OP_SHR,
00146 DSGA_OP_SAR,
00147 };
00148
00149
00150 struct DeterministicSpriteGroupAdjust {
00151 DeterministicSpriteGroupAdjustOperation operation;
00152 DeterministicSpriteGroupAdjustType type;
00153 byte variable;
00154 byte parameter;
00155 byte shift_num;
00156 uint32 and_mask;
00157 uint32 add_val;
00158 uint32 divmod_val;
00159 const SpriteGroup *subroutine;
00160 };
00161
00162
00163 struct DeterministicSpriteGroupRange {
00164 const SpriteGroup *group;
00165 uint32 low;
00166 uint32 high;
00167 };
00168
00169
00170 struct DeterministicSpriteGroup : SpriteGroup {
00171 DeterministicSpriteGroup() : SpriteGroup(SGT_DETERMINISTIC) {}
00172 ~DeterministicSpriteGroup();
00173
00174 VarSpriteGroupScope var_scope;
00175 DeterministicSpriteGroupSize size;
00176 uint num_adjusts;
00177 byte num_ranges;
00178 DeterministicSpriteGroupAdjust *adjusts;
00179 DeterministicSpriteGroupRange *ranges;
00180
00181
00182 const SpriteGroup *default_group;
00183
00184 protected:
00185 const SpriteGroup *Resolve(ResolverObject &object) const;
00186 };
00187
00188 enum RandomizedSpriteGroupCompareMode {
00189 RSG_CMP_ANY,
00190 RSG_CMP_ALL,
00191 };
00192
00193 struct RandomizedSpriteGroup : SpriteGroup {
00194 RandomizedSpriteGroup() : SpriteGroup(SGT_RANDOMIZED) {}
00195 ~RandomizedSpriteGroup();
00196
00197 VarSpriteGroupScope var_scope;
00198
00199 RandomizedSpriteGroupCompareMode cmp_mode;
00200 byte triggers;
00201 byte count;
00202
00203 byte lowest_randbit;
00204 byte num_groups;
00205
00206 const SpriteGroup **groups;
00207
00208 protected:
00209 const SpriteGroup *Resolve(ResolverObject &object) const;
00210 };
00211
00212
00213
00214
00215 struct CallbackResultSpriteGroup : SpriteGroup {
00221 CallbackResultSpriteGroup(uint16 value, bool grf_version8) :
00222 SpriteGroup(SGT_CALLBACK),
00223 result(value)
00224 {
00225
00226
00227 if (!grf_version8 && (this->result >> 8) == 0xFF) {
00228 this->result &= ~0xFF00;
00229 } else {
00230 this->result &= ~0x8000;
00231 }
00232 }
00233
00234 uint16 result;
00235 uint16 GetCallbackResult() const { return this->result; }
00236 };
00237
00238
00239
00240
00241 struct ResultSpriteGroup : SpriteGroup {
00248 ResultSpriteGroup(SpriteID sprite, byte num_sprites) :
00249 SpriteGroup(SGT_RESULT),
00250 sprite(sprite),
00251 num_sprites(num_sprites)
00252 {
00253 }
00254
00255 SpriteID sprite;
00256 byte num_sprites;
00257 SpriteID GetResult() const { return this->sprite; }
00258 byte GetNumResults() const { return this->num_sprites; }
00259 };
00260
00264 struct TileLayoutSpriteGroup : SpriteGroup {
00265 TileLayoutSpriteGroup() : SpriteGroup(SGT_TILELAYOUT) {}
00266 ~TileLayoutSpriteGroup() {}
00267
00268 NewGRFSpriteLayout dts;
00269
00270 const DrawTileSprites *ProcessRegisters(uint8 *stage) const;
00271 };
00272
00273 struct IndustryProductionSpriteGroup : SpriteGroup {
00274 IndustryProductionSpriteGroup() : SpriteGroup(SGT_INDUSTRY_PRODUCTION) {}
00275
00276 uint8 version;
00277 int16 subtract_input[3];
00278 uint16 add_output[2];
00279 uint8 again;
00280 };
00281
00288 struct ScopeResolver {
00289 ResolverObject &ro;
00290
00291 ScopeResolver(ResolverObject &ro);
00292 virtual ~ScopeResolver();
00293
00294 virtual uint32 GetRandomBits() const;
00295 virtual uint32 GetTriggers() const;
00296 virtual void SetTriggers(int triggers) const;
00297
00298 virtual uint32 GetVariable(byte variable, uint32 parameter, bool *available) const;
00299 virtual void StorePSA(uint reg, int32 value);
00300 };
00301
00308 struct ResolverObject {
00309 ResolverObject(const GRFFile *grffile, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0);
00310 virtual ~ResolverObject();
00311
00312 ScopeResolver default_scope;
00313
00314 CallbackID callback;
00315 uint32 callback_param1;
00316 uint32 callback_param2;
00317
00318 byte trigger;
00319
00320 uint32 last_value;
00321 uint32 reseed[VSG_END];
00322
00323 const GRFFile *grffile;
00324 const SpriteGroup *root_spritegroup;
00325
00330 const SpriteGroup *Resolve()
00331 {
00332 return SpriteGroup::Resolve(this->root_spritegroup, *this);
00333 }
00334
00339 uint16 ResolveCallback()
00340 {
00341 const SpriteGroup *result = Resolve();
00342 return result != NULL ? result->GetCallbackResult() : CALLBACK_FAILED;
00343 }
00344
00345 virtual const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const;
00346
00347 virtual ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0);
00348
00354 uint32 GetReseedSum() const
00355 {
00356 uint32 sum = 0;
00357 for (VarSpriteGroupScope vsg = VSG_BEGIN; vsg < VSG_END; vsg++) {
00358 sum |= this->reseed[vsg];
00359 }
00360 return sum;
00361 }
00362
00367 void ResetState()
00368 {
00369 this->last_value = 0;
00370 this->trigger = 0;
00371 memset(this->reseed, 0, sizeof(this->reseed));
00372 }
00373 };
00374
00375 #endif