お久しぶりですFreedomです。
前回の講座でフックしたいプログラムコード群を見つける方法を紹介しました。
今回はそこに自分の処理、すなわち武装新規装填の処理を挟み込んでみます。
大まかな流れを説明したあと、実際にデュエルASのコードを使って観察してみます。
まず武装を新規装填してくれる命令を紹介します。
jal $089F78A0 という命令が武装を新規に装填してくれる命令です。
この命令はいわばお使い命令で、右のアドレスに飛んで命令を実行して帰ってきてくれるというものですね。
ただし、おつかいにあたって何をしてほしいか伝えてあげなければフリーズしてしまいます。
よって今回の場合は3つのレジスタに必要な情報を与えてから、jal命令を実行しなければなりません。
まず1つ目、a0レジスタにはs3の値をそのままコピーして与えます。
「mov a0, s3」というような命令を実行するのが内部的には主流のようです。よって流用。
そして2つ目、a1レジスタには何番目の武装を装填するかを指定します。
「li a1, $xxxx」というように即値でお目当ての武装の番号を与えましょう。
仕上げに3つ目、a2レジスタにはs3の値に890h足したものを与えましょう。
「addiu a2, s3, $0890」という命令が主流らしいのでそのまま使います。パクれ。
1つ目と3つ目はプログラム的に必要なアドレスです。機体によってはs3の部分がs0だったりとまちまちなのですが説明が煩雑になるのを防ぐべく詳しくは割愛。
各自で調べてもらうかのちほど質問してください。
これで新規装填の準備ができました。お目当ての武装が新規に発射されていれば成功というわけです。
では実際にデュエルASのCSにサブのミサイルを追加してみます。
_C1 NEW Duel KCS P
_L 0xE11E0034 0x009B6020
_L 0x21700000 0x24050001
_L 0x21700004 0x0E27DE28
_L 0x21700008 0x26660890
_L 0x2170000C 0x02602021
_L 0x21700010 0x24050002
_L 0x21700014 0x0E27DE28
_L 0x21700018 0x26660890
_L 0x2170001C 0x02602021
_L 0x21700020 0x24050003
_L 0x21700024 0x0E27DE28
_L 0x21700028 0x26660890
_L 0x2170002C 0x02602021
_L 0x21700030 0x24050004
_L 0x21700034 0x0E27DE28
_L 0x21700038 0x26660890
_L 0x2170003C 0x02602021
_L 0x21700040 0x24050005
_L 0x21700044 0x0E27DE28
_L 0x21700048 0x26660890
_L 0x2170004C 0x02602021
_L 0x21700050 0x24050006
_L 0x21700054 0x0E27DE28
_L 0x21700058 0x26660890
_L 0x2170005C 0x02602021
_L 0x21700060 0x24050000
_L 0x21700064 0x0E27DE28
_L 0x21700068 0x26660890
_L 0x2170006C 0x02602021
_C1 NEW Duel KCS P
_L 0xE11E0034 0x009B6020
_L 0x213CFDF0 0x0A7C0000
_L 0x213CFDF4 0x00000000
_L 0x213CFDF8 0x00000000
_L 0x213CFDFC 0x00000000
_L 0x21700070 0x24050012
_L 0x21700074 0x00003021
_L 0x21700078 0x0E21A5E5
_L 0x2170007C 0x00003821
_L 0x21700080 0x02602021
_L 0x21700084 0x0A6F3F80
_L 0x21700088 0x00000000
このようなコードで追加することができます。
前回の講座で学んだフックを仕掛けて自作プログラムの領域(0x01700000あたり)に誘導し、
そこで先ほどのjalを何度も実行(ループ処理を使わないやべぇやり方)して新規装填しています。
今回はs3レジスタに基準となるアドレスデータが格納されてるようだったので、s3をa0に移しつつ、890h足したものをa2に代入しました。
またjal命令の重要な性質として、遅延スロッドというものがあります。
これはjal命令が実行されたとき、同時に1行下の命令も実行されるというもの。
よってjal命令は1行下の命令とセットで扱うのがセオリーとなっています。
このコードではaddiuが遅延スロッドにあたります。
以上のような手順でほかの機体にも武装を新規に追加することができます。
補講
コメントにあった疑問にお答えします。
武装ゲージ1の武装を武装ゲージ2に移植したとき、武装ゲージ2に残弾があっても武装ゲージ1が残弾0の場合、
カチャカチャと弾切れ音がしてしまいます。(??「弾切れなのかっ!?」)
これは武装を移植しても弾切れ判定が武装ゲージ1を参照し続けているためにおこる不具合です。
これを解消し、適切にゲージ2を参照させる方法が見つかりましたのでここに併記します。
_C0 TAMAGIRE address on (program)
_L 0x21700000 0x27BDFFF0
_L 0x21700004 0xAFB10004
_L 0x21700008 0x00000000
_L 0x2170000C 0x00051080
_L 0x21700010 0x00451021
_L 0x21700014 0x3C1109F0
_L 0x21700018 0xAE300050
_L 0x2170001C 0x00000000
_L 0x21700024 0x3C11091B
_L 0x21700028 0x00000000
_L 0x2170002C 0x8FB10004
_L 0x21700030 0x03E00008
_L 0x21700034 0x27BD0010
_L 0x201B7584 0x0E7C0000
_L 0x201B7588 0x00000000
_C0 TAMAGIRE address off (program)
_L 0x41700000 0x000E0001
_L 0x00000000 0x00000000
_L 0x201B7584 0x00051080
_L 0x201B7588 0x00451021
_L 0x21700050 0x00000000
プログラムコードなので解析して使い終わったら下のoffコードを実行して消したほうが空きアドレスの他のコードとの干渉を防げるかもしれません。(デュエルとおもっきしかぶってる)
このコードを使うと0x01700050にアドレスが表示されます。対象の射撃武装を発動した直後に見てください。
このアドレスの先には以下のような情報が含まれています。
1行目 08AC3148
2行目 00bb00aa
3行目 000000cc
4行目 00dd0000
5行目 FFFF00ee
6行目 000000ff
7行目 00000000
8行目 00000000
9行目 00gg001E
10行目 000100hh
※足止め武装の場合
15行目 3F800000 上下方向の慣性の残し方
16行目 3F800000 左右方向の慣性の残し方
1.0で等速直線運動。1.1とかでもものすごく加速するので危ない、最悪フリーズ。通常は1.0以下で指定すること。
それぞれの値の説明
aa モーションの大別 移動射撃モーションは04 足止め射撃は06 値を変えると格闘がでたりもする。
bb 射撃武装を持った状態の最初のモーション(いわゆる振り向き動作) 上と合わせてaabbがモーション番号になる
cc 格闘武装を持った状態の最初のモーション 上と合わせてaaccがモーション番号になる
dd 射撃武装が発射されるモーション 上と合わせてaaddがモーション番号になる
ee 武装をしまうモーション 上と合わせてaaeeがモーション番号になる
これらは0x009BC45F 0x009BC460 にある現在再生されているモーション番号2つと同様の形式であり、これと一致するはず。
ff WA☆KA☆RA☆N!
gg 武装の発動時に弾切れだった場合にどうするかの値。通常は1にしておく。
CSなど弾切れという概念がない武装の場合2にしておく。すると弾切れのカチャカチャ音がなくなる。
hh 弾切れの確認をどのゲージに行うかの値。例えばもともと1つ目のゲージの武装だったものを、
2つ目に移植した場合、ここの値を2つ目の武装ゲージの値にしなければならない。
さもなくば2つ目のゲージの残弾があっても、1つ目のゲージが残弾0だとカチャカチャいってしまう。これはむかつくので変えよう!
上のプログラムコードで見つからない場合は1行目の08AC3148hで0x013D0000あたりをサーチしてください。
いくつかヒットすると思うので上記の値を変更するなどして様子を見て探してください。
プログラムコードの知識が前提としてかなり必要な講座となってしまいました。
質問があればコメ欄へどうぞ。