sdl3-doom: add SDL3 Doom

A source port of DOOM to SDL3 (raydelto/sdl3_doom), the first real SDL3
application in the feed, replacing the orphaned sdl2-doom. It builds
against libsdl3 and libsdl3-mixer and plays authentic OPL FM music from
the IWAD's GENMIDI lump, needing no soundfont.

The upstream port targets an early SDL3_mixer prerelease (Mix_* API,
removed in SDL_mixer 3.2.0) and had dropped the OPL music backend. Carry
nine patches: port both audio backends to the track-based MIX_* API,
share a single mixer device, link the exported SDL3 CMake targets, build
the sound-effect module (FEATURE_SOUND), restore the Chocolate DOOM OPL
backend for native FM music, fix a pre-existing status-bar crash and drop
the stale SDL2_mixer cmake module. These are also suitable to submit
upstream.

https://github.com/raydelto/sdl3_doom
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
This commit is contained in:
Daniel Golle
2026-06-10 00:27:11 +01:00
parent 6dc81a7a4d
commit ed0ecdeb13
10 changed files with 9109 additions and 0 deletions
+44
View File
@@ -0,0 +1,44 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=sdl3-doom
PKG_SOURCE_DATE:=2025-01-26
PKG_RELEASE:=1
PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/raydelto/sdl3_doom
PKG_SOURCE_VERSION:=b271b6d72900d18ee3ef34c1608fe7e20a0c0ad3
PKG_MIRROR_HASH:=0d65720a1d68e63721cca360ebc2614fc2ad2e624df1e60a293a24ce67279373
PKG_MAINTAINER:=Daniel Golle <daniel@makrotopia.org>
PKG_LICENSE:=GPL-2.0-or-later
PKG_LICENSE_FILES:=License.md
PKG_BUILD_FLAGS:=gc-sections lto
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
define Package/sdl3-doom
SECTION:=games
CATEGORY:=Games
TITLE:=SDL3 Doom
URL:=https://github.com/raydelto/sdl3_doom
DEPENDS:=+libstdcpp +libsdl3 +libsdl3-mixer
endef
define Package/sdl3-doom/description
This is a source port of the ID Software source release of DOOM to SDL3.
Using low-resolution software rendering designed in 1993 by idSoftware
for (from today's perspective) very slow CPUs it runs with good
performance even on low-end devices.
endef
define Package/sdl3-doom/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/sdl3-doom $(1)/usr/bin
endef
define Build/Install
endef
$(eval $(call BuildPackage,sdl3-doom))
@@ -0,0 +1,287 @@
From 0898b8bc17127829ea44325985e70c49c800ff21 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Tue, 9 Jun 2026 16:25:51 +0100
Subject: [PATCH] i_sdlmusic: port music backend to the SDL3_mixer 3.2 MIX_*
API
The Mix_* SDL_mixer API used by this port was removed in SDL_mixer 3.2.0.
Port the music backend to the new track-based MIX_* API: a single
MIX_Mixer device and MIX_Track, MIX_LoadAudio for songs, MIX_PlayTrack
with the MIX_PROP_PLAY_LOOPS_NUMBER property for looping, MIX_SetTrackGain
for volume and MIX_GetTrackPlaybackPosition for the substitute-music loop
points (replacing the removed post-mix effect callback).
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
src/i_sdlmusic.c | 107 ++++++++++++++++++++++++-----------------------
1 file changed, 55 insertions(+), 52 deletions(-)
--- a/src/i_sdlmusic.c
+++ b/src/i_sdlmusic.c
@@ -119,12 +119,13 @@ static char *temp_timidity_cfg = NULL;
static boolean playing_substitute = false;
static file_metadata_t file_metadata;
-// Position (in samples) that we have reached in the current track.
-// This is updated by the TrackPositionCallback function.
-static unsigned int current_track_pos;
+// SDL3_mixer mixer device and the single track used for music playback.
+static MIX_Mixer *music_mixer = NULL;
+static MIX_Track *music_track = NULL;
+static int music_freq = 44100;
// Currently playing music track.
-static Mix_Music *current_track_music = NULL;
+static MIX_Audio *current_track_music = NULL;
// If true, the currently playing track is being played on loop.
static boolean current_track_loop;
@@ -852,12 +853,16 @@ static void I_SDL_ShutdownMusic(void)
{
if (music_initialized)
{
- Mix_HaltMusic();
+ MIX_StopTrack(music_track, 0);
music_initialized = false;
if (sdl_was_initialized)
{
- Mix_CloseAudio();
+ MIX_DestroyTrack(music_track);
+ music_track = NULL;
+ MIX_DestroyMixer(music_mixer);
+ music_mixer = NULL;
+ MIX_Quit();
SDL_QuitSubSystem(SDL_INIT_AUDIO);
sdl_was_initialized = false;
}
@@ -866,17 +871,7 @@ static void I_SDL_ShutdownMusic(void)
static boolean SDLIsInitialized(void)
{
- int freq, channels;
- SDL_AudioFormat format;
-
- return Mix_QuerySpec(&freq, &format, &channels) != 0;
-}
-
-// Callback function that is invoked to track current track position.
-void TrackPositionCallback(int chan, void *stream, int len, void *udata)
-{
- // Position is doubled up twice: for 16-bit samples and for stereo.
- current_track_pos += len / 4;
+ return music_mixer != NULL;
}
// Initialize music subsystem
@@ -928,20 +923,29 @@ static boolean I_SDL_InitMusic(void)
}
else
{
- const SDL_AudioSpec spec = {SDL_AUDIO_S16, 2, 1024};
+ const SDL_AudioSpec spec = {SDL_AUDIO_S16, 2, 44100};
if (!SDL_Init(SDL_INIT_AUDIO))
{
fprintf(stderr, "Unable to set up sound.\n");
}
- else if (!Mix_OpenAudio(0, &spec))
+ else if (!MIX_Init())
{
- fprintf(stderr, "Error initializing SDL_mixer: %s\n",
+ fprintf(stderr, "Error initializing SDL3_mixer: %s\n",
SDL_GetError());
SDL_QuitSubSystem(SDL_INIT_AUDIO);
}
+ else if (!(music_mixer = MIX_CreateMixerDevice(
+ SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec)))
+ {
+ fprintf(stderr, "Error initializing SDL3_mixer: %s\n",
+ SDL_GetError());
+ MIX_Quit();
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ }
else
{
- Mix_PauseAudio(0);
+ music_track = MIX_CreateTrack(music_mixer);
+ music_freq = spec.freq;
sdl_was_initialized = true;
music_initialized = true;
@@ -961,9 +965,6 @@ static boolean I_SDL_InitMusic(void)
fprintf(stderr, "SDL3_Mixer does not support external music playback.\n");
}
- // Register an effect function to track the music position.
- Mix_RegisterEffect(MIX_CHANNEL_POST, TrackPositionCallback, NULL, NULL);
-
// If we're in GENMIDI mode, try to load sound packs.
if (snd_musicdevice == SNDDEVICE_GENMIDI)
{
@@ -980,18 +981,18 @@ static boolean I_SDL_InitMusic(void)
static void UpdateMusicVolume(void)
{
- int vol;
+ float gain;
if (musicpaused)
{
- vol = 0;
+ gain = 0.0f;
}
else
{
- vol = (current_music_volume * MIX_MAX_VOLUME) / 127;
+ gain = (float) current_music_volume / 127.0f;
}
- Mix_VolumeMusic(vol);
+ MIX_SetTrackGain(music_track, gain);
}
// Set music volume (0 - 127)
@@ -1020,7 +1021,7 @@ static void I_SDL_PlaySong(void *handle,
return;
}
- current_track_music = (Mix_Music *) handle;
+ current_track_music = (MIX_Audio *) handle;
current_track_loop = looping;
if (looping)
@@ -1029,18 +1030,23 @@ static void I_SDL_PlaySong(void *handle,
}
else
{
- loops = 1;
+ loops = 0;
}
// Don't loop when playing substitute music, as we do it
// ourselves instead.
if (playing_substitute && file_metadata.valid)
{
- loops = 1;
- current_track_pos = 0; // start of track
+ loops = 0;
}
- Mix_PlayMusic(current_track_music, loops);
+ {
+ SDL_PropertiesID opts = SDL_CreateProperties();
+ SDL_SetNumberProperty(opts, MIX_PROP_PLAY_LOOPS_NUMBER, loops);
+ MIX_SetTrackAudio(music_track, current_track_music);
+ MIX_PlayTrack(music_track, opts);
+ SDL_DestroyProperties(opts);
+ }
}
static void I_SDL_PauseSong(void)
@@ -1074,14 +1080,14 @@ static void I_SDL_StopSong(void)
return;
}
- Mix_HaltMusic();
+ MIX_StopTrack(music_track, 0);
playing_substitute = false;
current_track_music = NULL;
}
static void I_SDL_UnRegisterSong(void *handle)
{
- Mix_Music *music = (Mix_Music *) handle;
+ MIX_Audio *music = (MIX_Audio *) handle;
if (!music_initialized)
{
@@ -1093,7 +1099,7 @@ static void I_SDL_UnRegisterSong(void *h
return;
}
- Mix_FreeMusic(music);
+ MIX_DestroyAudio(music);
}
// Determine whether memory block is a .mid file
@@ -1132,7 +1138,7 @@ static boolean ConvertMus(byte *musdata,
static void *I_SDL_RegisterSong(void *data, int len)
{
char *filename;
- Mix_Music *music;
+ MIX_Audio *music;
if (!music_initialized)
{
@@ -1146,7 +1152,7 @@ static void *I_SDL_RegisterSong(void *da
if (filename != NULL)
{
- music = Mix_LoadMUS(filename);
+ music = MIX_LoadAudio(music_mixer, filename, false);
if (music == NULL)
{
@@ -1185,7 +1191,7 @@ static void *I_SDL_RegisterSong(void *da
// by now, but Mix_SetMusicCMD() only works with Mix_LoadMUS(), so
// we have to generate a temporary file.
- music = Mix_LoadMUS(filename);
+ music = MIX_LoadAudio(music_mixer, filename, false);
if (music == NULL)
{
@@ -1217,19 +1223,13 @@ static boolean I_SDL_MusicIsPlaying(void
return false;
}
- return Mix_PlayingMusic();
+ return MIX_TrackPlaying(music_track);
}
// Get position in substitute music track, in seconds since start of track.
static double GetMusicPosition(void)
{
- unsigned int music_pos;
- int freq;
-
- Mix_QuerySpec(&freq, NULL, NULL);
- music_pos = current_track_pos;
-
- return (double) music_pos / freq;
+ return (double) MIX_GetTrackPlaybackPosition(music_track) / music_freq;
}
static void RestartCurrentTrack(void)
@@ -1244,15 +1244,18 @@ static void RestartCurrentTrack(void)
// If the track finished we need to restart it.
if (current_track_music != NULL)
{
- Mix_PlayMusic(current_track_music, 1);
+ SDL_PropertiesID opts = SDL_CreateProperties();
+ SDL_SetNumberProperty(opts, MIX_PROP_PLAY_LOOPS_NUMBER, 0);
+ MIX_SetTrackAudio(music_track, current_track_music);
+ MIX_PlayTrack(music_track, opts);
+ SDL_DestroyProperties(opts);
}
- Mix_SetMusicPosition(start);
- current_track_pos = file_metadata.start_time;
+ MIX_SetTrackPlaybackPosition(music_track, (Sint64) (start * music_freq));
}
else
{
- Mix_HaltMusic();
+ MIX_StopTrack(music_track, 0);
current_track_music = NULL;
playing_substitute = false;
}
@@ -1274,7 +1277,7 @@ static void I_SDL_PollMusic(void)
}
// Have we reached the actual end of track (not loop end)?
- if (!Mix_PlayingMusic() && current_track_loop)
+ if (!MIX_TrackPlaying(music_track) && current_track_loop)
{
RestartCurrentTrack();
}
@@ -0,0 +1,27 @@
From 9accc179f21c54a0ca552617dff243d9fdc3e1bf Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Tue, 9 Jun 2026 16:31:56 +0100
Subject: [PATCH] cmake: link against the exported SDL3 and SDL3_mixer targets
The link line referenced ${SDL3_LIBRARIES} and ${SDL3_mixer_LIBRARIES},
variables that the SDL3 / SDL3_mixer 3.2 CMake config packages do not
define. As a result the executable failed to link with a long list of
undefined references to the SDL and MIX_* symbols.
The config packages instead export the imported targets SDL3::SDL3 and
SDL3_mixer::SDL3_mixer (which also carry the correct include directories
and transitive dependencies). Link against those.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
CMakeLists.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,4 +21,4 @@ add_executable(sdl3-doom src/i_main.c sr
src/r_sky.c src/r_things.c src/sha1.c src/sounds.c src/statdump.c src/st_lib.c src/st_stuff.c src/s_sound.c src/tables.c
src/v_video.c src/wi_stuff.c src/w_checksum.c src/w_file.c src/w_main.c src/w_wad.c src/z_zone.c src/w_file_stdc.c )
-target_link_libraries(sdl3-doom PRIVATE ${SDL3_LIBRARIES} ${SDL3_mixer_LIBRARIES})
+target_link_libraries(sdl3-doom PRIVATE SDL3::SDL3 SDL3_mixer::SDL3_mixer)
@@ -0,0 +1,389 @@
From 729b82f23169b13b990a0799d6f7b2b1148fb431 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Tue, 9 Jun 2026 16:32:14 +0100
Subject: [PATCH] i_sdlsound: port SFX backend to the SDL3_mixer 3.2 MIX_* API
The Mix_* SDL_mixer API used by this port was removed in SDL_mixer 3.2.0.
Port the sound-effects backend to the new track-based MIX_* API,
mirroring the music backend port.
The fixed pool of 16 mixer channels becomes a pool of 16 MIX_Track
objects rendered by a single MIX_Mixer device. The per-sound Mix_Chunk
embedded in the sound cache is replaced by a raw PCM buffer plus a
MIX_Audio handle wrapping it:
- struct allocated_sound_s: drop Mix_Chunk chunk; add byte *abuf,
Uint32 alen and MIX_Audio *audio.
- AllocateSound() now returns allocated_sound_t* and only sets up the
raw buffer (abuf/alen, audio = NULL); the converted-PCM writers
(ExpandSoundData_SRC / ExpandSoundData_SDL) write into snd->abuf and
then call the new FinishSound() which wraps the buffer with
MIX_LoadRawAudio(sound_mixer, abuf, alen, &spec). FreeAllocatedSound()
releases it with MIX_DestroyAudio().
- I_SDL_InitSound: Mix_OpenAudio() -> MIX_Init() +
MIX_CreateMixerDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec); the
mixer_freq/format/channels formerly read back via Mix_QuerySpec() are
taken from the spec; Mix_AllocateChannels() becomes a loop of
MIX_CreateTrack(); Mix_PauseAudio() and the SDL_mixer <= 1.2.8
Mix_SetPanning workaround are dropped.
- I_SDL_ShutdownSound: destroy the tracks, MIX_DestroyMixer() and
MIX_Quit() (replacing Mix_CloseAudio()).
- I_SDL_StartSound: Mix_PlayChannelTimed() -> MIX_SetTrackAudio() +
MIX_PlayTrack(track, 0).
- I_SDL_StopSound: Mix_HaltChannel() -> MIX_StopTrack(track, 0).
- I_SDL_SoundIsPlaying: Mix_Playing() -> MIX_TrackPlaying().
- I_SDL_UpdateSoundParams: Mix_SetPanning(left, right) (0..255) ->
MIX_SetTrackStereo() with a MIX_StereoGains of left/255 and right/255.
MIX_MAX_VOLUME is gone; gains are floats in 0.0..1.0. GetSliceSize() is
removed as the new mixer device spec takes a sample rate, not a slice
size, and the function had no other users.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
src/i_sdlsound.c | 173 +++++++++++++++++++++++------------------------
1 file changed, 83 insertions(+), 90 deletions(-)
--- a/src/i_sdlsound.c
+++ b/src/i_sdlsound.c
@@ -51,15 +51,18 @@ typedef struct allocated_sound_s allocat
struct allocated_sound_s
{
sfxinfo_t *sfxinfo;
- Mix_Chunk chunk;
+ byte *abuf;
+ Uint32 alen;
+ MIX_Audio *audio;
int use_count;
allocated_sound_t *prev, *next;
};
-static boolean setpanning_workaround = false;
-
static boolean sound_initialized = false;
+static MIX_Mixer *sound_mixer = NULL;
+static MIX_Track *sound_tracks[NUM_CHANNELS];
+
static sfxinfo_t *channels_playing[NUM_CHANNELS];
static int mixer_freq;
@@ -143,7 +146,12 @@ static void FreeAllocatedSound(allocated
// Keep track of the amount of allocated sound data:
- allocated_sounds_size -= snd->chunk.alen;
+ allocated_sounds_size -= snd->alen;
+
+ if (snd->audio != NULL)
+ {
+ MIX_DestroyAudio(snd->audio);
+ }
free(snd);
}
@@ -201,7 +209,7 @@ static void ReserveCacheSpace(size_t len
// Allocate a block for a new sound effect.
-static Mix_Chunk *AllocateSound(sfxinfo_t *sfxinfo, size_t len)
+static allocated_sound_t *AllocateSound(sfxinfo_t *sfxinfo, size_t len)
{
allocated_sound_t *snd;
@@ -226,12 +234,11 @@ static Mix_Chunk *AllocateSound(sfxinfo_
} while (snd == NULL);
- // Skip past the chunk structure for the audio buffer
+ // The audio buffer immediately follows the structure header.
- snd->chunk.abuf = (byte *) (snd + 1);
- snd->chunk.alen = len;
- snd->chunk.allocated = 1;
- snd->chunk.volume = MIX_MAX_VOLUME;
+ snd->abuf = (byte *) (snd + 1);
+ snd->alen = len;
+ snd->audio = NULL;
snd->sfxinfo = sfxinfo;
snd->use_count = 0;
@@ -246,7 +253,25 @@ static Mix_Chunk *AllocateSound(sfxinfo_
AllocatedSoundLink(snd);
- return &snd->chunk;
+ return snd;
+}
+
+// Wrap the converted PCM buffer of an allocated sound in a MIX_Audio
+// object so that it can be assigned to a track and played back.
+
+static boolean FinishSound(allocated_sound_t *snd)
+{
+ const SDL_AudioSpec spec = {mixer_format, mixer_channels, mixer_freq};
+
+ snd->audio = MIX_LoadRawAudio(sound_mixer, snd->abuf, snd->alen, &spec);
+
+ if (snd->audio == NULL)
+ {
+ fprintf(stderr, "FinishSound: %s\n", SDL_GetError());
+ return false;
+ }
+
+ return true;
}
// Lock a sound, to indicate that it may not be freed.
@@ -344,7 +369,7 @@ static boolean ExpandSoundData_SRC(sfxin
uint32_t alen;
int retn;
int16_t *expanded;
- Mix_Chunk *chunk;
+ allocated_sound_t *snd;
src_data.input_frames = length;
src_data.data_in = malloc(length * sizeof(float));
@@ -375,14 +400,14 @@ static boolean ExpandSoundData_SRC(sfxin
alen = src_data.output_frames_gen * 4;
- chunk = AllocateSound(sfxinfo, src_data.output_frames_gen * 4);
+ snd = AllocateSound(sfxinfo, src_data.output_frames_gen * 4);
- if (chunk == NULL)
+ if (snd == NULL)
{
return false;
}
- expanded = (int16_t *) chunk->abuf;
+ expanded = (int16_t *) snd->abuf;
// Convert the result back into 16-bit integers.
@@ -436,12 +461,12 @@ static boolean ExpandSoundData_SRC(sfxin
if (clipped > 0)
{
- fprintf(stderr, "Sound '%s': clipped %u samples (%0.2f %%)\n",
+ fprintf(stderr, "Sound '%s': clipped %u samples (%0.2f %%)\n",
sfxinfo->name, clipped,
- 400.0 * clipped / chunk->alen);
+ 400.0 * clipped / snd->alen);
}
- return true;
+ return FinishSound(snd);
}
#endif
@@ -533,10 +558,10 @@ static boolean ExpandSoundData_SDL(sfxin
int samplerate,
int length)
{
- Mix_Chunk *chunk;
+ allocated_sound_t *snd;
uint32_t expanded_length;
-
- // Calculate the length of the expanded version of the sample.
+
+ // Calculate the length of the expanded version of the sample.
expanded_length = (uint32_t) ((((uint64_t) length) * mixer_freq) / samplerate);
@@ -546,15 +571,15 @@ static boolean ExpandSoundData_SDL(sfxin
// Allocate a chunk in which to expand the sound
- chunk = AllocateSound(sfxinfo, expanded_length);
+ snd = AllocateSound(sfxinfo, expanded_length);
- if (chunk == NULL)
+ if (snd == NULL)
{
return false;
}
// If we can, use the standard / optimized SDL conversion routines.
- Sint16 *expanded = (Sint16 *) chunk->abuf;
+ Sint16 *expanded = (Sint16 *) snd->abuf;
int expand_ratio;
int i;
@@ -614,7 +639,7 @@ static boolean ExpandSoundData_SDL(sfxin
}
#endif /* #ifdef LOW_PASS_FILTER */
- return true;
+ return FinishSound(snd);
}
// Load and convert a sound effect
@@ -814,17 +839,9 @@ static void I_SDL_UpdateSoundParams(int
if (right < 0) right = 0;
else if (right > 255) right = 255;
- // SDL_mixer version 1.2.8 and earlier has a bug in the Mix_SetPanning
- // function. A workaround is to call Mix_UnregisterAllEffects for
- // the channel before calling it. This is undesirable as it may lead
- // to the channel volumes resetting briefly.
-
- if (setpanning_workaround)
- {
- Mix_UnregisterAllEffects(handle);
- }
+ MIX_StereoGains gains = {left / 255.0f, right / 255.0f};
- Mix_SetPanning(handle, left, right);
+ MIX_SetTrackStereo(sound_tracks[handle], &gains);
}
//
@@ -865,7 +882,8 @@ static int I_SDL_StartSound(sfxinfo_t *s
// play sound
- Mix_PlayChannelTimed(channel, &snd->chunk, 0, -1);
+ MIX_SetTrackAudio(sound_tracks[channel], snd->audio);
+ MIX_PlayTrack(sound_tracks[channel], 0);
channels_playing[channel] = sfxinfo;
@@ -883,7 +901,7 @@ static void I_SDL_StopSound(int handle)
return;
}
- Mix_HaltChannel(handle);
+ MIX_StopTrack(sound_tracks[handle], 0);
// Sound data is no longer needed; release the
// sound data being used for this channel
@@ -899,7 +917,7 @@ static boolean I_SDL_SoundIsPlaying(int
return false;
}
- return Mix_Playing(handle);
+ return MIX_TrackPlaying(sound_tracks[handle]);
}
//
@@ -926,42 +944,25 @@ static void I_SDL_UpdateSound(void)
static void I_SDL_ShutdownSound(void)
{
+ int i;
+
if (!sound_initialized)
{
return;
}
- Mix_CloseAudio();
- SDL_QuitSubSystem(SDL_INIT_AUDIO);
-
- sound_initialized = false;
-}
-
-// Calculate slice size, based on snd_maxslicetime_ms.
-// The result must be a power of two.
-
-static int GetSliceSize(void)
-{
- int limit;
- int n;
-
- limit = (snd_samplerate * snd_maxslicetime_ms) / 1000;
-
- // Try all powers of two, not exceeding the limit.
-
- for (n=0;; ++n)
+ for (i = 0; i < NUM_CHANNELS; ++i)
{
- // 2^n <= limit < 2^n+1 ?
-
- if ((1 << (n + 1)) > limit)
- {
- return (1 << n);
- }
+ MIX_DestroyTrack(sound_tracks[i]);
+ sound_tracks[i] = NULL;
}
- // Should never happen?
+ MIX_DestroyMixer(sound_mixer);
+ sound_mixer = NULL;
+ MIX_Quit();
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
- return 1024;
+ sound_initialized = false;
}
static boolean I_SDL_InitSound(boolean _use_sfx_prefix)
@@ -982,17 +983,28 @@ static boolean I_SDL_InitSound(boolean _
fprintf(stderr, "Unable to set up sound.\n");
return false;
}
- const SDL_AudioSpec spec = {SDL_AUDIO_S16, 2, GetSliceSize()};
+ const SDL_AudioSpec spec = {SDL_AUDIO_S16, 2, snd_samplerate};
+
+ if (!MIX_Init())
+ {
+ fprintf(stderr, "Error initialising SDL3_mixer: %s\n", SDL_GetError());
+ return false;
+ }
+
+ sound_mixer = MIX_CreateMixerDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec);
- if (!Mix_OpenAudio(0, &spec))
+ if (sound_mixer == NULL)
{
- fprintf(stderr, "Error initialising SDL_mixer: %s\n", SDL_GetError());
+ fprintf(stderr, "Error initialising SDL3_mixer: %s\n", SDL_GetError());
+ MIX_Quit();
return false;
}
ExpandSoundData = ExpandSoundData_SDL;
- Mix_QuerySpec(&mixer_freq, &mixer_format, &mixer_channels);
+ mixer_freq = spec.freq;
+ mixer_format = spec.format;
+ mixer_channels = spec.channels;
#ifdef HAVE_LIBSAMPLERATE
if (use_libsamplerate != 0)
@@ -1014,30 +1026,11 @@ static boolean I_SDL_InitSound(boolean _
}
#endif
- // SDL_mixer version 1.2.8 and earlier has a bug in the Mix_SetPanning
- // function that can cause the game to lock up. If we're using an old
- // version, we need to apply a workaround. But the workaround has its
- // own drawbacks ...
-
+ for (i = 0; i < NUM_CHANNELS; ++i)
{
- int v = SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_MICRO_VERSION);
-
- if (v <= SDL_VERSIONNUM(1, 2, 8))
- {
- setpanning_workaround = true;
- fprintf(stderr, "\n"
- "ATTENTION: You are using an old version of SDL_mixer!\n"
- " This version has a bug that may cause "
- "your sound to stutter.\n"
- " Please upgrade to a newer version!\n"
- "\n");
- }
+ sound_tracks[i] = MIX_CreateTrack(sound_mixer);
}
- Mix_AllocateChannels(NUM_CHANNELS);
-
- Mix_PauseAudio(0);
-
sound_initialized = true;
return true;
@@ -0,0 +1,332 @@
From 586e123b3d64025739c6eef8e3f16c1091166150 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Tue, 9 Jun 2026 17:06:08 +0100
Subject: [PATCH] i_sound: share a single SDL3_mixer device between music and
SFX
The SDL2_mixer build opened one audio device with Mix_OpenAudio() that
was shared by music and every sound effect channel. The port to the
SDL3_mixer 3.2 MIX_* API instead created two independent mixers, one in
i_sdlmusic.c (music_mixer) and one in i_sdlsound.c (sound_mixer), each
via its own MIX_CreateMixerDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK).
That opens two separate output streams on the default device and leaves
both backends independently calling SDL_Init(SDL_INIT_AUDIO), MIX_Init()
and, on shutdown, MIX_Quit() plus SDL_QuitSubSystem(); whichever backend
shuts down first tears the mixer library out from under the other.
Introduce a small reference-counted helper, i_sdlmixer, that owns one
MIX_Mixer on the default playback device. Both backends acquire it on
init and release it on shutdown, so the device, MIX_Init() and the audio
subsystem are set up once and torn down once. Each backend keeps its own
MIX_Track(s) on the shared mixer, which matches the canonical SDL3_mixer
model of one mixer feeding many tracks.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
CMakeLists.txt | 4 +-
include/i_sdlmixer.h | 29 +++++++++++++++
src/i_sdlmixer.c | 87 ++++++++++++++++++++++++++++++++++++++++++++
src/i_sdlmusic.c | 65 +++++++--------------------------
src/i_sdlsound.c | 28 +++-----------
5 files changed, 138 insertions(+), 75 deletions(-)
create mode 100644 include/i_sdlmixer.h
create mode 100644 src/i_sdlmixer.c
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,8 +12,8 @@ include_directories(${SDL3_MIXER_INCLUDE
add_definitions(-Wall -D_REENTRANT -D_THREAD_SAFE)
add_executable(sdl3-doom src/i_main.c src/dummy.c src/am_map.c src/doomdef.c src/doomstat.c src/dstrings.c src/d_event.c
src/d_items.c src/d_iwad.c src/d_loop.c src/d_main.c src/d_mode.c src/d_net.c src/f_finale.c src/f_wipe.c src/g_game.c src/hu_lib.c
- src/hu_stuff.c src/info.c src/i_cdmus.c src/i_endoom.c src/i_joystick.c src/i_scale.c src/i_sound.c src/i_sdlmusic.c
- src/i_sdlsound.c src/i_system.c src/i_timer.c src/i_input.c src/i_video.c src/mus2mid.c src/memio.c src/m_argv.c
+ src/hu_stuff.c src/info.c src/i_cdmus.c src/i_endoom.c src/i_joystick.c src/i_scale.c src/i_sound.c src/i_sdlmixer.c src/i_sdlmusic.c
+ src/i_sdlsound.c src/i_system.c src/i_timer.c src/i_input.c src/i_video.c src/mus2mid.c src/memio.c src/m_argv.c
src/m_bbox.c src/m_cheat.c src/m_config.c src/m_controls.c src/m_fixed.c src/m_menu.c src/m_misc.c src/m_random.c
src/p_ceilng.c src/p_doors.c src/p_enemy.c src/p_floor.c src/p_inter.c src/p_lights.c src/p_map.c src/p_maputl.c
src/p_mobj.c src/p_plats.c src/p_pspr.c src/p_saveg.c src/p_setup.c src/p_sight.c src/p_spec.c src/p_switch.c
--- /dev/null
+++ b/include/i_sdlmixer.h
@@ -0,0 +1,29 @@
+//
+// Copyright(C) 1993-1996 Id Software, Inc.
+// Copyright(C) 2005-2014 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// DESCRIPTION:
+// Shared SDL3_mixer device, used by both the music and sound
+// effect backends.
+//
+
+#ifndef __I_SDLMIXER__
+#define __I_SDLMIXER__
+
+#include "SDL3_mixer/SDL_mixer.h"
+#include "doomtype.h"
+
+MIX_Mixer *I_SDLMixer_Acquire(void);
+void I_SDLMixer_Release(void);
+
+#endif
--- /dev/null
+++ b/src/i_sdlmixer.c
@@ -0,0 +1,87 @@
+//
+// Copyright(C) 1993-1996 Id Software, Inc.
+// Copyright(C) 2005-2014 Simon Howard
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// DESCRIPTION:
+// Shared SDL3_mixer device, used by both the music and sound
+// effect backends.
+//
+
+#include <stdio.h>
+
+#include "SDL3/SDL.h"
+#include "SDL3_mixer/SDL_mixer.h"
+
+#include "i_sdlmixer.h"
+#include "i_sound.h"
+
+static MIX_Mixer *shared_mixer = NULL;
+static int mixer_refcount = 0;
+
+MIX_Mixer *I_SDLMixer_Acquire(void)
+{
+ if (shared_mixer != NULL)
+ {
+ ++mixer_refcount;
+ return shared_mixer;
+ }
+
+ if (!SDL_Init(SDL_INIT_AUDIO))
+ {
+ fprintf(stderr, "Unable to set up sound.\n");
+ return NULL;
+ }
+
+ if (!MIX_Init())
+ {
+ fprintf(stderr, "Error initialising SDL3_mixer: %s\n", SDL_GetError());
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ return NULL;
+ }
+
+ const SDL_AudioSpec spec = {SDL_AUDIO_S16, 2, snd_samplerate};
+
+ shared_mixer = MIX_CreateMixerDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec);
+
+ if (shared_mixer == NULL)
+ {
+ fprintf(stderr, "Error initialising SDL3_mixer: %s\n", SDL_GetError());
+ MIX_Quit();
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ return NULL;
+ }
+
+ mixer_refcount = 1;
+
+ return shared_mixer;
+}
+
+void I_SDLMixer_Release(void)
+{
+ if (mixer_refcount <= 0)
+ {
+ return;
+ }
+
+ --mixer_refcount;
+
+ if (mixer_refcount > 0)
+ {
+ return;
+ }
+
+ MIX_DestroyMixer(shared_mixer);
+ shared_mixer = NULL;
+ MIX_Quit();
+ SDL_QuitSubSystem(SDL_INIT_AUDIO);
+}
--- a/src/i_sdlmusic.c
+++ b/src/i_sdlmusic.c
@@ -31,6 +31,7 @@
#include "deh_str.h"
#include "gusconf.h"
+#include "i_sdlmixer.h"
#include "i_sound.h"
#include "i_system.h"
#include "i_swap.h"
@@ -102,11 +103,6 @@ static const char *subst_config_filename
static boolean music_initialized = false;
-// If this is true, this module initialized SDL sound and has the
-// responsibility to shut it down
-
-static boolean sdl_was_initialized = false;
-
static boolean musicpaused = false;
static int current_music_volume;
@@ -856,24 +852,13 @@ static void I_SDL_ShutdownMusic(void)
MIX_StopTrack(music_track, 0);
music_initialized = false;
- if (sdl_was_initialized)
- {
- MIX_DestroyTrack(music_track);
- music_track = NULL;
- MIX_DestroyMixer(music_mixer);
- music_mixer = NULL;
- MIX_Quit();
- SDL_QuitSubSystem(SDL_INIT_AUDIO);
- sdl_was_initialized = false;
- }
+ MIX_DestroyTrack(music_track);
+ music_track = NULL;
+ music_mixer = NULL;
+ I_SDLMixer_Release();
}
}
-static boolean SDLIsInitialized(void)
-{
- return music_mixer != NULL;
-}
-
// Initialize music subsystem
static boolean I_SDL_InitMusic(void)
{
@@ -914,42 +899,20 @@ static boolean I_SDL_InitMusic(void)
DumpSubstituteConfig(myargv[i + 1]);
}
- // If SDL_mixer is not initialized, we have to initialize it
- // and have the responsibility to shut it down later on.
+ music_mixer = I_SDLMixer_Acquire();
- if (SDLIsInitialized())
- {
- music_initialized = true;
- }
- else
+ if (music_mixer != NULL)
{
- const SDL_AudioSpec spec = {SDL_AUDIO_S16, 2, 44100};
- if (!SDL_Init(SDL_INIT_AUDIO))
- {
- fprintf(stderr, "Unable to set up sound.\n");
- }
- else if (!MIX_Init())
- {
- fprintf(stderr, "Error initializing SDL3_mixer: %s\n",
- SDL_GetError());
- SDL_QuitSubSystem(SDL_INIT_AUDIO);
- }
- else if (!(music_mixer = MIX_CreateMixerDevice(
- SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec)))
- {
- fprintf(stderr, "Error initializing SDL3_mixer: %s\n",
- SDL_GetError());
- MIX_Quit();
- SDL_QuitSubSystem(SDL_INIT_AUDIO);
- }
- else
+ SDL_AudioSpec spec;
+
+ music_track = MIX_CreateTrack(music_mixer);
+
+ if (MIX_GetMixerFormat(music_mixer, &spec))
{
- music_track = MIX_CreateTrack(music_mixer);
music_freq = spec.freq;
-
- sdl_was_initialized = true;
- music_initialized = true;
}
+
+ music_initialized = true;
}
// Once initialization is complete, the temporary Timidity config
--- a/src/i_sdlsound.c
+++ b/src/i_sdlsound.c
@@ -32,6 +32,7 @@
#endif
#include "deh_str.h"
+#include "i_sdlmixer.h"
#include "i_sound.h"
#include "i_system.h"
#include "i_swap.h"
@@ -957,10 +958,8 @@ static void I_SDL_ShutdownSound(void)
sound_tracks[i] = NULL;
}
- MIX_DestroyMixer(sound_mixer);
sound_mixer = NULL;
- MIX_Quit();
- SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ I_SDLMixer_Release();
sound_initialized = false;
}
@@ -978,33 +977,18 @@ static boolean I_SDL_InitSound(boolean _
channels_playing[i] = NULL;
}
- if (!SDL_Init(SDL_INIT_AUDIO))
- {
- fprintf(stderr, "Unable to set up sound.\n");
- return false;
- }
- const SDL_AudioSpec spec = {SDL_AUDIO_S16, 2, snd_samplerate};
-
- if (!MIX_Init())
- {
- fprintf(stderr, "Error initialising SDL3_mixer: %s\n", SDL_GetError());
- return false;
- }
-
- sound_mixer = MIX_CreateMixerDevice(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &spec);
+ sound_mixer = I_SDLMixer_Acquire();
if (sound_mixer == NULL)
{
- fprintf(stderr, "Error initialising SDL3_mixer: %s\n", SDL_GetError());
- MIX_Quit();
return false;
}
ExpandSoundData = ExpandSoundData_SDL;
- mixer_freq = spec.freq;
- mixer_format = spec.format;
- mixer_channels = spec.channels;
+ mixer_freq = snd_samplerate;
+ mixer_format = SDL_AUDIO_S16;
+ mixer_channels = 2;
#ifdef HAVE_LIBSAMPLERATE
if (use_libsamplerate != 0)
@@ -0,0 +1,68 @@
From 9f4f3835a072293c185842972e713c2972fa3ec0 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Tue, 9 Jun 2026 17:06:18 +0100
Subject: [PATCH] st_stuff: fix arms widget crash from boolean width mismatch
boolean is typedef'd to the C99 bool, which is one byte wide, but the
status bar arms widgets were initialised with
(int *) &plyr->weaponowned[i+1]
and STlib_updateMultIcon() dereferences that int* to index mi->p[]. On a
one-byte bool this reads four adjacent ownership bytes as a single int,
yielding values such as 257 that index far out of the two-element arms
patch array. The result is a NULL patch passed to V_DrawPatch(), which
dereferences it and crashes; this triggers within seconds of the
attract-mode demo once the status bar is drawn.
Mirror the existing keyboxes idiom: keep an int shadow array,
st_armsowned[], updated each tick from plyr->weaponowned[], and point the
arms widgets at it. The widget then reads a correctly sized int holding 0
or 1, as it expects.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
src/st_stuff.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
--- a/src/st_stuff.c
+++ b/src/st_stuff.c
@@ -380,7 +380,10 @@ static int st_facecount = 0;
static int st_faceindex = 0;
// holds key-type for each key box on bar
-static int keyboxes[3];
+static int keyboxes[3];
+
+// holds weapon ownership (0 or 1) for each arms widget on bar
+static int st_armsowned[6];
// a random number per tick
static int st_randomnumber;
@@ -894,6 +897,12 @@ void ST_updateWidgets(void)
keyboxes[i] = i+3;
}
+ // update weapon ownership widgets
+ for (i=0;i<6;i++)
+ {
+ st_armsowned[i] = plyr->weaponowned[i+1] ? 1 : 0;
+ }
+
// refresh everything if this is him coming back to life
ST_updateFaceWidget();
@@ -1261,10 +1270,12 @@ void ST_createWidgets(void)
// weapons owned
for(i=0;i<6;i++)
{
+ st_armsowned[i] = plyr->weaponowned[i+1] ? 1 : 0;
+
STlib_initMultIcon(&w_arms[i],
ST_ARMSX+(i%3)*ST_ARMSXSPACE,
ST_ARMSY+(i/3)*ST_ARMSYSPACE,
- arms[i], (int *) &plyr->weaponowned[i+1],
+ arms[i], &st_armsowned[i],
&st_armson);
}
@@ -0,0 +1,43 @@
From d76f4e70fae478c139112f24d28a01e7f11769a4 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Tue, 9 Jun 2026 17:32:27 +0100
Subject: [PATCH] build: enable FEATURE_SOUND so the SDL sound-effect module is
built
The sound-effect backend (i_sdlsound.c, registered as sound_sdl_module)
is compiled in only when FEATURE_SOUND is defined. The legacy makefiles
pass -DFEATURE_SOUND, but the CMake build never did, so sound_modules[]
was empty, I_SDL_InitSound() was never called and the game had no sound
effects (only the music backend opened a device, which is hardcoded).
Define FEATURE_SOUND in CMakeLists.txt to match the makefiles, and fix
the now-compiled SDL_mixer include in i_sound.c to the SDL3_mixer path.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
CMakeLists.txt | 2 +-
src/i_sound.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -9,7 +9,7 @@ include_directories("/usr/local/include/
include_directories(${SDL3_INCLUDE_DIR})
include_directories(${SDL3_MIXER_INCLUDE_DIR})
-add_definitions(-Wall -D_REENTRANT -D_THREAD_SAFE)
+add_definitions(-Wall -D_REENTRANT -D_THREAD_SAFE -DFEATURE_SOUND)
add_executable(sdl3-doom src/i_main.c src/dummy.c src/am_map.c src/doomdef.c src/doomstat.c src/dstrings.c src/d_event.c
src/d_items.c src/d_iwad.c src/d_loop.c src/d_main.c src/d_mode.c src/d_net.c src/f_finale.c src/f_wipe.c src/g_game.c src/hu_lib.c
src/hu_stuff.c src/info.c src/i_cdmus.c src/i_endoom.c src/i_joystick.c src/i_scale.c src/i_sound.c src/i_sdlmixer.c src/i_sdlmusic.c
--- a/src/i_sound.c
+++ b/src/i_sound.c
@@ -19,7 +19,7 @@
#include <stdlib.h>
#ifdef FEATURE_SOUND
-#include "SDL3/SDL_mixer.h"
+#include "SDL3_mixer/SDL_mixer.h"
#endif
#include "config.h"
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,40 @@
From b649f9423125f87f63c2cdf611327547526a35b9 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Tue, 9 Jun 2026 18:30:46 +0100
Subject: [PATCH] build: change name to SDL3-Doom
Replace stale reference to the SDL2-Doom name.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
include/config.h | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/include/config.h
+++ b/include/config.h
@@ -70,13 +70,13 @@
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
-#define PACKAGE_NAME "SDL2-Doom"
+#define PACKAGE_NAME "SDL3-Doom"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "SDL2-Doom"
+#define PACKAGE_STRING "SDL3-Doom"
/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "sdl2-doom.tar"
+#define PACKAGE_TARNAME "sdl3-doom.tar"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
@@ -85,7 +85,7 @@
#define PACKAGE_VERSION 0.1
/* Change this when you create your awesome forked version */
-#define PROGRAM_PREFIX "sdl2-doom"
+#define PROGRAM_PREFIX "sdl3-doom"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
@@ -0,0 +1,240 @@
From 1c8bcca4ffe4b58bce9643a785d4590bc32a40a8 Mon Sep 17 00:00:00 2001
From: Daniel Golle <daniel@makrotopia.org>
Date: Tue, 9 Jun 2026 18:35:56 +0100
Subject: [PATCH] cmake: drop the unused SDL2_mixer find module
cmake/sdl2/FindSDL2_mixer.cmake is left over from the SDL2 era. The
build uses find_package(SDL3_mixer) and the SDL3_mixer::SDL3_mixer
imported target, and nothing references this module (no CMAKE_MODULE_PATH
points at cmake/sdl2), so remove it.
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
---
cmake/sdl2/FindSDL2_mixer.cmake | 220 --------------------------------
1 file changed, 220 deletions(-)
delete mode 100644 cmake/sdl2/FindSDL2_mixer.cmake
--- a/cmake/sdl2/FindSDL2_mixer.cmake
+++ /dev/null
@@ -1,220 +0,0 @@
-# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
-# file Copyright.txt or https://cmake.org/licensing for details.
-
-# Copyright 2019 Amine Ben Hassouna <amine.benhassouna@gmail.com>
-# Copyright 2000-2019 Kitware, Inc. and Contributors
-# All rights reserved.
-
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in the
-# documentation and/or other materials provided with the distribution.
-
-# * Neither the name of Kitware, Inc. nor the names of Contributors
-# may be used to endorse or promote products derived from this
-# software without specific prior written permission.
-
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#[=======================================================================[.rst:
-FindSDL2_mixer
---------------
-
-Locate SDL2_mixer library
-
-This module defines the following 'IMPORTED' target:
-
-::
-
- SDL2::Mixer
- The SDL2_mixer library, if found.
- Have SDL2::Core as a link dependency.
-
-
-
-This module will set the following variables in your project:
-
-::
-
- SDL2_MIXER_LIBRARIES, the name of the library to link against
- SDL2_MIXER_INCLUDE_DIRS, where to find the headers
- SDL2_MIXER_FOUND, if false, do not try to link against
- SDL2_MIXER_VERSION_STRING - human-readable string containing the
- version of SDL2_mixer
-
-This module responds to the following cache variables:
-
-::
-
- SDL2_MIXER_PATH
- Set a custom SDL2_mixer Library path (default: empty)
-
- SDL2_MIXER_NO_DEFAULT_PATH
- Disable search SDL2_mixer Library in default path.
- If SDL2_MIXER_PATH (default: ON)
- Else (default: OFF)
-
- SDL2_MIXER_INCLUDE_DIR
- SDL2_mixer headers path.
-
- SDL2_MIXER_LIBRARY
- SDL2_mixer Library (.dll, .so, .a, etc) path.
-
-
-Additional Note: If you see an empty SDL2_MIXER_LIBRARY in your project
-configuration, it means CMake did not find your SDL2_mixer library
-(SDL2_mixer.dll, libsdl2_mixer.so, etc). Set SDL2_MIXER_LIBRARY to point
-to your SDL2_mixer library, and configure again. This value is used to
-generate the final SDL2_MIXER_LIBRARIES variable and the SDL2::Mixer target,
-but when this value is unset, SDL2_MIXER_LIBRARIES and SDL2::Mixer does not
-get created.
-
-
-$SDL2MIXERDIR is an environment variable that would correspond to the
-./configure --prefix=$SDL2MIXERDIR used in building SDL2_mixer.
-
-$SDL2DIR is an environment variable that would correspond to the
-./configure --prefix=$SDL2DIR used in building SDL2.
-
-
-
-Created by Amine Ben Hassouna:
- Adapt FindSDL_mixer.cmake to SDL2_mixer (FindSDL2_mixer.cmake).
- Add cache variables for more flexibility:
- SDL2_MIXER_PATH, SDL2_MIXER_NO_DEFAULT_PATH (for details, see doc above).
- Add SDL2 as a required dependency.
- Modernize the FindSDL2_mixer.cmake module by creating a specific target:
- SDL2::Mixer (for details, see doc above).
-
-Original FindSDL_mixer.cmake module:
- Created by Eric Wing. This was influenced by the FindSDL.cmake
- module, but with modifications to recognize OS X frameworks and
- additional Unix paths (FreeBSD, etc).
-#]=======================================================================]
-
-# SDL2 Library required
-find_package(SDL2 QUIET)
-if(NOT SDL2_FOUND)
- set(SDL2_MIXER_SDL2_NOT_FOUND "Could NOT find SDL2 (SDL2 is required by SDL2_mixer).")
- if(SDL2_mixer_FIND_REQUIRED)
- message(FATAL_ERROR ${SDL2_MIXER_SDL2_NOT_FOUND})
- else()
- if(NOT SDL2_mixer_FIND_QUIETLY)
- message(STATUS ${SDL2_MIXER_SDL2_NOT_FOUND})
- endif()
- return()
- endif()
- unset(SDL2_MIXER_SDL2_NOT_FOUND)
-endif()
-
-
-# Define options for searching SDL2_mixer Library in a custom path
-
-set(SDL2_MIXER_PATH "" CACHE STRING "Custom SDL2_mixer Library path")
-
-set(_SDL2_MIXER_NO_DEFAULT_PATH OFF)
-if(SDL2_MIXER_PATH)
- set(_SDL2_MIXER_NO_DEFAULT_PATH ON)
-endif()
-
-set(SDL2_MIXER_NO_DEFAULT_PATH ${_SDL2_MIXER_NO_DEFAULT_PATH}
- CACHE BOOL "Disable search SDL2_mixer Library in default path")
-unset(_SDL2_MIXER_NO_DEFAULT_PATH)
-
-set(SDL2_MIXER_NO_DEFAULT_PATH_CMD)
-if(SDL2_MIXER_NO_DEFAULT_PATH)
- set(SDL2_MIXER_NO_DEFAULT_PATH_CMD NO_DEFAULT_PATH)
-endif()
-
-# Search for the SDL2_mixer include directory
-find_path(SDL2_MIXER_INCLUDE_DIR SDL_mixer.h
- HINTS
- ENV SDL2MIXERDIR
- ENV SDL2DIR
- ${SDL2_MIXER_NO_DEFAULT_PATH_CMD}
- PATH_SUFFIXES SDL2
- # path suffixes to search inside ENV{SDL2DIR}
- # and ENV{SDL2MIXERDIR}
- include/SDL2 include
- PATHS ${SDL2_MIXER_PATH}
- DOC "Where the SDL2_mixer headers can be found"
-)
-
-if(CMAKE_SIZEOF_VOID_P EQUAL 8)
- set(VC_LIB_PATH_SUFFIX lib/x64)
-else()
- set(VC_LIB_PATH_SUFFIX lib/x86)
-endif()
-
-# Search for the SDL2_mixer library
-find_library(SDL2_MIXER_LIBRARY
- NAMES SDL2_mixer
- HINTS
- ENV SDL2MIXERDIR
- ENV SDL2DIR
- ${SDL2_MIXER_NO_DEFAULT_PATH_CMD}
- PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
- PATHS ${SDL2_MIXER_PATH}
- DOC "Where the SDL2_mixer Library can be found"
-)
-
-# Read SDL2_mixer version
-if(SDL2_MIXER_INCLUDE_DIR AND EXISTS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h")
- file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+[0-9]+$")
- file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+[0-9]+$")
- file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+[0-9]+$")
- string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MAJOR "${SDL2_MIXER_VERSION_MAJOR_LINE}")
- string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MINOR "${SDL2_MIXER_VERSION_MINOR_LINE}")
- string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_PATCH "${SDL2_MIXER_VERSION_PATCH_LINE}")
- set(SDL2_MIXER_VERSION_STRING ${SDL2_MIXER_VERSION_MAJOR}.${SDL2_MIXER_VERSION_MINOR}.${SDL2_MIXER_VERSION_PATCH})
- unset(SDL2_MIXER_VERSION_MAJOR_LINE)
- unset(SDL2_MIXER_VERSION_MINOR_LINE)
- unset(SDL2_MIXER_VERSION_PATCH_LINE)
- unset(SDL2_MIXER_VERSION_MAJOR)
- unset(SDL2_MIXER_VERSION_MINOR)
- unset(SDL2_MIXER_VERSION_PATCH)
-endif()
-
-set(SDL2_MIXER_LIBRARIES ${SDL2_MIXER_LIBRARY})
-set(SDL2_MIXER_INCLUDE_DIRS ${SDL2_MIXER_INCLUDE_DIR})
-
-include(FindPackageHandleStandardArgs)
-
-FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2_mixer
- REQUIRED_VARS SDL2_MIXER_LIBRARIES SDL2_MIXER_INCLUDE_DIRS
- VERSION_VAR SDL2_MIXER_VERSION_STRING)
-
-
-mark_as_advanced(SDL2_MIXER_PATH
- SDL2_MIXER_NO_DEFAULT_PATH
- SDL2_MIXER_LIBRARY
- SDL2_MIXER_INCLUDE_DIR)
-
-
-if(SDL2_MIXER_FOUND)
-
- # SDL2::Mixer target
- if(SDL2_MIXER_LIBRARY AND NOT TARGET SDL2::Mixer)
- add_library(SDL2::Mixer UNKNOWN IMPORTED)
- set_target_properties(SDL2::Mixer PROPERTIES
- IMPORTED_LOCATION "${SDL2_MIXER_LIBRARY}"
- INTERFACE_INCLUDE_DIRECTORIES "${SDL2_MIXER_INCLUDE_DIR}"
- INTERFACE_LINK_LIBRARIES SDL2::Core)
- endif()
-endif()
\ No newline at end of file