OpenTTD Source 20260711-master-g3fb3006dff
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 <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
9
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 "table/strings.h"
20
21#include "../safeguards.h"
22
29 std::function<void(StringID)> func;
30};
31
33static std::vector<StringIDMapping> _string_to_grf_mapping;
34
40void AddStringForMapping(GRFStringID source, std::function<void(StringID)> &&func)
41{
42 func(STR_UNDEFINED);
43 _string_to_grf_mapping.emplace_back(_cur_gps.grffile->grfid, source, std::move(func));
44}
45
52{
53 AddStringForMapping(source, [target](StringID str) { *target = str; });
54}
55
64{
65 /* StringID table for TextIDs 0x4E->0x6D */
66 static const StringID units_volume[] = {
67 STR_ITEMS, STR_PASSENGERS, STR_TONS, STR_BAGS,
68 STR_LITERS, STR_ITEMS, STR_CRATES, STR_TONS,
69 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
70 STR_TONS, STR_TONS, STR_TONS, STR_BAGS,
71 STR_TONS, STR_TONS, STR_BAGS, STR_LITERS,
72 STR_TONS, STR_LITERS, STR_TONS, STR_ITEMS,
73 STR_BAGS, STR_LITERS, STR_TONS, STR_ITEMS,
74 STR_TONS, STR_ITEMS, STR_LITERS, STR_ITEMS
75 };
76
77 /* A string straight from a NewGRF; this was already translated by MapGRFStringID(). */
78 assert(!IsInsideMM(str.base(), 0xD000, 0xD7FF));
79
80#define TEXTID_TO_STRINGID(begin, end, stringid, stringend) \
81 static_assert(stringend - stringid == end - begin); \
82 if (str.base() >= begin && str.base() <= end) return StringID{str.base() + (stringid - begin)}
83
84 /* We have some changes in our cargo strings, resulting in some missing. */
85 TEXTID_TO_STRINGID(0x000E, 0x002D, STR_CARGO_PLURAL_NOTHING, STR_CARGO_PLURAL_FIZZY_DRINKS);
86 TEXTID_TO_STRINGID(0x002E, 0x004D, STR_CARGO_SINGULAR_NOTHING, STR_CARGO_SINGULAR_FIZZY_DRINK);
87 if (str.base() >= 0x004E && str.base() <= 0x006D) return units_volume[str.base() - 0x004E];
88 TEXTID_TO_STRINGID(0x006E, 0x008D, STR_QUANTITY_NOTHING, STR_QUANTITY_FIZZY_DRINKS);
89 TEXTID_TO_STRINGID(0x008E, 0x00AD, STR_ABBREV_NOTHING, STR_ABBREV_FIZZY_DRINKS);
90 TEXTID_TO_STRINGID(0x00D1, 0x00E0, STR_COLOUR_DARK_BLUE, STR_COLOUR_WHITE);
91
92 /* Map building names according to our lang file changes. There are several
93 * ranges of house ids, all of which need to be remapped to allow newgrfs
94 * to use original house names. */
95 TEXTID_TO_STRINGID(0x200F, 0x201F, STR_TOWN_BUILDING_NAME_TALL_OFFICE_BLOCK_1, STR_TOWN_BUILDING_NAME_OLD_HOUSES_1);
96 TEXTID_TO_STRINGID(0x2036, 0x2041, STR_TOWN_BUILDING_NAME_COTTAGES_1, STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1);
97 TEXTID_TO_STRINGID(0x2059, 0x205C, STR_TOWN_BUILDING_NAME_IGLOO_1, STR_TOWN_BUILDING_NAME_PIGGY_BANK_1);
98
99 /* Same thing for industries */
100 TEXTID_TO_STRINGID(0x4802, 0x4826, STR_INDUSTRY_NAME_COAL_MINE, STR_INDUSTRY_NAME_SUGAR_MINE);
101 TEXTID_TO_STRINGID(0x482D, 0x482E, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_PLANTED);
102 TEXTID_TO_STRINGID(0x4832, 0x4834, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES);
103 TEXTID_TO_STRINGID(0x4835, 0x4838, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM);
104 TEXTID_TO_STRINGID(0x4839, 0x483A, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM);
105
106 switch (str.base()) {
107 case 0x4830: return STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY;
108 case 0x4831: return STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED;
109 case 0x483B: return STR_ERROR_CAN_ONLY_BE_POSITIONED;
110 }
111#undef TEXTID_TO_STRINGID
112
113 if (str.base() == 0) return STR_EMPTY;
114
115 Debug(grf, 0, "Unknown StringID 0x{:04X} remapped to STR_EMPTY. Please open a Feature Request if you need it", str);
116
117 return STR_EMPTY;
118}
119
128{
129 if (IsInsideMM(str.base(), 0xD800, 0x10000)) {
130 /* General text provided by NewGRF.
131 * In the specs this is called the 0xDCxx range (misc persistent texts),
132 * but we meanwhile extended the range to 0xD800-0xFFFF.
133 * Note: We are not involved in the "persistent" business, since we do not store
134 * any NewGRF strings in savegames. */
135 return GetGRFStringID(grfid, str);
136 } else if (IsInsideMM(str.base(), 0xD000, 0xD800)) {
137 /* Callback text provided by NewGRF.
138 * In the specs this is called the 0xD0xx range (misc graphics texts).
139 * These texts can be returned by various callbacks.
140 *
141 * Due to how TTDP implements the GRF-local- to global-textid translation
142 * texts included via 0x80 or 0x81 control codes have to add 0x400 to the textid.
143 * We do not care about that difference and just mask out the 0x400 bit.
144 */
145 str = GRFStringID(str.base() & ~0x400);
146 return GetGRFStringID(grfid, str);
147 } else {
148 /* The NewGRF wants to include/reference an original TTD string.
149 * Try our best to find an equivalent one. */
151 }
152}
153
158{
160 it.func(MapGRFStringID(it.grfid, it.source));
161 }
163}
Functions related to debugging.
#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.
Base for the NewGRF implementation.
NewGRF internal processing state.
void AddStringForMapping(GRFStringID source, std::function< void(StringID)> &&func)
Record a static StringID for getting translated later.
StringID MapGRFStringID(GrfID grfid, GRFStringID str)
Used when setting an object's property to map to the GRF's strings while taking in consideration the ...
static std::vector< StringIDMapping > _string_to_grf_mapping
Strings to be mapped during load.
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(GrfID grfid, GRFStringID stringid)
Returns the index for this stringid associated with its grfID.
Header of Action 04 "universal holder" structure and functions.
Header of Action 04 "universal holder" structure.
StrongType::Typedef< uint32_t, struct GRFStringIDTag, StrongType::Compare, StrongType::Integer > GRFStringID
Type for GRF-internal string IDs.
uint32_t GrfID
The unique identifier of a NewGRF.
Definition newgrf_type.h:15
A number of safeguards to prevent using unsafe methods.
Definition of base types and functions in a cross-platform compatible way.
Types related to strings.
uint32_t StringID
Numeric value that represents a string, independent of the selected language.
Information for mapping static StringIDs.
std::function< void(StringID)> func
Function for mapping result.
GrfID grfid
Source NewGRF.
GRFStringID source
Source grf-local GRFStringID.