fc2ブログ

記事一覧

Em任意コード実行によるイベントスクリプトの実行【汎用コード】

現在、ブログでのコメントの返信は停止しております
返信を希望されるコメントについてはお手数ですがYouTubeの当方のチャンネルに投稿されている適当な動画に書き込みくださいますようお願いします


実践動画↓

【イベントスクリプトの概説】
アイテムの入手や固定シンボルポケモンとのエンカウントなどフィールド上で起こる各種イベントは、イベントスクリプトと呼ばれるフィールド上イベント用に予め用意されたプログラムを専用のコード(スクリプトコード)を用いて呼び出すことで実行している。
下記はFRLG用の資料であるが、Emもほぼ共通のコードでイベントスクリプトが用意されている。
https://wikiwiki.jp/pokemonhack/イベントスクリプト
https://wikiwiki.jp/pokemonhack/Specialコード

任意コード実行で任意のポケモンやアイテムを入手したい場合、態々手製のプログラムコードを用意しなくとも、イベントスクリプトを利用すればゲーム内に存在するプログラムを使って短い命令コードで目的の動作を再現することが出来る。



【汎用コードの概説】
イベントスクリプトの実行には特殊なメモリ操作が必要であり、任意のスクリプトの実行には専用のプログラムを組む必要がある。

この度私が作製したのは、ボックス名11〜13の3箇所だけを使って、ボックス名1〜10に記述したスクリプトを実行出来るようにするプログラムである。
このプログラムだけで凡ゆるイベントスクリプトと手製の任意プログラムを実行可能であり、このプログラムコードを汎用コードと呼称している。



【Em汎用コード環境の導入】
Emの任意コード実行にはバグポケモン0x085Fを使う方法が最良なので、0x085F向けの汎用コード環境の導入手順を紹介する。
0x085Fの入手方法についてはこちらを参照。


まず0x085Fの入手の時点から引き続いて、ボックス12の12番目からボックス14の30番目までを全て空きにしておき、ボックス名を以下のように変更する。

ボックス名1:[かッンNリGゲタ]
ボックス名2:[みくィぃBFC]
ボックス名3:不問
ボックス名4:[アタぢいいあ ]
ボックス名5:[ォッいべぞね び]
ボックス名6:[アあいうに  ]


そして、手持ちの3番目を空きにし、0x085Fの様子を見て任意コード実行をする。
すると、手持ちの3番目にNN[ォッいべぞ]の色フシギダネが生成される。
20200517014028d5c.jpeg
このフシギダネをとする。

生成した①を一旦退かして再度手持ちの3番目を空きにし、先程のコードの内ボックス名5[ャl]([l]は小文字L)に変更してからもう一度任意コード実行をする。
すると、今度はNN[ャl]の色フシギダネが生成される。
202005170140303f1.jpeg
このフシギダネをとする。

ボックス1215番目ボックス1428番目に配置し、ボックス名11〜13を以下のように変更する。

ボックス名11:[うッゃNさRまK]
ボックス名12:[アぃBFCあい]
ボックス名13:[pぬういぎせ う]


202005170140319a4.jpeg
①と②、上記コードを併せて汎用コード環境の整備が完了する。
今後は前3マス前後2マスにはポケモンを置かないようにし、①と②の配置場所、及びボックス名11〜13の名前は基本固定とする。



【汎用コードを使った任意スクリプト実行】
汎用コード環境下では、任意コード実行によりボックス名1〜10に記述した任意のスクリプトコードを実行することが可能である。
また、ボックス名1〜4内に専用のスクリプトコードを入力することで、ボックス名5〜10,14に記述した任意のプログラムコードの実行も可能となる。

以下にスクリプトコード入力時の注意点について解説する。
また、有用性の高いサンプルコードを纏めたものをこちらに用意した。


〜ボックス名データの構造について〜
ボックス名データのサイズは1つ当たり9バイトで、一度でも名前を変更したことのあるボックス名データは以下のような構造となっている。

XX XX XX XX XX XX XX XX FF

前8バイトが文字コードを入力する可変部で、実際にボックス名として表示される部分である。
終端部9バイト目のFFはボックス名の終了コードとして機能しており、(一度でも名前を変更したことのある)各ボックス名データに必ず存在し、且つ変更不可である。

このFFは他にも、入力したボックス名の文字数が7文字以下であった場合に、可変部の使用されなかった領域全てに終了コードとして埋め込まれる
例えば、ボックス名に[もけぬうい]と入力すると、バイナリデータは以下のようになる。

23 09 17 03 02 FF FF FF FF

6〜8文字目が不使用なので、可変部の該当する領域全てにFFが入る。

こうした9バイトのボックス名データが、14つ分連続して並んでいる。


〜スクリプトコードの入力方法について〜
スクリプトコードの入力は、目的のスクリプトコードと同じ番号の文字コードの文字を入力するだけでよい。
例えば、パソコン内にアイテムを追加するスクリプトコード49(c49)を入力したければ、文字コード49[べ]を入力する。

c49の場合、後ろに引数としてアイテムの種類(2バイト)と個数(2バイト)の指定も必要で、このような引数への数値データの入力についても同じく同値となる文字コードの文字を入力すればよい。
ただし、リトルエンディアンでの入力となるので、数値データは1バイト毎に分割して逆順に入力しなければならない点に注意が必要。
例として、マスターボール(0x000101 00)を999個(0x03E7E7 03)追加とする場合、入力コードは[べあ_sう](49 01 00 E7 03)となる。


〜終了コードとNOPコードについて〜
スクリプトは終了コードを読み込むことで実行を終了する。
逆に、記述したスクリプトコードの終端には必ず終了コードを用意しておかないと、意図しないスクリプトを実行したりフリーズすることがある。
イベントスクリプトの終了コードとして機能するコードは主に以下の2つである。

・c02[い]
・cFF[終](テキスト終了)


c02はゲーム内で主に使用されている、イベントスクリプト終了コードの基本である。
cFFは文字コードの終了コードでもあるが、実はスクリプトの終了コードとしても機能する。

前述の通り、各ボックス名の終端部には必ずFFが存在していて、可変部の使用されなかった領域にもFFが埋め込まれるようになっている。
つまり、ボックス名にスクリプトコードを記述する都合上、必然的にコードの終端にはcFFが用意されるのである。
要するに、スクリプトコードを記述する際、終了コードはゲーム側が勝手に用意してくれるので、終了コードの入力は不要なのである。

逆に、各ボックス名には必ずFFが存在することになるので、無対策だとボックス名1つ分のコードを読み込んだだけでスクリプトの実行が終了してしまうことになる。
この対策として、FFを回避する為のNOPコードというものを使用する。
NOPとはノーオペレーション即ち"何もしない"という意味で、何もせずそのまま次の命令に移動するだけの無操作命令のことである。
NOPコードには以下のようなものがある。

・c00[_](スペース記号)
・c01[あ]
・97 FF[ビ終]([終]は終端部FF)


c00とc01は、それ単体(1文字)でNOPコードとして機能する。
これらの使用により可変部FFの割り込みを防ぐことが出来る。

97 FFは、元々は画面フェード効果再生スクリプトc97のコードであるが、引数にFFを指定することでNOPコードとなる。
終端部FFを終了コードとしてではなくc97の引数として読み込ませることで、NOPコードとして通過させ後続のボックス名に記述されたスクリプトコードの実行が可能となる。

終了コードとNOPコードの具体的な使用例を以下に記す。

ボックス名1:[べあ sうああ]
ボックス名2:[べで sう]

まずボックス名1に[べあ sう](パソコン内にマスターボール×999個追加)というコードを入力し、ボックス名2の[べで sう](パソコン内に不思議な飴×999個追加)を続けて実行する為に、ボックス名1の8文字目に[]を入力して終端部FFを97 FFのNOPコードに変化させ、[]までの空いた隙間をNOPコード[]([_]でも可)で埋めることで可変部FFの割り込みを防ぐ。
[べで sう]実行後はその直後の可変部FFによる終了コードの機能によりスクリプトの実行が終了となる。


〜任意プログラムの実行方法について〜
スクリプトc23[も]はThumb形式のアセンブリ言語プログラムを実行するスクリプトで、その後ろにはプログラムの開始アドレスを指定する4バイトの引数を取る。
Em汎用コードでは、以下に記すc23を使用した専用スクリプトコードを実行することで、ボックス名5〜10,14に記述した任意プログラムコードを実行することが出来る。

・[もけぬうい]
・[もけぬ終い]([終]は終端部FF)


前者の指定アドレスは0x02031709で、後者は0x02FF1709となるが、この2つのアドレスは全く同じ意味を持ち、どちらもフシギダネ②のNNにアクセスしてボックス名5にジャンプする流れとなっている。

基本的には前者を使用すればよいが、任意乱数値指定プログラムなど他のスクリプトと連係して実行する必要があるプログラムの場合には後者を使用する必要がある。
スポンサーサイト



コメント

いつも楽しくブログを拝見させていただいてます。
任意コードについて質問などをしたりしたいのですが、ツイッターを始める予定はございますか?

No title

初めまして。ハタチューと申します。任意コード初心者です。
様々な記事を拝見させていただきました。この記事に書かれている、フシギダネ①、②の作成に成功して、ボックスへの配置も完了しました。
そこで、試しにこの記事に書かれていたマスターボールと不思議な飴を999個ボックスに追加するコードを入力してみようとしました。
ボックス名を変更するところまでは良かったのですが、変更した後は何をすれば良いのかがわかりませんでした。フシギダネを生成したときのように0x085Fの強さを見れば良いのかと考えましたが、フリーズしてしまうので違うのだと判断しました。どうか教えていただけると嬉しいです。

No title

ボックス名を変えて手持ちの3番目を空ける所まで行きましたが0x085Fの様子を見ても色フシギダネ生成がされません。
他に成功条件があるのでしょうか?

No title

ダブルスロットでポケモンを送ったことがあるデータの場合、ボックス12~14に一度ポケモンを置き移動させる(輸送しても残留データが残っている場合があるのでそれの除去をしないと成功しない)
フシギダネのNNをミスると汎用コード実行時フリーズする場合有り。
ようつべコメントから

Re:ボックス名を変えて手持ちの3番目を空ける所まで行きましたが0x085Fの様子を見ても色フシギダネ生成がされません。 他に成功条件があるのでしょうか?

本記事ではボックス3の名前を不問としていますが、おそらくボックス3の名前は何らかのものに変えておく必要があると思います。私もこの作業を行ったのですが、最初は成功せず、ボックス3の名前を変えると成功しました。参考にしていただけると幸いです。長文コメント失礼しました。

管理人のみ閲覧できます

このコメントは管理人のみ閲覧できます

色フシギダネが生成されない

ボックス1~6までの名前を変更し、
任意コード実行をしたのですが
ダメタマゴが生成されてしまいます。
確率は100%ということですが、ザロクバグによるタマゴの生成も間違っていなかったと思うのですが、
お時間がありましたら是非解決法を教えてください。

コメントの投稿

非公開コメント