■ 新・ゲーム開発講座 |
■ へっぽこプログラミング入門♪ |
■第48夜:SAVEデータのパッケージ ファイル入出力の基礎、画像ファイル名のキャッシュ処理ができたところで、今回はSAVEデータのパッケージ部分をインプリメントしましょう。ソースはこちらです(ようやく動くソースだ…^^;)。 ■仕様 スクリプト上で明示的にSAVEポイントを表すコマンドを定めます。正規表現(笑)と短縮表記をそれぞれ以下のように定めます。パラメータはありません。
#save_point コマンドは、コマンド実行時の以下の内容を、SAVEファイル構造体にコピーします。後日インプリメントするシステムメニューのSAVEが選択されたとき、この構造体の中身をDISKに書き出します。
■Mode_stat #save_point は一発完了型のコマンドなので、フラグ構造体
Mode_stat に新規メンバを加える必要はありません。 もういい加減ルーチンワークですが、一応解説しておきましょう(^^;) |
void Command_call() //「#」を見つけたところでこの関数を呼ぶと、「#」に //続くコマンド名を解析してその処理関数を呼びます {
|
■コマンド実行部 Text_Com_04.cpp
に 実行部を追加します。make_save_info() というのが処理の本体ですが、後日解説するSAVEポイントの自動生成で流用したいので処理本体を分割記述しました。ちょっとわかりにくくてすみません(汗)
で、SAVEポイント生成(=データのパッケージ)の本体部分は SystemMenu_01.cpp に加えることにしました。記述が分散してしまって申し訳ないのですが、くににん的脳内ではスクリプトコマンドは Text_Comなんたら.cpp、システムメニュー絡みの処理は SystemMenu_01.cpp に記述するというローカルルールがあるのでこんなことになっています。わかりにくかったらソースの切り貼り等みなさんで手を加えちゃってください (汗 ^^;) ではいよいよデータのパッケージ部分です。SystemMenu_01.h にSAVE構造体を以下のように宣言します。ファイル名1個あたり512byteとゆーのはちょっと大袈裟かもしれませんが、理論上はファイル名は256byteまで許されていますし、スクリプターがサブフォルダを掘ってスクリプトを格納する可能性もあるので多少の余裕をみておくことにします。 |
//SAVEファイル typedef struct _Save_stat {
extern _Save_stat Save_stat; |
ところでSAVEデータパッケージを作るにあたって、プログラマが絶対に守るべき掟がひとつあります。
↑これは絶対に守らなければなりません。ポインタはメモリの特定のアドレスを指し示していますが、一度SAVEしたデータを再ロードしたとき、以前のメモリ内アドレスが完全に再現する保証はありません (…といいますか、まずそんなことは無い)。ゲーム実行中にポインタで管理していたデータは、基準アドレスからのオフセットの形で保存しなければ危険です。 本稿のソースの中で、この制限に引っ掛かるのはテキストインタプリタの実行位置を示す *TEXT です。ところでテキストの実行位置は、スクリプトを格納するバッファ TEXT_BUF からの距離でも表すことができるため、int offset = TEXT - TEXT_BUF のようにポインタ同士の引き算でオフセット値に置き換えることができます。この基準アドレスからのオフセット量を保存するようにすれば、不都合はありません。いざデータを再LOADしたとき、メモリ内に確保されたバッファ TEXT_BUF の先頭アドレスはSAVE時と異なるかもしれませんが、TEXT = TEXT_BUF + offset とすれば *TEXT はバッファに読み込まれたスクリプトファイルの正しい位置を指し示します。 では、そのデータをパッケージする部分を見てみましょう (SystemMenu_01.cpp)。基本的にパラメータの単純コピーで、ポインタの部分だけ Save_stat.TEXT_offset = TEXT - TEXT_BUF とポインタ同士を引き算してメモリ上の距離=オフセット値を求めています。 |
_Save_stat Save_stat; //SAVEファイル構造体 void make_save_info()
|
■動作を確認しよう さて、今回は動作確認のために関数の最後にDISKへの強制書き出しを記述しています。 さて冗談はともかく、さっそく実行して動作を確認してみましょう。今回から、動作確認のため必要に応じてMIDIを鳴らしています。MIDIファイルは鷹月ぐみな情報局のフリーサウンドライブラリ(曲数が尋常ではないです ^^;)から、みくしぎまさき氏の曲を使わせて頂きました。素敵な曲をありがとうございます。 |
|
表面上は何も起こったようにみえませんが、フォルダ SAVE の中に test.svd という記念すべきSAVEデータ第一号ができています。さっそく、バイナリエディタで中身を覗いてみましょう。バイナリエディタはフリーの優れたものがネット上でも多く出回っています。くににんは DDS2氏作成の Stirling を愛用していますのでそれを使って↓確認を行いました(^^) まずデータの最初はスクリプトファイルの名称ですが、これは問題ないようです。512byteの余白がちょっともったいないような気がしますが、まあそこはそれ(^^;) |
|
そして512byte = 200h byte目がテキストポインタ
*TEXT をオフセット化した値になります。オフセットは 32bit int で格納したので
4 byte ぶんのサイズがあります。 エディタでみるとアドレス200h からの 4 byte は F1 01 00 00 となっていますが、インテル系CPUはリトルエンディアン(メモリの下位から値が格納される形式)なので、実際の値は 00 00 01 F1 となります。この値を覚えておいて、次にスクリプトファイル default.txt をメモ帳で開きましょう |
|
ここではSAVEポイントは短縮表記で #sp と表記してあります。この #sp の直後の位置がきちんとファイルに保存されていれば成功なのですが…どうでしょう? それをたしかめるには、このスクリプトファイルをメモ帳ではなくバイナリエディタで開くと検証が容易です。さっそく開いてみると… |
|
ファイル先頭から 00 00 01 F1 バイト目は、#sp の直後の CR(0D)-LF(0A) つまり改行コードのところを指しています。これで、ポインタの引き算で得られたオフセット値が正しくスクリプトファイル上のSAVE位置を表していることが確認できました。とりあえず成功のようです(^0^) |