Tutorial.20 回転(2) †回転 †スプライトの回転のパラメータは前回と同様に設定します。PA〜PDを操作する為、以下の関数を用意します。 void SpriteRotate(u32 num, s32 angle) { OBJAFFINE* rot = (OBJAFFINE*)OAM + num; rot->pa = GetCos(angle); rot->pb = GetSin(angle); rot->pc = -GetSin(angle); rot->pd = GetCos(angle); } 1つのスプライトを回転してみる例 †#include "lib/gba.h" #include "sintbl.h" #include "res.h" //--------------------------------------------------------------------------- void WaitForVsync(void) { while (*(volatile u16*)0x4000006 >= 160) {}; while (*(volatile u16*)0x4000006 < 160) {}; } //--------------------------------------------------------------------------- void SpriteRotate(u32 num, s32 angle) { OBJAFFINE* rot = (OBJAFFINE*)OAM + num; rot->pa = GetCos(angle); rot->pb = GetSin(angle); rot->pc = -GetSin(angle); rot->pd = GetCos(angle); } //--------------------------------------------------------------------------- /* SpriteSetRotateFlag スプライトの拡大縮小回転機能に関する設定 no ・・・ 使用するスプライトRotateパラメータの番号 double_flag ・・・ 描画領域を2倍使用できるようにするか 0なら通常の描画領域、SP_SIZE_DOUBLEなら2倍 */ void SpriteSetRotateFlag(u32 num, u32 no, u32 double_flag) { OBJATTR* sp = (OBJATTR*)OAM + num; sp->attr0 |= OBJ_ROT_SCALE_ON; sp->attr1 &= 0xC1ff; sp->attr1 |= OBJ_ROT_SCALE(no); sp->attr0 &= 0xfdff; sp->attr0 |= double_flag; } //--------------------------------------------------------------------------- void SpriteScale(u32 num, u32 xsc, u32 ysc) { OBJAFFINE* rot = (OBJAFFINE*)OAM + num; rot->pa = 256 * 100 / xsc; rot->pb = 0; rot->pc = 0; rot->pd = 256 * 100 / ysc; } //--------------------------------------------------------------------------- void SpriteSetPalNo(u32 num, u32 palNo) { OBJATTR* sp = (OBJATTR*)OAM + num; sp->attr2 &= 0x0fff; sp->attr2 |= (palNo << 12); } //--------------------------------------------------------------------------- void SpriteMove(u32 num, s32 x, s32 y) { OBJATTR* sp = (OBJATTR*)OAM + num; if(x<0) x += 512; if(y<0) y += 256; sp->attr1 &= 0xfe00; sp->attr0 &= 0xff00; sp->attr1 |= (x & 0x01ff); sp->attr0 |= (y & 0x00ff); } //--------------------------------------------------------------------------- void SpriteSetSize(u32 num, u32 size, u32 form, u32 col) { OBJATTR* sp = (OBJATTR*)OAM + num; sp->attr0 &= 0x1fff; sp->attr1 &= 0x3fff; sp->attr0 |= col | form | (160); sp->attr1 |= size | (240); } //--------------------------------------------------------------------------- void SpriteSetChr(u32 num, u32 ch) { OBJATTR* sp = (OBJATTR*)OAM + num; sp->attr2 &= 0xfc00; sp->attr2 |= ch; } //--------------------------------------------------------------------------- void SpriteInit(void) { u32 i; for(i=0; i<128; i++) { SpriteMove(i, 240, 160); } } //--------------------------------------------------------------------------- int main(void) { // モード設定 SetMode(MODE_0 | OBJ_ENABLE | OBJ_1D_MAP); u16* oam = OBJ_BASE_ADR; // スプライトデータ u16* pal = OBJ_COLORS; // スプライトパレット u32 i; // データの格納 for(i=0; i<sprTilesLen/2; i++) { oam[i] = sprTiles[i]; } // パレットの格納 for(i=0; i<16; i++) { pal[i] = sprPal[i]; } SpriteInit(); SpriteSetSize (0, OBJ_SIZE(1), OBJ_SQUARE, OBJ_16_COLOR); SpriteSetChr (0, 0); SpriteMove (0, 20, 20); SpriteSetPalNo(0, 0); SpriteSetRotateFlag(0, 0, OBJ_DOUBLE); s32 angle = 0; for(;;) { WaitForVsync(); if(++angle >= 360) { angle = 0; } SpriteRotate(0, angle); } } 動作画面 †![]() 履歴 †
|