OpenTTD Source: src/saveload/strings_sl.cpp Source File

OpenTTD Source 15.0-RC2

strings_sl.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#include "../stdafx.h"
11#include "../string_func.h"
12#include "../strings_func.h"
13#include "../core/string_builder.hpp"
14#include "saveload_internal.h"
15
16#include "table/strings.h"
17
18#include "../safeguards.h"
19
20 static const int NUM_OLD_STRINGS = 512;
21 static const size_t LEN_OLD_STRINGS = 32;
22
28 StringID RemapOldStringID(StringID s)
29{
30 switch (s) {
31 case 0x0006: return STR_SV_EMPTY;
32 case 0x7000: return STR_SV_UNNAMED;
33 case 0x70E4: return SPECSTR_COMPANY_NAME_START;
34 case 0x70E9: return SPECSTR_COMPANY_NAME_START;
35 case 0x8864: return STR_SV_TRAIN_NAME;
36 case 0x902B: return STR_SV_ROAD_VEHICLE_NAME;
37 case 0x9830: return STR_SV_SHIP_NAME;
38 case 0xA02F: return STR_SV_AIRCRAFT_NAME;
39
40 default:
41 if (IsInsideMM(s, 0x300F, 0x3030)) {
42 return s - 0x300F + STR_SV_STNAME;
43 } else {
44 return s;
45 }
46 }
47}
48
50std::unique_ptr<std::string[]> _old_name_array;
51
59std::string CopyFromOldName(StringID id)
60{
61 /* Is this name an (old) custom name? */
62 if (GetStringTab(id) != TEXT_TAB_OLD_CUSTOM) return std::string();
63
64 if (IsSavegameVersionBefore(SLV_37)) {
65 const std::string &strfrom = _old_name_array[GB(id, 0, 9)];
66
67 std::string result;
68 StringBuilder builder(result);
69 for (char s : strfrom) {
70 if (s == '\0') break;
71 char32_t c = static_cast<uint8_t>(s); // cast to unsigned before integer promotion
72
73 /* Map from non-ISO8859-15 characters to UTF-8. */
74 switch (c) {
75 case 0xA4: c = 0x20AC; break; // Euro
76 case 0xA6: c = 0x0160; break; // S with caron
77 case 0xA8: c = 0x0161; break; // s with caron
78 case 0xB4: c = 0x017D; break; // Z with caron
79 case 0xB8: c = 0x017E; break; // z with caron
80 case 0xBC: c = 0x0152; break; // OE ligature
81 case 0xBD: c = 0x0153; break; // oe ligature
82 case 0xBE: c = 0x0178; break; // Y with diaeresis
83 default: break;
84 }
85
86 if (IsPrintable(c)) builder.PutUtf8(c);
87 }
88
89 return result;
90 } else {
91 /* Name will already be in UTF-8. */
92 return StrMakeValid(_old_name_array[GB(id, 0, 9)]);
93 }
94}
95
100 void ResetOldNames()
101{
102 _old_name_array = nullptr;
103}
104
108 void InitializeOldNames()
109{
110 _old_name_array = std::make_unique<std::string[]>(NUM_OLD_STRINGS); // 200 would be enough for TTO savegames
111}
112
113 struct NAMEChunkHandler : ChunkHandler {
114 NAMEChunkHandler() : ChunkHandler('NAME', CH_READONLY) {}
115
116 void Load() const override
117 {
118 int index;
119
120 while ((index = SlIterateArray()) != -1) {
121 if (index >= NUM_OLD_STRINGS) SlErrorCorrupt("Invalid old name index");
122 size_t length = SlGetFieldLength();
123 if (length > LEN_OLD_STRINGS) SlErrorCorrupt("Invalid old name length");
124
125 SlReadString(_old_name_array[index], length);
126 }
127 }
128};
129
130static const NAMEChunkHandler NAME;
131static const ChunkHandlerRef name_chunk_handlers[] = {
132 NAME,
133};
134
135extern const ChunkHandlerTable _name_chunk_handlers(name_chunk_handlers);
GB
static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
Definition bitmath_func.hpp:32
BaseStringBuilder::PutUtf8
void PutUtf8(char32_t c)
Append UTF.8 char.
Definition string_builder.cpp:113
StringBuilder
Compose data into a growing std::string.
Definition string_builder.hpp:65
IsInsideMM
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
Definition math_func.hpp:267
SlIterateArray
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition saveload.cpp:677
SlGetFieldLength
size_t SlGetFieldLength()
Get the length of the current object.
Definition saveload.cpp:800
SlErrorCorrupt
void SlErrorCorrupt(const std::string &msg)
Error handler for corrupt savegames.
Definition saveload.cpp:369
SlReadString
void SlReadString(std::string &str, size_t length)
Read the given amount of bytes from the buffer into the string.
Definition saveload.cpp:1039
ChunkHandlerRef
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition saveload.h:524
ChunkHandlerTable
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition saveload.h:527
IsSavegameVersionBefore
bool IsSavegameVersionBefore(SaveLoadVersion major, uint8_t minor=0)
Checks whether the savegame is below major.
Definition saveload.h:1278
SLV_37
@ SLV_37
37 7182
Definition saveload.h:87
CH_READONLY
@ CH_READONLY
Chunk is never saved.
Definition saveload.h:474
saveload_internal.h
Declaration of functions used in more save/load files.
StrMakeValid
static void StrMakeValid(Builder &builder, StringConsumer &consumer, StringValidationSettings settings)
Copies the valid (UTF-8) characters from consumer to the builder.
Definition string.cpp:119
GetStringTab
StringTab GetStringTab(StringID str)
Extract the StringTab from a StringID.
Definition strings_func.h:22
_old_name_array
std::unique_ptr< std::string[]> _old_name_array
Location to load the old names to.
Definition strings_sl.cpp:50
ResetOldNames
void ResetOldNames()
Free the memory of the old names array.
Definition strings_sl.cpp:100
RemapOldStringID
StringID RemapOldStringID(StringID s)
Remap a string ID from the old format to the new format.
Definition strings_sl.cpp:28
NUM_OLD_STRINGS
static const int NUM_OLD_STRINGS
The number of custom strings stored in old savegames.
Definition strings_sl.cpp:20
LEN_OLD_STRINGS
static const size_t LEN_OLD_STRINGS
The number of characters per string.
Definition strings_sl.cpp:21
InitializeOldNames
void InitializeOldNames()
Initialize the old names table memory.
Definition strings_sl.cpp:108
CopyFromOldName
std::string CopyFromOldName(StringID id)
Copy and convert old custom names to UTF-8.
Definition strings_sl.cpp:59
StringID
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Definition strings_type.h:19
SPECSTR_COMPANY_NAME_START
static constexpr StringID SPECSTR_COMPANY_NAME_START
Special strings for company names on the form "TownName transport".
Definition strings_type.h:68
ChunkHandler
Handlers and description of chunk.
Definition saveload.h:478
NAMEChunkHandler
Definition strings_sl.cpp:113
NAMEChunkHandler::Load
void Load() const override
Load the chunk.
Definition strings_sl.cpp:116