1 #include "GameRes.h"
2
3 #include <locale.h>
4 #include <stdexcept>
5
6 #include "sgp/FileMan.h"
7
8 #include "Directories.h"
9 #include "Multi_Language_Graphic_Utils.h"
10 #include "Text.h"
11 #include "TranslationTable.h"
12 #include "GameState.h"
13 #include "EncodingCorrectors.h"
14
15 #include "Logger.h"
16
17 extern LanguageRes g_LanguageResDutch;
18 extern LanguageRes g_LanguageResEnglish;
19 extern LanguageRes g_LanguageResFrench;
20 extern LanguageRes g_LanguageResGerman;
21 extern LanguageRes g_LanguageResItalian;
22 extern LanguageRes g_LanguageResPolish;
23 extern LanguageRes g_LanguageResRussian;
24 extern LanguageRes g_LanguageResRussianGold;
25
26
27 /** Game version. */
28 static GameVersion s_gameVersion = GameVersion::ENGLISH;
29
30 /** Current language resources. */
31 const LanguageRes* g_langRes = &g_LanguageResEnglish;
32
33 /** Character->Glyph translation table for the current language. */
34 unsigned char const *TranslationTable = g_en_TranslationTable->m_table;
35
36
getZeroGlyphChar()37 char32_t getZeroGlyphChar()
38 {
39 if(s_gameVersion == GameVersion::RUSSIAN)
40 {
41 return U' ';
42 }
43 else
44 {
45 return U'A';
46 }
47 }
48
49
50 /** Set language resources. */
setResources(const LanguageRes * langRes,const CTranslationTable * translationTable)51 static void setResources(const LanguageRes* langRes, const CTranslationTable *translationTable)
52 {
53 g_langRes = langRes;
54 TranslationTable = translationTable->m_table;
55 }
56
57
58 /** Choose game version. */
setGameVersion(GameVersion ver)59 void setGameVersion(GameVersion ver)
60 {
61 s_gameVersion = ver;
62 switch(s_gameVersion)
63 {
64 case GameVersion::DUTCH: setResources(&g_LanguageResDutch, g_en_TranslationTable ); break;
65 case GameVersion::ENGLISH: setResources(&g_LanguageResEnglish, g_en_TranslationTable ); break;
66 case GameVersion::FRENCH: setResources(&g_LanguageResFrench, g_fr_TranslationTable ); break;
67 case GameVersion::GERMAN: setResources(&g_LanguageResGerman, g_en_TranslationTable ); break;
68 case GameVersion::ITALIAN: setResources(&g_LanguageResItalian, g_en_TranslationTable ); break;
69 case GameVersion::POLISH: setResources(&g_LanguageResPolish, g_en_TranslationTable ); break;
70 case GameVersion::RUSSIAN: setResources(&g_LanguageResRussian, g_rus_TranslationTable ); break;
71 case GameVersion::RUSSIAN_GOLD: setResources(&g_LanguageResRussianGold, g_rusGold_TranslationTable); break;
72 default:
73 {
74 SLOGW("Unknown version. Using ENGLISH by defaul");
75 s_gameVersion = GameVersion::ENGLISH;
76 setResources(&g_LanguageResEnglish, g_en_TranslationTable);
77 }
78 }
79 }
80
81
82 /** Check if this is English version of the game. */
isEnglishVersion()83 bool isEnglishVersion()
84 {
85 return s_gameVersion == GameVersion::ENGLISH;
86 }
87
88
89 /** Check if this is German version of the game. */
isGermanVersion()90 bool isGermanVersion()
91 {
92 return s_gameVersion == GameVersion::GERMAN;
93 }
94
95
96 /** Check if this is Polish version of the game. */
isPolishVersion()97 bool isPolishVersion()
98 {
99 return s_gameVersion == GameVersion::POLISH;
100 }
101
102
103 /** Check if this is Russian version of the game. */
isRussianVersion()104 bool isRussianVersion()
105 {
106 return s_gameVersion == GameVersion::RUSSIAN;
107 }
108
109
110 /** Check if this is Russian GOLD version of the game. */
isRussianGoldVersion()111 bool isRussianGoldVersion()
112 {
113 return s_gameVersion == GameVersion::RUSSIAN_GOLD;
114 }
115
116
117 /**
118 * Get encoding corrector for strings in data files.
119 * @return NULL when no encoding corrector is required */
getDataFilesEncodingCorrector()120 const IEncodingCorrector* getDataFilesEncodingCorrector()
121 {
122 static RussianEncodingCorrector s_russianFixer;
123 if(isRussianVersion() || isRussianGoldVersion())
124 {
125 return &s_russianFixer;
126 }
127 return NULL;
128 }
129
130 /** Get major map version. */
getMajorMapVersion()131 FLOAT getMajorMapVersion()
132 {
133 // Don't mess with this value, unless you want to force update all maps in the game!
134 return (s_gameVersion == GameVersion::RUSSIAN) ? 6.00 : 5.00;
135 }
136
137 /** Get list of resource libraries. */
GetResourceLibraries(const ST::string & dataDir)138 std::vector<ST::string> GetResourceLibraries(const ST::string &dataDir)
139 {
140 std::vector<ST::string> libraries = FindFilesInDir(dataDir, "slf", true, true);
141
142 // for (int i = 0; i < libraries.size(); i++)
143 // {
144 // SLOGW("%s", libraries[i].c_str());
145 // }
146
147 return libraries;
148 }
149
150
151 #define STI(LNG, x) LNG "/" x "_" LNG ".sti"
152 #define PCX(LNG, x) LNG "/" x "_" LNG ".pcx"
153
154
GetMLGFilename(MultiLanguageGraphic const id)155 char const* GetMLGFilename(MultiLanguageGraphic const id)
156 {
157 if((s_gameVersion == GameVersion::ENGLISH) || (s_gameVersion == GameVersion::FRENCH) || (s_gameVersion == GameVersion::RUSSIAN_GOLD))
158 {
159 switch (id)
160 {
161 case MLG_AIMSYMBOL: return LAPTOPDIR "/aimsymbol.sti";
162 case MLG_BOBBYNAME: return LAPTOPDIR "/bobbyname.sti";
163 case MLG_BOBBYRAYAD21: return LAPTOPDIR "/bobbyrayad_21.sti";
164 case MLG_BOBBYRAYLINK: return LAPTOPDIR "/bobbyraylink.sti";
165 case MLG_CLOSED: return LAPTOPDIR "/closed.sti";
166 case MLG_CONFIRMORDER: return LAPTOPDIR "/confirmorder.sti";
167 case MLG_DESKTOP: return LAPTOPDIR "/desktop.pcx";
168 case MLG_FUNERALAD9: return LAPTOPDIR "/funeralad_9.sti";
169 case MLG_GOLDPIECEBUTTONS: return INTERFACEDIR "/goldpiecebuttons.sti";
170 case MLG_HISTORY: return LAPTOPDIR "/history.sti";
171 case MLG_IMPSYMBOL: return LAPTOPDIR "/impsymbol.sti";
172 case MLG_INSURANCEAD10: return LAPTOPDIR "/insurancead_10.sti";
173 case MLG_INSURANCELINK: return LAPTOPDIR "/insurancelink.sti";
174 case MLG_INSURANCETITLE: return LAPTOPDIR "/largetitle.sti";
175 case MLG_LARGEFLORISTSYMBOL: return LAPTOPDIR "/largesymbol.sti";
176 case MLG_LOADSAVEHEADER: return INTERFACEDIR "/loadscreenaddons.sti";
177 case MLG_MCGILLICUTTYS: return LAPTOPDIR "/mcgillicuttys.sti";
178 case MLG_MORTUARY: return LAPTOPDIR "/mortuary.sti";
179 case MLG_MORTUARYLINK: return LAPTOPDIR "/mortuarylink.sti";
180 case MLG_OPTIONHEADER: return INTERFACEDIR "/optionscreenaddons.sti";
181 case MLG_ORDERGRID: return LAPTOPDIR "/ordergrid.sti";
182 case MLG_PREBATTLEPANEL: return INTERFACEDIR "/prebattlepanel.sti";
183 case MLG_SMALLFLORISTSYMBOL: return LAPTOPDIR "/smallsymbol.sti";
184 case MLG_SMALLTITLE: return LAPTOPDIR "/smalltitle.sti";
185 case MLG_SPLASH: return INTERFACEDIR "/splash.sti";
186 case MLG_STATSBOX: return LAPTOPDIR "/statsbox.sti";
187 case MLG_STOREPLAQUE: return LAPTOPDIR "/bobbystoreplaque.sti";
188 case MLG_TITLETEXT: return LOADSCREENSDIR "/titletext.sti";
189 case MLG_TOALUMNI: return LAPTOPDIR "/toalumni.sti";
190 case MLG_TOMUGSHOTS: return LAPTOPDIR "/tomugshots.sti";
191 case MLG_TOSTATS: return LAPTOPDIR "/tostats.sti";
192 case MLG_WARNING: return LAPTOPDIR "/warning.sti";
193 case MLG_YOURAD13: return LAPTOPDIR "/yourad_13.sti";
194 default:
195 break;
196 }
197 }
198 else if(s_gameVersion == GameVersion::GERMAN)
199 {
200 switch (id)
201 {
202 case MLG_AIMSYMBOL: return LAPTOPDIR "/aimsymbol.sti"; // Same graphic (no translation needed)
203 case MLG_BOBBYNAME: return LAPTOPDIR "/bobbyname.sti"; // Same graphic (no translation needed)
204 case MLG_BOBBYRAYAD21: return LAPTOPDIR "/bobbyrayad_21.sti"; // Same graphic (no translation needed)
205 case MLG_BOBBYRAYLINK: return "german" "/bobbyraylink_german.sti";
206 case MLG_CLOSED: return "german" "/closed_german.sti";
207 case MLG_CONFIRMORDER: return "german" "/confirmorder_german.sti";
208 case MLG_DESKTOP: return "german" "/desktop_german.pcx";
209 case MLG_FUNERALAD9: return "german" "/funeralad_12_german.sti";
210 case MLG_GOLDPIECEBUTTONS: return "german" "/goldpiecebuttons_german.sti";
211 case MLG_HISTORY: return "german" "/history_german.sti";
212 case MLG_IMPSYMBOL: return "german" "/impsymbol_german.sti";
213 case MLG_INSURANCEAD10: return "german" "/insurancead_10_german.sti";
214 case MLG_INSURANCELINK: return "german" "/insurancelink_german.sti";
215 case MLG_INSURANCETITLE: return "german" "/largetitle_german.sti";
216 case MLG_LARGEFLORISTSYMBOL: return "german" "/largesymbol_german.sti";
217 case MLG_LOADSAVEHEADER: return "german" "/loadscreenaddons_german.sti";
218 case MLG_MCGILLICUTTYS: return "german" "/mcgillicuttys_german.sti";
219 case MLG_MORTUARY: return "german" "/mortuary_german.sti";
220 case MLG_MORTUARYLINK: return "german" "/mortuarylink_german.sti";
221 case MLG_OPTIONHEADER: return "german" "/optionscreenaddons_german.sti";
222 case MLG_ORDERGRID: return LAPTOPDIR "/ordergrid.sti"; // Same file
223 case MLG_PREBATTLEPANEL: return "german" "/prebattlepanel_german.sti";
224 case MLG_SMALLFLORISTSYMBOL: return "german" "/smallsymbol_german.sti";
225 case MLG_SMALLTITLE: return "german" "/smalltitle_german.sti";
226 case MLG_SPLASH: return "german" "/splash_german.sti";
227 case MLG_STATSBOX: return LAPTOPDIR "/statsbox.sti"; // Same file
228 case MLG_STOREPLAQUE: return "german" "/storeplaque_german.sti";
229 case MLG_TITLETEXT: return "german" "/titletext_german.sti";
230 case MLG_TOALUMNI: return "german" "/toalumni_german.sti";
231 case MLG_TOMUGSHOTS: return "german" "/tomugshots_german.sti";
232 case MLG_TOSTATS: return "german" "/tostats_german.sti";
233 case MLG_WARNING: return "german" "/warning_german.sti";
234 case MLG_YOURAD13: return "german" "/yourad_13_german.sti";
235 default:
236 break;
237 }
238 }
239 else if(s_gameVersion == GameVersion::DUTCH)
240 {
241 switch (id)
242 {
243 case MLG_AIMSYMBOL: return STI("dutch", "aimsymbol");
244 case MLG_BOBBYNAME: return STI("dutch", "bobbyname");
245 case MLG_BOBBYRAYAD21: return STI("dutch", "bobbyrayad_21");
246 case MLG_BOBBYRAYLINK: return STI("dutch", "bobbyraylink");
247 case MLG_CLOSED: return STI("dutch", "closed");
248 case MLG_CONFIRMORDER: return STI("dutch", "confirmorder");
249 case MLG_DESKTOP: return PCX("dutch", "desktop");
250 case MLG_FUNERALAD9: return STI("dutch", "funeralad_9");
251 case MLG_GOLDPIECEBUTTONS: return STI("dutch", "goldpiecebuttons");
252 case MLG_HISTORY: return STI("dutch", "history");
253 case MLG_IMPSYMBOL: return STI("dutch", "impsymbol");
254 case MLG_INSURANCEAD10: return STI("dutch", "insurancead_10");
255 case MLG_INSURANCELINK: return STI("dutch", "insurancelink");
256 case MLG_INSURANCETITLE: return STI("dutch", "largetitle");
257 case MLG_LARGEFLORISTSYMBOL: return STI("dutch", "largesymbol");
258 case MLG_LOADSAVEHEADER: return STI("dutch", "loadscreenaddons");
259 case MLG_MCGILLICUTTYS: return STI("dutch", "mcgillicuttys");
260 case MLG_MORTUARY: return STI("dutch", "mortuary");
261 case MLG_MORTUARYLINK: return STI("dutch", "mortuarylink");
262 case MLG_OPTIONHEADER: return STI("dutch", "optionscreenaddons");
263 case MLG_ORDERGRID: return STI("dutch", "ordergrid");
264 case MLG_PREBATTLEPANEL: return STI("dutch", "prebattlepanel");
265 case MLG_SMALLFLORISTSYMBOL: return STI("dutch", "smallsymbol");
266 case MLG_SMALLTITLE: return STI("dutch", "smalltitle");
267 case MLG_SPLASH: return STI("dutch", "splash");
268 case MLG_STATSBOX: return STI("dutch", "statsbox");
269 case MLG_STOREPLAQUE: return STI("dutch", "storeplaque");
270 case MLG_TITLETEXT: return STI("dutch", "titletext");
271 case MLG_TOALUMNI: return STI("dutch", "toalumni");
272 case MLG_TOMUGSHOTS: return STI("dutch", "tomugshots");
273 case MLG_TOSTATS: return STI("dutch", "tostats");
274 case MLG_WARNING: return STI("dutch", "warning");
275 case MLG_YOURAD13: return STI("dutch", "yourad_13");
276 default:
277 break;
278 }
279 }
280 else if(s_gameVersion == GameVersion::ITALIAN)
281 {
282 switch (id)
283 {
284 case MLG_AIMSYMBOL: return STI("italian", "aimsymbol");
285 case MLG_BOBBYNAME: return STI("italian", "bobbyname");
286 case MLG_BOBBYRAYAD21: return STI("italian", "bobbyrayad_21");
287 case MLG_BOBBYRAYLINK: return STI("italian", "bobbyraylink");
288 case MLG_CLOSED: return STI("italian", "closed");
289 case MLG_CONFIRMORDER: return STI("italian", "confirmorder");
290 case MLG_DESKTOP: return PCX("italian", "desktop");
291 case MLG_FUNERALAD9: return STI("italian", "funeralad_9");
292 case MLG_GOLDPIECEBUTTONS: return STI("italian", "goldpiecebuttons");
293 case MLG_HISTORY: return STI("italian", "history");
294 case MLG_IMPSYMBOL: return STI("italian", "impsymbol");
295 case MLG_INSURANCEAD10: return STI("italian", "insurancead_10");
296 case MLG_INSURANCELINK: return STI("italian", "insurancelink");
297 case MLG_INSURANCETITLE: return STI("italian", "largetitle");
298 case MLG_LARGEFLORISTSYMBOL: return STI("italian", "largesymbol");
299 case MLG_LOADSAVEHEADER: return STI("italian", "loadscreenaddons");
300 case MLG_MCGILLICUTTYS: return STI("italian", "mcgillicuttys");
301 case MLG_MORTUARY: return STI("italian", "mortuary");
302 case MLG_MORTUARYLINK: return STI("italian", "mortuarylink");
303 case MLG_OPTIONHEADER: return STI("italian", "optionscreenaddons");
304 case MLG_ORDERGRID: return STI("italian", "ordergrid");
305 case MLG_PREBATTLEPANEL: return STI("italian", "prebattlepanel");
306 case MLG_SMALLFLORISTSYMBOL: return STI("italian", "smallsymbol");
307 case MLG_SMALLTITLE: return STI("italian", "smalltitle");
308 case MLG_SPLASH: return STI("italian", "splash");
309 case MLG_STATSBOX: return STI("italian", "statsbox");
310 case MLG_STOREPLAQUE: return STI("italian", "storeplaque");
311 case MLG_TITLETEXT: return STI("italian", "titletext");
312 case MLG_TOALUMNI: return STI("italian", "toalumni");
313 case MLG_TOMUGSHOTS: return STI("italian", "tomugshots");
314 case MLG_TOSTATS: return STI("italian", "tostats");
315 case MLG_WARNING: return STI("italian", "warning");
316 case MLG_YOURAD13: return STI("italian", "yourad_13");
317 default:
318 break;
319 }
320 }
321 else if(s_gameVersion == GameVersion::POLISH)
322 {
323 switch (id)
324 {
325 case MLG_AIMSYMBOL: return STI("polish", "aimsymbol");
326 case MLG_BOBBYNAME: return STI("polish", "bobbyname");
327 case MLG_BOBBYRAYAD21: return STI("polish", "bobbyrayad_21");
328 case MLG_BOBBYRAYLINK: return STI("polish", "bobbyraylink");
329 case MLG_CLOSED: return STI("polish", "closed");
330 case MLG_CONFIRMORDER: return STI("polish", "confirmorder");
331 case MLG_DESKTOP: return PCX("polish", "desktop");
332 case MLG_FUNERALAD9: return STI("polish", "funeralad_9");
333 case MLG_GOLDPIECEBUTTONS: return STI("polish", "goldpiecebuttons");
334 case MLG_HISTORY: return STI("polish", "history");
335 case MLG_IMPSYMBOL: return STI("polish", "impsymbol");
336 case MLG_INSURANCEAD10: return STI("polish", "insurancead_10");
337 case MLG_INSURANCELINK: return STI("polish", "insurancelink");
338 case MLG_INSURANCETITLE: return STI("polish", "largetitle");
339 case MLG_LARGEFLORISTSYMBOL: return STI("polish", "largesymbol");
340 case MLG_LOADSAVEHEADER: return STI("polish", "loadscreenaddons");
341 case MLG_MCGILLICUTTYS: return STI("polish", "mcgillicuttys");
342 case MLG_MORTUARY: return STI("polish", "mortuary");
343 case MLG_MORTUARYLINK: return STI("polish", "mortuarylink");
344 case MLG_OPTIONHEADER: return STI("polish", "optionscreenaddons");
345 case MLG_ORDERGRID: return STI("polish", "ordergrid");
346 case MLG_PREBATTLEPANEL: return STI("polish", "prebattlepanel");
347 case MLG_SMALLFLORISTSYMBOL: return STI("polish", "smallsymbol");
348 case MLG_SMALLTITLE: return STI("polish", "smalltitle");
349 case MLG_SPLASH: return STI("polish", "splash");
350 case MLG_STATSBOX: return STI("polish", "statsbox");
351 case MLG_STOREPLAQUE: return STI("polish", "storeplaque");
352 case MLG_TITLETEXT: return STI("polish", "titletext");
353 case MLG_TOALUMNI: return STI("polish", "toalumni");
354 case MLG_TOMUGSHOTS: return STI("polish", "tomugshots");
355 case MLG_TOSTATS: return STI("polish", "tostats");
356 case MLG_WARNING: return STI("polish", "warning");
357 case MLG_YOURAD13: return STI("polish", "yourad_13");
358 default:
359 break;
360 }
361 }
362 else if(s_gameVersion == GameVersion::RUSSIAN)
363 {
364 switch (id)
365 {
366 case MLG_AIMSYMBOL: return STI("russian", "aimsymbol");
367 case MLG_BOBBYNAME: return STI("russian", "bobbyname");
368 case MLG_BOBBYRAYAD21: return STI("russian", "bobbyrayad_21");
369 case MLG_BOBBYRAYLINK: return STI("russian", "bobbyraylink");
370 case MLG_CLOSED: return STI("russian", "closed");
371 case MLG_CONFIRMORDER: return STI("russian", "confirmorder");
372 case MLG_DESKTOP: return PCX("russian", "desktop");
373 case MLG_FUNERALAD9: return STI("russian", "funeralad_9");
374 case MLG_GOLDPIECEBUTTONS: return STI("russian", "goldpiecebuttons");
375 case MLG_HISTORY: return STI("russian", "history");
376 case MLG_IMPSYMBOL: return STI("russian", "impsymbol");
377 case MLG_INSURANCEAD10: return STI("russian", "insurancead_10");
378 case MLG_INSURANCELINK: return STI("russian", "insurancelink");
379 case MLG_INSURANCETITLE: return STI("russian", "largetitle");
380 case MLG_LARGEFLORISTSYMBOL: return STI("russian", "largesymbol");
381 case MLG_LOADSAVEHEADER: return STI("russian", "loadscreenaddons");
382 case MLG_MCGILLICUTTYS: return STI("russian", "mcgillicuttys");
383 case MLG_MORTUARY: return STI("russian", "mortuary");
384 case MLG_MORTUARYLINK: return STI("russian", "mortuarylink");
385 case MLG_OPTIONHEADER: return STI("russian", "optionscreenaddons");
386 case MLG_ORDERGRID: return STI("russian", "ordergrid");
387 case MLG_PREBATTLEPANEL: return STI("russian", "prebattlepanel");
388 case MLG_SMALLFLORISTSYMBOL: return STI("russian", "smallsymbol");
389 case MLG_SMALLTITLE: return STI("russian", "smalltitle");
390 case MLG_SPLASH: return STI("russian", "splash");
391 case MLG_STATSBOX: return STI("russian", "statsbox");
392 case MLG_STOREPLAQUE: return STI("russian", "bobbystoreplaque");
393 case MLG_TITLETEXT: return STI("russian", "titletext");
394 case MLG_TOALUMNI: return STI("russian", "toalumni");
395 case MLG_TOMUGSHOTS: return STI("russian", "tomugshots");
396 case MLG_TOSTATS: return STI("russian", "tostats");
397 case MLG_WARNING: return STI("russian", "warning");
398 case MLG_YOURAD13: return STI("russian", "yourad_13");
399 default:
400 break;
401 }
402 }
403
404 throw std::runtime_error(ST::format("Multilanguage resource {} is not found", id).to_std_string());
405 }
406
getStringEncType()407 STRING_ENC_TYPE getStringEncType()
408 {
409 if(isRussianVersion() || isRussianGoldVersion())
410 {
411 return SE_RUSSIAN;
412 }
413 else if(isPolishVersion())
414 {
415 return SE_POLISH;
416 }
417 else if(isEnglishVersion())
418 {
419 return SE_ENGLISH;
420 }
421 return SE_NORMAL;
422 }
423