30fps割り込みを試してみる
dswifiがうまく行かないので放置状態です。DSが2台必要なのもテストに面倒なところですね。子供から1台借りないといけない・・・。
そこで、そっちは置いといて、前々からやりたかった30fps割り込みを試してみました。
VBlank割り込み
ndsの割り込みとしては、メジャなものにVBlank割り込みがあります。これはゲームなどで1画面を作るときに発生する割り込みですね。このタイミングで画面に書くと絵がちらつかないと言うものです。
タイミング待ちに、swiWaitForVBlank(); なんてよくやりますよね。また、VBlank割り込みで何か処理をさせたいときには、下記のような感じで書きますよね。
//********************************************** // Vblank割り込み処理 //********************************************** void Vblank( void ) { //VBlankの処理 } //********************************************** // メイン関数 //********************************************** int main(void) { //割り込み関係の初期化 irqSet(IRQ_VBLANK, Vblank ); irqEnable( IRQ_VBLANK ); 以下略
イメージこんな感じですね。
タイマー割り込み
ndsには、この割り込みのほかに3つのタイマー割り込みがあります。この一つを使って割り込み処理を書いてみました。今回はTIMER0を使いました。dswifi何かだと中でTIMER3割り込みを使っているようなので、タイマー割り込みを使うときには他のプログラムとぶつかっていないか注意が必要です。
1秒間に30回割り込みを発生させるということで、下記のように書きました。
TIMER0_DATA = TIMER_FREQ_256( 30 ); // 1 秒間に 30 回、割り込みを発生させる TIMER0_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_DIV_256; irqSet(IRQ_TIMER0, Timer0Handler);
そして、動作させるときに、
irqEnable(IRQ_TIMER0);
停止させるときに、
irqDisable(IRQ_TIMER0);
設定を解除するときには、
irqClear( IRQ_TIMER0 );
と書きます。
これで、何をしたかというと、動画を動かしてみました。
動画を動かす
基本的に、30fpsの元動画からDS用の256×192画面サイズの画像データを作り、それを枚数分並べたバイナリファイルを用意して、割り込みのタイミングで読み込むだけのプログラムです。
FILE* Fp = NULL; volatile long Timer __attribute__ ((section (".dtcm"))); //***************************************** // TIMER0の割り込み //***************************************** void Timer0Handler() { Timer++; } //************************************************** // 動画表示 //************************************************** void execpro( void ) { playSoundData( 0 ); Timer = 0; irqEnable(IRQ_TIMER0); while( true ){ if( Timer>2690 ){ break; } fseek( Fp, Timer*0x18000, SEEK_SET ); fread( (uint16 *)MainScreenA, 0xc000, sizeof(uint16), Fp ); } irqDisable(IRQ_TIMER0); }
2690枚の絵を表示する感じです。処理落ちを考えてfseekを入れています。while()の中は、もう少しいろいろと作ってみましたが、基本はこんな感じです。
割り込みいろいろ
もっと違う速度の割り込みを使いたいときは、設定を変えればいいだけです。
10Hz割り込みをしたい場合、
TIMER0_DATA = TIMER_FREQ_256( 10 ); TIMER0_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_DIV_256;
100Hz割り込みをしたい場合、
TIMER0_DATA = TIMER_FREQ_64( 100 ); TIMER0_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_DIV_64;
1kHz割り込みをしたい場合、
TIMER0_DATA = TIMER_FREQ_64( 1000 ); TIMER0_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_DIV_64;
こんな感じです。
詳しくは、timers.h 辺りを見てください。
本当にやりたいことリスト
(ブログの終わりにやりたいことを書いておきたいと思います)
- 求職活動・・・このブログで興味を持った人一声かけてください。m(_ _)m
- Androidプログラム
- Web系のプログラム