A project I sometimes work on keeps its codebase usable with multiple versions of SDL.
Now that SDL3 has changed to headers like “<SDL3/SDL.h>”, what’s the recommended way to deal with this? There’s a lot of options I can imagine, eg: using a macro to pick the right header, but I’d love to know what’s preferred.
another option is to hide SDL interface completely and create your own API which has three implementations, one for each major SDL release, then you compile and link the correct implementation depending on which SDL version you link.
The degree of ‘compatibility’ it provides is limited. I can’t use it, because my app relies on OpenGL ES1 which is supported in SDL2 but not in SDL3 at all, as far as I’m aware. No “compatibility layer” can restore that support.
The advantage is that there is only one codebase with no unnecessary duplication of code or data files.
The disadvantage is that the code becomes more complicated. Especially since SDL2 and SDL3 are similar enough that you might sometimes want to reuse the same code for both but in other cases there are subtle differences (e.g. the error return values) that could easily lead to bugs if you mess them up. I therefore think that this approach might be better suited for completely different libraries (so that they require completely different code) or for library versions that are more similar (so that conditional compilation would only be required in a few places).
// Example
// Forget to use conditional compilation here
// and the code would still compile in both
// versions but would not work correctly.
#ifdef USE_SDL3
if (!SDL_Init(SDL_INIT_VIDEO))
#else
if (SDL_Init(SDL_INIT_VIDEO) != 0)
#endif
{
printf("SDL_Init error: %s\n", SDL_GetError());
}
2. Use separate versions (different codebases)
To create an SDL 3 version of your game, just copy all the files and start upgrading the code from SDL 2 to SDL 3.
The advantage is that the code is clean and easy to read. You can make changes and restructure the code freely if you find that it suits the way that SDL 3 works better.
The disadvantage is that whenever you make a change to your project (that is not SDL related) you need to remember to update both versions (using a diff tool would probably be very useful). I think this makes this approach more suitable for mature projects that have already been written and are not expecting much updates.
It’s of course possible to do something in-between. If SDL is only used in part of the project maybe you could find a way to only duplicate that part and use some build script logic to decide which version to compile and link with the rest.
SDL2-compat and SDL12-compat are useful if you want to use SDL 3 to run an older application that was written for SDL 2 or SDL 1.2 but I don’t think it’s an option if you want to be able to use features that only exist in SDL 3.
For example, if you’re writing a chat program you might want to take advantage of the new Camera API when the program is compiled with SDL 3 to allow the persons to see each other while the SDL 2 version of the chat program just doesn’t have that feature.
The Camera API would probably be the single most valuable feature of SDL3 for me, if only I could use it. But I am not aware of any workaround for the loss of support for OpenGL ES1, which my app needs.
I do not understand why that support was dropped, when there is no suggestion (that I am aware of) that either Android or iOS will stop supporting OpenGL ES1 any time soon.