(svn r11139) -Codechange: add support for persistent storage for NewGRFs.
This commit is contained in:
		| @@ -7,6 +7,7 @@ | |||||||
|  |  | ||||||
| #include "oldpool.h" | #include "oldpool.h" | ||||||
| #include "helpers.hpp" | #include "helpers.hpp" | ||||||
|  | #include "newgrf_storage.h" | ||||||
|  |  | ||||||
| typedef byte IndustryGfx; | typedef byte IndustryGfx; | ||||||
| typedef uint8 IndustryType; | typedef uint8 IndustryType; | ||||||
| @@ -94,6 +95,8 @@ DECLARE_OLD_POOL(Industry, Industry, 3, 8000) | |||||||
|  * Defines the internal data of a functionnal industry |  * Defines the internal data of a functionnal industry | ||||||
|  */ |  */ | ||||||
| struct Industry : PoolItem<Industry, IndustryID, &_Industry_pool> { | struct Industry : PoolItem<Industry, IndustryID, &_Industry_pool> { | ||||||
|  | 	typedef PersistentStorageArray<uint32, 16> PersistentStorage; | ||||||
|  |  | ||||||
| 	TileIndex xy;                       ///< coordinates of the primary tile the industry is built one | 	TileIndex xy;                       ///< coordinates of the primary tile the industry is built one | ||||||
| 	byte width; | 	byte width; | ||||||
| 	byte height; | 	byte height; | ||||||
| @@ -121,6 +124,8 @@ struct Industry : PoolItem<Industry, IndustryID, &_Industry_pool> { | |||||||
| 	Date last_cargo_accepted_at;        ///< Last day cargo was accepted by this industry | 	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 | 	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(TileIndex tile = 0) : xy(tile) {} | ||||||
| 	~Industry(); | 	~Industry(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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, last_cargo_accepted_at,     SLE_INT32,                 70, SL_MAX_VERSION), | ||||||
| 	SLE_CONDVAR(Industry, selected_layout,            SLE_UINT8,                 73, 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) */ | 	/* reserve extra space in savegame here. (currently 32 bytes) */ | ||||||
| 	SLE_CONDNULL(32, 2, SL_MAX_VERSION), | 	SLE_CONDNULL(32, 2, SL_MAX_VERSION), | ||||||
|  |  | ||||||
|   | |||||||
| @@ -243,6 +243,9 @@ uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte par | |||||||
| 		case 0x67: | 		case 0x67: | ||||||
| 		case 0x68: return GetCountAndDistanceOfClosestInstance(parameter, variable == 0x68 ? GB(GetRegister(0x101), 0, 8) : 0, industry); | 		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*/ | 		/* Industry structure access*/ | ||||||
| 		case 0x80: return industry->xy; | 		case 0x80: return industry->xy; | ||||||
| 		case 0x81: return GB(industry->xy, 8, 8); | 		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->GetVariable   = IndustryGetVariable; | ||||||
| 	res->ResolveReal   = IndustryResolveReal; | 	res->ResolveReal   = IndustryResolveReal; | ||||||
|  |  | ||||||
|  | 	res->psa             = &indus->psa; | ||||||
| 	res->u.industry.tile = tile; | 	res->u.industry.tile = tile; | ||||||
| 	res->u.industry.ind  = indus; | 	res->u.industry.ind  = indus; | ||||||
| 	res->u.industry.gfx  = INVALID_INDUSTRYTILE; | 	res->u.industry.gfx  = INVALID_INDUSTRYTILE; | ||||||
|   | |||||||
| @@ -140,6 +140,7 @@ static void NewIndustryTileResolver(ResolverObject *res, IndustryGfx gfx, TileIn | |||||||
| 	res->GetVariable   = IndustryTileGetVariable; | 	res->GetVariable   = IndustryTileGetVariable; | ||||||
| 	res->ResolveReal   = IndustryTileResolveReal; | 	res->ResolveReal   = IndustryTileResolveReal; | ||||||
|  |  | ||||||
|  | 	res->psa             = &indus->psa; | ||||||
| 	res->u.industry.tile = tile; | 	res->u.industry.tile = tile; | ||||||
| 	res->u.industry.ind  = indus; | 	res->u.industry.ind  = indus; | ||||||
| 	res->u.industry.gfx  = gfx; | 	res->u.industry.gfx  = gfx; | ||||||
|   | |||||||
| @@ -109,7 +109,7 @@ static inline uint32 GetVariable(const ResolverObject *object, byte variable, by | |||||||
| /* Evaluate an adjustment for a variable of the given size. | /* Evaluate an adjustment for a variable of the given size. | ||||||
| * U is the unsigned type and S is the signed type to use. */ | * U is the unsigned type and S is the signed type to use. */ | ||||||
| template <typename U, typename S> | template <typename U, typename S> | ||||||
| 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->shift_num; | ||||||
| 	value  &= adjust->and_mask; | 	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_XOR:  return last_value ^ value; | ||||||
| 		case DSGA_OP_STO:  _temp_store.Store(value, last_value); return last_value; | 		case DSGA_OP_STO:  _temp_store.Store(value, last_value); return last_value; | ||||||
| 		case DSGA_OP_RST:  return 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; | 		default:           return value; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @@ -177,9 +178,9 @@ static inline const SpriteGroup *ResolveVariable(const SpriteGroup *group, Resol | |||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		switch (group->g.determ.size) { | 		switch (group->g.determ.size) { | ||||||
| 			case DSG_SIZE_BYTE:  value = EvalAdjustT<uint8, int8>(adjust, last_value, value); break; | 			case DSG_SIZE_BYTE:  value = EvalAdjustT<uint8,  int8> (adjust, object, last_value, value); break; | ||||||
| 			case DSG_SIZE_WORD:  value = EvalAdjustT<uint16, int16>(adjust, last_value, value); break; | 			case DSG_SIZE_WORD:  value = EvalAdjustT<uint16, int16>(adjust, object, last_value, value); break; | ||||||
| 			case DSG_SIZE_DWORD: value = EvalAdjustT<uint32, int32>(adjust, last_value, value); break; | 			case DSG_SIZE_DWORD: value = EvalAdjustT<uint32, int32>(adjust, object, last_value, value); break; | ||||||
| 			default: NOT_REACHED(); break; | 			default: NOT_REACHED(); break; | ||||||
| 		} | 		} | ||||||
| 		last_value = value; | 		last_value = value; | ||||||
|   | |||||||
| @@ -76,6 +76,7 @@ enum DeterministicSpriteGroupAdjustOperation { | |||||||
| 	DSGA_OP_XOR,  ///< a ^ b | 	DSGA_OP_XOR,  ///< a ^ b | ||||||
| 	DSGA_OP_STO,  ///< store a into temporary storage, indexed by b. return a | 	DSGA_OP_STO,  ///< store a into temporary storage, indexed by b. return a | ||||||
| 	DSGA_OP_RST,  ///< return b | 	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 | 	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 { | 	union { | ||||||
| 		struct { | 		struct { | ||||||
| 			const struct Vehicle *self; | 			const struct Vehicle *self; | ||||||
|   | |||||||
| @@ -21,7 +21,14 @@ struct BaseStorageArray | |||||||
| 	 *  - reverting to the previous version | 	 *  - reverting to the previous version | ||||||
| 	 * @param keep_changes do we save or revert the changes since the last ClearChanges? | 	 * @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 pos   the position to write at | ||||||
| 	 * @param value the value to write | 	 * @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 */ | 		/* Out of the scope of the array */ | ||||||
| 		if (pos >= SIZE) return; | 		if (pos >= SIZE) return; | ||||||
| @@ -83,7 +90,7 @@ struct PersistentStorageArray : BaseStorageArray { | |||||||
| 	 * @param pos the position to get the data from | 	 * @param pos the position to get the data from | ||||||
| 	 * @return the data from that position | 	 * @return the data from that position | ||||||
| 	 */ | 	 */ | ||||||
| 	TYPE Get(uint pos) | 	TYPE Get(uint pos) const | ||||||
| 	{ | 	{ | ||||||
| 		/* Out of the scope of the array */ | 		/* Out of the scope of the array */ | ||||||
| 		if (pos >= SIZE) return 0; | 		if (pos >= SIZE) return 0; | ||||||
| @@ -124,7 +131,7 @@ struct TemporaryStorageArray : BaseStorageArray { | |||||||
| 	 * @param pos   the position to write at | 	 * @param pos   the position to write at | ||||||
| 	 * @param value the value to write | 	 * @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 */ | 		/* Out of the scope of the array */ | ||||||
| 		if (pos >= SIZE) return; | 		if (pos >= SIZE) return; | ||||||
| @@ -138,7 +145,7 @@ struct TemporaryStorageArray : BaseStorageArray { | |||||||
| 	 * @param pos the position to get the data from | 	 * @param pos the position to get the data from | ||||||
| 	 * @return the data from that position | 	 * @return the data from that position | ||||||
| 	 */ | 	 */ | ||||||
| 	TYPE Get(uint pos) | 	TYPE Get(uint pos) const | ||||||
| 	{ | 	{ | ||||||
| 		/* Out of the scope of the array */ | 		/* Out of the scope of the array */ | ||||||
| 		if (pos >= SIZE) return 0; | 		if (pos >= SIZE) return 0; | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ | |||||||
| #include "strings.h" | #include "strings.h" | ||||||
| #include <list> | #include <list> | ||||||
|  |  | ||||||
| extern const uint16 SAVEGAME_VERSION = 75; | extern const uint16 SAVEGAME_VERSION = 76; | ||||||
| uint16 _sl_version;       ///< the major savegame version identifier | uint16 _sl_version;       ///< the major savegame version identifier | ||||||
| byte   _sl_minor_version; ///< the minor savegame version, DO NOT USE! | byte   _sl_minor_version; ///< the minor savegame version, DO NOT USE! | ||||||
|  |  | ||||||
|   | |||||||
| @@ -211,15 +211,16 @@ typedef SaveLoad SaveLoadGlobVarList; | |||||||
| #define SLE_WRITEBYTE(base, variable, value) SLE_GENERAL(SL_WRITEBYTE, base, variable, 0, 0, value, value) | #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 */ | /* 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_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, from, to) | #define SLE_CONDVARX(offset, type, from, to) SLE_GENERALX(SL_VAR, offset, type, 0, from, to) | ||||||
| #define SLE_CONDREFX(offset, type, from, to) SLE_GENERALX(SL_REF, offset, type, 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_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_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_WRITEBYTEX(offset, something) SLE_GENERALX(SL_WRITEBYTE, offset, 0, 0, something, 0) | ||||||
| #define SLE_VEH_INCLUDEX() SLE_GENERALX(SL_VEH_INCLUDE, 0, 0, 0, SL_MAX_VERSION) | #define SLE_VEH_INCLUDEX() SLE_GENERALX(SL_VEH_INCLUDE, 0, 0, 0, 0, SL_MAX_VERSION) | ||||||
|  |  | ||||||
| /* End marker */ | /* End marker */ | ||||||
| #define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL} | #define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 rubidium
					rubidium