OpenTTD Source 20250331-master-g3c15e0c889
newgrf_stringmapping.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 "../debug.h"
12#include "../newgrf.h"
13#include "../newgrf_text.h"
14#include "../newgrf_text_type.h"
15#include "../strings_type.h"
16#include "newgrf_internal.h"
18
19#include "../safeguards.h"
20
21#include "../table/strings.h"
22
27 uint32_t grfid;
29 std::function<void(StringID)> func;
30
31 StringIDMapping(uint32_t grfid, GRFStringID source, std::function<void(StringID)> &&func) : grfid(grfid), source(source), func(std::move(func)) { }
32};
33
35static std::vector<StringIDMapping> _string_to_grf_mapping;
36
42void AddStringForMapping(GRFStringID source, std::function<void(StringID)> &&func)
43{
44 func(STR_UNDEFINED);
45 _string_to_grf_mapping.emplace_back(_cur.grffile->grfid, source, std::move(func));
46}
47
54{
55 AddStringForMapping(source, [target](StringID str) { *target = str; });
56}
57
66{
67 /* StringID table for TextIDs 0x4E->0x6D */
68 static const StringID units_volume[] = {
69 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
70 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
71 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
72 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
73 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
74 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
75 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
76 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
77 };
78
79 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
80 assert(!IsInsideMM(str.base(), 0xD000, 0xD7FF));
81
82#define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
83 static_assert(stringend - stringid == end - begin); \
84 if (str.base() >= begin && str.base() <= end) return StringID{str.base() + (stringid - begin)}
85
86 /* We have some changes in our cargo strings, resulting in some missing. */
87 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
88 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
89 if (str.base() >= 0x004E && str.base() <= 0x006D) return units_volume[str.base() - 0x004E];
90 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
91 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
92 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
93
94 /* Map building names according to our lang file changes. There are several
95 * ranges of house ids, all of which need to be remapped to allow newgrfs
96 * to use original house names. */
97 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
98 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
99 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
100
101 /* Same thing for industries */
102 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
103 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
104 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
105 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
106 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
107
108 switch (str.base()) {
109 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
110 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
111 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED;
112 }
113#undef TEXTID_TO_STRINGID
114
115 if (str.base() == 0) return STR_EMPTY;
116
117 Debug(grf, 0, "Unknown StringID 0x{:04X} remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
118
119 return STR_EMPTY;
120}
121
130{
131 if (IsInsideMM(str.base(), 0xD800, 0x10000)) {
132 /* General text provided by NewGRF.
133 * In the specs this is called the 0xDCxx range (misc persistent texts),
134 * but we meanwhile extended the range to 0xD800-0xFFFF.
135 * Note: We are not involved in the "persistent" business, since we do not store
136 * any NewGRF strings in savegames. */
137 return GetGRFStringID(grfid, str);
138 } else if (IsInsideMM(str.base(), 0xD000, 0xD800)) {
139 /* Callback text provided by NewGRF.
140 * In the specs this is called the 0xD0xx range (misc graphics texts).
141 * These texts can be returned by various callbacks.
142 *
143 * Due to how TTDP implements the GRF-local- to global-textid translation
144 * texts included via 0x80 or 0x81 control codes have to add 0x400 to the textid.
145 * We do not care about that difference and just mask out the 0x400 bit.
146 */
147 str = GRFStringID(str.base() & ~0x400);
148 return GetGRFStringID(grfid, str);
149 } else {
150 /* The NewGRF wants to include/reference an original TTD string.
151 * Try our best to find an equivalent one. */
153 }
154}
155
160{
162 it.func(MapGRFStringID(it.grfid, it.source));
163 }
165}
#define Debug(category, level, format_string,...)
Output a line of debugging information.
Definition debug.h:37
constexpr bool IsInsideMM(const size_t x, const size_t min, const size_t max) noexcept
Checks if a value is in an interval.
NewGRF internal processing state.
void AddStringForMapping(GRFStringID source, std::function< void(StringID)> &&func)
Record a static StringID for getting translated later.
static std::vector< StringIDMapping > _string_to_grf_mapping
Strings to be mapped during load.
StringID MapGRFStringID(uint32_t grfid, GRFStringID str)
Used when setting an object's property to map to the GRF's strings while taking in consideration the ...
static StringID TTDPStringIDToOTTDStringIDMapping(GRFStringID str)
Perform a mapping from TTDPatch's string IDs to OpenTTD's string IDs, but only for the ones we are aw...
void FinaliseStringMapping()
Finalise all string mappings.
NewGRF string mapping definition.
StringID GetGRFStringID(uint32_t grfid, GRFStringID stringid)
Returns the index for this stringid associated with its grfID.
StrongType::Typedef< uint32_t, struct GRFStringIDTag, StrongType::Compare, StrongType::Integer > GRFStringID
Type for GRF-internal string IDs.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
GRFFile * grffile
Currently processed GRF file.
Information for mapping static StringIDs.
uint32_t grfid
Source NewGRF.
std::function< void(StringID)> func
Function for mapping result.
GRFStringID source
Source grf-local GRFStringID.