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);
	}
}

動作画面

clip_1.png

履歴

  • 2015/10/07
  • 2007/09/08

添付ファイル: fileclip_1.png 203件 [詳細]

Last-modified: 2015-10-07 (水) 23:27:21 (2556d)