(svn r1788) -Add: Made RoadStops dynamic. You can now create up to 64k roadstops.
authortruelight
Fri, 04 Feb 2005 15:31:30 +0000
changeset 1284 e1969eb0227b
parent 1283 85b520ad7266
child 1285 4bda5c927b45
(svn r1788) -Add: Made RoadStops dynamic. You can now create up to 64k roadstops.
oldloader.c
saveload.c
station.h
station_cmd.c
ttd.c
--- a/oldloader.c	Fri Feb 04 14:45:32 2005 +0000
+++ b/oldloader.c	Fri Feb 04 15:31:30 2005 +0000
@@ -720,16 +720,32 @@
 
 		s->xy = o->xy;
 		s->town = REMAP_TOWN_PTR(o->town);
+
+		s->bus_stops = NULL;
+		s->truck_stops = NULL;
+
 		if (o->bus_tile != 0) {
-			s->bus_stops = GetFirstFreeRoadStop();
+			s->bus_stops = AllocateRoadStop();
 			s->bus_stops->xy = o->bus_tile;
-		} else
-			s->bus_stops = NULL;
+			s->bus_stops->used = true;
+			s->bus_stops->status = 3;
+			s->bus_stops->station = s->index;
+			s->bus_stops->next = NULL;
+			s->bus_stops->prev = NULL;
+			s->bus_stops->slot[0] = s->bus_stops->slot[1] = INVALID_SLOT;
+		}
+
 		if (o->lorry_tile != 0) {
-			s->truck_stops = GetFirstFreeRoadStop();
+			s->truck_stops = AllocateRoadStop();
 			s->truck_stops->xy = o->lorry_tile;
-		} else
-			s->truck_stops = 0;
+			s->truck_stops->used = true;
+			s->truck_stops->status = 3;
+			s->truck_stops->station = s->index;
+			s->truck_stops->next = NULL;
+			s->truck_stops->prev = NULL;
+			s->truck_stops->slot[0] = s->truck_stops->slot[1] = INVALID_SLOT;
+		}
+
 		s->train_tile = o->train_tile;
 		s->airport_tile = o->airport_tile;
 		s->dock_tile = o->dock_tile;
--- a/saveload.c	Fri Feb 04 14:45:32 2005 +0000
+++ b/saveload.c	Fri Feb 04 15:31:30 2005 +0000
@@ -917,10 +917,7 @@
 		case REF_STATION: return ((Station *)v)->index + 1;
 		case REF_TOWN:    return ((Town *)v)->index + 1;
 		case REF_ORDER:   return ((Order *)v)->index + 1;
-
-		case REF_ROADSTOPS:
-			//return ((byte*)v - (byte*)_roadstops) / sizeof(_roadstops[0]) + 1;
-			return (RoadStop *)v - _roadstops + 1;
+		case REF_ROADSTOPS: return ((RoadStop *)v)->index + 1;
 
 		default:
 			NOT_REACHED();
@@ -957,10 +954,12 @@
 				error("Towns: failed loading savegame: too many towns");
 			return GetTown(r - 1);
 		}
+		case REF_ROADSTOPS: {
+			if (!AddBlockIfNeeded(&_roadstop_pool, r - 1))
+				error("RoadStop: failed loading savegame: too many RoadStops");
+			return GetRoadStop(r - 1);
+		}
 
-		case REF_ROADSTOPS:
-			//return (byte*)_roadstops    + (r - 1) * sizeof(_roadstops[0]);
-			return &_roadstops[r - 1];
 		case REF_VEHICLE_OLD: {
 			/* Old vehicles were saved differently: invalid vehicle was 0xFFFF,
 			    and the index was not - 1.. correct for this */
--- a/station.h	Fri Feb 04 14:45:32 2005 +0000
+++ b/station.h	Fri Feb 04 15:31:30 2005 +0000
@@ -125,9 +125,6 @@
 void ShowStationViewWindow(int station);
 void UpdateAllStationVirtCoord(void);
 
-VARDEF RoadStop _roadstops[NUM_ROAD_STOPS * 2];
-VARDEF uint _roadstops_size;
-
 VARDEF SortStruct *_station_sort;
 
 extern MemoryPool _station_pool;
@@ -151,6 +148,33 @@
 #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)
 
+
+/* Stuff for ROADSTOPS */
+
+extern MemoryPool _roadstop_pool;
+
+/**
+ * Get the pointer to the roadstop with index 'index'
+ */
+static inline RoadStop *GetRoadStop(uint index)
+{
+	return (RoadStop*)GetItemFromPool(&_roadstop_pool, index);
+}
+
+/**
+ * Get the current size of the RoadStoptPool
+ */
+static inline uint16 GetRoadStopPoolSize(void)
+{
+	return _roadstop_pool.total_items;
+}
+
+#define FOR_ALL_ROADSTOPS_FROM(rs, start) for (rs = GetRoadStop(start); rs != NULL; rs = (rs->index + 1 < GetRoadStopPoolSize()) ? GetRoadStop(rs->index + 1) : NULL)
+#define FOR_ALL_ROADSTOPS(rs) FOR_ALL_ROADSTOPS_FROM(rs, 0)
+
+/* End of stuff for ROADSTOPS */
+
+
 VARDEF bool _station_sort_dirty[MAX_PLAYERS];
 VARDEF bool _global_station_sort_dirty;
 
@@ -238,7 +262,7 @@
 inline int GetRoadStopType(TileIndex tile);
 uint GetNumRoadStops(const Station *st, RoadStopType type);
 RoadStop * GetPrimaryRoadStop(const Station *st, RoadStopType type);
-RoadStop * GetFirstFreeRoadStop( void );
+RoadStop * AllocateRoadStop( void );
 
 static inline bool IsTrainStationTile(uint tile) {
 	return IsTileType(tile, MP_STATION) && IS_BYTE_INSIDE(_map5[tile], 0, 8);
--- a/station_cmd.c	Fri Feb 04 14:45:32 2005 +0000
+++ b/station_cmd.c	Fri Feb 04 15:31:30 2005 +0000
@@ -22,6 +22,10 @@
 	/* Max stations: 64000 (64 * 1000) */
 	STATION_POOL_BLOCK_SIZE_BITS = 6,       /* In bits, so (1 << 6) == 64 */
 	STATION_POOL_MAX_BLOCKS      = 1000,
+
+	/* Max roadstops: 64000 (32 * 2000) */
+	ROADSTOP_POOL_BLOCK_SIZE_BITS = 5,       /* In bits, so (1 << 5) == 32 */
+	ROADSTOP_POOL_MAX_BLOCKS      = 2000,
 };
 
 /**
@@ -35,8 +39,20 @@
 		st->index = start_item++;
 }
 
-/* Initialize the station-pool */
+/**
+ * Called if a new block is added to the roadstop-pool
+ */
+static void RoadStopPoolNewBlock(uint start_item)
+{
+	RoadStop *rs;
+
+	FOR_ALL_ROADSTOPS_FROM(rs, start_item)
+		rs->index = start_item++;
+}
+
+/* Initialize the station-pool and roadstop-pool */
 MemoryPool _station_pool = { "Stations", STATION_POOL_MAX_BLOCKS, STATION_POOL_BLOCK_SIZE_BITS, sizeof(Station), &StationPoolNewBlock, 0, 0, NULL };
+MemoryPool _roadstop_pool = { "RoadStop", ROADSTOP_POOL_MAX_BLOCKS, ROADSTOP_POOL_BLOCK_SIZE_BITS, sizeof(RoadStop), &RoadStopPoolNewBlock, 0, 0, NULL };
 
 
 // FIXME -- need to be embedded into Airport variable. Is dynamically
@@ -110,18 +126,25 @@
 	return num;
 }
 
-RoadStop * GetFirstFreeRoadStop( void )
+RoadStop *AllocateRoadStop( void )
 {
-	RoadStop *rs = _roadstops;
-	int i = 0;
-
-	for ( i = 0; i < NUM_ROAD_STOPS; i++, rs++) {
+	RoadStop *rs;
+
+	FOR_ALL_ROADSTOPS(rs) {
 		if (!rs->used) {
-			rs->index = i;
+			uint index = rs->index;
+
+			memset(rs, 0, sizeof(RoadStop));
+			rs->index = index;
+
 			return rs;
 		}
 	}
 
+	/* Check if we can add a block to the pool */
+	if (AddBlockToPool(&_roadstop_pool))
+		return AllocateRoadStop();
+
 	return NULL;
 }
 
@@ -1448,7 +1471,7 @@
 	}
 
 	//give us a road stop in the list, and check if something went wrong
-	road_stop = GetFirstFreeRoadStop();
+	road_stop = AllocateRoadStop();
 	if (road_stop == NULL)
 		return_cmd_error( (type) ? STR_3008B_TOO_MANY_TRUCK_STOPS : STR_3008A_TOO_MANY_BUS_STOPS);
 
@@ -2908,7 +2931,9 @@
 	CleanPool(&_station_pool);
 	AddBlockToPool(&_station_pool);
 
-	memset(_roadstops, 0, sizeof(_roadstops));
+	/* Clean the roadstop pool and create 1 block in it */
+	CleanPool(&_roadstop_pool);
+	AddBlockToPool(&_roadstop_pool);
 
 	_station_tick_ctr = 0;
 
@@ -2946,7 +2971,7 @@
 	SLE_REF(RoadStop,next,         REF_ROADSTOPS),
 	SLE_REF(RoadStop,prev,         REF_ROADSTOPS),
 
- SLE_ARR(RoadStop,slot,         SLE_UINT16, NUM_SLOTS),
+	SLE_ARR(RoadStop,slot,         SLE_UINT16, NUM_SLOTS),
 
 	SLE_END()
 };
@@ -3067,27 +3092,19 @@
 
 		if (_sl.full_version < 0x600) {
 			/* Convert old bus and truck tile to new-ones */
-			RoadStop **currstop;
-			RoadStop *prev = NULL;
-			RoadStop *road_stop;
-
 			if (st->bus_tile_obsolete != 0) {
-				road_stop = GetFirstFreeRoadStop();
-				if (road_stop == NULL)
+				st->bus_stops = AllocateRoadStop();
+				if (st->bus_stops == NULL)
 					error("Station: too many busstations in savegame");
 
-				FindRoadStationSpot(RS_BUS, st, &currstop, &prev);
-				*currstop = road_stop;
-				InitializeRoadStop(road_stop, prev, st->bus_tile_obsolete, st->index);
+				InitializeRoadStop(st->bus_stops, NULL, st->bus_tile_obsolete, st->index);
 			}
 			if (st->lorry_tile_obsolete != 0) {
-				road_stop = GetFirstFreeRoadStop();
-				if (road_stop == NULL)
+				st->truck_stops = AllocateRoadStop();
+				if (st->truck_stops == NULL)
 					error("Station: too many truckstations in savegame");
 
-				FindRoadStationSpot(RS_TRUCK, st, &currstop, &prev);
-				*currstop = road_stop;
-				InitializeRoadStop(road_stop, prev, st->lorry_tile_obsolete, st->index);
+				InitializeRoadStop(st->truck_stops, NULL, st->lorry_tile_obsolete, st->index);
 			}
 		}
 	}
@@ -3100,12 +3117,12 @@
 
 static void Save_ROADSTOP( void )
 {
-	uint i;
-
-	for (i = 0; i < lengthof(_roadstops); i++) {
-		if (_roadstops[i].used) {
-			SlSetArrayIndex(i);
-			SlObject(&_roadstops[i], _roadstop_desc);
+	RoadStop *rs;
+
+	FOR_ALL_ROADSTOPS(rs) {
+		if (rs->used) {
+			SlSetArrayIndex(rs->index);
+			SlObject(rs, _roadstop_desc);
 		}
 	}
 }
@@ -3114,8 +3131,15 @@
 {
 	int index;
 
-	while ((index = SlIterateArray()) != -1)
-		SlObject(&_roadstops[index], _roadstop_desc);
+	while ((index = SlIterateArray()) != -1) {
+		RoadStop *rs;
+
+		if (!AddBlockIfNeeded(&_roadstop_pool, index))
+			error("RoadStop: failed loading savegame: too many RoadStops");
+
+		rs = GetRoadStop(index);
+		SlObject(rs, _roadstop_desc);
+	}
 }
 
 const ChunkHandler _station_chunk_handlers[] = {
--- a/ttd.c	Fri Feb 04 14:45:32 2005 +0000
+++ b/ttd.c	Fri Feb 04 15:31:30 2005 +0000
@@ -495,7 +495,6 @@
 static void InitializeDynamicVariables(void)
 {
 	/* Dynamic stuff needs to be initialized somewhere... */
-	_roadstops_size = lengthof(_roadstops);
 	_orders_size    = lengthof(_orders);
 
 	_station_sort  = NULL;