mirror of https://github.com/OpenTTD/OpenTTD
(svn r1776) -Add: Dynamic stations. You can now have up to 64k of stations
parent
f1d4a85f59
commit
1938a73c90
|
@ -713,6 +713,9 @@ static void FixStation(OldStation *o, int num)
|
||||||
if (o->xy == 0)
|
if (o->xy == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (!AddBlockIfNeeded(&_station_pool, i))
|
||||||
|
error("Stations: failed loading savegame: too many stations");
|
||||||
|
|
||||||
s = GetStation(i);
|
s = GetStation(i);
|
||||||
|
|
||||||
s->xy = o->xy;
|
s->xy = o->xy;
|
||||||
|
|
|
@ -943,7 +943,11 @@ static void *IntToReference(uint r, uint t)
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case REF_ORDER: return GetOrder(r - 1);
|
case REF_ORDER: return GetOrder(r - 1);
|
||||||
case REF_VEHICLE: return GetVehicle(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: {
|
case REF_TOWN: {
|
||||||
if (!AddBlockIfNeeded(&_town_pool, r - 1))
|
if (!AddBlockIfNeeded(&_town_pool, r - 1))
|
||||||
error("Towns: failed loading savegame: too many towns");
|
error("Towns: failed loading savegame: too many towns");
|
||||||
|
|
22
station.h
22
station.h
|
@ -1,6 +1,7 @@
|
||||||
#ifndef STATION_H
|
#ifndef STATION_H
|
||||||
#define STATION_H
|
#define STATION_H
|
||||||
|
|
||||||
|
#include "pool.h"
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "tile.h"
|
#include "tile.h"
|
||||||
#include "vehicle.h"
|
#include "vehicle.h"
|
||||||
|
@ -125,19 +126,30 @@ void ShowStationViewWindow(int station);
|
||||||
void UpdateAllStationVirtCoord(void);
|
void UpdateAllStationVirtCoord(void);
|
||||||
|
|
||||||
VARDEF RoadStop _roadstops[NUM_ROAD_STOPS * 2];
|
VARDEF RoadStop _roadstops[NUM_ROAD_STOPS * 2];
|
||||||
VARDEF Station _stations[250];
|
|
||||||
VARDEF uint _roadstops_size;
|
VARDEF uint _roadstops_size;
|
||||||
VARDEF uint _stations_size;
|
|
||||||
|
|
||||||
VARDEF SortStruct *_station_sort;
|
VARDEF SortStruct *_station_sort;
|
||||||
|
|
||||||
|
extern MemoryPool _station_pool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the pointer to the station with index 'index'
|
||||||
|
*/
|
||||||
static inline Station *GetStation(uint index)
|
static inline Station *GetStation(uint index)
|
||||||
{
|
{
|
||||||
assert(index < _stations_size);
|
return (Station*)GetItemFromPool(&_station_pool, index);
|
||||||
return &_stations[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 _station_sort_dirty[MAX_PLAYERS];
|
||||||
VARDEF bool _global_station_sort_dirty;
|
VARDEF bool _global_station_sort_dirty;
|
||||||
|
|
|
@ -18,6 +18,27 @@
|
||||||
#include "sprite.h"
|
#include "sprite.h"
|
||||||
#include "npf.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
|
// FIXME -- need to be embedded into Airport variable. Is dynamically
|
||||||
// deducteable from graphics-tile array, so will not be needed
|
// deducteable from graphics-tile array, so will not be needed
|
||||||
const byte _airport_size_x[5] = {4, 6, 1, 6, 7 };
|
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);
|
void ShowAircraftDepotWindow(uint tile);
|
||||||
extern void UpdateAirplanesOnNewStation(Station *st);
|
extern void UpdateAirplanesOnNewStation(Station *st);
|
||||||
|
|
||||||
enum {
|
|
||||||
STATIONS_MIN_FREE_FOR_AI = 30
|
|
||||||
};
|
|
||||||
|
|
||||||
static void MarkStationDirty(Station *st)
|
static void MarkStationDirty(Station *st)
|
||||||
{
|
{
|
||||||
if (st->sign.width_1 != 0) {
|
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)
|
static Station *AllocateStation(void)
|
||||||
{
|
{
|
||||||
Station *st, *a_free = NULL;
|
Station *st = NULL;
|
||||||
int num_free = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
FOR_ALL_STATIONS(st) {
|
FOR_ALL_STATIONS(st) {
|
||||||
if (st->xy == 0) {
|
if (st->xy == 0) {
|
||||||
num_free++;
|
uint index = st->index;
|
||||||
if (a_free == NULL)
|
|
||||||
a_free = st;
|
memset(st, 0, sizeof(Station));
|
||||||
|
st->index = index;
|
||||||
|
|
||||||
|
return st;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a_free == NULL ||
|
/* Check if we can add a block to the pool */
|
||||||
(num_free < STATIONS_MIN_FREE_FOR_AI && IS_HUMAN_PLAYER(_current_player))) {
|
if (AddBlockToPool(&_station_pool))
|
||||||
_error_message = STR_3008_TOO_MANY_STATIONS_LOADING;
|
return AllocateStation();
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = a_free->index;
|
_error_message = STR_3008_TOO_MANY_STATIONS_LOADING;
|
||||||
memset(a_free, 0, sizeof(Station));
|
return NULL;
|
||||||
a_free->index = i;
|
|
||||||
return a_free;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2552,14 +2566,14 @@ static void StationHandleSmallTick(Station *st)
|
||||||
|
|
||||||
void OnTick_Station(void)
|
void OnTick_Station(void)
|
||||||
{
|
{
|
||||||
int i;
|
uint i;
|
||||||
Station *st;
|
Station *st;
|
||||||
|
|
||||||
if (_game_mode == GM_EDITOR)
|
if (_game_mode == GM_EDITOR)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
i = _station_tick_ctr;
|
i = _station_tick_ctr;
|
||||||
if (++_station_tick_ctr == _stations_size)
|
if (++_station_tick_ctr == GetStationPoolSize())
|
||||||
_station_tick_ctr = 0;
|
_station_tick_ctr = 0;
|
||||||
|
|
||||||
st = GetStation(i);
|
st = GetStation(i);
|
||||||
|
@ -2890,15 +2904,11 @@ static int32 ClearTile_Station(uint tile, byte flags) {
|
||||||
|
|
||||||
void InitializeStations(void)
|
void InitializeStations(void)
|
||||||
{
|
{
|
||||||
int i;
|
/* Clean the station pool and create 1 block in it */
|
||||||
Station *s;
|
CleanPool(&_station_pool);
|
||||||
|
AddBlockToPool(&_station_pool);
|
||||||
|
|
||||||
memset(_roadstops, 0, sizeof(_roadstops));
|
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;
|
_station_tick_ctr = 0;
|
||||||
|
|
||||||
|
@ -3038,8 +3048,12 @@ static void Load_STNS(void)
|
||||||
{
|
{
|
||||||
int index;
|
int index;
|
||||||
while ((index = SlIterateArray()) != -1) {
|
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);
|
SaveLoad_STNS(st);
|
||||||
|
|
||||||
// this means it's an oldstyle savegame without support for nonuniform stations
|
// 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
|
/* This is to ensure all pointers are within the limits of
|
||||||
_stations_size */
|
_stations_size */
|
||||||
if (_station_tick_ctr > _stations_size)
|
if (_station_tick_ctr > GetStationPoolSize())
|
||||||
_station_tick_ctr = 0;
|
_station_tick_ctr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -84,7 +84,7 @@ static void GlobalSortStationList(void)
|
||||||
*i = 0;
|
*i = 0;
|
||||||
|
|
||||||
/* Create array for sorting */
|
/* 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)
|
if (_station_sort == NULL)
|
||||||
error("Could not allocate memory for the station-sorting-list");
|
error("Could not allocate memory for the station-sorting-list");
|
||||||
|
|
||||||
|
@ -318,7 +318,7 @@ static void DrawStationViewWindow(Window *w)
|
||||||
byte *b;
|
byte *b;
|
||||||
|
|
||||||
|
|
||||||
station_id = (byte)w->window_number;
|
station_id = (uint16)w->window_number;
|
||||||
|
|
||||||
st = GetStation(w->window_number);
|
st = GetStation(w->window_number);
|
||||||
|
|
||||||
|
|
2
ttd.c
2
ttd.c
|
@ -495,7 +495,6 @@ static void ParseResolution(int res[2], char *s)
|
||||||
static void InitializeDynamicVariables(void)
|
static void InitializeDynamicVariables(void)
|
||||||
{
|
{
|
||||||
/* Dynamic stuff needs to be initialized somewhere... */
|
/* Dynamic stuff needs to be initialized somewhere... */
|
||||||
_stations_size = lengthof(_stations);
|
|
||||||
_roadstops_size = lengthof(_roadstops);
|
_roadstops_size = lengthof(_roadstops);
|
||||||
_vehicles_size = lengthof(_vehicles);
|
_vehicles_size = lengthof(_vehicles);
|
||||||
_sign_size = lengthof(_sign_list);
|
_sign_size = lengthof(_sign_list);
|
||||||
|
@ -512,6 +511,7 @@ static void UnInitializeDynamicVariables(void)
|
||||||
/* Dynamic stuff needs to be free'd somewhere... */
|
/* Dynamic stuff needs to be free'd somewhere... */
|
||||||
CleanPool(&_town_pool);
|
CleanPool(&_town_pool);
|
||||||
CleanPool(&_industry_pool);
|
CleanPool(&_industry_pool);
|
||||||
|
CleanPool(&_station_pool);
|
||||||
|
|
||||||
free(_station_sort);
|
free(_station_sort);
|
||||||
free(_vehicle_sort);
|
free(_vehicle_sort);
|
||||||
|
|
Loading…
Reference in New Issue