Reference Page for Development

Can somebody make a Reference page, with all of the Functions?
A link to the Arduino Reference would be great too, to help out beginners.

2 Likes

Currently I believe most of the Arduboy-specific functions can be found in arduboy.cpp/arduboy.h in the GitHub example game. From what they’ve been saying, it’s not final yet either. I’ll make a little summary of the functions here.

In the example game, all of these are called as display.something(); To clear the display, you type display.clearDisplay(); etc.

X and Y positions on the display are from the top left corner, thus a Y of 64 is the bottom of the screen and an X of 128 is the right side of the screen. “Color” or “value” means choosing whether a pixel is lit or not - if color is 0, the pixel is off (black), if color is 1, the pixel is on (white).

I should also probably explain a little about what a screen buffer is…basically it is an internal, “virtual” screen that you draw things on before sending it to the actual screen. This is so users don’t see you drawing directly on the screen including overlaying the graphics, building the picture from its component parts. Sort of like drawing on scrap paper privately before showing the drawing to everyone. Most of these functions draw to the screen buffer, and then when you’re ready you call display.display(); which sends the frame to the screen.

  • start();
    This function sets up everything for the Arduboy’s display and needs to be called at the start of your program.

  • blank();
    A raw, fast screen clear to black, which skips using the screen buffer. This is quick and dirty and probably going to be more useful for test/example programs. It’s important to remember that this does not touch the screen buffer, so if you call display() afterward it will still draw whatever was there before.

  • clearDisplay();
    A screen clear to black which uses the screen buffer. As with most of these functions, won’t be seen until you call display().

  • display();
    This function copies the contents of the screen buffer to the screen, finally displaying the image you’ve built on the buffer using all the other functions.

  • *drawScreen(const unsigned char image); drawScreen(unsigned char image[]);
    These functions draw an entire screen worth of data directly to the screen. One takes a pointer and can thus grab a screen you’ve embedded in your 32k program data (a title screen for example), the other takes an array and therefore comes from RAM. This function is called by display() in order to copy the screen buffer to the screen.

  • drawPixel(int x, int y, uint16_t value);
    Sets a single pixel on the screen buffer to white or black. This function is used by many of the line/shape drawing functions below.

  • drawCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
    Draws a circle of any radius in white or black. X and Y are the center point of the circle.

  • drawCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, uint16_t color);
    Draws one or more “corners” of a circle (1/4th of the circle) depending on which bits are sit in cornername. This function is called by the rounded rectangle functions below.

  • fillCircle(int16_t x0, int16_t y0, int16_t r, uint16_t color);
    Draws a filled-in circle of any radius in white or black. X and Y are the center point of the circle.

  • fillCircleHelper(int16_t x0, int16_t y0, int16_t r, uint8_t cornername, int16_t delta, uint16_t color);
    Draws one or both vertical halves of a filled-in circle depending on which bits are sit in cornername. This function is called by the rounded rectangle functions below.

  • drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
    Draws a white or black line from one point to another using Bresenham’s popular algorithm.

  • drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
    Draws a white or black rectangle of a certain width and height, starting at the top left corner.

  • drawFastVLine(int16_t x, int16_t y, int16_t h, uint16_t color);
    Draws a white or black vertical line of a certain height starting from the top.

  • drawFastHLine(int16_t x, int16_t y, int16_t w, uint16_t color);
    Draws a white or black horizontal line of a certain width starting from the left.

  • fillRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t color);
    Draws a filled-in rectangle in white or black and of a certain width and height, starting at the top left corner.

  • fillScreen(uint16_t color);
    Fills the entire screen buffer with white or black (uses a screen-sized fillRect to do this).

  • drawRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color);
    Draws a rectangle with rounded edges in white or black and of a certain width and height, starting at the top left corner. You can set the radius of the rounded corners as well.

  • fillRoundRect(int16_t x, int16_t y, int16_t w, int16_t h, int16_t r, uint16_t color);
    Draws a filled-in rectangle with rounded edges in white or black and of a certain width and height, starting at the top left corner. You can set the radius of the rounded corners as well.

  • drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);
    Draws a triangle between three points in white or black.

  • fillTriangle (int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color);
    Draws a filled-in triangle between three points in white or black.

  • *drawBitmap(int16_t x, int16_t y, const uint8_t bitmap, int16_t w, int16_t h, uint16_t color);
    Draws a bitmap from program memory to a specific X/Y location in white or black. This will be most commonly used for drawing sprites and other graphics on the screen.

  • drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size);
    Draws an ASCII character to a specific X/Y location in white or black. Individual characters are 6x8 pixels (5x7 with spacing on two edges). “Size” is a pixel multiplier, so a size of 2 means each character will be 12x16, etc. If color is 0 and bg is 1, the character will be drawn inverted (i.e. black with a white background).

  • setCursor(int16_t x, int16_t y);
    Sets the location of the internal cursor for the purpose of writing on the screen.

  • setTextSize(uint8_t s);
    Sets the text size. As mentioned above, individual ASCII characters are 6x8 pixels (5x7 with spacing on two edges). The size is a pixel multiplier, so a size of 2 means each character will be 12x16, etc.

  • setTextWrap(boolean w);
    Sets whether or not text written with the write() function will wrap when it reaches the edge of the screen. As the function is currently written, text will always wrap back to the left edge of the screen, and not to where you initially set the cursor’s X value.

  • write(uint8_t);
    Writes a single ASCII character to the screen, with properties determined by the use of the above functions (setCursor() etc.). This function is called by the print() function to print entire strings of text. The actual print() function is included in Print.h.

  • swap(int16_t& a, int16_t& b);
    Swaps the contents of the a and b variables with each other.

  • getInput();
    Returns a byte containing the current state of all the buttons, which are pressed and which are not, depending on which of the first six bits are 0 or 1. This way you won’t need to check them manually and can test at a glance if up and B are pressed, etc.

10 Likes

Now we can just take your definitions and put them in the header file for doxygen : P Comments are much needed in the next PR to the repository, this is for sure.

I hope it’s all accurate, you might want to check up on me to be sure. I made some assumptions. fillCircleHelper looks like it does semicircles, at least.

The most helpful would be to get @chris to bang out a commented version and do a PR to the example, but your descriptions are accurate. I believe fillCircleHelper() will do rounded cornered squares though.

Hi,
I would like share what I have find so far about Arduboy:

It is Arduino Leonardo connected to six buttons, one speaker and 128x64 OLED display.

Display
Display is driven by controller chip that has its own RAM to accomodate 128 x 64 pixels.
In addition, controller has functions to set contrast, inverse mode, display on/off (saves battery) and basic support for hardware scroll.
The display internal memory has a bit weird layout. Display is oraganized in 8 rows, 128 pixels wide and 8 pixels high. These rows are called pages. Each page contains 128 bytes, one per pixel column. Byte has 8 bits maped to 8 rows of page, most significant bit at bottom.
The OLED internal ram is fully adressable but controller’s API strongly suggests sequential fill. For most cases using 1KB array as backbuffer looks to be most practical method. Some games hungry for RAM still could benefit from software emulated text mode.
I believe the used driver is SSD 1306 OLED driver.

Sound
There is a piezo and there is a pin. You toogle it, you make noise. The tone() implements handler function for cpu timer interrupt. The function simply toogle speaker bit every time it is called and counts time. By setting timer to a frequency you produce square wave of half frequency.
Noise routine can be written same way. Also some more complicated effects are doable…

Buttons
Just buttons, no traps here.

Microcontroller
It is Atmel’s ATmega32u4

  • 8-bit cpu
  • 32KB FLASH (28KB available)
  • 2560 B SRAM (all available, effectively 1KB consumed by display buffer.
  • 1KB EEPROM (all available)
  • 1 x 8-bit timer, 2 x 16-bit timer, 2 x10-bit timer (at least one 16-bit and 10-bit available)

I have read the C compiles to effective code, thanks to friendly architecture.
Still, one should realize that it is 8-bit cpu, so operations on bytes are often compiled to single instruction while operations on wider operands (int,long,float) are always compiled to sequence of instructions.
Cpu has 16-bit index registers so I guess array access could be very fast.
Soon or later you probably would like to understand timers and interrupts.

Ardubreakout
Should be your first stop, it explains a lot.

6 Likes

catmeows, in the ATmega vs. Intel thread you mentioned writing directly to the OLED, but I thought this question would be more relevant here. I assumed we wouldn’t want to write directly to OLED, as that would immediately display anything we send to it, correct? And many games will be building the screen piece by piece, sprite by sprite, drawing a background first and then sprites on top of it, etc. Drawing directly to OLED would probably reveal all of this and look flickery/strange, right? Or does the screen have a built in refresh/“vblank” we can time our writes with, allowing us to skip making our own display buffer?

Also, you seem to say that sound is a simple one tone beeper, but the kickstarter says it’s 2 channel. I’m used to “channel” being used to refer to simultaneous voices, for example the NES has 2 square wave channels, a triangle wave channel, a noise channel and DPCM channel. So how many simultaneous voices do we have on this Piezo speaker?

Yes, you are correct that writing directly to OLED would reveal order of drawing. So for action games the buffer is most suitable method. But imagine you are writing a strategy or adventure game, where smooth display update is not big deal and you are desperate for SRAM space. Then, it is possible to adress a particular place in OLED ram and copy 8 bytes representing character on that place. In that way you can go with 128 bytes long character buffer (or no buffer at all) instead spending 1KB on bitmap buffer. That way, graphics capabilities are restricted to draw characters from font you defined. But nothing prevents you to define semi-graphic characters and use them. Chess game or Sokoban could work this way quite efficiently.

I don’t know details here. The Ardubreakout example uses tone() for sound and it works as described above. I assume Arduboy has connected two pins to speaker but way how to generate sound remains same, you just use two different pins and drive them by two different timers. Actually, there is quite lot of ways how to write tone / sound function, for example driving the two pins from single interrupt.

Read a thread here somewhere where @unclesporky mentioned the bootloader would probably take 2KB, it was also suggested that one could maybe even use a 512B one but that ought to be improbable. What’s with the sudden 4KB drop of usable flash instead of like 2 (excuse me if i’ve missed something important)

Well right in the top of that Ardubreakout code (.ino i think it was) theres a comment containing probably the authors name and a year 2011, well ain’t that long time before even ideas of Arduboy started floating around. I guess it’s probably a code for a leonardo using an inferior sound chip, after all kickstarter and other sources claim the Arrduboy’s speaker to be in fact a 2 channel Piezo, also i think @bateske talked something about usage of an arduino-playtune library if that says smth. about the nature of the chip of sound (sorry for summoning you again Bates : -D and again, OP-s, excuse my ignorance if i’ve left something important unnoticed, just raging and ranting around).

Hi, thanks for reply.

The figure is taken from Arduino IDE with setup for Arduino Leonardo and default bootloader. I think it is good conservative estimation. I would like to hear opinion of somebody who owns arduboy already.

I agree.

I just uploaded a modified version of the Ardubreakout code (turned off sounds), and this is what it said when uploading:

Sketch uses 16,028 bytes (55%) of program storage space. Maximum is 28,672 bytes.
Global variables use 1,643 bytes (64%) of dynamic memory, leaving 817 bytes for local variables. Maximum is 2,650 bytes.

So I guess the max storage is ~28KB, ya?

2 Likes

Hey guys thanks for filling in the blanks as I’ve been super slammed trying to run the kickstarter campaign. Me and @ekem are working on building this and all our internal documentation into a wiki by next week so stay tuned!

I can’t even describe to you how awesome it is to see you all picking up a device I’ve been spending a year of my life bringing to market! Thanks and keep being awesome!!! :slight_smile:

1 Like

X and Y positions start at 0, so the bottom right corner of the screen is at is X = 127 and Y = 63

we need a page like this :wink: http://gamebuino.com/wiki/index.php?title=Reference

I played around with the display.drawCircleHelper() function and thought I should document what it does. The uint8_t cornername argument is a number 1-15, here’s what they do:

I used the emulator that mrboggleman created for the screenshots. The small 1px gaps shown in the screenshots were also displayed on the actual physical device (Developer Kit). Not sure if that’s intentional or not.

  1. display.drawCircleHelper(64, 32, 15, 1, 1);

  2. display.drawCircleHelper(64, 32, 15, 2, 1);

  3. display.drawCircleHelper(64, 32, 15, 3, 1);

  4. display.drawCircleHelper(64, 32, 15, 4, 1);

  5. display.drawCircleHelper(64, 32, 15, 5, 1);

  6. display.drawCircleHelper(64, 32, 15, 6, 1);

  7. display.drawCircleHelper(64, 32, 15, 7, 1);

  8. display.drawCircleHelper(64, 32, 15, 8, 1);

  9. display.drawCircleHelper(64, 32, 15, 9, 1);

  10. display.drawCircleHelper(64, 32, 15, 10, 1);

  11. display.drawCircleHelper(64, 32, 15, 11, 1);

  12. display.drawCircleHelper(64, 32, 15, 12, 1);

  13. display.drawCircleHelper(64, 32, 15, 13, 1);

  14. display.drawCircleHelper(64, 32, 15, 14, 1);

  15. display.drawCircleHelper(64, 32, 15, 15, 1);

2 Likes

Yes, those pixels are a side effect of the way the function calculates the quadrant of the circle.

If you look at the fillCircle function, you’ll see that the first thing it does is draw a quick vertical line down the middle, before drawing two filled halves around it. That’s because those center pixels would be left out.

1 Like

This is a very nice post, i use it at reference all the time, saves me a lot of time browsing trought the actual .cpp file.

@ekem I feel this needs to be pinned at the top :smile:

Ha I have been half tempted to turn it into a wiki topic

Working on getting this turned into a wiki topic

2 Likes