正直日記



2006/05/30

_ ああくそっ
固定小数点を1:8:7で取るとき

(0,240)          (240,240)
 ┏━━━━━━━━━━━━┓
 ┃  ┌──────┐  ┃
 ┃  │      │  ┃
 ┃  │      │  ┃
 ┃  │      │  ┃
 ┃  │      │  ┃
 ┃  │      │  ┃
 ┃  │      │  ┃
 ┃  │      │  ┃
 ┃  │      │  ┃
 ┃  └──────┘  ┃
 ┗━━━━━━━━━━━━┛
(0,0)           (240,0)

こういう風に座標を取っちゃ駄目だ。右側に16ドットしか余裕が無い。
1:9:6にするか、中央を(0,0)にするかしたほうがいいな。あー。

2006/05/24

_ 比較の順番
シューティングの当たり判定は、縦シューなら縦軸を横シューなら横軸
を先に判定すると比較が少なくて良いのだな。特に、弾が膨大にあると
顕著。まあ考えてみれば当然か。

空間を分割して登録、比較するようにすれば多分もっと稼げるけどそこ
までするほど困ってないと言うか、登録するためのテーブルを用意する
ほどメモリがあるわけではないというか、メモリはあるんだけど、最終
的にリプレイを保存したいのでERAMは余っていればいるほど良いという
か、よくよく計算してみると毎フレ1バイトをRLEで圧縮という条件でも
約30分のリプレイが収まらないかもというか。

tekezo > BulletGBA の実測値だと、毎フレ2バイトのランレングスで 20分/32KB くらいになるみたいですよ。 もちろんキー入力の指向性が違った場合には無意味な数値ですが。  (2006/05/24 14:15:52)
> 秒間約5回の手連射が入って30分/60KBくらいかな。実のところあと50KBくらいしか空きが無かったり……。  (2006/05/25 23:19:14)

2006/05/23

_ タスクシステムとスプライトとポーズと
みんなポーズ機能はどうやって実装してるんだろうか。大雑把に書くと
「タスクを止める」か「タスクが止まる」かなんだけど。まあどっちで
やってもいいんだけど、止まっているキャラクタを描画したい&動いて
いるキャラもいるとかメニュー画面を出したいとか、という条件で……
えーと、前者の場合タスクは描画命令を出せない。だから、キャラクタ
の描画はどこかで肩代わりしてやるとか。後者の場合それぞれのタスク
にポーズ時の挙動を記述するのが面倒だが描画命令は出せるっつーか。
そもそも描画を命令する必要があるという設計がいかんのかもしんない。
でもタスクのリストを一からなめてどうこうってのもなんかヤじゃない。
virtual void draw(void) = 0;をオーバーライドして…みたいなさあ。
オブジェクト指向でなんでも解決できると思ったら大間違いなんだぞ。俺が。

唐突に結論を出すが、俺は明日死ぬ。

SaTa. >
VSYNC割り込みで処理しているんだったら、割り込みとめて、
ローカルで描画処理すればいいような気がします。
あとは、常に処理するものとポーズで止める処理をフラグで分けるとか。
 (2006/05/23 09:54:19)
> 何かすごい嘘波動を文末から感じるぜ!  (2006/05/23 10:56:16)
tekezo > 全然関係ないですが仮想関数はパフォーマンスに直結するので使うのにドキドキしますね  (2006/05/23 12:05:37)
>
VSYNC→PCM更新→BG・スプライト更新→割り込み終了→音楽生成→タスク実行
というループなので割り込み止めても変わらんです。

(「俺システム」の制約を今から書き足すのは後だしジャンケンの極みで気恥ずかしい
のですが)現在の自分のシステムでは登録したスプライトは表示された時点で登録抹消
されるので、毎回登録しなおす必要があるのですが、止められたタスクからは登録出来な
い。ポーズフラグを作り、タスクの方でそれを見て「スプライト登録はするが行動はしない」
という状態を作ればいいんですが、タスク関数を作るたびにいちいちそれを記述するのは
面倒くさい。という、すいません愚痴なのでした。
 (2006/05/24 09:10:45)
> ここは正直日記なので本当です。俺は今日死にます多分。というか正直日記という題名がまず嘘だが。  (2006/05/24 09:13:45)
>
仮想関数の合理性はまあ分かるんですが、純粋仮想関数には理想と現実の差を感じます。
とりあえず宣言しておく、というのが微妙。
 (2006/05/24 09:22:36)

2006/05/17

_ サウンドを鳴らす WonderSwan編〜そして伝説へ〜


曲コンバータも音源ドライバもほぼ完成し、意気揚々と実行してみたら
まともに曲が鳴らない。しばらくハマったがどうやら outb(port, var)
の引数 port には変数が使えないようだ。

void outb(u8 port, u8 value)
{
  asm push dx
  asm push ax
  asm mov dx, port
  asm mov al, value
  asm out dx, al
  asm pop ax
  asm pop dx
}

こんなの。アセンブリを吐かせると

  push bp
  mov  bp,sp
  push dx
  push ax
  mov  dx,[bp+4]
  mov  al,[bp+6]
  out  dx,al
  pop  ax
  pop  dx
  pop  bp
  ret

こんな感じ。使えそうな気がするんだけど使えない。定数ならOKで変数
が駄目な理由はなぜかしら。仕方ないのでアレをアレしたら、まともに
鳴るようになった。

絵・音・割り込みが使えるようになったので一通りのことが出来るよう
になったかな。満足したので、これにてWonderSwan編は終了。もし続き
をやるとしたら以降はmixiの方に書きます。

2006/05/16

_ サウンドを鳴らす WonderSwan編〜途中〜
一通りの鳴らし方が分かったのでシーケンスの作成だ。MMLコンパイラを
改造しようかと思ったが、MMLを打つのが激しく面倒なのでやっぱり例の
SMFコンバータを75Hz仕様にすることに。

MIDIメッセージ一つに4バイトも使うと、あっというまに容量をオーバー
してしまうので最大2バイトに圧縮。データ的にはMMLをコンパイルして
作るものと変わらんようなアレになった。エンベロープ仕様は取り合え
ずADSRでいいか。
_ サウンドを鳴らす WonderSwan編〜中途〜
WSCampは周波数を弄ると再発音するが、これは再発音しないほうが正解
のような気がする。ソースがあれば直すんだけどなあ。おかしなLPFの
せいで音が不自然に丸いのもどうにかしたい。

OSwanはソフトスウィープしても再発音せずに鳴っとるね。ただしこちら
はノイズチャネルを波形メモリ音源と併用したときの挙動や、ハードの
再生限界値を超えたときの挙動(最高/最低の周波数を入れて消音する
というテクニックがある)が大分怪しいな。まあこちらは修正可能だけ
ど。

2006/05/15

_ サウンドを鳴らす WonderSwan編


つーかスワン楽しすぎる。自分で割り込みが作れたもんだから嬉しくて
ついつい弄ってしまう。GBAでもまるきり同じことが出来るのに。この
感覚は久しぶりだなあ。

勿論GBAもちゃんと進めてます。スワンに掛かりっきりなわけではない。

割り込みが一段落したので、今度は音を出してみようかと思う。基本的
には周波数と音量を指定するだけなので、鳴らすこと自体は楽勝なよう
に思える。しかし音色はどこで変えるのだ?謎なのだ。

……どうやらI/Oの$8Fで波形メモリのベースアドレスを変えるらしい。
$8Fに書いた内容を6ビット左にシフトした値がベースアドレスとなり、
そこから順に16バイトずつ(1バイト2要素で)32要素の波形を書いてい
くようだ。


うーん、割り込みベクタからスプライト・BGテーブルから波形メモリ
に至るまで、なんでもかんでもIRAMに置いてあるのは、なんだかなあ。
CPUがCISCだから仕方ないんだろうけど。

00FF:FFFF +------------+
     |      |
     |  CODE  |
     |      |
0040:0000 +------------+
     |      ?     |
0002:0000 +------------+
     |  SRAM  |
0001:0000 +------------+
     |  IRAM  |
0000:0000 +------------+

現状、IRAMとCODE(の最初のバンク)しか使えておらず、しかもIRAMの
先頭64バイトは割り込みベクタに、末尾512バイトはグラフィック用に
使用している。

SRAM領域がメモリとして使えれば大分楽になるし、コードセグメントも
弄れれば尚いいんだけど……まあ本腰を入れるわけではないからいいか。
_ 割り込みを作る WonderSwan編〜そして伝説へ〜


やっと安定した。VBLANK割り込みでスプライトを表示しつつ、HBLANK割
り込みでBGをウネウネとスクロールさせてます。

ワンダースワンのHBLANK割り込みはnライン間隔で発行させられるので
色々と面白いことが出来そうである。8ライン間隔で割り込ませれば簡
単にスプライトダブラが作れそうじゃない?(GBAの場合、VCOUNT割り
込みを一々設定しなおさなければならないので少なからずロスがある)

問題は、スプライトダブラ分のスプライト領域を確保できるほどメモリ
があるわけではないということか。

2006/05/14

_ 割り込みを作る WonderSwan編〜再開〜
分からないまま放っておくのは精神衛生に悪いので、再挑戦した。が、
うっかり風邪をひいてしまい、体力と気力が尽きかけているので簡潔に
書く。

 callback.asm

つまるところVBLANK割り込みでスプライト更新関数を呼ぶことには成功
した。

しかしタイミングか何かの問題で(原因わっからん)数百回呼ぶとハン
グアップするのだ。HBLANK割り込みをさせようものなら、あっというま
にハングしてしまうー。

なので、今日はここまで。

2006/05/13

_ 割り込み諦め

ws_test3.zip (ソース込み)

作れそうな気がしたんだけどうまくいかない。つーかCSとかDSとか無理。
分からんものは分からんのだ。しばらく寝かせることにしてGBAに帰るよ。

ソースの231行目
/* if (!irq) {
    IRQ_SetHandler(IRQ_VBLANK_BEGIN, Vblank_Handler);
    irq = 1;
}*/
のコメントを外せば一応実験出来ます。
_ 割り込みを作る WonderSwan編
まずは手元にある資料でなんとかしようと思い、80386/486プログラミン
グガイドを読み直し、割り込みベクタはIDT(InterruptDescriptorTable)
を設定すれば良いことが分かった。そのためにSIDT命令が用意されてい
るが、この命令は8086には無いようだ。つーか、当たり前だがこの本で
8086の勉強をしようとしちゃ駄目だよ。(;´Д`)

仕方ないのでCygneのソースを読んだ。

void nec_int(DWORD wektor)
{
  DWORD dest_seg, dest_off;

  if(I.IF)
  {
    i_pushf();
    I.TF = I.IF = 0;
    dest_off = ReadWord(wektor);
    dest_seg = ReadWord(wektor+2);
    PUSH(I.sregs[CS]);
    PUSH(I.ip);
    I.ip = (WORD)dest_off;
    I.sregs[CS] = (WORD)dest_seg;
  }
}

(nec.cpp)
となっており、呼び出し側 (main.cpp) は nec_int((wsIO[0xb0]+n)*4); で呼んでいた。nに入る値は  0: シリアル送信  1: キー押下  2: RTCアラーム  3: シリアル受信  4: 描画ライン検出  5: 垂直同期タイマ  6: 垂直同期  7: 水平同期タイマ (あれ?0除算フォールトとかは潰されてる?) wstech24.txtによると、I/Oポートの$B0はInterrupt Baseとなっている ので、ここが0x00なら0000:0000から割り込みベクタが開始するようだ。

> 80386/486プログラミングガイド を読み直したら、第七章「リアルモード」の節に、ちゃんと割り込みベクタのことが書いてあったよ。つまりこの本で8086の勉強をしても良い。  (2006/05/23 08:07:16)

2006/05/12

_ 俺が勝手に買ってるだけだけど

ws_test2.zip

rep movswなんてものがあるじゃないの。というわけで高速化し、処理落
ちしなくなった。DMAが使えるといいんだけど、まだ使い方がよく分から
ないので保留。

Aボタン 表示数変更
Bボタン 回転
Yボタン グラフィックの変更

手探りでアレコレ試すのは楽しいな。楽しいんだけど、真剣に作ろうと
するなら、タイルの管理やメモリの節約で地獄を見ることになるんだろ
うな。

WonderMagicはゲームバンクでまだ買えるらしい?
http://gamebank-web.com/ec/store.asp?code_syosai=432180
しかし販売終了品のページにも載っているし、本当に買えるのか謎だ。
http://gamebank-web.com/ec/store.asp?kind=zzz&gazou=syousai
_ 売られた喧嘩は買わなきゃならねえ

ws_test.zip

情報があんまり無くて、ここまでたどり着くのに結構苦労した……それは
さておき。スワンのスプライトは8x8が128個だったのか。

CPUパワーが潤沢なら144ライン÷8ドット×32個(1ラインの最大表示数
が32個なので)で、最大576個まで表示できる計算になるが、ごらんの通
り256個の点滅表示でも既に処理落ちしてるのでスプライトダブラを作る
のはかなり難しそうだ。

というか、割り込みの作り方が分からないよ。割り込みベクタはどこに
あるのかしら。

2006/05/07

_ なんか
同じ場所をグルグルとループしている気がしてきた。まあいいけどさあ。
_ 巨大スプライトとスプライトダブラを併用したい
GWの間ずっと考えてた。面倒くさいので結論だけ書くと、巨大スプライト
をその場で複合スプライトにコンバートしてスプライトダブラで表示する
しかない(というか、その場でやると明らかに効率が悪いのであらかじめ
分割しておく)。でないと、どうしても優先度が破綻してしまう。

現状16x16サイズのスプライトを704個まで出すことが出来るけど、むしろ
352個までしか出せない代わりに32x32サイズのスプライトを使えるように
すると、案外バランスがよかったりするのかも。複合スプライトは作り直
しになるけど……。

tekezo > 素朴な疑問ですが、巨大スプライトはダブラを使わないという選択肢ではダメだったんですか?  (2006/05/07 22:47:47)
>
これが出来ないので…。
┌─┐
│小│━━━━┓
└─┘    ┃
 ┃  大  ┃
 ┃     ┃─┐
 ┗━━━━━┛小│
       └─┘
 (2006/05/08 17:06:13)
tekezo >
わたしのOBJ_PRIORITYに関する無知をさらしてしまいました……。
OBJ_PRIORITYでOBJATTRをソートしないといけないので、
いろいろややこしいんですね。目から鱗です。

ソート条件を考慮すると確かに複合スプライトに分割するのが自然な感じですね。

ダブラの管理下に置く OAM のエリアを
OAM[0] 〜 OAM[30] と OAM[40] 〜 OAM[100] までみたいな
形で穴抜け状態に出来るようにした上で、
穴抜けの範囲を動的に変更できるようにしても
いいかもしれないですが、なにか落し穴がありそうですし。
 (2006/05/08 22:45:59)
>
OBJATTRにある優先度とは別件なので(スプライト番号による優先度確保がしたい)
区別するためにOBJ登録順優先度(?)と書いたほうが良かったかもしれません。
どちらにも取れる書き方をしたのは失敗でした。すいません。

特定スプライト番号のマスクも考えたのですけど、DMAと相性が悪いし
CPU転送するにしてもいちいちマスクしてある番号を比較していたら
転送途中でHBLANK期間が終わってしまう……。
 (2006/05/08 23:15:57)

2006/05/06

_ おトイレは最後にやるべし
結構動くようになって、画面だけじゃ寂しいので音を入れてみたら負荷が
上がって 60fpsを維持できず悲鳴を上げたり、あとハードコーディングで
効果音命令を埋め込んでるので後から大変そうだなあとか。
_ Flash ROMってヘタるのかしら
FlashManagerで大きなイメージを焼くと途中で書き込みが止まってしまう
ことが割と頻繁に起こるようになった。ノリノリで作ってるところにこう
いうことがあると物凄く萎える。

そろそろ新しいFlashカートを調達しないといかんのかなあ。

2006/05/04

_ アンデフFMアレンジ祭りやろーぜ!
アンダーディフィートのFM音源アレンジにはしてやられた。

しかし個人的には「このパートはこの音色の方がいいはず」と思うところ
が少なからずあったし、大きなお友達のみんなもそう思っただろうことは
想像に難くない。

そういうわけで、みんなでFM音源にアレンジしよーぜ。
ほぼオッケーであろう耳コピ素材を置いとくので
VOPMなりFM7なり、携帯のMA-n系音源なりで鳴らして遊ぼうぜ。

 UnderDefeat - Can't come back (SMF)

んで、これが携帯の音源で素直に鳴らしてみた例。

 UnderDefeat - Can't come back (mp3)

パートを使いすぎているのでFM8パート+PCM2パートくらいに落とし込み
たいところではある。

(10:30追記) mp3を2loopにしたものと差し替えた。

最新
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