Автор Тема: Русификация Dwarf Fortress  (Прочитано 632921 раз)

0 Пользователей и 10 Гостей просматривают эту тему.

Оффлайн mialax

  • Постоялец
  • ***
  • Сообщений: 117
    • Просмотр профиля
Re: Русификация Dwarf Fortress
« Ответ #1095 : 29 Марта 2013, 09:03:02 »
mialax возможно ли сделать инструмент для превода с использованием скриптового языка(Питон, Луа) чтобы исключить процесс бесконечной компиляции в процессе перевода ? или это повлияет на производительность игры ?
...Или сделать подхват библиотекой списка замен из внешнего текстового файла вроде trans.txt?
Словарь замен во внешнем текстовом файле сделать недолго. Просто я не хотел загонять людей в рамки. Народ высказывал желание проводить анализ уже переведённого текста, с тем чтобы сделать перевод более красивым.
Так что я сделал болванку (ChangeText), чтобы людям не пришлось мучиться с исходниками sdl_ttf. А дальше уже кто на что горазд. Хоть питон, хоть внешний текстовый файл, хоть хитрый лексический и семантический анализатор.

Если с программированием плохо, то могу написать вариант библиотеки ChangeText.dll где будет производится замена по словарю во внешнем текстовом файле.

PS: Набросал по быстрому. Словарь замен берёт из words.txt
http://www.dfwk.ru/images/8/81/For_Arex.zip
« Последнее редактирование: 29 Марта 2013, 10:41:18 от mialax »

Оффлайн Arex

  • Старожил
  • ****
  • Сообщений: 407
  • Ленивый дварфовод
    • Просмотр профиля
    • На викидварфии
Re: Русификация Dwarf Fortress
« Ответ #1096 : 30 Марта 2013, 09:35:24 »
C++ я никогда не изучал. Вот с чем с ходу удалось разобраться (надеюсь, правильно понял):
Спойлер
// ChangeText.cpp: определяет экспортированные функции для приложения DLL.
//

#include "stdafx.h"
#include "ChangeText.h"
#include <stdio.h>
#include <locale>

/////////Вставьте здесь объявление своих переменных//
int LenDict = 0;  //номер строки в словаре (при составлении) и длина словаря
wchar_t Dict[10000][2][80]; //словарь, состоящий из 10000 пар значений оригинал-перевод (по 80 символов в каждой фразе?)
FILE* stream; //контейнер хранения файла замен
char first = 1; //флаг однократного считывания словаря
/////////////////////////////////////////////////////

CHANGETEXT_API wchar_t* ChangeText(wchar_t* inText)
{
wchar_t outText[80];
//////////Вставте здесь свой текст/////////////////
if (first) //проверка флага: выполнялось ли заполнение словаря
{
   first = 0; //меняет значение флага
   setlocale(LC_ALL, "Russian"); //устанавливает новую локализацию
   if( fopen_s( &stream, "words.txt", "r, ccs=UNICODE" ) == 0 ) //загоняет файл "words.txt" в поток обрботки в режиме юникода
   {
  while( fgetws( Dict[LenDict][0], 80, stream ) != NULL)  //считывает 80 символов из файла в строку переводимого значения;
    //исполнять цикл до ошибки или конца файла
  {
  fgetws( Dict[LenDict][1], 80, stream ); //четные строки файла берутся в качестве перевода

  Dict[LenDict][0][wcslen(Dict[LenDict][0]) - 1] = 0; //удаляется символ новой строки в конце
  Dict[LenDict][1][wcslen(Dict[LenDict][1]) - 1] = 0; //удаляется символ новой строки в конце
  LenDict++;
  }
  fclose( stream ); //закрыть поток ввода/вывода
   }
}

memset(outText, 0, 80*sizeof(wchar_t)); //заполняет блок памяти outText пустым значением в соответствующем формате
memcpy(outText, inText, wcslen((wchar_t*)inText) * sizeof(wchar_t)); //копирует блок памяти из адреса inText в outText
for (int i = 0; i < LenDict; i++) //для каждой из строк словаря
{
wchar_t* find = wcsstr(outText,Dict[i][0]); //ищет подстроку переводимой фразы в outText (первое совпадение!)
if (find != NULL) //если найдено
{
int pos = (int)(find - outText); //позиция первого символа найденной строки в outText (из разницы указателей)
memcpy(outText + pos + wcslen(Dict[i][1]), outText + pos + wcslen(Dict[i][0]), (wcslen(outText) - pos - wcslen(Dict[i][0]))*2);
outText[wcslen(outText) - wcslen(Dict[i][0]) + wcslen(Dict[i][1])] = 0;
memcpy(outText + pos, Dict[i][1], wcslen(Dict[i][1])*2);
//копирует ??? Короче, тут я запутался, но смысл тот, что заменяет переводимое значение на перевод,
//корректируя адреса в соответствии с длиной строк из словаря
}
}

///////////////////////////////////////////////////
return outText; //возвращает значение после перевода
}
[свернуть]
В связи с этим возникла пара вопросов:
С чем связано ограничение длины строк словаря в 80 символов (если я не ошибаюсь)?
Если в inText несколько раз встречается подстрока Dict[i][0], то переведётся только первое совпадение?

И можно ли еще выложить исходники измененной sdl и sdl_ttf, если не трудно? Хочется разобраться, как это все работает.
« Последнее редактирование: 30 Марта 2013, 09:43:51 от Arex »

Оффлайн insolor

  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 1064
  • Adequate Reverse Engineer
    • Просмотр профиля
Re: Русификация Dwarf Fortress
« Ответ #1097 : 30 Марта 2013, 10:45:54 »
Мне кажется или я слышу крики менеджера?
Тебе показалось.

Оффлайн mialax

  • Постоялец
  • ***
  • Сообщений: 117
    • Просмотр профиля
Re: Русификация Dwarf Fortress
« Ответ #1098 : 30 Марта 2013, 12:10:06 »
Arex, понял правильно. 80 символов взято с потолка и это ограничение можно свободно менять.  (Если привязывать перевод "мысли и предпочтения", то менять по любому придётся).
Переведётся только первое совпадение (я проглядел этот момент). Решить легко.
      if (find != NULL)
      {
                     .......................
                     i--;
      }

Вот изменённые исходники sdl библиотек. Правда разобраться там будет ещё сложнее (также поленился раскомментировать). Да и для компиляции много чего хотят (Потому то я вынес перевод в отдельную библиотеку).
http://www.dfwk.ru/images/e/ef/SDL_ttf-2.0.11_ar.zip
http://www.dfwk.ru/images/1/15/SDL-1.2.15_ar.ZIP

Оффлайн Arex

  • Старожил
  • ****
  • Сообщений: 407
  • Ленивый дварфовод
    • Просмотр профиля
    • На викидварфии
Re: Русификация Dwarf Fortress
« Ответ #1099 : 30 Марта 2013, 13:44:07 »
Переведётся только первое совпадение (я проглядел этот момент). Решить легко.
      if (find != NULL)
      {
                     .......................
                     i--;
      }
Ага, тоже об этом подумал, но проверить пока не получилось: не получается скомпилировать библиотеку. Один раз компиляция прошла, на выходе размер получился 32КБ (против 9 КБ у тебя). Пользуюсь Visual C++ 2010 Express. Раньше VS не пользовался, так что понимания маловато, буду разбираться.

По ходу возник еще вопрос. Раз используются wcsstr и wcslen, разве не надо было добавить #include <string.h> ?

Сейчас пробую, в качестве учебного задания, подключить trans.txt вместо words.txt.

Оффлайн Arex

  • Старожил
  • ****
  • Сообщений: 407
  • Ленивый дварфовод
    • Просмотр профиля
    • На викидварфии
Re: Русификация Dwarf Fortress
« Ответ #1100 : 30 Марта 2013, 16:06:45 »
С компилированием вроде разобрался, была проблема с путями. Единственное, размер по-прежнему почему-то получается 32КБ.

С подключением trans.txt возникли трудности. Код я написал, вроде должно работать.
Спойлер
// ChangeText.cpp: определяет экспортированные функции для приложения DLL.
//

#include "stdafx.h"
#include "ChangeText.h"
#include <stdio.h>
#include <locale>
#include <string.h>

/////////Вставьте здесь объявление своих переменных//
int LenDict = 0;
wchar_t s[256];
wchar_t Dict[10000][2][128];
FILE* stream;
char first = 1;
/////////////////////////////////////////////////////

CHANGETEXT_API wchar_t* ChangeText(wchar_t* inText)
{
wchar_t outText[128];
//////////Вставте здесь свой текст/////////////////
if (first)
{
   first = 0;
   setlocale(LC_ALL, "Russian");
   if( fopen_s( &stream, "trans.txt", "r, ccs=UNICODE" ) == 0 )
   {
while( fgetws( s, 256, stream ) != NULL)
{
int i, d, dlmtr = 0;// dlmtr - порядковый номер разделителя в строке, d - позиция следущего за ним символа
while( dlmtr < 3 )
{
if( dlmtr > 0 ) Dict[LenDict][dlmtr-1][i-d] = s[i];
if( s[i] = '|')
{
if( dlmtr > 0 ) Dict[LenDict][dlmtr-1][i-d] = 0;
d = i + 1;
dlmtr++;
}
i++;
}
LenDict++;
}
  fclose( stream );
   }
}

memset(outText, 0, 128*sizeof(wchar_t));
memcpy(outText, inText, wcslen((wchar_t*)inText) * sizeof(wchar_t));
for (int i = 0; i < LenDict; i++)
{
wchar_t* find = wcsstr(outText,Dict[i][0]);
if (find != NULL)
{
int pos = (int)(find - outText);
memcpy(outText + pos + wcslen(Dict[i][1]), outText + pos + wcslen(Dict[i][0]), (wcslen(outText) - pos - wcslen(Dict[i][0]))*2);
outText[wcslen(outText) - wcslen(Dict[i][0]) + wcslen(Dict[i][1])] = 0;
memcpy(outText + pos, Dict[i][1], wcslen(Dict[i][1])*2);
}
}

///////////////////////////////////////////////////
return outText;
}
[свернуть]
Однако при отладке (и компиляции) возникает ошибка:
Цитировать
Run-Time Check Failure #3 - The variable 'i' is being used without being initialized.

Отчет при компиляции:
Спойлер
1>------ Построение начато: проект: ChangeText, Конфигурация: Debug Win32 ------
1>  ChangeText.cpp
1>d:\projects\changetext\changetext\changetext.cpp(63): warning C4172: возвращение адреса локальной или временной переменной
1>d:\projects\changetext\changetext\changetext.cpp(34): warning C4700: использована неинициализированная локальная переменная "i"
1>  ChangeText.vcxproj -> D:\Projects\ChangeText\Debug\ChangeText.dll
========== Построение: успешно: 1, с ошибками: 0, без изменений: 0, пропущено: 0 ==========
[свернуть]

Что это значит? Инициация вроде проведена.

Оффлайн insolor

  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 1064
  • Adequate Reverse Engineer
    • Просмотр профиля
Re: Русификация Dwarf Fortress
« Ответ #1101 : 30 Марта 2013, 16:17:59 »
Что это значит? Инициация вроде проведена.
Инициализация - присвоение первоначального значения. Если переменную объявить как int i; то она будет просто объявлена, но что в ней лежит неизвестно. Поэтому нужно делать int i = 0; (или что там должно лежать)

Оффлайн Arex

  • Старожил
  • ****
  • Сообщений: 407
  • Ленивый дварфовод
    • Просмотр профиля
    • На викидварфии
Re: Русификация Dwarf Fortress
« Ответ #1102 : 30 Марта 2013, 16:46:10 »
Хм... Я почему-то решил, что int i, d, dlmtr = 0; присваивает значение всем трем переменным, вроде бы я где-то видел подобный код. После разделения на три строки ошибка исчезла.

P.S. Осталось только разобраться, почему же код не работает.  ::)
« Последнее редактирование: 30 Марта 2013, 16:58:18 от Arex »

Оффлайн insolor

  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 1064
  • Adequate Reverse Engineer
    • Просмотр профиля
Re: Русификация Dwarf Fortress
« Ответ #1103 : 30 Марта 2013, 16:52:57 »
Хм... Я почему-то решил, что int i, d, dlmtr = 0; присваивает значение всем трем переменным, вроде бы я где-то видел подобный код. После разделения на три строки ошибка исчезла.
Не верь всему что написано) Даже если написано int * a, b, c; то указателем будет только a.
В твоем случае нужно писать int i=0, d=0, dlmtr=0;

Оффлайн Jesus

  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 1459
  • Баню, удаляю исключительно рекламо-спамеров.
    • Просмотр профиля
Re: Русификация Dwarf Fortress
« Ответ #1104 : 30 Марта 2013, 16:56:58 »
Хм... Я почему-то решил, что int i, d, dlmtr = 0; присваивает значение всем трем переменным, вроде бы я где-то видел подобный код. После разделения на три строки ошибка исчезла.
наверное ты видел что-то похожее i = d = dlmtr = 0;можно как-то так int i, d, dlmtr = i = d = 0; лучше определение одной переменной - одна строка.

Оффлайн Arex

  • Старожил
  • ****
  • Сообщений: 407
  • Ленивый дварфовод
    • Просмотр профиля
    • На викидварфии
Re: Русификация Dwarf Fortress
« Ответ #1105 : 30 Марта 2013, 19:16:53 »
Кстати, при использовании измененной sdl_ttf замечен баг. Если в главном меню нажать Esc, а затем двигать курсор вверх или вниз, значение всех строк будет меняться на Dwarf Fortress Options. Кроме того, довольно часто эта строка остается и после возвращения в главное меню.
А вот где именно: в sdl_ttf или ChangeText содержится ошибка - я не знаю.

Оффлайн Lens

  • Ветеран
  • *****
  • Сообщений: 884
  • Наш мир тьмой побежден или нет..
    • Просмотр профиля
Re: Русификация Dwarf Fortress
« Ответ #1106 : 01 Апреля 2013, 09:42:02 »
В меню, осмотр комнат\строений  "R" сундуки названы тоже как ящики .
Вернемся к нашим зубам и волосам "её  зубы запутаны. Скрин.
А также жир ушел? это как хехе.. тоже что нибудь другое надо. Скрин.
« Последнее редактирование: 01 Апреля 2013, 09:52:04 от Lens »
http://steamcommunity.com/groups/DFrus Русское steam комьюнити.
Шмалим в эльфов, бьём людей, Дуем ром, пиво пьем, Пиво пьем, пьем, пьем, И подделки продаем!
Кто продает?! Мы продаем! Вырезаем - продаем!
Пятнашка ?, эльфачок, Гони в лапу пятачок!
Если с бабками облом - То депо мы разнесем.

Оффлайн insolor

  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 1064
  • Adequate Reverse Engineer
    • Просмотр профиля
Re: Русификация Dwarf Fortress
« Ответ #1107 : 01 Апреля 2013, 09:58:04 »

Оффлайн insolor

  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 1064
  • Adequate Reverse Engineer
    • Просмотр профиля
Re: Русификация Dwarf Fortress
« Ответ #1108 : 01 Апреля 2013, 10:00:05 »
Вернемся к нашим зубам и волосам "её  зубы запутаны. Скрин.
А также жир ушел? это как хехе.. тоже что нибудь другое надо. Скрин.
Снимок любопытный :) Посмотрю, когда будет время

Оффлайн Lens

  • Ветеран
  • *****
  • Сообщений: 884
  • Наш мир тьмой побежден или нет..
    • Просмотр профиля
Re: Русификация Dwarf Fortress
« Ответ #1109 : 01 Апреля 2013, 10:20:16 »
 ХХскелет гоблинаХХ подогнан? Вообще не понимаю о чем это.
http://steamcommunity.com/groups/DFrus Русское steam комьюнити.
Шмалим в эльфов, бьём людей, Дуем ром, пиво пьем, Пиво пьем, пьем, пьем, И подделки продаем!
Кто продает?! Мы продаем! Вырезаем - продаем!
Пятнашка ?, эльфачок, Гони в лапу пятачок!
Если с бабками облом - То депо мы разнесем.