From 43bebecf3bb37b2aeacbfb5d635d1bc73e7b5f73 Mon Sep 17 00:00:00 2001 From: Misa Date: Wed, 30 Nov 2022 22:35:42 -0800 Subject: [PATCH] Make room names own their own memory This makes it so room names are no longer pointers to someone else's memory, and instead to set them you use `mapclass::setroomname`. If the string is short enough to fit in a static, no-alloc buffer, then it gets copied there. Otherwise, a new heap allocation is made that duplicates the string, and the new pointer is used instead. This makes it possible for room names to contain arbitrary data whose origin is temporary (e.g. from a script command that could be added in the future). --- desktop_version/src/Map.cpp | 56 +++++++++++++++++++++++++++--------- desktop_version/src/Map.h | 3 ++ desktop_version/src/main.cpp | 1 + 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/desktop_version/src/Map.cpp b/desktop_version/src/Map.cpp index d278c28c..674e464f 100644 --- a/desktop_version/src/Map.cpp +++ b/desktop_version/src/Map.cpp @@ -1,6 +1,7 @@ #define MAP_DEFINITION #include "Map.h" +#include "Alloc.h" #include "Constants.h" #include "CustomLevels.h" #include "Entity.h" @@ -80,10 +81,18 @@ mapclass::mapclass(void) nexttowercolour_set = false; - roomname = ""; + setroomname(""); hiddenname = ""; } +static char roomname_static[SCREEN_WIDTH_CHARS]; +static char* roomname_heap; + +void mapclass::destroy(void) +{ + VVV_free(roomname_heap); +} + //Areamap starts at 100,100 and extends 20x20 const int mapclass::areamap[] = { 1,2,2,2,2,2,2,2,0,3,0,0,0,4,4,4,4,4,4,4, @@ -163,6 +172,25 @@ void mapclass::settrinket(int x, int y) shinytrinkets.push_back(temp); } +void mapclass::setroomname(const char* name) +{ + VVV_free(roomname_heap); + + const size_t size = SDL_strlcpy( + roomname_static, name, sizeof(roomname_static) + ) + 1; + roomname = roomname_static; + + if (size > sizeof(roomname_static)) + { + roomname_heap = SDL_strdup(name); + if (roomname_heap != NULL) + { + roomname = roomname_heap; + } + } +} + void mapclass::resetmap(void) { //clear the explored area of the map @@ -1386,7 +1414,7 @@ void mapclass::loadlevel(int rx, int ry) obj.customplatformtile=0; obj.vertplatforms = false; obj.horplatforms = false; - roomname = ""; + setroomname(""); hiddenname = ""; background = 1; warpx = false; @@ -1518,7 +1546,7 @@ void mapclass::loadlevel(int rx, int ry) extrarow = 1; const short* tmap = otherlevel.loadlevel(rx, ry); copy_short_to_int(contents, tmap, SDL_arraysize(contents)); - roomname = otherlevel.roomname; + setroomname(otherlevel.roomname); hiddenname = otherlevel.hiddenname; tileset = otherlevel.roomtileset; break; @@ -1527,7 +1555,7 @@ void mapclass::loadlevel(int rx, int ry) { const short* tmap = lablevel.loadlevel(rx, ry); copy_short_to_int(contents, tmap, SDL_arraysize(contents)); - roomname = lablevel.roomname; + setroomname(lablevel.roomname); tileset = 1; background = 2; graphics.rcol = lablevel.rcol; @@ -1540,7 +1568,7 @@ void mapclass::loadlevel(int rx, int ry) graphics.towerbg.scrolldir = 0; setbgobjlerp(graphics.towerbg); - roomname = "The Tower"; + setroomname("The Tower"); tileset = 1; background = 3; towermode = true; @@ -1574,7 +1602,7 @@ void mapclass::loadlevel(int rx, int ry) { const short* tmap = warplevel.loadlevel(rx, ry); copy_short_to_int(contents, tmap, SDL_arraysize(contents)); - roomname = warplevel.roomname; + setroomname(warplevel.roomname); tileset = 1; background = 3; graphics.rcol = warplevel.rcol; @@ -1592,7 +1620,7 @@ void mapclass::loadlevel(int rx, int ry) { const short* tmap = spacestation2.loadlevel(rx, ry); copy_short_to_int(contents, tmap, SDL_arraysize(contents)); - roomname = spacestation2.roomname; + setroomname(spacestation2.roomname); tileset = 0; break; } @@ -1600,7 +1628,7 @@ void mapclass::loadlevel(int rx, int ry) { const short* tmap = finallevel.loadlevel(rx, ry); copy_short_to_int(contents, tmap, SDL_arraysize(contents)); - roomname = finallevel.roomname; + setroomname(finallevel.roomname); tileset = 1; background = 3; graphics.backgrounddrawn = false; @@ -1630,7 +1658,7 @@ void mapclass::loadlevel(int rx, int ry) graphics.towerbg.scrolldir = 1; setbgobjlerp(graphics.towerbg); - roomname = "Panic Room"; + setroomname("Panic Room"); tileset = 1; background = 3; towermode = true; @@ -1652,7 +1680,7 @@ void mapclass::loadlevel(int rx, int ry) graphics.towerbg.scrolldir = 1; setbgobjlerp(graphics.towerbg); - roomname = "Panic Room"; + setroomname("Panic Room"); tileset = 1; background = 3; towermode = true; @@ -1681,7 +1709,7 @@ void mapclass::loadlevel(int rx, int ry) graphics.towerbg.scrolldir = 0; setbgobjlerp(graphics.towerbg); - roomname = "The Final Challenge"; + setroomname("The Final Challenge"); tileset = 1; background = 3; towermode = true; @@ -1726,7 +1754,7 @@ void mapclass::loadlevel(int rx, int ry) graphics.towerbg.scrolldir = 0; setbgobjlerp(graphics.towerbg); - roomname = "The Final Challenge"; + setroomname("The Final Challenge"); tileset = 1; background = 3; towermode = true; @@ -1759,7 +1787,7 @@ void mapclass::loadlevel(int rx, int ry) { const short* tmap = finallevel.loadlevel(rx, ry); copy_short_to_int(contents, tmap, SDL_arraysize(contents)); - roomname = finallevel.roomname; + setroomname(finallevel.roomname); tileset = 2; if (rx == 108) { @@ -1842,7 +1870,7 @@ void mapclass::loadlevel(int rx, int ry) break; } - roomname = room->roomname.c_str(); + setroomname(room->roomname.c_str()); extrarow = 1; const int* tmap = cl.loadlevel(rx, ry); SDL_memcpy(contents, tmap, sizeof(contents)); diff --git a/desktop_version/src/Map.h b/desktop_version/src/Map.h index 3a439f3e..8268e7bf 100644 --- a/desktop_version/src/Map.h +++ b/desktop_version/src/Map.h @@ -22,6 +22,7 @@ class mapclass { public: mapclass(void); + void destroy(void); int getwidth(void); @@ -33,6 +34,8 @@ public: void settrinket(int x, int y); + void setroomname(const char* name); + void resetmap(void); void resetnames(void); diff --git a/desktop_version/src/main.cpp b/desktop_version/src/main.cpp index 25d4779f..b3fda94d 100644 --- a/desktop_version/src/main.cpp +++ b/desktop_version/src/main.cpp @@ -755,6 +755,7 @@ static void cleanup(void) graphics.destroy_buffers(); graphics.destroy(); music.destroy(); + map.destroy(); NETWORK_shutdown(); SDL_Quit(); FILESYSTEM_deinit();