Subversion Repositories Games.Chess Giants

Rev

Rev 56 | Rev 136 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. // localizedtexts.cpp
  2.  
  3. #include "common.h"
  4.  
  5.  
  6. void LocalizedTexts_Init (void)
  7. {
  8.    // this function opens and parses the INI files containing the localized texts and fills the
  9.    // global language_t structure.
  10.  
  11.    static wchar_t lngfile_pattern[MAX_PATH];
  12.    static wchar_t lngfile_pathname[MAX_PATH];
  13.    void *inifile;
  14.    text_t *text;
  15.    int text_index;
  16.    wchar_t *id_string;
  17.    wchar_t *filter_char;
  18.    WIN32_FIND_DATA wfd;
  19.    HANDLE hFind;
  20.  
  21.    language_count = 0;
  22.    swprintf_s (lngfile_pattern, sizeof (lngfile_pattern), L"%s\\data\\languages\\*.ini", app_path); // build the search pattern string out of the path
  23.    hFind = FindFirstFile (lngfile_pattern, &wfd); // initiate search from that point
  24.    if (hFind != INVALID_HANDLE_VALUE)
  25.    {
  26.       // start examining search results...
  27.       do
  28.       {
  29.          // open the INI file
  30.          swprintf_s (lngfile_pathname, WCHAR_SIZEOF (lngfile_pathname), L"%s\\data\\languages\\%s", app_path, wfd.cFileName);
  31.          inifile = INIFile_LoadINIFile (lngfile_pathname);
  32.  
  33.          // consistency check (FIXME: this should never happen)
  34.          if (inifile == NULL)
  35.             continue;
  36.  
  37.          // file successfully opened, reallocate languages structure to hold one language more
  38.          languages = (language_t *) SAFE_realloc (languages, language_count, language_count + 1, sizeof (language_t), false);
  39.  
  40.          // read the number of known localized texts and mallocate enough space for them
  41.          languages[language_count].text_count = INIFile_GetNumberOfEntries (inifile, L"texts");
  42.          languages[language_count].texts = (text_t *) SAFE_malloc (languages[language_count].text_count, sizeof (text_t), true);
  43.  
  44.          // now read all of them
  45.          for (text_index = 0; text_index < languages[language_count].text_count; text_index++)
  46.          {
  47.             text = &languages[language_count].texts[text_index]; // quick access to text
  48.  
  49.             id_string = INIFile_GetEntryName (inifile, L"texts", text_index); // read this entry
  50.             if (id_string == NULL)
  51.             {
  52.                MessageBox (NULL, L"There is an inconsistency in Chess Giants's language file.\n\nPlease reinstall the program to fix the problem.", L"Chess Giants", MB_ICONERROR | MB_OK);
  53.                continue; // consistency check
  54.             }
  55.  
  56.             text->id_string = _wcsdup (id_string); // have a copy of ID string and save it
  57.             text->localized_string = (wchar_t *) SAFE_malloc (65536, sizeof (wchar_t), false); // allocate big space for localized string...
  58.             wcscpy_s (text->localized_string, 65536, INIFile_ReadEntryAsString (inifile, L"texts", text->id_string, text->id_string)); // ... read it...
  59.             text->localized_string = (wchar_t *) SAFE_realloc (text->localized_string, 65536, wcslen (text->localized_string) + 1, sizeof (wchar_t), false); // and resize correctly
  60.  
  61.             // conventionally, all texts whose ID end in "FileFilter" are file filters. Convert them for Windows API.
  62.             // Reminder: INI file key entries are LOWERCASE.
  63.             if (wcsistr (text->id_string, L"FileFilter") != NULL)
  64.             {
  65.                filter_char = text->localized_string; // convert vertical bars into string terminator characters
  66.                while (*filter_char != 0) { if (*filter_char == L'|') *filter_char = 0; filter_char++; }
  67.             }
  68.          }
  69.  
  70.          // close the INI file
  71.          INIFile_FreeINIFile (inifile);
  72.  
  73.          // save the language name (and chop off the trailing ".ini" suffix)
  74.          wcscpy_s (languages[language_count].name, WCHAR_SIZEOF (languages[language_count].name), wfd.cFileName);
  75.          languages[language_count].name[wcslen (languages[language_count].name) - 4] = 0;
  76.  
  77.          language_count++; // we've identified one language more
  78.       } while (FindNextFile (hFind, &wfd)); // ...and don't stop as long as there are files to go
  79.  
  80.       FindClose (hFind); // close the search handle
  81.    }
  82.  
  83.    return; // finished loading texts
  84. }
  85.  
  86.  
  87. void LocalizedTexts_Shutdown (void)
  88. {
  89.    // this function unloads all the contents of the localized texts array, freeing
  90.    // the associated memory space, and resets the text_count variable to zero.
  91.  
  92.    int language_index;
  93.    int text_index;
  94.  
  95.    // cycle through all the localized texts and free their mallocated space
  96.    for (language_index = 0; language_index < language_count; language_index++)
  97.    {
  98.       for (text_index = 0; text_index < languages[language_index].text_count; text_index++)
  99.       {
  100.          SAFE_free ((void **) &languages[language_index].texts[text_index].id_string);
  101.          SAFE_free ((void **) &languages[language_index].texts[text_index].localized_string);
  102.       }
  103.       SAFE_free ((void **) &languages[language_index].texts); // free the texts array themselves
  104.       languages[language_index].text_count = 0; // reset the localized texts count
  105.    }
  106.    SAFE_free ((void **) &languages); // free the languages array themselves
  107.    language_count = 0; // and reset the languages count
  108.  
  109.    return; // finished unloading texts
  110. }
  111.  
  112.  
  113. wchar_t *LocalizedTexts_GetLocalizedTextFor (wchar_t *id_string)
  114. {
  115.    // this function returns the localized text corresponding to a given id string
  116.  
  117.    language_t *language;
  118.    int text_index;
  119.  
  120.    language = &languages[language_id]; // quick access to language
  121.  
  122.    // cycle through all the localized texts and find the one we want
  123.    // NOTE: case-insensitive comparison mandatory, for dictionary entries are lowercase.
  124.    for (text_index = 0; text_index < language->text_count; text_index++)
  125.       if (_wcsicmp (language->texts[text_index].id_string, id_string) == 0)
  126.          return (language->texts[text_index].localized_string); // when found, return a pointer to it
  127.  
  128.    Debug_Log (L"===WARNING: translation missing for string ID [%s]!===\n", id_string);
  129.    return (id_string); // when not found, return the ID string itself
  130. }
  131.