戻る

画面表示

256色モードでDMAを使用して10x10のキャラクタを画面に表示するサンプルプログラムです。
96*64バイトの画面の大きさと同じscreen_bufferを2つ作成して交互にDMA転送している。
TinyScreen::writeBufferDMAは画面を転送する前に戻って来るのでtiny_screen.getReadyStatusDMA()で
DMA転送が終わったかどうか毎回チェックしている。
TinyScreen::writeBufferでは画面描画には256色で約4550マイクロ秒,65536色で約9100マイクロ秒かかるが
TinyScreen::writeBufferDMAは画面を描いている間にCPUが処理できる。
このサンプルでは60FPSで描画している。

サンプルプログラム

#include <TinyScreen.h>

#define COLOR8(r,g,b) ((b>>5)<<5|(g>>5)<<2|(r>>6))

static const unsigned int SCREEN_WIDTH = 96;
static const unsigned int SCREEN_HEIGHT = 64;
static const unsigned int BUFFER_SIZE = (SCREEN_WIDTH * SCREEN_HEIGHT);
static const unsigned int BUFFER_COUNT = 2;
static const unsigned long FPS =  30;
static const unsigned long INTERVAL_TIME = 1000000 / FPS;

TinyScreen tiny_screen = TinyScreen(TinyScreenPlus);
unsigned char screen_buffer[BUFFER_COUNT][BUFFER_SIZE];
unsigned long micros_time;
int current_buffer;
int x;
int anime_count;

// Character image
const unsigned char Hiyoko_1[10 * 10] =
{
	0x00, 0x00, 0x00, 0x1B, 0x1B, 0x1B, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00, 0x00,
	0x00, 0x1B, 0x40, 0x40, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
	0x00, 0x1B, 0xFF, 0x40, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00,
	0x00, 0x1B, 0x40, 0x40, 0x1B, 0x5B, 0x5B, 0x5B, 0x5B, 0x5B,
	0x0F, 0x0F, 0x0F, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x5B,
	0x00, 0x00, 0x00, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x5B, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x1B, 0x1B, 0x1B, 0x5B, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x00
};

const unsigned char Hiyoko_2[10 * 10] =
{
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x1B, 0x1B, 0x1B, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x00, 0x00, 0x00,
	0x00, 0x1B, 0x40, 0x40, 0x1B, 0x1B, 0x1B, 0x5B, 0x5B, 0x5B,
	0x00, 0x1B, 0xFF, 0x40, 0x1B, 0x1B, 0x5B, 0x1B, 0x1B, 0x5B,
	0x00, 0x1B, 0x40, 0x40, 0x1B, 0x5B, 0x1B, 0x1B, 0x1B, 0x5B,
	0x0F, 0x0F, 0x0F, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x5B, 0x00,
	0x00, 0x00, 0x00, 0x1B, 0x1B, 0x1B, 0x1B, 0x5B, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x0F, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x00
};

void setup()
{
	tiny_screen.begin();
	tiny_screen.setBitDepth(TSBitDepth8);
	tiny_screen.setBrightness(7);
	tiny_screen.setFont(liberationSansNarrow_12ptFontInfo);
	tiny_screen.fontColor(TS_8b_White, TS_8b_Black);
	tiny_screen.initDMA();
	current_buffer = 0;
	x = 86;
	anime_count = 0;
}

// Draw sprite no clip
void DrawSprite(const unsigned char* buffer, int x, int y, int width, int height, int color_key)
{
	int scan_x;
	int scan_y;
	int source_address = 0;
	int destination_address = SCREEN_WIDTH * y + x;
	for(scan_y = 0; scan_y < height; ++ scan_y)
	{
		for(scan_x = 0; scan_x < width; ++ scan_x)
		{
			unsigned char color = buffer[source_address + scan_x];
			if(static_cast<int>(color) != color_key)
			{
				screen_buffer[current_buffer][destination_address + scan_x] = color;
			}
		}
		source_address += width;
		destination_address += SCREEN_WIDTH;
	}
}

void loop()
{
	unsigned long interval_time = micros() - micros_time;
	if(interval_time > INTERVAL_TIME)
	{
		// Clear buffer
		memset(screen_buffer[current_buffer], COLOR8(30, 30, 100), BUFFER_SIZE);
		// Move & draw sprite
		-- x;
		if(x < 0)
		{
			x = 86;
		}
		++ anime_count;
		if(anime_count >= 16)
		{
			anime_count = 0;
		}
		if(anime_count < 8)
		{
			DrawSprite(Hiyoko_1, x, 27, 10, 10, 0);
		}
		else
		{
			DrawSprite(Hiyoko_2, x, 27, 10, 10, 0);
		}
		// Wait DMA transfer
		while(!tiny_screen.getReadyStatusDMA());
		// End DMA transfer
		tiny_screen.endTransfer();
		// Start DMA transfer
		current_buffer = 1 - current_buffer;
		tiny_screen.goTo(0, 0);
		tiny_screen.setX(0, SCREEN_WIDTH - 1);
		tiny_screen.setY(0, SCREEN_HEIGHT - 1);
		tiny_screen.startData();
		tiny_screen.writeBufferDMA(screen_buffer[current_buffer], BUFFER_SIZE);
		micros_time = micros();
	}
}

実行結果

#ref(): File not found: "ScreenSample1.jpg" at page "TinyArcade/DMA転送を使って60FPSで画面表示"

サンプルプログラムのダウンロード

fileScreenSample4.zip

トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS