mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r22567) -Codechange: Store persistent storages inside a pool.
This commit is contained in:
parent
9f55abf51a
commit
00e5c1df18
|
@ -740,6 +740,7 @@
|
||||||
<ClInclude Include="..\src\saveload\saveload_internal.h" />
|
<ClInclude Include="..\src\saveload\saveload_internal.h" />
|
||||||
<ClCompile Include="..\src\saveload\signs_sl.cpp" />
|
<ClCompile Include="..\src\saveload\signs_sl.cpp" />
|
||||||
<ClCompile Include="..\src\saveload\station_sl.cpp" />
|
<ClCompile Include="..\src\saveload\station_sl.cpp" />
|
||||||
|
<ClCompile Include="..\src\saveload\storage_sl.cpp" />
|
||||||
<ClCompile Include="..\src\saveload\strings_sl.cpp" />
|
<ClCompile Include="..\src\saveload\strings_sl.cpp" />
|
||||||
<ClCompile Include="..\src\saveload\subsidy_sl.cpp" />
|
<ClCompile Include="..\src\saveload\subsidy_sl.cpp" />
|
||||||
<ClCompile Include="..\src\saveload\town_sl.cpp" />
|
<ClCompile Include="..\src\saveload\town_sl.cpp" />
|
||||||
|
|
|
@ -1440,6 +1440,9 @@
|
||||||
<ClCompile Include="..\src\saveload\station_sl.cpp">
|
<ClCompile Include="..\src\saveload\station_sl.cpp">
|
||||||
<Filter>Save/Load handlers</Filter>
|
<Filter>Save/Load handlers</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="..\src\saveload\storage_sl.cpp">
|
||||||
|
<Filter>Save/Load handlers</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="..\src\saveload\strings_sl.cpp">
|
<ClCompile Include="..\src\saveload\strings_sl.cpp">
|
||||||
<Filter>Save/Load handlers</Filter>
|
<Filter>Save/Load handlers</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
|
@ -2254,6 +2254,10 @@
|
||||||
RelativePath=".\..\src\saveload\station_sl.cpp"
|
RelativePath=".\..\src\saveload\station_sl.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\..\src\saveload\storage_sl.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\..\src\saveload\strings_sl.cpp"
|
RelativePath=".\..\src\saveload\strings_sl.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -2251,6 +2251,10 @@
|
||||||
RelativePath=".\..\src\saveload\station_sl.cpp"
|
RelativePath=".\..\src\saveload\station_sl.cpp"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\..\src\saveload\storage_sl.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\..\src\saveload\strings_sl.cpp"
|
RelativePath=".\..\src\saveload\strings_sl.cpp"
|
||||||
>
|
>
|
||||||
|
|
|
@ -498,6 +498,7 @@ saveload/saveload_filter.h
|
||||||
saveload/saveload_internal.h
|
saveload/saveload_internal.h
|
||||||
saveload/signs_sl.cpp
|
saveload/signs_sl.cpp
|
||||||
saveload/station_sl.cpp
|
saveload/station_sl.cpp
|
||||||
|
saveload/storage_sl.cpp
|
||||||
saveload/strings_sl.cpp
|
saveload/strings_sl.cpp
|
||||||
saveload/subsidy_sl.cpp
|
saveload/subsidy_sl.cpp
|
||||||
saveload/town_sl.cpp
|
saveload/town_sl.cpp
|
||||||
|
|
|
@ -38,8 +38,6 @@ enum ProductionLevels {
|
||||||
* Defines the internal data of a functional industry.
|
* Defines the internal data of a functional industry.
|
||||||
*/
|
*/
|
||||||
struct Industry : IndustryPool::PoolItem<&_industry_pool> {
|
struct Industry : IndustryPool::PoolItem<&_industry_pool> {
|
||||||
typedef PersistentStorageArray<int32, 16> PersistentStorage;
|
|
||||||
|
|
||||||
TileArea location; ///< Location of the industry
|
TileArea location; ///< Location of the industry
|
||||||
Town *town; ///< Nearest town
|
Town *town; ///< Nearest town
|
||||||
CargoID produced_cargo[2]; ///< 2 production cargo slots
|
CargoID produced_cargo[2]; ///< 2 production cargo slots
|
||||||
|
@ -72,7 +70,7 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> {
|
||||||
byte random_triggers; ///< Triggers for the random
|
byte random_triggers; ///< Triggers for the random
|
||||||
uint16 random; ///< Random value used for randomisation of all kinds of things
|
uint16 random; ///< Random value used for randomisation of all kinds of things
|
||||||
|
|
||||||
PersistentStorage psa; ///< Persistent storage for NewGRF industries.
|
PersistentStorage *psa; ///< Persistent storage for NewGRF industries.
|
||||||
|
|
||||||
Industry(TileIndex tile = INVALID_TILE) : location(tile, 0, 0) {}
|
Industry(TileIndex tile = INVALID_TILE) : location(tile, 0, 0) {}
|
||||||
~Industry();
|
~Industry();
|
||||||
|
|
|
@ -167,6 +167,9 @@ Industry::~Industry()
|
||||||
/* don't let any disaster vehicle target invalid industry */
|
/* don't let any disaster vehicle target invalid industry */
|
||||||
ReleaseDisastersTargetingIndustry(this->index);
|
ReleaseDisastersTargetingIndustry(this->index);
|
||||||
|
|
||||||
|
/* Clear the persistent storage. */
|
||||||
|
delete this->psa;
|
||||||
|
|
||||||
DecIndustryTypeCount(this->type);
|
DecIndustryTypeCount(this->type);
|
||||||
|
|
||||||
DeleteIndustryNews(this->index);
|
DeleteIndustryNews(this->index);
|
||||||
|
|
|
@ -149,7 +149,7 @@ uint32 AirportGetVariable(const ResolverObject *object, byte variable, byte para
|
||||||
|
|
||||||
switch (variable) {
|
switch (variable) {
|
||||||
/* Get a variable from the persistent storage */
|
/* Get a variable from the persistent storage */
|
||||||
case 0x7C: return st->airport.psa.GetValue(parameter);
|
case 0x7C: return (st->airport.psa != NULL) ? st->airport.psa->GetValue(parameter) : 0;
|
||||||
|
|
||||||
case 0xF0: return st->facilities;
|
case 0xF0: return st->facilities;
|
||||||
case 0xFA: return Clamp(st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535);
|
case 0xFA: return Clamp(st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535);
|
||||||
|
@ -194,7 +194,17 @@ void AirportStorePSA(ResolverObject *object, uint pos, int32 value)
|
||||||
{
|
{
|
||||||
Station *st = object->u.airport.st;
|
Station *st = object->u.airport.st;
|
||||||
if (object->scope != VSG_SCOPE_SELF || st == NULL) return;
|
if (object->scope != VSG_SCOPE_SELF || st == NULL) return;
|
||||||
st->airport.psa.StoreValue(pos, value);
|
|
||||||
|
if (st->airport.psa == NULL) {
|
||||||
|
/* There is no need to create a storage if the value is zero. */
|
||||||
|
if (value == 0) return;
|
||||||
|
|
||||||
|
/* Create storage on first modification. */
|
||||||
|
uint32 grfid = (object->grffile != NULL) ? object->grffile->grfid : 0;
|
||||||
|
assert(PersistentStorage::CanAllocateItem());
|
||||||
|
st->airport.psa = new PersistentStorage(grfid);
|
||||||
|
}
|
||||||
|
st->airport.psa->StoreValue(pos, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NewAirportResolver(ResolverObject *res, TileIndex tile, Station *st, byte airport_id, byte layout)
|
static void NewAirportResolver(ResolverObject *res, TileIndex tile, Station *st, byte airport_id, byte layout)
|
||||||
|
|
|
@ -158,7 +158,7 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allows to know the size of the persistent storage.
|
* Allows to know the size of the persistent storage.
|
||||||
* @param index Unused.
|
* @param index Index of the item.
|
||||||
* @param grfid Unused.
|
* @param grfid Unused.
|
||||||
* @return Size of the persistent storage in indices.
|
* @return Size of the persistent storage in indices.
|
||||||
*/
|
*/
|
||||||
|
@ -169,7 +169,7 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the first position of the array containing the persistent storage.
|
* Gets the first position of the array containing the persistent storage.
|
||||||
* @param index Unused.
|
* @param index Index of the item.
|
||||||
* @param grfid Unused.
|
* @param grfid Unused.
|
||||||
* @return Pointer to the first position of the storage array or NULL if not present.
|
* @return Pointer to the first position of the storage array or NULL if not present.
|
||||||
*/
|
*/
|
||||||
|
@ -368,11 +368,11 @@ struct NewGRFInspectWindow : Window {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint psa_size = nih->GetPSASize(0, 0);
|
uint psa_size = nih->GetPSASize(index, 0);
|
||||||
if (psa_size != 0) {
|
int32 *psa = nih->GetPSAFirstPosition(index, 0);
|
||||||
|
if (psa_size != 0 && psa != NULL) {
|
||||||
this->DrawString(r, i++, "Persistent storage:");
|
this->DrawString(r, i++, "Persistent storage:");
|
||||||
assert(psa_size % 4 == 0);
|
assert(psa_size % 4 == 0);
|
||||||
int32 *psa = nih->GetPSAFirstPosition(0, 0);
|
|
||||||
for (uint j = 0; j < psa_size; j += 4, psa += 4) {
|
for (uint j = 0; j < psa_size; j += 4, psa += 4) {
|
||||||
this->DrawString(r, i++, " %i: %i %i %i %i", j, psa[0], psa[1], psa[2], psa[3]);
|
this->DrawString(r, i++, " %i: %i %i %i %i", j, psa[0], psa[1], psa[2], psa[3]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -283,7 +283,7 @@ uint32 IndustryGetVariable(const ResolverObject *object, byte variable, byte par
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get a variable from the persistent storage */
|
/* Get a variable from the persistent storage */
|
||||||
case 0x7C: return industry->psa.GetValue(parameter);
|
case 0x7C: return (industry->psa != NULL) ? industry->psa->GetValue(parameter) : 0;
|
||||||
|
|
||||||
/* Industry structure access*/
|
/* Industry structure access*/
|
||||||
case 0x80: return industry->location.tile;
|
case 0x80: return industry->location.tile;
|
||||||
|
@ -386,7 +386,19 @@ void IndustryStorePSA(ResolverObject *object, uint pos, int32 value)
|
||||||
{
|
{
|
||||||
Industry *ind = object->u.industry.ind;
|
Industry *ind = object->u.industry.ind;
|
||||||
if (object->scope != VSG_SCOPE_SELF || ind->index == INVALID_INDUSTRY) return;
|
if (object->scope != VSG_SCOPE_SELF || ind->index == INVALID_INDUSTRY) return;
|
||||||
ind->psa.StoreValue(pos, value);
|
|
||||||
|
if (ind->psa == NULL) {
|
||||||
|
/* There is no need to create a storage if the value is zero. */
|
||||||
|
if (value == 0) return;
|
||||||
|
|
||||||
|
/* Create storage on first modification. */
|
||||||
|
const IndustrySpec *indsp = GetIndustrySpec(ind->type);
|
||||||
|
uint32 grfid = (indsp->grf_prop.grffile != NULL) ? indsp->grf_prop.grffile->grfid : 0;
|
||||||
|
assert(PersistentStorage::CanAllocateItem());
|
||||||
|
ind->psa = new PersistentStorage(grfid);
|
||||||
|
}
|
||||||
|
|
||||||
|
ind->psa->StoreValue(pos, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *indus, IndustryType type)
|
static void NewIndustryResolver(ResolverObject *res, TileIndex tile, Industry *indus, IndustryType type)
|
||||||
|
|
|
@ -158,7 +158,19 @@ void IndustryTileStorePSA(ResolverObject *object, uint pos, int32 value)
|
||||||
{
|
{
|
||||||
Industry *ind = object->u.industry.ind;
|
Industry *ind = object->u.industry.ind;
|
||||||
if (object->scope != VSG_SCOPE_PARENT || ind->index == INVALID_INDUSTRY) return;
|
if (object->scope != VSG_SCOPE_PARENT || ind->index == INVALID_INDUSTRY) return;
|
||||||
ind->psa.StoreValue(pos, value);
|
|
||||||
|
if (ind->psa == NULL) {
|
||||||
|
/* There is no need to create a storage if the value is zero. */
|
||||||
|
if (value == 0) return;
|
||||||
|
|
||||||
|
/* Create storage on first modification. */
|
||||||
|
const IndustrySpec *indsp = GetIndustrySpec(ind->type);
|
||||||
|
uint32 grfid = (indsp->grf_prop.grffile != NULL) ? indsp->grf_prop.grffile->grfid : 0;
|
||||||
|
assert(PersistentStorage::CanAllocateItem());
|
||||||
|
ind->psa = new PersistentStorage(grfid);
|
||||||
|
}
|
||||||
|
|
||||||
|
ind->psa->StoreValue(pos, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void NewIndustryTileResolver(ResolverObject *res, IndustryGfx gfx, TileIndex tile, Industry *indus)
|
static void NewIndustryTileResolver(ResolverObject *res, IndustryGfx gfx, TileIndex tile, Industry *indus)
|
||||||
|
|
|
@ -11,8 +11,12 @@
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "newgrf_storage.h"
|
#include "newgrf_storage.h"
|
||||||
|
#include "core/pool_func.hpp"
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
PersistentStoragePool _persistent_storage_pool("PersistentStorage");
|
||||||
|
INSTANTIATE_POOL_METHODS(PersistentStorage)
|
||||||
|
|
||||||
/** The changed storage arrays */
|
/** The changed storage arrays */
|
||||||
static std::set<BaseStorageArray*> _changed_storage_arrays;
|
static std::set<BaseStorageArray*> _changed_storage_arrays;
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#define NEWGRF_STORAGE_H
|
#define NEWGRF_STORAGE_H
|
||||||
|
|
||||||
#include "core/alloc_func.hpp"
|
#include "core/alloc_func.hpp"
|
||||||
|
#include "core/pool_type.hpp"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for all NewGRF storage arrays. Nothing fancy, only here
|
* Base class for all NewGRF storage arrays. Nothing fancy, only here
|
||||||
|
@ -178,4 +179,40 @@ struct TemporaryStorageArray : BaseStorageArray {
|
||||||
void AddChangedStorage(BaseStorageArray *storage);
|
void AddChangedStorage(BaseStorageArray *storage);
|
||||||
void ClearStorageChanges(bool keep_changes);
|
void ClearStorageChanges(bool keep_changes);
|
||||||
|
|
||||||
|
|
||||||
|
typedef PersistentStorageArray<int32, 16> OldPersistentStorage;
|
||||||
|
|
||||||
|
typedef uint32 PersistentStorageID;
|
||||||
|
|
||||||
|
struct PersistentStorage;
|
||||||
|
typedef Pool<PersistentStorage, PersistentStorageID, 1, 0xFF000> PersistentStoragePool;
|
||||||
|
|
||||||
|
extern PersistentStoragePool _persistent_storage_pool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for pooled persistent storage of data.
|
||||||
|
* On ClearChanges that data is always zero-ed.
|
||||||
|
*/
|
||||||
|
struct PersistentStorage : PersistentStorageArray<int32, 16>, PersistentStoragePool::PoolItem<&_persistent_storage_pool> {
|
||||||
|
uint32 grfid; ///< GRFID associated to this persistent storage. A value of zero means "default".
|
||||||
|
|
||||||
|
/** We don't want GCC to zero our struct! It already is zeroed and has an index! */
|
||||||
|
PersistentStorage(const uint32 new_grfid) : grfid(new_grfid)
|
||||||
|
{
|
||||||
|
this->prev_storage = NULL;
|
||||||
|
memset(this->storage, 0, sizeof(this->storage));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Free the memory used by the persistent storage. */
|
||||||
|
~PersistentStorage()
|
||||||
|
{
|
||||||
|
free(this->prev_storage);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_compile(cpp_lengthof(OldPersistentStorage, storage) == cpp_lengthof(PersistentStorage, storage));
|
||||||
|
|
||||||
|
#define FOR_ALL_STORAGES_FROM(var, start) FOR_ALL_ITEMS_FROM(PersistentStorage, storage_index, var, start)
|
||||||
|
#define FOR_ALL_STORAGES(var) FOR_ALL_STORAGES_FROM(var, 0)
|
||||||
|
|
||||||
#endif /* NEWGRF_STORAGE_H */
|
#endif /* NEWGRF_STORAGE_H */
|
||||||
|
|
|
@ -2595,6 +2595,58 @@ bool AfterLoadGame()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IsSavegameVersionBefore(161)) {
|
||||||
|
/* Before savegame version 161, persistent storages were not stored in a pool. */
|
||||||
|
|
||||||
|
if (!IsSavegameVersionBefore(76)) {
|
||||||
|
Industry *ind;
|
||||||
|
FOR_ALL_INDUSTRIES(ind) {
|
||||||
|
assert(ind->psa != NULL);
|
||||||
|
|
||||||
|
/* Check if the old storage was empty. */
|
||||||
|
bool is_empty = true;
|
||||||
|
for (uint i = 0; i < sizeof(ind->psa->storage); i++) {
|
||||||
|
if (ind->psa->GetValue(i) != 0) {
|
||||||
|
is_empty = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_empty) {
|
||||||
|
ind->psa->grfid = _industry_mngr.GetGRFID(ind->type);
|
||||||
|
} else {
|
||||||
|
delete ind->psa;
|
||||||
|
ind->psa = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsSavegameVersionBefore(145)) {
|
||||||
|
Station *st;
|
||||||
|
FOR_ALL_STATIONS(st) {
|
||||||
|
if (!st->facilities & FACIL_AIRPORT) continue;
|
||||||
|
assert(st->airport.psa != NULL);
|
||||||
|
|
||||||
|
/* Check if the old storage was empty. */
|
||||||
|
bool is_empty = true;
|
||||||
|
for (uint i = 0; i < sizeof(st->airport.psa->storage); i++) {
|
||||||
|
if (st->airport.psa->GetValue(i) != 0) {
|
||||||
|
is_empty = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_empty) {
|
||||||
|
st->airport.psa->grfid = _airport_mngr.GetGRFID(st->airport.type);
|
||||||
|
} else {
|
||||||
|
delete st->airport.psa;
|
||||||
|
st->airport.psa = NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Road stops is 'only' updating some caches */
|
/* Road stops is 'only' updating some caches */
|
||||||
AfterLoadRoadStops();
|
AfterLoadRoadStops();
|
||||||
AfterLoadLabelMaps();
|
AfterLoadLabelMaps();
|
||||||
|
|
|
@ -11,10 +11,13 @@
|
||||||
|
|
||||||
#include "../stdafx.h"
|
#include "../stdafx.h"
|
||||||
#include "../industry.h"
|
#include "../industry.h"
|
||||||
|
#include "../newgrf.h"
|
||||||
|
|
||||||
#include "saveload.h"
|
#include "saveload.h"
|
||||||
#include "newgrf_sl.h"
|
#include "newgrf_sl.h"
|
||||||
|
|
||||||
|
static OldPersistentStorage _old_ind_persistent_storage;
|
||||||
|
|
||||||
static const SaveLoad _industry_desc[] = {
|
static const SaveLoad _industry_desc[] = {
|
||||||
SLE_CONDVAR(Industry, location.tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
SLE_CONDVAR(Industry, location.tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
|
||||||
SLE_CONDVAR(Industry, location.tile, SLE_UINT32, 6, SL_MAX_VERSION),
|
SLE_CONDVAR(Industry, location.tile, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||||
|
@ -50,7 +53,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_CONDARR(Industry, psa.storage, SLE_UINT32, 16, 76, SL_MAX_VERSION),
|
SLEG_CONDARR(_old_ind_persistent_storage.storage, SLE_UINT32, 16, 76, 160),
|
||||||
|
SLE_CONDREF(Industry, psa, REF_STORAGE, 161, SL_MAX_VERSION),
|
||||||
|
|
||||||
SLE_CONDVAR(Industry, random_triggers, SLE_UINT8, 82, SL_MAX_VERSION),
|
SLE_CONDVAR(Industry, random_triggers, SLE_UINT8, 82, SL_MAX_VERSION),
|
||||||
SLE_CONDVAR(Industry, random, SLE_UINT16, 82, SL_MAX_VERSION),
|
SLE_CONDVAR(Industry, random, SLE_UINT16, 82, SL_MAX_VERSION),
|
||||||
|
@ -90,6 +94,14 @@ static void Load_INDY()
|
||||||
while ((index = SlIterateArray()) != -1) {
|
while ((index = SlIterateArray()) != -1) {
|
||||||
Industry *i = new (index) Industry();
|
Industry *i = new (index) Industry();
|
||||||
SlObject(i, _industry_desc);
|
SlObject(i, _industry_desc);
|
||||||
|
|
||||||
|
/* Before savegame version 161, persistent storages were not stored in a pool. */
|
||||||
|
if (IsSavegameVersionBefore(161) && !IsSavegameVersionBefore(76)) {
|
||||||
|
/* Store the old persistent storage. The GRFID will be added later. */
|
||||||
|
assert(PersistentStorage::CanAllocateItem());
|
||||||
|
i->psa = new PersistentStorage(0);
|
||||||
|
memcpy(i->psa->storage, _old_ind_persistent_storage.storage, sizeof(i->psa->storage));
|
||||||
|
}
|
||||||
Industry::IncIndustryTypeCount(i->type);
|
Industry::IncIndustryTypeCount(i->type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -225,8 +225,9 @@
|
||||||
* 158 21933
|
* 158 21933
|
||||||
* 159 21962
|
* 159 21962
|
||||||
* 160 21974
|
* 160 21974
|
||||||
|
* 161 22567
|
||||||
*/
|
*/
|
||||||
extern const uint16 SAVEGAME_VERSION = 160; ///< Current savegame version of OpenTTD.
|
extern const uint16 SAVEGAME_VERSION = 161; ///< Current savegame version of OpenTTD.
|
||||||
|
|
||||||
SavegameType _savegame_type; ///< type of savegame we are loading
|
SavegameType _savegame_type; ///< type of savegame we are loading
|
||||||
|
|
||||||
|
@ -404,6 +405,7 @@ extern const ChunkHandler _autoreplace_chunk_handlers[];
|
||||||
extern const ChunkHandler _labelmaps_chunk_handlers[];
|
extern const ChunkHandler _labelmaps_chunk_handlers[];
|
||||||
extern const ChunkHandler _airport_chunk_handlers[];
|
extern const ChunkHandler _airport_chunk_handlers[];
|
||||||
extern const ChunkHandler _object_chunk_handlers[];
|
extern const ChunkHandler _object_chunk_handlers[];
|
||||||
|
extern const ChunkHandler _persistent_storage_chunk_handlers[];
|
||||||
|
|
||||||
/** Array of all chunks in a savegame, \c NULL terminated. */
|
/** Array of all chunks in a savegame, \c NULL terminated. */
|
||||||
static const ChunkHandler * const _chunk_handlers[] = {
|
static const ChunkHandler * const _chunk_handlers[] = {
|
||||||
|
@ -434,6 +436,7 @@ static const ChunkHandler * const _chunk_handlers[] = {
|
||||||
_labelmaps_chunk_handlers,
|
_labelmaps_chunk_handlers,
|
||||||
_airport_chunk_handlers,
|
_airport_chunk_handlers,
|
||||||
_object_chunk_handlers,
|
_object_chunk_handlers,
|
||||||
|
_persistent_storage_chunk_handlers,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1173,9 +1176,10 @@ static size_t ReferenceToInt(const void *obj, SLRefType rt)
|
||||||
case REF_TOWN: return ((const Town*)obj)->index + 1;
|
case REF_TOWN: return ((const Town*)obj)->index + 1;
|
||||||
case REF_ORDER: return ((const Order*)obj)->index + 1;
|
case REF_ORDER: return ((const Order*)obj)->index + 1;
|
||||||
case REF_ROADSTOPS: return ((const RoadStop*)obj)->index + 1;
|
case REF_ROADSTOPS: return ((const RoadStop*)obj)->index + 1;
|
||||||
case REF_ENGINE_RENEWS: return ((const EngineRenew*)obj)->index + 1;
|
case REF_ENGINE_RENEWS: return ((const EngineRenew*)obj)->index + 1;
|
||||||
case REF_CARGO_PACKET: return ((const CargoPacket*)obj)->index + 1;
|
case REF_CARGO_PACKET: return ((const CargoPacket*)obj)->index + 1;
|
||||||
case REF_ORDERLIST: return ((const OrderList*)obj)->index + 1;
|
case REF_ORDERLIST: return ((const OrderList*)obj)->index + 1;
|
||||||
|
case REF_STORAGE: return ((const PersistentStorage*)obj)->index + 1;
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1245,6 +1249,10 @@ static void *IntToReference(size_t index, SLRefType rt)
|
||||||
if (CargoPacket::IsValidID(index)) return CargoPacket::Get(index);
|
if (CargoPacket::IsValidID(index)) return CargoPacket::Get(index);
|
||||||
SlErrorCorrupt("Referencing invalid CargoPacket");
|
SlErrorCorrupt("Referencing invalid CargoPacket");
|
||||||
|
|
||||||
|
case REF_STORAGE:
|
||||||
|
if (PersistentStorage::IsValidID(index)) return PersistentStorage::Get(index);
|
||||||
|
SlErrorCorrupt("Referencing invalid PersistentStorage");
|
||||||
|
|
||||||
default: NOT_REACHED();
|
default: NOT_REACHED();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,7 @@ enum SLRefType {
|
||||||
REF_ENGINE_RENEWS = 6, ///< Load/save a reference to an engine renewal (autoreplace).
|
REF_ENGINE_RENEWS = 6, ///< Load/save a reference to an engine renewal (autoreplace).
|
||||||
REF_CARGO_PACKET = 7, ///< Load/save a reference to a cargo packet.
|
REF_CARGO_PACKET = 7, ///< Load/save a reference to a cargo packet.
|
||||||
REF_ORDERLIST = 8, ///< Load/save a reference to an orderlist.
|
REF_ORDERLIST = 8, ///< Load/save a reference to an orderlist.
|
||||||
|
REF_STORAGE = 9, ///< Load/save a reference to a persistent storage.
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Highest possible savegame version. */
|
/** Highest possible savegame version. */
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "../roadstop_base.h"
|
#include "../roadstop_base.h"
|
||||||
#include "../vehicle_base.h"
|
#include "../vehicle_base.h"
|
||||||
#include "../newgrf_station.h"
|
#include "../newgrf_station.h"
|
||||||
|
#include "../newgrf.h"
|
||||||
|
|
||||||
#include "saveload.h"
|
#include "saveload.h"
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
|
@ -344,6 +345,8 @@ static const SaveLoad _base_station_desc[] = {
|
||||||
SLE_END()
|
SLE_END()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static OldPersistentStorage _old_st_persistent_storage;
|
||||||
|
|
||||||
static const SaveLoad _station_desc[] = {
|
static const SaveLoad _station_desc[] = {
|
||||||
SLE_WRITEBYTE(Station, facilities, FACIL_NONE),
|
SLE_WRITEBYTE(Station, facilities, FACIL_NONE),
|
||||||
SLE_ST_INCLUDE(),
|
SLE_ST_INCLUDE(),
|
||||||
|
@ -362,7 +365,8 @@ static const SaveLoad _station_desc[] = {
|
||||||
SLE_CONDVAR(Station, airport.layout, SLE_UINT8, 145, SL_MAX_VERSION),
|
SLE_CONDVAR(Station, airport.layout, SLE_UINT8, 145, SL_MAX_VERSION),
|
||||||
SLE_VAR(Station, airport.flags, SLE_UINT64),
|
SLE_VAR(Station, airport.flags, SLE_UINT64),
|
||||||
SLE_CONDVAR(Station, airport.rotation, SLE_UINT8, 145, SL_MAX_VERSION),
|
SLE_CONDVAR(Station, airport.rotation, SLE_UINT8, 145, SL_MAX_VERSION),
|
||||||
SLE_CONDARR(Station, airport.psa.storage, SLE_UINT32, 16, 145, SL_MAX_VERSION),
|
SLEG_CONDARR(_old_st_persistent_storage.storage, SLE_UINT32, 16, 145, 160),
|
||||||
|
SLE_CONDREF(Station, airport.psa, REF_STORAGE, 161, SL_MAX_VERSION),
|
||||||
|
|
||||||
SLE_VAR(Station, indtype, SLE_UINT8),
|
SLE_VAR(Station, indtype, SLE_UINT8),
|
||||||
|
|
||||||
|
@ -437,6 +441,15 @@ static void Load_STNN()
|
||||||
|
|
||||||
if (!waypoint) {
|
if (!waypoint) {
|
||||||
Station *st = Station::From(bst);
|
Station *st = Station::From(bst);
|
||||||
|
|
||||||
|
/* Before savegame version 161, persistent storages were not stored in a pool. */
|
||||||
|
if (IsSavegameVersionBefore(161) && !IsSavegameVersionBefore(145) && st->facilities & FACIL_AIRPORT) {
|
||||||
|
/* Store the old persistent storage. The GRFID will be added later. */
|
||||||
|
assert(PersistentStorage::CanAllocateItem());
|
||||||
|
st->airport.psa = new PersistentStorage(0);
|
||||||
|
memcpy(st->airport.psa->storage, _old_st_persistent_storage.storage, sizeof(st->airport.psa->storage));
|
||||||
|
}
|
||||||
|
|
||||||
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
for (CargoID i = 0; i < NUM_CARGO; i++) {
|
||||||
SlObject(&st->goods[i], GetGoodsDesc());
|
SlObject(&st->goods[i], GetGoodsDesc());
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
/* $Id$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of OpenTTD.
|
||||||
|
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||||
|
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file persistent_storage_sl.cpp Code handling saving and loading of persistent storages. */
|
||||||
|
|
||||||
|
#include "../stdafx.h"
|
||||||
|
#include "../newgrf_storage.h"
|
||||||
|
#include "saveload.h"
|
||||||
|
|
||||||
|
/** Description of the data to save and load in #PersistentStorage. */
|
||||||
|
static const SaveLoad _storage_desc[] = {
|
||||||
|
SLE_CONDVAR(PersistentStorage, grfid, SLE_UINT32, 6, SL_MAX_VERSION),
|
||||||
|
SLE_CONDARR(PersistentStorage, storage, SLE_UINT32, 16, 161, SL_MAX_VERSION),
|
||||||
|
SLE_END()
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Load persistent storage data. */
|
||||||
|
static void Load_PSAC()
|
||||||
|
{
|
||||||
|
int index;
|
||||||
|
|
||||||
|
while ((index = SlIterateArray()) != -1) {
|
||||||
|
assert(PersistentStorage::CanAllocateItem());
|
||||||
|
PersistentStorage *ps = new (index) PersistentStorage(0);
|
||||||
|
SlObject(ps, _storage_desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Save persistent storage data. */
|
||||||
|
static void Save_PSAC()
|
||||||
|
{
|
||||||
|
PersistentStorage *ps;
|
||||||
|
|
||||||
|
/* Write the industries */
|
||||||
|
FOR_ALL_STORAGES(ps) {
|
||||||
|
SlSetArrayIndex(ps->index);
|
||||||
|
SlObject(ps, _storage_desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Chunk handler for persistent storages. */
|
||||||
|
extern const ChunkHandler _persistent_storage_chunk_handlers[] = {
|
||||||
|
{ 'PSAC', Save_PSAC, Load_PSAC, NULL, NULL, CH_ARRAY | CH_LAST},
|
||||||
|
};
|
|
@ -96,6 +96,10 @@ Station::~Station()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear the persistent storage. */
|
||||||
|
delete this->airport.psa;
|
||||||
|
|
||||||
|
|
||||||
InvalidateWindowData(WC_STATION_LIST, this->owner, 0);
|
InvalidateWindowData(WC_STATION_LIST, this->owner, 0);
|
||||||
|
|
||||||
DeleteWindowById(WC_STATION_VIEW, index);
|
DeleteWindowById(WC_STATION_VIEW, index);
|
||||||
|
|
|
@ -56,15 +56,14 @@ struct GoodsEntry {
|
||||||
|
|
||||||
/** All airport-related information. Only valid if tile != INVALID_TILE. */
|
/** All airport-related information. Only valid if tile != INVALID_TILE. */
|
||||||
struct Airport : public TileArea {
|
struct Airport : public TileArea {
|
||||||
typedef PersistentStorageArray<int32, 16> PersistentStorage;
|
|
||||||
|
|
||||||
Airport() : TileArea(INVALID_TILE, 0, 0) {}
|
Airport() : TileArea(INVALID_TILE, 0, 0) {}
|
||||||
|
|
||||||
uint64 flags; ///< stores which blocks on the airport are taken. was 16 bit earlier on, then 32
|
uint64 flags; ///< stores which blocks on the airport are taken. was 16 bit earlier on, then 32
|
||||||
byte type; ///< Type of this airport, @see AirportTypes.
|
byte type; ///< Type of this airport, @see AirportTypes.
|
||||||
byte layout; ///< Airport layout number.
|
byte layout; ///< Airport layout number.
|
||||||
Direction rotation; ///< How this airport is rotated.
|
Direction rotation; ///< How this airport is rotated.
|
||||||
PersistentStorage psa; ///< Persistent storage for NewGRF airports
|
|
||||||
|
PersistentStorage *psa; ///< Persistent storage for NewGRF airports.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the AirportSpec that from the airport type of this airport. If there
|
* Get the AirportSpec that from the airport type of this airport. If there
|
||||||
|
|
|
@ -2191,7 +2191,6 @@ CommandCost CmdBuildAirport(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
|
||||||
st->airport.layout = layout;
|
st->airport.layout = layout;
|
||||||
st->airport.flags = 0;
|
st->airport.flags = 0;
|
||||||
st->airport.rotation = rotation;
|
st->airport.rotation = rotation;
|
||||||
st->airport.psa.ResetToZero();
|
|
||||||
|
|
||||||
st->rect.BeforeAddRect(tile, w, h, StationRect::ADD_TRY);
|
st->rect.BeforeAddRect(tile, w, h, StationRect::ADD_TRY);
|
||||||
|
|
||||||
|
@ -2271,6 +2270,9 @@ static CommandCost RemoveAirport(TileIndex tile, DoCommandFlag flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & DC_EXEC) {
|
if (flags & DC_EXEC) {
|
||||||
|
/* Clear the persistent storage. */
|
||||||
|
delete st->airport.psa;
|
||||||
|
|
||||||
const AirportSpec *as = st->airport.GetSpec();
|
const AirportSpec *as = st->airport.GetSpec();
|
||||||
for (uint i = 0; i < st->airport.GetNumHangars(); ++i) {
|
for (uint i = 0; i < st->airport.GetNumHangars(); ++i) {
|
||||||
DeleteWindowById(
|
DeleteWindowById(
|
||||||
|
@ -2288,7 +2290,6 @@ static CommandCost RemoveAirport(TileIndex tile, DoCommandFlag flags)
|
||||||
|
|
||||||
st->airport.Clear();
|
st->airport.Clear();
|
||||||
st->facilities &= ~FACIL_AIRPORT;
|
st->facilities &= ~FACIL_AIRPORT;
|
||||||
st->airport.psa.ResetToZero();
|
|
||||||
|
|
||||||
SetWindowWidgetDirty(WC_STATION_VIEW, st->index, SVW_PLANES);
|
SetWindowWidgetDirty(WC_STATION_VIEW, st->index, SVW_PLANES);
|
||||||
|
|
||||||
|
|
|
@ -291,12 +291,13 @@ class NIHIndustry : public NIHelper {
|
||||||
const void *GetSpec(uint index) const { return GetIndustrySpec(Industry::Get(index)->type); }
|
const void *GetSpec(uint index) const { return GetIndustrySpec(Industry::Get(index)->type); }
|
||||||
void SetStringParameters(uint index) const { this->SetSimpleStringParameters(STR_INDUSTRY_NAME, index); }
|
void SetStringParameters(uint index) const { this->SetSimpleStringParameters(STR_INDUSTRY_NAME, index); }
|
||||||
void Resolve(ResolverObject *ro, uint32 index) const { extern void GetIndustryResolver(ResolverObject *ro, uint index); GetIndustryResolver(ro, index); }
|
void Resolve(ResolverObject *ro, uint32 index) const { extern void GetIndustryResolver(ResolverObject *ro, uint index); GetIndustryResolver(ro, index); }
|
||||||
uint GetPSASize(uint index, uint32 grfid) const { return cpp_lengthof(Industry, psa.storage); }
|
uint GetPSASize(uint index, uint32 grfid) const { return cpp_lengthof(PersistentStorage, storage); }
|
||||||
|
|
||||||
int32 *GetPSAFirstPosition(uint index, uint32 grfid) const
|
int32 *GetPSAFirstPosition(uint index, uint32 grfid) const
|
||||||
{
|
{
|
||||||
const void *base = this->GetInstance(index);
|
Industry *i = (Industry *)this->GetInstance(index);
|
||||||
return (int32*)((byte*)base + cpp_offsetof(Industry, psa.storage));
|
if (i->psa == NULL) return NULL;
|
||||||
|
return (int32 *)(&i->psa->storage);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue