Rev 56 | Rev 136 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line | 
|---|---|---|---|
| 1 | pmbaty | 1 | // localizedtexts.cpp | 
| 2 | |||
| 3 | #include "common.h" | ||
| 4 | |||
| 5 | |||
| 59 | pmbaty | 6 | void LocalizedTexts_Init (void) | 
| 1 | pmbaty | 7 | { | 
| 59 | pmbaty | 8 |    // this function opens and parses the INI files containing the localized texts and fills the | 
| 9 |    // global language_t structure. | ||
| 1 | pmbaty | 10 | |
| 59 | pmbaty | 11 | static wchar_t lngfile_pattern[MAX_PATH]; | 
| 11 | pmbaty | 12 | static wchar_t lngfile_pathname[MAX_PATH]; | 
| 1 | pmbaty | 13 | void *inifile; | 
| 14 | text_t *text; | ||
| 15 | int text_index; | ||
| 16 | wchar_t *id_string; | ||
| 17 | wchar_t *filter_char; | ||
| 59 | pmbaty | 18 |    WIN32_FIND_DATA wfd; | 
| 19 |    HANDLE hFind; | ||
| 1 | pmbaty | 20 | |
| 59 | pmbaty | 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); | ||
| 11 | pmbaty | 32 | |
| 59 | pmbaty | 33 |          // consistency check (FIXME: this should never happen) | 
| 34 | if (inifile == NULL) | ||
| 35 | continue; | ||
| 1 | pmbaty | 36 | |
| 59 | pmbaty | 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); | ||
| 1 | pmbaty | 39 | |
| 59 | pmbaty | 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); | ||
| 1 | pmbaty | 43 | |
| 59 | pmbaty | 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 | ||
| 1 | pmbaty | 48 | |
| 59 | pmbaty | 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 |             } | ||
| 1 | pmbaty | 55 | |
| 59 | pmbaty | 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 | ||
| 1 | pmbaty | 60 | |
| 59 | pmbaty | 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 |          } | ||
| 1 | pmbaty | 69 | |
| 59 | pmbaty | 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 | ||
| 1 | pmbaty | 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 | |||
| 59 | pmbaty | 92 | int language_index; | 
| 1 | pmbaty | 93 | int text_index; | 
| 94 | |||
| 95 |    // cycle through all the localized texts and free their mallocated space | ||
| 59 | pmbaty | 96 | for (language_index = 0; language_index < language_count; language_index++) | 
| 1 | pmbaty | 97 |    { | 
| 59 | pmbaty | 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 | ||
| 1 | pmbaty | 105 |    } | 
| 59 | pmbaty | 106 | SAFE_free ((void **) &languages); // free the languages array themselves | 
| 107 | language_count = 0; // and reset the languages count | ||
| 1 | pmbaty | 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 | |||
| 59 | pmbaty | 117 | language_t *language; | 
| 1 | pmbaty | 118 | int text_index; | 
| 119 | |||
| 59 | pmbaty | 120 | language = &languages[language_id]; // quick access to language | 
| 121 | |||
| 1 | pmbaty | 122 |    // cycle through all the localized texts and find the one we want | 
| 123 |    // NOTE: case-insensitive comparison mandatory, for dictionary entries are lowercase. | ||
| 59 | pmbaty | 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 | ||
| 1 | pmbaty | 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 | } |