A small RPG company

Name: Viobyte
Version: 0.0.0
Author: Dennis Payne
License: GPLv3
Operating System: Linux and TinyScreen/TinyDuino
Website: http://identicalsoftware.com/viobyte/

TinyScreen Video Game Kit

Some time ago, I had a Space Invaders keychain which played a monochrome version of the game that was fun. When it broke I purchased a color version of the keychain. It also broke. My youngest thought I should get another one. Last I looked I didn't find anything I liked but I tried again.

My search discovered the TinyScreen Video Game Kit. I knew of TinyCurcuits from the TinyArcade Kickstarter but hadn't seen this product. To make a keychain it would still need a case but the size was appropriate. If I had spent a little more time on the site, I might have noticed the TinyScreen+. It combined many TinyScreen Video Game Kit components together with a more powerful processor and more memory. To my dismay the TinyScreen+ with the joystick shield cannot replace the TinyScreen Video Game Kit. The connector on the TinyScreen+ only connected to the back of the joystick shield. TinyCurcuits demoed a TinyScreen+ integrated with a joystick shield but it has yet to be released.


Arduino was designed to be a cheaper microcontroller for students initially. While I knew of it, I've never used it for a project. TinyCurcuit used codebender.cc for it's sample programs. While the site is well made and easily allowed me to upload the sample programs to my device, I wasn't going to spend $10/month on the site.

Fedora instructions for arduino programming suggested the arduino IDE or the command line ino program. Ino is no longer available unfortunately. After setting the board and installing the TinyScreen library, the Space Invaders demo program was running once again. When you compile a program, the IDE informed how much program storage and dynamic memory your program used. This can be important to running on such a restricted platform.

Programming an arduino device was designed to be simple. While it supports C/C++ syntax, the .ino file did not require writing main. The program needed two functions setup and loop. Setup runs once at start and loop keeps executing. If you used the TinyScreen library, the display was already setup. To my dismay, I did find the compiler much more permissive than a normal compiler. The arduino IDE assumed all .ino, .cpp, and .c found in the directory must be compiled. I doubt much of the standard library is available nor would I expect complex features like templates but I did not test them.


Debugging on the device would be annoying. On the TinyCurcuit's forum, zet23t posted about a library and simulator he made for TinyArcade development. The two platforms were similar. With some minor tweaks, I compiled the SpaceInvaders game on my linux machine. It didn't work well because it used fonts which weren't implemented by zet23t. Another example by jonwingrove worked perfectly.

Viobyte in simulator

The td2play simulator used OpenGL for it's display via the GLFW3 library. The developer even included a display to show the status of the joystick and buttons. Had I written a simulator from scratch, I would have used SDL and not bothered with displaying the joystick and buttons. If I wanted to release a Windows or Linux version of the program using the same codebase, I thought it would look better to disable that functionality. Instead I decided to add a G and H to the buttons. To properly support the video game kit, it also needed an additional joystick but that could wait.

zet23t proposed writing a wrapper for each project to compile in the simulator. His library had several wrappers for his projects which would include the .ino file. I wanted something more automatic and created the tinyscreensim. The tinyscreensim shell script copied the .ino file to a .cpp and compiled everything.

Just Like the Real Thing

TinyCurcuit had several sample programs for the video game kit, Space Invaders, Asteroids, Flappy Bird and a Mario jumping game. Without any storage for save files, an arcade style game made the most sense. Something you could pick up and try easily. I decided to try for a Pac-Man clone.

With 30K for the program and 2K for variables, you might think there isn't much you can do. The bigger limitation was the 96x64 pixel screen. jonwinggrove's sprite library used 8x8 pixel tiles. My plan was to use the tile map to determine which directions of travel were possible. 8x8 tiles gave a board of 12x8 which was too small for a maze. While I could have scrolled around a larger screen, it would have altered the game play as you couldn't always see the ghosts.

Even 6x6 tiles proved too large. At 5x5 I was able to dummy up a reasonable maze. The space invaders sample also happened to use 5x5 sprites. The sprite library could be enhanced for different sized tiles but for initial test I simply changed everything to assume 5x5 pixels. A more generic and general purpose sprite library might be slower and I didn't know how much processor time I had to spare.

For the first tests, I created a sprite for the Pac-Man and for every dot on the map. I didn't expect to use this solution but it was a quick test. The compiler confirmed that this was not possible:

Global variables use 2,594 bytes (126%) of dynamic memory, leaving -546 bytes for local variables.

The tinyscreensim didn't have this restriction allowing me to test the solution. Once Pac-Man was eating dots, I revisited how to solve the problem.

Viobyte Screenshot

A possible solution would be to make the dots part of the tiles. When consumed, the tile changes to a tile without a dot. I decided against that approach. Instead I added a callback in the screen drawing routine to allow me to insert whatever is needed. Originally this was used only for dots but it proved convenient for lives and score as well. This change fixed the memory issue preventing the program from running on the video game kit.

Not Quite the Same

When making a clone of a product, studying the product would be advisable. Viobyte stopped when you are not pressing a direction. I noticed this earlier on but chose not alter it. One thing I didn't check nor remembered was how death was handled. Viobyte immediately respawned without altering the ghost locations. This has led to some short games as you die again due to a ghost standing in the square. The original game reset the ghosts on death.

Power pellets are not implemented. I have considered implementing multiple types of power pellets. In addition to the normal option of eating ghosts, I have considered the ability to walk through ghosts. Fruit are not currently implemented as well.

One feature not implemented which I have looked at is animation. Currently Viobyte keeps his mouth open. Adding a second frame to close the mouth would be easy. Due to the small screen size I've avoided adding animation. It simply wouldn't be visible on the tinyscreen video game kit.

Second Map

Adding a second map proved to be more difficult. When I first created the new level, the screen went black. As mentioned earlier you had 30K for the program and 2K for your data. Some constant data could be stored in the 30K to reduce the data used. The constant data needed be const and have the PROGMEM specified on the variable. All images and the level maps were done this way.

Data stored in the program memory is accessed differently. The compiler hid this when only one map was used. When the code started using "maps[currentMap]", the compiler did not handle the access automatically. The pgm_read_* family of functions fixed that problem. However it can be complex to read information from a structure. For example:


It would probably be easier to have an array of X starting positions instead of using an array of LevelMap structures but I prefer the grouping of the map data.

With the memory accessed properly, the second map appeared with a graphical glitch at the bottom. The last row and a couple tiles above were not right and changed. Due to the changing I ran out of memory and was overwriting data. How could that be since I seemed to have plenty of variable memory left. To test I removed the first level from the game. The second level displayed properly. Looking at the global variable usage showed something was off.

Two maps used 1,002 bytes while one map used 932 bytes. The tile map was 228 pointers to Sprite objects. There was no way a pointer was less than a byte. The example code for the Sprite routines used the following code:

static TileMap8pix s_tileMap2 = { 19,12,1,4, new const Sprite*[228] { ... }};

Both maps were dynamically allocating 228 pointers. Unless pointers are a single byte which they are not, I've used too much memory. Dynamic allocation avoided the accounting system of the compiler. The data was unchanging so I moved it to the program memory. Rather than recode the sprite library to use the pgm_read_* function, I created a single 228 sprite array in the variable memory. When the map starts it copies all the content for that map into the variable data array, the second map functioned properly.


Right now I have optimized little except not using sprites for the dots and avoiding dynamic allocation for the maps. If I added the ability the swap one color or specify a palette, the ghosts could have one image instead of four copies. The title screen could be greatly compressed as could other sprites. For even more complexity collision detection could be done while drawing the screen. By using a little more memory multiple division operations could be avoided every frame. I do not know if that would result in an improvement. Overall the tinyscreen platform was a lot of fun to program.


No comments yet.

(optional, e-mail address only visible by admins)

Last modified: 2017-10-23, 18:37

© 2009-2016 Identical Games

powered by phpSQLiteCMS