diff options
-rw-r--r-- | src/saveload/saveload.cpp | 6 | ||||
-rw-r--r-- | src/string.cpp | 26 | ||||
-rw-r--r-- | src/string_func.h | 1 | ||||
-rw-r--r-- | src/table/control_codes.h | 6 |
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, |