From 233fce7ef6d92fd67b6eab57824a9e874d333070 Mon Sep 17 00:00:00 2001 From: Kevin Caccamo Date: Sun, 30 Jul 2017 19:34:05 -0400 Subject: [PATCH] Initial attempt to make timidity work on Linux again Add code to find the timidity executable, and split the command line into separate arguments by spaces. For some reason, this doesn't work, although reverting 64e96c5f makes timidity work again. --- .../music_timiditypp_mididevice.cpp | 77 ++++++++++++++----- 1 file changed, 59 insertions(+), 18 deletions(-) diff --git a/src/sound/mididevices/music_timiditypp_mididevice.cpp b/src/sound/mididevices/music_timiditypp_mididevice.cpp index 39a7dcb78..0628ea140 100644 --- a/src/sound/mididevices/music_timiditypp_mididevice.cpp +++ b/src/sound/mididevices/music_timiditypp_mididevice.cpp @@ -269,7 +269,7 @@ int TimidityPPMIDIDevice::Open(MidiCallback callback, void *userdata) #ifdef _WIN32 static SECURITY_ATTRIBUTES inheritable = { sizeof(inheritable), NULL, true }; - + if (!Validated && !ValidateTimidity ()) { return 101; @@ -287,7 +287,7 @@ int TimidityPPMIDIDevice::Open(MidiCallback callback, void *userdata) // buffer reads in FillStream() under NT. This does not seem to be an // issue under 9x. int bitmask = pipeSize & -pipeSize; - + while (bitmask < pipeSize) bitmask <<= 1; pipeSize = bitmask; @@ -321,7 +321,7 @@ int TimidityPPMIDIDevice::Open(MidiCallback callback, void *userdata) #endif } } - + if (pipeSize == 0) { Printf(PRINT_BOLD, "If your soundcard cannot play more than one\n" @@ -514,26 +514,67 @@ bool TimidityPPMIDIDevice::LaunchTimidity () // Timidity was previously launched, so the write end of the pipe // is closed, and the read end is still open. Close the pipe // completely and reopen it. - + close (WavePipe[0]); WavePipe[0] = -1; delete Stream; Stream = NULL; Open (NULL, NULL); } - + int forkres; glob_t glb; - switch (glob (CommandLine.GetChars(), 0, NULL, &glb)) - { - case 0: // all good - break; - - case GLOB_NOSPACE: - globfree (&glb); - default: - return false; + // Get timidity executable path + int spaceIdx = 0; + int spaceInExePathCount = -1; + FString TimidityExe; + do { + spaceIdx = CommandLine.IndexOf(' ', spaceIdx); + spaceInExePathCount += 1; + TimidityExe = CommandLine.Left(spaceIdx); + glob(TimidityExe.GetChars(), 0, NULL, &glb); + } while (spaceIdx != -1 && glb.gl_pathc == 0); + if (spaceIdx == -1) return false; + globfree(&glb); + + int strCount = 1; + for (spaceIdx = 0; spaceIdx < CommandLine.Len(); spaceIdx++) { + if (CommandLine[spaceIdx] == ' ') { + ++strCount; + if (CommandLine[spaceIdx+1] == ' ') { + --strCount; + } + } + } + strCount -= spaceInExePathCount; + + char** TimidityArgs = new char*[strCount]; + + spaceIdx = CommandLine.IndexOf(' '); + int curSpace = spaceIdx, i = 1; + + TimidityArgs[0] = new char[TimidityExe.Len() + 1]; + 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]; + 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 (); @@ -546,7 +587,7 @@ bool TimidityPPMIDIDevice::LaunchTimidity () // freopen ("/dev/null", "w", stderr); close (WavePipe[1]); - execvp (glb.gl_pathv[0], glb.gl_pathv); + execvp (TimidityExe.GetChars(), TimidityArgs); fprintf(stderr,"execvp failed\n"); _exit (0); // if execvp succeeds, we never get here } @@ -566,7 +607,7 @@ bool TimidityPPMIDIDevice::LaunchTimidity () fprintf(stderr,"Launching timidity failed\n"); }*/ } - + globfree (&glb); return ChildProcess != -1; #endif // _WIN32 @@ -581,7 +622,7 @@ bool TimidityPPMIDIDevice::LaunchTimidity () bool TimidityPPMIDIDevice::FillStream(SoundStream *stream, void *buff, int len, void *userdata) { TimidityPPMIDIDevice *song = (TimidityPPMIDIDevice *)userdata; - + #ifdef _WIN32 DWORD avail, got, didget; @@ -606,7 +647,7 @@ bool TimidityPPMIDIDevice::FillStream(SoundStream *stream, void *buff, int len, memset ((uint8_t *)buff+didget, 0, len-didget); break; } - } + } } #else ssize_t got;