EU4のパッチ情報です。
前回
パッチバグについて
翻訳が進むに連れて、強制終了の報告が多く上がるようになりました。
これは44文字目もしくは45文字目にエスケープ文字が存在するマップテキストのバイト列が、次章で示す理由により45文字目で途切れた時に、不正なコードポイントが発生することで、フォントデータへのアクセス違反を誘発するために起こるバグです。修正に確信が持てないため、すぐに修正するにはmapテキストに関する翻訳ファイル(prov_namesなど)を適用しないでください。
なぜ45文字で途切れるか
簡単に言えば、内部のコードがそうなっているからです。下記の画像の左のルートのpush 2Dhがそれです。
テキストバイト列はここで、0x38の大きさを持つ構造体(下記は適当です)のテキスト用の変数(大きさ0x2E、最後にnull文字が入るため)にコピー(sub_1A1B180)されます。
typedef struct hoge{ uint32_t* address; uint32_t index; char maptext[2E]; char length; char padding; } hoge_t;
修正できるのか?
上記の2DをFFなどに変えれば修正可能に思われますが、構造体そのもの大きさが決められているため、うまく行きません(でした)。しかし、左のルートではなくて、右のルートを見てください。こちらはテキスト元(esi)のアドレスをそのまま転送(mov [ecx+eax*4], esi)しているように見えます。実際この右ルートに入ってくるマップテキストも存在しており、例えばPROV1がそれです。PROV1とPROV2に同じ文字列を設定していますが、PROV2に対してPROV1の表示がすべて表示されていることがわかります。
一方で、テキストが不自然に大きかったり、まっすぐ過ぎたり、なぜ右ルートに入るマップテキストと左ルートに入るマップテキストがあるのかわかっていません。
右ルートと左ルートの分岐条件(追記)
テキストが不自然になるのに、思いあたりがあります。map/positions.txtです(詳細はここを参照)。確認してみると、PROV1とPROV2は次のような感じでした。
PROV1はText Rotationが0.087で、PROV2は0.000です。一方で条件分岐にブレークポイントを置いたときの決定打となるxmm0レジスタの値は下記です。
浮動小数点の誤差が出ていますが、positions.txtのrotationの値で間違いなさそうです。
次回プログラムを改造する(E)に続く