Emulating Arduboy

I am completely new to Arduino and Arduboy seems like a good way to start.

But I would like to start making Arduboy games right now! Are there any tool that would fit for emulating a Arduboy? I know a few engines emulate Arduino and, given the right specs, I could build an Arduboy-like emulated system.

Or is it best for me just wait for my Arduboy to arrive before programming? Any insights?

1 Like

I can help with a couple of insights. There is no official method for emulating an Arduboy for a development environment at the moment.

But… if one looks through the example game and specifically at functions like:

void Arduboy::drawPixel(int x, int y, uint16_t value)

We see this is a function that takes two integers x and y and draws to canvas that is

#define WIDTH 128      
#define HEIGHT 64

What this means is essentially any drawing interface that allows you to set the width and height of a draw context and place a pixel is going to be efficient at emulating the drawing methods of the Arduboy.

Having said that one could craft logic in javascript (see drawPixel example) and port it to the Arduboy, or use a library like SDL or GLFW. We notice in the Arduboy.cpp that almost all of the functions tie back into the drawPixel method. If we construct an ArduboyModified.cpp that includes the SDL library and replaces the Arduboy drawPixel with SDL’s - then we are pretty close. Clean up the source and then write your game in C++. When you have an Arduboy to test on, make your game now include the Arduboy library and use the Arduboy drawPixel() - this will make it compatible with the device. Obviously this isn’t a step by step solution but it breaks down one possible solution to writing code for a device without having to upload the code each time.

2 Likes

This might not exactly be helpful with regard to finding an Arduboy emulator, but Arduboy is actually not the first Arduino-based game system out there. I’ve seen at least two others, the Gamby and the Gamebuino. In fact, many of the existing Arduboy games are ports from these other devices. And emulators may already exist for some of them - for example here is a Gamebuino emulator. There are definitely some differences between the devices. I haven’t looked extensively into all of them, but I do know that Gamebuino has 512 bytes less RAM than Arduboy, one more button than Arduboy, and a display of only 84x48 (Arduboy’s is 128x64). So they’re not entirely equivalent, but coding for one will likely provide experience in coding for the other, and could even produce games that are easily port-able from one to the other.

Another thing you could do is simply examine existing code for Arduino-based games and start working on your own code along those lines, even without a system to test on. Most of the completed games on this page have full source available for your perusal, it could be very educational.


Moderator Note:
Links to Team ARG’s website have been removed due to malicious new owners.

1 Like

This is so awesome! I saw something basic @ekem whipped together and it’s looking really promising! It would be amazing if the emulator could be built in HTML5 to allow all arduboy games to be created and played online or any device!

I think the community we create here about making awesome games is just the beginning. If we can create awesome games on such a simple device, then imagine where they can grow when we get just a little more horsepower and maybe a color screen :smile:

Keep on it team! You guys are amazing!

A big problem with just using SDL like that is that there’s nothing to make your program run at anything like the speed of the Arduboy. We need something that imposes the correct limitations on you, and which is in the same language.

You can just throw a delay in the game loop, thats what I used anyway. Works fine in SDL. The only thing I never got around to was adding proper interrupts for sounds.

Now I never actually said the timing was accurate, I never defined a method to come up with a way to literally match the clockspeed of arduino, just adjust your program so you can change the speed of the game.

for(;;){
        /* ...  */
	lastFrame = currentFrame;
	currentFrame = SDL_GetTicks();

	deltaTime = (float)(currentFrame - lastFrame)/1000;

	drawLoop();
	int currentSpeed = SDL_GetTicks() - currentFrame;
	if(fpsMill > currentSpeed)
	{
		SDL_Delay(fpsMill - currentSpeed);
	}
}

I don’t understand why it’s allegedly so difficult for the Arduboy team to have put out a package that will let you write your game once and deploy it to both Arduboy and PC via an emulator with a reasonable approximation of the clock speed and all relevant features.

Doing it this way, your game could require an order of magnitude more speed than the actual device possesses.

1 Like

@BenMcLean It’s not that difficult it just takes time and resources we have dedicated to fulfilling all the kickstarter backer units first! We’ve got a long list of things we promised to get through already before we are able to sign up for more. But there are some great things community members have already put together and we will for sure support anything that get’s built!

1 Like

OK well it really seems like this should’ve been a priority, because it would mean a bigger library of games would be produced when the physical product finally ships. For anybody who wants to sell to non-developers, content is king.

Personally, I have decided to take up writing games in the kivy framework for the PC with a gameboy-like aesthetic. I may switch to C++ and supporting the Arduboy if we ever get an easy way to rapidly test our projects in an accurate emulator.

1 Like

Dev kit was our priority for getting games made, that gives people a chance to play around with the hardware too. We’re kind of a small outfit of just 3 people and I’m the only one working full time on the project so it’s absolutely awesome when members of the community can pitch in.

We may never be perfect but we can always do better! :smile:

3 Likes

@BenMclean, I have a working emulator, if you want to pop into IRC I we can talk about getting a github setup for it. I just havent had time to clean it up and make it easy to deploy. Frankly Im embarrassed to released unfinished code :slight_smile:

2 Likes

@ekem Did you get any further with the emulator? sadly i missed out on the dev kit, but it would be awesome to get writing before my actual arduboy arrives :wink:

2 Likes

I haven’t gotten very far, but this is available for Linux.

Arduino IDE mod with Arduboy simulator.

1 Like

Heh, this one time, I opened it and looked at it ; ) – I worked a bit on cmake setup so it will compile both on linux and windows, no changes to the code itself though. So it’s still without font rendering and proper sound interrupts. I thought about making it a private repo on github if there are a couple people who want to work on it, then release it publicly, but I haven’t talked with anyone yet.

3 Likes

Thanks for the simulator. It works great for games that use the frame buffer, but with the ‘Squario’ game, which uses direct rendering to the screen vi SPI calls, the screen seems to get a bit messed up. I’m wondering if this is a problem with the game itself or the simulator? (I’m writing a game that uses similar rendering and am struggling to test it, dev kit is ordered but waiting for delivery…)

edit - curiously, the Javascript emulator does exactly the same thing.

Thanks for using it. Its always great to get feedback.
It does not surprise me that the behavior does not differ between versions. The UI elements are rewrites, but most of the Javascript code is actually just emscripten compiled C code.

I think this is a simulator issue.
The code that writes to the screen is very primitive.
I do not have a unit either, so everything I build is reverse engineered by way of static source analysis and decompiling assembly code. See below.

If you are doing something outside of the standard library, I’d be interested to see a snippet and determine if it can be supported in some standard way.

Note, I would also look into getting that methodology added to the standard library if it is trending. Not sure if there are plans for that or not. I am a proponent of the Arduboy team distributing a full custom IDE so there is a one stop mentality to downloading libraries, running the simulator, contributing etc. Currently there are a bunch of distributed solutions to problems and it is kind of hard to keep track of everything going on.

private int X=0, Y=0; public void send(int portValue, int data) { if(portValue == 0x50) { for(int j = 0; j < 8; j++) { int color = Color.parseColor((data & (1 << j)) == 0 ? "#000000": "#FFFFFF"); setPixel(X, Y+j, color); } if(++X == getScreenWidth()) { X = 0; Y += 8; if(Y == getScreenHeight()) { Y = 0; } } } }

Hi again Blake.
OK, here’s a code snippet. It’s mostly based on code from Arduboy::drawTile from the Arduboy.cpp file in the Squario source. This snippet can be saved as an ‘ino’ file in a blank sketch and compiled for testing. In theory it should simply toggle 8 vertical pixels in the top-left of the screen every second. (i.e. set co-ordinates to 0,0 and write either 0 or 255).
In the emulator however, the co-ordinates never seem to get reset to 0,0 and a sequence of on-off bars crawls across the screen. (I’ve no idea what happens on an actual dev board with this code though).

(edit: I don’t know if line 25 should have a 0 or a 1 either)

#include 
#include 

#define CS              6
#define DC              4

Arduboy display;

void setup() {
  display.start();
}
int toggle=0;
void loop() {
  //  *csport |= ~cspinmask;
  *portOutputRegister(digitalPinToPort(CS)) |= digitalPinToBitMask(CS);
  //*dcport &= ~dcpinmask;
  *portOutputRegister(digitalPinToPort(DC)) &= ~digitalPinToBitMask(DC);
  //*csport &= ~cspinmask;
  *portOutputRegister(digitalPinToPort(CS)) &= ~digitalPinToBitMask(CS);
  
  SPI.transfer(0x20);     // set display mode
  SPI.transfer(0x00);     // horizontal addressing mode
  SPI.transfer(0x21);     // set col address
  SPI.transfer(0); // start
  SPI.transfer(0); // end
  SPI.transfer(0x22); // set page address
  SPI.transfer(0); // start
  SPI.transfer(0); // end
  //  *dcport |= dcpinmask;
  *portOutputRegister(digitalPinToPort(DC)) |= digitalPinToBitMask(DC);
  //  *csport &= ~cspinmask;
  *portOutputRegister(digitalPinToPort(CS)) &= ~digitalPinToBitMask(CS);
  if (toggle) SPI.transfer(255); else SPI.transfer(0);
  toggle=!toggle;
  delay(500);
}