Add codec fallback support for sound files not found, Patch by Zack Middleton (#4982)

This commit is contained in:
Thilo Schulz 2011-05-09 22:40:25 +00:00
parent 2eb9975334
commit 185d2d6b60
2 changed files with 76 additions and 57 deletions

View file

@ -53,46 +53,90 @@ static char *S_FileExtension(const char *fni)
/* /*
================= =================
S_FindCodecForFile S_CodecGetSound
Select an appropriate codec for a file based on its extension Opens/loads a sound, tries codec based on the sound's file extension
then tries all supported codecs.
================= =================
*/ */
static snd_codec_t *S_FindCodecForFile(const char *filename) static void *S_CodecGetSound(const char *filename, snd_info_t *info)
{ {
char *ext = S_FileExtension(filename); snd_codec_t *codec;
snd_codec_t *codec = codecs; snd_codec_t *orgCodec = NULL;
qboolean orgNameFailed = qfalse;
char localName[ MAX_QPATH ];
const char *ext;
char altName[ MAX_QPATH ];
void *rtn = NULL;
if(!ext) Q_strncpyz(localName, filename, MAX_QPATH);
ext = S_FileExtension(localName);
if( *ext )
{ {
// No extension - auto-detect // Look for the correct loader and use it
while(codec) for( codec = codecs; codec; codec = codec->next )
{ {
char fn[MAX_QPATH]; if( !Q_stricmp( ext, codec->ext ) )
{
// there is no extension so we do not need to subtract 4 chars // Load
Q_strncpyz(fn, filename, MAX_QPATH); if( info )
COM_DefaultExtension(fn, MAX_QPATH, codec->ext); rtn = codec->load(localName, info);
else
// Check it exists rtn = codec->open(localName);
if(FS_ReadFile(fn, NULL) != -1) break;
return codec; }
// Nope. Next!
codec = codec->next;
} }
// Nothin' // A loader was found
return NULL; if( codec )
{
if( !rtn )
{
// Loader failed, most likely because the file isn't there;
// try again without the extension
orgNameFailed = qtrue;
orgCodec = codec;
COM_StripExtension( filename, localName, MAX_QPATH );
}
else
{
// Something loaded
return rtn;
}
}
} }
while(codec) // Try and find a suitable match using all
// the sound codecs supported
for( codec = codecs; codec; codec = codec->next )
{ {
if(!Q_stricmp(ext, codec->ext)) if( codec == orgCodec )
return codec; continue;
codec = codec->next;
Com_sprintf( altName, sizeof (altName), "%s%s", localName, codec->ext );
// Load
if( info )
rtn = codec->load(altName, info);
else
rtn = codec->open(altName);
if( rtn )
{
if( orgNameFailed )
{
Com_DPrintf(S_COLOR_YELLOW "WARNING: %s not present, using %s instead\n",
filename, altName );
} }
return rtn;
}
}
Com_Printf(S_COLOR_YELLOW "WARNING: Failed to %s sound %s!\n", info ? "load" : "open", filename);
return NULL; return NULL;
} }
@ -104,10 +148,13 @@ S_CodecInit
void S_CodecInit() void S_CodecInit()
{ {
codecs = NULL; codecs = NULL;
S_CodecRegister(&wav_codec);
#ifdef USE_CODEC_VORBIS #ifdef USE_CODEC_VORBIS
S_CodecRegister(&ogg_codec); S_CodecRegister(&ogg_codec);
#endif #endif
// Register wav codec last so that it is always tried first when a file extension was not found
S_CodecRegister(&wav_codec);
} }
/* /*
@ -138,20 +185,7 @@ S_CodecLoad
*/ */
void *S_CodecLoad(const char *filename, snd_info_t *info) void *S_CodecLoad(const char *filename, snd_info_t *info)
{ {
snd_codec_t *codec; return S_CodecGetSound(filename, info);
char fn[MAX_QPATH];
codec = S_FindCodecForFile(filename);
if(!codec)
{
Com_Printf("Unknown extension for %s\n", filename);
return NULL;
}
strncpy(fn, filename, sizeof(fn));
COM_DefaultExtension(fn, sizeof(fn), codec->ext);
return codec->load(fn, info);
} }
/* /*
@ -161,20 +195,7 @@ S_CodecOpenStream
*/ */
snd_stream_t *S_CodecOpenStream(const char *filename) snd_stream_t *S_CodecOpenStream(const char *filename)
{ {
snd_codec_t *codec; return S_CodecGetSound(filename, NULL);
char fn[MAX_QPATH];
codec = S_FindCodecForFile(filename);
if(!codec)
{
Com_Printf("Unknown extension for %s\n", filename);
return NULL;
}
strncpy(fn, filename, sizeof(fn));
COM_DefaultExtension(fn, sizeof(fn), codec->ext);
return codec->open(fn);
} }
void S_CodecCloseStream(snd_stream_t *stream) void S_CodecCloseStream(snd_stream_t *stream)

View file

@ -205,8 +205,6 @@ void *S_WAV_CodecLoad(const char *filename, snd_info_t *info)
FS_FOpenFileRead(filename, &file, qtrue); FS_FOpenFileRead(filename, &file, qtrue);
if(!file) if(!file)
{ {
Com_Printf( S_COLOR_RED "ERROR: Could not open \"%s\"\n",
filename);
return NULL; return NULL;
} }