ユーザ用ツール

サイト用ツール


サイドバー

guide:イベント命令での自前関数呼び出し

イベント命令の 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以降のレジスタの保存

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でデータを書き込もう。
関数を呼び出したりなんでもできます。

guide/イベント命令での自前関数呼び出し.txt · 最終更新: 2018/09/09 00:42 (外部編集)