トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS

解説/FEBuilderGBA/FEBuilderGBAのconfigデータ構造

Last-modified: 2017-12-11 (月) 22:07:49 (9h)

FEBuilderGBAのconfigディレクトリ内のデータ構造について説明します。

設定ファイルのルール

/config/config.xml

このツールの設定が格納されます。


/config/translate/

このツールが利用する翻訳リソースです。
GNU GetText?みたいな考え方をもとにした、KEY:\r\nVALUE形式です。

:元文字列
翻訳文字列


https://i.imgur.com/iPFRtmE.jpg

/config/data/

このツールが利用する、ゲーム内での設定データがあります。
項目が長くなったり、外部リソースとして切り出した方が拡張性が高くなると判断したデータが入っています。


ファイル適合ルール

設定ファイルは、以下の順番で探索されます。
langには、選択されている言語入ります。en=英語 ,zh=中国語。
file_VERSION.lang.txt
file_VERSION.txt
file_ALL.lang.txt
file_ALL.txt

また、ファイル内にも、{J} {U} で切り替わるものが有ります。
例えば、ポインタ値は、FE8J FE8Uで違いますので、この切替に利用されます。

例.

search"foo"
gameFE8
langen
typeFE8U
if ( Exists("config/data/foo_FE8.en.txt") )
{
   return found;
}
if ( Exists("config/data/foo_FE8.txt") )
{
   return found;
}
if ( Exists("config/data/foo_ALL.en.txt") )
{
   return found;
}
if ( Exists("config/data/foo_ALL.txt") )
{
   return found;
}
return NOT_FOUND;


仮に、foo_ALL.txt が見つかったとします。

foo_ALL.txtの中身が以下のように書かれていたと仮定します。

TEST1=A
TEST2=B	{U}
TEST3=C	{J}


探索命令でtype==FE8U と指定したため、以下の内容が取得されます。

TEST1=A
TEST2=B


もし、探索命令で type==FE8J であった場合、以下の内容が取得されます。

TEST1=A
TEST3=C

すべてのファイルは タブ区切りのTSV形式です。
文字コードはUTF-8で統一です。

一覧

ai1ユニット配置のAI1の一覧を定義します
ai2ユニット配置のAI2の一覧を定義します
aiscriptaiscript命令を定義します
asmmap関数マップ 逆アセンブラ時にヒントを表示します
base_rom_info無改造ROMの容量とCRCを定義します
battleanime_85command戦闘アニメのC85コマンド一覧を定義します
battleanime_auto_recolor戦闘アニメで敵配色を決定するのに利用します
battleanime_mode戦闘アニメの種類を定義します
eventイベント命令を定義します
eventcondイベント条件の種類を定義します
func_langFEBuilderGBAで利用できる言語の一覧を定義します
item_anime_effect武器アニメエフェクトの一覧を定義します
item_staff_use_effectアイテムを利用した場合の効果を定義します
item_weapon_effect武器の追加効果を定義します
magic_command魔法拡張のコマンドを定義します
magic_csa_spell_table魔法拡張の魔法アニメーションを定義するCSATABLEを検索する条件を定義します
magic_extends魔法拡張の是非を判定する方法を定義します
mappointerマップポインタ名を定義します
mapstyleマップスタイル一覧を定義します
other_textC言語の文字列直値が埋め込まれているアドレス一覧を定義します
skill_extendsスキル拡張の是非を判定する方法を定義します
skill_extends_*スキル拡張別に、スキルIDを定義します
song_instrument楽器情報をMD5化し、楽器アドレスに楽器名を振ります
song_instrumentsetNIMAPの是非を判定する方法を定義します
sound効果音名を定義します
sound_foot_steps足音を定義します FE8のみ
tbl_condtblを利用するべきかどうかを定義します
translate_textid翻訳のために日米のROMでの文字列IDの対応表を作ります
updater.bat.txt設定ファイルではない。 自動アップデートのバッチファイルです。



/config/patch/

細かい設定がパッチとして切り出されています。
メニューの 機能->パッチ管理 からアクセスできます。

https://i.imgur.com/59gvcy9.jpg

パッチ形式

パッチファイルは、 KEY=VALUE 形式です。
数字データは 0xをつけると16進数になります。何も付けないと10進数です。

+0x08000000 GBAポインタにしてもしなくても、どちらでも問題ありません。~


共通項

NAME=名前

パッチの名前を定義します。
未定義の場合、パッチのファイル名になります。

TYPE=IMAGE TYPE=ADDR TYPE=STRUCT TYPE=BIN TYPE=EA

パッチの種類を定義します。5つの種類があります。
詳しくは後で説明します。

INFO=詳しい情報を書きます。\r\n可能であれば説明を書いてください。

詳しい情報を書きます。 改行は\r\nにしてください。


IF:0xEE594=0x4B 0xFA 0x2F 0x59 0x7E 0x19

パッチが利用できるかどうかを定義します。
この例では、ROM内 0xEE594 が 0x4B 0xFA 0x2F 0x59 0x7E 0x19 となっているかどうかを見ています。
もし、 0xEE594 が 0x4B 0xFA 0x2F 0x59 0x7E 0x19 であれば、このパッチを利用できます。

IF_NOT:0xEE594=0x4B 0xFA 0x2F 0x59 0x7E 0x19

パッチが利用できるかどうかを定義します。
先ほどとは逆に、ROM内 0xEE594 が 0x4B 0xFA 0x2F 0x59 0x7E 0x19 で、なければ、利用可能になります。

PATCHED_IF:0x080bb182=0x45 0x46 0xE0 0xB4
PATCHED_IF_NOT:0x080bb182=0x45 0x46 0xE0 0xB4

既にパッチが適合されたかどうかを定義します。
2回パッチを当てるとまずい BINパッチで主に使われます。

マルチ言語

英語名を記述するには、 .en をつけます。
中国名を記述するには、 .zh をつけます。

NAME=日本語名
NAME.en=English
NAME.zh=中国語

ver20171211から、すべてのパラメータに対して、 AAAA.en などの言語指定ができるようになりました。

パッチの種類 ADDRパッチ

NAME=きずぐすりの回復量
NAME.en=Recovery amount of Vulnerary
NAME.zh=责骂的回收量

//アドレスパッチとして実装します
TYPE=ADDR

ADDRESS=0x2fe16

AUTHOR=出典:aeraさんの資料より\r\nhttp://ngmansion.xyz/wiki/hackfe/index.php?%E3%83%91%E3%83%83%E3%83%81#jf501d8a
AUTHOR.zh=来源:从aera的数据\r\nhttp://ngmansion.xyz/wiki/hackfe/index.php?%E3%83%91%E3%83%83%E3%83%81#jf501d8a
AUTHOR.en=Source: From aera's data\r\http://ngmansion.xyz/wiki/hackfe/index.php?%E3%83%91%E3%83%83%E3%83%81#jf501d8a


FE8Jの傷薬の回復量は0x2fe16に格納されています。
これは、それを変更するパッチです。

https://i.imgur.com/YLOE1U7.jpg

マルチバイト

ADDRは、基本的に1バイトの変更のみですが、2バイト以上を変更をしたい場合、以下のように、コンボボックス形式にしてください。

NAME=フリーマップから入らないとフリーズする制約を消す
NAME.en=Eliminate the constraint of freezing unless it enters from the world map.
NAME.zh=消除冻结的限制,除非从免费地图进入

//Implement as an address patch.
TYPE=ADDR

ADDRESS=0xc1e7c
COMBO=default|0x47 0x2D|fix|0xB8 0xE0


https://i.imgur.com/vRuzDeu.jpg

ADDRESSの同時指定

ADRESSに、スペース区切りで、複数のアドレスを書くことができます。
それぞれに同じ値が設定されます。
いろいろな場所を同時に変えないといけない場合に利用します。

NAME=幸運上限
NAME.en=Upper limit of lucky
NAME.zh=运气最大

//アドレスパッチとして実装します
TYPE=ADDR

ADDRESS=0x80CA0 0x29f0e 0x29f12 0x180d8 0x180dc 0x95694 0x95694 0x9585C

例えば、幸運上限はいろいろな場所に設定が点在してハードコーディングされているので、
上記のように記述して、一気に値を変えてしまいます。

HEX

UIに表示する数字を10進数にしたい場合は、 HEX=FALSE を利用してください。

NAME=最大レベル
NAME.en=Max Level
NAME.zh=最高级别

//アドレスパッチとして実装します
TYPE=ADDR

ADDRESS=0x25132
HEX=false //レベルなので10進数で表示します.


https://i.imgur.com/cRQavFM.jpg

ADDRESS_TYPE

値に関連付けたいものがある場合 ADDRESS_TYPE を利用してください。

ADDRESS_TYPE=UNIT //ユニットIDとして扱います
ADDRESS_TYPE=ITEM //アイテムIDとして扱います
ADDRESS_TYPE=CLASS //クラスIDとして扱います
ADDRESS_TYPE=SONG //音楽IDとして扱います
NAME=進撃準備
NAME.en=MUSIC_Preparation
NAME.zh=MUSIC_提前准备
//アドレスパッチとして実装します
TYPE=ADDR

ADDRESS=0x080495cc 0x080af17e 0x08031654 0x08090048 0x080960b4 0x0809b880 0x0809c7f6
ADDRESS_TYPE=SONG //進撃準備BGMを変更するので音楽IDとして扱います


https://i.imgur.com/gen0Pz4.jpg

パッチの種類 IMAGEパッチ


TYPE=IMAGE

画像を変更するパッチを定義します。
このパッチは、画像アドレスではなく、ポインタで書く必要があります。
なぜなら、画像は可変長なので、画像アドレスが変更される可能性があるためです。

以下は、FE8Jの FIN を変更するパッチです。

NAME=SYSTEM_FIN

TYPE=IMAGE

WIDTH=256
HEIGHT=160
//利用パレット数
PALETTE=1

//圧縮画像
ZIMAGE_POINTER=0xBBF48
//非圧縮ヘッダー付きTSA
HEADERTSA_POINTER=0xBBF54
//非圧縮パレット
PALETTE_POINTER=0xBBF44


https://i.imgur.com/oEtDONy.jpg

無圧縮の画像
IMAGE_POINTER

圧縮された画像
ZIMAGE_POINTER

圧縮TSAを利用する
ZTSA_POINTER

圧縮ヘッダー付きTSAを利用する
ZHEADERTSA_POINTER

無圧縮ヘッダー付きTSAを利用する
HEADERTSA_POINTER

無圧縮パレットを利用する
PALETTE_POINTER

画像の表示とインポート時に使われます。
以下の例だと、256x160の大きさの画像で、16色のパレット1種類を保持していることが条件になります。

WIDTH=256
HEIGHT=160
//利用パレット数
PALETTE=1


画像パッチを書くのは大変なので、自動的に生成することができます。
メニュー->ツール->グラフィックツール で、画像を探して、TSA等を探り当てたのち、右下のPatch Makerボタンをクリックすると、全自動でパッチを作ってくれます。
いちいち、ポインターを手で計算する必要はありません。

https://i.imgur.com/WHG6zIQ.jpg

https://i.imgur.com/LTklo5l.jpg

https://i.imgur.com/Qj0vh2c.jpg


パッチの種類 STRUCTパッチ

TYPE=STRUCT

構造体パッチ

構造体のようにデータを変更したい場合使います。
ただし、ツール本体でやっているような高度なことはできません。
難しいものを作りたく、それが汎用化できる場合、ツール本体側で作るべきです。

//STRUCTパッチとして実装します
TYPE=STRUCT

//データへのポインタ
POINTER=$GREP4END 0x00 0xB5 0xC0 0x46 0x06 0x48 0xC0 0x46 0x06 0x49 0x89 0x7B 0x89 0x00 0x40 0x58 0x01 0x21 0x00 0xF0 0x02 0xF8 0x17 0x20 0x00 0xBD 0xC0 0x46 0x02 0x4B 0x9F 0x46

//ユニット クラス 0x00 0x00 アニメ設定ポインタ
//データサイズ(10進数)
DATASIZE=8

//データ個数(10進数)
DATACOUNT=12

//データを定義します
//P0 ポインタ が 0バイトからあります
//その型は EVENT 
//名前は、イベントポインタとしました。
B0:UNIT=ユニット
B1:CLASS=クラス
B2=00
B3=00
P4:BATTLEANIMENAME=アニメ設定


https://i.imgur.com/NOQORUH.jpg

FE8ユグドラパッチの個別アニメを設定するパッチです。
怪盗パッチには追加構造体がないので、ユグドラを例に説明します。

B0:UNIT=ユニット
B1:CLASS=クラス
B2=00
B3=00
P4:BATTLEANIMENAME=アニメ設定

↓↓↓↓↓

struct 
{
	byte	unit;			// +0
	byte	class;			// +1
	byte	zero1;			// +2
	byte	zero2;			// +3
	void*	battleanime;	// +4
};



b	sbyte( char )	-128 ~ 127
B	byte			0 ~ 255
W	word			0 ~ 65535
D	dword			0 ~ 4294836225
P	dword			0 ~ 4294836225


D と P の違いについて
Pの場合、必ずポインタとして記録されます。
ユーザが、 0x123 と入れた場合、 Dでは 0x123 と記録しますが、 Pだと、 0x08000123 として記録します。


パッチの種類 BINパッチ

type=BIN
バイナリデータとソースコード

NAME=SOUND_NIMAP(Native Instrument Map)

TYPE=BIN

PATCHED_IFNOT:$GREP4 0x00 0x3C 0x00 0x00 0x68 0x27 0x50 0x08 0xFF 0xFA 0x00 0xCC 0x00 0x3C 0x00 0x00 0x18 0x7D 0x29 0x08 0xFF 0xFA 0x00 0xCC 0x00 0x3C 0x00 0x00 0x3C 0x8E 0x28 0x08 0xFF 0xF9 0x00 0xA5 0x01 0x3C 0x00 0x00 0x02 0x00 0x00 0x00 0x00 0x00 0x0F 0x00=0x00 0x3C 0x00 0x00
BIN:$FREEAREA=JAPFE8_NI_Map.bin
INFO=Midi Instrument Map



https://i.imgur.com/oB9KLti.jpg

JAPFE8_NI_Map.bin を、適当な $FREEAREAに貼り付けます。
2回貼り付けるとまずいので、 $GREP4 で、適応しているかどうか調べています。

マクロ
$FREEAREA	フリーエリア
$GREP4		バイト列を検索 ただし4バイト単位(高速)
$GREP1		バイト列を検索 ただし1バイト単位(低速)
$GREP4_NOT	バイト列を検索して見つからないこと
$GREP1_NOT	バイト列を検索して見つからないこと




NAME=10分割CG表示

//BINパッチとして実装します
TYPE=BIN

//パッチ適応条件
PATCHED_IF:0x080bb182=0x45 0x46 0xE0 0xB4

BIN:$FREEAREA=show_10split_image.bin

//10分割画像表示ルーチンを入れたところに飛ばす
JUMP:0x080bb182:$r4=show_10split_image.bin

INFO=10分割CGを表示できるようにします


https://i.imgur.com/41kVbuk.jpg

show_10split_image.binを、フリーエリアに貼り付ける。
貼り付けた、データに対して、飛ばすコードを生成する。この時、r4レジスタを利用する。

ジャンプするコードは、以下のようなコードが生成されます。

アドレスが4バイトで割り切れる場合 (addr%4 == 0)
ldr r4,[JUMP ADDR]		//+0
mov pc,r4;				//+2
JUMP ADDR				//+4  -->合計 8バイト

ただし、2バイトで割り切れる場合 NOPが差し込まれます。

NOP						//+0
ldr r4,[JUMP ADDR]		//+2
mov pc,r4;				//+4
JUMP ADDR				//+6  -->合計 10バイト

オフセット追加

JUMP:0x080bb182:$r4:+2=show_10split_image.bin


こうすると、 show_10split_image.bin の設置場所+2 のアドレスへジャンプできます。


直値 $NONE

JUMP:0x080bb182:$NONE=show_10split_image.bin


ジャンプコードを生成せずに、 show_10split_image.bin を設置したアドレスをそのまま書き込みます。
アドレスなので4バイト消費します。書き込むアドレスはリトルエンディアン形式です。

実用的な使い方としては、設定からコードへ飛ばすところで使うと思います。

//メニュー効果に、指南プログラムのアドレスを書き入れます.
//直値を入れるので、レジスタ関係ないので $NONE
//直値の場合 アドレス+1 にしないといけないので、 +1 
JUMP:0x5C53A8:$NONE:+1=main指南本体.bin


B ジャンプ生成

JUMP:0x988c6:$B=0x9893a


0x988c6 のアドレスに、 b 0x9893a のASMオペコードを生成します。
b ジャンプなので、あまり遠くへは飛べません。
b ジャンプなので2バイト消費します。


BL ジャンプ生成

JUMP:0x340cc:$BL=0x988c8


0x340cc のアドレスに、 bl 0x988c8 のASMオペコードを生成します。
bl ジャンプなので、あまり遠くへは飛べません。
bl ジャンプなので4バイト消費します。


テキスト拡張命令

EXTENDS:0xe30=TEXT    //テキストテーブルを 0xe30 まで拡張します
TEXT:0x0e01=0x0e01.txt  //テキスト 0xe01 に 0x0e01.txt の内容を書き込みます.
TEXT:0x0e02=0x0e02.txt
TEXT:0x0e00=0x0e00.txt


テキストテーブルの拡張と書き込みをサポートしています。
ただし、今のところ、他のテーブルの拡張はできません。

パッチの種類 EAパッチ

TYPE=EA

EA=ea.event


https://i.imgur.com/WaVR6Ro.jpg

Event Assemblerを利用して、データを追加します。
現在のROMに、EAで指定した、Event Assembler scriptの内容を追加します。

MOD

パッチのパラメータとして、構造体の未使用領域を利用したいときがあります。
FEBuilderGBAでは、patchディレクトリ内にMOD_*.txtを作成すると利用できます。

IF:0x89268=0x00 0x4B 0x9F 0x46
FORM=UnitForm   //UnitForm(FE8用)で動作します
J_38=スキル1
J_39=スキル2
J_49=個人スキル
J_38:NAME=J_38_SKILLASSIGNMENT_SCROLL1_B39
J_39:NAME=J_39_SKILLASSIGNMENT_SCROLL2_B38
J_49:NAME=J_49_SKILLASSIGNMENT_MASTERY


ただし、MODに設定するパラメータは、FEBuilderGBAのC#内に使われているラベル名になりますので、ソースコードを理解する必要があります。
また、欧米の改造では、未使用領域ではなく、独自に構造体を作ってしまうことが多いように思います。
そう考えると、MODは日本の改造で多く使われる機能かもしれませんね。