diff --git a/recipes/sdl2_gears/font.ttf b/recipes/sdl2_gears/font.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..eb1000bcad0d83e1d1561bbcf191b2173ede705c
Binary files /dev/null and b/recipes/sdl2_gears/font.ttf differ
diff --git a/recipes/sdl2_gears/gears.c b/recipes/sdl2_gears/gears.c
index 19a655533d28400493fcacc7ca84c4099678a168..33d99ca5695bfba518df6319577584e3b6d1ca9a 100644
--- a/recipes/sdl2_gears/gears.c
+++ b/recipes/sdl2_gears/gears.c
@@ -8,11 +8,11 @@
 
 /* Conversion to GLUT by Mark J. Kilgard */
 
-#include <math.h>
-#include <stdlib.h>
-#include <GL/gl.h>
-#include <GL/glu.h>
 #include <SDL2/SDL.h>
+#include <SDL2/SDL_opengl.h>
+#include <SDL2/SDL_image.h>
+#include <SDL2/SDL_mixer.h>
+#include <SDL2/SDL_ttf.h>
 
 #ifndef M_PI
 #define M_PI 3.14159265
@@ -56,6 +56,7 @@ gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
     {
         angle = i * 2.0 * M_PI / teeth;
         glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
+
         glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
         glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
         glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da), width * 0.5);
@@ -276,33 +277,65 @@ void CheckSDLError(int line)
     }
 }
 
-void audio_callback(void *userdata, Uint8 *stream, int len);
-static Uint8 *audio_pos; // global pointer to the audio buffer to be played
-static Uint32 audio_len; // remaining length of the sample we have to play
+SDL_Surface *image;
+const char *IMAGE_FILE_NAME = "image.png";
+
+Mix_Music *music = NULL;
+const char *MUSIC_FILE_NAME = "music.wav";
 
-void audio_callback(void *userdata, Uint8 *stream, int len)
+TTF_Font *font = NULL;
+const char *TTF_FILE_NAME = "font.ttf";
+
+void cleanup()
 {
-    if (audio_len == 0)
-        return;
+    if (context != NULL)
+    {
+        SDL_GL_DeleteContext(context);
+        context = NULL;
+    }
+    if (window != NULL)
+    {
+        SDL_DestroyWindow(window);
+        window = NULL;
+    }
 
-    len = (len > audio_len ? audio_len : len);
-    SDL_memcpy (stream, audio_pos, len); 					// simply copy from one buffer into the other
-    //SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME); //FIXME: broken in redox
+    if (image != NULL)
+    {
+        SDL_FreeSurface(image);
+        image = NULL;
+        IMG_Quit();
+    }
+
+    if (music != NULL)
+    {
+        Mix_FreeMusic(music);
+        music = NULL;
+        Mix_CloseAudio();
+    }
 
-    audio_pos += len;
-    audio_len -= len;
+    if (font != NULL)
+    {
+        TTF_CloseFont(font);
+        font = NULL;
+    }
+
+    // Shutdown SDL 2
+    SDL_Quit();
 }
 
 int main(int argc, char *argv[])
 {
+    // Main
     printf("Initializing SDL\n");
     if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO) < 0)
     {
         printf("Failed to init SDL\n");
         CheckSDLError(__LINE__);
+        cleanup();
         return -1;
     }
 
+    // Video / window
     printf("Creating SDL window\n");
     window = SDL_CreateWindow(
         "Gears",
@@ -315,6 +348,7 @@ int main(int argc, char *argv[])
     {
         printf("Unable to create window\n");
         CheckSDLError(__LINE__);
+        cleanup();
         return -1;
     }
 
@@ -324,6 +358,7 @@ int main(int argc, char *argv[])
     {
         printf("Unable to create SDL GL context\n");
         CheckSDLError(__LINE__);
+        cleanup();
         return -1;
     }
 
@@ -331,32 +366,70 @@ int main(int argc, char *argv[])
 
     reshape(width, height);
 
+    // Image
+    printf("Initializing SDL image supporting formats png and jpeg\n");
+    int flags = IMG_INIT_JPG | IMG_INIT_PNG;
+    int initted = IMG_Init(flags);
+    if ((initted & flags) != flags)
+    {
+        printf("IMG_Init: Failed to init required jpg and png support: %s\n", IMG_GetError());
+        CheckSDLError(__LINE__);
+        cleanup();
+        return -1;
+    }
+
+    image = IMG_Load(IMAGE_FILE_NAME);
+    if (image == NULL)
+    {
+        printf("IMG_Load failed: %s\n", IMG_GetError());
+        CheckSDLError(__LINE__);
+        cleanup();
+        return -1;
+    }
+
     // Audio
-    // local variables
-    static Uint32 wav_length = 0;    // length of our sample
-    static Uint8 *wav_buffer = NULL; // buffer containing our audio file
-    static SDL_AudioSpec wav_spec;   // the specs of our piece of music
-
-    // Load the WAV
-    // the specs, length and buffer of our wav are filled
-    const char* audio_file_name = "./test.wav";
-    if (SDL_LoadWAV(audio_file_name, &wav_spec, &wav_buffer, &wav_length) == NULL)
+    printf("Opening SDL mixer audio\n");
+    if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 4096) < 0)
+    {
+        fprintf(stderr, "Couldn't open audio mixer: %s\n", SDL_GetError());
+        CheckSDLError(__LINE__);
+        cleanup();
+        return -1;
+    }
+
+    music = Mix_LoadMUS(MUSIC_FILE_NAME);
+    if (music == NULL)
+    {
+        fprintf(stderr, "Couldn't open audio file %s: %s\n", MUSIC_FILE_NAME, SDL_GetError());
+        CheckSDLError(__LINE__);
+        cleanup();
+        return -1;
+    }
+
+    if (Mix_PlayMusic(music, -1) < 0)
     {
-        fprintf(stderr, "Couldn't open audio file %s: %s\n", audio_file_name, SDL_GetError());
+        fprintf(stderr, "Couldn't play music: %s\n", SDL_GetError());
+        CheckSDLError(__LINE__);
+        cleanup();
         return -1;
     }
 
-    // set the callback function
-    wav_spec.callback = audio_callback;
-    wav_spec.userdata = NULL;
-    // set our global static variables
-    audio_pos = wav_buffer; // copy sound buffer
-    audio_len = wav_length; // copy file length
+    // TTF
+    printf("Initializing TTF\n");
+    if (TTF_Init() < 0)
+    {
+        printf("Failed to init TTF\n");
+        CheckSDLError(__LINE__);
+        cleanup();
+        return -1;
+    }
 
-    /* Open the audio device */
-    if (SDL_OpenAudio(&wav_spec, NULL) < 0)
+    font = TTF_OpenFont(TTF_FILE_NAME, 30);
+    if (font == NULL)
     {
-        fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
+        printf("Couldn't open TTF file %s: %s\n", TTF_FILE_NAME, SDL_GetError());
+        CheckSDLError(__LINE__);
+        cleanup();
         return -1;
     }
 
@@ -368,10 +441,7 @@ int main(int argc, char *argv[])
         idle();
 
         // Loop track
-        if (audio_len <= 0) {
-            audio_pos = wav_buffer;
-            audio_len = wav_length;
-        }
+        Mix_PlayingMusic();
 
         while (SDL_PollEvent(&event))
         {
@@ -384,16 +454,27 @@ int main(int argc, char *argv[])
                 {
                 case SDLK_p:
                 {
-                    if (playing_audio)
+                    if (!Mix_PlayingMusic())
                     {
-                        fprintf(stderr, "Pausing SDL audio\n");
+                        if (Mix_PlayMusic(music, -1) < 0)
+                        {
+                            fprintf(stderr, "Couldn't play music: %s\n", SDL_GetError());
+                            CheckSDLError(__LINE__);
+                            cleanup();
+                            return -1;
+                        }
                     }
                     else
                     {
-                        fprintf(stderr, "Playing SDL audio\n");
+                        if (Mix_PausedMusic())
+                        {
+                            Mix_ResumeMusic();
+                        }
+                        else
+                        {
+                            Mix_PauseMusic();
+                        }
                     }
-                    SDL_PauseAudio(playing_audio);
-                    playing_audio = playing_audio > 0 ? 0 : 1;
                     break;
                 }
                 case SDLK_a:
@@ -434,16 +515,11 @@ int main(int argc, char *argv[])
                 }
             }
         }
-    }
-
-    SDL_GL_DeleteContext(context);
-    SDL_DestroyWindow(window);
 
-    SDL_CloseAudio();
-    SDL_FreeWAV(wav_buffer);
+        SDL_Delay(10);
+    }
 
-    // Shutdown SDL 2
-    SDL_Quit();
+    cleanup();
 
     return 0;
 }
\ No newline at end of file
diff --git a/recipes/sdl2_gears/image.png b/recipes/sdl2_gears/image.png
new file mode 100644
index 0000000000000000000000000000000000000000..f3a6f1140276a0d83b2858b4741ba2df56ec6f20
Binary files /dev/null and b/recipes/sdl2_gears/image.png differ
diff --git a/recipes/sdl2_gears/music.wav b/recipes/sdl2_gears/music.wav
new file mode 100644
index 0000000000000000000000000000000000000000..f29a8c9c22906088b6f19fcb03dc6aa39e9e5fc9
Binary files /dev/null and b/recipes/sdl2_gears/music.wav differ
diff --git a/recipes/sdl2_gears/recipe.sh b/recipes/sdl2_gears/recipe.sh
index e933b0a07754078a2c79bdb30294a59bd5e757cd..baae90cde02e724e525969db0babb198d282615f 100644
--- a/recipes/sdl2_gears/recipe.sh
+++ b/recipes/sdl2_gears/recipe.sh
@@ -1,4 +1,4 @@
-BUILD_DEPENDS=(sdl2 liborbital llvm mesa mesa_glu zlib)
+BUILD_DEPENDS=(sdl2_image sdl2_mixer sdl2_ttf sdl2 liborbital llvm mesa mesa_glu freetype libjpeg libpng zlib)
 
 function recipe_version {
     printf "1.0.0"
@@ -19,7 +19,7 @@ function recipe_prepare {
 function recipe_build {
     sysroot="$(realpath ../sysroot)"
     set -x
-    "${CXX}" -O2 -I "$sysroot/include" -L "$sysroot/lib" gears.c -o sdl2_gears -lSDL2 -lorbital $("${PKG_CONFIG}" --libs glu) -lglapi -lz
+    "${CXX}" -O2 -I "$sysroot/include" -L "$sysroot/lib" gears.c -o sdl2_gears -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lSDL2 -lorbital $("${PKG_CONFIG}" --libs glu) -lfreetype -lpng -ljpeg -lglapi -lz
     set +x
     skip=1
 }
@@ -39,6 +39,8 @@ function recipe_stage {
     mkdir -pv "$dest/games/sdl2_gears"
     mkdir -pv "$dest/home/user"
     cp -v "sdl2_gears" "$dest/games/sdl2_gears/sdl2_gears"
-    cp -v "../test.wav" "$dest/home/user/test.wav"
+    cp -v "../image.png" "$dest/home/user/image.png"
+    cp -v "../music.wav" "$dest/home/user/music.wav"
+    cp -v "../font.ttf" "$dest/home/user/font.ttf"
     skip=1
 }
diff --git a/recipes/sdl2_gears/test.wav b/recipes/sdl2_gears/test.wav
deleted file mode 100644
index 12348effa02fe93fbe9be9a2c4a3a74c02339183..0000000000000000000000000000000000000000
Binary files a/recipes/sdl2_gears/test.wav and /dev/null differ
diff --git a/recipes/sdl2_image/recipe.sh b/recipes/sdl2_image/recipe.sh
new file mode 100644
index 0000000000000000000000000000000000000000..7a52bb28fcffb8d7d0966e72f3688200466bd077
--- /dev/null
+++ b/recipes/sdl2_image/recipe.sh
@@ -0,0 +1,40 @@
+VERSION=2.0.4
+TAR=https://www.libsdl.org/projects/SDL_image/release/SDL2_image-$VERSION.tar.gz
+BUILD_DEPENDS=(sdl2 liborbital mesa llvm mesa mesa_glu libiconv libjpeg libpng zlib)
+
+function recipe_version {
+    echo "$VERSION"
+    skip=1
+}
+
+function recipe_update {
+    echo "skipping update"
+    skip=1
+}
+
+function recipe_build {
+    sysroot="$(realpath ../sysroot)"
+    export CFLAGS="-I$sysroot/include"
+    export LDFLAGS="-L$sysroot/lib"
+    export SDL_LIBS="-lSDL2 -lorbital $("${PKG_CONFIG}" --libs glu) -lglapi -lz -lm -lpthread -lstdc++"
+    ./configure --prefix=/ --build=${BUILD} --host=${HOST} --disable-shared --disable-sdltest --enable-png --enable-jpg
+    make -j"$(nproc)"
+    skip=1
+}
+
+function recipe_test {
+    echo "skipping test"
+    skip=1
+}
+
+function recipe_clean {
+    make clean
+    skip=1
+}
+
+function recipe_stage {
+    dest="$(realpath $1)"
+    make DESTDIR="$dest" install
+    rm -f "$dest/lib/"*.la
+    skip=1
+}
diff --git a/recipes/sdl2_mixer/recipe.sh b/recipes/sdl2_mixer/recipe.sh
new file mode 100644
index 0000000000000000000000000000000000000000..ad54075b8891d616bac8a4f1e08197c5303cbbbb
--- /dev/null
+++ b/recipes/sdl2_mixer/recipe.sh
@@ -0,0 +1,51 @@
+VERSION=2.0.4
+TAR=https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-$VERSION.tar.gz
+BUILD_DEPENDS=(sdl2 liborbital llvm mesa mesa_glu zlib)
+
+function recipe_version {
+    echo "$VERSION"
+    skip=1
+}
+
+function recipe_update {
+    echo "skipping update"
+    skip=1
+}
+
+function recipe_build {
+    sysroot="$(realpath ../sysroot)"
+    export CFLAGS="-I$sysroot/include"
+    export LDFLAGS="-L$sysroot/lib"
+    export SDL_LIBS="-lSDL2 -lorbital $("${PKG_CONFIG}" --libs glu) -lglapi -lz -lm -lpthread -lstdc++"
+    ./autogen.sh
+    ./configure \
+        --prefix=/ \
+        --build=${BUILD} \
+        --host=${HOST} \
+        --disable-shared \
+        --disable-sdltest \
+        --disable-music-cmd \
+        --disable-music-mp3 \
+        --disable-smpegtest \
+        --disable-music-midi \
+        --disable-music-mod
+    make -j"$(nproc)"
+    skip=1
+}
+
+function recipe_test {
+    echo "skipping test"
+    skip=1
+}
+
+function recipe_clean {
+    make clean
+    skip=1
+}
+
+function recipe_stage {
+    dest="$(realpath $1)"
+    make DESTDIR="$dest" install
+    rm -f "$dest/lib/"*.la
+    skip=1
+}
diff --git a/recipes/sdl2_ttf/recipe.sh b/recipes/sdl2_ttf/recipe.sh
new file mode 100644
index 0000000000000000000000000000000000000000..c1a942b20bb247cfcb3bacd022ca2335985b5396
--- /dev/null
+++ b/recipes/sdl2_ttf/recipe.sh
@@ -0,0 +1,41 @@
+VERSION=2.0.15
+TAR=https://www.libsdl.org/projects/SDL_ttf/release/SDL2_ttf-$VERSION.tar.gz
+BUILD_DEPENDS=(sdl2 liborbital llvm mesa mesa_glu freetype libpng zlib)
+
+function recipe_version {
+    echo "$VERSION"
+    skip=1
+}
+
+function recipe_update {
+    echo "skipping update"
+    skip=1
+}
+
+function recipe_build {
+    sysroot="$(realpath ../sysroot)"
+    export CFLAGS="-I$sysroot/include"
+    export LDFLAGS="-L$sysroot/lib"
+    export SDL_LIBS="-lSDL2 -lorbital $("${PKG_CONFIG}" --libs glu) -lglapi -lz -lm -lpthread -lstdc++"
+    ./autogen.sh
+    ./configure --prefix=/ --build=${BUILD} --host=${HOST} --enable-opengl --disable-shared --disable-sdltest
+    make -j"$(nproc)"
+    skip=1
+}
+
+function recipe_test {
+    echo "skipping test"
+    skip=1
+}
+
+function recipe_clean {
+    make clean
+    skip=1
+}
+
+function recipe_stage {
+    dest="$(realpath $1)"
+    make DESTDIR="$dest" install
+    rm -f "$dest/lib/"*.la
+    skip=1
+}