最新の10件
ページ | 日付 |
---|---|
en:guid:febuildergba:work_support | 2023/06/08 20:25 |
guide:febuildergba:作品支援 | 2023/06/08 20:24 |
最新の10件
ページ | 日付 |
---|---|
en:guid:febuildergba:work_support | 2023/06/08 20:25 |
guide:febuildergba:作品支援 | 2023/06/08 20:24 |
イベント命令の 40 0D から始まる命令で、呼び出される、自前asm関数について解説する。
イベント命令から自前のasm関数呼ぶには、以下のようにする。
40 0D 00 00 アドレス+1
例: 40 0D 00 00 81 F6 E4 08
これで、 0x08E4F680 に設置した関数を呼び出すことができる。
これで↓が呼べる @org $08E4F680 @thumb push {lr} ここに好きな処理 mov r0, #0 pop {pc}
r4以降のレジスタを壊す場合は pushするのが望ましい(多分?)
@org $08E4F680 @thumb push {r4,r5,r6,r7, lr} ここに好きな処理 mov r0, #0 pop {pc,r7, r6 , r5 ,r4 }
UCHAR2つ(USHORT値)の引数を取ることができる。
r0 or r3 or r4 = 0x02025018 + 0x38 offset = 2025050 (アドレスは進捗状況によるかも)
ここに、実行しているイベント命令へのポインタがある。
ldr r0, [r0, #0x38] //イベント命令にアクセスらしい [r3,#0x38] でイベント命令が書いてあるアドレスの場所へ
ldrb r1, [r0, #0x2] //引数1 40 0D [引数1] [引数2] [プログラム場所 XX XX XX 08]
ldrb r2, [r0, #0x3] //引数2 40 0D [引数1] [引数2] [プログラム場所 XX XX XX 08]
例: 40 0D 11 22 81 F6 E4 08
@org $08E4F680 @thumb push {lr} ldr r0, [r0, #0x38] //イベント命令にアクセスらしい [r3,#0x38] でイベント命令が書いてあるアドレスの場所へ ldrb r1, [r0, #0x2] //引数1 40 0D [引数1] [引数2] [プログラム場所 XX XX XX 08] ldrb r2, [r0, #0x3] //引数2 40 0D [引数1] [引数2] [プログラム場所 XX XX XX 08] ;以下のようになる ;r1 = 11 ;r2 = 22 ここに好きな処理 mov r0, #0 pop {pc}
ldrh を使えば、 unsigned short で取れる。
ldr r0, [r0, #0x38] //イベント命令にアクセスらしい [r3,#0x38] でイベント命令が書いてあるアドレスの場所へ ldrh r2, [r0, #0x2] ;引数1 40 0D [11] [22] [プログラム場所 XX XX XX 08] ;→リトルエンディアンなので、 0x2211 が取れる。
イベントフラグにアクセスしたり、アセンブラなので全メモリ空間にアクセスできるため、情報は好きなだけ取れる。
一部関数(魔王出現エフェクト 08081bb6)などで、 r0 == 0 のチェックをしている箇所がある。
今のところ確認できていないが、関数呼び出しがされた結果、 r0 == 0 になることがあるのかもしれない。
もし、見かけたら教えてほしい。
イベント命令の条件式として利用するには、以下のようにする。
ldr r2, =$030004B0 ; + #0x30 str r0, [r2, #0x30] ;条件式で取れる領域に書き込む
例:
所持金で分岐する場合とか。
;所持金チェック 所持金が指定ゴールド以上かどうか ;gold_find.asm ; ;40 0D [11] [22] E1 F6 E4 08 ; ;-> 0x2211ゴールド(8721ゴールド) @org $08E4F6E0 @thumb push {lr} ldr r0, [r0, #0x38] ;イベント命令にアクセスらしい [r3,#0x38] でイベント命令が書いてあるアドレスの場所へ ldrh r2, [r0, #0x2] ;引数1 40 0D [引数1] [引数2] [プログラム場所 XX XX XX 08] ;所持金 ldr r3, =$0202BCF4 ;所持金を取得 ldr r1, [r3,#0x0] mov r0, #0x0 cmp r1,r2 ;お金の比較 BLT exit_result ;お金がなければ、 exit_result へ mov r0, #1 ;金があるなら・・・ exit_result ldr r2, =$030004B0 ; + #0x30 str r0, [r2, #0x30] ;条件式で取れる領域に書き込む mov r0, #0 pop {pc}
イベント命令をこんな感じで作る。
400D50C3''不明 //5万ゴールドの確認 gold_find.asm 0x50C3=>50000 E1F6E408''不明 4005050001000000''[05]条件作成終わり??? 410C05000C000500''条件成立時にイベントID[0005]で以下を実行[05]2??? 2016B900''[B9]効果音 //5万ゴールドぽんとくれたぜ 201A0000''会話開始 //あざーす 201B5D05201D0000''[055D]背景無会話表示 20090400''不成立時に条件イベントID[0004]で以下を実行 20080500''条件イベントID[0005]終了 201A0000''会話開始 //カネがないのかよ 201B5E05201D0000''[055E]背景無会話表示 20080400''条件イベントID[0004]終了
なお、イベント命令の分岐の書き方は、他にもある。
会話テキストで、@0080@0005 で10進数で取ることができる。
ただし、@0080@0005 が使えるのは、吹き出しの会話のみ。システムメッセージでは取れない。
例
;r0に格納されている数字を @0080@0005で取れるように書き込む ;注意:@0080@0005は会話でしか取れない。システムメッセージでは読めないらしい mov r0,r7 ldr r1,=$08008914 mov lr, r1 @dcw $F800
↓こういうふうに使います。
@0080@0005ゴールドもっているかい?@0003
asmなので、全メモリにアクセスできる。(ただし、一部領域は例外)
ldrでデータを読み出して、 strでデータを書き込もう。
関数を呼び出したりなんでもできます。