2006/07/04(火) [n年前の日記]
#1 [iappli] スクラッチパッドサイズ
ADF中のスクラッチパッドサイズ指定が大きすぎる、という話があったので、適切なサイズを概算・jamファイルを更新するスクリプトを作成。その時々の概算サイズをログに残し、それと比較して、値が大きくなっていたら更新するように。
#!/usr/bin/perl # # スクラッチパッド(SP)のサイズ(概算)を求める。 # # usage : perl getspsize.pl [DIR\HOGE.jam] [DIR2\HOGE.jam] # # # * jam ファイルのパスを与えると、該当 jam の SPsize を書き換える。 # 何も指定がなければ、概算値の表示のみ行う。 # # * 概算したサイズ値は、'getspsize.log' に記録される。 # 既に記録されたサイズ値と比較して、増えているときだけ更新。 # # * 概算したサイズ値は、1024 byte 単位で切り上げをした値。 # # # ◎ 前提・仮定条件: # # * ハイスコア等情報 / 画像データ / サウンドデータ の順でSPに記録。 # # * ハイスコア・その他の記録は、0x0100 byte 使う。 # # * 画像データとサウンドデータの間には、0 が 0x010 byte 入る。 # # * SPの最後には、0 が 0x010 byte 入る。 # # * 画像データ(.res)は、'data' ディレクトリ内にある。 # # * サウンドデータ(.res)は、'sound' ディレクトリ以下に # 「端末別」で、ディレクトリを分けて入ってるものとする。 # use strict; # ハイスコアその他の記録に使ってるサイズ my $etcinfosize = 0x0100; # 画像データとサウンドデータの間に入る 0x00 のサイズ my $imgsndsepsize = 0x010; # 最後に取る 0x00 のサイズ my $lastnullsize = 0x010; # 画像データ拡張子 my $imgext = '.res'; # 画像データフォルダ my $imgdir = 'data'; # サウンドデータ拡張子 my $sndext = '.res'; # サウンドデータフォルダ my $snddir = 'sound'; # ログファイル my $logfile = 'getspsize.log'; # ---------------------------------------- print "\n --- SPsize の概算値を求めます ---\n\n"; my $old_spsize = 0; # 既にログファイルがあるなら読み込んでおく if ( -f $logfile ) { open(IN,$logfile) || die "Can't read open $logfile : $!"; my @l = <IN>; close(IN); $old_spsize = $l[0]; } else { print "not found log. ($logfile)\n"; } # 画像データファイル名の取得 my @img_res_list = (); opendir(DH, $imgdir) || die "Can't open dir $imgdir : $!"; while ( my $f = readdir DH ) { next if $f =~ /^\.{1,2}$/; next unless $f =~ /$imgext$/; push(@img_res_list, $f) if -f "$imgdir/$f"; } closedir(DH); # 画像データファイルの総サイズを取得 my $imgsize = 0; foreach (@img_res_list) { # print $_ , "\n"; $imgsize += -s "$imgdir/$_"; } print "$imgdir/*$imgext\t", $imgsize, " byte ... image .res total size.\n\n"; # サウンドデータファイル名の取得 my %snd_resdir_size_list = (); read_dir_snd_res($snddir, $sndext); foreach ( sort keys(%snd_resdir_size_list) ) { print $_, "\t", $snd_resdir_size_list{$_}, " byte\n"; } print "\n"; # サウンドデータサイズをソート my @keys = sort { $snd_resdir_size_list{$b} <=> $snd_resdir_size_list{$a} } keys %snd_resdir_size_list; # サウンドデータ最大値を取得 my $max_snddir = $keys[0]; my $max_sndsize = $snd_resdir_size_list{$max_snddir}; print "MAX\n", $max_snddir, "\t", $max_sndsize, " byte\n\n"; # SPsize を計算 my $true_spsize = $imgsize + $max_sndsize + $etcinfosize + $imgsndsepsize + $lastnullsize; my $new_spsize = ((int ( $true_spsize / 1024 )) + 1) * 1024; printf("OLD SPsize = %8d (0x%08X)\n", $old_spsize, $old_spsize ); printf("NEW SPsize(true) = %8d (0x%08X)\n", $true_spsize, $true_spsize ); printf("NEW SPsize = %8d (0x%08X)\n", $new_spsize, $new_spsize); print "\n"; if ( $new_spsize > $old_spsize ) { # 新SPsize のほうが値が大きい。ログを更新。 open(OUT,">$logfile") || die "Can't write open $logfile : $!"; print OUT $new_spsize; close(OUT); print "log update. ( NEW SPsize > OLD SPsize)\n\n"; # jam ファイル更新 foreach my $jamfile (@ARGV) { if ( -f $jamfile ) { print "found $jamfile\n"; # jam ファイル読み込み my @l = (); open(IN,$jamfile) || die "Can't read open $jamfile : $!"; while(<IN>) { chomp; push(@l,$_); } close(IN); # jam ファイル更新 open(OUT,">$jamfile") || die "Can't write oprn $jamfile : $!"; foreach(@l) { if ( /SPsize = / ) { $_ = "SPsize = ". $new_spsize; } print OUT $_, "\n"; } close(OUT); print "update $jamfile\n\n"; } } } else { # 更新無し。 print "not update. ( NEW SPsize <= OLD SPsize)\n"; } exit; # ---------------------------------------- # サウンドデータディレクトリを辿って .res があればサイズを取得・記録 sub read_dir_snd_res { my($dirname, $extname) = @_; my @list = (); my @flist = (); # ディレクトリ中のファイル名 or ディレクトリ名の一覧を取得 opendir(DH, $dirname) || die "Can't open dir $snddir : $!"; @flist = readdir DH; closedir(DH); foreach my $f (@flist) { next if $f =~ /^\.{1,2}$/; if ( $f =~ /$extname$/ && -f "$dirname/$f") { # データファイルを見つけたので記録 push(@list, $f); } elsif ( -d "$dirname/$f" ) { # ディレクトリを見つけたので辿る read_dir_snd_res("$dirname/$f", $extname); } } # .res があったらディレクトリ中の総サイズを求めてハッシュに記録 unless ( $#list < 0 ) { my $size = 0; foreach (@list) { $size += -s "$dirname/$_"; } $snd_resdir_size_list{$dirname} = $size; } }
◎ 画像の追加・差し替えが頻繁にあったものだから :
その都度 SPsize を求めなおす・指定し直すのが面倒で。
また、最初の頃は、最終的にどの程度画像・サウンドをSPに入れることになるのか、まったく見当もつかなくて。
さらに、DoJa 3.0 の PDF を読むと、「後からSPsizeを増やす分には構わない」「減らすのはマズイです」と書いてあったりもして。
てなモロモロがあったので、「最大値を入れておけば問題は起きないだろう」と安易に指定しちゃってたという。…早い段階からこういうスクリプトを作っておけば良かったのだな。失敗した。
また、最初の頃は、最終的にどの程度画像・サウンドをSPに入れることになるのか、まったく見当もつかなくて。
さらに、DoJa 3.0 の PDF を読むと、「後からSPsizeを増やす分には構わない」「減らすのはマズイです」と書いてあったりもして。
てなモロモロがあったので、「最大値を入れておけば問題は起きないだろう」と安易に指定しちゃってたという。…早い段階からこういうスクリプトを作っておけば良かったのだな。失敗した。
◎ 全然関係ないけど Perl って :
printf() が使えたのだな。知らなかった。…アレ? Perl は元々あったんだっけか。何かの言語は無かったような記憶が…。
[ ツッコむ ]
#2 [eclipse] _Eclipse Wiki Editor Plugin
_CoolなEclipseプラグイン(7)プログラミングにあると便利なプラグイン
eclipse 上で wiki が使えるようになるらしい。
入れてみた。
.wiki という拡張子のファイルを作成・開くだけで、wikiっぽく書き込めるらしい。下のほうに、「Source」「Browser」「Syntax」というタブがある。Source で編集・保存。Browser で表示確認。Syntax で記法についてのヘルプ文書(?)を読める。が、英語で記述されてるからよくわからない。
む。コレ、htmlで保存とかエクスポートとかできないのか。それじゃ使えないな…。
eclipse 上で wiki が使えるようになるらしい。
入れてみた。
- eclipse 3.1.1 を使ってるので、com.teaminabox.eclipse.wiki_2.4.0.zip をDL。
- zip を解凍すると com.teaminabox.eclipse.wiki_2.4.0 というフォルダができた。
- eclipse の plugin フォルダの中に、フォルダごとコピー。
- eclipse を起動。設定で、wiki のソレを変更。
.wiki という拡張子のファイルを作成・開くだけで、wikiっぽく書き込めるらしい。下のほうに、「Source」「Browser」「Syntax」というタブがある。Source で編集・保存。Browser で表示確認。Syntax で記法についてのヘルプ文書(?)を読める。が、英語で記述されてるからよくわからない。
む。コレ、htmlで保存とかエクスポートとかできないのか。それじゃ使えないな…。
[ ツッコむ ]
#3 [iappli] 結合データがオリジナルデータと合ってるかどうかを確認するプログラムを作成
SO902iでサウンドがスクラッチパッドから読み込めない問題を調査中。Perlで結合していることで、結合データ中の一部がおかしくなってるのかな、と不安になったので、チェックするプログラムは Java で作成。ファイル名を取得するあたりでちとハマる。出来上がってからふと気づく。考えてみれば、String[] として持ってしまって良かったのかもしれん。どうせ使い捨てのプログラムなんだし。
こんな感じになった。
チェックしてみた。オリジナルデータと一致してる。うーん。一体何がおかしいのか。わからん。
こんな感じになった。
import java.io.File; import java.io.FileInputStream; import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.util.Arrays; import java.util.Comparator; /* * サウンド用 .res の内容と、.mld の内容を比較する */ public class CheckResCoherent implements FilenameFilter { /** * @param args mld格納フォルダ res格納フォルダ */ public static void main(String[] args) { // 引数の数が合ってなかったら使い方を表示 if (args.length != 2) { usage(); return; } // ファイル情報取得 File[] filesMld = new File(args[0]).listFiles(new CheckResCoherent()); File[] filesRes = new File(args[1]).listFiles(new CheckResCoherent()); // ファイル名でソート Arrays.sort(filesMld, new NameComparator()); Arrays.sort(filesRes, new NameComparator()); // 念のためにファイル名一覧を表示 for (int i = 0; i < filesMld.length; i++) { System.out.println(filesMld[i].getPath()); } // 念のためにファイル名一覧を表示。ついでに総サイズも取得 int resSize = 0; for (int i = 0; i < filesRes.length; i++) { System.out.println(filesRes[i].getPath()); resSize += filesRes[i].length(); } // 結合データを読み込む int cnt = 0; byte[] buf = new byte[resSize]; InputStream in = null; for (int i = 0; i < filesRes.length; i++) { try { in = new FileInputStream(filesRes[i].getPath()); int ch; while ((ch = in.read()) != -1) { buf[cnt] = (byte) (ch & 0x0ff); cnt++; } } catch (IOException e) { System.out.println(e); } finally { try { if (in != null) { in.close(); } } catch (Exception e) { } } } System.out.println(cnt + " byte ... res total size"); // 結合データのヘッダ部分から、格納されてるファイル数等を取得 int ofs = 0; int fnum = getShort(buf, ofs); System.out.println("file num = " + fnum); ofs += 2; int cksum = getShort(buf, ofs); System.out.println("Checksum = " + cksum); ofs += 2; int fsize = getInt(buf, ofs); System.out.println("file size = " + fsize); ofs += 4; // 1ファイルずつチェック for (int i = 0; i < fnum; i++) { // データ種類取得 int datakind = buf[ofs]; ofs += 1; // オフセット取得 int dofs = getInt(buf, ofs); ofs += 4; // サイズ取得 int dlen = getInt(buf, ofs); ofs += 4; // オリジナルの mld データを読み込む long osize = filesMld[i].length(); if (osize != dlen) { System.out.println("Error:" + i + "\tファイルサイズが一致しません。 orgsize=" + osize + " ressize=" + dlen); return; } byte[] ob = new byte[(int) osize]; int cn = 0; try { in = new FileInputStream(filesMld[i].getPath()); int ch; while ((ch = in.read()) != -1) { ob[cn] = (byte) (ch & 0x0ff); cn++; } } catch (IOException e) { System.out.println(e); } finally { try { if (in != null) { in.close(); } } catch (Exception e) { } } // 結合データの中身と、オリジナル mld を、1byteずつ比較 int fg = -1; for (int n = 0; n < ob.length; n++) { if (ob[n] != buf[dofs + n]) { fg = n; break; } // System.out.println(n); } if (fg >= 0) { System.out.println("Error:" + i + "\tデータが一致しません。\toffset=" + fg); return; } System.out.println("kind=" + datakind + "\toffset=" + dofs + "\tlength=" + dlen + " : check OK " + i); } } // 一応、使い方を説明 static void usage() { final String[] mes = { "サウンド用 .res の内容と、.mld の内容を比較します。", // "usage : java MLD_DIR RES_DIR", // }; for (int i = 0; i < mes.length; i++) { System.out.println(mes[i]); } } // 特定拡張子のファイル名だけを取り出す public boolean accept(File dir, String name) { if (name.endsWith(".mld") || name.endsWith(".res")) return true; return false; } // byte[] から short を取得 static int getShort(byte[] b, int offset) { return (((b[offset] << 8) & 0x0ff00) | (b[offset + 1] & 0x00ff)); } // byte[] から int を取得 static int getInt(byte[] b, int offset) { return (((b[offset] << 24) & 0x0ff000000) | ((b[offset + 1] << 16) & 0x0ff0000) | ((b[offset + 2] << 8) & 0x0ff00) | (b[offset + 3] & 0x00ff)); } } // ソート用 class NameComparator implements Comparator { public int compare(Object o1, Object o2) { File f1 = (File) o1; File f2 = (File) o2; return (f1.getName().compareTo(f2.getName())); } }
チェックしてみた。オリジナルデータと一致してる。うーん。一体何がおかしいのか。わからん。
[ ツッコむ ]
#4 [novel] マリア様がみてるの選挙の巻を読んだ
妹が新刊を買ってきたとのことで、貸してもらった。
ドリル。引っ張るなぁ。
ドリル。引っ張るなぁ。
[ ツッコむ ]
#5 [comic] 観用少女の特集号とやらを読んだ
これも妹が(以下略。
川原由美子先生のインタビュー記事が。最近漫画を描いてないらしい。残念な話。
川原由美子先生のインタビュー記事が。最近漫画を描いてないらしい。残念な話。
[ ツッコむ ]
以上、1 日分です。