This is the Amiga Development blog of Steffest.
I'm a webdeveloper but have zero experience in C or developing for the Amiga.
These are my notes of the journey into Amiga dev-land.
A new blog ...
I don't know anything about C.
Compiling a C program for me in the past was something like
However ... as my interesting in all things computing expands, and one goes of to explore new systems, new OSses, new hardware, retro hardware, then one also discovers the itch to write some code for that platform.
Almost: it runs on any modern platform but it's complety useless on retro platforms like my first true love: the Amiga.
Of course, die-hard amiga developers work directly in assembly, but let's keep it somewhat portable and develop a new skillset that is usefull for the future.
Enter C - the one universal language that is truely present on all platforms.
(Ok, I know maybe Pascal could also be a fit, but ... maybe later)
To create a simple game from the same source files for these completely different target platforms, both retro and modern.
This blog is a log of my findings.
To document the process from a total C-noob to a true cross-platform single-source app.
Let's do this!
Of course, chasing the cross-platform dream is nothing new in the C-world.
There are lot's of examples out there and one that is particularly close to my own personal interest is "Emerald X11" by David Tritscher.
It's plain C, has full source code and is already targeted towards multiple platfoms, including amiga.
Emscripten really is a very cool tool.
It's well documented and very easy to setup.
The hardest part is converting endless loops in C.
the Emerald X11 code has lot's stuff like.
input = readInput();
if (input>0) break;
Instead, everything is event driven.
For games and other graphical stuff, there's usually a single function called by requestAnimationFrame to keep the UI in sync with the screen refresh rate.
This means that you have to transform these c loops to functions that gets called 60 times a second using emscripten_set_main_loop.
As I'm starting from scratch, this is just something I need to be aware of from the start.
The source of Emerald X11 is very structured.
It's a perfect example how to structure your code towards multiple compile targets.
There are usually the same kind of platform specific components needed in most types of software:
The goal is to wrap each of those components in a generic function that we can swap with another implementation when compiling for a platform.
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
context.fillStyle = "black";
var playerImage = new Image();
playerImage.src = "playerWalk.png";
var audio = document.getElementById("audio");
audio.src = "audio/walk.wav";
but wrap everything in generic function like
So you can write the entire game logic in C, controlled by a single "timer" function and do the platform specific implementation per platform.
An obvious no-brainer really - but still good to get clear from the start.
The web part of the project is covered. let's focus on the Amiga!
Should I setup 1 dev environment so I can compile everything one the same platform?
This might seem the most logical setup but maybe not:
Allthough there are some really interesting setup to compile amiga binaries on osX, widows and Linux, I ended up setting up a compiler on the amiga itself.
On the emulated amiga, I use a virtual harddisk that resides on Dropbox.
So whatever system I'm using, when I fire up an emulated amiga, it will always be the exact same setup on everyplatform because the hard disk file is synced.
Even more: after setup, I can just dump the content of the virtual harddisk onto a CF-card, pop it into a real amiga and BAM! everything is up and running there also (try doing THAT with a windows PC!)
All the source files are on Dropbox too, available both local and on the emulated amiga.
I can still use my editor of choice (Jetbrains FTW!) and compile it on the amiga.
If I'm REALLY eager, I can even run the virtual amiga on my Android phone - with the exact same virtual harddisk - and compile from there (OK, not very practical, but it's possible)
So let's keep Amiga compiling on the Amiga.
We'll worry about mobile later.
It seems there are 4 main options for Amiga C compilers
After some fiddling I decided to go with GCC 2.95 on the amiga.
Would there be any performance differences in the final binary when using different compilers? To test.
Ok: Baby steps
Let's get the basics first: opening screens and windows, displaying something on the screen.
I've made a new repo on Github collecting all small examples.
If there are no building instructions you can compile them with:
Let's not worry about portabilty at this point. The first goal is to get a program running that
Some interesting resources:
And some reading:
Don't you love the internet!
The trouble with stackoverflow is that is is an ungooglable error :-)
But lucky I found this:
I often see people define arrays of large size as local vars in a function, and they are unaware that this ends up in stack space.
Indeed! I tumbled into that booby trap also.
Note to self: define large data arrays as const outside any function.
It appears that GCC includes the standard C libraries libnix which defaults to V37 of Amiga libraries.
This makes it pretty hard to target kickstart 1.3 amigas as v37 was included with kickstart 2.04 ...
You can avoid this by using the -nostdlib flag but this opens a whole can of worms (no reference to __main, no reference to atexit ....)
So as a general rule: If you want to target kickstart 1.3 or lower: avoid GCC, use VBCC or SAS/C instead.
I started writing my own chunky versus planar rountine but ofcourse somebody already did that.
I found this totally execellent package at Aminet: GetImage: http://aminet.net/package/dev/c/GetImage
This takes an image (or multiple image inside a Dpaint Brush) and converts it to a C Image data structure ready to by used.
I you're starting with a .png file you can use e.g. Personal Paint to convert it to an DPaint brush.
On the amiga we can include this file and avoid having to do any (slow) chunky/planar conversions, on other platforms we can just include the original .png file.
Someone on the EAB board mentioned "Gamesmith Development System"
Normally I don't want to use "Frameworks" because I like to dig into it myself, but seeing I was having a hard time getting any kind of graphic performance out of my own code I decided to take a look.
I'm glad I did - it looks like it is the perfect "middleware" between high level C drawing function and the raw amiga specific stuff.
It's a library written in Assembler and C that exposes some basic graphic and audio functions to any other language that can load external libraries.
It comes with both a C and a Assemler compiler, but it also works with Sas/C
It was a commercial product but apparently it's in the public domain now.
I found the download here and the manual here.
The installation barfed on the final steps on my system, so I had to complete it manually: assign the GameSmith: path to the installation dir and rename the correct header file for use with Sas/C.
Some of the examples even are very "bunnymark" like so that looks really promising.
Gamesmith includes some "link" files you can excute, but I could not get them to work.
According to the Sas/C user guide you don't really need to do the compiling and linking in 2 steps, you can just use the sc command with the "link" parameter to do everyrthing in 1 step.
You can use the "lib" parameter to define the include libraries.
So to compile the example it would be "sc file.c link lib GameSmith:GameSmith.lib to file"
Awesome. Gamesmith includes lot's of stuff I don't really need, I guess, but the base seems really really promising: fast and easy to integrate.
Let's give it a try.