The Gameduino has a small onboard flash memory. In addition to the FPGA boot image, this memory holds a small asset libary that holds some media useful for games and other applications.
GD provides a class Asset that lets you use the assets in your game.
Assets are just big chunks of binary data. To read an asset, first declare an Asset object and use the open method to open one of the game assets (listed below) for reading:
Asset a; a.open("voice", "nice", NULL);
the arguments to open are the asset location, folder first then filename, and a NULL terminator. So in this example the asset loader first looks for the "voice" folder, then the "nice" object.
You can find how many bytes are in the asset using the available method, and read bytes using the read method. So to dump the complete asset in hex:
byte b; while (a.available()) { a.read(&b, 1); Serial.println(b, HEX); }
You can also load the asset directly into Gameduino memory with the load method. For example:
a.load(RAM_SPRIMG);
loads the asset's data into Gameduino memory starting at RAM_SPRIMG.
All Gameduinos ship with the following assets:
pickups pal img voice ar duino game go nice ohdear over ready fonts font8x8 font16 drumkit bassdrum2 bassdrum4 clap conga2 conga3 cowbell1 cymbal1 cymbal3 hihat1 hihat2 snaredrum2 snaredrum3
The directory pickups contains a set of game-related sprite images. The 256-color sprite palette (pal) and images (img) should be loaded into RAM_SPRPAL and RAM_SPRIMG respectively. These are the same sprites used in the sprites256 sample. Thanks to SpriteLib.
The directory drumkit contains various 8-bit samples of a drum kit. Thanks to http://www.drumsamples.org/ and Colin Dooley.
The directory voice contains various 8-bit voice samples, spoken by some guy.
The directory fonts contains two fonts. font8x8 is for use in character maps, and font16 is a 16x16 4-color font for loading into sprites.
The code sample plays back some of the voice samples, first saying "Gameduino ready", then yells "Game Over" repeatedly, interspersed with random hits on the drums. It also loads the pickup sprite set and randomly scatters sprites across the screen.
The sample playback uses a simple delay loop, as in the first example here.
#include <SPI.h>
#include <GD.h>
static void playsample(Asset &a)
{
while (a.available()) {
byte b;
a.read(&b, 1);
GD.wr(SAMPLE_L + 1, b);
GD.wr(SAMPLE_R + 1, b);
delayMicroseconds(80);
}
}
static void say(const char *word)
{
Asset a;
a.open("voice", word, NULL);
playsample(a);
}
void setup()
{
GD.begin();
// Say "Gameduino ready"
say("game");
say("duino");
delay(100);
say("ready");
// Load the pickups starting at sprite 0.
// First copy pickups/pal into RAM_SPRPAL, then
// pickups/img into RAM_SPRIMG.
Asset a;
a.open("pickups", "pal", NULL);
a.load(RAM_SPRPAL);
a.open("pickups", "img", NULL);
a.load(RAM_SPRIMG);
}
void loop()
{
// Scatter sprites across the screen
for (int i = 0; i < 256; i++)
GD.sprite(i, random(400), random(300), random(47), 0, 0);
// Play a random instrument from the 12 in the drumkit
static const char *drums[12] = {
"bassdrum2",
"bassdrum4",
"clap",
"conga2",
"conga3",
"cowbell1",
"cymbal1",
"cymbal3",
"hihat1",
"hihat2",
"snaredrum2",
"snaredrum3"
};
Asset drum;
drum.open("drumkit", drums[random(12)], NULL);
playsample(drum);
// Say "game over"
say("game");
say("over");
}
The fonts/font16 asset is a 16x16 ASCII font with four-color sprites. The 96 ASCII characters are each one four-color sprite, so the total sprite memory required is 6144 bytes out of the Gameduino's total 16K.
This sample shows how to draw text in sprites using the font.
It loads the asset, loads four-color palette A with a white-gray color scheme, then draws the text using sprites.
The math in text() takes each character of the string and figures out the sprite image and palette. (See the reference poster and sample palettes for details on four-color sprites.)
#include <SPI.h>
#include <GD.h>
#define GRAY(c) RGB(c,c,c)
void setup()
{
GD.begin();
// Load the font16 into sprite RAM_SPRIMG
Asset a;
a.open("fonts", "font16", NULL);
a.load(RAM_SPRIMG);
GD.wr16(PALETTE4A , GRAY(255));
GD.wr16(PALETTE4A + 2, GRAY(128));
GD.wr16(PALETTE4A + 4, GRAY( 64));
GD.wr16(PALETTE4A + 6, TRANSPARENT);
GD.wr16(RAM_PAL, RGB(0, 64, 32)); // teal background
}
// Write string s at pixel (x,y) using sprites starting at sprnum
static void text(int sprnum, int x, int y, char *s)
{
while (*s) {
byte c = *s - ' '; // font characters start at ' '
byte image = c >> 2; // four characters per image
byte pal = 8 | ((c & 3) << 1); // 4-color palette select
GD.sprite(sprnum, x, y, image, pal, 0);
x += 11;
sprnum++;
s++;
}
}
void loop()
{
text(0, 10, 100, "This is font16");
text(20, 10, 120, "loaded from flash");
GD.waitvblank();
}
The fonts/font8x8 contains the same font that is loaded by the GD.ascii() function. The advantage of using the asset library version is that you save 768 bytes of Arduino flash - the size of the 96-character font. Here is a code fragment to load fonts/font8x8, for use as a replacement for GD.ascii:
static byte stretch[16] = { 0x00, 0x03, 0x0c, 0x0f, 0x30, 0x33, 0x3c, 0x3f, 0xc0, 0xc3, 0xcc, 0xcf, 0xf0, 0xf3, 0xfc, 0xff }; void asset_ascii() { asset a; a.open("fonts", "font8x8", NULL); for (int i = 0; i < 768; i++) { byte b; a.read(&b, 1); byte h = stretch[b >> 4]; byte l = stretch[b & 0xf]; GD.wr(0x1000 + (16 * ' ') + (2 * i), h); GD.wr(0x1000 + (16 * ' ') + (2 * i) + 1, l); } for (i = 0x20; i < 0x80; i++) { GD.setpal(4 * i + 0, TRANSPARENT); GD.setpal(4 * i + 3, RGB(255,255,255)); } GD.fill(RAM_PIC, ' ', 4096); }