LedControl performance for simple game design . . . new library?

I was excited about finishing a small project -- using an IR remote with mouse pad to control a LED on a 16 x 16 blue Led Matrix, see following video

http://player.youku.com/player.php/sid/XNTA2ODAwNDQ0/v.swf

I am thinking about making a simple game (not sure what yet, any ideas would be greatly appreciated) that uses this mouse pad as human input. However, after looking at LedControl CPP file, I am worried about the performance.

So I am contemplating an idea to write a buffer based LedMatrix lib that works like a video card -- when screen needs to be manipulated, it is done in memory, after all operations, the content of memory is dumped to device to make it faster, particularly scrolling, line drawing, circles, and rectangles.

Or there is a such thing already and I just don't know it.

I have just finished V0.07 of a fast buffer based led matrix library. Please check out this thread.

http://arduino.cc/forum/index.php/topic,147544.0.html

So far it is pretty fast with both sprite drawing and scrolling. Video will be posted soon.

Sprite drawing demostration.

Can it go past the edge of the matrix?

fungus:
Can it go past the edge of the matrix?

Yes, I programmed it to stop at the edge. Anything outside the specified boundary will be clipped so there is no waste of CPU.

Sorry, I did not post code here, but here it is:

//
//
// Written by Peter Y Lin, a.k.a MJKZZ
//
// Do whatever you want to do with this code but use this code at your own risk
//
#include <avr/io.h>
#include <avr/interrupt.h>
#include "LedMatrix.h"

#define TICK_IR_BREAK		5000
#define TICK_IR_ONE_MIN		400
#define TICK_IR_ONE_MAX		600

#define	MAX_IR_PULSE		24
#define MAX_IR_DATA			8
#define MAX_IR_REPEAT		1
#define	PIN_IR				2

#define IR_CODE_UP			0xC500
#define	IR_CODE_DOWN		0xC480
#define IR_CODE_LEFT		0xC560
#define IR_CODE_RIGHT		0xC460
#define IR_CODE_UPLEFT		0xC562
#define IR_CODE_UPRIGHT		0xC462
#define IR_CODE_DOWNLEFT	0xC566
#define	IR_CODE_DOWNRIGHT	0xC466
#define IR_CODE_UPARROW		0xC590
#define IR_CODE_DOWNARROW	0xC4D0
#define IR_CODE_LEFTARROW	0xC430
#define IR_CODE_RIGHTARROW	0xC420

volatile unsigned int		g_tkPulse	= 0;
volatile unsigned int		g_ctPulse	= 0;
volatile unsigned int		g_arPulse[MAX_IR_PULSE];
volatile unsigned int		g_irCode	= 0;
volatile unsigned int		g_irTemp	= 0;
volatile unsigned int		g_ctCode	= 0;

LedMatrix					ledDisplay	= LedMatrix(5, 6, 7, 16, 16);

//
// This is a bitmap for a sprite
// The first two bytes specify width and height of
// sprite and the rest are bitmaps for sprite
//
byte g_sprite[6] = 
{
	0x03,		// width
	0x04,		// height
	0b10110000, 
	0b01001000, 
	0b01000100,
	0b10100010,
};

volatile unsigned char		g_x		= 0;
volatile unsigned char		g_y		= 0;

void isr_ir()
{
	g_tkPulse	= TCNT1;
	TCNT1		= 0;

	if (g_tkPulse > TICK_IR_BREAK)
	{		
		g_ctPulse = 0;
	}
	else if (g_ctPulse < MAX_IR_PULSE)
	{
		g_arPulse[g_ctPulse] = g_tkPulse;
		g_ctPulse++;

		if (g_ctPulse == 16)
		{
			g_irTemp = 0;
			for(int i=0; i<g_ctPulse; i++)
			{
				if (g_arPulse[i] > TICK_IR_ONE_MIN && g_arPulse[i] < TICK_IR_ONE_MAX)
				{
					g_irTemp |= 1;
				}
				g_irTemp = g_irTemp << 1;
			}

			if (g_irTemp == g_irCode)
			{
				if (g_ctCode < MAX_IR_REPEAT)
				{
					g_ctCode++;
				}
			}
			else
			{
				g_ctCode = 1;
			}
			g_irCode = g_irTemp;
		}
	}
}

void setup()
{
	Serial.begin(115200);

	TCCR1A = 0b00000000;
	TCCR1B = 0b00000011;    // Clk*64 = 4uS
	TCCR1C = 0b00000000;

	pinMode(PIN_IR, INPUT);
	attachInterrupt(0, isr_ir, FALLING);

	ledDisplay.init(8);
	ledDisplay.blank();
	ledDisplay.sprite(g_x, g_y, (const char *)g_sprite, 6, GRAPHIC_DRAW_SRC);

	ledDisplay.update();
}

void loop()
{
	if (g_ctCode == MAX_IR_REPEAT)
	{
		//Serial.print("Code = ");
		//Serial.println(g_irCode, HEX);
		ledDisplay.sprite(g_x, g_y, (const char *)g_sprite, 6, GRAPHIC_DRAW_XOR);

		switch(g_irCode)
		{
		case IR_CODE_LEFT:
		case IR_CODE_LEFTARROW:
			if (g_x)
			{
				g_x--;
			}
			break;
		case IR_CODE_RIGHT:
		case IR_CODE_RIGHTARROW:
			if (g_x < ledDisplay.getWidth()-3)
			{
				g_x++;
			}
			break;
		case IR_CODE_UP:
		case IR_CODE_UPARROW:
			if (g_y)
			{
				g_y--;
			}
			break;
		case IR_CODE_DOWN:
		case IR_CODE_DOWNARROW:
			if (g_y < ledDisplay.getHeight()-4)
			{
				g_y++;
			}
			break;
		case IR_CODE_UPLEFT:
			if (g_y)
			{
				g_y--;
			}
			if (g_x)
			{
				g_x--;
			}
			break;
		case IR_CODE_UPRIGHT:
			if (g_y)
			{
				g_y--;
			}
			if (g_x < ledDisplay.getWidth()-3)
			{
				g_x++;
			}
			break;
		case IR_CODE_DOWNLEFT:
			if (g_y < ledDisplay.getHeight()-4)
			{
				g_y++;
			}
			if (g_x)
			{
				g_x--;
			}
			break;
		case IR_CODE_DOWNRIGHT:
			if (g_y < ledDisplay.getHeight()-4)
			{
				g_y++;
			}
			if (g_x < ledDisplay.getWidth()-3)
			{
				g_x++;
			}
			break;
		}

		Serial.println(g_x, DEC);

		ledDisplay.sprite(g_x, g_y, (const char *)g_sprite, 6, GRAPHIC_DRAW_SRC);
		ledDisplay.update();
		g_irCode = 0;
		g_ctCode = 0;
	}
}

As you can see in code, the -3 and -4 at width and height part is stopping the sprite, but it can go over the edge, of course, out of edge part of sprite will be clipped.

LedMatrix library is available on github . . .

https://github.com/mjkzz/LedMatrix