OpenTTD Source 20250613-master-ga1786fa1f4
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 "../core/string_builder.hpp"
14#include "saveload_internal.h"
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::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
101{
102 _old_name_array = nullptr;
103}
104
109{
110 _old_name_array = std::make_unique<std::string[]>(NUM_OLD_STRINGS); // 200 would be enough for TTO savegames
111}
112
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);
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.
void PutUtf8(char32_t c)
Append UTF.8 char.
Compose data into a growing std::string.
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:665
size_t SlGetFieldLength()
Get the length of the current object.
Definition saveload.cpp:788
void SlErrorCorrupt(const std::string &msg)
Error handler for corrupt savegames.
Definition saveload.cpp:357
void SlReadString(std::string &str, size_t length)
Read the given amount of bytes from the buffer into the string.
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(Builder &builder, StringConsumer &consumer, StringValidationSettings settings)
Copies the valid (UTF-8) characters from consumer to the builder.
Definition string.cpp:117
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.