Перейти к содержимому
Zone of Games Forum

Рекомендованные сообщения

Некоторые маленькие игры создаются полностью на технологии Adobe (Macromedia) Flash или Adobe Flex.

Иногда встаёт вопрос: "как их русифицировать?"

В этой теме я постараюсь подробно описать, как мне удалось в такой игре заменить шрифт и перевести несколько строк текста без ограничений на длину строки (как решить эту проблему в играх не на Flash'е я немного писал тут: Длина строки).

Речь пойдёт об игре VVVVVV.

 

Spoiler

839590.jpg

Вся игра заключена в один файл: VVVVVV.exe (40 Мб)

Создана она на Flash'е (или на Flex'е), поэтому её exe-шник можно открыть и подредактировать в программе Flash Decompiler Trillix (или любом другом Flash-декомпиляторе).

Но сохранить отредактированный файл можно будет только как SWF, но нам нужен EXE.

Что представляет из себя файл VVVVVV.exe ?

На самом деле он "склеен" из двух файлов:

Flash-плеер.EXE и Flash-ролик.SWF

и в конец получившегося файла добавлено 8 байт:

4 байта: $FA123456

4 байта: размер SWF-ролика.

(так работают простейшие конверторы swf -> exe, в роли Flash-плеер.EXE они могут использовать Adobe Flash CS4\Players\FlashPlayer.exe, в нашем случае нельзя заменять оригинальный плеер игры)

Наша задача заключается в том, чтобы разделить VVVVVV.exe на Flash-плеер.EXE и Flash-ролик.SWF, отредактировать SWF, а затем опять склеить эти 2 файла в VVVVVV.exe, добавив в конец число $FA123456 и размер нового ролика. Для разъединения и склеивания можно воспользоваться какой-то готовой программой.

Разъединили.

Меняем шрифт (в оригинальном шрифте нет русских букв).

Открываем Flash-ролик.SWF во Flash Decompiler Trillix. Находим в разделе Images картинку со шрифтом:

839576.jpg Извлекаем, добавляем русские буквы: 839582.png

Заменяем в Flash Decompiler Trillix картинку со шрифтом на нашу. Сохраняем отредактированный SWF-ролик.

Чтобы посмотреть новый шрифт в игре склеиваем Flash-плеер.EXE и Flash-ролик.SWF, добавляем в конец служебные 8 байт. Запускаем, смотрим что получилось.

 

Spoiler

839604.jpg

Переводим текст меню.

Открываем наш Flash-ролик.SWF в HEX-редакторе, ищем ASCII-строку "start game".

 

Spoiler

4987de55b51bfbe29b6eaf53d0715718.jpg

Можно перевести, но символов недостаточно, чтобы написать "НАЧАТЬ ИГРУ".

Замечаем, что байт перед этой строкой обозначает длину строки: 0A (10.)

Но мало изменять лишь этот байт - игра не запустится или зависнет.

 

Spoiler

71134df1324c795fe8a4767dfda7fac9.jpg

Разбираем формат SWF-файла, чтобы узнать, как изменять длину любой строки.

Для этого я воспользовался официальной спецификацией формата SWF (на англ. языке): SWF File Format Specification, Version 10 (последнюю версию всегда можно взять с оф.сайта).

Итак, любой SWF-файл состоит из заголовка файла (SWFHeader) и идущих следом друг за другом независимых блоков (TAG-ов).

Если заголовок начинается с CWS, ролик сжат, и нужно его сначала чем-то распаковать. В нашем случае он начинается с FWS – всё в порядке.

Каждый TAG имеет свой формат и содержит разные данные (есть tag со шрифтом, tag со звуками, tag со скриптами и т.д.).

Каждый TAG можно изменять/удалять/добавлять независимо от остальных (в разумных пределах). Нужно лишь в заголовке файла изменять одно значение - FileLength (смещение: 04) - размер всего SWF-файла.

 

Spoiler

19f21adb3aed16dd9085f7edbebffa4d.gif

f2b11df75e79881806b849431e321462.gif

401bb1ea336ccc66732eca4873d36e17.gif

Написав по этой документации небольшую программку, я смог составить список всех TAG-ов в нашем Flash-ролике.SWF

 

Spoiler
[ SWF HEADER ]sgn: FWSver = 10FileLength = $22FF144--- FrameSize ---Nbits = 15Nbytes = 8X: 0-6400 Y: 0-588----FrameRate = 0FrameCount = 542[ TAGs ]startpos = $15TAGtype = $45 TAGlen = $04 TAGpos = $15 TAGname = FileAttributesTAGtype = $FF TAGlen = $01 TAGpos = $1B TAGname = TAGtype = $4D TAGlen = $1CA TAGpos = $1E TAGname = MetadataTAGtype = $41 TAGlen = $04 TAGpos = $1EE TAGname = ScriptLimitsTAGtype = $09 TAGlen = $03 TAGpos = $1F4 TAGname = SetBackgroundColorTAGtype = $29 TAGlen = $1A TAGpos = $1F9 TAGname = TAGtype = $2B TAGlen = $0A TAGpos = $215 TAGname = FrameLabelTAGtype = $24 TAGlen = $4E3 TAGpos = $221 TAGname = DefineBitsLossless2TAGtype = $52 TAGlen = $2545 TAGpos = $70A TAGname = DoABCTAGtype = $4C TAGlen = $23 TAGpos = $2C55 TAGname = SymbolClassTAGtype = $01 TAGlen = $00 TAGpos = $2C7A TAGname = ShowFrameTAGtype = $2B TAGlen = $06 TAGpos = $2C7C TAGname = FrameLabelTAGtype = $0E TAGlen = $146C TAGpos = $2C84 TAGname = DefineSoundTAGtype = $0E TAGlen = $28D0 TAGpos = $40F6 TAGname = DefineSoundTAGtype = $0E TAGlen = $1B8F TAGpos = $69CC TAGname = DefineSoundTAGtype = $0E TAGlen = $486B TAGpos = $8561 TAGname = DefineSoundTAGtype = $0E TAGlen = $1985 TAGpos = $CDD2 TAGname = DefineSoundTAGtype = $0E TAGlen = $146C TAGpos = $E75D TAGname = DefineSoundTAGtype = $0E TAGlen = $43EF33 TAGpos = $FBCF TAGname = DefineSoundTAGtype = $0E TAGlen = $1880 TAGpos = $44EB08 TAGname = DefineSoundTAGtype = $0E TAGlen = $830 TAGpos = $45038E TAGname = DefineSoundTAGtype = $0E TAGlen = $72E TAGpos = $450BC4 TAGname = DefineSoundTAGtype = $0E TAGlen = $72E TAGpos = $4512F8 TAGname = DefineSoundTAGtype = $0E TAGlen = $7C6A TAGpos = $451A2C TAGname = DefineSoundTAGtype = $0E TAGlen = $2284DA TAGpos = $45969C TAGname = DefineSoundTAGtype = $0E TAGlen = $1B96 TAGpos = $681B7C TAGname = DefineSoundTAGtype = $0E TAGlen = $C48 TAGpos = $683718 TAGname = DefineSoundTAGtype = $0E TAGlen = $F57 TAGpos = $684366 TAGname = DefineSoundTAGtype = $0E TAGlen = $938 TAGpos = $6852C3 TAGname = DefineSoundTAGtype = $0E TAGlen = $628 TAGpos = $685C01 TAGname = DefineSoundTAGtype = $0E TAGlen = $333F5D TAGpos = $68622F TAGname = DefineSoundTAGtype = $0E TAGlen = $40D601 TAGpos = $9BA192 TAGname = DefineSoundTAGtype = $0E TAGlen = $30DDAF TAGpos = $DC7799 TAGname = DefineSoundTAGtype = $0E TAGlen = $3F3E31 TAGpos = $10D554E TAGname = DefineSoundTAGtype = $0E TAGlen = $72E TAGpos = $14C9385 TAGname = DefineSoundTAGtype = $0E TAGlen = $348FCF TAGpos = $14C9AB9 TAGname = DefineSoundTAGtype = $0E TAGlen = $72E TAGpos = $1812A8E TAGname = DefineSoundTAGtype = $0E TAGlen = $13228 TAGpos = $18131C2 TAGname = DefineSoundTAGtype = $0E TAGlen = $72E TAGpos = $18263F0 TAGname = DefineSoundTAGtype = $0E TAGlen = $32780 TAGpos = $1826B24 TAGname = DefineSoundTAGtype = $0E TAGlen = $72E TAGpos = $18592AA TAGname = DefineSoundTAGtype = $0E TAGlen = $9CF TAGpos = $18599DE TAGname = DefineSoundTAGtype = $0E TAGlen = $1DC3 TAGpos = $185A3B3 TAGname = DefineSoundTAGtype = $0E TAGlen = $72E TAGpos = $185C17C TAGname = DefineSoundTAGtype = $0E TAGlen = $72E TAGpos = $185C8B0 TAGname = DefineSoundTAGtype = $0E TAGlen = $3E48 TAGpos = $185CFE4 TAGname = DefineSoundTAGtype = $0E TAGlen = $4E9FCA TAGpos = $1860E32 TAGname = DefineSoundTAGtype = $0E TAGlen = $199FB3 TAGpos = $1D4AE02 TAGname = DefineSoundTAGtype = $0E TAGlen = $89A TAGpos = $1EE4DBB TAGname = DefineSoundTAGtype = $0E TAGlen = $1267 TAGpos = $1EE565B TAGname = DefineSoundTAGtype = $0E TAGlen = $1E231 TAGpos = $1EE68C8 TAGname = DefineSoundTAGtype = $0E TAGlen = $27C71D TAGpos = $1F04AFF TAGname = DefineSoundTAGtype = $24 TAGlen = $233E TAGpos = $2181222 TAGname = DefineBitsLossless2TAGtype = $24 TAGlen = $2365 TAGpos = $2183566 TAGname = DefineBitsLossless2TAGtype = $24 TAGlen = $2233 TAGpos = $21858D1 TAGname = DefineBitsLossless2TAGtype = $24 TAGlen = $26C2 TAGpos = $2187B0A TAGname = DefineBitsLossless2TAGtype = $24 TAGlen = $62D TAGpos = $218A1D2 TAGname = DefineBitsLossless2TAGtype = $24 TAGlen = $1CFC TAGpos = $218A805 TAGname = DefineBitsLossless2TAGtype = $24 TAGlen = $272C TAGpos = $218C507 TAGname = DefineBitsLossless2TAGtype = $24 TAGlen = $176B TAGpos = $218EC39 TAGname = DefineBitsLossless2TAGtype = $24 TAGlen = $1C TAGpos = $21903AA TAGname = DefineBitsLossless2TAGtype = $24 TAGlen = $F2E TAGpos = $21903CC TAGname = DefineBitsLossless2TAGtype = $24 TAGlen = $12B TAGpos = $2191300 TAGname = DefineBitsLossless2TAGtype = $24 TAGlen = $12F TAGpos = $2191431 TAGname = DefineBitsLossless2TAGtype = $24 TAGlen = $127 TAGpos = $2191566 TAGname = DefineBitsLossless2TAGtype = $24 TAGlen = $FBD TAGpos = $2191693 TAGname = DefineBitsLossless2TAGtype = $24 TAGlen = $B2 TAGpos = $2192656 TAGname = DefineBitsLossless2TAGtype = $24 TAGlen = $131 TAGpos = $219270E TAGname = DefineBitsLossless2TAGtype = $24 TAGlen = $88 TAGpos = $2192845 TAGname = DefineBitsLossless2TAGtype = $24 TAGlen = $AE TAGpos = $21928D3 TAGname = DefineBitsLossless2TAGtype = $38 TAGlen = $227 TAGpos = $2192987 TAGname = ExportAssetsTAGtype = $52 TAGlen = $16C20A TAGpos = $2192BB4 TAGname = DoABCTAGtype = $4C TAGlen = $376 TAGpos = $22FEDC4 TAGname = SymbolClassTAGtype = $01 TAGlen = $00 TAGpos = $22FF140 TAGname = ShowFrameTAGtype = $00 TAGlen = $00 TAGpos = $22FF142 TAGname = End

 

Строка "start game" находится по смещению 22562DD, а это значит, что она содержится вот в этом TAG'е:

TAGtype = $52 TAGlen = $16C20A TAGpos = $2192BB4 TAGname = DoABC

(тип DoABC означает, что в этом теге содержится байт-код, который выполняет виртуальная машина ActionScript, а это усложняет отладку в программах вроде OllyDbg и SoftIce, однако, это же означает, что данный код не содержит абсолютных адресов, что упростит его изменение – мои догадки)

Начинается он со смещения 2192BB4, переходим сюда в HEX-редакторе. Попадаем на заголовок TAG'а. Первые 2 байта нас не интересуют (они содержат тип тега), далее идёт 4 байта, в которых указывается размер тега. И если мы увеличим длину строки в этом теге, то и размер тега нам тоже надо увеличить.

Итак, выяснили, чтобы заменить строку "start game" на "НАЧАТЬ ИГРУ" (наша строка на 1 байт длиннее) нужно сделать следующее:

1) заменить текст, вставив один лишний символ

2) перед строкой указать правильную длину строки: вместо 0A пишем 0B (11.)

3) указываем в заголовке тега длину на 1 больше, чем было

4) указываем в заголовке файла длину на 1 больше, чем было

Всё! Склеиваем Flash-плеер.EXE и отредактированный Flash-ролик.SWF, дописываем в конец 8 служебных байт, запускаем смотрим.

Если ничего не напортачили, всё будет работать. Вот, что у меня получилось после перевода таким методом двух пунктов меню:

 

Spoiler

5c7d53508b41be8137ce2397a20f7727.jpg

Осталось лишь отшлифовать шрифт, чтобы аккуратней был, и перевести весь остальной текст. И очевидно, что изменять каждую строку лучше не вручную... :)

Изменено пользователем enz°
  • Лайк (+1) 1

Поделиться сообщением


Ссылка на сообщение

@SkeleTos 

Перешли файл *.swf, посмотрю так ли это

А дальше будет видно, если в этом причина, то надо делать через программу Adobe Flash CS6 — шрифт и переносить в твой *.swf

Поделиться сообщением


Ссылка на сообщение

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!

Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.

Войти сейчас


  • Сейчас популярно

  • Продвигаемые темы

  • Последние сообщения

    • пол года аниме не смотрел, глянул что вышло, Звездное дитя уже третий сезон все еще на уровне первого.
    • Тьфу ты... Я уж подумал об анонсе озвучки на Expanse: Osiris Reborn, а тут говно какоето безродное. 
    • Там с зайцами туго поэтому здесь мало кому зайдёт.
    • да сам столкнулся с проблемой что батник удаляет .ехе файл, врезультате полез на их сайт, скачал пиратку с 1.1 русификатором, откатил и накатил на ней эту версию 1.2  и уже потом закинул в стим
       
    • Привет всем, зарегался впервые просто чтобы написать сюда. Ничего не знаю о сайте, я тут как нормис. Эта самая нишевая шедевральная игра, в которой нет русского, и требующая академического уровня знания языка. А те самые "переводчики" от яндекс или гугл передают такую хрень, что легче самому разобраться, и все это усугубляет её нишевость из за которой нормального русификатора не то чтобы нет, его вообще не существует. Тем не менее, я наиграл 6 часов ориентируясь хуй знает как и мне зашло, потому что я фанат всяких самурайских тем и истории в целом, с около двух тысяч часов в Shogun 2. Игра сама по себе не казуальная, и не популярна в плане подхода к геймдизайну — вообще нет всяких тупых марок и сотни подсказок куда тебе идти, и во всех квестах чтобы понять чо от тебя хотят надо говорить с нпс, и понимать чо вообще от тебя хотят. Я это люблю но бл это сюжетный иммерсив сим где куча всяких концовок, и очень обидно бегать без понимания что и как да и вообще я за 6 часов понял только как оружие ковать и махаться им, попутно изучая навыки и убивая пол карты (после чего от меня каждый 3 нпс убегал, ведь мне нравилось всех резать. я даже у кого то катану сломал) при этом ни один квест не выполнил. Скажите как русик появится, давно мечтаю. Будь у меня русский, это наверно, та самая игра которой я не пожалею 100 часов своей жалкой жизни Круто!!!! Братан, я думал не увижу такое сообщение вообще никогда, перевод наверно, выйдет не скоро, но лучше не торопится в таком отважном деле. Как никак в этой игре важен контекст.
    • Да, я тут. Через пару дней выложу сюда ссылку на открытый пост на Бусти) А, собственно, уже прикрепили сверху) Ну, короче, скоро все будет for free) Изменил настройки на Бусти, видимо, так по умолчанию стояло.
    • Обновление перевода: синхронизация с патчем от 15.04.26. По тесту вижу, что как минимум действия с дверями точно перевелись. Выполнил 1 миссию, не видел английского текста.
    • PS PLUS EXTRA И PREMIUM - АПРЕЛЬ 2026

      PlayStation Plus Extra и Premium:
      • The Crew Motorfest (PS5, PS4)
      • Horizon Zero Dawn Remastered (PS5)
      • Horizon Zero Dawn Complete Edition (PS4)
      • Football Manager 26 Console (PS5)
      • Warriors: Abyss (PS5, PS4)
      • Squirrel with a Gun (PS5)
      • The Casting of Frank Stone (PS5)
      • Monster Train (PS5)

      PlayStation Plus Premium:
      • Wild Arms 4 (PS5, PS4)

      Игры станут доступны с 21 апреля 2026
  • Изменения статусов

    • Jimmi Hopkins  »  SerGEAnt

      Это не просто перевод, а полноценная авторская сценарная адаптация. Диалоги переписаны так, чтобы персонажи звучали живо, остро и в характере. Добавлен чёрный юмор там, где авторы постеснялись. Убраны лорные противоречия, докручены мотивации. В результате игра стала умнее, злее и смешнее оригинала.
      · 0 ответов
    • ElikaStudio

      Долгожданный релиз полного сезона состоялся!
      https://youtu.be/mwBk2stm2OQ?si=qpJojB_XDABaC0We
      https://vk.com/video-48153754_456239394?sh=4&list=c62797c2b7d0725d6e
      Life is Strange: Before the Storm:
      Эпизод 1: "Прoбуждeниe"
      Эпизод 2: "О дивный новый мир"
      Эпизод 3: "Ад пуст"
      Бонусный эпизод: "Прощание"
      Русская озвучка уже доступна для скачивания!
      ElikaStudio выражает огромную благодарность всем, кто принял участие в создании проекта! 
      Группе Mechanics VoiceOver R.G. MVO , в частности их руководителю Дмитрию за неоценимую помощь в выпуске эпизода.
      Скачать для PC Classic (2018):
      GDrive: - https://drive.google.com/file/d/19CL_L80Mz0sIxcb54Ss64byAkeZmV22r/view?usp=sharing
      Скачать для PC Remastered (2022):
      GDrive: - https://drive.google.com/file/d/13q58Lpvw5_aYPYeZ7OGYZlAKOoS1gEbL/view?usp=sharing
      Скачать для Свитч(2022):
      GDrive: - https://drive.google.com/file/d/15e—T1LQiGQCYIHeNnj_C2qJA16Gvh1i/view?usp=sharing
      Ручная установка PC(оба издания):
      https://drive.google.com/drive/folders/1MJPd8965m4XxxAuOBt8enSHtv8_yy5xh?usp=sharing
      Баг репорт в обсуждении:
      https://vk.com/topic-48153754_55571577
      ___________________________________________
      Финансовый аппарат:
      www.donationalerts.com/r/elikastudio
      Пожертвовать средства на наши проекты:
      Кошелек ЮMoney 4100 1188 6818 3009
      карта Сбер банк 2202 2018 6334 1042
      карта Альфа банк 5559 4937 0209 8584
      Спасибо за вашу поддержку!
      #elikastudio #русскаяозвучка
      · 0 ответов
    • fox222  »  Siberian GRemlin

      Здравствуйте, хочу купить персональный доступ к переводам, сколько стоит?
      · 1 ответ
    • vitkach  »  eaZy

      Извините за беспокойство. Хотел спросить, а русификатор ещё когда-нибудь будет обновляться? Дело в том, что после его выхода выходили ещё обновления, в частности обновление 1.1, вышедшее летом 2023 года, где была добавлена целая сюжетная глава в конце если проходишь на лучшую концовку золотого пути, это где-то ещё полчаса диалогов. Также в игре присутсвуют иногда кракозябры вместо русского языка, это в основном связано с тем, что кое-где текст был изменён, в основном в обучающих сообщениях.
      · 0 ответов
    • TerryBogard  »  Siberian GRemlin

      C&C: RA: Retaliation (ПК) не работает.
      · 0 ответов
  • Лучшие авторы


Zone of Games © 2003–2026 | Реклама на сайте.

×