mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-09 23:50:25 +00:00
(svn r11943) -Codechange: add and use a simple structure to support small stacks by allocating it on the heap or pushing a few kB of data onto the stack when there is a large stack.
This commit is contained in:
parent
30bac58bde
commit
59ec5e62ce
@ -81,4 +81,35 @@ template <typename T> FORCEINLINE T* ReallocT(T *t_ptr, size_t num_elements)
|
||||
return t_ptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* A small 'wrapper' for allocations that can be done on most OSes on the
|
||||
* stack, but are just too large to fit in the stack on devices with a small
|
||||
* stack such as the NDS.
|
||||
* So when it is possible a stack allocation is made, otherwise a heap
|
||||
* allocation is made and this is freed once the struct goes out of scope.
|
||||
* @param T the type to make the allocation for
|
||||
* @param length the amount of items to allocate
|
||||
*/
|
||||
template <typename T, size_t length>
|
||||
struct SmallStackSafeStackAlloc {
|
||||
#if !defined(__NDS__)
|
||||
/** Storing the data on the stack */
|
||||
T data[length];
|
||||
#else
|
||||
/** Storing it on the heap */
|
||||
T *data;
|
||||
|
||||
/** Allocating the memory */
|
||||
SmallStackSafeStackAlloc() : data(MallocT<T>(length)) {}
|
||||
/** And freeing when it goes out of scope */
|
||||
~SmallStackSafeStackAlloc() { free(data); }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Gets a pointer to the data stored in this wrapper.
|
||||
* @return the pointer.
|
||||
*/
|
||||
operator T* () { return data; }
|
||||
};
|
||||
|
||||
#endif /* ALLOC_FUNC_HPP */
|
||||
|
226
src/misc.cpp
226
src/misc.cpp
@ -25,6 +25,7 @@
|
||||
#include "texteff.hpp"
|
||||
#include "string_func.h"
|
||||
#include "gfx_func.h"
|
||||
#include "core/alloc_func.hpp"
|
||||
|
||||
#include "table/strings.h"
|
||||
#include "table/sprites.h"
|
||||
@ -260,196 +261,161 @@ static void Load_MAPS()
|
||||
AllocateMap(_map_dim_x, _map_dim_y);
|
||||
}
|
||||
|
||||
enum {
|
||||
MAP_SL_BUF_SIZE = 4096
|
||||
};
|
||||
|
||||
static void Load_MAPT()
|
||||
{
|
||||
uint size = MapSize();
|
||||
uint i;
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
for (i = 0; i != size;) {
|
||||
byte buf[4096];
|
||||
uint j;
|
||||
|
||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
||||
for (j = 0; j != lengthof(buf); j++) _m[i++].type_height = buf[j];
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].type_height = buf[j];
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_MAPT()
|
||||
{
|
||||
uint size = MapSize();
|
||||
uint i;
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
SlSetLength(size);
|
||||
for (i = 0; i != size;) {
|
||||
byte buf[4096];
|
||||
uint j;
|
||||
|
||||
for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].type_height;
|
||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].type_height;
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_MAP1()
|
||||
{
|
||||
uint size = MapSize();
|
||||
uint i;
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
for (i = 0; i != size;) {
|
||||
byte buf[4096];
|
||||
uint j;
|
||||
|
||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
||||
for (j = 0; j != lengthof(buf); j++) _m[i++].m1 = buf[j];
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m1 = buf[j];
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_MAP1()
|
||||
{
|
||||
uint size = MapSize();
|
||||
uint i;
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
SlSetLength(size);
|
||||
for (i = 0; i != size;) {
|
||||
byte buf[4096];
|
||||
uint j;
|
||||
|
||||
for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m1;
|
||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m1;
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_MAP2()
|
||||
{
|
||||
uint size = MapSize();
|
||||
uint i;
|
||||
SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
for (i = 0; i != size;) {
|
||||
uint16 buf[4096];
|
||||
uint j;
|
||||
|
||||
SlArray(buf, lengthof(buf),
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
SlArray(buf, MAP_SL_BUF_SIZE,
|
||||
/* In those versions the m2 was 8 bits */
|
||||
CheckSavegameVersion(5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16
|
||||
);
|
||||
for (j = 0; j != lengthof(buf); j++) _m[i++].m2 = buf[j];
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m2 = buf[j];
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_MAP2()
|
||||
{
|
||||
uint size = MapSize();
|
||||
uint i;
|
||||
SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
SlSetLength(size * sizeof(_m[0].m2));
|
||||
for (i = 0; i != size;) {
|
||||
uint16 buf[4096];
|
||||
uint j;
|
||||
|
||||
for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m2;
|
||||
SlArray(buf, lengthof(buf), SLE_UINT16);
|
||||
SlSetLength(size * sizeof(uint16));
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m2;
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_MAP3()
|
||||
{
|
||||
uint size = MapSize();
|
||||
uint i;
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
for (i = 0; i != size;) {
|
||||
byte buf[4096];
|
||||
uint j;
|
||||
|
||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
||||
for (j = 0; j != lengthof(buf); j++) _m[i++].m3 = buf[j];
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m3 = buf[j];
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_MAP3()
|
||||
{
|
||||
uint size = MapSize();
|
||||
uint i;
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
SlSetLength(size);
|
||||
for (i = 0; i != size;) {
|
||||
byte buf[4096];
|
||||
uint j;
|
||||
|
||||
for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m3;
|
||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m3;
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_MAP4()
|
||||
{
|
||||
uint size = MapSize();
|
||||
uint i;
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
for (i = 0; i != size;) {
|
||||
byte buf[4096];
|
||||
uint j;
|
||||
|
||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
||||
for (j = 0; j != lengthof(buf); j++) _m[i++].m4 = buf[j];
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m4 = buf[j];
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_MAP4()
|
||||
{
|
||||
uint size = MapSize();
|
||||
uint i;
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
SlSetLength(size);
|
||||
for (i = 0; i != size;) {
|
||||
byte buf[4096];
|
||||
uint j;
|
||||
|
||||
for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m4;
|
||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m4;
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_MAP5()
|
||||
{
|
||||
uint size = MapSize();
|
||||
uint i;
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
for (i = 0; i != size;) {
|
||||
byte buf[4096];
|
||||
uint j;
|
||||
|
||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
||||
for (j = 0; j != lengthof(buf); j++) _m[i++].m5 = buf[j];
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m5 = buf[j];
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_MAP5()
|
||||
{
|
||||
uint size = MapSize();
|
||||
uint i;
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
SlSetLength(size);
|
||||
for (i = 0; i != size;) {
|
||||
byte buf[4096];
|
||||
uint j;
|
||||
|
||||
for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m5;
|
||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m5;
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_MAP6()
|
||||
{
|
||||
/* Still available for loading old games */
|
||||
uint size = MapSize();
|
||||
uint i;
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
if (CheckSavegameVersion(42)) {
|
||||
for (i = 0; i != size;) {
|
||||
uint8 buf[1024];
|
||||
uint j;
|
||||
|
||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
||||
for (j = 0; j != lengthof(buf); j++) {
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
/* 1024, otherwise we overflow on 64x64 maps! */
|
||||
SlArray(buf, 1024, SLE_UINT8);
|
||||
for (uint j = 0; j != 1024; j++) {
|
||||
_m[i++].m6 = GB(buf[j], 0, 2);
|
||||
_m[i++].m6 = GB(buf[j], 2, 2);
|
||||
_m[i++].m6 = GB(buf[j], 4, 2);
|
||||
@ -457,57 +423,45 @@ static void Load_MAP6()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i != size;) {
|
||||
byte buf[4096];
|
||||
uint j;
|
||||
|
||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
||||
for (j = 0; j != lengthof(buf); j++) _m[i++].m6 = buf[j];
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m6 = buf[j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_MAP6()
|
||||
{
|
||||
uint size = MapSize();
|
||||
uint i;
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
SlSetLength(size);
|
||||
for (i = 0; i != size;) {
|
||||
uint8 buf[4096];
|
||||
uint j;
|
||||
|
||||
for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m6;
|
||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m6;
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_MAP7()
|
||||
{
|
||||
uint size = MapSize();
|
||||
uint i;
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
for (i = 0; i != size;) {
|
||||
uint8 buf[4096];
|
||||
uint j;
|
||||
|
||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
||||
for (j = 0; j != lengthof(buf); j++) _me[i++].m7 = buf[j];
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m7 = buf[j];
|
||||
}
|
||||
}
|
||||
|
||||
static void Save_MAP7()
|
||||
{
|
||||
uint size = MapSize();
|
||||
uint i;
|
||||
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
SlSetLength(size);
|
||||
for (i = 0; i != size;) {
|
||||
uint8 buf[4096];
|
||||
uint j;
|
||||
|
||||
for (j = 0; j != lengthof(buf); j++) buf[j] = _me[i++].m7;
|
||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m7;
|
||||
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user