pop↑ push↓

☆ (ゝω・)v

中国チームのEU4の中文化手法について

はじめに

 52pcgame内でEU4の中文化を開発している中国チームより、プロダクトを掲載する許可を戴いたため、ここでご紹介をしたいと思います。プロダクトのレポジトリは下記になります。

Bitbucket

どのようなものか

 上記のレポジトリのReadMeにもありますが、この方式には素晴らしい点がたくさんありますので、順を追って説明したいと思います。

① exeを改竄しなくてよい

 exeを改竄しないで、UTF-8表示が可能になっています。したがってたとえアップデートがあっても、再度パッチを当てる必要がありません。これをどのように実現しているかは後述したいと思います。

② 変更箇所のパターン認識

 これはパッチを作っている私からすると大変に助かることなのですが、プログラムが登録されているパターンを探して、マルチバイト文字の表示に必要な変更を自動で加えるため、アップデートがあっても、1からパッチを作り直す必要がありません。

③ 文字データがUTF-8

 文字データをUTF-8としてそのままで扱っているため、保存したセーブデータやログなどはそのままテキストエディタで読むことができます。また、翻訳ファイルを変換することなく、扱うことができます。

④ フォントデータに制限がない

私の作ったパッチだと、一部使えない文字範囲があるのですが、このパッチはすべてのUTF-8の範囲を扱うことができます。

どのように実現しているか

プロキシDLL

まず、①についてです。これはプロキシDLLという仕組みを使っています。詳細は下記を見てください。

D3D9プロキシDLLの作り方 · GitHub

 解説しますと、Windowsのプログラムファイルは、実行時に必要なDLLをロードする際、まず最初にexeがあるディレクトリ(カレントディレクトリ)を見て、なければ共有のDLLフォルダを見に行くという仕様があります。

 ここでその名前の、ほとんどの処理は元のDLLに丸投げするが、一部の処理のみを変更したDLLを作り、カレントディレクトリに置いておくと、プログラムはそのDLLを読み込みますから、プログラムに対して処理を変更させることができます。

プロキシDLLは更に別のDLLを読み込む

 今回のプロキシDLLのターゲットはd3d9.dllで、これはDirectXの描画に使われれているものです。面白いのはDirectXの動作は変更せず、初期化の部分だけを変更し、そこでLoadLibraryWを使って、他のDLLを更にインポートしている点です。これにより拡張性と見通しが良くなっています。今回はpluginフォルダ以下のDLL(plugin.dll)を読み込むようになっていました。

f:id:saito-matanki:20180618230622p:plain

動的プログラム変更

 ここからがまた面白いです。plugin.dll内でGetModuleHandleA(NULL)を実行することで、eu4.exeのマッピングアドレスを取得しています。

モジュールのマッピング

[PE(Portable Executable)ファイルフォーマットの概要

f:id:saito-matanki:20180618234020p:plain

そこにはPIMAGE_SECTION_HEADERがありますから、RVAを取得して、.textと.rdataの位置を割り出しています。つまり、IDAで見えるようなセグメントを実行時に取得できたことになります。

f:id:saito-matanki:20180618234528p:plain

そして、.textにはプログラムのコードが存在していますので、ここから、特定のバイトパターンを検索して、メモリを書き換えることで、パッチを使わずに動的にexeの動作を変更できるというわけです。

f:id:saito-matanki:20180618235041p:plain

ローカライズの難易度

ASCII内で表現可能なスペースで分かち書きする言語 難易度-0

 ASCIIはこれ。  f:id:saito-matanki:20180512193439p:plain  アクセント付き文字が含まれていないため、これに該当するのは厳密には英語しかない。

CP1252で表現可能なスペースで分かち書きする言語 難易度ー1

 CP1252はこれ。  f:id:saito-matanki:20180512193730p:plain  ASCIIにアクセント付き文字が含まれたため、スペイン語、ドイツ語、フランス語などのヨーロッパ諸言語が大体表現可能。EU4、CK2のデフォルトの文字コードがこれに当たる。

CP1252では完全に表現可能ではないが、ほぼ可能でスペースで分かち書きする言語 難易度ー1

 例えば、トルコ語やヴェトナム語。 f:id:saito-matanki:20180512195057p:plain f:id:saito-matanki:20180512195024p:plain

ğやưはCP1252にはない。これはCP1252で使わないアクセント付き文字をすげ替えればよい。

Unicodeの0x100~0xFFFF範囲(UCS2)にあるが、表現に必要な文字数がアルファベット程度で、スペースで分かち書きをする言語 難易度-2

 ロシア語、ギリシャ語がこれに該当する。  f:id:saito-matanki:20180512194632p:plain   これらは、CP1252のアルファベットの文字列をすげ替えて対応することで、対応できる

Unicodeの0x100~0xFFFF範囲(UCS2)にあり、表現に必要な文字数がアルファベット程度で、スペースで分かち書きをする右から左に進む言語 難易度ー10

 これはヘブライ語しかない。 f:id:saito-matanki:20180512202208p:plain  これの難しさは言語的な難しさよりもUIをどうするかという点である。

Unicodeの0x100~0xFFFF範囲(UCS2)にあり、表現に必要な文字数が256を超える言語 難易度-15

 いわゆるCJK、中国語、日本語、韓国語がこれに該当する。容量の問題をクリアすれば、表現に必要な文字が予めUnicodeに定義済みのため、ギリギリ対応が可能。  f:id:saito-matanki:20180512202249p:plain f:id:saito-matanki:20180512203126p:plain

Unicodeの0x100~0xFFFF範囲(UCS2)にあり、表現がそれらの合字で表現される言語 難易度ー30

 インド系文字。 f:id:saito-matanki:20180512203342p:plain

 とりあえず下記を見て欲しい。  f:id:saito-matanki:20180512200848g:plain  上記の画像はヒンディー語のデバナガリの例で、MSのサイトから取ってきたものだが、一筋縄ではいかないことがわかる。

 下記はミャンマー語のビルマ文字の例だが、▂▅▇█▓▒░(’ω’)░▒▓█▇▅▂  f:id:saito-matanki:20180512201100p:plain

 ただし、オープンソースとしてよくメンテナンスされた組み立てエンジン(harfbuzz)が存在し、それを利用すれば可能かもしれない。  

Unicodeの0x100~0xFFFF範囲(UCS2)にあり、表現がそれらの合字で表現される、右から左に進む言語 難易度ー35

 アラビア語。  f:id:saito-matanki:20180512202443p:plain

 これもインド系文字と同様に文字の組み立てが発生する。ただし、それほどは鬼畜ではない。一方、右から左に進むというUI的な問題が同時に存在しており、非常に厳しい。ただし、これもharfbuzzを利用すれば可能かもしれない。

EU4のあれ

総括

 します

注意

 嫌なことをたくさん書いてます。上から目線です。でも読んで欲しい('ω')。

翻訳(90点)

 500万文字もあったEU4の翻訳作業。自分だと2行しか翻訳していないのに、全部翻訳された。ほぇ~、絶対無理だと思ってました。侮っていてご免なさい。

-10点

 翻訳の表記ゆれがある。

パッチ(80点)

 できないと思ってたけど、なんとかなった ∩( ・ω・)∩  ただこの半年、めっちゃ辛かった…

-5点

 パッチバグ(特定年代で強制終了?未確認)

-15点

 修正できなかった点(セーブファイル名、マップの1文字表示)

Mod(90点)

 なんとかなった ∩( ・ω・)∩

-10点

 プロビ名などを他Modに分離してない

プロジェクト(70点)

 そこそこ見やすいスプレッドシートにできたと思ってる。スクリプトも頑張った(自画自賛)

-20点

 イシューに対応してない

-10点

 フォントの字種まとめてない

プロジェクト企画・進行(10点)

 あえて言おう。失敗だったと。

-90点

 無償の努力に頼った。良いわけない。翻訳1文字10円とすると本来5000万円かかる。これが0円。やりがい搾取以外の何物でもない。翻訳者達には「いやーありがと~次も( ゚д゚)ノ ヨロ」とはちょっと言えない。とりあえず貸し(favor)でお願いしたいです。

今後

 1.25.1に対応したあとはMod、作業書の更新は終了とします。公開は続けますので自由に使ってください。 理由としては、上記の無償の努力の前例が出来るのが良くないと思ったからです。最低でも翻訳者の方たちに還元される仕組みができるようになったらまた再開しようと考えています。 パッチは要望があれば開発します。

CK2に関して

 翻訳率100%なるまでは続けようと思っています。それまでは無償の努力になってしまうので、納得できる方だけが参加お願いします。すいません。

以上