From 59ec5e62ce645e09657764344108cae3b7b03632 Mon Sep 17 00:00:00 2001 From: rubidium Date: Tue, 22 Jan 2008 12:09:12 +0000 Subject: (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. --- src/core/alloc_func.hpp | 31 +++++++ src/misc.cpp | 226 +++++++++++++++++++----------------------------- 2 files changed, 121 insertions(+), 136 deletions(-) (limited to 'src') diff --git a/src/core/alloc_func.hpp b/src/core/alloc_func.hpp index 5d88e64e8..97e598598 100644 --- a/src/core/alloc_func.hpp +++ b/src/core/alloc_func.hpp @@ -81,4 +81,35 @@ template 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 +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(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 */ diff --git a/src/misc.cpp b/src/misc.cpp index 55a62e532..599a3563d 100644 --- a/src/misc.cpp +++ b/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 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 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 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 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; - - for (i = 0; i != size;) { - uint16 buf[4096]; - uint j; + SmallStackSafeStackAlloc buf; + TileIndex size = MapSize(); - 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; - - SlSetLength(size * sizeof(_m[0].m2)); - for (i = 0; i != size;) { - uint16 buf[4096]; - uint j; + SmallStackSafeStackAlloc buf; + TileIndex size = MapSize(); - 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; - - for (i = 0; i != size;) { - byte buf[4096]; - uint j; + SmallStackSafeStackAlloc buf; + TileIndex size = MapSize(); - 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 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; - - for (i = 0; i != size;) { - byte buf[4096]; - uint j; + SmallStackSafeStackAlloc buf; + TileIndex size = MapSize(); - 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 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 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 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 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 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; - - for (i = 0; i != size;) { - uint8 buf[4096]; - uint j; + SmallStackSafeStackAlloc buf; + TileIndex size = MapSize(); - 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 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); } } -- cgit v1.2.3-70-g09d2