diff options
-rw-r--r-- | oldloader.c | 3 | ||||
-rw-r--r-- | saveload.c | 6 | ||||
-rw-r--r-- | station.h | 22 | ||||
-rw-r--r-- | station_cmd.c | 74 | ||||
-rw-r--r-- | station_gui.c | 4 | ||||
-rw-r--r-- | ttd.c | 2 |
6 files changed, 72 insertions, 39 deletions
diff --git a/oldloader.c b/oldloader.c index 6de0c483e..4ad72a72f 100644 --- a/oldloader.c +++ b/oldloader.c @@ -713,6 +713,9 @@ static void FixStation(OldStation *o, int num) 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; diff --git a/saveload.c b/saveload.c index 8db82bf2c..174d65703 100644 --- a/saveload.c +++ b/saveload.c @@ -943,7 +943,11 @@ static void *IntToReference(uint r, uint t) 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"); @@ -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 ShowStationViewWindow(int station); 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); +} + +/** + * Get the current size of the StationPool + */ +static inline uint16 GetStationPoolSize(void) +{ + return _station_pool.total_items; } -#define FOR_ALL_STATIONS(st) for(st = _stations; st != &_stations[_stations_size]; st++) +#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; diff --git a/station_cmd.c b/station_cmd.c index cbce2014b..edcefccb4 100644 --- a/station_cmd.c +++ b/station_cmd.c @@ -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 @@ const byte _airport_size_y[5] = {3, 6, 1, 6, 7 }; 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 bool CheckStationSpreadOut(Station *st, uint tile, int w, int h) 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; - } + /* Check if we can add a block to the pool */ + if (AddBlockToPool(&_station_pool)) + return AllocateStation(); - i = a_free->index; - memset(a_free, 0, sizeof(Station)); - a_free->index = i; - return a_free; + _error_message = STR_3008_TOO_MANY_STATIONS_LOADING; + return NULL; } @@ -2552,14 +2566,14 @@ static void StationHandleSmallTick(Station *st) 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 @@ static int32 ClearTile_Station(uint tile, byte flags) { 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 @@ static void Load_STNS(void) { 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 @@ static void Load_STNS(void) /* 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; } diff --git a/station_gui.c b/station_gui.c index d7316d429..fe57f4dbe 100644 --- a/station_gui.c +++ b/station_gui.c @@ -84,7 +84,7 @@ static void GlobalSortStationList(void) *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 @@ static void DrawStationViewWindow(Window *w) byte *b; - station_id = (byte)w->window_number; + station_id = (uint16)w->window_number; st = GetStation(w->window_number); @@ -495,7 +495,6 @@ static void ParseResolution(int res[2], char *s) 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 @@ static void UnInitializeDynamicVariables(void) /* Dynamic stuff needs to be free'd somewhere... */ CleanPool(&_town_pool); CleanPool(&_industry_pool); + CleanPool(&_station_pool); free(_station_sort); free(_vehicle_sort); |