Функция loadPOFile() представляет из себя функцию заполняющую ассоциативный массив std::map<std::string, std::string> строками из PO файла в формате msgid = msgstr. Для этого в начале мы определяем переменную mapping являющуюся этим ассоциативным массивом. Проверяем переданный SDL_RWops на то, что он не нулевой указатель. если все же нулевой, просто возвращаем mapping. Далее определяются 6 переменных, манипулируя которыми из PO файла собирается ассоциативный массив. Строковые msgid и msgstr это то, чем мы заполняем массив. Две переменные выставленные в false это булевы переменные msgidMode и msgstrMode, помогающие контролировать поток выполнения внутри функции и заполнения массива в соответствии с тем какой режим будет активен. Целочисленная переменная lineNum указывает на номер строки в разбираемом PO файле. И последняя булева перемена bFinished используется как флаг прекращения бесконечного цикла разбора. Ниже идет этот самый цикл разбора. Сначала производится инкремент lineNum, потому как мы не можем иметь нулевую строку. Потом определяются ещё две переменные одна получения результирующей строки - completeLine, вторая для временного хранения символа строки, которую мы читаем побайтно за раз из SDL_RWops - tmp. А далее идет ещё один бесконечный цикл, в котором мы пытаемся заполнить completeLine. После того как мы заполнили completeLine мы пытается найти в ней то место которое начинается не с табуляции. Если такого места нет или позиция на которую указывает это место это символ # , то мы переходим к началу цикла потому что то, что мы нашли это либо пустая строка, либо комментарий. Далее после того как мы присвоили эту позицию lineStart, мы можем начать заполнять массив. Берем подстроку в completeLine начиная от lineStart вперед на 5 символов и сравниваем ее cо строкой "msgid", если мы и правда наткнулись на msgid, проверяем выставлен ли msgidMode в true, если и это так записываем лог. Если же msgidMode не true проверяем msgstrMode. Если последний в true это значит что мы находимся на следующей паре "msgid + msgstr" и следовательно пора записать в массив значение msgstr для его msgid, об этом нам так же подсказывает комментарий к коду записи. После обновляем переменные msgid и msgstr пустыми строками и выставляем msgstrMode в false. Возвращаясь назад к потому до того момента когда бы проверяем msgstrMode, если он оказывается false, но при этом msgid == true, то это означает что мы находимся на той стадии разбора пары "msgid + msgstr", когда мы ещё не дошли до "msgstr," но уже должны прочитать "msgid", что мы и делаем таким кодом:
Локализация может дело и третье, но если вы в принципе планируете переводить игру на другие языки в хоть сколько-то обозримом будущем (неважно каким способом), то этим лучше в любом случае озадачиться заранее, на этапе написания кода. Потому что потом это все перелопачивать и вмещать невмещаемое в строгие рамки отнимет в три раза больше времени и нервов, а также негативно скажется на качестве продукта, планируемого на другие рынки.
Могу согласиться лишь в том, что всё индивидуально. Тот же gettext тем и хорош, что интегрируется в код очень просто, и ничего особо "перелопачивать" не надо. С оговоркой на то, что под локализацией понимается перевод текстовой информации. Со звуком конечно всё намного сложнее. Вообще в принципе локализация довольно объемная и непростая тема... я не хотел создать впечатление, что это просто, а лишь показал как это решали создатели ремейка и на мой взгляд это достаточно интересный подход.
Комментарий недоступен
С текстом все относительно просто в этом вы совершенно правы. Сложности возникают тогда, когда вы например хотите чтобы локализованный звук попадал в мимику анимации + субтитры не отставали от этого дела + желательно чтобы все это динамически подгонялось при просадках в fps, но так чтобы это было незаметно на слух или глаз (как пример достаточно сложной реализации механизма локализации в игре). Не говоря уже действительно о сложности перевода и о том что фраза на одном языке может быть более короткой и лаконичной чем на другом и наоборот. И это все помимо такой вкусовщины, как "этот голос не подходит к этому персонажу". В общем-то проблем достаточно.