changeset 8987:7901d37c4329 draft

(svn r12782) -Codechange: remove some functions from functions.h and do not statically 'waste' memory when the old name array is not needed anymore.
author rubidium <rubidium@openttd.org>
date Sat, 19 Apr 2008 08:21:55 +0000
parents 6691bccdc43d
children 85e362a3caf5
files src/functions.h src/misc.cpp src/oldloader.cpp src/openttd.cpp src/saveload.cpp src/strings.cpp src/strings_func.h
diffstat 7 files changed, 139 insertions(+), 105 deletions(-) [+]
line wrap: on
line diff
--- a/src/functions.h
+++ b/src/functions.h
@@ -33,10 +33,6 @@
 
 void InitializeLandscapeVariables(bool only_constants);
 
-/* misc.cpp */
-bool IsCustomName(StringID id);
-char *CopyFromOldName(StringID id);
-
 /* misc functions */
 /**
  * Mark a tile given by its coordinate dirty for repaint.
@@ -68,11 +64,8 @@
 
 void RedrawAutosave();
 
-StringID RemapOldStringID(StringID s);
-
 void UpdateViewportSignPos(ViewportSign *sign, int left, int top, StringID str);
 
-
 /* callback from drivers that is called if the game size changes dynamically */
 void GameSizeChanged();
 const char *GetCurrentLocale(const char *param);
--- a/src/misc.cpp
+++ b/src/misc.cpp
@@ -23,14 +23,12 @@
 #include "date_func.h"
 #include "vehicle_func.h"
 #include "texteff.hpp"
-#include "string_func.h"
 #include "gfx_func.h"
 #include "core/alloc_type.hpp"
 
 #include "table/strings.h"
 #include "table/sprites.h"
 
-char _name_array[512][32];
 extern TileIndex _cur_tileloop_tile;
 
 void InitializeVehicles();
@@ -49,10 +47,10 @@
 void InitializeSigns();
 void InitializeStations();
 void InitializeCargoPackets();
-static void InitializeNameMgr();
 void InitializePlayers();
 void InitializeCheats();
 void InitializeNPF();
+void InitializeOldNames();
 
 void InitializeGame(int mode, uint size_x, uint size_y)
 {
@@ -93,7 +91,7 @@
 	InitializeIndustries();
 	InitializeBuildingCounts();
 
-	InitializeNameMgr();
+	InitializeOldNames();
 	InitializeVehiclesGuiList();
 	InitializeTrains();
 	InitializeNPF();
@@ -111,60 +109,6 @@
 	ResetObjectToPlace();
 }
 
-bool IsCustomName(StringID id)
-{
-	return GB(id, 11, 5) == 15;
-}
-
-
-static void InitializeNameMgr()
-{
-	memset(_name_array, 0, sizeof(_name_array));
-}
-
-/* Copy and convert old custom names to UTF-8 */
-char *CopyFromOldName(StringID id)
-{
-	if (!IsCustomName(id)) return NULL;
-
-	if (CheckSavegameVersion(37)) {
-		/* Old names were 32 characters long, so 128 characters should be
-		 * plenty to allow for expansion when converted to UTF-8. */
-		char tmp[128];
-		const char *strfrom = _name_array[GB(id, 0, 9)];
-		char *strto = tmp;
-
-		for (; *strfrom != '\0'; strfrom++) {
-			WChar c = (byte)*strfrom;
-
-			/* Map from non-ISO8859-15 characters to UTF-8. */
-			switch (c) {
-				case 0xA4: c = 0x20AC; break; // Euro
-				case 0xA6: c = 0x0160; break; // S with caron
-				case 0xA8: c = 0x0161; break; // s with caron
-				case 0xB4: c = 0x017D; break; // Z with caron
-				case 0xB8: c = 0x017E; break; // z with caron
-				case 0xBC: c = 0x0152; break; // OE ligature
-				case 0xBD: c = 0x0153; break; // oe ligature
-				case 0xBE: c = 0x0178; break; // Y with diaresis
-				default: break;
-			}
-
-			/* Check character will fit into our buffer. */
-			if (strto + Utf8CharLen(c) > lastof(tmp)) break;
-
-			strto += Utf8Encode(strto, c);
-		}
-
-		/* Terminate the new string and copy it back to the name array */
-		*strto = '\0';
-
-		return strdup(tmp);
-	} else {
-		/* Name will already be in UTF-8. */
-		return strdup(_name_array[GB(id, 0, 9)]);
-	}
-}
 
 /* Calculate constants that depend on the landscape type. */
 void InitializeLandscapeVariables(bool only_constants)
@@ -177,15 +121,6 @@
 	}
 }
 
-static void Load_NAME()
-{
-	int index;
-
-	while ((index = SlIterateArray()) != -1) {
-		SlArray(_name_array[index], SlGetFieldLength(), SLE_UINT8);
-	}
-}
-
 static const SaveLoadGlobVarList _date_desc[] = {
 	SLEG_CONDVAR(_date,                   SLE_FILE_U16 | SLE_VAR_I32,  0,  30),
 	SLEG_CONDVAR(_date,                   SLE_INT32,                  31, SL_MAX_VERSION),
@@ -469,7 +404,6 @@
 	{ 'MAPE', Save_MAP6,     Load_MAP6,     CH_RIFF },
 	{ 'MAP7', Save_MAP7,     Load_MAP7,     CH_RIFF },
 
-	{ 'NAME', NULL,          Load_NAME,     CH_ARRAY},
 	{ 'DATE', SaveLoad_DATE, SaveLoad_DATE, CH_RIFF},
 	{ 'VIEW', SaveLoad_VIEW, SaveLoad_VIEW, CH_RIFF | CH_LAST},
 };
--- a/src/oldloader.cpp
+++ b/src/oldloader.cpp
@@ -24,6 +24,7 @@
 #include "date_func.h"
 #include "vehicle_func.h"
 #include "variables.h"
+#include "strings_func.h"
 
 #include "table/strings.h"
 
@@ -84,6 +85,12 @@
 
 	OC_TILE      = OC_VAR_U32  | OC_FILE_U16,
 
+	/**
+	 * Dereference the pointer once before writing to it,
+	 * so we do not have to use big static arrays.
+	 */
+	OC_DEREFERENCE_POINTER = 1 << 31,
+
 	OC_END       = 0 ///< End of the whole chunk, all 32bits set to zero
 };
 
@@ -201,10 +208,10 @@
 	byte *base_ptr = (byte*)base;
 
 	while (chunk->type != OC_END) {
-		byte* ptr = (byte*)chunk->ptr;
-		uint i;
+		byte *ptr = (byte*)chunk->ptr;
+		if ((chunk->type & OC_DEREFERENCE_POINTER) != 0) ptr = *(byte**)ptr;
 
-		for (i = 0; i < chunk->amount; i++) {
+		for (uint i = 0; i < chunk->amount; i++) {
 			if (ls->failed) return false;
 
 			/* Handle simple types */
@@ -391,7 +398,7 @@
 
 extern TileIndex *_animated_tile_list;
 extern uint _animated_tile_count;
-extern char _name_array[512][32];
+extern char *_old_name_array;
 
 static byte   _old_vehicle_multiplier;
 static uint8  _old_map3[OLD_MAP_SIZE * 2];
@@ -1521,7 +1528,7 @@
 
 	OCL_ASSERT( 0x6F0F2 ),
 
-	OCL_VAR (  OC_UINT8, 32 * 500, &_name_array[0] ),
+	OCL_VAR (  OC_UINT8 | OC_DEREFERENCE_POINTER, 32 * 500, &_old_name_array ),
 
 	OCL_NULL( 0x2000 ),            ///< Old hash-table, no longer in use
 
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -91,6 +91,7 @@
 void DoPaletteAnimations();
 void MusicLoop();
 void ResetMusic();
+void ResetOldNames();
 
 extern void SetDifficultyLevel(int mode, GameOptions *gm_opt);
 extern Player* DoStartupNewPlayer(bool is_ai);
@@ -1390,6 +1391,9 @@
 		}
 	}
 
+	/* From this point the old names array is cleared. */
+	ResetOldNames();
+
 	/* convert road side to my format. */
 	if (_opt.road_side) _opt.road_side = 1;
 
--- a/src/saveload.cpp
+++ b/src/saveload.cpp
@@ -1248,6 +1248,7 @@
 
 /* these define the chunks */
 extern const ChunkHandler _misc_chunk_handlers[];
+extern const ChunkHandler _name_chunk_handlers[];
 extern const ChunkHandler _cheat_chunk_handlers[] ;
 extern const ChunkHandler _setting_chunk_handlers[];
 extern const ChunkHandler _player_chunk_handlers[];
@@ -1268,6 +1269,7 @@
 
 static const ChunkHandler * const _chunk_handlers[] = {
 	_misc_chunk_handlers,
+	_name_chunk_handlers,
 	_cheat_chunk_handlers,
 	_setting_chunk_handlers,
 	_veh_chunk_handlers,
--- a/src/strings.cpp
+++ b/src/strings.cpp
@@ -37,6 +37,7 @@
 #include "settings_type.h"
 #include "video/video_driver.hpp"
 #include "engine_func.h"
+#include "saveload.h"
 
 #include "table/strings.h"
 #include "table/control_codes.h"
@@ -1226,31 +1227,6 @@
 	return NULL;
 }
 
-/**
- * remap a string ID from the old format to the new format
- * @param s StringID that requires remapping
- * @return translated ID*/
-StringID RemapOldStringID(StringID s)
-{
-	switch (s) {
-		case 0x0006: return STR_SV_EMPTY;
-		case 0x7000: return STR_SV_UNNAMED;
-		case 0x70E4: return SPECSTR_PLAYERNAME_ENGLISH;
-		case 0x70E9: return SPECSTR_PLAYERNAME_ENGLISH;
-		case 0x8864: return STR_SV_TRAIN_NAME;
-		case 0x902B: return STR_SV_ROADVEH_NAME;
-		case 0x9830: return STR_SV_SHIP_NAME;
-		case 0xA02F: return STR_SV_AIRCRAFT_NAME;
-
-		default:
-			if (IsInsideMM(s, 0x300F, 0x3030)) {
-				return s - 0x300F + STR_SV_STNAME;
-			} else {
-				return s;
-			}
-	}
-}
-
 #ifdef ENABLE_NETWORK
 extern void SortNetworkLanguages();
 #else /* ENABLE_NETWORK */
@@ -1548,3 +1524,118 @@
 		}
 	}
 }
+
+
+/* --- Handling of saving/loading string IDs from old savegames --- */
+
+/**
+ * Remap a string ID from the old format to the new format
+ * @param s StringID that requires remapping
+ * @return translated ID
+ */
+StringID RemapOldStringID(StringID s)
+{
+	switch (s) {
+		case 0x0006: return STR_SV_EMPTY;
+		case 0x7000: return STR_SV_UNNAMED;
+		case 0x70E4: return SPECSTR_PLAYERNAME_ENGLISH;
+		case 0x70E9: return SPECSTR_PLAYERNAME_ENGLISH;
+		case 0x8864: return STR_SV_TRAIN_NAME;
+		case 0x902B: return STR_SV_ROADVEH_NAME;
+		case 0x9830: return STR_SV_SHIP_NAME;
+		case 0xA02F: return STR_SV_AIRCRAFT_NAME;
+
+		default:
+			if (IsInsideMM(s, 0x300F, 0x3030)) {
+				return s - 0x300F + STR_SV_STNAME;
+			} else {
+				return s;
+			}
+	}
+}
+
+/** Location to load the old names to. */
+char *_old_name_array = NULL;
+
+/**
+ * Copy and convert old custom names to UTF-8.
+ * They were all stored in a 512 by 32 long string array and are
+ * now stored with stations, waypoints and other places with names.
+ * @param id the StringID of the custom name to clone.
+ * @return the clones custom name.
+ */
+char *CopyFromOldName(StringID id)
+{
+	/* Is this name an (old) custom name? */
+	if (GB(id, 11, 5) != 15) return NULL;
+
+	if (CheckSavegameVersion(37)) {
+		/* Old names were 32 characters long, so 128 characters should be
+		 * plenty to allow for expansion when converted to UTF-8. */
+		char tmp[128];
+		const char *strfrom = &_old_name_array[32 * GB(id, 0, 9)];
+		char *strto = tmp;
+
+		for (; *strfrom != '\0'; strfrom++) {
+			WChar c = (byte)*strfrom;
+
+			/* Map from non-ISO8859-15 characters to UTF-8. */
+			switch (c) {
+				case 0xA4: c = 0x20AC; break; // Euro
+				case 0xA6: c = 0x0160; break; // S with caron
+				case 0xA8: c = 0x0161; break; // s with caron
+				case 0xB4: c = 0x017D; break; // Z with caron
+				case 0xB8: c = 0x017E; break; // z with caron
+				case 0xBC: c = 0x0152; break; // OE ligature
+				case 0xBD: c = 0x0153; break; // oe ligature
+				case 0xBE: c = 0x0178; break; // Y with diaresis
+				default: break;
+			}
+
+			/* Check character will fit into our buffer. */
+			if (strto + Utf8CharLen(c) > lastof(tmp)) break;
+
+			strto += Utf8Encode(strto, c);
+		}
+
+		/* Terminate the new string and copy it back to the name array */
+		*strto = '\0';
+
+		return strdup(tmp);
+	} else {
+		/* Name will already be in UTF-8. */
+		return strdup(&_old_name_array[32 * GB(id, 0, 9)]);
+	}
+}
+
+/**
+ * Free the memory of the old names array.
+ * Should be called once the old names have all been converted.
+ */
+void ResetOldNames()
+{
+	free(_old_name_array);
+	_old_name_array = NULL;
+}
+
+/**
+ * Initialize the old names table memory.
+ */
+void InitializeOldNames()
+{
+	free(_old_name_array);
+	_old_name_array = CallocT<char>(512 * 32);
+}
+
+static void Load_NAME()
+{
+	int index;
+
+	while ((index = SlIterateArray()) != -1) {
+		SlArray(&_old_name_array[32 * index], SlGetFieldLength(), SLE_UINT8);
+	}
+}
+
+extern const ChunkHandler _name_chunk_handlers[] = {
+	{ 'NAME', NULL, Load_NAME, CH_ARRAY | CH_LAST},
+};
--- a/src/strings_func.h
+++ b/src/strings_func.h
@@ -78,4 +78,7 @@
 
 void CheckForMissingGlyphsInLoadedLanguagePack();
 
+StringID RemapOldStringID(StringID s);
+char *CopyFromOldName(StringID id);
+
 #endif /* STRINGS_TYPE_H */