Stage and display list style graphics library

Projectitis

Well-known member
Hi all,

Just thought I'd update you on recent progress on μac/mac (microcontroller app creator). It started off as a low level sprite blitting and vector shape drawing library using a framebuffer. This meant that you needed enough ram for a framebuffer (320x240 pixels @16bpp color with double buffering = 300kb for example), but you got very fast rendering, double buffering, transparent/alpha support etc.

I decided to refactor everything to support hardware with way lower specs, and have now ended up with a stage and display list library in a similar style to Adobe Flash. I've switched out the framebuffer for a linebuffer, (still double-buffered) which renders the screen one line at a time instead of a frame at a time. This uses much less ram (1.2kb for the same example as above) but still has the same benefits of very fast rendering, double buffering, transparent/alpha support etc. It also only updates the part of the display that has changed.

I haven't got DMA working from the buffer to the display yet, but that would really take this to the next level.

Next on the list (as well as DMA) are animated sprites and vector graphics. I also want to tackle sprite rotation (that isn't the simple cases of 90/180/270 and flip that I already support).

Here is the example code used for the screenshots below:
  • Display scaled to 2x2 pixels (1, 2, 4 and 8 scaling supported. Scaling requires less memory but you lose resolution)
  • Large background sprite
  • Several smaller sprites (some rotated and flipped)
  • A text area with dynamic height (anti-aliased fonts also supported)
  • A transparent box sized to the text area
  • A sprite that moves on button press
  • Redraw areas shown on screen (only modified areas redrawn)
  • Note: setting "id" on display objects is optional. I did this for debugging only.

Code:
#include <mac.h>
#include <grocer.h>
#include <characters.h>
#include "<PixelSix008.h>"

using namespace mac;

App *app;
Sprite *sprite;
Text *text;
Box* box;

CallbackListener* listener;

boolean buttonClicked( uint32_t event, void* data ) {
	sprite->x( sprite->x()+10 );
	sprite->y( sprite->y()+10 );
	return true;
}

void setup() {
	app = new App(
		new DisplayILI9341( 10, 15, 4, 11, 13, 12, 6, pixelScale_2x2 )
	);
	app->serialBegin( true );
	app->stage->backgroundColor( 0x8f8767 );
	app->stage->debug = true;
	app->stage->id = 0;

	sprite = Sprite::Create( (Tilemap*)&grocer, 0 );
	sprite->id = 100;
	app->stage->addChild( sprite );

	sprite = Sprite::Create( (Tilemap*)&characters, 0 );
	sprite->x( 2 );
	sprite->y( 60 );
	sprite->id = 1;
	app->stage->addChild( sprite );

	sprite = Sprite::Create( (Tilemap*)&characters, 1 );
	sprite->x( 16 );
	sprite->y( 30 );
	sprite->transform = Transform::rotate180;
	sprite->id = 2;
	app->stage->addChild( sprite );

	sprite = Sprite::Create( (Tilemap*)&characters, 2 );
	sprite->x( 32 );
	sprite->y( 30 );
	sprite->transform = Transform::flipH;
	sprite->id = 3;
	app->stage->addChild( sprite );

	box = Box::Create();
	box->color = 0xff9900;
	box->alpha = 0.5;
	app->stage->addChild( box );
	box->id = 6;

	text = Text::Create( (packedbdf_t*)&PixelSix008 );
	text->text( (char*)F("All children, except one, grow up. They soon know that they will grow up, and the way Wendy knew was this.") );
	text->color( RGB888_White );
	text->width( 100 );
	text->x( 45 );
	text->y( 12 );
	text->id = 7;
	app->stage->addChild( text );

	box->x( text->x() - 5 );
	box->y( text->y() - 5 );
	box->width( text->width() + 10 );
	box->height( text->height() + 10 );

	listener = new CallbackListener( buttonClicked );
	app->input->map( 35, PinType::digital, ClickType::click, Event::action_play );
	app->messenger->addListener( Event::action_play, listener );
}

void loop(){
	app->update();
}

mac-1.jpg
mac-2.jpg
 
Back
Top