strings_sl.cpp

Go to the documentation of this file.
00001 /* $Id: strings_sl.cpp 22747 2011-08-14 15:23:10Z rubidium $ */
00002 
00003 /*
00004  * This file is part of OpenTTD.
00005  * 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.
00006  * 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.
00007  * 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/>.
00008  */
00009 
00012 #include "../stdafx.h"
00013 #include "../string_func.h"
00014 #include "saveload_internal.h"
00015 
00016 #include "table/strings.h"
00017 
00018 static const int NUM_OLD_STRINGS     = 512; 
00019 static const int LEN_OLD_STRINGS     =  32; 
00020 static const int LEN_OLD_STRINGS_TTO =  24; 
00021 
00027 StringID RemapOldStringID(StringID s)
00028 {
00029   switch (s) {
00030     case 0x0006: return STR_SV_EMPTY;
00031     case 0x7000: return STR_SV_UNNAMED;
00032     case 0x70E4: return SPECSTR_PLAYERNAME_ENGLISH;
00033     case 0x70E9: return SPECSTR_PLAYERNAME_ENGLISH;
00034     case 0x8864: return STR_SV_TRAIN_NAME;
00035     case 0x902B: return STR_SV_ROAD_VEHICLE_NAME;
00036     case 0x9830: return STR_SV_SHIP_NAME;
00037     case 0xA02F: return STR_SV_AIRCRAFT_NAME;
00038 
00039     default:
00040       if (IsInsideMM(s, 0x300F, 0x3030)) {
00041         return s - 0x300F + STR_SV_STNAME;
00042       } else {
00043         return s;
00044       }
00045   }
00046 }
00047 
00049 char *_old_name_array = NULL;
00050 
00058 char *CopyFromOldName(StringID id)
00059 {
00060   /* Is this name an (old) custom name? */
00061   if (GB(id, 11, 5) != 15) return NULL;
00062 
00063   if (IsSavegameVersionBefore(37)) {
00064     /* Allow for expansion when converted to UTF-8. */
00065     char tmp[LEN_OLD_STRINGS * MAX_CHAR_LENGTH];
00066     uint offs = _savegame_type == SGT_TTO ? LEN_OLD_STRINGS_TTO * GB(id, 0, 8) : LEN_OLD_STRINGS * GB(id, 0, 9);
00067     const char *strfrom = &_old_name_array[offs];
00068     char *strto = tmp;
00069 
00070     for (; *strfrom != '\0'; strfrom++) {
00071       WChar c = (byte)*strfrom;
00072 
00073       /* Map from non-ISO8859-15 characters to UTF-8. */
00074       switch (c) {
00075         case 0xA4: c = 0x20AC; break; // Euro
00076         case 0xA6: c = 0x0160; break; // S with caron
00077         case 0xA8: c = 0x0161; break; // s with caron
00078         case 0xB4: c = 0x017D; break; // Z with caron
00079         case 0xB8: c = 0x017E; break; // z with caron
00080         case 0xBC: c = 0x0152; break; // OE ligature
00081         case 0xBD: c = 0x0153; break; // oe ligature
00082         case 0xBE: c = 0x0178; break; // Y with diaresis
00083         default: break;
00084       }
00085 
00086       /* Check character will fit into our buffer. */
00087       if (strto + Utf8CharLen(c) > lastof(tmp)) break;
00088 
00089       strto += Utf8Encode(strto, c);
00090     }
00091 
00092     /* Terminate the new string and copy it back to the name array */
00093     *strto = '\0';
00094 
00095     return strdup(tmp);
00096   } else {
00097     /* Name will already be in UTF-8. */
00098     return strdup(&_old_name_array[LEN_OLD_STRINGS * GB(id, 0, 9)]);
00099   }
00100 }
00101 
00106 void ResetOldNames()
00107 {
00108   free(_old_name_array);
00109   _old_name_array = NULL;
00110 }
00111 
00115 void InitializeOldNames()
00116 {
00117   free(_old_name_array);
00118   _old_name_array = CallocT<char>(NUM_OLD_STRINGS * LEN_OLD_STRINGS); // 200 * 24 would be enough for TTO savegames
00119 }
00120 
00121 static void Load_NAME()
00122 {
00123   int index;
00124 
00125   while ((index = SlIterateArray()) != -1) {
00126     if (index >= NUM_OLD_STRINGS) SlErrorCorrupt("Invalid old name index");
00127     if (SlGetFieldLength() > (uint)LEN_OLD_STRINGS) SlErrorCorrupt("Invalid old name length");
00128 
00129     SlArray(&_old_name_array[LEN_OLD_STRINGS * index], SlGetFieldLength(), SLE_UINT8);
00130     /* Make sure the old name is null terminated */
00131     _old_name_array[LEN_OLD_STRINGS * index + LEN_OLD_STRINGS - 1] = '\0';
00132   }
00133 }
00134 
00135 extern const ChunkHandler _name_chunk_handlers[] = {
00136   { 'NAME', NULL, Load_NAME, NULL, NULL, CH_ARRAY | CH_LAST},
00137 };