summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--oldloader.c3
-rw-r--r--order.h28
-rw-r--r--order_cmd.c52
-rw-r--r--order_gui.c9
-rw-r--r--saveload.c8
-rw-r--r--station_cmd.c2
-rw-r--r--ttd.c3
7 files changed, 74 insertions, 31 deletions
diff --git a/oldloader.c b/oldloader.c
index 08165476f..b46fd3c90 100644
--- a/oldloader.c
+++ b/oldloader.c
@@ -803,6 +803,9 @@ static void FixOrder(uint16 *o, int num)
int i;
for (i = 0; i < num; ++i) {
+ if (!AddBlockIfNeeded(&_order_pool, i))
+ error("Orders: failed loading savegame: too many orders");
+
order = GetOrder(i);
AssignOrder(order, UnpackOldOrder(*o));
/* Recover the next list */
diff --git a/order.h b/order.h
index 430e3bb8b..840e1ec22 100644
--- a/order.h
+++ b/order.h
@@ -1,6 +1,8 @@
#ifndef ORDER_H
#define ORDER_H
+#include "pool.h"
+
/* Order types */
enum {
OT_NOTHING = 0,
@@ -64,17 +66,27 @@ typedef struct {
VARDEF TileIndex _backup_orders_tile;
VARDEF BackuppedOrders _backup_orders_data[1];
-VARDEF Order _orders[5000];
-VARDEF uint32 _orders_size;
+extern MemoryPool _order_pool;
+/**
+ * Get the pointer to the order with index 'index'
+ */
static inline Order *GetOrder(uint index)
{
- assert(index < _orders_size);
- return &_orders[index];
+ return (Order*)GetItemFromPool(&_order_pool, index);
+}
+
+/**
+ * Get the current size of the OrderPool
+ */
+static inline uint16 GetOrderPoolSize(void)
+{
+ return _order_pool.total_items;
}
-#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)
+#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)
@@ -82,6 +94,10 @@ static inline bool HasOrderPoolFree(uint amount)
{
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)
if (order->type == OT_NOTHING)
if (--amount == 0)
diff --git a/order_cmd.c b/order_cmd.c
index 71ab2c068..d28f3a6ff 100644
--- a/order_cmd.c
+++ b/order_cmd.c
@@ -8,6 +8,26 @@
#include "news.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)
@@ -87,13 +107,19 @@ static Order *AllocateOrder(void)
FOR_ALL_ORDERS(order) {
if (order->type == OT_NOTHING) {
uint index = order->index;
+
memset(order, 0, sizeof(Order));
order->index = index;
order->next = NULL;
+
return order;
}
}
+ /* Check if we can add a block to the pool */
+ if (AddBlockToPool(&_order_pool))
+ return AllocateOrder();
+
return NULL;
}
@@ -906,14 +932,8 @@ bool CheckForValidOrders(Vehicle *v)
void InitializeOrders(void)
{
- Order *order;
- int i;
-
- memset(&_orders, 0, sizeof(_orders[0]) * _orders_size);
-
- i = 0;
- FOR_ALL_ORDERS(order)
- order->index = i++;
+ CleanPool(&_order_pool);
+ AddBlockToPool(&_order_pool);
_backup_orders_tile = 0;
}
@@ -955,22 +975,28 @@ static void Load_ORDR(void)
uint16 orders[5000];
len /= sizeof(uint16);
- assert (len <= _orders_size);
+ assert (len <= lengthof(orders));
SlArray(orders, len, SLE_UINT16);
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]));
}
} else if (_sl.full_version <= 0x501) {
uint32 orders[5000];
len /= sizeof(uint32);
- assert (len <= _orders_size);
+ assert (len <= lengthof(orders));
SlArray(orders, len, SLE_UINT32);
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]));
}
}
@@ -987,8 +1013,12 @@ static void Load_ORDR(void)
int index;
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);
}
}
diff --git a/order_gui.c b/order_gui.c
index 7cbd0089c..298b2ba67 100644
--- a/order_gui.c
+++ b/order_gui.c
@@ -167,15 +167,6 @@ static void *FindVehicleCallb(Vehicle *v, FindVehS *f)
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)
{
Order order;
diff --git a/saveload.c b/saveload.c
index d5fabd7cc..f4902c5f4 100644
--- a/saveload.c
+++ b/saveload.c
@@ -941,7 +941,11 @@ static void *IntToReference(uint r, uint t)
return NULL;
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: {
if (!AddBlockIfNeeded(&_vehicle_pool, r - 1))
error("Vehicles: failed loading savegame: too many vehicles");
@@ -959,7 +963,7 @@ static void *IntToReference(uint r, uint t)
}
case REF_ROADSTOPS: {
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);
}
diff --git a/station_cmd.c b/station_cmd.c
index 61c09e2c0..67457728d 100644
--- a/station_cmd.c
+++ b/station_cmd.c
@@ -3138,7 +3138,7 @@ static void Load_ROADSTOP( void )
RoadStop *rs;
if (!AddBlockIfNeeded(&_roadstop_pool, index))
- error("RoadStop: failed loading savegame: too many RoadStops");
+ error("RoadStops: failed loading savegame: too many RoadStops");
rs = GetRoadStop(index);
SlObject(rs, _roadstop_desc);
diff --git a/ttd.c b/ttd.c
index 83c3e58cb..f4d98a5b1 100644
--- a/ttd.c
+++ b/ttd.c
@@ -440,8 +440,6 @@ static void ParseResolution(int res[2], char *s)
static void InitializeDynamicVariables(void)
{
/* Dynamic stuff needs to be initialized somewhere... */
- _orders_size = lengthof(_orders);
-
_station_sort = NULL;
_vehicle_sort = NULL;
_town_sort = NULL;
@@ -456,6 +454,7 @@ static void UnInitializeDynamicVariables(void)
CleanPool(&_station_pool);
CleanPool(&_vehicle_pool);
CleanPool(&_sign_pool);
+ CleanPool(&_order_pool);
free(_station_sort);
free(_vehicle_sort);