mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r1818) -Add: Dynamic orders (up to 64k orders)
This commit is contained in:
parent
e9c93f9c0c
commit
020c1e9b6c
|
@ -803,6 +803,9 @@ static void FixOrder(uint16 *o, int num)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < num; ++i) {
|
for (i = 0; i < num; ++i) {
|
||||||
|
if (!AddBlockIfNeeded(&_order_pool, i))
|
||||||
|
error("Orders: failed loading savegame: too many orders");
|
||||||
|
|
||||||
order = GetOrder(i);
|
order = GetOrder(i);
|
||||||
AssignOrder(order, UnpackOldOrder(*o));
|
AssignOrder(order, UnpackOldOrder(*o));
|
||||||
/* Recover the next list */
|
/* Recover the next list */
|
||||||
|
|
28
order.h
28
order.h
|
@ -1,6 +1,8 @@
|
||||||
#ifndef ORDER_H
|
#ifndef ORDER_H
|
||||||
#define ORDER_H
|
#define ORDER_H
|
||||||
|
|
||||||
|
#include "pool.h"
|
||||||
|
|
||||||
/* Order types */
|
/* Order types */
|
||||||
enum {
|
enum {
|
||||||
OT_NOTHING = 0,
|
OT_NOTHING = 0,
|
||||||
|
@ -64,17 +66,27 @@ typedef struct {
|
||||||
VARDEF TileIndex _backup_orders_tile;
|
VARDEF TileIndex _backup_orders_tile;
|
||||||
VARDEF BackuppedOrders _backup_orders_data[1];
|
VARDEF BackuppedOrders _backup_orders_data[1];
|
||||||
|
|
||||||
VARDEF Order _orders[5000];
|
extern MemoryPool _order_pool;
|
||||||
VARDEF uint32 _orders_size;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the pointer to the order with index 'index'
|
||||||
|
*/
|
||||||
static inline Order *GetOrder(uint index)
|
static inline Order *GetOrder(uint index)
|
||||||
{
|
{
|
||||||
assert(index < _orders_size);
|
return (Order*)GetItemFromPool(&_order_pool, index);
|
||||||
return &_orders[index];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define FOR_ALL_ORDERS_FROM(o, from) for(o = GetOrder(from); o != &_orders[_orders_size]; o++)
|
/**
|
||||||
#define FOR_ALL_ORDERS(o) FOR_ALL_ORDERS_FROM(o, 0)
|
* Get the current size of the OrderPool
|
||||||
|
*/
|
||||||
|
static inline uint16 GetOrderPoolSize(void)
|
||||||
|
{
|
||||||
|
return _order_pool.total_items;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define FOR_ALL_ORDERS_FROM(order, start) for (order = GetOrder(start); order != NULL; order = (order->index + 1 < GetOrderPoolSize()) ? GetOrder(order->index + 1) : NULL)
|
||||||
|
#define FOR_ALL_ORDERS(order) FOR_ALL_ORDERS_FROM(order, 0)
|
||||||
|
|
||||||
|
|
||||||
#define FOR_VEHICLE_ORDERS(v, order) for (order = v->orders; order != NULL; order = order->next)
|
#define FOR_VEHICLE_ORDERS(v, order) for (order = v->orders; order != NULL; order = order->next)
|
||||||
|
|
||||||
|
@ -82,6 +94,10 @@ static inline bool HasOrderPoolFree(uint amount)
|
||||||
{
|
{
|
||||||
const Order *order;
|
const Order *order;
|
||||||
|
|
||||||
|
/* There is always room if not all blocks in the pool are reserved */
|
||||||
|
if (_order_pool.current_blocks < _order_pool.max_blocks)
|
||||||
|
return true;
|
||||||
|
|
||||||
FOR_ALL_ORDERS(order)
|
FOR_ALL_ORDERS(order)
|
||||||
if (order->type == OT_NOTHING)
|
if (order->type == OT_NOTHING)
|
||||||
if (--amount == 0)
|
if (--amount == 0)
|
||||||
|
|
52
order_cmd.c
52
order_cmd.c
|
@ -8,6 +8,26 @@
|
||||||
#include "news.h"
|
#include "news.h"
|
||||||
#include "saveload.h"
|
#include "saveload.h"
|
||||||
|
|
||||||
|
enum {
|
||||||
|
/* Max orders: 64000 (64 * 1000) */
|
||||||
|
ORDER_POOL_BLOCK_SIZE_BITS = 6, /* In bits, so (1 << 6) == 64 */
|
||||||
|
ORDER_POOL_MAX_BLOCKS = 1000,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called if a new block is added to the order-pool
|
||||||
|
*/
|
||||||
|
static void OrderPoolNewBlock(uint start_item)
|
||||||
|
{
|
||||||
|
Order *order;
|
||||||
|
|
||||||
|
FOR_ALL_ORDERS_FROM(order, start_item)
|
||||||
|
order->index = start_item++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Initialize the order-pool */
|
||||||
|
MemoryPool _order_pool = { "Orders", ORDER_POOL_MAX_BLOCKS, ORDER_POOL_BLOCK_SIZE_BITS, sizeof(Order), &OrderPoolNewBlock, 0, 0, NULL };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Unpacks a order from savegames made with TTD(Patch)
|
* Unpacks a order from savegames made with TTD(Patch)
|
||||||
|
@ -87,13 +107,19 @@ static Order *AllocateOrder(void)
|
||||||
FOR_ALL_ORDERS(order) {
|
FOR_ALL_ORDERS(order) {
|
||||||
if (order->type == OT_NOTHING) {
|
if (order->type == OT_NOTHING) {
|
||||||
uint index = order->index;
|
uint index = order->index;
|
||||||
|
|
||||||
memset(order, 0, sizeof(Order));
|
memset(order, 0, sizeof(Order));
|
||||||
order->index = index;
|
order->index = index;
|
||||||
order->next = NULL;
|
order->next = NULL;
|
||||||
|
|
||||||
return order;
|
return order;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if we can add a block to the pool */
|
||||||
|
if (AddBlockToPool(&_order_pool))
|
||||||
|
return AllocateOrder();
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -906,14 +932,8 @@ bool CheckForValidOrders(Vehicle *v)
|
||||||
|
|
||||||
void InitializeOrders(void)
|
void InitializeOrders(void)
|
||||||
{
|
{
|
||||||
Order *order;
|
CleanPool(&_order_pool);
|
||||||
int i;
|
AddBlockToPool(&_order_pool);
|
||||||
|
|
||||||
memset(&_orders, 0, sizeof(_orders[0]) * _orders_size);
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
FOR_ALL_ORDERS(order)
|
|
||||||
order->index = i++;
|
|
||||||
|
|
||||||
_backup_orders_tile = 0;
|
_backup_orders_tile = 0;
|
||||||
}
|
}
|
||||||
|
@ -955,22 +975,28 @@ static void Load_ORDR(void)
|
||||||
uint16 orders[5000];
|
uint16 orders[5000];
|
||||||
|
|
||||||
len /= sizeof(uint16);
|
len /= sizeof(uint16);
|
||||||
assert (len <= _orders_size);
|
assert (len <= lengthof(orders));
|
||||||
|
|
||||||
SlArray(orders, len, SLE_UINT16);
|
SlArray(orders, len, SLE_UINT16);
|
||||||
|
|
||||||
for (i = 0; i < len; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
|
if (!AddBlockIfNeeded(&_order_pool, i))
|
||||||
|
error("Orders: failed loading savegame: too many orders");
|
||||||
|
|
||||||
AssignOrder(GetOrder(i), UnpackVersion4Order(orders[i]));
|
AssignOrder(GetOrder(i), UnpackVersion4Order(orders[i]));
|
||||||
}
|
}
|
||||||
} else if (_sl.full_version <= 0x501) {
|
} else if (_sl.full_version <= 0x501) {
|
||||||
uint32 orders[5000];
|
uint32 orders[5000];
|
||||||
|
|
||||||
len /= sizeof(uint32);
|
len /= sizeof(uint32);
|
||||||
assert (len <= _orders_size);
|
assert (len <= lengthof(orders));
|
||||||
|
|
||||||
SlArray(orders, len, SLE_UINT32);
|
SlArray(orders, len, SLE_UINT32);
|
||||||
|
|
||||||
for (i = 0; i < len; ++i) {
|
for (i = 0; i < len; ++i) {
|
||||||
|
if (!AddBlockIfNeeded(&_order_pool, i))
|
||||||
|
error("Orders: failed loading savegame: too many orders");
|
||||||
|
|
||||||
AssignOrder(GetOrder(i), UnpackOrder(orders[i]));
|
AssignOrder(GetOrder(i), UnpackOrder(orders[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -987,8 +1013,12 @@ static void Load_ORDR(void)
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
while ((index = SlIterateArray()) != -1) {
|
while ((index = SlIterateArray()) != -1) {
|
||||||
Order *order = GetOrder(index);
|
Order *order;
|
||||||
|
|
||||||
|
if (!AddBlockIfNeeded(&_order_pool, index))
|
||||||
|
error("Orders: failed loading savegame: too many orders");
|
||||||
|
|
||||||
|
order = GetOrder(index);
|
||||||
SlObject(order, _order_desc);
|
SlObject(order, _order_desc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,15 +167,6 @@ static void *FindVehicleCallb(Vehicle *v, FindVehS *f)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Vehicle *GetVehicleOnTile(TileIndex tile, byte owner)
|
|
||||||
{
|
|
||||||
FindVehS fs;
|
|
||||||
fs.tile = tile;
|
|
||||||
fs.owner = owner;
|
|
||||||
fs.type = 0;
|
|
||||||
return VehicleFromPos(tile, &fs, (VehicleFromPosProc*)FindVehicleCallb);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Order GetOrderCmdFromTile(Vehicle *v, uint tile)
|
static Order GetOrderCmdFromTile(Vehicle *v, uint tile)
|
||||||
{
|
{
|
||||||
Order order;
|
Order order;
|
||||||
|
|
|
@ -941,7 +941,11 @@ static void *IntToReference(uint r, uint t)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case REF_ORDER: return GetOrder(r - 1);
|
case REF_ORDER: {
|
||||||
|
if (!AddBlockIfNeeded(&_order_pool, r - 1))
|
||||||
|
error("Orders: failed loading savegame: too many orders");
|
||||||
|
return GetOrder(r - 1);
|
||||||
|
}
|
||||||
case REF_VEHICLE: {
|
case REF_VEHICLE: {
|
||||||
if (!AddBlockIfNeeded(&_vehicle_pool, r - 1))
|
if (!AddBlockIfNeeded(&_vehicle_pool, r - 1))
|
||||||
error("Vehicles: failed loading savegame: too many vehicles");
|
error("Vehicles: failed loading savegame: too many vehicles");
|
||||||
|
@ -959,7 +963,7 @@ static void *IntToReference(uint r, uint t)
|
||||||
}
|
}
|
||||||
case REF_ROADSTOPS: {
|
case REF_ROADSTOPS: {
|
||||||
if (!AddBlockIfNeeded(&_roadstop_pool, r - 1))
|
if (!AddBlockIfNeeded(&_roadstop_pool, r - 1))
|
||||||
error("RoadStop: failed loading savegame: too many RoadStops");
|
error("RoadStops: failed loading savegame: too many RoadStops");
|
||||||
return GetRoadStop(r - 1);
|
return GetRoadStop(r - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3138,7 +3138,7 @@ static void Load_ROADSTOP( void )
|
||||||
RoadStop *rs;
|
RoadStop *rs;
|
||||||
|
|
||||||
if (!AddBlockIfNeeded(&_roadstop_pool, index))
|
if (!AddBlockIfNeeded(&_roadstop_pool, index))
|
||||||
error("RoadStop: failed loading savegame: too many RoadStops");
|
error("RoadStops: failed loading savegame: too many RoadStops");
|
||||||
|
|
||||||
rs = GetRoadStop(index);
|
rs = GetRoadStop(index);
|
||||||
SlObject(rs, _roadstop_desc);
|
SlObject(rs, _roadstop_desc);
|
||||||
|
|
3
ttd.c
3
ttd.c
|
@ -440,8 +440,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... */
|
||||||
_orders_size = lengthof(_orders);
|
|
||||||
|
|
||||||
_station_sort = NULL;
|
_station_sort = NULL;
|
||||||
_vehicle_sort = NULL;
|
_vehicle_sort = NULL;
|
||||||
_town_sort = NULL;
|
_town_sort = NULL;
|
||||||
|
@ -456,6 +454,7 @@ static void UnInitializeDynamicVariables(void)
|
||||||
CleanPool(&_station_pool);
|
CleanPool(&_station_pool);
|
||||||
CleanPool(&_vehicle_pool);
|
CleanPool(&_vehicle_pool);
|
||||||
CleanPool(&_sign_pool);
|
CleanPool(&_sign_pool);
|
||||||
|
CleanPool(&_order_pool);
|
||||||
|
|
||||||
free(_station_sort);
|
free(_station_sort);
|
||||||
free(_vehicle_sort);
|
free(_vehicle_sort);
|
||||||
|
|
Loading…
Reference in New Issue