(svn r1776) -Add: Dynamic stations. You can now have up to 64k of stations
authortruelight
Thu, 03 Feb 2005 17:22:35 +0000
changeset 1272 d3e09adb7736
parent 1271 2b8bfb61ce90
child 1273 240fa6848fbc
(svn r1776) -Add: Dynamic stations. You can now have up to 64k of stations
oldloader.c
saveload.c
station.h
station_cmd.c
station_gui.c
ttd.c
--- a/oldloader.c	Wed Feb 02 20:36:04 2005 +0000
+++ b/oldloader.c	Thu Feb 03 17:22:35 2005 +0000
@@ -713,6 +713,9 @@
 		if (o->xy == 0)
 			continue;
 
+		if (!AddBlockIfNeeded(&_station_pool, i))
+			error("Stations: failed loading savegame: too many stations");
+
 		s = GetStation(i);
 
 		s->xy = o->xy;
--- a/saveload.c	Wed Feb 02 20:36:04 2005 +0000
+++ b/saveload.c	Thu Feb 03 17:22:35 2005 +0000
@@ -943,7 +943,11 @@
 	switch (t) {
 		case REF_ORDER:   return GetOrder(r - 1);
 		case REF_VEHICLE: return GetVehicle(r - 1);
-		case REF_STATION: return GetStation(r - 1);
+		case REF_STATION: {
+			if (!AddBlockIfNeeded(&_station_pool, r - 1))
+				error("Stations: failed loading savegame: too many stations");
+			return GetStation(r - 1);
+		}
 		case REF_TOWN: {
 			if (!AddBlockIfNeeded(&_town_pool, r - 1))
 				error("Towns: failed loading savegame: too many towns");
--- a/station.h	Wed Feb 02 20:36:04 2005 +0000
+++ b/station.h	Thu Feb 03 17:22:35 2005 +0000
@@ -1,6 +1,7 @@
 #ifndef STATION_H
 #define STATION_H
 
+#include "pool.h"
 #include "sprite.h"
 #include "tile.h"
 #include "vehicle.h"
@@ -125,19 +126,30 @@
 void UpdateAllStationVirtCoord(void);
 
 VARDEF RoadStop _roadstops[NUM_ROAD_STOPS * 2];
-VARDEF Station _stations[250];
 VARDEF uint _roadstops_size;
-VARDEF uint _stations_size;
 
 VARDEF SortStruct *_station_sort;
 
+extern MemoryPool _station_pool;
+
+/**
+ * Get the pointer to the station with index 'index'
+ */
 static inline Station *GetStation(uint index)
 {
-	assert(index < _stations_size);
-	return &_stations[index];
+	return (Station*)GetItemFromPool(&_station_pool, index);
 }
 
-#define FOR_ALL_STATIONS(st) for(st = _stations; st != &_stations[_stations_size]; st++)
+/**
+ * Get the current size of the StationPool
+ */
+static inline uint16 GetStationPoolSize(void)
+{
+	return _station_pool.total_items;
+}
+
+#define FOR_ALL_STATIONS_FROM(st, start) for (st = GetStation(start); st != NULL; st = (st->index + 1 < GetStationPoolSize()) ? GetStation(st->index + 1) : NULL)
+#define FOR_ALL_STATIONS(st) FOR_ALL_STATIONS_FROM(st, 0)
 
 VARDEF bool _station_sort_dirty[MAX_PLAYERS];
 VARDEF bool _global_station_sort_dirty;
--- a/station_cmd.c	Wed Feb 02 20:36:04 2005 +0000
+++ b/station_cmd.c	Thu Feb 03 17:22:35 2005 +0000
@@ -18,6 +18,27 @@
 #include "sprite.h"
 #include "npf.h"
 
+enum {
+	/* Max stations: 64000 (64 * 1000) */
+	STATION_POOL_BLOCK_SIZE_BITS = 6,       /* In bits, so (1 << 6) == 64 */
+	STATION_POOL_MAX_BLOCKS      = 1000,
+};
+
+/**
+ * Called if a new block is added to the station-pool
+ */
+static void StationPoolNewBlock(uint start_item)
+{
+	Station *st;
+
+	FOR_ALL_STATIONS_FROM(st, start_item)
+		st->index = start_item++;
+}
+
+/* Initialize the station-pool */
+MemoryPool _station_pool = { "Stations", STATION_POOL_MAX_BLOCKS, STATION_POOL_BLOCK_SIZE_BITS, sizeof(Station), &StationPoolNewBlock, 0, 0, NULL };
+
+
 // FIXME -- need to be embedded into Airport variable. Is dynamically
 // deducteable from graphics-tile array, so will not be needed
 const byte _airport_size_x[5] = {4, 6, 1, 6, 7 };
@@ -26,10 +47,6 @@
 void ShowAircraftDepotWindow(uint tile);
 extern void UpdateAirplanesOnNewStation(Station *st);
 
-enum {
-	STATIONS_MIN_FREE_FOR_AI = 30
-};
-
 static void MarkStationDirty(Station *st)
 {
 	if (st->sign.width_1 != 0) {
@@ -216,28 +233,25 @@
 
 static Station *AllocateStation(void)
 {
-	Station *st, *a_free = NULL;
-	int num_free = 0;
-	int i;
+	Station *st = NULL;
 
 	FOR_ALL_STATIONS(st) {
 		if (st->xy == 0) {
-			num_free++;
-			if (a_free == NULL)
-				a_free = st;
+			uint index = st->index;
+
+			memset(st, 0, sizeof(Station));
+			st->index = index;
+
+			return st;
 		}
 	}
 
-	if (a_free == NULL ||
-			(num_free < STATIONS_MIN_FREE_FOR_AI && IS_HUMAN_PLAYER(_current_player))) {
-		_error_message = STR_3008_TOO_MANY_STATIONS_LOADING;
-		return NULL;
-	}
-
-	i = a_free->index;
-	memset(a_free, 0, sizeof(Station));
-	a_free->index = i;
-	return a_free;
+	/* Check if we can add a block to the pool */
+	if (AddBlockToPool(&_station_pool))
+		return AllocateStation();
+
+	_error_message = STR_3008_TOO_MANY_STATIONS_LOADING;
+	return NULL;
 }
 
 
@@ -2552,14 +2566,14 @@
 
 void OnTick_Station(void)
 {
-	int i;
+	uint i;
 	Station *st;
 
 	if (_game_mode == GM_EDITOR)
 		return;
 
 	i = _station_tick_ctr;
-	if (++_station_tick_ctr == _stations_size)
+	if (++_station_tick_ctr == GetStationPoolSize())
 		_station_tick_ctr = 0;
 
 	st = GetStation(i);
@@ -2890,15 +2904,11 @@
 
 void InitializeStations(void)
 {
-	int i;
-	Station *s;
+	/* Clean the station pool and create 1 block in it */
+	CleanPool(&_station_pool);
+	AddBlockToPool(&_station_pool);
 
 	memset(_roadstops, 0, sizeof(_roadstops));
-	memset(_stations, 0, sizeof(_stations[0]) * _stations_size);
-
-	i = 0;
-	FOR_ALL_STATIONS(s)
-		s->index = i++;
 
 	_station_tick_ctr = 0;
 
@@ -3038,8 +3048,12 @@
 {
 	int index;
 	while ((index = SlIterateArray()) != -1) {
-		Station *st = GetStation(index);
-
+		Station *st;
+
+		if (!AddBlockIfNeeded(&_station_pool, index))
+			error("Stations: failed loading savegame: too many stations");
+
+		st = GetStation(index);
 		SaveLoad_STNS(st);
 
 		// this means it's an oldstyle savegame without support for nonuniform stations
@@ -3080,7 +3094,7 @@
 
 	/* This is to ensure all pointers are within the limits of
 	    _stations_size */
-	if (_station_tick_ctr > _stations_size)
+	if (_station_tick_ctr > GetStationPoolSize())
 		_station_tick_ctr = 0;
 }
 
--- a/station_gui.c	Wed Feb 02 20:36:04 2005 +0000
+++ b/station_gui.c	Thu Feb 03 17:22:35 2005 +0000
@@ -84,7 +84,7 @@
 		*i = 0;
 
 	/* Create array for sorting */
-	_station_sort = realloc(_station_sort, _stations_size * sizeof(_station_sort[0]));
+	_station_sort = realloc(_station_sort, GetStationPoolSize() * sizeof(_station_sort[0]));
 	if (_station_sort == NULL)
 		error("Could not allocate memory for the station-sorting-list");
 
@@ -318,7 +318,7 @@
 	byte *b;
 
 
-	station_id = (byte)w->window_number;
+	station_id = (uint16)w->window_number;
 
 	st = GetStation(w->window_number);
 
--- a/ttd.c	Wed Feb 02 20:36:04 2005 +0000
+++ b/ttd.c	Thu Feb 03 17:22:35 2005 +0000
@@ -495,7 +495,6 @@
 static void InitializeDynamicVariables(void)
 {
 	/* Dynamic stuff needs to be initialized somewhere... */
-	_stations_size  = lengthof(_stations);
 	_roadstops_size = lengthof(_roadstops);
 	_vehicles_size  = lengthof(_vehicles);
 	_sign_size      = lengthof(_sign_list);
@@ -512,6 +511,7 @@
 	/* Dynamic stuff needs to be free'd somewhere... */
 	CleanPool(&_town_pool);
 	CleanPool(&_industry_pool);
+	CleanPool(&_station_pool);
 
 	free(_station_sort);
 	free(_vehicle_sort);