« PDA | メイン | PSP »

2007年12月08日

●PerlでONS こんにゃく編 その0 進捗ようよう

と、いうことでアレやアレはのアレ?

シナリオファイルをバイナリエディタで眺めること幾星霜、
ようやっと通常パート(絵・音・文)の目処だけは立ったような感じです。
ただし選択パートとかフラグとかは全然なので、途中で頓挫する可能性が結構あります。

運良く頓挫しないにしても再現すべき処理が多いためいつ終わるのやら。現在移植度10%くらい?
そのためまたメモついでに記事数を稼ぎながらのんびりと進行していこうかと。
時々放置して衝動的に別のものを始める可能性もかなりあります。
実はアレやアレやのアレとか全然関係ないソレも同時進行だったり。
とはいえこっち以上に全然進んでませんが、詰まったらとりあえず次へ

・独り言にしてメモ
多分0x0001260からスクリプト開始。その後は行?番号がついてるのでそこで改行。
バイナリだとどこで分けるかが一番大変なので、こうやって明確に示して貰えると大分楽になる。
その後の処理も1個ずつ潰していけるし。バイトコードの整形全般について一度まとめてみよう。
コードの種別は行のラストっぽい。台詞・効果音・立ち絵・立ち絵消去・背景・立ち絵移動等を確認
シナリオファイル後部メッセージは1から割り当て。台詞・効果音済み
立ち絵、背景、音楽等は config/xxx.dat で定義。コード内の数値で呼び出し。立ち絵・背景済み
ただし重ね合わせは移動処理等がめんどくさいのでmasaemonさんの合成ツールを前提に…。大感謝
あ、音声ファイルがなんだか展開出来ない?西側はやだなぁ
拡大演出はある程度再現出来るかも。
場所選択パートはどうなってるのかな。うん、またにしよう
カスタマイズも頑張らないと。REQUIEMからおとボクへのフィードバックもあるしエンドレス。
何回やっても何回やっても3度目のしょうたが倒せない。勇者のくせになまいきだ。

2007年10月09日

●まさに外道

時期が空いてしまいましたが前回の画像の種明かし。

*start
setwindow 45,460,28,3,24,24,1,2,10,0,0,"image/message_00.png",0,412
lsp 2,"image/tak00a.png",100,0
lsp 3,"image/bg03d.png",-200,0
print 1
name "貴子"
「お姉さま…」
\

と、ただ単に手で打ち込んだだけだったりします。
ハメコミ合成の名に嘘偽りなし。まさに外道。
あの時点では解析(のようなもの)も何も殆どやっていなかったという。
ええと…ご寛恕下さい

ということで体験版です。
(002:音関係を微修正→006:疲れた…。残るは地道に照らし合わせてスクリプト直書き。orz)
体験版といっても、製品版で使えないのではなくコンバータ自体が体験版なのです。
別のところで弄れるようにアップしただけなんだからねっ(?
所持しているのはDVD版のみですが、調べたところCD版でも使えると思います。
一応の正式アップに比べて、タイトル・選択肢・予告編・そしてreadme などが実装されていません。
あとは細かな表示の不具合もありそうです。

なので簡単に手順を書かせて頂きます。
masaemon様謹製 キャラメルBOX Plug-in ver.03 をデータ抽出に利用させていただきました。
カタハネに引き続きお世話になります。

各アーカイブから
png 画像→ [Image]フォルダ
bgmxx.ogg → [bgm]フォルダ
sexx.ogg → [se]フォルダ
data.bin 内音声ファイル → [voice] フォルダ
scb , anb ファイル →[system]フォルダ へ展開、振り分けます。
その他のファイルはよく分かりませんが、適当なところへ。
※system.bin 内 yokokuxx.ogg も[voice]。ただサイズが大きいのでひとまとめにアーカイブ化せず、
実行場所で別に[voice]フォルダを作ってyokokuxxをそのまま置いておく方がいいかもしれません。

*シナリオ変換

[hoge]任意のフォルダ
otbk.pl
nsc.pl
-[system]フォルダ
  xx.scb
  xx.anb

と配置したあと otbk.pl nsc.pl の順で実行。
1.txtが作成されますので同梱の0.txt とともにONS実行フォルダへ。
沢山出来る作業用のファイルは見ないでゴミ箱推奨。

*画像変換
png 画像を faststonimageviewer などでリサイズ。基本的には45%でいいと思います。
透過がおかしい場合は、リサイズの際に上記のソフトでやってみてください。

*音声変換
邪魔にならない程度に再圧縮

*実行
各種ONS実行環境にて実行してください。
タイトル画面がなく、いきなり最初のシーンから始まります。
体験ですのでm(_ _)m
お客様の中にPSPでSEVEN.NETを動かす剛の者はいらっしゃいませんか?

94 名前:名無しさん@お腹いっぱい。[sage] 投稿日:2007/06/10(日) 16:37:59 ID:3pKf8cph
ところでいつの間にかまともなPSP用Linuxが出てたんだな
誰か詳しい人、Mono入れてSEVEN.NETでおとボク動かしてください

95 名前:名無しさん@お腹いっぱい。[sage] 投稿日:2007/06/10(日) 17:24:07 ID:t+3ME4uT
uCLinuxなので無理ってことで。


2007年09月11日

●PerlでONS 応用編 日本語ファイル名の置換

ONS等への移植をする際に、元のゲームで日本語のファイル名が使われていることがあります。
ONScripterでは基本的に日本語ファイル名は使えるのですが、
雪希4であったり、稀にONSでも使用出来ない文字列(0823でFIXされてますが)もあるので
一気に英数ファイル名へ置換するスクリプトを組んでみました。

題材は吉里吉里、Fate/stay night
日本語が画像ファイルだけだとつまらないので、勝手に音楽も日本語ファイル名に代えていたり。

@fadein file=oアインツ洋館-(夜) time=800 rule=シャッター左から vague=64
@play file=洋館 time=200

こんな感じで元スクリプトがあるとします。

if ( $line =~ /^@fadein file=(.*) time=(\d*) rule=(.*) / ){
	my $file = $1;
	my $time = $2;
	my $rule = $3;
	print OUT "bg \"$file.png\",18,$time,\"$rule\"\n";
}
elsif ( $line =~ /^@play file=(.*) / ){
	my $file = $1;
	print OUT "bgm \"$file.ogg\"\n";
}

と今まで通りにマッチさせると

bg "oアインツ洋館-(夜).png",18,800,"シャッター左から.png"
bgm "洋館.ogg"

と出力。ここで、ファイル名を常に変更していくサブルーチンを加えてみます。

(略)
open (REN,">rename.bat");#リネーム用のBATファイルも同時に作成
%file;
%count;
(略)

if ( $line =~ /^@fadein file=(.*) time=(\d*) rule=(.*) / ){ my $storage = &filename($1,"png");#サブルーチンにファイル名と拡張子を渡し、その返値を受け取る my $time = $2; my $rule = &filename($3,"png"); print OUT "bg \"$storage.png\",18,$time,\"$rule\"\n"; } elsif ( $line =~ /^@play file=(.*) / ){ my $storage = &filename($1,"ogg"); print OUT "bgm \"$storage.ogg\"\n"; } (略)
;#サブルーチン sub filename{ if ( defined($file{$_[0]}) ){ #このファイル名が既出がどうかチェック $result = $file{$_[0]}; #既に代入した置換後のファイル名へ }else{ #初出ならば $file{$_[0]} = "$_[1]\_$count{$_[1]}"; #今後、このファイルは (拡張子)_(番号)とする (ex. png_105) print REN "ren \"$_[0].$_[1]\" \"$file{$_[0]}.$_[1]\"\n"; #BATファイルへ出力 $result = $file{$_[0]}; $count{$_[1]}++; #拡張子ごとに番号プラス1 } return $result; #サブルーチンの返値 }

これで、

bg "png_105.png",18,800,"png_36.png"
bgm "ogg_9.ogg"

#rename.bat ren "oアインツ洋館-(夜).png" "png_105.png" ren "洋館.ogg" "ogg_9.ogg" 以下略

となりました。ハッシュ(連想配列)に入れていくのが肝ですね。
今後使う機会があるかどうかは微妙ですが、何かしら応用できるといいかも。

9/12)
改めて考えると、この方法だとスクリプトに変動があるとファイル名が変わってしまいますね…。
完成してからならともかく、作成中だと結構難がありそうです。
基本的な考え方は同じですが、やっぱり別にリスト化したものを読み込んで
それをハッシュのキーとして扱った方が良いかも知れません、ですよ?

2007年08月24日

●PerlでONS Bullet Butlers編 ただのメモ

このエントリは書き込み未遂中です。
試しに体験版部分のyoutube動画を貼ってみましたが特にヤマもオチもありません。
というか音ズレしまくりです。久々過ぎて動画作成の知識も環境も壊滅していました…
後でもう少し直して再うpしようかと。

ONS更新でdrawbg2の処理が直ったのはとっても喜ばしいのですが、
この作品の場合はlsp2じゃないと辛いかもです。
そのため今回ズーム処理に手を出せていません。
加えてNスク宿願のマルチスレッドな感じでエフェクトや文章を流せれば…贅沢言いすぎですね。

なので今後、エフェクト部分は細かい修正はあれども、大体のレベルは上の動画程度になりそうです。
このあとはフラグ関係を追ってみようと思います。

2007年08月12日

●応用編 で 魂響編 その1 拡大縮小回転移動

講座というよりも備忘録なこのカテゴリ

魂響~円環の絆~(吉里吉里製)の変換では、 drawbg/sp2 を使ったエフェクトに手を出してみました
なかなか元のスクリプトを忠実に反映出来なかったのですが、ようやく目処が立ったのでメモメモ

@eff layer=3 storage=EV_KASUMI_BAT_00_D ss=2.75 ds=3 path=(331,123,0)(331,123,255) time=600 sr=0 dr=+0.0 pathtype=true

この作品では上記のような命令で画像に対して拡大縮小回転移動のエフェクトをかけています。
@move命令と同じように、始値と終値(とはいわないと思う)を指定しての連続的なエフェクト指定です。
Nスクでも拡大略自体は出来るのですが、連続させて動かしたりエフェクトをかけることは出来ません。
そう、なので "スプライトを動かす"時と同様に timer を使った for 文 でぶん回しましょう
基本的には移動時と同じく各パラメータを 始値+(終値-始値)×経過時間÷完了時間 で計算

textoff
mov $1,"EV_KASUMI_BAT_00_D"  defsubでgetparamする時を考えて、文字変数に入れています
saveoff:textoff
csp -1;bg black 0
lsp 9,":c;image/"+$1+".png",0,0     文字変数をファイル名に使う時の処理。この辺、あんまり解説がないかも
resettimer
for %1=1 to 999999
gettimer %9
if %9>=600 break
mov %3,0+(255-(0))*%9/600	透過度
mov %4,331+(331-(331))*%9/600	画面の中心となる、画像上のx座標
mov %5,123+(123-(123))*%9/600	画面の中心となる、画像上のy座標
mov %6,275+(300-(275))*%9/600	拡大率
mov %7,-0+(0-(-0))*%9/600	回転度
if %6>=215 add %7,180		*ONS不具合。拡大率215以上の場合は上下反転
mov %4,800-((%4-400)*%6/100+400)	*拡大の中心となる、スクリーン上のx座標 なんだかよく分からない計算
mov %5,600-((%5-300)*%6/100+300)	*拡大の中心となる、スクリーン上のy座標 同上
drawclear		前回描画分消去
drawsp2 9,1,%3,%4,%5,%6,%6,%7	描画 スプライト番号,セル番号,透過度,x座標,y座標,縦拡大率,横拡大率,回転度
draw	実画面に表示
next
drawsp2 9,1,%3,572,742,300,300,180 最後に終了の値で表示
draw
saveon

こんな感じになりました。
詳しくは 魂響コンバータの sub eff{ 以下を見てください(投げた
いえ、PATHが複数ある際の処理など、微妙に複雑且つ長くなってしまうのです…

Nスクの拡大略仕様がいまいち判らなくて、元スクリプトでの値をどうすればいいか迷ってました
元スクリプトでは 「画面の中心となる、画像上の座標」 が書かれているのですが、
Nスクでは 「拡大の中心となる、画面上の座標」 を drawbg/sp2 で使っているようです。
(うーん、この違いを言葉で説明するのは難しい)

しかも前者は等倍での座標、後者は拡縮を適用させた後の座標だったようで
ようやく本日、上記なんだかよく分からない計算で求めることができました。近日アップデート予定

が、しかし!どうもONSでは drawbg/sp2 の際に解像度の変更(800にしてます)が効いてないみたい
本家Nスクでは再現出来た部分が、ONSだとずれて表示されてしまう…orz
215%の反転表示に加えて、要検証かもしれません。近日アップデート未定

しょうがないのでもう少し数字と格闘しようと思いました。備忘備忘
…って、せめて動画でもおかないと何が何だかわからないですねえ

8/13)細々追記修正。なお本ページの全エントリは予告なくせこせこ修正されます。
それはそれとして、ONSだと魔の215%を境に拡大率がおかしくなっているという仮説を立ててみる
Nスクの300%がONSのほぼ240%だ。どうしよう

9/10)
ONS更新によって上記の描画不具合が修正。
これで思った通りに動いてくれる様になりました。
改めて本家Ogapee様、PSP&Winバイナリ作成すとーむ様に感謝いたします。乙です!
下は検証用に…

2007年07月15日

●応用編 で かにしの編  その6 スクリプトサイズ削減

すっかりさぼってしまっていた今日この頃
ONSforPSPでのメモリ不足に泣くのは何処様も同じのようです
特にかにしのは、某エロゲ研究室様(デコードでお世話になりました)調べでは
純粋な表示テキストだけで3.85MB。
1 『僕と僕らの夏完全版』 2 『Fate/stay night』 3 『CLANNAD』
に次ぐ4番目のシナリオサイズを誇っているようです。
(もちろん調査されていないゲームの中に更に大きなものもあるでしょう)
Perlでだらだらっと出力するのが好きだったのですが、さすがに10MBを越えてしまってはどうにも…

というわけで、無駄な部分を"defsub"命令を使ってサイズ節約してみます。
極力変数を使わずに、長いスクリプトをそのまま吐いているあたりがターゲットです。
以前記事にした名前表示のところが一番削減できそうですね。

	}elsif ( $line =~ /^%00%42(?:%[0-9A-Fa-f][0-9A-Fa-f]){2}%00%00(.*?)%00(.*?)%00/ ){
		$name = $1;
		$dec = $2;
		$name =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg;
		$dec =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg;
		$dec =~ s/\{(.*?):(.*?)\}/\($1\/$2\)/gi;
		$dec =~ s/\\n/\n/gi;
		$nalocate = 220 - (length($name))*6;
		print OUT "erasetextwindow 0\n";
		print OUT "lsp 0,\":s/24,24,2;#FFFFFF$name\",$nalocate,431\n";
		print OUT "lsp 1,\"image/nmbase.jpg\",50,424\n";
		print OUT "print 1\n";
		print OUT "$dec\\\n";
		print OUT "csp 0:csp 1:print 1:erasetextwindow 1:dwavestop 0\n";

というPerlスクリプトで

erasetextwindow 0
lsp 0,":s/24,24,2;#FFFFFF少女",196,431
lsp 1,"image/nmbase.jpg",50,424
print 1
「台詞」\
csp 0:csp 1:print 1:erasetextwindow 1:dwavestop 0

こんなNスクのスクリプトを吐いています。
ここで場面によって変化するのは「名前」「名前の表示座標」「台詞」だけで、他は毎回同じです。
ノベルゲームの常として、会話が非常に多いので総計でかなりの容量を使ってしまっています。
そのため必要最低限の引数だけとって、あとは"defsub"でユーザー定義命令にしてしまいましょう。
0.txtに

*define
(略)
defsub name
defsub nend

game
*name getparam $1,%1 ;名前と座標を受け取ります erasetextwindow 0 ;ここからは今まで1.txtに吐いていた部分 lsp 0,":s/24,24,2;#FFFFFF$1",%1,431 lsp 1,"image/nmbase.jpg",50,424 print 1 return ;ユーザー定義命令終了
*nend csp 0:csp 1:print 1:erasetextwindow 1:dwavestop 0 ;ここも長いので4文字にまとめてみた return

これでシナリオ中、名前と座標の引数を自作した"name"命令に渡してやることで
最初の長ったらしいスクリプトと同様の動作をするようになりました。
Perlの方はこんな感じ

	}elsif ( $line =~ /^%00%42(?:%[0-9A-Fa-f][0-9A-Fa-f]){2}%00%00(.*?)%00(.*?)%00/ ){
		$name = $1;
		$dec = $2;
		$name =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg;
		$dec =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg;
		$dec =~ s/\{(.*?):(.*?)\}/\($1\/$2\)/gi;
		$dec =~ s/\\n/\n/gi;
		$nalocate = 220 - (length($name))*6;
		;#print OUT "erasetextwindow 0\n";
		;#print OUT "lsp 0,\":s/24,24,2;#FFFFFF$name\",$nalocate,431\n";
		;#print OUT "lsp 1,\"image/nmbase.jpg\",50,424\n";
		;#print OUT "print 1\n";
		print OUT "name \"$name\",$nalocate\n";
		print OUT "$dec\\\n";
		;#print OUT "csp 0:csp 1:print 1:erasetextwindow 1:dwavestop 0\n";
		print OUT "nend\n";

name "少女",196
「台詞」\
nend

となります。うん、すっきり
変更した結果、全体のスクリプトサイズが7.5MB、分割したものは3MB・4MB程度になりました。
まだまだサイズは大きいですが、多少なりとも余裕ができたんじゃないでしょーか
今後も過去のものを含めてちまちま削っていければと思います。

2007年06月30日

●応用編 で かにしの編  その5 スプライト移動

ちょっと落ち着いたので、一応「応用編」です。
サンプルにすることでかにしの編も兼ねているというあたり、深い意味はなさそうです

前置きとして、Nスクにはスプライトを移動する命令が二つあります
"msp"と"amsp"、前者が相対的な増分を取るのに対して、後者は絶対位置での移動指定。
for文で"msp"を使うのが割と楽なのですが、そのままだと移動速度が環境に依存してしまいます。
PCではシュパーと移動しても、遅いマシン、特にPSPだとし、ゆ、う、ぅ、ぱ、ぁ、ぁというように…

そこでタイマーと組み合わせて移動量を調整することで、ほぼ同じ時間で移動させてみます。
原案はNスクスレその8>450です。感謝

とりあえずPerlでの移植は無視して、Nスクでどうすればいいか

lsp 6,"image/G1_AA01S.jpg",800,-40
saveoff
resettimer				#タイマー作動
for %1=1 to 999999			#ひたすら繰り返します
gettimer %2				#経過した時間を取得
if %2>=500 break			#完了時間を超えてたら終了
mov ?1[0],800+(591-(800))*%2/500	#?は配列。x座標を計算してます。
mov ?2[0],-40+(-40-(-40))*%2/500	#y座標(透過度も同じように求められます)
amsp 6,?1[0],?2[0],255			#求めた現在あるべき座標に移動
print 1					#表示
next					#ふりだしに戻る
amsp 6,591,-40,255			#最後に終点で表示
print 1
saveon

このように 始点+(終点-始点)×経過時間÷完了時間 という計算式を立てます。
現時点での絶対位置を求め、そこにスプライトを移動。
あとはタイマーが完了時間を越えるまで、ひたすら上記の処理をぶんまわしてやればおk
そんなに難しくないですね

次に他のスクリプトからの機械的変換を試みます
吉里吉里はデフォルトの"move"タグが都合よく終点と時間を指定しているので、
単純にマッチさせてやればその二つは問題ありません

@move layer=0 path=(-150,0,255) time=2000
↓
$line =~ /^@move layer=(\d*) path=\((.\d*),(.\d*),(\d*)\) time=(\d*)/ ;

少しめんどくさいのが始点の取得です。
Nスクではスプライトの表示座標を得る命令がないので、表示する度にPerlの変数に
入れておくのがいいでしょう。

例:かにしのでの座標管理

;#スプライト表示(始点取得) elsif ( $line =~ /^%00%48%([0-9A-Fa-f][0-9A-Fa-f])%([0-9A-Fa-f][0-9A-Fa-f])%([0-9A-Fa-f][0-9A-Fa-f])%([0-9A-Fa-f][0-9A-Fa-f])%([0-9A-Fa-f][0-9A-Fa-f])(?:%00){5}%[0-9A-Fa-f][0-9A-Fa-f](.*?)%00/ ){ $num = 6 - hex($1); #スプライト番号(Nスクは若い方が上になります) if ( substr($3,0,1) eq "f" ){ #後ろ1バイトが"F"で始まる場合 $left[$num] = hex($2) - (( 256 - hex($3)) * 256); #こういう式のようです }else{ $left[$num] = hex("$3$2"); #x座標。スプライト番号で配列へ } if ( substr($5,0,1) eq "f" ){ $top[$num] = hex($4) - (( 256 - hex($5)) * 256); #同様にy座標 }else{ $top[$num] = hex("$5$4"); } $dec = $6; $dec =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg; print OUT "lsp $num,\"image/$dec.jpg\",$left[$num],$top[$num]\n"; }
;#移動時の終点取得 elsif ( $line =~ /^%00%4b%([0-A-Fa-f][0-9A-Fa-f])%([0-A-Fa-f][0-9A-Fa-f])%([0-A-Fa-f][0-9A-Fa-f])%([0-A-Fa-f][0-9A-Fa-f])%([0-A-Fa-f][0-9A-Fa-f])%([0-A-Fa-f][0-9A-Fa-f])%([0-A-Fa-f][0-9A-Fa-f])/ ){ if ( $moveon[$num] == 1 ){ $num = 7 - hex($1); #スプライト番号。上とは一つずれてます $mnum[$mn] = $num; #以下、移動する個数"$mn"でそれぞれの値を配列に if ( substr($3,0,1) eq "f" ){ $endleft[$mn] = $left[$num] + ( hex($2) - (( 256 - hex($3)) * 256) ); #データは増分なので、始点+増分で終点を求めます }else{ $endleft[$mn] = $left[$num] + hex("$3$2"); } if ( substr($5,0,1) eq "f" ){ $endtop[$mn] = $top[$num] + ( hex($4) - (( 256 - hex($5)) * 256)); # }else{ $endtop[$mn] = $top[$num] + hex("$5$4"); } $movetime = hex("$7$6"); $mn++; #移動する個数チェック $moveon[$num] = 0; }else{ $moveon[$num] = 1; #何故か同じ移動命令が二回続くので、一回目はスルー } }

上手いことデータをこねくり回して座標その他を取得出来たら、

}elsif ( $line =~ /^%00%4c%/ ){	#00 4b で記述された移動命令を実行します
	&move();
	$mn = 0;	#移動フラグ初期化
}



sub move{ print OUT "saveoff\nresettimer\n"; print OUT "for %1=1 to 999999\n"; print OUT "gettimer %2\n"; for ( $i = 0 ; $i < $mn ; $i++ ){ $num = $mnum[$i]; print OUT "mov \?1\[$i\],$left[$num]+($endleft[$i]-($left[$num]))*%2/$movetime\n"; print OUT "mov \?2\[$i\],$top[$num]+($endtop[$i]-($top[$num]))*%2/$movetime\n"; print OUT "amsp $num,\?1\[$i\],\?2\[$i\],255\n"; } print OUT "print 1\n"; print OUT "if %2>=$movetime break\nnext\n"; for ( $i = 0 ; $i < $mn ; $i++ ){ $num = $mnum[$i]; print OUT "amsp $num,$endleft[$i],$endtop[$i],255\n"; $left[$num] = $endleft[$i]; #最後に、移動の終点を次回の始点として使えるようにします $top[$num] = $endtop[$i]; } print OUT "print 1\nsaveon\n";saveon }

と処理。(いつかスクリプトに※入れます)
サブルーチンに一々引数を渡すのがめんどくさいので、座標類はグローバル変数だったりします。
分けた意味ナス
ちなみに途中にあるfor文で、同時に移動するスプライトの数だけ計算→移動を繰り返します
理論上は何個でも動かせるとは思いますが、サンプルに使ったかにしのでは
立ち絵4つが同時に動くのが最大だったので未検証です。というかそれも体験版だけだったし…!

追記)
よく考えると、わざわざ増分から終点求める必要はないですね
始点+増分×経過時間÷完了時間 で済む話でした。
吉里吉里の場合は値が終点なので上記のようにしたのか。
ちなみに吉里吉里はよーいドンで動き出さないので、複数動かすための判定が難しいかも
breakのポイント変更。行き過ぎちゃってましたね

2007年06月24日

●かにしの編 その4 トランジションと名前表示

トランジション(背景画像切り替え)に白黒のマスク画像を使ったエフェクトを
かけるゲームが一般的です。
幸いにしてNスクにもマスクトランジションがあるので、移植の際に大助かり。
凝った記述をしなくても、 print 命令にマスク画像を渡してあげるだけで原作通りの効果が出せます。
かにしのにはなんと77枚ものトランジション用マスク画像が…

	}elsif ( $line =~ /^%00%54(.*?)%00/ ){
		$efmsk = $1;
		$efmsk =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg;

でマスク画像ファイル名を変数(非ローカル)に渡して
}elsif ( $line =~ /^%00%4a%([0-9A-Fa-f][0-9A-Fa-f])%([0-9A-Fa-f][0-9A-Fa-f])%([0-9A-Fa-f][0-9A-Fa-f])/ ){ $time = hex("$3$2"); if ( $time == 0 ) { print OUT "print 1\n"; }elsif ( $1 eq "2a") { print OUT "print 18,$time,\":c;image/$efmsk.jpg\"\n"; }elsif ( $1 eq "1d" ){ print OUT "print 14,$time\n"; }else{ print OUT "print 10,$time\n"; } }

とマスクを使うかどうかの判別をして、トランジションにかかる時間とともに書き出します。
ちなみに "4a $1" の$1でマスクトランジション以外にも色々エフェクトを指定しているようです。
"1d"だと上にスクロール?なので "print 14,$time"
これはNスクのエフェクト表と照らし合わせたり自作して当てはめます。
さて、ノイズエフェクトとかラスタースクロールはどうしよう、お兄ちゃん…

ということでシステム面に踏み込めない(私の)なんちゃって移植より、栖香ちゃんに期待だ!


お次は名前表示です。
"nmbase.jpg"が名前欄の画像なので、これと文字スプライトを合わせてテキストウインドウに重ねます。

	}elsif ( $line =~ /^%00%42(?:%[0-9A-Fa-f][0-9A-Fa-f]){2}%00%00(.*?)%00(.*?)%00/ ){
		$name = $1;
		$dec = $2;
		$name =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg;
		$dec =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg;
		$dec =~ s/\{(.*?):(.*?)\}/\($1\/$2\)/gi;
		$dec =~ s/\\n/\n/gi;
		$nalocate = 220 - (length($name))*6;
		print OUT "erasetextwindow 0\n";
		print OUT "lsp 0,\":s/24,24,2;#FFFFFF$name\",$nalocate,431\n";
		print OUT "lsp 1,\"image/nmbase.jpg\",50,424\n";
		print OUT "print 1\n";
		print OUT "$dec\\\n";
		print OUT "csp 0:csp 1:print 1:erasetextwindow 1\n";
	}

細かい工夫として文字数によるx座標調整と、表示・非表示の際に
テキストウインドウが消えないようにしています。
もっともここでの苦労は、手探りで表示座標を決めた点が主です。何この半端な数字

ちなみにONSは"windowchip"命令に対応していないのでメニューを出す時などに
名前欄だけ残ってしまうのが難点です。
あと、画像の周りのゴミを手動で消してやると綺麗かな?

これで何とか最低限の見栄えは整ったので、暫定公開へ。
でもReadmeで手順書くのが辛いです…orz

2007年06月23日

●基本編 Nスクの設定とタイトルメニュー

シナリオは無事に変換できても、Nスクの設定(定義)を書かないとまともには動きません。
とはいえNスクの講座サイトは結構多く、私が語るだけの余地も知識もないので
私がONS移植に使いまわしている設定?の紹介のみ

;mode800
*define
nsa
menusetwindow 18,18,2,2,0,1,#BB8866
savenumber 20
rmenu "画像表示",windowerase ,"セーブ",save,"ロード",load,"選択肢まで進む",skip,"回想",lookback,"終了する",reset
effect 2,10,1000
effect 3,3,500
effect 4,10,300
defaultspeed 10,5,1
transmode alpha
effectcut
globalon

…変数定義を除けば define節は基本的にこれだけです
うーむ、これぞNスク!と言わんばかりの主張が込められた簡潔にして王道の以下略
よく考えたら Fate converter のものを流用させてもらっていたような気も…

ちなみにシステムカスタマイズをすればオリジナルゲームは勿論、ONS移植でも
忠実にこだわったセーブ画面やコンフィグ画面を作れるのですが、現状そこまでやれません orz

ただPSP用には、ムービー命令を defsub で自作する必要があります。
大本はすとーむ様のスクリプトなのですが、ほんの少しだけ弄らせて貰いました。

(*define)defsub movie
============================

*movie csp -1 getparam $2,%2 fileexist %3,$2:if %3=0 return saveoff split $2,".",$1:add $1,"-"
mov %1,0:mov %4,7 for %0=0 to 999999 step 100 itoa $0,%0:len %5,$0:mov %6,%4-%5 for %7=1 to %6:mov $0,"0"+$0:next fileexist %3,$1+$0+".jpg" if %3=1 add %1,100 if %3=0 mov %8,%0-100:sub %1,100:break next
for %0=%8 to 999999 itoa $0,%0:len %5,$0:mov %6,%4-%5 for %7=1 to %6:mov $0,"0"+$0:next fileexist %3,$1+$0+".jpg" if %3=1 inc %1 if %3=0 break next
mov %0,0 lr_trap *movie_end bgmonce $2 resettimer for %0=1 to 999999 gettimer %3 itoa $0,%1*%3/%2:len %5,$0:mov %6,%4-%5 for %7=1 to %6:mov $0,"0"+$0:next if %3>=%2 break bg $1+$0+".jpg",1 ;btndef $1+$0+".jpg":blt 0,0,800,600,0,0,800,600 next goto *movie_end2
*movie_end if %0>0 break:next *movie_end2 lr_trap off ;ofscpy bg black,1:stop saveon return

画像チェックの短縮と、saveon、saveoff の修正だけしています。

*あと、今までのONS移植は何となく解像度 640x480 でやっていましたが、
;mode800 でそのままやっても問題ない?ので、今後はそうしようかと。一々座標を4/5してたし

まあdefine節はこのぐらいとして、次はノベルゲームの命とも言えるテキストウィンドウ。
これはちょっぴり気を遣っています。
吉里吉里など表示座標が直接読み取れるものはいいのですが、そうでない場合は
試行錯誤してウィンドウ位置と文字位置を調整しなければなりません。
setwindow 命令は熟読ですね

例)かにしの
setwindow 74,480,28,3,26,26,1,2,10,1,1,":a;image/winbase0.jpg",0,414

で、最後にタイトルメニュー
これも吉里吉里なんかはボタンまで何とか再現していますが、
ボタンやクリッカブルマップを置換スクリプトで再現するのがめんどくさい時は超手抜きだったりします。
タイトルで使われている画像と音楽を持ってきて、左クリック→スタート 右クリック→ロード のみ!

一応サンプルとしては私の過去のブツでも見てください(ここでも手抜き


うーん、しかし基本編は薄いわ、かにしの編は一般性が無いわと…やっぱり講座じゃないですよ?

●かにしの編 その3 ラベルとフラグと選択肢

ようやっとほぼ読み終えてフラグ実装。
"<="なのか"<"なのか、はたまた">"なのか微妙なところもありますが、
テストプレイしながら直していこうかと。

とりあえず通常のフラグは"flag_xx"、グローバルは"gflag_xx"と置換しました。
1.txtの作成が終わったら、*define節用にシナリオからフラグ(変数)を拾います

open (IN, "1.txt");
open (OUT,">num.txt");
$gloval = 201;
$user = 11;
%flag;
while ( $line = <IN> ){
	if ( $line =~ /\%(g[a-zA-Z_0-9]*)/ ){
		if (( $flag{$1} != 1 ) && ( $1 ne "" )){
			print OUT "numalias $1,$gloval\n";
			$gloval++;
			$flag{$1} = 1;
		}

}elsif( $line =~ /\%([a-zA-z][a-zA-Z_0-9]*)/ ){ if (( $flag{$1} != 1 ) && ( $1 ne "" )){ print OUT "numalias $1,$user\n"; $user++; $flag{$1} = 1; } } } close IN; close OUT;

初出の変数を拾って、通常のものは"11"から、グローバルは"201"から numalias で定義

numalias gflag_c6,201
numalias gflag_f0,202
numalias flag_10,11
numalias flag_0f,12
numalias flag_05,13
numalias flag_11,14
numalias flag_06,15
numalias flag_07,16
numalias flag_01,17
numalias flag_03,18
numalias flag_08,19
numalias flag_09,20
numalias flag_0a,21
numalias gflag_f8,203
numalias flag_12,22
numalias flag_02,23
numalias gflag_f6,204
numalias gflag_f2,205
numalias gflag_f4,206
numalias gflag_f5,207
numalias gflag_f3,208
numalias flag_04,24
numalias gflag_f7,209

これを *define節に貼り付けてやれば完了です。

選択肢は

elsif ( $line =~ /^%00%02%02%00(?:%[0-9A-Fa-f][0-9A-Fa-f]){2}(.*?)%00(?:%[0-9A-Fa-f][0-9A-Fa-f]){3}%07(.*?)%00(?:%[0-9A-Fa-f][0-9A-Fa-f]){2}(.*?)%00(?:%[0-9A-Fa-f][0-9A-Fa-f]){3}%07(.*?)%00/ ){
		$sel1 = $1;
		$goto1 = $2;
		$sel2 = $3;
		$goto2 = $4;
		$sel1 =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg;
		$sel2 =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg;
		$goto1 =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg;
		$goto2 =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg;
		print OUT "select \"$sel1\",\*$goto1,\"$sel2\",\*$goto2\n";
	}

こんな感じ。変数の使い方が汚いのはご勘弁。
今はNスクデフォルトの "select" を使ってますが、車輪の国などのように
選択肢ウインドウ+文字スプライトのボタン化をすると原物に近づきます。
でも、車輪は単純な "select" じゃ実装出来なかったんですが、これは別に支障ないからなぁ…

ラベル、これはファイル名(拡張子なし)そのままでいいので楽ちんです

と、いうことで曲がりなりにも通しプレイ可能な状態となりました。
適当に暫定公開して、今後は随時演出強化の方向で行ってみたいと思います。
でもONSじゃ拡大・縮小は無理っぽい。大声とかで文字を大きくする演出も当面難しそうです

6/25追記)
>拡縮
と思ったら、ONSでも"drawbg2"が使える模様。Yu--Sさま感謝
"lsp2"が未対応だから、てっきりこちらもアウトかと…
かにしのタスクリストに追加です。不具合が治れば

| 3 / 4 |