NEO: That's not entirely true. SDL2 does not work on some platforms like QNX, SunOS, Windows CE, BeOS, and AmigaOS4 where SDL 1.2 did work, and support is spotty on Solaris, AIX, HP-UX, and Haiku.

So basically, you lose some old-world mobile platforms and QNX, and it becomes hard going on traditional, commercial Unix, and Haiku. I for one do not mourn for the platforms that become unusable. Having Unix, Windows (Win32 and Metro), Haiku, Android, and iOS, in addition to a theoretical HTML5/JSM platform seems like plenty to me.

SDL2 supports compiling out certain portions, too (for instance, the SDL that I distribute with TS has no audio support), but I found that SFML can do that too, and I suspect Allegro could as well.

SDL2 (and for the most part SDL 1.2) are a mix of OOP and procedural code. I find it pretty easy to work with in either C or C++, it doesn't feel all that unnatural in either. I'd say its worth considering, Allegro is fine with me, too. These are all fairly comparable solutions, and I wouldn't say that its 'wrong' to choose any of them.

So Allegro's API is actually quite nice. Much less boilerplate required to get things up and running compared to SFML. Just create a display and an event queue, and then a main loop that calls al_flip_display() and processes events and you're good to go. SFML was such a pain in the ass, requiring creating structures all over the place just to do something as simple as draw a rectangle.

Honestly, Allegro seems like a perfect fit for the backend of a Sphere engine: Its API is very close in structure to the way the Sphere 1.x API is already designed, meaning this should be pretty painless.

So Allegro's API is actually quite nice. Much less boilerplate required to get things up and running compared to SFML. Just create a display and an event queue, and then a main loop that calls al_flip_display() and processes events and you're good to go. SFML was such a pain in the ass, requiring creating structures all over the place just to do something as simple as draw a rectangle.

Honestly, Allegro seems like a perfect fit for the backend of a Sphere engine: Its API is very close in structure to the way the Sphere 1.x API is already designed, meaning this should be pretty painless.

I agree.

If you use code to help you code you can use less code to code. Also, I have approximate knowledge of many things.

So fairly big showstopper I just hit: Duktape creates and writes JS objects entirely in-engine with the only thing existing on the native side being the code of native functions. There doesn't appear to be a way to create an object on the native side (e.g. a sound) and have data associated with it that is invisible to JS (pointers or handles, say) but readily accessible to native code. The only facility Duktape supplies for this purpose is the "stash", which is itself an in-engine (but invisible to script) JS object and global to the JS context--not exactly suitable.

So yeah, not really sure what to do here.

edit: Also, Allegro's handling of alpha is... odd. I draw two overlapping rectangles, both with alpha 0. These should be completely invisible, right? Instead I get this...

edit 2: Well, I figured it out the alpha issue anyway, Allegro's default blend mode assumes premultiplied alpha, so I just had to change it using al_set_blender()

Okay, so Duktape is very strange. If you try to retrieve the location (file and line number) of a script error, it instead gives you the filename of the C source file which called the script and the line in that file where the Duktape call was made. For instance, calling Abort() reports that the error happened in sphere_api.c on line 49--in other words, the duk_error call. Even for, say, syntax errors though, it seems to correctly report the line in the script, but not the filename--instead it returns the path of the C file making the duk_peval_*() call.

Here's where things get strange though: It correctly reports the source file and line number for the duk_error() call even in release mode, where that information shouldn't even be available (there's no debugging info). What sorcery is this?

Yeah, that's what it is, half of Duktape's API is just macros that call internal functions. Thank goodness Intellisense works with macros now (it never used to, at least it didn't the last time I used VC++), otherwise that would be annoying as hell.

I also did some reading and found out I can store internal state for native-created JS objects. It's simple, too: On the native side, you just set properties on the object with identifiers starting with 0xFF as the first character. Since that creates an invalid UTF-8 string, such properties aren't accessible on the JS side but the native code can access them easily.

So something interesting I found out: Duktape uses reference counting for garbage collection, only falling back on mark/sweep if refcounting fails to free the object--i.e. circular refs. Which means a call like the following:

...will cause the garbage collector to finalize and free the sound as soon as play() returns (meaning this snippet is effectively an expensive no-op under Duktape), whereas, say, SpiderMonkey, the sound might actually stick around for a while. Something to keep in mind.

As for actual minisphere news, I've implemented about half of the Sound API (NOT the SoundEffect API though, that's a different beast entirely), meaning minisphere can load and play music and sounds now! It definitely helps that the learning curve on Allegro (and even Duktape, for the most part) is practically non-existent, which is awesome. Now I remember why I used to love coding in C. Sure, it's ridiculously easy to shoot yourself in the foot (although perhaps not quite so bad as C++), but the language is so simple that, for the most part, it ends up being self-documenting.