index ade82620b1dd0bec1c121a52b7e43ed28b787428..f71805ef50324de7d8d9b171871d7a783605753a 100644 (file)
*
* 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
*
* 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
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
interface
uses
interface
uses
- sdl2,
- SDL2_mixer,
{$IFDEF USE_MEMPOOL}mempool,{$ENDIF}
{$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
type
TSoundRec = record
Sound: PMix_Chunk;
Music: PMix_Music;
isMusic: Boolean;
Sound: PMix_Chunk;
Music: PMix_Music;
isMusic: Boolean;
+ Loops: Boolean;
nRefs: Integer;
end;
nRefs: Integer;
end;
function e_InitSoundSystem(NoOutput: Boolean = False): Boolean;
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;
// returns channel number or -1
function e_PlaySound(ID: DWORD): Integer;
var
e_SoundsArray: array of TSoundRec = nil;
var
e_SoundsArray: array of TSoundRec = nil;
+ e_TimidityDecoder: Boolean; (* sdl_mixer special *)
+
implementation
uses
implementation
uses
rfreq: Integer;
rformat: UInt16;
rchans: Integer;
rfreq: Integer;
rformat: UInt16;
rchans: Integer;
+ flags: Integer;
begin
if SoundInitialized then begin Result := true; Exit end;
Result := False;
SoundInitialized := False;
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
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);
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);
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);
if res = -1 then
begin
e_WriteLog('Error initializing SDL mixer:', TMsgType.Fatal);
begin
e_WriteLog(Format('SDL: chunk decoder %s is avalable', [Mix_GetChunkDecoder(i)]), TMsgType.Notify);
end;
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
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;
e_WriteLog(Format('SDL: music decoder %s is avalable', [Mix_GetMusicDecoder(i)]), TMsgType.Notify);
end;
end;
end;
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
var
find_id: DWORD;
begin
e_SoundsArray[find_id].Data := nil;
e_SoundsArray[find_id].isMusic := isMusic;
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
e_SoundsArray[find_id].nRefs := 0;
if isMusic then
Result := True;
end;
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;
var
find_id: DWORD;
rw: PSDL_RWops;
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].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].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);
if e_SoundsArray[find_id].Music = nil then
begin
e_WriteLog(Format('ERROR LOADING MUSIC:', [find_id]), TMsgType.Warning);
function e_PlaySound (ID: DWORD): Integer;
var
res: Integer = -1;
function e_PlaySound (ID: DWORD): Integer;
var
res: Integer = -1;
+ loops: Integer = 0;
begin
Result := -1;
if not SoundInitialized then Exit;
begin
Result := -1;
if not SoundInitialized then Exit;
begin
if e_SoundsArray[ID].nRefs >= gMaxSimSounds then Exit;
Inc(e_SoundsArray[ID].nRefs);
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;
if res >= 0 then
begin
ChanSIds[res].id := ID;
begin
if not e_isMusic(ID) then Exit;
Mix_HaltMusic();
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;
if res >= 0 then res := N_MUSCHAN;
if SoundMuted then Mix_VolumeMusic(0) else Mix_VolumeMusic(MusVolume);
Result := res;