DEADSOFTWARE

sdlmixer: more midi configuration
[d2df-sdl.git] / src / engine / e_sound_sdl.inc
index ade82620b1dd0bec1c121a52b7e43ed28b787428..f71805ef50324de7d8d9b171871d7a783605753a 100644 (file)
@@ -2,8 +2,7 @@
  *
  * 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 3 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, version 3 of the License ONLY.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 interface
 
 uses
-  sdl2,
-  SDL2_mixer,
   {$IFDEF USE_MEMPOOL}mempool,{$ENDIF}
-  e_log,
-  SysUtils;
+  {$IFDEF USE_SDL}
+    SDL, SDL_mixer,
+    {$DEFINE SDL1MIXER}
+    {$UNDEF  SDL2MIXER}
+  {$ELSE}
+    SDL2, SDL2_mixer,
+    {$UNDEF  SDL1MIXER}
+    {$DEFINE SDL2MIXER}
+  {$ENDIF}
+  envvars, e_log, SysUtils;
 
 type
   TSoundRec = record
@@ -28,6 +33,7 @@ type
     Sound: PMix_Chunk;
     Music: PMix_Music;
     isMusic: Boolean;
+    Loops: Boolean;
     nRefs: Integer;
   end;
 
@@ -71,8 +77,8 @@ const
 
 function e_InitSoundSystem(NoOutput: Boolean = False): Boolean;
 
-function e_LoadSound(FileName: string; var ID: DWORD; isMusic: Boolean): Boolean;
-function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; isMusic: Boolean): Boolean;
+function e_LoadSound(FileName: string; var ID: DWORD; isMusic: Boolean; ForceNoLoop: Boolean = False): Boolean;
+function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; isMusic: Boolean; ForceNoLoop: Boolean = False): Boolean;
 
 // returns channel number or -1
 function e_PlaySound(ID: DWORD): Integer;
@@ -92,6 +98,8 @@ procedure e_SoundUpdate();
 var
   e_SoundsArray: array of TSoundRec = nil;
 
+  e_TimidityDecoder: Boolean; (* sdl_mixer special *)
+
 implementation
 
 uses
@@ -174,27 +182,39 @@ var
   rfreq: Integer;
   rformat: UInt16;
   rchans: Integer;
+  flags: Integer;
 begin
   if SoundInitialized then begin Result := true; Exit end;
 
   Result := False;
   SoundInitialized := False;
 
+  {$IFDEF HEADLESS}
+    // HACK: shit this into env and hope for the best
+    SetEnvVar('SDL_AUDIODRIVER', 'dummy');
+  {$ENDIF}
+
   if NoOutput then begin Result := true; Exit end;
 
   // wow, this is actually MIDI player!
   // we need module player
-  res := Mix_Init(MIX_INIT_FLAC or MIX_INIT_MOD or MIX_INIT_MODPLUG or MIX_INIT_MP3 or MIX_INIT_OGG or MIX_INIT_FLUIDSYNTH);
+  flags := MIX_INIT_FLAC or MIX_INIT_MOD or MIX_INIT_MP3 or MIX_INIT_OGG or MIX_INIT_FLUIDSYNTH;
+  {$IFDEF SDL2MIXER}
+    flags := flags or MIX_INIT_MODPLUG;
+  {$ENDIF}
+  res := Mix_Init(flags);
   e_WriteLog(Format('SDL: res=0x%x', [res]), TMsgType.Notify);
   if (res and MIX_INIT_FLAC) <> 0 then e_WriteLog('SDL: FLAC playback is active', TMsgType.Notify);
   if (res and MIX_INIT_MOD) <> 0 then e_WriteLog('SDL: MOD playback is active', TMsgType.Notify);
-  if (res and MIX_INIT_MODPLUG) <> 0 then e_WriteLog('SDL: MODPLUG playback is active', TMsgType.Notify);
+  {$IFDEF SDL2MIXER}
+    if (res and MIX_INIT_MODPLUG) <> 0 then e_WriteLog('SDL: MODPLUG playback is active', TMsgType.Notify);
+  {$ENDIF}
   if (res and MIX_INIT_MP3) <> 0 then e_WriteLog('SDL: MP3 playback is active', TMsgType.Notify);
   if (res and MIX_INIT_OGG) <> 0 then e_WriteLog('SDL: OGG playback is active', TMsgType.Notify);
   if (res and MIX_INIT_FLUIDSYNTH) <> 0 then e_WriteLog('SDL: FLUIDSYNTH playback is active', TMsgType.Notify);
 
   e_WriteLog(Format('SDL: initializing mixer at %d with buffer %d', [gsSDLSampleRate, gsSDLBufferSize]), TMsgType.Notify);
-  res := Mix_OpenAudio(gsSDLSampleRate, AUDIO_S16LSB, 2, gsSDLBufferSize);
+  res := Mix_OpenAudio(gsSDLSampleRate, MIX_DEFAULT_FORMAT, 2, gsSDLBufferSize);
   if res = -1 then
   begin
     e_WriteLog('Error initializing SDL mixer:', TMsgType.Fatal);
@@ -211,8 +231,13 @@ begin
   begin
     e_WriteLog(Format('SDL: chunk decoder %s is avalable', [Mix_GetChunkDecoder(i)]), TMsgType.Notify);
   end;
+
+  e_TimidityDecoder := false;
   for i := 0 to Mix_GetNumMusicDecoders()-1 do
   begin
+    case AnsiString(Mix_GetMusicDecoder(i)) of
+      'TIMIDITY': e_TimidityDecoder := true;
+    end;
     e_WriteLog(Format('SDL: music decoder %s is avalable', [Mix_GetMusicDecoder(i)]), TMsgType.Notify);
   end;
 
@@ -283,7 +308,7 @@ begin
   end;
 end;
 
-function e_LoadSound(FileName: String; var ID: DWORD; isMusic: Boolean): Boolean;
+function e_LoadSound(FileName: String; var ID: DWORD; isMusic: Boolean; ForceNoLoop: Boolean = False): Boolean;
 var
   find_id: DWORD;
 begin
@@ -306,6 +331,7 @@ begin
 
   e_SoundsArray[find_id].Data := nil;
   e_SoundsArray[find_id].isMusic := isMusic;
+  e_SoundsArray[find_id].Loops := isMusic and not ForceNoLoop;
   e_SoundsArray[find_id].nRefs := 0;
 
   if isMusic then
@@ -331,7 +357,7 @@ begin
   Result := True;
 end;
 
-function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; isMusic: Boolean): Boolean;
+function e_LoadSoundMem(pData: Pointer; Length: Integer; var ID: DWORD; isMusic: Boolean; ForceNoLoop: Boolean = False): Boolean;
 var
   find_id: DWORD;
   rw: PSDL_RWops;
@@ -372,12 +398,17 @@ begin
   e_SoundsArray[find_id].Data := pData;
   if isid3 then e_SoundsArray[find_id].Data := nil;
   e_SoundsArray[find_id].isMusic := isMusic;
+  e_SoundsArray[find_id].Loops := isMusic and not ForceNoLoop;
   e_SoundsArray[find_id].nRefs := 0;
 
   if isMusic then
   begin
     e_WriteLog(Format('  MUSIC SLOT: %u', [find_id]), TMsgType.Notify);
-    e_SoundsArray[find_id].Music := Mix_LoadMUS_RW(rw, 0);
+    {$IFDEF SDL1MIXER}
+      e_SoundsArray[find_id].Music := Mix_LoadMUS_RW(rw);
+    {$ELSE}
+      e_SoundsArray[find_id].Music := Mix_LoadMUS_RW(rw, 0);
+    {$ENDIF}
     if e_SoundsArray[find_id].Music = nil then
     begin
       e_WriteLog(Format('ERROR LOADING MUSIC:', [find_id]), TMsgType.Warning);
@@ -416,6 +447,7 @@ end;
 function e_PlaySound (ID: DWORD): Integer;
 var
   res: Integer = -1;
+  loops: Integer = 0;
 begin
   Result := -1;
   if not SoundInitialized then Exit;
@@ -424,7 +456,8 @@ begin
   begin
     if e_SoundsArray[ID].nRefs >= gMaxSimSounds then Exit;
     Inc(e_SoundsArray[ID].nRefs);
-    res := Mix_PlayChannel(-1, e_SoundsArray[ID].Sound, 0);
+    if e_SoundsArray[ID].Loops then loops := -1;
+    res := Mix_PlayChannel(-1, e_SoundsArray[ID].Sound, loops);
     if res >= 0 then
     begin
       ChanSIds[res].id := ID;
@@ -442,7 +475,8 @@ begin
   begin
     if not e_isMusic(ID) then Exit;
     Mix_HaltMusic();
-    res := Mix_PlayMusic(e_SoundsArray[ID].Music, -1);
+    if e_SoundsArray[ID].Loops then loops := -1;
+    res := Mix_PlayMusic(e_SoundsArray[ID].Music, loops);
     if res >= 0 then res := N_MUSCHAN;
     if SoundMuted then Mix_VolumeMusic(0) else Mix_VolumeMusic(MusVolume);
     Result := res;