void main() { //SETUP VIDEO BUFFER static VideoBuffer vid; //create video buffer for each cube vid.initMode(BG0_SPR_BG1); //set video buffer to BG0_SPR_BG1 mode vid.attach(0); //attach video buffer to cube with ID 0 //BACKGROUND LAYER vid.bg0.image(vec(0,0), MyBG0Image); //Set the image `Background` defined in assets.lua to the VideoBuffer's BG0 layer //SPRITES LAYER vid.sprites[0].setImage(MyRedSprite); //assign our first sprite vid.sprites[0].move(15,15); //move it to where we want it vid.sprites[1].setImage(MyBlueSprite); vid.sprites[1].move(93, 60); //FOREGROUND LAYER vid.bg1.setMask(BG1Mask::filled(vec(4,4), vec(8,8))); //Mask an area in the location and size of our BG1 image vid.bg1.image(vec(4,4), MyBG1Image); //Place a BG1 image in the same space as the mask. while (1) { //game looop System::paint(); } }
void main() { unsigned fg = BG0ROMDrawable::SOLID_FG ^ BG0ROMDrawable::BLUE; unsigned bg = BG0ROMDrawable::SOLID_FG ^ BG0ROMDrawable::BLACK; vid.initMode(BG0_ROM); vid.attach(cube); vid.bg0rom.erase(bg); vid.bg0rom.fill(vec(0,0), vec(3,3), fg); synthInit(); float hz = 0; while (1) { // Scale to [-1, 1] auto accel = cube.accel() / 128.f; // Glide to the target note (half-steps above or below middle C) float note = 261.6f * pow(1.05946f, 8 + round(accel.y * 24.f)); hz += (note - hz) * 0.4f; synthesize(hz, accel.x - 0.2f, clamp(accel.x + 0.5f, 0.f, 1.f)); const Int2 center = LCD_center - vec(24,24)/2; vid.bg0rom.setPanning(-(center + accel.xy() * 60.f)); System::paint(); } }
void main() { CubeID cube(0); VideoBuffer vid; vid.initMode(BG0); vid.attach(cube); for (int x = -1; x < 17; x++) { drawColumn(vid, x); } /* * Scroll horizontally through our background based on the accelerometer's X axis. * * We can scroll with pixel accuracy within a column of tiles via bg0.setPanning(). * When we get to either edge of the currently plotted tiles, draw a new column * of tiles from the source image. * * Because BG0 is 1 tile wider and taller than the viewport itself, we can pre-load * the next column of tiles into the column at the edge before it comes into view. */ float x = 0; int prev_xt = 0; for (;;) { // Scroll based on accelerometer tilt Int2 accel = vid.physicalAccel().xy(); // Floating point pixels x += accel.x * (40.0f / 128.0f); // Integer pixels int xi = x + 0.5f; // Integer tiles int xt = x / 8; while (prev_xt < xt) { // Fill in new tiles, just past the right edge of the screen drawColumn(vid, prev_xt + 17); prev_xt++; } while (prev_xt > xt) { // Fill in new tiles, just past the left edge drawColumn(vid, prev_xt - 2); prev_xt--; } // pixel-level scrolling within the current column vid.bg0.setPanning(vec(xi, 0)); System::paint(); } }
void main() { vid.initMode(BG0_ROM); vid.attach(0); String <128> text; text << "Hello World" << "\n"; vid.bg0rom.text(vec(0,0),text); playSfx (CountSound); // AudioTracker::play(Count); while (1) System::paint(); }
void main() { const CubeID cube(0); static VideoBuffer vid; vid.attach(cube); /* * Blank the screen. This also blanks the one-pixel region between * the bottom of the fractal and the top of the elapsed time indicator * below. */ vid.initMode(SOLID_MODE); vid.colormap[0] = RGB565::fromRGB(0xFFFFFF); System::paint(); /* * We use STAMP mode in a special way here, to do (slow) true-color * rendering: The framebuffer is simply set up as an identity mapping * that shows each of the 16 colors in our colormap. Now we can put * a row of 16 pixels directly into the colormap, and render the screen * using 1024 of these little 16x1 pixel "frames". * * Clearly this is really slow, and this technique is unlikely to be * frequently useful, but it's a fun parlour trick :) */ SystemTime startTime = SystemTime::now(); vid.initMode(STAMP); vid.stamp.disableKey(); auto &fb = vid.stamp.initFB<16,1>(); for (unsigned i = 0; i < 16; i++) fb.plot(vec(i, 0U), i); for (unsigned y = 0; y < LCD_height - 9; y++) for (unsigned x = 0; x < LCD_width; x += 16) { /* * Render 16 pixels at a time, into a buffer in RAM. */ static RGB565 pixels[16]; for (unsigned i = 0; i < 16; i++) pixels[i] = calculateMandelbrot(vec(x+i, y)); /* * Now copy to VRAM and start painting. By waiting until * now to call finish(), we're allowing the calculation above * to run concurrently with the cube's paint operation. * * Note that our "frames" are actually just tiny pieces of the * screen, so we need to avoid the default frame rate limits * in order to render at an at all reasonable rate. This is * where paintUnlimited() comes into play. */ System::finish(); vid.stamp.setBox(vec(x,y), vec(16,1)); vid.colormap.set(pixels); System::paintUnlimited(); } /* * Use BG0_ROM mode to draw the elapsed time at the bottom of the screen. */ TimeDelta elapsed = SystemTime::now() - startTime; String<16> message; message << (elapsed.milliseconds() / 1000) << "." << Fixed(elapsed.milliseconds() % 1000, 3) << " sec"; LOG("Elapsed time: %s\n", message.c_str()); vid.initMode(BG0_ROM); vid.bg0rom.text(vec(1,0), message); vid.setWindow(LCD_height - 8, 8); // Kill time (efficiently) while (1) System::paint(); }
void main() { /* * Display text in BG0_ROM mode on Cube 0 */ CubeID cube = 0; vid.initMode(BG0_ROM); vid.attach(cube); vid.bg0rom.text(vec(0,0), " USB Demo ", vid.bg0rom.WHITE_ON_TEAL); // Zero out our counters usbCounters.reset(); /* * When we transmit packets in this example, we'll fill them with our * cube's accelerometer state. When we receive packets, they'll * be hex-dumped to the screen. We also keep counters that show how many * packets have been processed. * * If possible, applications are encouraged to use event handlers so that * they only try to read packets when packets are available, and they only * write packets when buffer space is available. In this example, we always * want to read packets when they arrive, so we keep an onRead() handler * registered at all times. We also want to write as long as there's buffer * space, but only when a peer is connected. So we'll register and unregister * our onWrite() handler in onConnect() and onDisconnect(), respectively. * * Note that attach() will empty our transmit and receive queues. If we want * to enqueue write packets in onConnct(), we need to be sure the pipe is * attached before we set up onConnect/onDisconnect. */ Events::usbReadAvailable.set(onReadAvailable); usbPipe.attach(); updatePacketCounts(0, 0); /* * Watch for incoming connections, and display some text on the screen to * indicate connection state. */ Events::usbConnect.set(onConnect); Events::usbDisconnect.set(onDisconnect); if (Usb::isConnected()) { onConnect(); } else { onDisconnect(); } /* * Everything else happens in event handlers, nothing to do in our main loop. */ while (1) { for (unsigned n = 0; n < 60; n++) { readPacket(); writePacket(); System::paint(); } /* * For debugging, periodically log the USB packet counters. */ usbCounters.capture(); LOG("USB-Counters: rxPackets=%d txPackets=%d rxBytes=%d txBytes=%d rxUserDropped=%d\n", usbCounters.receivedPackets(), usbCounters.sentPackets(), usbCounters.receivedBytes(), usbCounters.sentBytes(), usbCounters.userPacketsDropped()); } }