(svn r1787) -Add: Dynamic signs (euh.. yeah, this means you can built 64k signs)
authortruelight
Fri, 04 Feb 2005 14:45:32 +0000
changeset 1283 b9569cc0644f
parent 1282 e7a73ee62d2f
child 1284 06a52178bf46
(svn r1787) -Add: Dynamic signs (euh.. yeah, this means you can built 64k signs)
oldloader.c
signs.c
signs.h
ttd.c
--- a/oldloader.c	Fri Feb 04 14:24:23 2005 +0000
+++ b/oldloader.c	Fri Feb 04 14:45:32 2005 +0000
@@ -1100,6 +1100,9 @@
 		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;
--- a/signs.c	Fri Feb 04 14:24:23 2005 +0000
+++ b/signs.c	Fri Feb 04 14:45:32 2005 +0000
@@ -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 @@
 		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 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 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 @@
 {
 	int index;
 	while ((index = SlIterateArray()) != -1) {
-		SignStruct *s = GetSign(index);
+		SignStruct *ss;
 
-		SlObject(s, _sign_desc);
+		if (!AddBlockIfNeeded(&_sign_pool, index))
+			error("Signs: failed loading savegame: too many signs");
+
+		ss = GetSign(index);
+		SlObject(ss, _sign_desc);
 	}
 }
 
--- a/signs.h	Fri Feb 04 14:24:23 2005 +0000
+++ b/signs.h	Fri Feb 04 14:45:32 2005 +0000
@@ -1,6 +1,8 @@
 #ifndef SIGNS_H
 #define SIGNS_H
 
+#include "pool.h"
+
 typedef struct SignStruct {
 	StringID     str;
 	ViewportSign sign;
@@ -13,16 +15,26 @@
 	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);
 }
 
-#define FOR_ALL_SIGNS(s) for(s = _sign_list; s != &_sign_list[_sign_size]; s++)
+/**
+ * Get the current size of the SignPool
+ */
+static inline uint16 GetSignPoolSize(void)
+{
+	return _sign_pool.total_items;
+}
+
+#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;
 
--- a/ttd.c	Fri Feb 04 14:24:23 2005 +0000
+++ b/ttd.c	Fri Feb 04 14:45:32 2005 +0000
@@ -496,7 +496,6 @@
 {
 	/* 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 @@
 	CleanPool(&_industry_pool);
 	CleanPool(&_station_pool);
 	CleanPool(&_vehicle_pool);
+	CleanPool(&_sign_pool);
 
 	free(_station_sort);
 	free(_vehicle_sort);