正直日記



2006/01/28

_ GBP、なんかおかしくね?
GBプレイヤーで縦画面のテストをしていたら動作が妙にガクガクするので気
になった。4〜5秒に一度、一瞬止まる感じがする。

NTSCが59.94Hz、GBAが59.72Hzなので、1秒間に0.22フレームずれる計算に
なり、ということは5秒に一度、フレームスキップが入るのかもしれない。
今度キャプチャして確認してみようかと思う。

ところで0.22フレームで合ってる?
あれれ、どうなっているんだこれは?

SaTa. > GBPだとGCのプログレッシブモードも使えるので、それもタイミング変わるのかなぁ。  (2006/01/29 07:59:59)
SaTa. >
NDSで計ったら、今のところ約59.83Hzっぽい。
GBA用の測定ツールも作っているのでそのうち。
 (2006/01/30 15:59:58)
> そういえば、GBPのメニュー画面なんかを見た感じだとインターレースで表示してるっぽいんですよねえ。ひょっとしたら29.97fpsなのかも。プログレッシブモードだと59.94なんでしょうね。後でキャプって検証してみます。  (2006/01/30 16:31:02)
SaTa. >
VSYNCカウント中
NDS(ARM9)138万回、 59.82Hzまで確定。
GBmicro 25万回、 59.7Hzまでは確定。
 (2006/01/30 18:30:33)
>
経過フレーム数を表示して1ドットずつスクロールするだけのテスト
ツールを、GBPからS端子経由にて 640*480 29.97fpsでキャプチャし
たのちに、aviutlで59.94fpsとして読み込んで奇数・偶数フィールド
に分離してみたのですが、稀に連続して4フレーム落ちてました。
(4フレームも止まったら目に見えてガクガクするよなあ)

一応そのときの様子と、テストに使ったソースをアップしておきます。
動画の方は容量が大きいため最初の60フレームだけを切り出しました。
http://www.liarsoft.org/data/gbp_test.zip
http://www.liarsoft.org/data/gbp_test_rom.zip
 (2006/01/30 18:48:54)
>
>59.7Hzまでは確定
お疲れ様です。

GBAは1ドット表示するために4サイクル必要で
H(240+96) * V(160+68) * 4 = 280,896

GBAのクロックをそれで割って
16MHz / 280896 = 59.7275...

と、机上計算でもそういう数字が出るみたいですが、
実機で確認出来たのは安心しますね。

ところで http://www.bottledlight.com/ds/index.php/Video/Screens
によると、NDSの場合6サイクル必要で
32MHz / ( H(256+99) * V(192+71) * 6 ) = 59.8983...
という計算になるようですが59.82Hzですか。
0.07くらいだったら誤差の範囲だろうけど……。
 (2006/01/30 19:21:58)
SaTa. >
クロックの話はここで書いてます
http://www.pat.hi-ho.ne.jp/sata68/200601.html#26_gogo2
そして、テストプログラムです。
http://www.pat.hi-ho.ne.jp/sata68/200601.html#30_yoru
GBA,GBASP,GBm,NDSはあるけど
GBPは手元にないので気になりますね。
 (2006/01/30 22:33:49)
>
なるほど、1000*1000ですか!それなら59.82でピタリですね。
テストプログラムなのですが、私が使っているカートはRTC無しの
F2A ProなのでGBPで計測が出来ません。GBPはミクロと違って
GB/GBCもプレイできるので、GBAと同じなのでは無いかなあ。

……あっ、なんでミクロで計測してるのかやっと分かった(^^;
クロック周波数が16.756MHz * 1の可能性があるわけですか。
ああなるほどなぁ。だから計ってたんですか。
 (2006/01/31 00:17:11)
SaTa. >
ひとまずこんな状況
http://www.pat.hi-ho.ne.jp/sata68/200601.html#31
GBm,NDS,NDSのGBAモードでバラバラ。
 (2006/01/31 15:16:26)
>
そのフレームレートをPCMのサンプリングレートに換算してみると……
(GBAを16,776,000Hzとして1フレームあたりのサンプルバッファ528バイト
=サンプリングレート31533.83Hzを基準にする)

GBm: 31533.74Hz
NDS: 31496.26Hz

コレを聴き分け出来る人は流石にいないだろうな。
 (2006/02/01 01:20:33)

2006/01/27

_ 指定初期化子 designated Initializer
GCCで使用できる指定初期化子(C99にも取り込まれている)はenumと組み合
わせると、キャラクター配列を作るときに便利だね。
enum {
	chr_walk_pattern,
	chr_run_pattern,
	chr_sleep_pattern,
};

const struct {
	ANIME_CHR *anime_dat;
	int anime_number;
	int anime_wait;
} Charactor[] = {
	[chr_walk_pattern]  = {&chr_walk, 4, 2},
	[chr_run_pattern]   = {&chr_run, 4, 1},
	[chr_sleep_pattern] = {&chr_sleep, 2, 6},
};
後になって新しいパターンをあいだに挿入したくなったとき、いちいち番号 を書き換えなくても済むのが素晴らしいのだ。

2006/01/20

_ 本日のポカミス
中ボスキャラが一定のダメージを受けると攻撃手段を変える、という処理を
作っていて、それまで保持していた攻撃タスクを捨てて新しい攻撃タスクを
生成するという風に実装した。

捨てるときは、子タスクの死亡フラグを立てて勝手に死んでもらうようにし
ていた。(更に子供・兄弟がいるときは勝手に連鎖して死んでもらう)
	enemy->child->status = DEAD;
まあ、こんな感じで。 んで、新しい子供の動作が出来上がったところでテストプレイしてみると、 いざ新攻撃だ!と思ったところでボスの攻撃がピタリと止まってしまった。 なぜだ! 坊やだったからさ。 まあネタは置いといて何度かテストしてみると、ちゃんと攻撃してくるとき と来ないときがあることが判明した。で、よくよく調べてみると新しく作っ た子タスクの生存状態を初期化し忘れていて
	enemy->child->status = DEAD;
のままだったという……。たまたま他のタスクが、攻撃タスクで言うところ の status == ALIVEのまま破棄されて、その要素を使いまわしたときに攻撃 してきていたようだ。そういうわけでちゃんと攻撃してくるのはバグだった。 うん。ポカどころか渾身のミスだね。こうして晒すことによって、バンバン 信用を失っていくのもそれはそれで。 全然関係ない話になるけど、GBAのちっこい画面でテストプレイして目が慣れ てしまうと、ゲーセンのでっかい縦画面が全然目に入らなくて困る。つまり どういうことかと言うと『虫姫を 二面で終える 昼下がり』

> 季語:虫姫  (2006/01/21 01:03:48)

2006/01/19

_ 思考の狭間から
ゲームループが1フレームに間に合わなかったときに、ループの最後でHALT
すると次フレームを丸々損してしまう。ひょっとしたら次フレームで必要な
ループは残された時間内に収まるかもしれないし。

なら、おっかけで処理すれば、とか思うのだけど、残された時間に収まらな
かった場合を考えると自転車操業になってしまうので、どうしたもんかなー
とか考えてた。

先行処理しとくって手もあるけど、すると今度は入力遅延ですよ。

要するにHALTにこだわらなくてもいーじゃん?という意識変革が俺の中で起
こりつつあるのだけど、処理落ちしてもいいならHALTしたっていーような気
もするじゃん?どっちだよ!俺の明日はどっちだよ!

ちなみに、今のところ間に合ってるから。こんなこと考えなくても十分だか
ら。二つで間に合ってるから。

SaTa. >
前回1フレーム内で処理できなかったとき
次のフレームで2フレーム分の処理をするとか、
まあ、処理落ちorフレームスキップのどちらしかありませんが。
表示/入力処理以外だったら処理させておくとう手もありますかね。
スケジューリングが難しくなりますが。
 (2006/01/20 08:43:13)
>
ティアリング覚悟で無理矢理VDISP期間に更新してしまうという
手もありそう。まあ更新したところで、次フレームがまた間に
合わなかったら堂々巡りですが……。

ティアリングは、実機で実験してみると、GBA(SP・Micro含む)
なら気になりませんがGBPだとかなり気になりますね。

フローが複雑になるのは避けたいので、処理落ちを選択するのが
一番無難かな。
 (2006/01/21 00:34:24)

2006/01/18

_ 近況
水を得た魚のようにアセンブリを書きまくっていたが、結局はコンパイラに
勝てなかったので翼を折られた天使であった。

そこで、ふと手を休めて自分を見直してみると、手段と目的が逆転している
ことに気づいてしまった。ゲームを作るために環境を整備していたはずが、
いつの間にか環境を作ることのみに夢中になっていたというアレ。

そういうわけでアレの続きを開始したが、モリモリ進んでいるような、設計
を見直したくなるような、そのなんだ、アレだ。アレが多くなってきたので
俺にはPSPのアレが必要だ。脳を鍛えるアレ。

それはさておき、本日のポカミス。
int main(void) {
	while (1) {
		asm("swi 0x0002"); // Halt
		TaskExec();
	}
}
メインループをこう記述して、毎フレーム一回ずつTaskExec()が実行されて いた。今までVBLANK割り込みしか使ってなかったので、それで正常に動いて いたのだが、HBLANK割り込みで画面エフェクトを作ってみたら、1ライン毎 の割り込みでHALTが解除されて早回しがかかってしまったという。 止めたいと思っても止まらないので──そのうち男はHALTを使うのをやめた。

SaTa. >
VBLANK割り込みでフレームカウントして、
TaskExec()内で前回呼び出しとのフレームカウントの差を見て
処理を進めるのがいいでしょうか。
進んでなかったら即リターン。
 (2006/01/18 22:45:04)
>
VBLANK割り込み関数の中に入れてみたり、
haltの代わりに while (REG_VCOUNT != 160) {} で空ループさせて
みたりしてたんですが、そちらの方がhaltも使えるし良いですね。
 (2006/01/19 07:56:17)

2006/01/12

_ インターフェース2月号
を買ってきた。「ARMアセンブラ・コードを理解しよう」という記事が目的
だったのだけど、ARMメモARM7TDMIの部屋を一通り読んで頭に入れてから
gccに最適化無しで吐かせたコードを眺めれば済んでしまう内容だったので
立ち読みしてから買うかどうか決めれば良かったかもしれない。

そこから先に進みたければやはり、それなりのアレをナニしなけりゃならん
ね。

2006/01/10

_ 俺はコンパイラに勝てない屑人間
gcc の吐くコードを眺めると条件実行がさほど使われて無いことに気づく。
じゃあ条件実行を使いまくればいーじゃんという素人考えでリファレンスと
格闘しながら書いてるんだけど、結局のところコンパイラに勝ててない。

というか、条件付き命令の使いどころがあんま思いつかないよ。4ニーモニッ
ク以上にまたがる様なら分岐した方が速い様な気もするし。

2006/01/09

_ GCC3のインラインアセンブリ
asm文一つに複数の命令を書きたい場合
	asm (
		"add    r0, r0, r1 \n"
		"subs   r1, r0, #0xff \n"
	);
のように一命令ごとにダブルクォーテーションで括って、しかも命令の最後 は\nで締めないといけないと思ってたんだけど、実は
	asm (" 
		add    r0, r0, r1;
		subs   r1, r0, #0xff;
	"); 
セミコロンで区切ればいちいちダブルクォーテーションで括ったり改行記号 を入れたりしなくていいようだ。今までこのような書き方をしてるところを 見たことが無いんだけど、何か副作用でもあるんだろうか? あ、無いけど、あるね。 -Sでアセンブリコードを吐かせると……。
_ 俺は2005年がとても好きだったので
それが終わってしまって残念に思っている。辛い。
_ ファオ!
最近の俺はドリキャスづいていて、今はトライジールとスペースチャネル5
をやっているのだが、スペチャンをやっていたら何故かCaptain EOが見たく
なったのでGoogle Videoで検索してみたら全く引っかからなかったのでGoo-
gle Videoは駄目だな!でもGoogleで検索してみたらすぐ出てきたよ。ネット
は千葉大だわ……。

中身を殆ど覚えてなかったけど、観たらなぜスペチャンをやってCaptain EO
が見たくなったのかがよく分かった。マイコー先生はマジかっこいいなぁ。
_ 折角公開したんだし
もうちょいなんとかするかと思って、なんとかしてるんだけどなんともなら
ないよ。とにかくミキサをどうにかしないと話が進まないので、そればっか
弄ってる。つーかひらがなが多いよ。

で、弄って一番効果が大きかったのはサチュレーションだった。
これまでがこんな感じ。
	if (m0 > 127) {
		m0 = 127;
	} else if (m0 < -127) {
		m0 = -127;
	}
分岐が二回も入っていや〜んなので、飽和演算でググってひっかかったアレ、 というかくりあき先生のところに書いてあった飽和演算のアレを試してみる。
	m0 += 128;
	if (m0 &amp; 0xffffff00) m0 = (m0 >> 24) ^ 0xff;
	m0 -= 128;
すると、約1%も速くなったよすげええええええええええええええええ11 という夢を正月に見ました。

> 夢かよ!  (2006/01/09 23:25:38)
> マジ多幸感に包まれた夢だったぜ(´ー`)hehehe...  (2006/01/10 00:20:18)

最新
2010 | 01 04
2009 | 01 02 03 04 05 06 07 09 10 11 12
2008 | 01 02 03 04 05 06 07 08 09 10 11 12
2007 | 02 03 04 05 06 07 08 10 11 12
2006 | 01 02 03 04 05 06 07 08 09 10 11 12
2005 | 01 02 03 04 05 06 07 08 09 10 11 12