From 60f1eb21fa31d64c9b2651a09193a62472174a20 Mon Sep 17 00:00:00 2001 From: rubidium Date: Sat, 22 Sep 2007 13:56:38 +0000 Subject: [PATCH] (svn r11139) -Codechange: add support for persistent storage for NewGRFs. --- src/industry.h | 5 +++++ src/industry_cmd.cpp | 2 ++ src/newgrf_industries.cpp | 4 ++++ src/newgrf_industrytiles.cpp | 1 + src/newgrf_spritegroup.cpp | 9 +++++---- src/newgrf_spritegroup.h | 3 +++ src/newgrf_storage.h | 17 ++++++++++++----- src/saveload.cpp | 2 +- src/saveload.h | 11 ++++++----- 9 files changed, 39 insertions(+), 15 deletions(-) diff --git a/src/industry.h b/src/industry.h index d2fabf2dd6..e8d5596c98 100644 --- a/src/industry.h +++ b/src/industry.h @@ -7,6 +7,7 @@ #include "oldpool.h" #include "helpers.hpp" +#include "newgrf_storage.h" typedef byte IndustryGfx; typedef uint8 IndustryType; @@ -94,6 +95,8 @@ DECLARE_OLD_POOL(Industry, Industry, 3, 8000) * Defines the internal data of a functionnal industry */ struct Industry : PoolItem { + typedef PersistentStorageArray PersistentStorage; + TileIndex xy; ///< coordinates of the primary tile the industry is built one byte width; byte height; @@ -121,6 +124,8 @@ struct Industry : PoolItem { Date last_cargo_accepted_at; ///< Last day cargo was accepted by this industry byte selected_layout; ///< Which tile layout was used when creating the industry + PersistentStorage psa; ///< Persistent storage for NewGRF industries. + Industry(TileIndex tile = 0) : xy(tile) {} ~Industry(); diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 45b1ce60d2..9674625273 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -2074,6 +2074,8 @@ static const SaveLoad _industry_desc[] = { SLE_CONDVAR(Industry, last_cargo_accepted_at, SLE_INT32, 70, SL_MAX_VERSION), SLE_CONDVAR(Industry, selected_layout, SLE_UINT8, 73, SL_MAX_VERSION), + SLE_CONDARRX(cpp_offsetof(Industry, psa) + cpp_offsetof(Industry::PersistentStorage, storage), SLE_UINT32, 16, 76, SL_MAX_VERSION), + /* reserve extra space in savegame here. (currently 32 bytes) */ SLE_CONDNULL(32, 2, SL_MAX_VERSION), diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index 608b7ff054..5574673a66 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.cpp @@ -243,6 +243,9 @@ uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte par case 0x67: case 0x68: return GetCountAndDistanceOfClosestInstance(parameter, variable == 0x68 ? GB(GetRegister(0x101), 0, 8) : 0, industry); + /* Get a variable from the persistent storage */ + case 0x7C: return industry->psa.Get(parameter); + /* Industry structure access*/ case 0x80: return industry->xy; case 0x81: return GB(industry->xy, 8, 8); @@ -323,6 +326,7 @@ static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *i res->GetVariable = IndustryGetVariable; res->ResolveReal = IndustryResolveReal; + res->psa = &indus->psa; res->u.industry.tile = tile; res->u.industry.ind = indus; res->u.industry.gfx = INVALID_INDUSTRYTILE; diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp index 0fb78bf49d..7de6358080 100644 --- a/src/newgrf_industrytiles.cpp +++ b/src/newgrf_industrytiles.cpp @@ -140,6 +140,7 @@ static void NewIndustryTileResolver(ResolverObject *res, IndustryGfx gfx, TileIn res->GetVariable = IndustryTileGetVariable; res->ResolveReal = IndustryTileResolveReal; + res->psa = &indus->psa; res->u.industry.tile = tile; res->u.industry.ind = indus; res->u.industry.gfx = gfx; diff --git a/src/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp index bc71ca19f2..37f5e65f18 100644 --- a/src/newgrf_spritegroup.cpp +++ b/src/newgrf_spritegroup.cpp @@ -109,7 +109,7 @@ static inline uint32 GetVariable(const ResolverObject *object, byte variable, by /* Evaluate an adjustment for a variable of the given size. * U is the unsigned type and S is the signed type to use. */ template -static U EvalAdjustT(const DeterministicSpriteGroupAdjust *adjust, U last_value, uint32 value) +static U EvalAdjustT(const DeterministicSpriteGroupAdjust *adjust, ResolverObject *object, U last_value, uint32 value) { value >>= adjust->shift_num; value &= adjust->and_mask; @@ -139,6 +139,7 @@ static U EvalAdjustT(const DeterministicSpriteGroupAdjust *adjust, U last_value, case DSGA_OP_XOR: return last_value ^ value; case DSGA_OP_STO: _temp_store.Store(value, last_value); return last_value; case DSGA_OP_RST: return value; + case DSGA_OP_STOP: if (object->psa != NULL) object->psa->Store(value, last_value); return last_value; default: return value; } } @@ -177,9 +178,9 @@ static inline const SpriteGroup *ResolveVariable(const SpriteGroup *group, Resol } switch (group->g.determ.size) { - case DSG_SIZE_BYTE: value = EvalAdjustT(adjust, last_value, value); break; - case DSG_SIZE_WORD: value = EvalAdjustT(adjust, last_value, value); break; - case DSG_SIZE_DWORD: value = EvalAdjustT(adjust, last_value, value); break; + case DSG_SIZE_BYTE: value = EvalAdjustT (adjust, object, last_value, value); break; + case DSG_SIZE_WORD: value = EvalAdjustT(adjust, object, last_value, value); break; + case DSG_SIZE_DWORD: value = EvalAdjustT(adjust, object, last_value, value); break; default: NOT_REACHED(); break; } last_value = value; diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h index 50b75b849b..ebe07cd635 100644 --- a/src/newgrf_spritegroup.h +++ b/src/newgrf_spritegroup.h @@ -76,6 +76,7 @@ enum DeterministicSpriteGroupAdjustOperation { DSGA_OP_XOR, ///< a ^ b DSGA_OP_STO, ///< store a into temporary storage, indexed by b. return a DSGA_OP_RST, ///< return b + DSGA_OP_STOP, ///< store a into persistent storage, indexed by b, return a }; @@ -199,6 +200,8 @@ struct ResolverObject { bool info_view; ///< Indicates if the item is being drawn in an info window + BaseStorageArray *psa; ///< The persistent storage array of this resolved object. + union { struct { const struct Vehicle *self; diff --git a/src/newgrf_storage.h b/src/newgrf_storage.h index 93aab09dc2..cf7690a924 100644 --- a/src/newgrf_storage.h +++ b/src/newgrf_storage.h @@ -21,7 +21,14 @@ struct BaseStorageArray * - reverting to the previous version * @param keep_changes do we save or revert the changes since the last ClearChanges? */ - virtual void ClearChanges(bool keep_changes) {} + virtual void ClearChanges(bool keep_changes) = 0; + + /** + * Stores some value at a given position. + * @param pos the position to write at + * @param value the value to write + */ + virtual void Store(uint pos, uint32 value) = 0; }; /** @@ -54,7 +61,7 @@ struct PersistentStorageArray : BaseStorageArray { * @param pos the position to write at * @param value the value to write */ - void Store(uint pos, TYPE value) + void Store(uint pos, uint32 value) { /* Out of the scope of the array */ if (pos >= SIZE) return; @@ -83,7 +90,7 @@ struct PersistentStorageArray : BaseStorageArray { * @param pos the position to get the data from * @return the data from that position */ - TYPE Get(uint pos) + TYPE Get(uint pos) const { /* Out of the scope of the array */ if (pos >= SIZE) return 0; @@ -124,7 +131,7 @@ struct TemporaryStorageArray : BaseStorageArray { * @param pos the position to write at * @param value the value to write */ - void Store(uint pos, TYPE value) + void Store(uint pos, uint32 value) { /* Out of the scope of the array */ if (pos >= SIZE) return; @@ -138,7 +145,7 @@ struct TemporaryStorageArray : BaseStorageArray { * @param pos the position to get the data from * @return the data from that position */ - TYPE Get(uint pos) + TYPE Get(uint pos) const { /* Out of the scope of the array */ if (pos >= SIZE) return 0; diff --git a/src/saveload.cpp b/src/saveload.cpp index 3550e1cefd..60e8ae7e23 100644 --- a/src/saveload.cpp +++ b/src/saveload.cpp @@ -29,7 +29,7 @@ #include "strings.h" #include -extern const uint16 SAVEGAME_VERSION = 75; +extern const uint16 SAVEGAME_VERSION = 76; uint16 _sl_version; ///< the major savegame version identifier byte _sl_minor_version; ///< the minor savegame version, DO NOT USE! diff --git a/src/saveload.h b/src/saveload.h index 793b63dba5..c684030bc2 100644 --- a/src/saveload.h +++ b/src/saveload.h @@ -211,15 +211,16 @@ typedef SaveLoad SaveLoadGlobVarList; #define SLE_WRITEBYTE(base, variable, value) SLE_GENERAL(SL_WRITEBYTE, base, variable, 0, 0, value, value) /* The same as the ones at the top, only the offset is given directly; used for unions */ -#define SLE_GENERALX(cmd, offset, type, param1, param2) {false, cmd, type, 0, param1, param2, (void*)(offset)} -#define SLE_CONDVARX(offset, type, from, to) SLE_GENERALX(SL_VAR, offset, type, from, to) -#define SLE_CONDREFX(offset, type, from, to) SLE_GENERALX(SL_REF, offset, type, from, to) +#define SLE_GENERALX(cmd, offset, type, length, param1, param2) {false, cmd, type, length, param1, param2, (void*)(offset)} +#define SLE_CONDVARX(offset, type, from, to) SLE_GENERALX(SL_VAR, offset, type, 0, from, to) +#define SLE_CONDARRX(offset, type, length, from, to) SLE_GENERALX(SL_ARR, offset, type, length, from, to) +#define SLE_CONDREFX(offset, type, from, to) SLE_GENERALX(SL_REF, offset, type, 0, from, to) #define SLE_VARX(offset, type) SLE_CONDVARX(offset, type, 0, SL_MAX_VERSION) #define SLE_REFX(offset, type) SLE_CONDREFX(offset, type, 0, SL_MAX_VERSION) -#define SLE_WRITEBYTEX(offset, something) SLE_GENERALX(SL_WRITEBYTE, offset, 0, something, 0) -#define SLE_VEH_INCLUDEX() SLE_GENERALX(SL_VEH_INCLUDE, 0, 0, 0, SL_MAX_VERSION) +#define SLE_WRITEBYTEX(offset, something) SLE_GENERALX(SL_WRITEBYTE, offset, 0, 0, something, 0) +#define SLE_VEH_INCLUDEX() SLE_GENERALX(SL_VEH_INCLUDE, 0, 0, 0, 0, SL_MAX_VERSION) /* End marker */ #define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL}