Merge remote-tracking branch 'origin/master' into archive_split

This commit is contained in:
Rachael Alexanderson 2017-09-10 08:10:14 -04:00
commit c4ad6e53e9
6 changed files with 133 additions and 122 deletions

View file

@ -65,7 +65,7 @@
CVAR (Float, mouse_sensitivity, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Float, mouse_sensitivity, 1.f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, show_messages, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, show_messages, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, show_obituaries, true, CVAR_ARCHIVE) CVAR (Bool, show_obituaries, true, CVAR_ARCHIVE)
CVAR(Bool, m_showinputgrid, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR (Int, m_showinputgrid, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
CVAR(Bool, m_blockcontrollers, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) CVAR(Bool, m_blockcontrollers, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)

View file

@ -1386,6 +1386,7 @@ static void InitMusicMenus()
DMenuDescriptor **gusmenu = MenuDescriptors.CheckKey("GusConfigMenu"); DMenuDescriptor **gusmenu = MenuDescriptors.CheckKey("GusConfigMenu");
DMenuDescriptor **timiditymenu = MenuDescriptors.CheckKey("TimidityExeMenu"); DMenuDescriptor **timiditymenu = MenuDescriptors.CheckKey("TimidityExeMenu");
DMenuDescriptor **wildmidimenu = MenuDescriptors.CheckKey("WildMidiConfigMenu"); DMenuDescriptor **wildmidimenu = MenuDescriptors.CheckKey("WildMidiConfigMenu");
DMenuDescriptor **timiditycfgmenu = MenuDescriptors.CheckKey("TimidityConfigMenu");
DMenuDescriptor **fluidmenu = MenuDescriptors.CheckKey("FluidPatchsetMenu"); DMenuDescriptor **fluidmenu = MenuDescriptors.CheckKey("FluidPatchsetMenu");
const char *key, *value; const char *key, *value;
@ -1426,6 +1427,11 @@ static void InitMusicMenus()
auto it = CreateOptionMenuItemCommand(key, FStringf("wildmidi_config %s", NicePath(value).GetChars()), true); auto it = CreateOptionMenuItemCommand(key, FStringf("wildmidi_config %s", NicePath(value).GetChars()), true);
static_cast<DOptionMenuDescriptor*>(*wildmidimenu)->mItems.Push(it); static_cast<DOptionMenuDescriptor*>(*wildmidimenu)->mItems.Push(it);
} }
if (timiditycfgmenu != nullptr)
{
auto it = CreateOptionMenuItemCommand(key, FStringf("timidity_config \"%s\"", NicePath(value).GetChars()), true);
static_cast<DOptionMenuDescriptor*>(*timiditycfgmenu)->mItems.Push(it);
}
} }
} }
} }
@ -1437,6 +1443,8 @@ static void InitMusicMenus()
if (it != nullptr) d->mItems.Delete(d->mItems.Find(it)); if (it != nullptr) d->mItems.Delete(d->mItems.Find(it));
it = d->GetItem("WildMidiConfigMenu"); it = d->GetItem("WildMidiConfigMenu");
if (it != nullptr) d->mItems.Delete(d->mItems.Find(it)); if (it != nullptr) d->mItems.Delete(d->mItems.Find(it));
it = d->GetItem("TimidityConfigMenu");
if (it != nullptr) d->mItems.Delete(d->mItems.Find(it));
} }
#ifdef _WIN32 // Different Timidity paths only make sense if they can be stored in arbitrary paths with local configs (i.e. not if things are done the Linux way) #ifdef _WIN32 // Different Timidity paths only make sense if they can be stored in arbitrary paths with local configs (i.e. not if things are done the Linux way)
if (GameConfig->SetSection("TimidityExes")) if (GameConfig->SetSection("TimidityExes"))

View file

@ -34,6 +34,8 @@
#include "i_midi_win32.h" #include "i_midi_win32.h"
#include <string>
#include <vector>
#include "i_musicinterns.h" #include "i_musicinterns.h"
#include "c_cvars.h" #include "c_cvars.h"
@ -46,6 +48,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <wordexp.h>
#include <glob.h> #include <glob.h>
#include <signal.h> #include <signal.h>
@ -81,14 +84,16 @@ protected:
HANDLE ReadWavePipe; HANDLE ReadWavePipe;
HANDLE WriteWavePipe; HANDLE WriteWavePipe;
HANDLE ChildProcess; HANDLE ChildProcess;
FString CommandLine;
size_t LoopPos;
bool Validated; bool Validated;
bool ValidateTimidity(); bool ValidateTimidity();
#else // _WIN32 #else // _WIN32
int WavePipe[2]; int WavePipe[2];
pid_t ChildProcess; pid_t ChildProcess;
#endif #endif
FString CommandLine; FString ExeName;
size_t LoopPos; bool Looping;
static bool FillStream(SoundStream *stream, void *buff, int len, void *userdata); static bool FillStream(SoundStream *stream, void *buff, int len, void *userdata);
#ifdef _WIN32 #ifdef _WIN32
@ -118,6 +123,7 @@ CUSTOM_CVAR(String, timidity_exe, "timidity", CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
} }
CVAR (String, timidity_extargs, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // extra args to pass to Timidity CVAR (String, timidity_extargs, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) // extra args to pass to Timidity
CVAR (String, timidity_config, "", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (String, timidity_chorus, "0", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (String, timidity_chorus, "0", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (String, timidity_reverb, "0", CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (String, timidity_reverb, "0", CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CVAR (Bool, timidity_stereo, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CVAR (Bool, timidity_stereo, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
@ -137,9 +143,9 @@ CUSTOM_CVAR (Float, timidity_mastervolume, 1.0f, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
CUSTOM_CVAR (Int, timidity_pipe, 90, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) CUSTOM_CVAR (Int, timidity_pipe, 90, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
{ // pipe size in ms { // pipe size in ms
if (timidity_pipe < 0) if (self < 20)
{ // a negative size makes no sense { // Don't allow pipes less than 20ms
timidity_pipe = 0; self = 20;
} }
} }
@ -162,20 +168,30 @@ TimidityPPMIDIDevice::TimidityPPMIDIDevice(const char *args)
#ifdef _WIN32 #ifdef _WIN32
ReadWavePipe(INVALID_HANDLE_VALUE), WriteWavePipe(INVALID_HANDLE_VALUE), ReadWavePipe(INVALID_HANDLE_VALUE), WriteWavePipe(INVALID_HANDLE_VALUE),
ChildProcess(INVALID_HANDLE_VALUE), ChildProcess(INVALID_HANDLE_VALUE),
Validated(false) Validated(false),
#else #else
ChildProcess(-1) ChildProcess(-1),
#endif #endif
Looping(false)
{ {
#ifndef _WIN32 #ifndef _WIN32
WavePipe[0] = WavePipe[1] = -1; WavePipe[0] = WavePipe[1] = -1;
#endif #endif
if (args == NULL || *args == 0) args = timidity_exe; if (args == NULL || *args == 0) args = timidity_exe;
ExeName = args;
#ifdef _WIN32
CommandLine.Format("%s %s -EFchorus=%s -EFreverb=%s -s%d ", CommandLine.Format("%s %s -EFchorus=%s -EFreverb=%s -s%d ",
args, *timidity_extargs, args, *timidity_extargs,
*timidity_chorus, *timidity_reverb, *timidity_frequency); *timidity_chorus, *timidity_reverb, *timidity_frequency);
if (**timidity_config != '\0')
{
CommandLine += "-c \"";
CommandLine += timidity_config;
CommandLine += "\" ";
}
#endif
if (DiskName == NULL) if (DiskName == NULL)
{ {
@ -229,14 +245,17 @@ bool TimidityPPMIDIDevice::Preprocess(MIDIStreamer *song, bool looping)
bool success; bool success;
FILE *f; FILE *f;
if (CommandLine.IsEmpty()) if (ExeName.IsEmpty())
{ {
return false; return false;
} }
// Tell TiMidity++ whether it should loop or not // Tell TiMidity++ whether it should loop or not
#ifdef _WIN32
CommandLine.LockBuffer()[LoopPos] = looping ? 'l' : ' '; CommandLine.LockBuffer()[LoopPos] = looping ? 'l' : ' ';
CommandLine.UnlockBuffer(); CommandLine.UnlockBuffer();
#endif
Looping = looping;
// Write MIDI song to temporary file // Write MIDI song to temporary file
song->CreateSMF(midi, looping ? 0 : 1); song->CreateSMF(midi, looping ? 0 : 1);
@ -298,46 +317,31 @@ int TimidityPPMIDIDevice::Open(MidiCallback callback, void *userdata)
#endif #endif
{ {
Printf(PRINT_BOLD, "Could not create a data pipe for TiMidity++.\n"); Printf(PRINT_BOLD, "Could not create a data pipe for TiMidity++.\n");
pipeSize = 0; return 1;
} }
else
Stream = GSnd->CreateStream(FillStream, pipeSize,
(timidity_stereo ? 0 : SoundStream::Mono) |
(timidity_8bit ? SoundStream::Bits8 : 0),
timidity_frequency, this);
if (Stream == NULL)
{ {
Stream = GSnd->CreateStream(FillStream, pipeSize, Printf(PRINT_BOLD, "Could not create music stream.\n");
(timidity_stereo ? 0 : SoundStream::Mono) |
(timidity_8bit ? SoundStream::Bits8 : 0),
timidity_frequency, this);
if (Stream == NULL)
{
Printf(PRINT_BOLD, "Could not create music stream.\n");
pipeSize = 0;
#ifdef _WIN32 #ifdef _WIN32
CloseHandle(WriteWavePipe); CloseHandle(WriteWavePipe);
CloseHandle(ReadWavePipe); CloseHandle(ReadWavePipe);
ReadWavePipe = WriteWavePipe = INVALID_HANDLE_VALUE; ReadWavePipe = WriteWavePipe = INVALID_HANDLE_VALUE;
#else #else
close(WavePipe[1]); close(WavePipe[1]);
close(WavePipe[0]); close(WavePipe[0]);
WavePipe[0] = WavePipe[1] = -1; WavePipe[0] = WavePipe[1] = -1;
#endif #endif
} return 1;
}
if (pipeSize == 0)
{
Printf(PRINT_BOLD, "If your soundcard cannot play more than one\n"
"wave at a time, you will hear no music.\n");
}
else
{
CommandLine += "-o - -Ors";
} }
} }
if (pipeSize == 0) #ifdef _WIN32
{ CommandLine += "-o - -Ors";
CommandLine += "-Od";
}
CommandLine += timidity_stereo ? 'S' : 'M'; CommandLine += timidity_stereo ? 'S' : 'M';
CommandLine += timidity_8bit ? '8' : '1'; CommandLine += timidity_8bit ? '8' : '1';
if (timidity_byteswap) if (timidity_byteswap)
@ -349,6 +353,7 @@ int TimidityPPMIDIDevice::Open(MidiCallback callback, void *userdata)
CommandLine += " -idl "; CommandLine += " -idl ";
CommandLine += DiskName.GetName(); CommandLine += DiskName.GetName();
#endif
return 0; return 0;
} }
@ -456,6 +461,7 @@ bool TimidityPPMIDIDevice::ValidateTimidity()
bool TimidityPPMIDIDevice::LaunchTimidity () bool TimidityPPMIDIDevice::LaunchTimidity ()
{ {
#ifdef _WIN32
if (CommandLine.IsEmpty()) if (CommandLine.IsEmpty())
{ {
return false; return false;
@ -463,7 +469,6 @@ bool TimidityPPMIDIDevice::LaunchTimidity ()
DPrintf (DMSG_NOTIFY, "cmd: \x1cG%s\n", CommandLine.GetChars()); DPrintf (DMSG_NOTIFY, "cmd: \x1cG%s\n", CommandLine.GetChars());
#ifdef _WIN32
STARTUPINFO startup = { sizeof(startup), }; STARTUPINFO startup = { sizeof(startup), };
PROCESS_INFORMATION procInfo; PROCESS_INFORMATION procInfo;
@ -509,6 +514,11 @@ bool TimidityPPMIDIDevice::LaunchTimidity ()
} }
return false; return false;
#else #else
if (ExeName.IsEmpty())
{
return false;
}
if (WavePipe[0] != -1 && WavePipe[1] == -1 && Stream != NULL) if (WavePipe[0] != -1 && WavePipe[1] == -1 && Stream != NULL)
{ {
// Timidity was previously launched, so the write end of the pipe // Timidity was previously launched, so the write end of the pipe
@ -523,78 +533,55 @@ bool TimidityPPMIDIDevice::LaunchTimidity ()
} }
int forkres; int forkres;
wordexp_t words;
glob_t glb; glob_t glb;
// Get timidity executable path // Get timidity executable path
int spaceIdx = 0; const char *exename = "timidity"; // Fallback default
int spaceInExePathCount = -1; glob(ExeName.GetChars(), 0, NULL, &glb);
FString TimidityExe; if(glb.gl_pathc != 0)
do exename = glb.gl_pathv[0];
// Get user-defined extra args
wordexp(timidity_extargs, &words, WRDE_NOCMD);
std::string chorusarg = std::string("-EFchorus=") + *timidity_chorus;
std::string reverbarg = std::string("-EFreverb=") + *timidity_reverb;
std::string sratearg = std::string("-s") + std::to_string(*timidity_frequency);
std::string outfilearg = "-o"; // An extra "-" is added later
std::string outmodearg = "-Or";
outmodearg += timidity_8bit ? "u8" : "s1";
outmodearg += timidity_stereo ? "S" : "M";
if(timidity_byteswap) outmodearg += "x";
std::string ifacearg = "-id";
if(Looping) ifacearg += "l";
std::vector<const char*> arglist;
arglist.push_back(exename);
for(size_t i = 0;i < words.we_wordc;i++)
arglist.push_back(words.we_wordv[i]);
if(**timidity_config != '\0')
{ {
spaceIdx = CommandLine.IndexOf(' ', spaceIdx); arglist.push_back("-c");
TimidityExe = CommandLine.Left(spaceIdx); arglist.push_back(timidity_config);
glob(TimidityExe.GetChars(), 0, NULL, &glb);
spaceIdx += 1;
spaceInExePathCount += 1;
} while (spaceIdx != 0 && glb.gl_pathc == 0);
if (spaceIdx == 0)
{
TimidityExe = FString("timidity"); // Maybe it's in your PATH?
spaceInExePathCount = 0;
} }
globfree(&glb); arglist.push_back(chorusarg.c_str());
arglist.push_back(reverbarg.c_str());
arglist.push_back(sratearg.c_str());
arglist.push_back(outfilearg.c_str());
arglist.push_back("-");
arglist.push_back(outmodearg.c_str());
arglist.push_back(ifacearg.c_str());
arglist.push_back(DiskName.GetName());
int strCount = 1; DPrintf(DMSG_NOTIFY, "Timidity EXE: \x1cG%s\n", exename);
for (spaceIdx = 0; spaceIdx < static_cast<int>(CommandLine.Len()); spaceIdx++) int i = 1;
{ std::for_each(arglist.begin()+1, arglist.end(),
if (CommandLine[spaceIdx] == ' ') [&i](const char *arg)
{ { DPrintf(DMSG_NOTIFY, "arg %d: \x1cG%s\n", i++, arg); }
++strCount; );
if (CommandLine[spaceIdx+1] == ' ') arglist.push_back(nullptr);
{
--strCount;
}
}
}
strCount -= spaceInExePathCount;
char** TimidityArgs = new char*[strCount + 1];
TimidityArgs[strCount] = NULL;
spaceIdx = CommandLine.IndexOf(' ');
int curSpace = spaceIdx, i = 1;
TimidityArgs[0] = new char[TimidityExe.Len() + 1];
TimidityArgs[0][TimidityExe.Len()] = 0;
strcpy(TimidityArgs[0], TimidityExe.GetChars());
int argLen;
while (curSpace != -1)
{
curSpace = CommandLine.IndexOf(' ', spaceIdx);
if (curSpace != spaceIdx)
{
argLen = curSpace - spaceIdx + 1;
if (argLen < 0)
{
argLen = CommandLine.Len() - curSpace;
}
TimidityArgs[i] = new char[argLen];
TimidityArgs[i][argLen-1] = 0;
strcpy(TimidityArgs[i], CommandLine.Mid(spaceIdx, curSpace - spaceIdx).GetChars());
i += 1;
}
spaceIdx = curSpace + 1;
}
DPrintf(DMSG_NOTIFY, "Timidity EXE: \x1cG%s\n", TimidityExe.GetChars());
for (i = 0; i < strCount; i++)
{
DPrintf(DMSG_NOTIFY, "arg %d: \x1cG%s\n", i, TimidityArgs[i]);
}
forkres = fork (); forkres = fork ();
if (forkres == 0) if (forkres == 0)
{ {
close (WavePipe[0]); close (WavePipe[0]);
@ -603,7 +590,7 @@ bool TimidityPPMIDIDevice::LaunchTimidity ()
// freopen ("/dev/null", "w", stderr); // freopen ("/dev/null", "w", stderr);
close (WavePipe[1]); close (WavePipe[1]);
execvp (TimidityExe.GetChars(), TimidityArgs); execvp (exename, const_cast<char*const*>(arglist.data()));
fprintf(stderr,"execvp failed: %s\n", strerror(errno)); fprintf(stderr,"execvp failed: %s\n", strerror(errno));
_exit (0); // if execvp succeeds, we never get here _exit (0); // if execvp succeeds, we never get here
} }
@ -624,12 +611,7 @@ bool TimidityPPMIDIDevice::LaunchTimidity ()
}*/ }*/
} }
for (i = 0; i < strCount; i++) wordfree(&words);
{
delete [] TimidityArgs[i];
}
delete [] TimidityArgs;
globfree (&glb); globfree (&glb);
return ChildProcess != -1; return ChildProcess != -1;
#endif // _WIN32 #endif // _WIN32
@ -672,7 +654,6 @@ bool TimidityPPMIDIDevice::FillStream(SoundStream *stream, void *buff, int len,
} }
} }
#else #else
ssize_t got;
fd_set rfds; fd_set rfds;
struct timeval tv; struct timeval tv;
@ -697,11 +678,26 @@ bool TimidityPPMIDIDevice::FillStream(SoundStream *stream, void *buff, int len,
} }
// fprintf(stderr,"something\n"); // fprintf(stderr,"something\n");
got = read(song->WavePipe[0], (uint8_t *)buff, len); ssize_t got = 0;
if (got < len) do {
{ ssize_t r = read(song->WavePipe[0], (uint8_t*)buff+got, len-got);
memset((uint8_t *)buff+got, 0, len-got); if(r < 0)
} {
if(errno == EWOULDBLOCK || errno == EAGAIN)
{
FD_ZERO(&rfds);
FD_SET(song->WavePipe[0], &rfds);
tv.tv_sec = 0;
tv.tv_usec = 50;
select(1, &rfds, NULL, NULL, &tv);
continue;
}
break;
}
got += r;
} while(got < len);
if(got < len)
memset((uint8_t*)buff+got, 0, len-got);
#endif #endif
return true; return true;
} }
@ -761,8 +757,7 @@ int TimidityPPMIDIDevice::Resume()
{ {
if (LaunchTimidity()) if (LaunchTimidity())
{ {
// Assume success if not mixing with the sound system if (Stream != NULL && Stream->Play(true, timidity_mastervolume))
if (Stream == NULL || Stream->Play(true, timidity_mastervolume))
{ {
Started = true; Started = true;
return 0; return 0;

View file

@ -2163,6 +2163,7 @@ ADVSNDMNU_REVERB = "Reverb";
ADVSNDMNU_FLUIDVOICES = "MIDI voices"; ADVSNDMNU_FLUIDVOICES = "MIDI voices";
ADVSNDMNU_TIMIDITY = "Timidity++"; ADVSNDMNU_TIMIDITY = "Timidity++";
ADVSNDMNU_TIMIDITYEXE = "Path for executable"; ADVSNDMNU_TIMIDITYEXE = "Path for executable";
ADVSNDMNU_TIMIDITYCONFIG = "Timidity config file";
ADVSNDMNU_TIMIDITYCHORUS = "Chorus"; ADVSNDMNU_TIMIDITYCHORUS = "Chorus";
ADVSNDMNU_TIMIDITYVOLUME = "Relative volume"; ADVSNDMNU_TIMIDITYVOLUME = "Relative volume";
ADVSNDMNU_WILDMIDI = "WildMidi"; ADVSNDMNU_WILDMIDI = "WildMidi";

View file

@ -1680,6 +1680,8 @@ OptionMenu AdvSoundOptions protected
{ {
SubMenu "$ADVSNDMNU_SELCONFIG", "TimidityExeMenu" SubMenu "$ADVSNDMNU_SELCONFIG", "TimidityExeMenu"
} }
TextField "$ADVSNDMNU_TIMIDITYCONFIG", "timidity_config"
SubMenu "$ADVSNDMNU_SELCONFIG", "TimidityConfigMenu"
Option "$ADVSNDMNU_REVERB", "timidity_reverb", "OnOff" Option "$ADVSNDMNU_REVERB", "timidity_reverb", "OnOff"
Option "$ADVSNDMNU_TIMIDITYCHORUS", "timidity_chorus", "OnOff" Option "$ADVSNDMNU_TIMIDITYCHORUS", "timidity_chorus", "OnOff"
Slider "$ADVSNDMNU_TIMIDITYVOLUME", "timidity_mastervolume", 0, 4, 0.2, 1 Slider "$ADVSNDMNU_TIMIDITYVOLUME", "timidity_mastervolume", 0, 4, 0.2, 1
@ -1705,6 +1707,11 @@ OptionMenu TimidityExeMenu protected
Title "$ADVSNDMNU_SELCONFIG" Title "$ADVSNDMNU_SELCONFIG"
} }
OptionMenu TimidityConfigMenu protected
{
Title "$ADVSNDMNU_SELCONFIG"
}
OptionMenu FluidPatchsetMenu protected OptionMenu FluidPatchsetMenu protected
{ {
Title "$ADVSNDMNU_SELCONFIG" Title "$ADVSNDMNU_SELCONFIG"

View file

@ -63,7 +63,7 @@ class TextEnterMenu : Menu
mEnterString = textbuffer; mEnterString = textbuffer;
mEnterSize = maxlen < 0 ? 0x7fffffff : maxlen; mEnterSize = maxlen < 0 ? 0x7fffffff : maxlen;
mSizeMode = sizemode; mSizeMode = sizemode;
mInputGridOkay = showgrid || m_showinputgrid; mInputGridOkay = (showgrid && (m_showinputgrid == 0)) || (m_showinputgrid >= 1);
if (mEnterString.Length() > 0) if (mEnterString.Length() > 0)
{ {
InputGridX = INPUTGRID_WIDTH - 1; InputGridX = INPUTGRID_WIDTH - 1;