Belgian Amiga Club

Wanderings in Amiga dev-land

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.

The Goal:
To create a simple game from the same source files for 3 completely different target platforms:
a stock Amiga 500, a modern Mobile Phone and the Modern Web.

You are viewing the articles in chronological order.
You can also view them reversed, which might make more sense as a blog



Bridging retro and modern platforms as a developer

So ...
A new blog ...

I don't know anything about C.
Compiling a C program for me in the past was something like

  • install toolchain:
    • google
    • type "brew something something"
    • type "sudo brew something something"
    • wait 
    • wait in awe, wondering why on earth it has to pull in 4 GB of stuff to compile a few lines of code.
  • cd into src directory
  • type "make"
  • cross fingers and hope it works
  • if it doesn't work - go find someone who knows this stuff.

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.

I'm a web developer, the browser is my natural habitat and javascript is king, queen and army. Javascript runs on everything right!
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.
As you can transpile C into javascript too these days, that seems like the perfect fit.
(Ok, I know maybe Pascal could also be a fit, but ... maybe later)

The goal:

To create a simple game from the same source files for these completely different target platforms, both retro and modern.

  • Amiga, because it's the coolest platform EVER. preferably as low as kickstart 1.3, but we'll settle for 3.1 for now.
  • Mobile, because it's the primary and ubiquitous platform. Android first, maybe iOS too if it's not too much trouble.
  • Web, because it's heaven: the one platform that's available to all, instantly, always, for free.

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!

Written on 23/01/2018 by Steffest

Cross platform examples

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.
It has no javascript port yet but that's my cup of tea - Done!

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.

While(){
   input = readInput();
   if (input>0) break;
}

This doesn't work in javascript.
javascript runs in a single thread and you can't use endless loops like this.
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.
This means converting an existing C source to javascript might require some restructuring.

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:

  • input
    • read user input like keyboard, mouse, joystick
    • reaad files
  • output
    • create a screen
    • display something on the screen
    • connect audio output
    • play an audio sample
    • write files

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.

in pseudo javascript:

Don't write

function movePlayer(){
     var canvas = document.getElementById("canvas");
     var context = canvas.getContext("2d");
     context.fillStyle = "black";
     canvas.drawRect(0,0,800,600)
     
     var playerImage = new Image();
     playerImage.src = "playerWalk.png";
     context.drawBitmap(playerImage,0,0,32,32,x,y,32,32);

     var audio = document.getElementById("audio");
     audio.src = "audio/walk.wav";
     audio.play();
}

but wrap everything in generic function like

function movePlayer(){
     clearScreen();
     drawSprite(SPRITE_PLAYER_WALK,x,y,32,32);
     playAudio(SAMPLE_WALK);
}

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!

Written on 30/01/2018 by

To cross-compile or not to cross-compile

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:

  • emscripten will always be a different compiler and a different path
  • I use osX, Windows en Ubuntu, depending on what I'm doing ... I want to fiddle with code on each of those platforms.
    javascript is the same everywhere, but C compilers are not ... keeping a dev tool chain up and running on those 3 platforms might more work then its worth - use Docker maybe?
  • I still have some real (physical) Amiga's ... it would be nice to code on them as well

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.

 

Written on 10/02/2018 by Steffest

Amiga C compilers

It seems there are 4 main options for Amiga C compilers

  • Sas/C
  • VBCC
    • made for cross platform compiling
    • needs addiotional header files from os3.9 NDK
    • it appears much easier to set this up outside the amiga using https://github.com/kusma/amiga-dev
    • works ... if I ever want to compile on windows this seems a good way.
  • Storm C
    • a full IDE - not really needed
    • V4 is still being sold here
    • Found V3 on http://www.amigafuture.de/downloads.php?view=detail&df_id=664 but could not get it to work
      • Ah ... the name of the install script is wrong (correct it in Install_storm_hd_english.info)
        Image: stormCfix.png

      • And the install script refers to the folder "StormC_3.0" instead of "StormC_3_0" ->rename it
      • Ok - it installs now.
      • Works: Simple Hello-word compiles and runs - Yay!
      • I like it. It seems to be the only mature C IDE on the Amiga?
      • emeraldX11 code barfs though ... to investigate.
  • GCC
    • the latest standalone version on aminet is 2.70, seems a bit old.
    • This package is promising: http://aminet.net/package/dev/gcc/ADE
      • Yes, this seems the one ... based on gcc 2.95
      • I like that you can just park it somwhere, run 1 "ADE-Startup" scriopt and everything works, nothing to install, nothing to configure.
      • I seems to compile the sources I used for my emscripten port nicely - ACE! Got myself a working Amiga binary.
    • Gcc 6.2 was ported back to 68k atari: http://d-bug.mooo.com/beyondbrown/post/gcc-6/ - cool!
    • also very cool ,to check out if I ever take on Assembler: online C to assembler tool: http://brownbot.hopto.org/


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.

Update:

  • It appears Sas/C produces much smaller binaries than GCC
  • to autogenerate the smakefile use "mkmk" in the sourcedir
  • to build the smakefile use "smake"
  • bottom line: I like Sas/C - let's go with that.

Written on 03/03/2018 by

First Steps - simple demo programs

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:

  • Sas/C: type "mkmk" then "smake"
  • GCC: type "gcc -noixemul ****.c -o ****"

Let's not worry about portabilty at this point. The first goal is to get a program running that

  • runs fullscreen
  • displays an animated sprite 
  • listens for mouse and keyboard input
  • does some kind of performance test
  • exits gracefully on click

Maybe a bunnymark to test raw sprite perfomance?

My first semi-usefull program: detect if we are running on AGA Amiga or not. Yay! works fine.

Some interesting resources:

And some reading: 

Don't you love the internet!

Written on 07/04/2018 by Steffest

Troubleshooting

The trouble with stackoverflow is that is is an ungooglable error :-)

But lucky I found this:

http://www.amiga.org/forums/showpost.php?p=237540&postcount=14

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.

Written on 14/04/2018 by Steffest

Chunky versus Planar

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.
Ecellent!

Written on 05/05/2018 by Steffest

GameSmith

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.

Written on 26/05/2018 by Steffest