From 8e8362799187dab20c81aca4f19b6f6a218306be Mon Sep 17 00:00:00 2001 From: rubidium Date: Tue, 1 Apr 2008 21:12:51 +0000 Subject: [PATCH] (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). --- src/core/alloc_func.hpp | 25 +++++++++++++++-- src/pathfind.cpp | 62 ++++++++++++++++++++--------------------- src/viewport.cpp | 14 ++++++---- 3 files changed, 63 insertions(+), 38 deletions(-) diff --git a/src/core/alloc_func.hpp b/src/core/alloc_func.hpp index a2cae3e3db..57a5fc3d49 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(length)) {} + SmallStackSafeStackAlloc() : data(MallocT(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 ea84a76a24..c6f171dabb 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 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; + SmallStackSafeStackAlloc 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)); + 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); + NTPEnum(tpf, tile, direction); } diff --git a/src/viewport.cpp b/src/viewport.cpp index 659834fd1b..934cd18c94 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 mem; + SmallStackSafeStackAlloc 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;