- refactored the GUS/Timidity player's path building code so that it can also be used by WildMidi.

- fixed crash during sound reset - in this case I_ShutdownMusic should not close the WildMidi player.
This commit is contained in:
Christoph Oelckers 2015-12-29 20:38:08 +01:00
parent 0634205d7f
commit fe2dcfd588
11 changed files with 198 additions and 121 deletions

View file

@ -915,6 +915,7 @@ add_executable( zdoom WIN32 MACOSX_BUNDLE
nodebuild_extract.cpp nodebuild_extract.cpp
nodebuild_gl.cpp nodebuild_gl.cpp
nodebuild_utility.cpp nodebuild_utility.cpp
pathexpander.cpp
p_3dfloors.cpp p_3dfloors.cpp
p_3dmidtex.cpp p_3dmidtex.cpp
p_acs.cpp p_acs.cpp

134
src/pathexpander.cpp Normal file
View file

@ -0,0 +1,134 @@
/*
** pathexpander.cpp
** Utility class for expanding a given path with a range of directories
**
**---------------------------------------------------------------------------
** Copyright 2015 Christoph Oelckers
** All rights reserved.
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** 2. 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.
** 3. The name of the author may not be used to endorse or promote products
** derived from this software without specific prior written permission.
**
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
**---------------------------------------------------------------------------
**
*/
#include "pathexpander.h"
#include "cmdlib.h"
#include "w_wad.h"
//============================================================================
//
//
//
//============================================================================
static FString BuildPath(const FString &base, const char *name)
{
FString current;
if (base.IsNotEmpty())
{
current = base;
if (current[current.Len() - 1] != '/') current += '/';
}
current += name;
return current;
}
//============================================================================
//
// This is meant to find and open files for reading.
//
//============================================================================
FileReader *PathExpander::openFileReader(const char *name, int *plumpnum)
{
FileReader *fp;
FString current_filename;
if (!name || !(*name))
{
return 0;
}
/* First try the given name */
current_filename = name;
FixPathSeperator(current_filename);
int lumpnum = Wads.CheckNumForFullName(current_filename);
if (openmode != OM_FILE)
{
if (lumpnum >= 0)
{
fp = Wads.ReopenLumpNum(lumpnum);
if (plumpnum) *plumpnum = lumpnum;
return fp;
}
if (openmode == OM_LUMP) // search the path list when not loading the main config
{
for (unsigned int plp = PathList.Size(); plp-- != 0; )
{ /* Try along the path then */
current_filename = BuildPath(PathList[plp], name);
lumpnum = Wads.CheckNumForFullName(current_filename);
if (lumpnum >= 0)
{
fp = Wads.ReopenLumpNum(lumpnum);
if (plumpnum) *plumpnum = lumpnum;
return fp;
}
}
return NULL;
}
}
if (plumpnum) *plumpnum = -1;
fp = new FileReader;
if (fp->Open(current_filename)) return fp;
if (name[0] != '/')
{
for (unsigned int plp = PathList.Size(); plp-- != 0; )
{ /* Try along the path then */
current_filename = BuildPath(PathList[plp], name);
if (fp->Open(current_filename)) return fp;
}
}
delete fp;
/* Nothing could be opened. */
return NULL;
}
/* This adds a directory to the path list */
void PathExpander::addToPathlist(const char *s)
{
FString copy = s;
FixPathSeperator(copy);
PathList.Push(copy);
}
void PathExpander::clearPathlist()
{
PathList.Clear();
}

31
src/pathexpander.h Normal file
View file

@ -0,0 +1,31 @@
#ifndef __PATHEXPANDER_H
#define __PATHEXPANDER_H
#include "tarray.h"
#include "zstring.h"
#include "files.h"
class PathExpander
{
TArray<FString> PathList;
public:
int openmode;
enum
{
OM_FILEORLUMP = 0,
OM_LUMP,
OM_FILE
};
PathExpander(int om = OM_FILEORLUMP)
{
openmode = om;
}
void addToPathlist(const char *s);
void clearPathlist();
FileReader *openFileReader(const char *name, int *plumpnum);
};
#endif

View file

@ -162,7 +162,7 @@ void I_InitMusic (void)
if (!setatterm) if (!setatterm)
{ {
setatterm = true; setatterm = true;
atterm (I_ShutdownMusic); atterm (I_ShutdownMusicExit);
#ifndef _WIN32 #ifndef _WIN32
signal (SIGCHLD, ChildSigHandler); signal (SIGCHLD, ChildSigHandler);
@ -178,7 +178,7 @@ void I_InitMusic (void)
// //
//========================================================================== //==========================================================================
void I_ShutdownMusic(void) void I_ShutdownMusic(bool onexit)
{ {
if (MusicDown) if (MusicDown)
return; return;
@ -189,12 +189,17 @@ void I_ShutdownMusic(void)
assert (currSong == NULL); assert (currSong == NULL);
} }
Timidity::FreeAll(); Timidity::FreeAll();
WildMidi_Shutdown(); if (onexit) WildMidi_Shutdown();
#ifdef _WIN32 #ifdef _WIN32
I_ShutdownMusicWin32(); I_ShutdownMusicWin32();
#endif // _WIN32 #endif // _WIN32
} }
void I_ShutdownMusicExit()
{
I_ShutdownMusic(true);
}
//========================================================================== //==========================================================================
// //

View file

@ -43,7 +43,8 @@ struct FOptionValues;
// MUSIC I/O // MUSIC I/O
// //
void I_InitMusic (); void I_InitMusic ();
void I_ShutdownMusic (); void I_ShutdownMusic (bool onexit = false);
void I_ShutdownMusicExit ();
void I_BuildMIDIMenuList (FOptionValues *); void I_BuildMIDIMenuList (FOptionValues *);
void I_UpdateMusic (); void I_UpdateMusic ();

View file

@ -35,82 +35,6 @@
namespace Timidity namespace Timidity
{ {
static TArray<FString> PathList;
FString BuildPath(FString base, const char *name)
{
FString current;
if (base.IsNotEmpty())
{
current = base;
if (current[current.Len() - 1] != '/') current += '/';
}
current += name;
return current;
}
/* This is meant to find and open files for reading. */
FileReader *open_filereader(const char *name, int open, int *plumpnum)
{
FileReader *fp;
FString current_filename;
if (!name || !(*name))
{
return 0;
}
/* First try the given name */
current_filename = name;
FixPathSeperator(current_filename);
int lumpnum = Wads.CheckNumForFullName(current_filename);
if (open != OM_FILE)
{
if (lumpnum >= 0)
{
fp = Wads.ReopenLumpNum(lumpnum);
if (plumpnum) *plumpnum = lumpnum;
return fp;
}
if (open == OM_LUMP) // search the path list when not loading the main config
{
for (unsigned int plp = PathList.Size(); plp-- != 0; )
{ /* Try along the path then */
current_filename = BuildPath(PathList[plp], name);
lumpnum = Wads.CheckNumForFullName(current_filename);
if (lumpnum >= 0)
{
fp = Wads.ReopenLumpNum(lumpnum);
if (plumpnum) *plumpnum = lumpnum;
return fp;
}
}
return NULL;
}
}
if (plumpnum) *plumpnum = -1;
fp = new FileReader;
if (fp->Open(current_filename)) return fp;
if (name[0] != '/')
{
for (unsigned int plp = PathList.Size(); plp-- != 0; )
{ /* Try along the path then */
current_filename = BuildPath(PathList[plp], name);
if (fp->Open(current_filename)) return fp;
}
}
delete fp;
/* Nothing could be opened. */
current_filename = "";
return NULL;
}
/* This'll allocate memory or die. */ /* This'll allocate memory or die. */
@ -132,17 +56,5 @@ void *safe_malloc(size_t count)
return 0; // Unreachable. return 0; // Unreachable.
} }
/* This adds a directory to the path list */
void add_to_pathlist(const char *s)
{
FString copy = s;
FixPathSeperator(copy);
PathList.Push(copy);
}
void clear_pathlist()
{
PathList.Clear();
}
} }

View file

@ -159,12 +159,12 @@ static Instrument *load_instrument(Renderer *song, const char *name, int percuss
if (!name) return 0; if (!name) return 0;
/* Open patch file */ /* Open patch file */
if ((fp = open_filereader(name, openmode, NULL)) == NULL) if ((fp = pathExpander.openFileReader(name, NULL)) == NULL)
{ {
/* Try with various extensions */ /* Try with various extensions */
FString tmp = name; FString tmp = name;
tmp += ".pat"; tmp += ".pat";
if ((fp = open_filereader(tmp, openmode, NULL)) == NULL) if ((fp = pathExpander.openFileReader(tmp, NULL)) == NULL)
{ {
#ifdef __unix__ // Windows isn't case-sensitive. #ifdef __unix__ // Windows isn't case-sensitive.
tmp.ToUpper(); tmp.ToUpper();

View file

@ -54,7 +54,7 @@ void font_add(const char *filename, int load_order)
} }
else else
{ {
FileReader *fp = open_filereader(filename, openmode, NULL); FileReader *fp = pathExpander.openFileReader(filename, NULL);
if (fp != NULL) if (fp != NULL)
{ {

View file

@ -1502,7 +1502,7 @@ void SFFile::ApplyGeneratorsToRegion(SFGenComposite *gen, SFSample *sfsamp, Rend
void SFFile::LoadSample(SFSample *sample) void SFFile::LoadSample(SFSample *sample)
{ {
FileReader *fp = open_filereader(Filename, openmode, NULL); FileReader *fp = pathExpander.openFileReader(Filename, NULL);
DWORD i; DWORD i;
if (fp == NULL) if (fp == NULL)

View file

@ -42,10 +42,10 @@ CVAR(Int, gus_memsize, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
namespace Timidity namespace Timidity
{ {
PathExpander pathExpander;
ToneBank *tonebank[MAXBANK], *drumset[MAXBANK]; ToneBank *tonebank[MAXBANK], *drumset[MAXBANK];
static FString def_instr_name; static FString def_instr_name;
int openmode = OM_FILEORLUMP;
static int read_config_file(const char *name, bool ismain) static int read_config_file(const char *name, bool ismain)
{ {
@ -62,21 +62,21 @@ static int read_config_file(const char *name, bool ismain)
return (-1); return (-1);
} }
if (ismain) openmode = OM_FILEORLUMP; if (ismain) pathExpander.openmode = PathExpander::OM_FILEORLUMP;
if (!(fp = open_filereader(name, openmode, &lumpnum))) if (!(fp = pathExpander.openFileReader(name, &lumpnum)))
return -1; return -1;
if (ismain) if (ismain)
{ {
if (lumpnum > 0) if (lumpnum > 0)
{ {
openmode = OM_LUMP; pathExpander.openmode = PathExpander::OM_LUMP;
clear_pathlist(); // when reading from a PK3 we won't want to use any external path pathExpander.clearPathlist(); // when reading from a PK3 we don't want to use any external path
} }
else else
{ {
openmode = OM_FILE; pathExpander.openmode = PathExpander::OM_FILE;
} }
} }
@ -288,7 +288,7 @@ static int read_config_file(const char *name, bool ismain)
return -2; return -2;
} }
for (i = 1; i < words; i++) for (i = 1; i < words; i++)
add_to_pathlist(w[i]); pathExpander.addToPathlist(w[i]);
} }
else if (!strcmp(w[0], "source")) else if (!strcmp(w[0], "source"))
{ {
@ -532,15 +532,15 @@ int LoadConfig(const char *filename)
* file itself since that file should contain any other directory * file itself since that file should contain any other directory
* that needs to be added to the search path. * that needs to be added to the search path.
*/ */
clear_pathlist(); pathExpander.clearPathlist();
#ifdef _WIN32 #ifdef _WIN32
add_to_pathlist("C:\\TIMIDITY"); pathExpander.addToPathlist("C:\\TIMIDITY");
add_to_pathlist("\\TIMIDITY"); pathExpander.addToPathlist("\\TIMIDITY");
add_to_pathlist(progdir); pathExpander.addToPathlist(progdir);
#else #else
add_to_pathlist("/usr/local/lib/timidity"); pathExpander.addToPathlist("/usr/local/lib/timidity");
add_to_pathlist("/etc/timidity"); pathExpander.addToPathlist("/etc/timidity");
add_to_pathlist("/etc"); pathExpander.addToPathlist("/etc");
#endif #endif
/* Some functions get aggravated if not even the standard banks are available. */ /* Some functions get aggravated if not even the standard banks are available. */
@ -579,10 +579,10 @@ int LoadDMXGUS()
if (ultradir.IsNotEmpty()) if (ultradir.IsNotEmpty())
{ {
ultradir += "/midi"; ultradir += "/midi";
add_to_pathlist(ultradir.GetChars()); pathExpander.addToPathlist(ultradir.GetChars());
} }
// Load DMXGUS lump and patches from gus_patchdir // Load DMXGUS lump and patches from gus_patchdir
add_to_pathlist(gus_patchdir); pathExpander.addToPathlist(gus_patchdir);
char readbuffer[1024]; char readbuffer[1024];
long size = data.GetLength(); long size = data.GetLength();

View file

@ -21,6 +21,7 @@
#define TIMIDITY_H #define TIMIDITY_H
#include "doomtype.h" #include "doomtype.h"
#include "pathexpander.h"
class FileReader; class FileReader;
@ -172,17 +173,8 @@ extern __inline__ double pow_x87_inline(double x,double y)
common.h common.h
*/ */
#define OM_FILEORLUMP 0
#define OM_LUMP 1
#define OM_FILE 2
extern void add_to_pathlist(const char *s);
extern void clear_pathlist();
extern void *safe_malloc(size_t count); extern void *safe_malloc(size_t count);
FileReader *open_filereader(const char *name, int open, int *plumpnum);
extern int openmode;
/* /*
controls.h controls.h
*/ */
@ -627,6 +619,7 @@ int LoadConfig(const char *filename);
int LoadDMXGUS(); int LoadDMXGUS();
extern int LoadConfig(); extern int LoadConfig();
extern void FreeAll(); extern void FreeAll();
extern PathExpander pathExpander;
extern ToneBank *tonebank[MAXBANK]; extern ToneBank *tonebank[MAXBANK];
extern ToneBank *drumset[MAXBANK]; extern ToneBank *drumset[MAXBANK];