This article will be about how to keep your code base organized while getting the most of the compiler for the small amount of memory the watch provides.
Source code layout
I may not have mentioned but, I'm using CloudPebble to develop on Pebble.This is a fantastic development tool for few reasons:
- First of all, it makes my code accessible from any device. Knowing that I'm coding on 3 different PC/Laptop and occasionally on a tablet, this makes my life a lot easier.
- Secondly, it's platform independent. The above hardware list I'm using to code, features Windows, Ubuntu and Android operating systems. Cloud Pebble has no trouble there :)
- It supports multiple source files projects
There's few reasons for that:
- Editing preferences: you can find everything in one place without having to switch from one file to the other and every piece of code can be accessed by any other one.
- Compiler friendly: reduced link time and the ability for the compiler to be able to globally optimize the final executable.
The second argument is, in my opinion, the most valid. Especially in a resource-constrained platform like the Pebble Watch.
And i measured it: with the compiler setup to optimizing for size, one big file results in a smaller executable than having the exact same code spread in multiple source files.
But ... I like organizing my code in multiple files (.h and .c):
- First, because of my long API developer experience. I write libraries of functions that I can reuse in future programs so it makes each iterations faster.
- Second, because I want to find quickly where the monsters related code is: in monsters.c :)
- Third (related also to the API point), I want my header files to be the public side of each libraries and the .c file to have all the internal business hidden from outside.
There's a simple way to get the benefits of both worlds. It's used professionally on large projects (and particularly in professional video game development): bulk builds.
Bulk builds
The concept is rather simple:- Spread your source code in multiple source files
- Exclude them from compiling
- Have a "bulk.c" file that includes all the above source files and compile only this one.
CloudPebble doesn't give you the ability to exclude files from the build. To go around this you could use a different (non compilable) extension for your files. For example .inc files.
Since I already had all my .c files in place, I decided to use the pre-processor to help me. Each file is shaped this way:
#include "config.h"#ifdef BULK_BUILD
// source code
#endif // BULK_BUILD
Then the bulk.c file looks like:
#include "config.h"#ifndef BULK_BUILD#define BULK_BUILD
#include<a.c>#include<a.c>// more includes
#endif // !BULK_BUILD
Now I can easily switch from bulk builds to non ones.
By default they are on. If I want to compile normally, I simply add #define BULK_BUILD in config.h file and now all the individual files are compiled separately.
This solution makes it easy to port any project to support bulk builds without having to deal with compiler settings.
Results
On my dungeon 3D game project this allow me to gain a fair amount of free space to add more features and data.Here's the comparison on both generation of the watch ( using SDK 3.0 ).
- Regular build
-------------------------------------------------------
APLITE APP MEMORY USAGE
Total footprint in RAM: 24016 bytes / 24KB
Free RAM available (heap): 560 bytes
-------------------------------------------------------
BASALT APP MEMORY USAGE
Total footprint in RAM: 43572 bytes / 64KB
Free RAM available (heap): 21964 bytes
-------------------------------------------------------
- Bulk builds
-------------------------------------------------------
APLITE APP MEMORY USAGE
Total footprint in RAM: 23672 bytes / 24KB
Free RAM available (heap): 904 bytes
-------------------------------------------------------
BASALT APP MEMORY USAGE
Total footprint in RAM: 42916 bytes / 64KB
Free RAM available (heap): 22620 bytes
------------------------------------------------------
If we look at the size of the executable, the bulk build version is only a few percent smaller than the regular build.
This may not seem significant, but in that case this translates to 344 and 656 bytes of extra space that can be used to add more code or content. And believe me, once you reach the limit of the device, every byte counts.
On this note, I will certainly talk more about how I manage to squeeze all the features of my dungeon game in the tiny memory of the Pebble Watch.
There was a great article from David Drake on this subject related to his game:
http://davidcdrake.com/2015/03/27/pebblequest-25kb-of-awesome/
Conclusion
Developing for the Pebble Watch is a very challenging but extremely fun experience. There's many roads that are just waiting to be explored which makes it exciting.
You need to experiment, invent and think out of the box to define what you've designed to finally see it coming to live on the device.
I'll try to up the pace of my posts. Let me know if this article was useful or if even share your own experience with this device.
Pretty cool read
ReplyDeleteCan't wait for this
ReplyDelete