« PerlでONS -かにしの編 その0 ~見まねデコード~ | メイン | PerlでONSへ変換しよう  基本編 ~シナリオ読込~ »

2007年06月15日

●PerlでONS -かにしの編 その1 ~テキスト整形~

前回でとりあえず日本語に復号はしましたが、テキストとファイル名以外の箇所は
まともに読めません。これは制御コードなので暗号とかそういう以前の問題だそうです。

しょうがないので、プレイしながら地道にバイナリエディタで付き合わせてみる
以下解析推測メモ。不完全且つ誤り多し。随時更新

00 07 [file]	:シナリオジャンプ
00 21 0d xx xx 0A	:BGM -番号,時間
00 22 0d xx xx 00	:BGMストップ -番号,時間
00 23 00 	:ボイス
00 25 0d xx 00	:SE -番号
00 26 0d 00	:SEストップ -番号
00 29 00 xx xx 00	:ウェイト? -時間?
00 41 xx xx 00	:テキスト -通番
00 42 xx xx 00	:テキスト(名前有り) -通番
00 46 00 	:背景
00 48 0d xx xx yy ff 00 :画像読み込み -番号,x座標,y座標(-255?)
00 49 0d 00	:画像消去
00 4a xx yy yy 	:描画 -エフェクト[19 通常,2A マスク,1A ?,1D 上スク],時間
00 4b 0d xx xx yy ff zz zz 00	:画像移動 -番号,x値,y値(-255?),時間
00 4d 01	:振動
00 54 [file]	:マスク読み込み

これがある程度まとまったら、それぞれのところで改行を入れて整形します。
勿論、オリジナルに忠実なものではなく、あくまで私が勝手に処理しやすいよーに

(前略)
	@decode = split( /:/,&plast($char1));
	foreach $decode(@decode){
		$decode =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/pack("H2", $1)/eg;
		print OUT "\x0D\x0A$decode";
	}
(後略)


sub plast{ $_[0] =~ s/(%00%21(?:%[0-9A-Fa-f][0-9A-Fa-f]){3}%0a)/:$1/gi; $_[0] =~ s/(%00%22(?:%[0-9A-Fa-f][0-9A-Fa-f]){3}%00)/:$1/gi; $_[0] =~ s/(%00%23%00)/:$1/gi; $_[0] =~ s/(%00%25(?:%[0-9A-Fa-f][0-9A-Fa-f]){2}%00)/:$1/gi; $_[0] =~ s/(%00%26(?:%[0-9A-Fa-f][0-9A-Fa-f]){1}%00)/:$1/gi; $_[0] =~ s/(%00%29(?:%[0-9A-Fa-f][0-9A-Fa-f]){3}%00)/:$1/gi; $_[0] =~ s/(%00%41(?:%[0-9A-Fa-f][0-9A-Fa-f]){2}%00)/:$1/gi; $_[0] =~ s/(%00%42(?:%[0-9A-Fa-f][0-9A-Fa-f]){2}%00)/:$1/gi; $_[0] =~ s/(%00%46%00)/:$1/gi; $_[0] =~ s/(%00%48(?:%[0-9A-Fa-f][0-9A-Fa-f]){5}%00)/:$1/gi; $_[0] =~ s/(%00%49(?:%[0-9A-Fa-f][0-9A-Fa-f]){1}%00)/:$1/gi; $_[0] =~ s/(%00%4a(?:%[0-9A-Fa-f][0-9A-Fa-f]){3}%00)/:$1/gi; $_[0] =~ s/(%00%4b(?:%[0-9A-Fa-f][0-9A-Fa-f]){7}%00)/:$1/gi; $_[0] =~ s/(%00%4c%00)/:$1/gi; $_[0] =~ s/(%00%4d%01)/:$1/gi; $_[0] =~ s/(%00%54%45%46)/:$1/gi; return $_[0];

}

トラックバックURL

このエントリーのトラックバックURL:
http://hitotsumori.com/x/cgi-bin/mt/mt-tb.cgi/25

コメント

こんにちは
今度はこの段階で躓いてしまいました。
作業を進めていると 行の後ろの方にあるコマンドがすべてスルーされていることに気がつきました。なぜかなと調べてみると、おそらく"$line=~/()/g"コマンドですると 二回目以降のヒットしたやつは$1以外のどこかへ入ってしまうようです。
そこで、シナリオを改造しようと思ったのですが、こちらのゲームでは 改行がコマンドとして使われていてそれを無視して取り込むにはどうすればいいかわからなくなってしまいました。どうでしょうか?

"$line =~ /(\w*)(\w*)/g"
だとすると順番に$1、$2に入ります
以下同様に$3、$4、$5・・・となります

改行がコマンド、とはどのような常態か思いつかないんですが、どんな感じになっているのでしょうか

m// 演算子及び s// における g の挙動の違いでしょうかねー

$line =~ m/(hoge)/g;  (mは通常省略してます)

ですと、確かに繰り返しマッチさせても最初にマッチしたものが$1に入るだけですね。
(一度 $_ に入れて @list = m/(hoge)/g; とすると配列@list に順次入っていきます)

なので私は
$line =~ s/(hoge)/:$1/g;
として、順次置換を繰り返す様な形でやってます。
":"を付け足して、後ほど改行にするという形なのですが…元記事では説明してませんね。ううむ

改行コマンドについては、例など示して頂けると助言できるかもしれません。

ありがとうございます。実はシナリオ変換をやっているところでつまずきまして、これをやってみようと思ったのですが。
(なので、;を区切りとしてLineに突っ込んでる関数のところは理解していました。)
受験も終わりまして、ゆっくり考えてみまして
@関数に代入して Foreachで取り出して見るという方法を思いつきました。Perlはいろいろやり方があるので、ひとつずつできるまでやってみようと思います。

改行コマンドについて(これが解決すればずいぶん楽になるはず)
こちらで変換しようとしているゲームは機能別に別の関数が作ってあって、そのときにある数値?を送ってその関数の中にあるものを実行するみたいなところがあるのです。

例     BG\BG_04_s.png   2 etc\BGMstop.yks Flag   etc\bgmchange.yks  TA\m_kona_01.png TA\m_kona_01_A.png  TA\m_hide_03.png TA\m_hide_03_A.png ・ 2  d VO\VOKO_1189.ogg ついに全員がそろった青空戦隊丘見えセブン!  TA\m_nono_04.png TA\m_nono_04_A.png X ッ  d VO\VOKO_1190.ogg しかし!ブラックNの裏切りによって、 部隊はいきなり壊滅状態に!? d VO\VOKO_1191.ogg  TA\m_hide_02.png TA\m_hide_02_A.png ・ ・  TA\m_kou_02.png TA\m_kou_02_A.png h ・  この窮地を、秀兄ぃはどう切り抜けるのか!

Flag   etc\bgmchange.yks ここのフラッグの間の部分に記号があって(コピペなのであるはず)

Bgmchangeの一文
 エ g  } ヘ  Flag  {    bgm\m07_01.ogg bgm\m07_02.ogg  
 エ g  } ・  Flag G {    bgm\m07p_01.ogg bgm\m07p_02.ogg  
これでどれを再生するか選んでます。ここのフラッグの部分に改行(¥nなのか?)が使われているのです。 バイナリで開くと00 0A 00 00 の部分が改行扱いになってます。
シナリオ中にも0Aを送ろうとするところがそこで行が切れてしまうので、どうすればよいのかわからないのです。。

長文失礼します。

なるほど、バイナリ形式で扱うのかテキストとして扱うのかにもよりますが

undef local $/;
local $line = <IN>;

とすると見かけの改行を無視して一気に読み込んでくれます。詳しくは「入力レコードセパレータ」で。
これで処理できないでしょうか?

そして受験お疲れ様でした。
Perlは本当にやり方がいくらでもあるので、ゆっくりしながら色々遊んでみてください。

遅くなりましたが、返答ありがとうございます。まだそこまでいけてないので、ためしていませんが、(今ためしても、内部だからっ出力にはそのままでてくるからわからない)

splitが途中で止まるのですが、なぜだか見当がつきませんセパレーターの:(3A)は入るんですが、改行がなされないのです。リミットの数字も入れてないですし。
00 00 0D 0A 20 0D 0A 00 00 00
(短い空白に改行がはいって、その次の行の先頭が必ず3つ空白があってその次の行からかいぎょうがきかなくなっています。)
何かピンと来るものはないでしょうか?

毎度毎度すいませんん

うーむ、ごめんなさい、ちょっとピンとこなかったです…。
splitが途中で止まるという状況はよく分かりませんね。
お役に立てず申し訳ありません。

いえいえ、そんなことはないです。
いろいろ確かめてみます。

コメントする