いろいろと

いろいろあります。(http://web.archive.org/web/20070110101128/http://www10.plala.or.jp/sryu/nanika/tips/ りゅう様)




SAORI呼び出しに\![raise]を使うかどうか

raiseを使う必要があるのは「呼び出しタイミングが重要なもの」の場合です。
raiseを使わなければさおりは常に台詞が流れだす直前に実行されるので。

easyballoonやfill_desktopなどの視覚効果系はraiseを使うのが一般的ですが、
逆に内部処理目的のexec.dllやstring.dllなどはraise使わないのが一般的です。

raise使うかどうかの判断は、
「会話が始まる直前(というか始まると同時)にSAORIが呼び出されたら困るかどうか」
でOKかと。
困らなかったら、raise使わないほうがスクリプトもすっきりしていい感じです。


ちなみに里々にはphase 105から、\![raise]を使ったSAORI呼び出しを簡単に書くためのsync関数が実装されています。
:・・・・あっ!\![raise,OnBln]そうだ!!!
*OnBln
(bln,exclamation)

このようなSAORI呼び出しはsync関数を使うと
:・・・・あっ!(sync,bln,exclamation)そうだ!!!
のように非常にスマートに書けます。

華和梨でも「私設「華和梨」応援団」の「華和梨 Phase 8用サンプルスクリプト詰め合わせ」(samplescript.lzh)内の
raisesaori.kisを使えば、里々のsync関数とほぼ同等の機能を持ったraisesaori関数が使えます。



SAORI-basicの呼び出し(set_wall_paper.exeなど)

SAORI-basicのプログラムを使うには基本的にプロキシDLLを使う必要があります。
例外として、里々と忍はプロキシ機能を内蔵しているのでそのままbasicを呼び出せます。

プロキシDLLとしては孔明氏作のproxy.dllが有名(というかそれしかない)。
しかしproxy.dllはSecurityLevelヘッダがLocalでないと使えない上、
SHIORIによってはSecurityLevelヘッダをlocalとして渡すものがあるため、このようなSHIORIでは使えません。
美坂もそのようになっているらしいです。
ちなみに、SAORI仕様書ではSecurityLevelがとりうる値はLocalまたはExternalだと書いてあるので、proxy.dllの挙動は正しい。

そういうSHIORIを使っていて、SAORI-basicを使いたい人は

のどれか。

exec.dllで代用する場合は、引数1に"s_hide"を付けるのを忘れないようにしてください。
(詳しくはexec.dllのreadme.txtを参照)



拡張子判定の方法

ファイルの拡張子を調べるのは、主に壁紙変更で画像ファイルかどうかを判定する時に必要になります。
方法はいくつかありますが、基本的にループが必要なので難しい(というか面倒)です。
ここではループの不要な方法として拙作のstring.dllと正規表現を用いた方法を紹介します。

美坂の場合
{$if ({$saori("string.dll","match",{$reference(0)},"/\.(png|jpg|jpeg|bmp)$/i")}) {
  画像ファイルの場合の処理
}

文の場合
if FUNCTIONEX("string.dll","match",reference0,"/\.(png|jpg|jpeg|bmp)$/i") == 1
{
  画像ファイルの場合の処理
}

忍の場合
\ev[OnFileDrop, %saori[string.dll,match,%ref0,/\\.\(png|jpg|jpeg|bmp\)\$/i]],
  画像ファイルの場合の処理

ここでは正規表現の詳しい説明は省きますが、
簡単に言うと正規表現とは文字列のパターンを表すための記述法で、
上の正規表現は「ピリオドの次にpngかjpgかjpegかbmpがきて文字列が終わる」というパターンを表しています。
括弧の中を png|jpg|jpeg|bmp から zip|nar に書き換えればアーカイブかどうかの判定もできます。



SSPでpnaを有効にする方法

SSP 1.01.02からは自動判別されるようになったので設定は不要です。

SSPはデフォルトではpnaは使わない設定になっています。
pnaを使うには右クリックメニューの「設定」でSSP設定を開いて、
「表示」タブにある「透明化(Layered Window)を使う」にチェックを入れてください。

注:MATERIAと同じく、Win2000以降でないとpnaは使えません。



SAORIを扱うエトセトラ

お役立ちサイトリンク

SAORI-basicの辞書登録について

使用するSAORIを事前に辞書に登録しておくタイプのSHIORIで、例えばset_wall_paper.exeなどのSAORI-basicを使うときに
SAORIとして登録するのはset_wall_paper.exeではなくプロキシDLLであるproxy.dllです。
例外として、プロキシ機能を内蔵しているSHIORI(里々と忍)ではset_wall_paper.exeを登録しておきます。

パスの区切り文字について

ghost\master\以下にディレクトリを作ってそこにSAORIを入れている場合、
ファイル名の指定は例えば saori/bln.dll のように行いますが、
このときのパスの区切り文字は / よりも \ のほうが不具合がおきにくいようです。
つまり saori/bln.dll と書くよりは saori\bln.dll と書いたほうが良いということ。

ファイルサイズが気になるなら

多くのSAORIを組み込んでいくとだんだんゴーストのサイズが膨らんでいきますね。
UPXというツールを使えば、exeやdllを実行可能のまま圧縮できます。
UPXで圧縮しても、ロードされる段階でメモリ上に展開されるので、実行速度の低下はありません。
(その分ロードが多少遅くなるかもしれませんが、シェルのロードにかかる時間に比べれば些細なものです。)
SAORIだけでなくSHIORIも圧縮することができます。
華和梨・里々・忍などは既にUPXで圧縮された状態で配布されています。
併せて、pngもちぢめで再圧縮すると幸せになれるかもしれません。→補注「OptiPNG」でpng最適化によりサイズ減少可能。

ロードとアンロードをきちんと対応させる

これはSAORIのロード&アンロードを自動でやってくれるタイプのSHIORIを使っている人は気にする必要の無いことですが、
SAORIは一旦ロードしたら、アンロードするまでは再度ロードしようとしてはいけません。
ロードした状態でさらにロードしようとしたり、アンロードした後さらにアンロードしようとすると嬉しくないことが起こる可能性があります。
チェキ!を使うとロードとアンロードが正しく対応しているかどうかを比較的簡単に調べることができます。

SAORIのネットワーク更新

うちが各SHIORIや本体ごとの挙動・対応状況を把握しきれていないこと、
より簡単な対応方法などについて考察が不十分なこと等のため、
一旦この項目を灰色表示にしておきます。

常時ロードしているSAORIはそのままではネットワーク更新ができません。
Windowsではロードされた状態のdllは上書き・変更できないからです。
そのため遅くとも上書き直前には当該SAORIをアンロードしてやる必要があります。
当然、上書き終了後には必ずロード処理も行う必要があります。

ネットワーク更新時に発生するイベント
正常終了時 更新なしの時 エラー時(MD5不一致など)
OnUpdateBegin
OnUpdateReady
---以下、ファイルの数だけ繰り返し
OnUpdate.OnDownloadBegin
OnUpdate.OnMD5CompareBegin
OnUpdate.OnMD5CompareComplete
(ファイル上書き)
---繰り返しここまで
OnUpdateComplete(ref0=changed)
OnUpdateBegin
OnUpdateComplete(ref0=none)
OnUpdateBegin
OnUpdateReady
---以下、ファイルの数だけ繰り返し
OnUpdate.OnDownloadBegin
OnUpdate.OnMD5CompareBegin
OnUpdate.OnMD5CompareComplete or OnUpdate.OnMD5CompareFailure
(ファイル上書き) or (繰り返し終了)
---繰り返しここまで
OnUpdateFailure

方法は3つ。
・OnUpdateReadyで全SAORIをアンロードし、OnUpdateComplete(ref0=changed)とOnUpdateFailureで全て再ロード。
・SAORIのOnUpdate.OnMD5CompareCompleteでアンロードし、直後のOnUpdateComplete(ref0=changed)、OnUpdate.OnDownloadBegin、OnUpdateFailureでのみ再ロード。
・「SAORIなんてネットワーク更新しないから大丈夫。更新するときにはアーカイブ更新するさ。」

さらに同様のことはDnDインストール時にも起こる。(自分自身のアーカイブがインストールされる場合)
DnDインストール時に発生するイベント
正常終了時 対象ゴーストと違う時 エラー時
OnInstallBegin
OnInstallComplete
OnInstallBegin
OnInstallRefuse
OnInstallBegin
OnInstallFailure

こちらは方法は2つ。
・OnInstallBeginで全SAORIをアンロードし、OnInstallCompleteとOnInstallRefuseとOnInstallFailureで全て再ロード。
・「立ち上げたままで同じゴーストをインストールしなけりゃいんだから大丈夫だよ〜。」

このあたりのことは各ゴーストデペロパがそれぞれ行うと泥沼になりそうなので 是非SHIORIのDLLがよきにはからってくれるようになって欲しいところ。特に里々とか。



美坂に関するエトセトラ

お役立ちサイトリンク

辞書エラーの見つけ方

misaka.iniに error,1 と書いておくと辞書に括弧忘れなどのミスがあるとmisaka_error.txtが作られ、ミスのあった行が一覧出力される。
犬死朗さんとこのEasyScriptCheckerを使うのもおすすめ。

10円の切り替え判定

美坂では10円の\0名などの括弧のついた文字列の判定を素直に
 {$if ({$reference(0)}==(・∀・))}
のように書くと、書式エラーとみなされうまくいかない場合がある。
このような場合は括弧を取り除き、
 {$if ({$insentence({$reference(0)},・∀・)})}
のように$insentence関数を使うとよい。

ループ処理

美坂にはforやwhileなどのループ機構が用意されていないので、ループ処理をしたい場合には
再帰(関数の中からさらに関数を呼び出すこと。同じ関数を呼ぶこともある。)を用いる。
例えば1〜10の合計を求めるスクリプトは以下のとおり。

$Sum
{
{$tmp=1}{$sum=0}{$_Sum}
\01〜10を足すと{$sum}\e
}

$_Sum; {$if ({$tmp}<=10)};
{$sum+={$tmp}}{$tmp++}{$_Sum}

SAORIにダブルクオートしたファイル名を渡す方法

例えばOnFileDrop2でset_wall_paper.exeを呼ぶ場合、
 {$saori("exec.dll","norm","set_wall_paper.exe","{$reference(0)}")}
このように書いてもSAORIに渡される段階ではref0のファイル名の両端にダブルクオーテーションはつきません。
両端をダブルクオーテーションで囲む必要がある場合は、
 {$saori("exec.dll","norm","set_wall_paper.exe", "{$reference(0)}" )}
このようにします。つまり前後にスペースを入れればOK。


文にまつわる et cetera

お役立ちサイトリンク

常時ロード型のSAORIを使うとき

ネットワーク更新開始時にOnUpdateReadyイベントが来ると、文は全てのSAORIを自動的にアンロードします。
ここでアンロードされたSAORIはネットワーク更新が終了しても自動でリロードされることはありません。
そのためゴースト起動中常にロードされている必要のあるSAORIは、
ネットワーク更新終了後にFUNCTIUONEX関数を呼び出してロードしなおす必要があります。

2次元配列を実現する関数

aya_2darray.txt
ご自由にお使いくださいませませ。

2次元配列とは、通常1次元的に広がっている配列を、2次元方向にも拡張したものです。
って文章だけで書いても解かりにくいので、、、

通常の配列(1次元配列)は
abcdefghijil mnopqrstuvwx yzABCDEFGHIJ KLMNOPQRSTUV
こんな感じで、例えば 5 と指定して pqr にアクセスできますね。

それに対して2次元配列は
abcdefghijil
mnopqrstuvwx
yzABCDEFGHIJ
KLMNOPQRSTUV
こんな感じになっていて、例えば (2, 3) と指定して QRS にアクセスできます。

簡易関数電卓スクリプト

aya_calc.txt
ご自由にお使いくださいませませ。

里々のssuにあるcalc関数をつかうという手も。


里々・バイト値 1 の表し方

ssuにsprintfという関数があり、(sprintf,%c,1)とすることでバイト値 1 が表せます。
 $byte1【タブ】(sprintf,%c,1)
としておくと後々便利かもしれません。