Skip to content

SDL Migration proposition

Érico Vieira Porto edited this page Jul 7, 2020 · 15 revisions

This ticket is to discuss move AGS to SDL2 instead of Allegro, with ags4 mindset. Jump to the end for tasklist.

SDL API docs is here.

Background

Using SDL as a backend is a huge undertake that I think it's impossible to do it as a single person. Yet Sonneveld did one WORKING version, so we can discuss with some real implementation that can be used to run ~3.4.x games, it's on branch ags3--sdl2 and I will reference it to help illustrate things. I actually navigate the code with an IDE to help following things, but I will link some files here in GitHub. If things are hard, inspect in a proper IDE (I used CLion, but you can check in VS).

As Allegro 5 has a SDL2 backend, Sonneveld added a SDL2 backend to Allegro 4 and removed as much as possible from it to minimize the amount of things changed. This proposition is to not do this, and instead end up removing Allegro at the end. It may be smarter to the way of Sonneveld and go back removing Allegro, since using a diff tool is relatively easy to pickup his changes and apply.

This is sort of ordered in expected PRs against a branch doing things and keeping it buildable and runnable. I am not as smart as you people, so... Help needed.

1. Branch decision

I suggest forking ags4 into ags4-sdl2 and working there so it's easier to keep ags4 synced with anything that end up hitting ags3 (current master). We need a place to get code flowing in.

2. Reduce Allegro BITMAPS part 1.

We use some allegro add-on libraries, that depend on Allegro itself, for some operations for Drawing Surface and possibly other places.

They kinda operate with some minimal Allegro expectations I think can be removed but gettind rid of them right now is hard for me to figure out, so need help dealing here. Note that these are used in the Editor too. This should help fail fast, if we can't figure this out, then going the approach Sonneveld did will be faster.

  • aastrc, tiny library for anti aliased operations of Bitmaps
    • aastrc -> this does anti aliased streching for Allegro, can we absorb this and remove Allegro dependency?
    • aarot -> this does anti aliased rotation for Allegro, can we absorb this and remove Allegro dependency?
  • alfont, tiny library we use for rasterizing text to Bitmaps
    • higly connected with Engine/font.

We use bitmap drawing on the Editor too, so this is hard to get rid now. Sonneveld strategy was to keep mostly just the Bitmap drawing from Allegro while deleting practically everything else:

 ags3--sdl2  …  libsrc  allegro  src  ls
allegro.c   color.c     file.c      inline.c  polygon.c   stream.c    vtable16.c  win/
blit.c      config.c    fli.c       libc.c    quantize.c  timer.c     vtable24.c
bmp.c       dataregi.c  flood.c     math.c    readbmp.c   unicode.c   vtable32.c
c/          dispsw.c    gfx.c       midi.c    rotate.c    unix/       vtable8.c
colblend.c  dither.c    graphics.c  pcx.c     sdl2/       vtable15.c  vtable.c

vtables are used for bmp of different depths. There are still files above that are never used.

A good maintained switch is pixman+stb_image, should give most of the features we need.

3. Apeg and Video

APEG is the add-on library for Allegro. In AGS this is reasonably separated in Engine/media/video.cpp.

I recommend using AGS_NO_VIDEO_PLAYER flag through the development or stubing anything that calls Apeg. When AGS plays video it doesn't do anything else, so eventually fixing this may not be hard, but right now it's a hard detour to figure.

4. SDL Library placement in Filesystem and CMakeLists.txt, Makefile, Vcxproj, ...

SDL will be referenced in Common/ and Engine/. I prefer adding it in the repository like Sonneveld did, in /libsrc, but this has a terrible side effect that now I need to learn how to build SDL, which is easy in Linux but I can't seem to figure out from the Windows side.

So it may be easier that we do the properties(VS)/include(Makefile)/fetch &include(CMake) way like vorbis and other libraries.

Ignore Android and iOS here.

5. SDL in the CI and Dockerfiles

We need to have SDL in the Dockerfiles and in the CI pipeline code. Note, we already have it for the Linux builds.

6. SDL in AGS Architecture decision

After this transition, we don't expect to have two backends, we expect to use SDL, so there is no need to hide SDL complexities behind an interface.

SDL has a good C API and we will use it directly as much as possible. If something has to be done twice or repeatedly we may group these in methods where convenient, probably new the top of the files that use it directly. I didn't find as much Allegro objects being traded inside the engine so I don't think this will happen when switching to Allegro.

7. Keycodes

AGS has AGS Keycodes for the keyboard input. SDL2 has SDL_SCANCODEs and SDLK_s. Currently, the AGS Keycodes are dealt in ac/sys_events.cpp, and other places mentioned further.

Should there be some dictionary for these key code somewhere or should we use the SDL codes directly? If we should have a dictionary, where should it be? Note, SDL has tons of codes. Here's how Sonneveld did it: ags3--sdl2/Engine/ac/sys_events.cpp

This is only a decision and no code should come from this task.

8. Path handling

AGS uses allegro/file.h for a single canonicalize_filename() function. The SDL FileSystem is kinda slim, but has some helpful multiplatform solutions. Still, we need to write some of own functions to "unallegrify" Common/util/path.cpp and Common/util/misc.cpp.

Also, we should just use dirent, and yes dirent.h in Windows too.

9. Audio and SDL and AGS

SDL Audio is the first subsytem we will implement. Except it may require some more thoughts, on additional libraries.

AGS uses Allegro to pass audio to different audio drivers. This all lives in the neat directory Engine/media/audio/ and has also to be initialized in the Engine/main/engine.cpp. Reading on SDL Audio, it appears to be meant more to play a wav file and have the decompression/decoding from elsewhere. I think we can use Ogg and Vorbis for a start and pass the result of decoding to SDL.

Sonneveld used "SDL_sound" (it's an external library made by iccullus too) and created a new audiocore there that also uses OpenAL (note: iccullus also has MojoAL, which is OpenAL SDL port, maybe worth checking?). I recommend taking a look in his source code ags3--sdl2/Engine/media/audio.

Sound programming is very alien to me so I hope someone can figure this out.

10. SDL Events

SDL_Event is the second subsystem we will implement. SDL will handle Mouse and Keyboard instead of Allegro. This task includes figuring where SDL Events handling for keyboard and mouse should go. This should replace initializing keyboard and mouse in Allegro.

Keyboard and mouse impacts:

I don't know if figuring things like mouse/window position will be possible, so this may not be done in one swept. Keyboard should be easier.

11. SDL Video and Window handling and graphics

For now, we can remove the Software renderer. I think it's easier to comment out anything relative to non 32-bit mode too. We can read on SDL Video Window Management here.

Using the OpenGL renderer, it's time to understand the long path towards ags figuring out what resolution to use in Engine/main/engine.cpp and Engine/main/graphics_mode.cpp, and remove any Allegro functions and let SDL create and destroy windows as needed. For OpenGL, SDL will enable getting the context we will use for the GL functions we already use for drawing.

12. SDL and Directx9 renderer

SDL also has Platform-specific Window Management that may be useful to get DirectX renderer back working. This should be reasonably easy to add back.

13. Fixing video playback back

Remember we removed video? Now that we have SDL windows we can restore it with SDL functions.

14. Removing Allegro and seeing what breaks (and fixing)

Pretty self explanatory.

15. Project files, packaging, ...

This task should enable anyone to build an ags game with sdl2 from the editor, if they build the editor themselves.

16. CI and Docker and releasing.

Until now, all builds should have been shipable, but we may have broken things on the CI along the way.

Ideally we are fixing those as we go, but if that did not happen, this is time to create a beta version regular people can use and fixing everything in the CI and Dockerfiles used by the CI system.

17. Android and SDL and touch events and the future

Decision time. Our Android port uses jni to pass touch input events. SDL also has those.

From a game developer perspective I prefer to handle the touch events myself (have no idea on AGS Script API for those!), instead of the current touch as a mouse thing. This may sadden people that use ags android port to play games but I kinda don't care, having developed some (including unreleased) ags game with Android in mind, the touch as mouse makes me crazy (can't do multitouch, so no joystick overlays!).

Because at this point we at least have AGS4 with SDL2 working on Linux and Windows, from now on it's time to replan things.


Task List

  1. Set a branch to commit this sdl implementations;
  2. Reduce Allegro BITMAPS part 1;
  3. Apeg (Allegro Video Addon) removal;
  4. Fix project files;
  5. Fix CI;
  6. SDL in AGS Architecture decision;
  7. Keycode decision;
  8. Path handling;
  9. New audio system for AGS;
  10. SDL Events;
  11. Replacing platform window and graphics for SDL Video;
  12. Adding back Directx9 render with SDL;
  13. Fixing video playback back;
  14. Removing Allegro and seeing what breaks (and fixing);
  15. Project files, packaging, ...;
  16. CI and Docker and releasing;
  17. Fixing the incomplete platforms left;