summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrubidium <rubidium@openttd.org>2008-04-01 21:12:51 +0000
committerrubidium <rubidium@openttd.org>2008-04-01 21:12:51 +0000
commit8e8362799187dab20c81aca4f19b6f6a218306be (patch)
tree8b8b47a627fbcb06ab1faeb36727a71765a27279
parent81b6125ac2adf4aeac327aa6a80cced3f4c84f35 (diff)
downloadopenttd-8e8362799187dab20c81aca4f19b6f6a218306be.tar.xz
(svn r12536) -Codechange: some stack allocations were too large for NDS, so use the SmallStackSafeStackAlloc wrapper. Allocate on the stack by default and on the heap for NDS (or other devices that have a very small stack).
-rw-r--r--src/core/alloc_func.hpp25
-rw-r--r--src/pathfind.cpp66
-rw-r--r--src/viewport.cpp14
3 files changed, 65 insertions, 40 deletions
diff --git a/src/core/alloc_func.hpp b/src/core/alloc_func.hpp
index a2cae3e3d..57a5fc3d4 100644
--- a/src/core/alloc_func.hpp
+++ b/src/core/alloc_func.hpp
@@ -107,9 +107,11 @@ struct SmallStackSafeStackAlloc {
#else
/** Storing it on the heap */
T *data;
+ /** The length (in elements) of data in this allocator. */
+ size_t len;
/** Allocating the memory */
- SmallStackSafeStackAlloc() : data(MallocT<T>(length)) {}
+ SmallStackSafeStackAlloc() : data(MallocT<T>(length)), len(length) {}
/** And freeing when it goes out of scope */
~SmallStackSafeStackAlloc() { free(data); }
#endif
@@ -118,7 +120,26 @@ struct SmallStackSafeStackAlloc {
* Gets a pointer to the data stored in this wrapper.
* @return the pointer.
*/
- operator T* () { return data; }
+ inline operator T* () { return data; }
+
+ /**
+ * Gets a pointer to the data stored in this wrapper.
+ * @return the pointer.
+ */
+ inline T* operator -> () { return data; }
+
+ /**
+ * Gets a pointer to the last data element stored in this wrapper.
+ * @note needed because endof does not work properly for pointers.
+ * @return the 'endof' pointer.
+ */
+ inline T* EndOf() {
+#if !defined(__NDS__)
+ return endof(data);
+#else
+ return &data[len];
+#endif
+ }
};
#endif /* ALLOC_FUNC_HPP */
diff --git a/src/pathfind.cpp b/src/pathfind.cpp
index ea84a76a2..c6f171dab 100644
--- a/src/pathfind.cpp
+++ b/src/pathfind.cpp
@@ -17,6 +17,7 @@
#include "depot.h"
#include "tunnelbridge_map.h"
#include "core/random_func.hpp"
+#include "core/alloc_func.hpp"
#include "tunnelbridge.h"
/* remember which tiles we have already visited so we don't visit them again. */
@@ -291,39 +292,38 @@ static void TPFMode1(TrackPathFinder* tpf, TileIndex tile, DiagDirection directi
void FollowTrack(TileIndex tile, uint16 flags, uint sub_type, DiagDirection direction, TPFEnumProc *enum_proc, TPFAfterProc *after_proc, void *data)
{
- TrackPathFinder tpf;
+ assert(IsValidDiagDirection(direction));
- assert(direction < 4);
+ SmallStackSafeStackAlloc<TrackPathFinder, 1> tpf;
/* initialize path finder variables */
- tpf.userdata = data;
- tpf.enum_proc = enum_proc;
- tpf.new_link = tpf.links;
- tpf.num_links_left = lengthof(tpf.links);
+ tpf->userdata = data;
+ tpf->enum_proc = enum_proc;
+ tpf->new_link = tpf->links;
+ tpf->num_links_left = lengthof(tpf->links);
- tpf.rd.cur_length = 0;
- tpf.rd.depth = 0;
- tpf.rd.last_choosen_track = INVALID_TRACK;
+ tpf->rd.cur_length = 0;
+ tpf->rd.depth = 0;
+ tpf->rd.last_choosen_track = INVALID_TRACK;
- tpf.var2 = HasBit(flags, 15) ? 0x43 : 0xFF; // 0x8000
+ tpf->var2 = HasBit(flags, 15) ? 0x43 : 0xFF; // 0x8000
- tpf.disable_tile_hash = HasBit(flags, 12); // 0x1000
+ tpf->disable_tile_hash = HasBit(flags, 12); // 0x1000
- tpf.tracktype = (TransportType)(flags & 0xFF);
- tpf.sub_type = sub_type;
+ tpf->tracktype = (TransportType)(flags & 0xFF);
+ tpf->sub_type = sub_type;
if (HasBit(flags, 11)) {
- tpf.enum_proc(tile, data, INVALID_TRACKDIR, 0);
- TPFMode2(&tpf, tile, direction);
+ tpf->enum_proc(tile, data, INVALID_TRACKDIR, 0);
+ TPFMode2(tpf, tile, direction);
} else {
/* clear the hash_heads */
- memset(tpf.hash_head, 0, sizeof(tpf.hash_head));
- TPFMode1(&tpf, tile, direction);
+ memset(tpf->hash_head, 0, sizeof(tpf->hash_head));
+ TPFMode1(tpf, tile, direction);
}
- if (after_proc != NULL)
- after_proc(&tpf);
+ if (after_proc != NULL) after_proc(tpf);
}
struct StackedItem {
@@ -820,18 +820,18 @@ start_at:
/** new pathfinder for trains. better and faster. */
void NewTrainPathfind(TileIndex tile, TileIndex dest, RailTypes railtypes, DiagDirection direction, NTPEnumProc* enum_proc, void* data)
{
- NewTrackPathFinder tpf;
-
- tpf.dest = dest;
- tpf.userdata = data;
- tpf.enum_proc = enum_proc;
- tpf.tracktype = TRANSPORT_RAIL;
- tpf.railtypes = railtypes;
- tpf.maxlength = min(_patches.pf_maxlength * 3, 10000);
- tpf.nstack = 0;
- tpf.new_link = tpf.links;
- tpf.num_links_left = lengthof(tpf.links);
- memset(tpf.hash_head, 0, sizeof(tpf.hash_head));
-
- NTPEnum(&tpf, tile, direction);
+ SmallStackSafeStackAlloc<NewTrackPathFinder, 1> tpf;
+
+ tpf->dest = dest;
+ tpf->userdata = data;
+ tpf->enum_proc = enum_proc;
+ tpf->tracktype = TRANSPORT_RAIL;
+ tpf->railtypes = railtypes;
+ tpf->maxlength = min(_patches.pf_maxlength * 3, 10000);
+ tpf->nstack = 0;
+ tpf->new_link = tpf->links;
+ tpf->num_links_left = lengthof(tpf->links);
+ memset(tpf->hash_head, 0, sizeof(tpf->hash_head));
+
+ NTPEnum(tpf, tile, direction);
}
diff --git a/src/viewport.cpp b/src/viewport.cpp
index 659834fd1..934cd18c9 100644
--- a/src/viewport.cpp
+++ b/src/viewport.cpp
@@ -27,11 +27,15 @@
#include "player_func.h"
#include "settings_type.h"
#include "station_func.h"
+#include "core/alloc_func.hpp"
#include "table/sprites.h"
#include "table/strings.h"
-#define VIEWPORT_DRAW_MEM (65536 * 2)
+enum {
+ VIEWPORT_DRAW_MEM = (65536 * 2),
+ PARENT_LIST_SIZE = 6144,
+};
PlaceProc *_place_proc;
Point _tile_fract_coords;
@@ -1541,8 +1545,8 @@ void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom
int y;
DrawPixelInfo *old_dpi;
- byte mem[VIEWPORT_DRAW_MEM];
- ParentSpriteToDraw *parent_list[6144];
+ SmallStackSafeStackAlloc<byte, VIEWPORT_DRAW_MEM> mem;
+ SmallStackSafeStackAlloc<ParentSpriteToDraw*, PARENT_LIST_SIZE> parent_list;
_cur_vd = &vd;
@@ -1566,9 +1570,9 @@ void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom
vd.dpi.dst_ptr = BlitterFactoryBase::GetCurrentBlitter()->MoveTo(old_dpi->dst_ptr, x - old_dpi->left, y - old_dpi->top);
vd.parent_list = parent_list;
- vd.eof_parent_list = endof(parent_list);
+ vd.eof_parent_list = parent_list.EndOf();
vd.spritelist_mem = mem;
- vd.eof_spritelist_mem = endof(mem) - sizeof(LARGEST_SPRITELIST_STRUCT);
+ vd.eof_spritelist_mem = mem.EndOf() - sizeof(LARGEST_SPRITELIST_STRUCT);
vd.last_string = &vd.first_string;
vd.first_string = NULL;
vd.last_tile = &vd.first_tile;