diff options
-rw-r--r-- | oldloader.c | 3 | ||||
-rw-r--r-- | signs.c | 52 | ||||
-rw-r--r-- | signs.h | 22 | ||||
-rw-r--r-- | ttd.c | 2 |
4 files changed, 58 insertions, 21 deletions
diff --git a/oldloader.c b/oldloader.c index ad7455c4e..8647a0eeb 100644 --- a/oldloader.c +++ b/oldloader.c @@ -1100,6 +1100,9 @@ static void FixSign(OldSign *o, int num) if (o->text == 0) continue; + if (!AddBlockIfNeeded(&_sign_pool, i)) + error("Signs: failed loading savegame: too many signs"); + n = GetSign(i); n->str = o->text; @@ -5,6 +5,26 @@ #include "saveload.h" #include "command.h" +enum { + /* Max signs: 64000 (4 * 16000) */ + SIGN_POOL_BLOCK_SIZE_BITS = 2, /* In bits, so (1 << 2) == 4 */ + SIGN_POOL_MAX_BLOCKS = 16000, +}; + +/** + * Called if a new block is added to the sign-pool + */ +static void SignPoolNewBlock(uint start_item) +{ + SignStruct *ss; + + FOR_ALL_SIGNS_FROM(ss, start_item) + ss->index = start_item++; +} + +/* Initialize the sign-pool */ +MemoryPool _sign_pool = { "Signs", SIGN_POOL_MAX_BLOCKS, SIGN_POOL_BLOCK_SIZE_BITS, sizeof(SignStruct), &SignPoolNewBlock, 0, 0, NULL }; + /** * * Update the coordinate of one sign @@ -60,6 +80,10 @@ static SignStruct *AllocateSign(void) if (s->str == 0) return s; + /* Check if we can add a block to the pool */ + if (AddBlockToPool(&_sign_pool)) + return AllocateSign(); + return NULL; } @@ -177,14 +201,8 @@ void PlaceProc_Sign(uint tile) */ void InitializeSigns(void) { - SignStruct *s; - int i; - - memset(_sign_list, 0, sizeof(_sign_list[0]) * _sign_size); - - i = 0; - FOR_ALL_SIGNS(s) - s->index = i++; + CleanPool(&_sign_pool); + AddBlockToPool(&_sign_pool); } static const byte _sign_desc[] = { @@ -205,13 +223,13 @@ static const byte _sign_desc[] = { */ static void Save_SIGN(void) { - SignStruct *s; + SignStruct *ss; - FOR_ALL_SIGNS(s) { + FOR_ALL_SIGNS(ss) { /* Don't save empty signs */ - if (s->str != 0) { - SlSetArrayIndex(s->index); - SlObject(s, _sign_desc); + if (ss->str != 0) { + SlSetArrayIndex(ss->index); + SlObject(ss, _sign_desc); } } } @@ -225,9 +243,13 @@ static void Load_SIGN(void) { int index; while ((index = SlIterateArray()) != -1) { - SignStruct *s = GetSign(index); + SignStruct *ss; + + if (!AddBlockIfNeeded(&_sign_pool, index)) + error("Signs: failed loading savegame: too many signs"); - SlObject(s, _sign_desc); + ss = GetSign(index); + SlObject(ss, _sign_desc); } } @@ -1,6 +1,8 @@ #ifndef SIGNS_H #define SIGNS_H +#include "pool.h" + typedef struct SignStruct { StringID str; ViewportSign sign; @@ -13,16 +15,26 @@ typedef struct SignStruct { uint16 index; } SignStruct; -VARDEF SignStruct _sign_list[40]; -VARDEF uint _sign_size; +extern MemoryPool _sign_pool; +/** + * Get the pointer to the sign with index 'index' + */ static inline SignStruct *GetSign(uint index) { - assert(index < _sign_size); - return &_sign_list[index]; + return (SignStruct*)GetItemFromPool(&_sign_pool, index); +} + +/** + * Get the current size of the SignPool + */ +static inline uint16 GetSignPoolSize(void) +{ + return _sign_pool.total_items; } -#define FOR_ALL_SIGNS(s) for(s = _sign_list; s != &_sign_list[_sign_size]; s++) +#define FOR_ALL_SIGNS_FROM(ss, start) for (ss = GetSign(start); ss != NULL; ss = (ss->index + 1 < GetSignPoolSize()) ? GetSign(ss->index + 1) : NULL) +#define FOR_ALL_SIGNS(ss) FOR_ALL_SIGNS_FROM(ss, 0) VARDEF SignStruct *_new_sign_struct; @@ -496,7 +496,6 @@ static void InitializeDynamicVariables(void) { /* Dynamic stuff needs to be initialized somewhere... */ _roadstops_size = lengthof(_roadstops); - _sign_size = lengthof(_sign_list); _orders_size = lengthof(_orders); _station_sort = NULL; @@ -512,6 +511,7 @@ static void UnInitializeDynamicVariables(void) CleanPool(&_industry_pool); CleanPool(&_station_pool); CleanPool(&_vehicle_pool); + CleanPool(&_sign_pool); free(_station_sort); free(_vehicle_sort); |