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!