diff options
-rw-r--r-- | oldloader.c | 28 | ||||
-rw-r--r-- | saveload.c | 13 | ||||
-rw-r--r-- | station.h | 32 | ||||
-rw-r--r-- | station_cmd.c | 84 | ||||
-rw-r--r-- | ttd.c | 1 |
5 files changed, 110 insertions, 48 deletions
diff --git a/oldloader.c b/oldloader.c index 8647a0eeb..24db721cc 100644 --- a/oldloader.c +++ b/oldloader.c @@ -720,16 +720,32 @@ static void FixStation(OldStation *o, int num) 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; diff --git a/saveload.c b/saveload.c index 71596a883..ef621afcd 100644 --- a/saveload.c +++ b/saveload.c @@ -917,10 +917,7 @@ static uint ReferenceToInt(void *v, uint t) 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 @@ static void *IntToReference(uint r, uint t) 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 */ @@ -125,9 +125,6 @@ TileIndex GetStationTileForVehicle(const Vehicle *v, const Station *st); 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 @@ static inline uint16 GetStationPoolSize(void) #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 @@ RoadStop * GetRoadStopByTile(TileIndex tile, RoadStopType type); 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); diff --git a/station_cmd.c b/station_cmd.c index edcefccb4..a29400a67 100644 --- a/station_cmd.c +++ b/station_cmd.c @@ -22,6 +22,10 @@ enum { /* 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 @@ static void StationPoolNewBlock(uint start_item) 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 @@ uint GetNumRoadStops(const Station *st, RoadStopType type) return num; } -RoadStop * GetFirstFreeRoadStop( void ) +RoadStop *AllocateRoadStop( void ) { - RoadStop *rs = _roadstops; - int i = 0; + RoadStop *rs; - for ( i = 0; i < NUM_ROAD_STOPS; i++, 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 @@ int32 CmdBuildRoadStop(int x, int y, uint32 flags, uint32 direction, uint32 type } //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 @@ void InitializeStations(void) 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 @@ static const byte _roadstop_desc[] = { 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 @@ static void Load_STNS(void) 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 Load_STNS(void) static void Save_ROADSTOP( void ) { - uint i; + RoadStop *rs; - for (i = 0; i < lengthof(_roadstops); i++) { - if (_roadstops[i].used) { - SlSetArrayIndex(i); - SlObject(&_roadstops[i], _roadstop_desc); + FOR_ALL_ROADSTOPS(rs) { + if (rs->used) { + SlSetArrayIndex(rs->index); + SlObject(rs, _roadstop_desc); } } } @@ -3114,8 +3131,15 @@ static void Load_ROADSTOP( void ) { 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[] = { @@ -495,7 +495,6 @@ static void ParseResolution(int res[2], char *s) static void InitializeDynamicVariables(void) { /* Dynamic stuff needs to be initialized somewhere... */ - _roadstops_size = lengthof(_roadstops); _orders_size = lengthof(_orders); _station_sort = NULL; |