Where to start in development without an Arduboy?


(Trevor Ancona) #1

So I ordered an arduboy earlier this week and am interested in developing for it, but with out one on hand, coding would be hard as I couldn’t test it. I have already come up with a few good ideas that could work well around the limited memory size. How is the art rendered? Black and white bitmaps that I could make in another program and import?


USB HID - Turn Arduboy Into Generic Gamepad
Welcome New Developers! A Listing of Development Links and Articles
Programming tutorial
(Ross) #2

Well howdy @GERD !

Thanks for asking a question, let’s get some answers. : )

Art on the Arduboy


The art, or graphic assets, for a game that runs on an Arduboy is stored as a byte array, or bitmap, in the Arduboy’s volatile memory. It is not an array you will create by hand. To create the array’s information you will want to take an existing image file and convert it to a byte sequence the Arduboy understands. A byte sequence can be generated online (next section) and stored as a variable in a program’s source, and used by the program to draw to the Arduboy’s screen.

Generating Imagery

It should be noted that using the Arduboy API you can draw images procedurally/programmatically to the screen, one pixel at a time, or by using a number of other functions built into the Arduboy Library. Function that will draw primitive shapes like points, lines, squares and circles to the screen are easily called as member function of an Aruboy class instance. However, I will only outline converting, storing and drawing bitmaps to the screen in this guide.

Converting Images

There are several online image converters that will convert an image to a byte sequence for use in your Arduboy application. These online converters have been built by other users in the community and can do some of the heavy lifting for your project. See the link below for one, or search the forums for others.

Arduboy Online Image Converter, by Andrew Lowndes
http://www.andrewlowndes.co.uk/blog/graphics/arduboy-image-converter.

Where to Start


Try putting a few images into the application hosted at the link above and see what you think. Look at the output box and check out what the array looks like, take some guesses as to what you think is going on. Then move to the next section of this guide.

How to Really Get it.

After looking through this guide, don’t stop. Keep reading through as much source code related to the Arduino or Arduboy platform as you can handle. Look for examples where other people have stored images or sprites, observe how they format and setup their source files, and emulate what you decide are the best practices, or what approaches meet your needs.

Always feel free to ask questions of your peers.

How Images are Stored in Source Files


For convenience, the following source code from @MLXXXp’s FlappyBird game is provided. Take a second to grok it as best you can.
https://github.com/MLXXXp/FlappyBall/blob/master/bitmaps.cpp

Looking at the statement on line 3 from the bitmaps.cpp file,

PROGMEM const unsigned char floatyball [] = { 0x0, 0x0, ..., 0x0 };

we see the declaration of a variable named floatyball that fulfills the definition made for floatyball in the bitmaps.h header file.

If you wanted to describe floatyball, you could say that is a constant (const), unsigned array ([]) of characters (char).

Looking again at line 93 from the game.cpp source file, the floatyball variable is being assigned a byte array that can be seen on the right hand side (RHS) of the equality operator (=) as a list of comma separated hexadecimal values (0x00, 0x01, ..., 0xFF) placed between a left and right curly brace like so, { 0x0, 0x0, ..., 0x0 }.

This RHS of the statement (right of the = character) is also where the sequence of bytes generated in first section (see, online image converter) will go when you write your own programs. Just change the variable name to one of your liking.

In your programs, the variables storing your bitmaps will generally look like the statement below, but with more byte values in the array.

PROGMEM const unsigned char my_bitmap [] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };

Easy right?

In the FlappyBall game, The floatyball variable is how the sprites are being stored for use in the program. The variable floatyball can be referenced in the game’s other source files wherever the bitmaps.h header file has been included, which can be accomplished by adding the line, #include "bitmaps.h" at the top of any .c, .cpp, .h or .hpp file where the definitions in the bitmaps.h header are needed.

Drawing an Image to the Screen


The source for FlappyBall also provides us with an example on how to draw bitmaps to the Arduboy’s screen. In the the FlappyBall program’s “sketch” file, the .ino file, on line 93 we see a call to the drawSlowXYBitmap(x, y, bitmap, w, h, color) function from the Arduboy API. It is being passed the floatyball variable (defined in the bitmaps.h header file) as the const uint8_t *bitmap parameter needed by the drawSlowXYBitmap function, which is the third parameter out of six that this function requires to be called successfully.

arduboy.drawSlowXYBitmap(0,0,floatyball,128,64,1);

This is the line that actually produces your image on the Arduboy’s screen.

Complete Examples for Drawing Bitmaps


One demo that is designed to showcase the display of an image on an Arduboy is the firstIMAGE demo (Github) by Joeri.

Programming for the Arduboy


This section provides some general tips on getting started in programming for the Arduboy. This section also contains a brief, working example of a program that will emulate the Arduboy Library’s API through a locally implemented class named Arduboy. Our custom Arduboy class contains a sample print() function from the Arduboy API and allow you to build a program for your PC that will also compile for an Arduboy. The rest of the API is left open to implement as needed.

This is only some boiler plate to get started, please respond to this thread if you have an problems.

Tips


Some general tips to help you get started.

1) Start Looking at other people’s work and project files.

One of the best things you can do is start to browse some of the source code that composes other people’s games. You will start to see that similar methods, or design patterns, are present throughout a lot of the games. You can use these same patterns to build your own games.

Codebender

A good place to start might be the ArduboyGames repository on Codebender, which is an online IDE.

2) Use git and Github.

Start a Github account ASAP. Install the git program for your system and learn how to open your terminal/console. Start a local repository and see if you can get it “pushed” to your Github account.

A good place to start learning about Github is by reading their own Hello World guide.

Arduboy Related Repositories

Here are some useful, Arduboy related repositories hosted on Github.

FlappyBall - https://github.com/MLXXXp/FlappyBall
Another great example from @MLXXXp with a ton of great commenting.

Arduboy Library - https://github.com/Arduboy/Arduboy
The core Arduboy Library for making applications on an Arduboy.

3) Skim books, or heck, even read them.


There is at least one book list on the Arduboy forum. Outside of that, I would recommend looking for books that are geared towards Arduino and C. Modern C++ is a bit different than what Arduino uses, which is more like a C interface. For that reason, a lot of the stuff in C++ will not apply to Arduino programming. Modern C++ makes good use of templates and the STL (Standard Template Library), but these are not present on the Arduino implementation of C++.

A canonical book on C happens is K&R’s C, otherwise know as…
http://www.amazon.com/Programming-Language-Brian-W-Kernighan/dp/0131103628

So maybe try and see if a library near you has the above book, or do an inter-library loan request for a copy (it’s worth it).

:100: Programming for an Arduboy, Without an Arduboy


Occasionally I am working on something that will run on an Arduboy, and even though I have an Arduboy, I don’t write my program and compile to the Arduboy first. I will usually write my program and test it on the command-line, writing simple number values to stdout. Sometimes the command-line I use is Powershell, sometimes it is bash, it’s not going to make a big difference.

To follow this guide all you will need is make and gcc installed. The example shows the commands being entered in Windows Powershell, but any command-line interface (CLI) is fine.

Helpful Articles

For Linux, see the article below or search for a similar guide for your Linux distribution.
Debian Linux Install GNU GCC Compiler and Development Environment

For Windows and running GNU/Linux programs try,
GCC and Make: Compiling, Linking and Building C/C++ Applications.

Other articles can easily be found using Google, these may not be helpful to you.

What are We Doing?

This example is of one way out of many possible ways to test and start working with the C++ programming language and create a program that will be compatible with the both Arduboy and a PC. Remember, most of the the rules that to apply programming for any Arduino platform will apply to the Arduboy, and in general the rules for ANSI C and C++98 will apply to all Arduino projects, so we can use these when developing for the Arduboy.

Benefits

Using the following source and ideas, you should be able to start testing small programs and begin to work out some general logic and datatypes for your game/application. On a PC, your program’s output will be directed to the stdout of the command-line of terminal (console) you started your program in. You will not be drawing images to the console, and it is primarily for testing.

To reiterate, we are just testing that our logic all works when running this on a PC, images can be added later in later development step.

Prerequisites


List of requirements:

  • The program make must be installed
  • The compiler gcc must be installed

Linux/Mac

If you run a Unix like operating system, like Linux or Mac, make will probably be on your system already.

Windows

If you are running in a Windows environment, try installing Cygwin or googling “running make on Windows”. The newer versions of Windows will soon have Linux libraries running natively, so there is that to look forward to.

Game Source


The following is the source for a working program that will compile a the game(.exe) binary in the bin/ folder of the project directory. The project is built using make with the makefile provided in the last subsection of the Game Source section. The project’s folder structure must be created before running make; the required folder structure for the makefile can be found in the subsection below, At the Command-Line.

The example source includes a reference to an Arduboy object with only the print function implemented. The print function is called with the same syntax as if this were running on an Arduboy using v1.1 of the Arduboy API. Our program includes a game.cpp file, a game.h file and a special file called a makefile that is used to instruct the make binary in building our program.

Header File

The header file for our program (game.h).

// game.h

// The #ifndef (if not defined) fence below checks to see if the Arduboy Library 
// has been defined. If not, then we will create a local class that can mimic the 
// Arduboy's API (Application Program Interface).

#ifndef ARDUBOY_H
#define ARDUBOY_H

// Include the libraries needed to handle i/o on our system.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>
#include <string.h> 

// Our local Arduboy class.
class Arduboy
{
public:
    // We overload the print function to allow different datatypes.
    void print(char const*); // print a string.
    void print(uint8_t); // print a number.
};

#endif

// Define a macro for setting bits at index 'n' in the bistring.
#define BITSET(var, n) ((var) & (1<<(n)))

// Define a macro for a TYPE unit mapped to an unsigned, 8-bit int.
#define TYPE uint8_t

// A class representing a game.
class Game
{
public:
    Game();             // class Game constructor
    // Rules *rules;       // Pointer to a rules struct (not implemented)
    // Entity *players;    // Pointer to an Entity struct (not implemented)
    Arduboy *arduboy;   // Pointer to the Arduboy class
    TYPE start();       // declare a function named start that returns an uint8_t.
};

Source File

The source file for our program (game.cpp).

//game.cpp

#include "game.h"

void Arduboy::print(char const* s)
{
    printf("%s", s);
}

void Arduboy::print(uint8_t v)
{
    printf("%d", v);
}

Game::Game()
{
    // Instantiate a reference to a new Arduboy object.
    arduboy = new Arduboy;
    
    // Use the 'print()' member function from the new arduboy object.
    arduboy->print("test\n"); 
}

TYPE Game::start()
{
    return 0;
}

// The main entry point for our program.
int main (int argc, char* argv)
{
    // Declare a pointer to a Game object and create the object.
    Game* game = new Game; 
}

At the Command-Line

Inspect the folder structure for our game that sits on the desktop. Then compile and run the program from the command-line. In this case we use Powershell.

PS C:\Users\ekem\Desktop\game> ls


    Directory: C:\Users\ekem\Desktop\game


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----          5/6/2016  11:49 PM            bin
d----          5/6/2016  11:49 PM            obj
d----          5/6/2016  11:48 PM            src
-a---         4/28/2016  12:48 AM        479 makefile


PS C:\Users\ekem\Desktop\game> ls .\src\


    Directory: C:\Users\ekem\Desktop\game\src


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---          5/6/2016  11:48 PM       2374 game.cpp
-a---          5/6/2016  11:47 PM       1338 game.h


PS C:\Users\ekem\Desktop\game> which make
/cygdrive/c/ruby_dev/bin/make

PS C:\Users\ekem\Desktop\game> make
make.exe": `bin/game' is up to date."

PS C:\Users\ekem\Desktop\game> .\bin\game.exe
test

The makefile File

The system tool make is a compilation tool that allows you to automate your build processes. It uses a configuration file usually named ‘makefile’. A makefile can be put in the root directory of your project to direct the build process for that project. When the make binary (executable) is ran, it will start by looking in the current working directory for a makefile. If it finds a makefile it will attempt to run the build instructions provided by the makefile. Type man make into your CLI for more information on the make program.

The example below is one that can be used to build the source above. Don’t worry so much about understanding this file right now. It is worth noting that this file separates the working directory for the project into three folders: bin/ (final binary executable), src/ (source/header files), and obj/ (object files to be linked). Each folder is searched for a particular file type (*.cpp,*.h, *.o) and automatically provided to a build target based on your project’s folder name.

After creating the relevant file structure (see the At the Command Line section for a directory printout) and copying the makefile file into your project’s working directory, simply type make at the command-line to build the project. When it is complete you will find the executable in the ./bin/ directory.

# makefile

TARGET	= game

CC	= g++
CFLAGS	= -Wall -I. -ansi

LD	= g++ -o
LFLAGS	= -Wall -I.

SRC_DIR = src
OBJ_DIR = obj
BIN_DIR = bin

SOURCES := $(wildcard $(SRC_DIR)/*.cpp)
INCLUDES := $(wildcard $(SRC_DIR)/*.h)
OBJECTS := $(SOURCES:$(SRC_DIR)/%.cpp=$(OBJ_DIR)/%.o)
rm	= rm -f

$(BIN_DIR)/$(TARGET): $(OBJECTS)
	@$(LD) $@ $(LFLAGS) $(OBJECTS)

$(OBJECTS): $(OBJ_DIR)/%.o : $(SRC_DIR)/%.cpp
	@$(CC) $(CFLAGS) -c $< -o $@

.PHONEY: clean
clean:
	@$(rm) $(OBJECTS) 

Develop for Arduboy on a Pocket CHIP
(Jmurff) #3

Is there a way to query the device and see device level stuff like memory usage, filesystem(?), os info(?)…


(Ross) #4

It is possible to talk to an Arduboy through a serial connection. If you provided a function to poll the hardware state, you could send it across the usb wire as a serial signal. Checkout some of the node.js modules to make this happen, there are some great serial port emulators for node.js. Javascript, more and more, is positioning itself to power the Internet of Things that is apparently “happening”, so it is worth learning.


(Scott) #5

@jmurff, There isn’t really an O/S or filesystem. There’s just a single program (sketch) running as a single thread.

When you verify or upload a sketch using the Arduino IDE, some memory usage statistics are printed at the end of the compile.

If you use the frame functions provided by the Arduboy Library: setFrameRate() and nextFrame(), your sketch can call the cpuLoad() function, which will provide a percentage value giving some indication of how much horsepower you have to spare. You can display this value somewhere on the screen during debugging, or send it as serial data over the USB port occasionally.


(Holmes) #6

Does this only work with CLI applications? I got the test application to run, and it outputs “Test” like it’s supposed to, but I’d like to be able to compile something like Flappy Ball so that I can start coding games without having my Arduboy, yet.


(Ross) #7

I was just thinking about making an addition that would use ImageMagick to write out some stills :smiley:.

It would also be possible to use imagemagick to convert images to the 1-bit color range that the Arduboy uses.

convert -monochrome in.png out.png

or

convert yo.jpg -colorspace Gray -ordered-dither h4x4a -scale 2000x2000 mono.png 

http://stackoverflow.com/questions/15861025/how-to-convert-an-image-to-1bit-px-binary-bitmap-with-imagemagick-or-rmagick

I really just wanted to give a starting point and a possible implementation for those interested in pursuing development outside the Arduino IDE.


(Holmes) #8

Lemme know if you ever get around to it or if we can get a visual in some way. :slight_smile:


(Ross) #9

I updated the Makefile in my post, I had chopped off the top, sorry about that.