mieki256's diary



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を増やす分には構わない」「減らすのはマズイです」と書いてあったりもして。

てなモロモロがあったので、「最大値を入れておけば問題は起きないだろう」と安易に指定しちゃってたという。…早い段階からこういうスクリプトを作っておけば良かったのだな。失敗した。

全然関係ないけど Perl って :

printf() が使えたのだな。知らなかった。…アレ? Perl は元々あったんだっけか。何かの言語は無かったような記憶が…。

#2 [eclipse] _Eclipse Wiki Editor Plugin

_CoolなEclipseプラグイン(7)プログラミングにあると便利なプラグイン

eclipse 上で wiki が使えるようになるらしい。

入れてみた。
  1. eclipse 3.1.1 を使ってるので、com.teaminabox.eclipse.wiki_2.4.0.zip をDL。
  2. zip を解凍すると com.teaminabox.eclipse.wiki_2.4.0 というフォルダができた。
  3. eclipse の plugin フォルダの中に、フォルダごとコピー。
  4. eclipse を起動。設定で、wiki のソレを変更。
記法を弄ってみたけど、snipsnap というのが一番機能が実装されてるっぽいように見えた。

.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 日分です。

過去ログ表示

Prev - 2006/07 - Next
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project