mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-10 08:00:05 +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;
|
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 */
|
#endif /* ALLOC_FUNC_HPP */
|
||||||
|
226
src/misc.cpp
226
src/misc.cpp
@ -25,6 +25,7 @@
|
|||||||
#include "texteff.hpp"
|
#include "texteff.hpp"
|
||||||
#include "string_func.h"
|
#include "string_func.h"
|
||||||
#include "gfx_func.h"
|
#include "gfx_func.h"
|
||||||
|
#include "core/alloc_func.hpp"
|
||||||
|
|
||||||
#include "table/strings.h"
|
#include "table/strings.h"
|
||||||
#include "table/sprites.h"
|
#include "table/sprites.h"
|
||||||
@ -260,196 +261,161 @@ static void Load_MAPS()
|
|||||||
AllocateMap(_map_dim_x, _map_dim_y);
|
AllocateMap(_map_dim_x, _map_dim_y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
MAP_SL_BUF_SIZE = 4096
|
||||||
|
};
|
||||||
|
|
||||||
static void Load_MAPT()
|
static void Load_MAPT()
|
||||||
{
|
{
|
||||||
uint size = MapSize();
|
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||||
uint i;
|
TileIndex size = MapSize();
|
||||||
|
|
||||||
for (i = 0; i != size;) {
|
for (TileIndex i = 0; i != size;) {
|
||||||
byte buf[4096];
|
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||||
uint j;
|
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].type_height = buf[j];
|
||||||
|
|
||||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
|
||||||
for (j = 0; j != lengthof(buf); j++) _m[i++].type_height = buf[j];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Save_MAPT()
|
static void Save_MAPT()
|
||||||
{
|
{
|
||||||
uint size = MapSize();
|
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||||
uint i;
|
TileIndex size = MapSize();
|
||||||
|
|
||||||
SlSetLength(size);
|
SlSetLength(size);
|
||||||
for (i = 0; i != size;) {
|
for (TileIndex i = 0; i != size;) {
|
||||||
byte buf[4096];
|
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].type_height;
|
||||||
uint j;
|
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||||
|
|
||||||
for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].type_height;
|
|
||||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_MAP1()
|
static void Load_MAP1()
|
||||||
{
|
{
|
||||||
uint size = MapSize();
|
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||||
uint i;
|
TileIndex size = MapSize();
|
||||||
|
|
||||||
for (i = 0; i != size;) {
|
for (TileIndex i = 0; i != size;) {
|
||||||
byte buf[4096];
|
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||||
uint j;
|
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m1 = buf[j];
|
||||||
|
|
||||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
|
||||||
for (j = 0; j != lengthof(buf); j++) _m[i++].m1 = buf[j];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Save_MAP1()
|
static void Save_MAP1()
|
||||||
{
|
{
|
||||||
uint size = MapSize();
|
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||||
uint i;
|
TileIndex size = MapSize();
|
||||||
|
|
||||||
SlSetLength(size);
|
SlSetLength(size);
|
||||||
for (i = 0; i != size;) {
|
for (TileIndex i = 0; i != size;) {
|
||||||
byte buf[4096];
|
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m1;
|
||||||
uint j;
|
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||||
|
|
||||||
for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m1;
|
|
||||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_MAP2()
|
static void Load_MAP2()
|
||||||
{
|
{
|
||||||
uint size = MapSize();
|
SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
|
||||||
uint i;
|
TileIndex size = MapSize();
|
||||||
|
|
||||||
for (i = 0; i != size;) {
|
for (TileIndex i = 0; i != size;) {
|
||||||
uint16 buf[4096];
|
SlArray(buf, MAP_SL_BUF_SIZE,
|
||||||
uint j;
|
|
||||||
|
|
||||||
SlArray(buf, lengthof(buf),
|
|
||||||
/* In those versions the m2 was 8 bits */
|
/* In those versions the m2 was 8 bits */
|
||||||
CheckSavegameVersion(5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16
|
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()
|
static void Save_MAP2()
|
||||||
{
|
{
|
||||||
uint size = MapSize();
|
SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
|
||||||
uint i;
|
TileIndex size = MapSize();
|
||||||
|
|
||||||
SlSetLength(size * sizeof(_m[0].m2));
|
SlSetLength(size * sizeof(uint16));
|
||||||
for (i = 0; i != size;) {
|
for (TileIndex i = 0; i != size;) {
|
||||||
uint16 buf[4096];
|
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m2;
|
||||||
uint j;
|
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16);
|
||||||
|
|
||||||
for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m2;
|
|
||||||
SlArray(buf, lengthof(buf), SLE_UINT16);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_MAP3()
|
static void Load_MAP3()
|
||||||
{
|
{
|
||||||
uint size = MapSize();
|
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||||
uint i;
|
TileIndex size = MapSize();
|
||||||
|
|
||||||
for (i = 0; i != size;) {
|
for (TileIndex i = 0; i != size;) {
|
||||||
byte buf[4096];
|
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||||
uint j;
|
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m3 = buf[j];
|
||||||
|
|
||||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
|
||||||
for (j = 0; j != lengthof(buf); j++) _m[i++].m3 = buf[j];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Save_MAP3()
|
static void Save_MAP3()
|
||||||
{
|
{
|
||||||
uint size = MapSize();
|
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||||
uint i;
|
TileIndex size = MapSize();
|
||||||
|
|
||||||
SlSetLength(size);
|
SlSetLength(size);
|
||||||
for (i = 0; i != size;) {
|
for (TileIndex i = 0; i != size;) {
|
||||||
byte buf[4096];
|
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m3;
|
||||||
uint j;
|
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||||
|
|
||||||
for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m3;
|
|
||||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_MAP4()
|
static void Load_MAP4()
|
||||||
{
|
{
|
||||||
uint size = MapSize();
|
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||||
uint i;
|
TileIndex size = MapSize();
|
||||||
|
|
||||||
for (i = 0; i != size;) {
|
for (TileIndex i = 0; i != size;) {
|
||||||
byte buf[4096];
|
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||||
uint j;
|
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m4 = buf[j];
|
||||||
|
|
||||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
|
||||||
for (j = 0; j != lengthof(buf); j++) _m[i++].m4 = buf[j];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Save_MAP4()
|
static void Save_MAP4()
|
||||||
{
|
{
|
||||||
uint size = MapSize();
|
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||||
uint i;
|
TileIndex size = MapSize();
|
||||||
|
|
||||||
SlSetLength(size);
|
SlSetLength(size);
|
||||||
for (i = 0; i != size;) {
|
for (TileIndex i = 0; i != size;) {
|
||||||
byte buf[4096];
|
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m4;
|
||||||
uint j;
|
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||||
|
|
||||||
for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m4;
|
|
||||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_MAP5()
|
static void Load_MAP5()
|
||||||
{
|
{
|
||||||
uint size = MapSize();
|
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||||
uint i;
|
TileIndex size = MapSize();
|
||||||
|
|
||||||
for (i = 0; i != size;) {
|
for (TileIndex i = 0; i != size;) {
|
||||||
byte buf[4096];
|
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||||
uint j;
|
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m5 = buf[j];
|
||||||
|
|
||||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
|
||||||
for (j = 0; j != lengthof(buf); j++) _m[i++].m5 = buf[j];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Save_MAP5()
|
static void Save_MAP5()
|
||||||
{
|
{
|
||||||
uint size = MapSize();
|
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||||
uint i;
|
TileIndex size = MapSize();
|
||||||
|
|
||||||
SlSetLength(size);
|
SlSetLength(size);
|
||||||
for (i = 0; i != size;) {
|
for (TileIndex i = 0; i != size;) {
|
||||||
byte buf[4096];
|
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m5;
|
||||||
uint j;
|
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||||
|
|
||||||
for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m5;
|
|
||||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_MAP6()
|
static void Load_MAP6()
|
||||||
{
|
{
|
||||||
/* Still available for loading old games */
|
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||||
uint size = MapSize();
|
TileIndex size = MapSize();
|
||||||
uint i;
|
|
||||||
|
|
||||||
if (CheckSavegameVersion(42)) {
|
if (CheckSavegameVersion(42)) {
|
||||||
for (i = 0; i != size;) {
|
for (TileIndex i = 0; i != size;) {
|
||||||
uint8 buf[1024];
|
/* 1024, otherwise we overflow on 64x64 maps! */
|
||||||
uint j;
|
SlArray(buf, 1024, SLE_UINT8);
|
||||||
|
for (uint j = 0; j != 1024; j++) {
|
||||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
|
||||||
for (j = 0; j != lengthof(buf); j++) {
|
|
||||||
_m[i++].m6 = GB(buf[j], 0, 2);
|
_m[i++].m6 = GB(buf[j], 0, 2);
|
||||||
_m[i++].m6 = GB(buf[j], 2, 2);
|
_m[i++].m6 = GB(buf[j], 2, 2);
|
||||||
_m[i++].m6 = GB(buf[j], 4, 2);
|
_m[i++].m6 = GB(buf[j], 4, 2);
|
||||||
@ -457,57 +423,45 @@ static void Load_MAP6()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i != size;) {
|
for (TileIndex i = 0; i != size;) {
|
||||||
byte buf[4096];
|
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||||
uint j;
|
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m6 = buf[j];
|
||||||
|
|
||||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
|
||||||
for (j = 0; j != lengthof(buf); j++) _m[i++].m6 = buf[j];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Save_MAP6()
|
static void Save_MAP6()
|
||||||
{
|
{
|
||||||
uint size = MapSize();
|
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||||
uint i;
|
TileIndex size = MapSize();
|
||||||
|
|
||||||
SlSetLength(size);
|
SlSetLength(size);
|
||||||
for (i = 0; i != size;) {
|
for (TileIndex i = 0; i != size;) {
|
||||||
uint8 buf[4096];
|
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m6;
|
||||||
uint j;
|
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||||
|
|
||||||
for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m6;
|
|
||||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_MAP7()
|
static void Load_MAP7()
|
||||||
{
|
{
|
||||||
uint size = MapSize();
|
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||||
uint i;
|
TileIndex size = MapSize();
|
||||||
|
|
||||||
for (i = 0; i != size;) {
|
for (TileIndex i = 0; i != size;) {
|
||||||
uint8 buf[4096];
|
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||||
uint j;
|
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m7 = buf[j];
|
||||||
|
|
||||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
|
||||||
for (j = 0; j != lengthof(buf); j++) _me[i++].m7 = buf[j];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Save_MAP7()
|
static void Save_MAP7()
|
||||||
{
|
{
|
||||||
uint size = MapSize();
|
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
|
||||||
uint i;
|
TileIndex size = MapSize();
|
||||||
|
|
||||||
SlSetLength(size);
|
SlSetLength(size);
|
||||||
for (i = 0; i != size;) {
|
for (TileIndex i = 0; i != size;) {
|
||||||
uint8 buf[4096];
|
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m7;
|
||||||
uint j;
|
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
|
||||||
|
|
||||||
for (j = 0; j != lengthof(buf); j++) buf[j] = _me[i++].m7;
|
|
||||||
SlArray(buf, lengthof(buf), SLE_UINT8);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user