移動なし起動の変化球

がちゃがちゃ組んでいるのだが、途中で一つあることを思いついてしまったので、変更してしまった。
これまでのファイル移動なし起動は、カレントディレクトリ(何もしなければNScr.exeのあるディレクトリ)から動かずに、セーブファイルだけをハードディスクに置くことを考えていた。セーブとかロードとかの瞬間だけカレントディレクトリをハードディスク上のどこかに移動させて、用が済めばまた戻すと言うやり方だ。
そのつもりでスクリプトを組んでいたのだが、ここでふと脳裏を過ぎったのは「そんなちまちましたことしなくて、どっかりハードディスク上の居座ればいいじゃん」と言う悪魔か何かの囁きだった。
俺「え、そんな。じゃあ、CDに残してきたarc.nsaとか、*.dllとかのその他のファイルはどうすればいいんだ?」
悪魔「arc.nsaはaddnsadirで対処しな。その他のコマンドには、全部フルパスでファイル指定させろよ。それで万事オッケーオッケー。グローバル変数だってこれで解決だろう?」
俺「グローバル変数は本当に大丈夫かどうかわからない*1が、exec_dllでさえフルパス指定に対応してるんだから、いいのかも……」
実は、ハードディスクに居座った方がスクリプトはさらに単純になると言う罠。
と、言う訳でサンプルを。

ファイル移動なし起動に必要な部分

*define
; ここから
numalias current_dir,100 ; 初期ディレクトリを保存する文字変数の番号。
; 数値はかぶらないように適当に変更する。
getreg $0,"Volatile Environment","APPDATA" ; アプリケーションディレクトリの取得
add $0,"\NScr"
exec_dll "current.dll/110&"+$0 ; アプリケーションディレクトリの中にNScrディレクトリを作成。
add $0,"\mygame" ; mygameの部分は開発者それぞれが変更すべし。
exec_dll "current.dll/110&"+$0 ; 最終的な専用のディレクトリを作成する。
exec_dll "current.dll/111&"+$0 ; getretに初期ディレクトリを保存しつつ、ディレクトリ移動。
; ここまで。これ以降、game命令までexec_dllを実行してはならない。
globalon ; グローバル変数を使用するなら、カレントディレクトリを移動した後で。
game
*start
getret $current_dir ; 他のexec_dllを実行しないうちに取得しておく。
addnsadir $current_dir ; これをやっておかないと、CDに置いてきたnsa.arcにアクセスできない。
mesbox $current_dir,"元のディレクトリは"
exec_dll $current_dir+"\current.dll/108&" ; プラグインファイルの指定は、フルパスでも可能
getret $0
mesbox $0,"現在のディレクトリは"
end

$current_dirは書き換えないように注意を払うこと。

使うdll

URL
http://www.eiji8pou.net/download/current.zip
md5
93798b19d2730fb43b52f436c020c1b6

まとめ

サンプル見ればわかると思うけど。
nsa.arcにアクセスするためには、nsa命令やらに加えて、addnsadirをお忘れなく。
ディスクに置いてきたその他のファイルにアクセスするには、フルパス指定をすればよいので、お間違いなく。

*1:gloval.savにアクセスしてグローバル変数を読み出すタイミングが問題。でも多分、gloval.savが生成されるタイミングがそれこそアクセスのタイミングだと思うので、define節中にグローバル変数にアクセスせず、start直後にディレクトリの移動を行なえば大丈夫な気がする。