summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/saveload/saveload.cpp6
-rw-r--r--src/string.cpp26
-rw-r--r--src/string_func.h1
-rw-r--r--src/table/control_codes.h6
4 files changed, 35 insertions, 4 deletions
diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp
index 92b222d69..8a012b233 100644
--- a/src/saveload/saveload.cpp
+++ b/src/saveload/saveload.cpp
@@ -232,8 +232,9 @@
* 166 23415
* 167 23504
* 168 23637
+ * 169 23816
*/
-extern const uint16 SAVEGAME_VERSION = 168; ///< Current savegame version of OpenTTD.
+extern const uint16 SAVEGAME_VERSION = 169; ///< Current savegame version of OpenTTD.
SavegameType _savegame_type; ///< type of savegame we are loading
@@ -1096,6 +1097,9 @@ static void SlString(void *ptr, size_t length, VarType conv)
StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK;
if ((conv & SLF_ALLOW_CONTROL) != 0) {
settings = settings | SVS_ALLOW_CONTROL_CODE;
+ if (IsSavegameVersionBefore(169)) {
+ str_fix_scc_encoded((char *)ptr, (char *)ptr + len);
+ }
}
if ((conv & SLF_ALLOW_NEWLINE) != 0) {
settings = settings | SVS_ALLOW_NEWLINE;
diff --git a/src/string.cpp b/src/string.cpp
index bc9933b40..4f7865ada 100644
--- a/src/string.cpp
+++ b/src/string.cpp
@@ -178,6 +178,30 @@ char *CDECL str_fmt(const char *str, ...)
return p;
}
+/**
+ * Scan the string for old values of SCC_ENCODED and fix it to
+ * it's new, static value.
+ * @param str the string to scan
+ * @param last the last valid character of str
+ */
+void str_fix_scc_encoded(char *str, const char *last)
+{
+ while (str <= last && *str != '\0') {
+ size_t len = Utf8EncodedCharLen(*str);
+ if ((len == 0 && str + 4 > last) || str + len > last) break;
+
+ WChar c;
+ len = Utf8Decode(&c, str);
+ if (c == '\0') break;
+
+ if (c == 0xE028 || c == 0xE02A) {
+ c = SCC_ENCODED;
+ }
+ str += Utf8Encode(str, c);
+ }
+ *str = '\0';
+}
+
/**
* Scans the string for valid characters and if it finds invalid ones,
@@ -207,7 +231,7 @@ void str_validate(char *str, const char *last, StringValidationSettings settings
* characters to be skipped */
if (c == '\0') break;
- if ((IsPrintable(c) && (c < SCC_SPRITE_START || c > SCC_SPRITE_END)) || ((settings & SVS_ALLOW_CONTROL_CODE) != 0 && IsInsideMM(c, SCC_CONTROL_START, SCC_CONTROL_END))) {
+ if ((IsPrintable(c) && (c < SCC_SPRITE_START || c > SCC_SPRITE_END)) || ((settings & SVS_ALLOW_CONTROL_CODE) != 0 && c == SCC_ENCODED)) {
/* Copy the character back. Even if dst is current the same as str
* (i.e. no characters have been changed) this is quicker than
* moving the pointers ahead by len */
diff --git a/src/string_func.h b/src/string_func.h
index ac2fd0e76..070695fdb 100644
--- a/src/string_func.h
+++ b/src/string_func.h
@@ -40,6 +40,7 @@ int CDECL seprintf(char *str, const char *last, const char *format, ...) WARN_FO
char *CDECL str_fmt(const char *str, ...) WARN_FORMAT(1, 2);
void str_validate(char *str, const char *last, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK);
+void str_fix_scc_encoded(char *str, const char *last);
void str_strip_colours(char *str);
bool strtolower(char *str);
diff --git a/src/table/control_codes.h b/src/table/control_codes.h
index 28266c155..81b100921 100644
--- a/src/table/control_codes.h
+++ b/src/table/control_codes.h
@@ -23,8 +23,11 @@ enum StringControlCode {
SCC_SPRITE_START = 0xE200,
SCC_SPRITE_END = SCC_SPRITE_START + 0xFF,
+ /* This must be the first entry. It's encoded in strings that are saved. */
+ SCC_ENCODED = SCC_CONTROL_START,
+
/* Display control codes */
- SCC_SETX = SCC_CONTROL_START,
+ SCC_SETX,
SCC_SETXY,
SCC_TINYFONT, ///< Switch to small font
SCC_BIGFONT, ///< Switch to large font
@@ -74,7 +77,6 @@ enum StringControlCode {
SCC_STRING6,
SCC_STRING7,
- SCC_ENCODED,
SCC_STRING,
SCC_COMMA,