ia: Benvenite! In mi blog io scribe in interlingua, italiano e anglese.

it: Benvenuti! Nel mio blog scrivo in interlingua, italiano e inglese.

en: Welcome! In my blog I write in Interlingua, Italian and English.

Choreograph is still alive

Back in 2023 I started writing a game -- which is still under development as I'm dedicating very little time to it -- and at a certain point I found myself in need of animating the movement of a few rectangles on the screen. Having decided to code the game in C++ and to use just libSDL as a base (in order to keep the game as portable as possible), I started looking around for existing solutions which would do just what I need: animating points between two values, while being display and platform agnostic.

Choreograph

I was happy to find the Choreograph library, which promised to do exactly what I needed, without bringing in any more dependencies. Integrating it in my project proved to be extremely easy, and it took me a few minutes to implement the animation.

All was perfect, except one thing: the last commit to the repository happened in 2016. I submitted a couple of minor fixes, and there was no reaction. Even though I was very happy with the library, I decided not to get tied to a project that was apparently dead, so I dropped this integration and instead wrote my own implementation -- which was just enough to fill my immediate need, but was unlikely to be reusable as a generic animation framework.

Over time, though, several times I happened to bump into a situation where I would have liked to add some animation, but given that I was not really happy with my home-brew solution, I always held myself back from this desire and focused on more substantial issues: so, no animations. In March this year I decided to write to the author of Choreograph to check whether he was still interested in maintaining the project, but got no answer.

A maintained fork

Well, one cannot certainly accuse me of being impatient in this case, since I waited a few more months before finally deciding that I find Choreograph to be too convenient to let it just rot. Here is my maintained (for how long, we'll see!) fork of the Choreograph project; so far I've added:

  • A few commits to fix compilation warnings
  • Recipes for the Meson build system, to make it easier to build the project in Linux
  • CI via GitHub actions
  • Updated the tests and the samples to build without libCinder

I'm not yet able to announce what I'm going to work on next in Choreograph; this will become clear as I'll be using it more. For the time being, it's enough for you to know that such a project exists, and I'll be happy to accept contributions in the form of code and ideas.

No, libogc did not steal RTEMS code

Update 09/05/2025: while the text below addresses a couple of specific blocks of code, after publishing this article I've been contacted by some people providing more evidence pointing that the similarity of the code goes beyond what one might interpret as “inspiration”. There are also a couple of other bits on information that the reader might want to take into account: first, a screenshot of an email in which Shagkur tells his version of how the code came about (which seems to point that, if a copyright infringement actually happened, this was done without the knowledge of devkitPro's maintainers) and a public statement by RTEMS.

All of a sudden the Wii homebrew community is in flames after Hector Martin (marcan, also known in the Linux Kernel community), co-author of “The Homebrew Channel” application, decided to close the project and denounce libogc for its “theft” of RTEMS's code:

It has recently been revealed that the threading/OS implementation in libogc is, in fact, stolen from RTEMS. The authors of libogc didn't just steal proprietary Nintendo code, but also saw it fit to steal an open source RTOS and remove all attribution and copyright information. This goes far beyond ignorance about the copyright implications of reverse engineering Nintendo binaries, and goes straight into outright deliberate, malicious code theft and copyright infringement.

A little below, Hector Martin provides this “proof”: you can compare this function in libogc to this function in a really old version of RTEMS.

While I don't know the truth about libogc's history (I've started contributing to it only in the last couple of years), and I'd welcome a first-hand explanation from shagkur (Michael Wiedenbauer), I can confidently say that the accusation is unfounded, by just looking at the code. To be more precise: I cannot vouch for the whole of libogc, I can only say that this function, that Hector Martin offers as example, actually hints that the code was not stolen.

While it's obvious that the developer of libogc's code did have a look at RTEMS's code, and this can be assumed because the variable names are very similar (and in some cases they are so badly named, that they cannot be this similar by accident!), the code only looks vaguely similar. Furthermore, for some reason Hector Martin decided to pick a rather recent version of libogc's code, but if we look at the first version that was committed (well, to git, at least), we see that similarities are much less striking. Let's look at a small snippet of the function, where the thread object's members are being initialized:

RTEMS from 1996:

  the_thread->Start.is_preemptible = is_preemptible;
  the_thread->Start.is_timeslice   = is_timeslice;
  the_thread->Start.isr_level      = isr_level;

  the_thread->current_state          = STATES_DORMANT;
  the_thread->resource_count         = 0;
  the_thread->real_priority          = priority;
  the_thread->Start.initial_priority = priority;

libogc from 2023:

    thethread->budget_algo = (prio<128 ? LWP_CPU_BUDGET_ALGO_NONE : LWP_CPU_BUDGET_ALGO_TIMESLICE);
    thethread->is_preemptible = is_preemtible;
    thethread->isr_level = isr_level;
    thethread->real_prio = prio;
    thethread->cur_state = LWP_STATES_DORMANT;
    thethread->cpu_time_budget = _lwp_ticks_per_timeslice;
    thethread->suspendcnt = 0;
    thethread->res_cnt = 0;

libogc from before 2004:

    thethread->isr_level = isr_level;
    thethread->real_prio = prio;
    thethread->cur_state = LWP_STATES_DORMANT;
    thethread->suspendcnt = 0;
    thethread->res_cnt = 0;

Let's pay attention to the is_preemtible variable, which is present in current's libogc and in RTEMS, but not in the old libogc: it was added later. Now, RTEMS has it since at least 1996, so, if libogc was actually copied from it, how come this variable was not copied, too, but added at a later time? Note, the accusation against libogc has been formulated in clear-cut terms: ...steal an open source RTOS and remove all attribution and copyright information...; it's clear that this is not what happened. It's much more likely that libogc's developers did look at RTEMS code (which at that time had another license and was known as the Real Time Executive for Missile Systems or Real Time Executive for Military Systems) as a model and source of information, but since the code was heavily adapted for libogc, they didn't feel they were creating a “derivative work”. It's a grey area, but even myself, if I took a project written in C++ and translated it into Rust or C#, for example, I'm rather sure I wouldn't consider my work to be a derivative of the original; I'm not a lawyer, so I might be plain wrong here, but I would be in good faith.

At most, libogc could be accused of plagiarism, but in my humble opinion even that would be a stretch: since we are not talking of some artistic work, but of work of science/ingeneering, it's normal to build upon others' work. Yes, credit should generally be given, but given that we are talking of a US military-related project, I can see that there could be ethical reasons for not wanting to do so.

Summing up

I'm consciously omitting the other old accusations about “stealing” Nintendo's code, first because they are not new, and secondly because I don't consider reverse-engineering as stealing. What I found most disturbing about this story is that it smells hatred from far away, since I have a hard time to understand why someone felt the need to look into libogc's origin and publicly smearing the project and ultimately harming the whole of the Wii homebrew community.

Porting OpenGL games to the Nintendo Wii: chro.mono

More than one year has passed since my last blog post, and I'm a bit ashamed to confess that today's post is again about porting games to the Nintendo Wii — I always tell to myself that I'm soon going to move to something else, possibly less geeky than this (by the way, there is something else I could write about, but I'll leave it for another post!), but the problems posed by porting games to an old console are just way too stimulating, and my brain gets attracted to them in a way that I cannot resist.

Anyway, have you ever heard of OpenGX? It's a project aiming to write an OpenGL driver for the Nintendo GameCube and Wii's GX API: while these consoles have good (at the time, at least) 3D capabilities, they were programmed via an API not even remotely close to OpenGL, so back in 2013 one developer by the name of David Guillen Fandos started a project to investigate the possibility of wrapping the GX API in OpenGL. The project was abandoned after reaching a very basic state, but it's author was diligent enough to write a PDF file describing its design and some implementation details. Having bumped into this document, I was inspired by it and felt it was a pity that such a project had died -- especially given the fact that this didn't happen because of some technical infeasibility. So exactly one year ago, in the spring of 2024, I picked it up and tried porting the game BillardGL to the Wii; I had to add quite a few things to OpenGX, and adjusting the lighting pipeline, but after less than one month the port of BillardGL was ready. In the following months, I ported several other OpenGL 1.x games, gradually enhancing and expanding OpenGX, until I got most of OpenGL 1.4 supported.

A 23 year old game was just ported to a 19 year old console.

Should I have stopped there? Probably. Because indeed the Wii's GPU, despite allowing a good degree of complexity in setting up its shading engine (called TEV, Texture Environment), does not support the modern GL shading language, and trying to have the CPU compile the shaders into something that GX could understand is a task doomed to fail, in part because this would eat up all the computing power, but especially because there simply isn't an algorithm that could translate GLSL into GX commands. Is this the end of the journey then?

Well, the fact that OpenGL 2.0+ shaders can not be machine-translated into GX commands does not mean that this task is impossible: we've still got the human brain to use! The idea is the following: let the deveoper who is porting the game write the GX code corresponding to the GLSL code by hand. Saying it like this might feel like this is no better than saying “Just port the whole rendering backend to GX!” but as a matter of facts, there's a big difference: with this approach all the rest of the OpenGL code stays untouched, and the way I have design this shader substitution to work in OpenGX allows one to keep the GX code isolated in its own source file, without having to change a single line of the program, save from adding a line near the beginning (in main(), typically) to install the GX hooks. This means that your program will still call glUniform*(), glVertexAttribPointer() and so on to setup the rendering pipeline, but when the program will get to execute glDrawArrays() OpenGX will pass control to the hooks previously installed, which will receive the uniforms and the attributes, and setup the pipeline using GX commands. It might seem complicated, but it really isn't (well, if you can deal with the GX API), and it's even more efficient than the fixed pipeline of OpenGL 1.x, since here the GX commands are reduced to the bare minimum required by the shader, whereas in the fixed pipeline we have to follow predefined steps.

chro.mono running on a Nintendo Wii.

The first (and for the time being, the last) OpenGL 2.0+ game I've ported to the Wii is chro.mono, a nice puzzle game from 2013 whose source code has been released in 2021. It uses the FBO feature from OpenGL 3.0, so I had to implement it in OpenGX as well. I'm quite satisfied with the result, not only because the game runs at 60 FPS, but because it shows how rather complex shaders (the game has more than a dozen of them) can be realized in GX; to tell the truth, in couple of cases I had to implement the fragment shader by converting its code to C and drawing to a temporary texture, but luckily these shaders are used only during program startup to draw to an FBO and don't negatively affect the game performance. You can download it from here.

Summing up, if you get really bored and would like to engage in something unusual (read: useless), porting games to older consoles would definitely keep you active for some time. Unfortunately there aren't that many OpenGL games which are open source, so the candidates for porting are not that many (by the way, feel free to suggest in the comments — well, not for me, but maybe someone else will do it).

libSDL2 and VVVVVV for the Wii

Just a quick update on something that I've been working on in my free time.

I recently refurbished my old Nintendo Wii, and for some reason I cannot yet explain (not even to myself) I got into homebrew programming and decided to port libSDL (the 2.x version -- a 1.x port already existed) to it. The result of this work is already available via the devkitPro distribution, and although I'm sure there are still many bugs, it's overall quite usable.

In order to prove it, I ported the game VVVVVV to the Wii:

During the process I had to fix quite a few bugs in my libSDL port and in a couple of other libraries used by VVVVVV, which will hopefully will make it easier to port more games. There's still an issue that bothers me, where the screen resolution seems to be not totally supported by my TV (or is it the HDMI adaptor's fault?), resulting in a few pixels being cut at the top and at the bottom of the screen. But unless you are a perfectionist, it's a minor issue.

In case you have a Wii to spare, or wouldn't mind playing on the Dolphin emulator, here's the link to the VVVVVV release. Have fun! :-)