OpenTTD Source 20250312-master-gcdcc6b491d
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 <http://www.gnu.org/licenses/>.
6 */
7
10#include "../stdafx.h"
11#include "../string_func.h"
12#include "../strings_func.h"
13#include "saveload_internal.h"
14#include <sstream>
15
16#include "table/strings.h"
17
18#include "../safeguards.h"
19
20static const int NUM_OLD_STRINGS = 512;
21static const size_t LEN_OLD_STRINGS = 32;
22
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
60{
61 /* Is this name an (old) custom name? */
62 if (GetStringTab(id) != TEXT_TAB_OLD_CUSTOM) return std::string();
63
65 const std::string &strfrom = _old_name_array[GB(id, 0, 9)];
66
67 std::ostringstream tmp;
68 std::ostreambuf_iterator<char> strto(tmp);
69 for (char32_t c : strfrom) {
70 if (c == '\0') break;
71
72 /* Map from non-ISO8859-15 characters to UTF-8. */
73 switch (c) {
74 case 0xA4: c = 0x20AC; break; // Euro
75 case 0xA6: c = 0x0160; break; // S with caron
76 case 0xA8: c = 0x0161; break; // s with caron
77 case 0xB4: c = 0x017D; break; // Z with caron
78 case 0xB8: c = 0x017E; break; // z with caron
79 case 0xBC: c = 0x0152; break; // OE ligature
80 case 0xBD: c = 0x0153; break; // oe ligature
81 case 0xBE: c = 0x0178; break; // Y with diaeresis
82 default: break;
83 }
84
85 if (IsPrintable(c)) Utf8Encode(strto, c);
86 }
87
88 return tmp.str();
89 } else {
90 /* Name will already be in UTF-8. */
91 return StrMakeValid(_old_name_array[GB(id, 0, 9)]);
92 }
93}
94
100{
101 _old_name_array = nullptr;
102}
103
108{
109 _old_name_array = std::make_unique<std::string[]>(NUM_OLD_STRINGS); // 200 would be enough for TTO savegames
110}
111
114
115 void Load() const override
116 {
117 int index;
118
119 while ((index = SlIterateArray()) != -1) {
120 if (index >= NUM_OLD_STRINGS) SlErrorCorrupt("Invalid old name index");
121 size_t length = SlGetFieldLength();
122 if (length > LEN_OLD_STRINGS) SlErrorCorrupt("Invalid old name length");
123
124 SlReadString(_old_name_array[index], length);
125 }
126 }
127};
128
129static const NAMEChunkHandler NAME;
130static const ChunkHandlerRef name_chunk_handlers[] = {
131 NAME,
132};
133
134extern const ChunkHandlerTable _name_chunk_handlers(name_chunk_handlers);
debug_inline static constexpr uint GB(const T x, const uint8_t s, const uint8_t n)
Fetch n bits from x, started at bit s.
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
int SlIterateArray()
Iterate through the elements of an array and read the whole thing.
Definition saveload.cpp:663
size_t SlGetFieldLength()
Get the length of the current object.
Definition saveload.cpp:786
void SlErrorCorrupt(const std::string &msg)
Error handler for corrupt savegames.
Definition saveload.cpp:355
void SlReadString(std::string &str, size_t length)
Read the given amount of bytes from the buffer into the string.
Definition saveload.cpp:990
std::reference_wrapper< const ChunkHandler > ChunkHandlerRef
A reference to ChunkHandler.
Definition saveload.h:514
std::span< const ChunkHandlerRef > ChunkHandlerTable
A table of ChunkHandler entries.
Definition saveload.h:517
bool IsSavegameVersionBefore(SaveLoadVersion major, uint8_t minor=0)
Checks whether the savegame is below major.
Definition saveload.h:1268
@ SLV_37
37 7182
Definition saveload.h:87
@ CH_READONLY
Chunk is never saved.
Definition saveload.h:464
Declaration of functions used in more save/load files.
static void StrMakeValid(T &dst, const char *str, const char *last, StringValidationSettings settings)
Copies the valid (UTF-8) characters from str up to last to the dst.
Definition string.cpp:125
size_t Utf8Encode(T buf, char32_t c)
Encode a unicode character and place it in the buffer.
Definition string.cpp:478
StringTab GetStringTab(StringID str)
Extract the StringTab from a StringID.
std::unique_ptr< std::string[]> _old_name_array
Location to load the old names to.
void ResetOldNames()
Free the memory of the old names array.
StringID RemapOldStringID(StringID s)
Remap a string ID from the old format to the new format.
static const int NUM_OLD_STRINGS
The number of custom strings stored in old savegames.
static const size_t LEN_OLD_STRINGS
The number of characters per string.
void InitializeOldNames()
Initialize the old names table memory.
std::string CopyFromOldName(StringID id)
Copy and convert old custom names to UTF-8.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
static constexpr StringID SPECSTR_COMPANY_NAME_START
Special strings for company names on the form "TownName transport".
Handlers and description of chunk.
Definition saveload.h:468
void Load() const override
Load the chunk.