Tuesday, September 6, 2016

Локализация. Часть 1

Итак, первая игра переведена, деньги получены равно как и удовлетворение от проделанной работы.
Что меняется после этого?

Медные трубы


После этого начинаешь совершенно по другому смотреть на игры. Как архитектор, который уже не может в полной мере насладиться красотой дома, как дизайнер, который видит рекламный плакат не так как все...так и бедный локализатор, уже совсем по другому смотрит на игру, мысленно уже разбирая её на кусочки.

Лично у меня до сих пор осталась привычка. Установив свежую игру, которую жуть как хочется посмотреть, я не запускаю её. Нет. Я иду в каталог где она записана и смотрю как организованы данные, в чем видео записано, в чем звук, где текстуры, где тексты... Это происходит настолько машинально, что и не задумываешься об этом.

И только после всего этого, запускаешь...

Следующее наблюдение связано с посещением мест где продают диски. Тут медные трубы в первый раз дают вам о себе знать:
- Ты играл в "Вихри враждебные"? (WarWind)
- Нет...
- На, поиграй.. на русском...класс!
И внутри просыпается гордость за содеянное, счастливая улыбка сама наползает на лицо...
Потом продавец пытается вам продать ваш же перевод...
Это серьезно влияет на вашу мотивацию и работу над будущими играми. Причем как в положительную так и в отрицательную сторону.

Как мы работали...

Однако, давайте продолжим и рассмотрим этапы разборки игры.
Для программиста:
- Установить, залезть в каталог посмотреть что где лежит
- Запустить игру, настроить, запомнить какой-нибудь текст, желательно не "New Game", а из самого игрового процесса, идеально кусок какого-нибудь брифинга, или диалога в текстовом виде
- Поиграть немного, чтобы примерно понять: есть ли текст на текстурах, какой звук, сколько его
- Выйти из игры и искать текст, в разных кодировках DOS/WIN/UNICODE и т.д.
- Вырезать текст отдать переводчикам с комментариями
- Искать звук и вырезать его
- Посчитать в минутах продолжительность, сказать менеджеру, пускай думает "а стоит ли оно того?"
- Получив положительный ответ, заниматься расшифровкой звука по необходимости
- Отдать звуки переводчикам
- Заниматься расшифровкой шрифтов в картинки
- Вырезать шрифты в картинки и отдать художнику
- Нарисовать пару букв самому в текстуру со шрифтом, и пару русских букв в текст
- Пытаться вставлять текстуру со шрифтом обратно
- если звук приходилось декодировать, написать кодировщик :)
- Пытаться вставить в игру свой звук
- Получить первые тексты от переводчиков
- Получить текстуру от художника
- Собрать первую версию, показать менеджеру
- Если замечены неточности, записать в бумажку (это важно! именно записать от руки в бумажку! иначе будет пропущено)
- Собирать шрифты из готовых текстур
- Получить весь звук и текст, собрать
- Показать первую версию народу
- Собирать и показывать пока не надоест, пока не иссякнут замечания и исправления или пока не будет решено, ну хватит, отправляем...
...
Примерно такой план работы. Немного сумбурно, конечно и не всегда все происходит именно так, но в основном похоже.

Итак, имеем четыре основных фронта работ:
- Разборка - сборка
- Перевод текста; Перевод видео и написание "сценария" для актеров
- Рисование
- Звукорежиссура и нарезка звука

Звук

От себя добавлю что у нас было все много проще.
Кладовка/Туалет, много лотков из под яиц, медная проволока с натянутым чулком (плевательница, т.с. :)) Для того чтобы микрофон не записывал звук попадающих на него частиц слюны, когда говоришь. И наконец микрофон за сумасшедшие деньги. Звук записывался в присутствии только работающего актера и оператора. Все остальные отправлялись "в сад", т.е. работать дома.

Сегодня я попытаюсь рассказать про основные принципы разборки игры на составные части.

Ломать не строить

Разборка прежде всего требует очень хороших знаний всевозможных форматов и типов файлов. Графика, объекты, звук, текст, кодировки, основные способы шифрования. К чему я клоню, чтобы понять файл это или нет - надо знать как он выглядит, причем в основном в машинных кодах.

Если разработчик был ленивый/низко оплачиваемый - он просто набросал файлов по каталогам. Эти случаи самые расслабляющие, тут и делать собственно ничего не надо, просто бери да и копируй. Но бывает и по другому.
Если каталог с данными содержит только файлы вроде: "textures.dat", "sound.dat", "music.dat", "video.dat" и т.д.
Тут придется сделать утилиту, которая будет способна разобрать/собрать такие файлы. Такие утилиты чаще всего пишутся под конкретную игру, потому что одинаковых программ даже один и тот же человек никогда не пишет.

Чаще всего данные организовываются по принципу
- заголовок
- таблица размещения
- блоки данных

Например, возьмем какой-нибудь гипотетический файл "sound.dat" и открыть его простой (хе-хе) и удобной программой hiew32.exe. Само название подсказывает что здесь должен быть звук. Первое что можно в нем поискать - аббревиатуру RIFF, т.е. стандартный заголовок мультимедийных данных, и если нашли, то можно смело нарезать файлик от заголовка к заголовку - повезло. Можно быстро накропать разрезающую программу и послушать что и где, и если есть какой-то звук - отдать переводчику, пусть сортирует и переводит, пока Вы будете искать таблицу - заголовок к этому/в этом файле чтобы вставить его потом назад. Без заголовка почти никогда файлы не встречаются. Я имею в виду файлы с данными, которые объединены.

К чему я клоню, к тому что если вы точно уверены что нашли начало какого-нибудь файла внутри большого, который называется соответственно: "dat", "dta" и т.п. - вы можете смело искать в этом файле ссылку на начальное смещение этого куска, и с очень большой вероятностью - это и будет таблица.

Итак, наши действия:
- Ищем знакомые заголовки/идентификаторы начала файлов внутри большого файла данных
- запоминаем начальное смещение
- считаем размер файла путем вычисления "смещение2"-"смещение1"
- ищем найденные цифры в этом файле
- Анализируем найденную структуру таблицы. Пробуем выравнивать значения по 4 байта, по 8мь
- Пишем программу, которая будет разбирать файл на основе таблицы.

Не забудьте что все записано в обратном порядке, т.е. число 0x8FBD55 будет записано в файле в виде 0x55BD8F. Т.е. от младшего байта к старшему (умное и пугающее не знакомого с ним человека слово little-endian :).
Разбирать на основе таблицы, а не просто так, нужно прежде для того, чтобы потом все собрать назад.
Игра же должна будет использовать созданные нами данные и не подозревать того что они были изменены, правда?

Уважающий себя разработчик, пытается изо-всех-сил усложнить процесс разбора данных.
Подчас таблицу шифруют и прячут всеми известными способами. Но ведь для этого и придумал SoftICE и другие отличные программы. Работа с данными приложениями - совсем другая история. :)

Надо добавить что в последнее время человеку, который хочет организовать данные в своей игре и писать толком самому ничего не надо. Написано куча библиотек, которыми просто бери и пользуйся, уведомив автора, или вообще без надобности уведомления (gzip например)

Созданные таким способом файлы легко разбираются при помощи утилит от автора самого метода или уже написанной мастерами утилиты, которая разбирает файл на кусочки.
Например MPQ формат от Blizzard. Отличная работа по написанию прямо таки своей файловой системы с поддержкой версий, локализации и кучи всего прочего. Если я не ошибаюсь - там тоже используется gzip как компонент.

Это всего лишь общий принцип разборки, который известен мне. Я переводчик в конце концов...

И на закуску, история про Tomb Raider.
Это была наша следующая игра.
Текста в ней было мало, самое сложное было перевести видео на слух, потому что акцент присутствовал, особенно в отрывке, когда Боги Атлантиды судят Наттлу.
Идея с гербом на паспорте родилась сама собой :) Я только что пришел домой с паспортом, положил его рядом на стол и стал перерисовывать картинки к игре, т.к. их было мало, я сам перерисовывал, художника не нанимали. И Когда наткнулся на картинку паспорта, не смог удержаться.

Звук делали нанятые со стороны ребята, озвучивали тоже они.
С выражением у них было слабовато. Фраза "Убейте её" в одном из отрывков звучала как-то обыденно, как будто Наттла говорит "Принесите мне пивка...".
Но, тем не менее ребята старались. Есть момент, когда при обучении Лара выныривает из воды и говорит "Ооох.. Оххх.. Свежий воздух!" В английском варианте это звучит как просто радость с небольшой отдышкой: "Oh! Fresh Air! Let's....". Но в русском варианте, бедной девушке зажали рот, чтобы не дышала примерно тоже самое время что  в игре отводиться на "поплавать один раз", поднесли текст и микрофон, и только потом отпустили. Самоотверженно, правда?

Тестирование было проведено полностью, потому что к тому моменту, когда были готовы утилиты по сборке, я уже два дня как все перевел и проходил последний уровень.

Это единственная игра, для которой утилиты по разбору, по забытой уже причине были написаны на Ассемблере.
Ниже, например, кусок кода, который достает данные звука в черновом формате из RPL файлов первого Tomb Raider-а

Первый кусок просто чтение/запись файлов, ничего интересного, просто используем родное 21е прерывание.
Приведу лишь кусок кода, который собственно декодирует:
;------------------------------------------------------------
                proc ctoh
                mov dword ptr cs:[string],'0000'      ; а это и есть собственно декодер аудио
                mov dword ptr cs:[string+4],'0000'
                mov cx,0
ctoh1:          cmp byte ptr [si],30h
                jc ctoh2
                cmp byte ptr [si],3ah
                jnc ctoh2
                inc si
                inc cx
                jmp ctoh1
ctoh2:
                mov di,offset cs:string+7
                push si
                dec si
                std
            rep movsb
                pop si
                inc si
                mov bx,offset cs:string+7
                mov edx,1
                mov cx,8
                mov dword ptr cs:[len],0
ctoh_loop1:
                mov eax,0
                mov al,byte ptr cs:[bx]
                sub al,30h
                imul eax,edx
                add dword ptr cs:[len],eax
                imul edx,10
                dec bx
                loop ctoh_loop1
                ret
ctoh            endp


Спасибо за внимание.

No comments: