summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--oldloader.c3
-rw-r--r--signs.c52
-rw-r--r--signs.h22
-rw-r--r--ttd.c2
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;
diff --git a/signs.c b/signs.c
index 10b6c155c..267a254f5 100644
--- a/signs.c
+++ b/signs.c
@@ -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);
}
}
diff --git a/signs.h b/signs.h
index 98934ef78..1d19206c5 100644
--- a/signs.h
+++ b/signs.h
@@ -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;
diff --git a/ttd.c b/ttd.c
index 1f951b19d..f0239c608 100644
--- a/ttd.c
+++ b/ttd.c
@@ -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);