Tutorial.19 回転(1) †回転 †今回は回転機能を扱います。前回のは書きませんでしたが、 画像を回転させるには、4つのパラメータを以下のように設定します。
このように値をセットすればそれだけで元の画像を回転させた画像が表示されますが、 s16の配列でSinTab[]、CosTab[]という配列のデータを使います。 また整数の角度から配列のデータを取得するGetSin()、GetCos()関数を作っておきます。 REG_BG2PA = GetCos(angle); REG_BG2PB = GetSin(angle); REG_BG2PC = -GetSin(angle); REG_BG2PD = GetCos(angle); これに加えて、BGの回転では、回転の中心を画面の中心になるようにしてみます。 REG_BGxX、REG_BGxY †#define REG_BG2X *((vu32 *)(REG_BASE + 0x28)) #define REG_BG2Y *((vu32 *)(REG_BASE + 0x2c)) #define REG_BG3X *((vu32 *)(REG_BASE + 0x38)) #define REG_BG3Y *((vu32 *)(REG_BASE + 0x3c)) REG_BG2XとREG_BG2Yは、格納した値がそのまま画面上のBGの移動になるのでなく、 bgx = x1 - α* cos(θ-β)*hzoom bgy = y1 - α*-sin(θ-β)*vzoom
こちらも浮動小数点で求めると処理が重くなるので、あらかじめ分かる値は入れておき、sin、cos配列も使います。 s32 bg2x = 120 * 256 - 144 * GetCos(angle-33); s32 bg2y = 80 * 256 - 144 * -GetSin(angle-33); また、REG_BG2X、REG_BG2Yに格納するときに、 //REG_BGX,Yの28bitフォーマットに調整 if(bg2x < 0) { REG_BG2X = 0xFFFFFFF - abs(bg2x); } else { REG_BG2X = abs(bg2x); } if(bg2y < 0) { REG_BG2Y = 0xFFFFFFF - abs(bg2y); } else { REG_BG2Y = abs(bg2y); } 画面全体を回転してみる例 †#include <stdlib.h> #include "lib/gba.h" #include "sintbl.h" #include "res.h" //--------------------------------------------------------------------------- void WaitForVsync(void) { while (*(volatile u16*)0x4000006 >= 160) {}; while (*(volatile u16*)0x4000006 < 160) {}; } //--------------------------------------------------------------------------- //BG2の縦・横の拡大率を%で指定 void RotateBG2(s32 angle) { REG_BG2PA = GetCos(angle); REG_BG2PB = GetSin(angle); REG_BG2PC = -GetSin(angle); REG_BG2PD = GetCos(angle); // bgx = x1 - α * cos(θ-β) * hzoom // bgy = y1 - α * -sin(θ-β) * vzoom s32 bg2x = 120 * 256 - 144 * GetCos(angle-33); s32 bg2y = 80 * 256 - 144 * -GetSin(angle-33); if(bg2x < 0) { REG_BG2X = 0xFFFFFFF - abs(bg2x); } else { REG_BG2X = abs(bg2x); } if(bg2y < 0) { REG_BG2Y = 0xFFFFFFF - abs(bg2y); } else { REG_BG2Y = abs(bg2y); } } //--------------------------------------------------------------------------- int main(void) { // モード設定 SetMode(MODE_3 | BG2_ENABLE); // 画像の読み込み REG_DMA3SAD = (u32)&imageBitmap; REG_DMA3DAD = (u32)VRAM; REG_DMA3CNT = (u32)(240*160) | (DMA_SRC_INC | DMA_DST_INC | DMA16 | DMA_ENABLE); s32 angle = 0; for(;;) { WaitForVsync(); if(++angle >= 360) { angle = 0; } RotateBG2(angle); } } 動作画面 †![]() 履歴 †
|