shithub: choc

Download patch

ref: 2f8ed99c11279ab932dbda6db0647f70c3280b7a
parent: a941e8c70a73570b6c9bae3c037e880262bb499d
author: Alex Mayfield <alexmax2742@gmail.com>
date: Fri Feb 10 13:40:34 EST 2017

Normalize header comments and file extensions

--- /dev/null
+++ b/midiproc/main.c
@@ -1,0 +1,377 @@
+//
+// Copyright(C) 2012 James Haley
+//
+// 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 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// DESCRIPTION:
+//
+// Win32/SDL_mixer MIDI RPC Server
+//
+// Uses RPC to communicate with Doom. This allows this separate process to
+// have its own independent volume control even under Windows Vista and up's 
+// broken, stupid, completely useless mixer model that can't assign separate
+// volumes to different devices for the same process.
+//
+// Seriously, how did they screw up something so fundamental?
+//
+
+#include <windows.h>
+#include <stdlib.h>
+#include "SDL.h"
+#include "SDL_mixer.h"
+#include "midiproc.h"
+
+// Currently playing music track
+static Mix_Music *music = NULL;
+static SDL_RWops *rw    = NULL;
+
+static void UnregisterSong();
+
+//=============================================================================
+//
+// RPC Memory Management
+//
+
+void __RPC_FAR * __RPC_USER midl_user_allocate(size_t size)
+{
+   return malloc(size);
+}
+
+void __RPC_USER midl_user_free(void __RPC_FAR *p)
+{
+   free(p);
+}
+
+//=============================================================================
+//
+// SDL_mixer Interface
+//
+
+//
+// InitSDL
+//
+// Start up SDL and SDL_mixer.
+//
+static bool InitSDL()
+{
+   if(SDL_Init(SDL_INIT_AUDIO) == -1)
+      return false;
+
+   if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0)
+      return false;
+
+   return true;
+}
+
+//
+// RegisterSong
+//
+static void RegisterSong(void *data, size_t size)
+{
+   if(music)
+      UnregisterSong();
+
+   rw    = SDL_RWFromMem(data, size);
+   music = Mix_LoadMUS_RW(rw);
+}
+
+//
+// StartSong
+//
+static void StartSong(bool loop)
+{
+   if(music)
+      Mix_PlayMusic(music, loop ? -1 : 0);
+}
+
+//
+// SetVolume
+//
+static void SetVolume(int volume)
+{
+   Mix_VolumeMusic((volume * 128) / 15);
+}
+
+static int paused_midi_volume;
+
+//
+// PauseSong
+//
+static void PauseSong()
+{
+   paused_midi_volume = Mix_VolumeMusic(-1);
+   Mix_VolumeMusic(0);
+}
+
+//
+// ResumeSong
+//
+static void ResumeSong()
+{
+   Mix_VolumeMusic(paused_midi_volume);
+}
+
+//
+// StopSong
+//
+static void StopSong()
+{
+   if(music)
+      Mix_HaltMusic();
+}
+
+//
+// UnregisterSong
+//
+static void UnregisterSong()
+{
+   if(!music)
+      return;
+
+   StopSong();
+   Mix_FreeMusic(music);
+   rw    = NULL;
+   music = NULL;
+}
+
+//
+// ShutdownSDL
+//
+static void ShutdownSDL()
+{
+   UnregisterSong();
+   Mix_CloseAudio();
+   SDL_Quit();
+}
+
+//=============================================================================
+//
+// Song Buffer
+//
+// The MIDI program will be transmitted by the client across RPC in fixed-size
+// chunks until all data has been transmitted.
+//
+
+typedef unsigned char midibyte;
+
+class SongBuffer
+{
+protected:
+   midibyte *buffer;    // accumulated input
+   size_t    size;      // size of input
+   size_t    allocated; // amount of memory allocated (>= size)
+
+   static const int defaultSize = 128*1024; // 128 KB
+
+public:
+   // Constructor
+   // Start out with an empty 128 KB buffer.
+   SongBuffer()
+   {
+      buffer = static_cast<midibyte *>(calloc(1, defaultSize));
+      size = 0;
+      allocated = defaultSize;
+   }
+
+   // Destructor.
+   // Release the buffer.
+   ~SongBuffer()
+   {
+      if(buffer)
+      {
+         free(buffer);
+         buffer = NULL;
+         size = allocated = 0;
+      }
+   }
+
+   //
+   // addChunk
+   //
+   // Add a chunk of MIDI data to the buffer.
+   //
+   void addChunk(midibyte *data, size_t newsize)
+   {
+      if(size + newsize > allocated)
+      {
+         allocated += newsize * 2;
+         buffer = static_cast<midibyte *>(realloc(buffer, allocated));
+      }
+
+      memcpy(buffer + size, data, newsize);
+      size += newsize;
+   }
+
+   // Accessors
+
+   midibyte *getBuffer() const { return buffer; }
+   size_t    getSize()   const { return size;   }
+};
+
+static SongBuffer *song;
+
+//=============================================================================
+//
+// RPC Server Interface
+//
+
+//
+// MidiRPC_PrepareNewSong
+//
+// Prepare the engine to receive new song data from the RPC client.
+//
+void MidiRPC_PrepareNewSong()
+{
+   // Stop anything currently playing and free it.
+   UnregisterSong();
+
+   // free any previous song buffer
+   delete song;
+
+   // prep new song buffer
+   song = new SongBuffer();
+}
+
+//
+// MidiRPC_AddChunk
+//
+// Add a chunk of data to the song.
+//
+void MidiRPC_AddChunk(unsigned int count, byte *pBuf)
+{
+   song->addChunk(pBuf, static_cast<size_t>(count));
+}
+
+//
+// MidiRPC_PlaySong
+//
+// Start playing the song.
+//
+void MidiRPC_PlaySong(boolean looping)
+{
+   RegisterSong(song->getBuffer(), song->getSize());
+   StartSong(!!looping);
+}
+
+//
+// MidiRPC_StopSong
+//
+// Stop the song.
+//
+void MidiRPC_StopSong()
+{
+   StopSong();
+}
+
+//
+// MidiRPC_ChangeVolume
+//
+// Set playback volume level.
+//
+void MidiRPC_ChangeVolume(int volume)
+{
+   SetVolume(volume);
+}
+
+//
+// MidiRPC_PauseSong
+//
+// Pause the song.
+//
+void MidiRPC_PauseSong()
+{
+   PauseSong();
+}
+
+//
+// MidiRPC_ResumeSong
+//
+// Resume after pausing.
+//
+void MidiRPC_ResumeSong()
+{
+   ResumeSong();
+}
+
+//
+// MidiRPC_StopServer
+//
+// Stops the RPC server so the program can shutdown.
+//
+void MidiRPC_StopServer()
+{
+   // Local shutdown tasks
+   ShutdownSDL();
+   delete song;
+   song = NULL;
+
+   // Stop RPC server
+   RpcMgmtStopServerListening(NULL);
+}
+
+//
+// RPC Server Init
+//
+static bool MidiRPC_InitServer()
+{
+   RPC_STATUS status;
+
+   // Initialize RPC protocol
+   status = 
+      RpcServerUseProtseqEp
+      (
+         (RPC_CSTR)("ncalrpc"),
+         RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
+         (RPC_CSTR)("2d4dc2f9-ce90-4080-8a00-1cb819086970"),
+         NULL
+      );
+
+   if(status)
+      return false;
+
+   // Register server
+   status = RpcServerRegisterIf(MidiRPC_v1_0_s_ifspec, NULL, NULL);
+
+   if(status)
+      return false;
+
+   // Start listening
+   status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, FALSE);
+
+   return !status;
+}
+
+//=============================================================================
+//
+// Main Program
+//
+
+//
+// WinMain
+//
+// Application entry point.
+//
+int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
+                     LPSTR lpCmdLine, int nCmdShow)
+{
+   // Initialize SDL
+   if(!InitSDL())
+      return -1;
+
+   // Initialize RPC Server
+   if(!MidiRPC_InitServer())
+      return -1;
+
+   return 0;
+}
+
+// EOF
+
--- a/midiproc/main.cpp
+++ /dev/null
@@ -1,386 +1,0 @@
-// Emacs style mode select   -*- C++ -*-
-//-----------------------------------------------------------------------------
-//
-// Copyright(C) 2012 James Haley
-//
-// 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 2 of the License, or
-// (at your option) any later version.
-// 
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// 
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-//
-//-----------------------------------------------------------------------------
-//
-// DESCRIPTION:
-//
-// Win32/SDL_mixer MIDI RPC Server
-//
-// Uses RPC to communicate with Eternity. This allows this separate process to
-// have its own independent volume control even under Windows Vista and up's 
-// broken, stupid, completely useless mixer model that can't assign separate
-// volumes to different devices for the same process.
-//
-// Seriously, how did they screw up something so fundamental?
-//
-//-----------------------------------------------------------------------------
-
-#include <windows.h>
-#include <stdlib.h>
-#include "SDL.h"
-#include "SDL_mixer.h"
-#include "midiproc.h"
-
-// Currently playing music track
-static Mix_Music *music = NULL;
-static SDL_RWops *rw    = NULL;
-
-static void UnregisterSong();
-
-//=============================================================================
-//
-// RPC Memory Management
-//
-
-void __RPC_FAR * __RPC_USER midl_user_allocate(size_t size)
-{
-   return malloc(size);
-}
-
-void __RPC_USER midl_user_free(void __RPC_FAR *p)
-{
-   free(p);
-}
-
-//=============================================================================
-//
-// SDL_mixer Interface
-//
-
-//
-// InitSDL
-//
-// Start up SDL and SDL_mixer.
-//
-static bool InitSDL()
-{
-   if(SDL_Init(SDL_INIT_AUDIO) == -1)
-      return false;
-
-   if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0)
-      return false;
-
-   return true;
-}
-
-//
-// RegisterSong
-//
-static void RegisterSong(void *data, size_t size)
-{
-   if(music)
-      UnregisterSong();
-
-   rw    = SDL_RWFromMem(data, size);
-   music = Mix_LoadMUS_RW(rw);
-}
-
-//
-// StartSong
-//
-static void StartSong(bool loop)
-{
-   if(music)
-      Mix_PlayMusic(music, loop ? -1 : 0);
-}
-
-//
-// SetVolume
-//
-static void SetVolume(int volume)
-{
-   Mix_VolumeMusic((volume * 128) / 15);
-}
-
-static int paused_midi_volume;
-
-//
-// PauseSong
-//
-static void PauseSong()
-{
-   paused_midi_volume = Mix_VolumeMusic(-1);
-   Mix_VolumeMusic(0);
-}
-
-//
-// ResumeSong
-//
-static void ResumeSong()
-{
-   Mix_VolumeMusic(paused_midi_volume);
-}
-
-//
-// StopSong
-//
-static void StopSong()
-{
-   if(music)
-      Mix_HaltMusic();
-}
-
-//
-// UnregisterSong
-//
-static void UnregisterSong()
-{
-   if(!music)
-      return;
-
-   StopSong();
-   Mix_FreeMusic(music);
-   rw    = NULL;
-   music = NULL;
-}
-
-//
-// ShutdownSDL
-//
-static void ShutdownSDL()
-{
-   UnregisterSong();
-   Mix_CloseAudio();
-   SDL_Quit();
-}
-
-//=============================================================================
-//
-// Song Buffer
-//
-// The MIDI program will be transmitted by the client across RPC in fixed-size
-// chunks until all data has been transmitted.
-//
-
-typedef unsigned char midibyte;
-
-class SongBuffer
-{
-protected:
-   midibyte *buffer;    // accumulated input
-   size_t    size;      // size of input
-   size_t    allocated; // amount of memory allocated (>= size)
-
-   static const int defaultSize = 128*1024; // 128 KB
-
-public:
-   // Constructor
-   // Start out with an empty 128 KB buffer.
-   SongBuffer()
-   {
-      buffer = static_cast<midibyte *>(calloc(1, defaultSize));
-      size = 0;
-      allocated = defaultSize;
-   }
-
-   // Destructor.
-   // Release the buffer.
-   ~SongBuffer()
-   {
-      if(buffer)
-      {
-         free(buffer);
-         buffer = NULL;
-         size = allocated = 0;
-      }
-   }
-
-   //
-   // addChunk
-   //
-   // Add a chunk of MIDI data to the buffer.
-   //
-   void addChunk(midibyte *data, size_t newsize)
-   {
-      if(size + newsize > allocated)
-      {
-         allocated += newsize * 2;
-         buffer = static_cast<midibyte *>(realloc(buffer, allocated));
-      }
-
-      memcpy(buffer + size, data, newsize);
-      size += newsize;
-   }
-
-   // Accessors
-
-   midibyte *getBuffer() const { return buffer; }
-   size_t    getSize()   const { return size;   }
-};
-
-static SongBuffer *song;
-
-//=============================================================================
-//
-// RPC Server Interface
-//
-
-//
-// MidiRPC_PrepareNewSong
-//
-// Prepare the engine to receive new song data from the RPC client.
-//
-void MidiRPC_PrepareNewSong()
-{
-   // Stop anything currently playing and free it.
-   UnregisterSong();
-
-   // free any previous song buffer
-   delete song;
-
-   // prep new song buffer
-   song = new SongBuffer();
-}
-
-//
-// MidiRPC_AddChunk
-//
-// Add a chunk of data to the song.
-//
-void MidiRPC_AddChunk(unsigned int count, byte *pBuf)
-{
-   song->addChunk(pBuf, static_cast<size_t>(count));
-}
-
-//
-// MidiRPC_PlaySong
-//
-// Start playing the song.
-//
-void MidiRPC_PlaySong(boolean looping)
-{
-   RegisterSong(song->getBuffer(), song->getSize());
-   StartSong(!!looping);
-}
-
-//
-// MidiRPC_StopSong
-//
-// Stop the song.
-//
-void MidiRPC_StopSong()
-{
-   StopSong();
-}
-
-//
-// MidiRPC_ChangeVolume
-//
-// Set playback volume level.
-//
-void MidiRPC_ChangeVolume(int volume)
-{
-   SetVolume(volume);
-}
-
-//
-// MidiRPC_PauseSong
-//
-// Pause the song.
-//
-void MidiRPC_PauseSong()
-{
-   PauseSong();
-}
-
-//
-// MidiRPC_ResumeSong
-//
-// Resume after pausing.
-//
-void MidiRPC_ResumeSong()
-{
-   ResumeSong();
-}
-
-//
-// MidiRPC_StopServer
-//
-// Stops the RPC server so the program can shutdown.
-//
-void MidiRPC_StopServer()
-{
-   // Local shutdown tasks
-   ShutdownSDL();
-   delete song;
-   song = NULL;
-
-   // Stop RPC server
-   RpcMgmtStopServerListening(NULL);
-}
-
-//
-// RPC Server Init
-//
-static bool MidiRPC_InitServer()
-{
-   RPC_STATUS status;
-
-   // Initialize RPC protocol
-   status = 
-      RpcServerUseProtseqEp
-      (
-         (RPC_CSTR)("ncalrpc"),
-         RPC_C_PROTSEQ_MAX_REQS_DEFAULT,
-         (RPC_CSTR)("2d4dc2f9-ce90-4080-8a00-1cb819086970"),
-         NULL
-      );
-
-   if(status)
-      return false;
-
-   // Register server
-   status = RpcServerRegisterIf(MidiRPC_v1_0_s_ifspec, NULL, NULL);
-
-   if(status)
-      return false;
-
-   // Start listening
-   status = RpcServerListen(1, RPC_C_LISTEN_MAX_CALLS_DEFAULT, FALSE);
-
-   return !status;
-}
-
-//=============================================================================
-//
-// Main Program
-//
-
-//
-// WinMain
-//
-// Application entry point.
-//
-int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
-                     LPSTR lpCmdLine, int nCmdShow)
-{
-   // Initialize SDL
-   if(!InitSDL())
-      return -1;
-
-   // Initialize RPC Server
-   if(!MidiRPC_InitServer())
-      return -1;
-
-   return 0;
-}
-
-// EOF
-
--- /dev/null
+++ b/src/i_midirpc.c
@@ -1,0 +1,389 @@
+//
+// Copyright(C) 2013 James Haley et al.
+//
+// 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 2
+// of the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// DESCRIPTION:
+//     Client Interface to RPC Midi Server
+//
+
+#ifdef EE_FEATURE_MIDIRPC
+
+#include <windows.h>
+#include "midiproc.h"
+
+#include "../hal/i_timer.h"
+#include "../m_qstr.h"
+
+#if defined(_DEBUG) && defined(EE_RPC_DEBUG)
+#define DEBUGOUT(s) puts(s)
+#else
+#define DEBUGOUT(s)
+#endif
+
+//=============================================================================
+//
+// Data
+//
+
+static unsigned char *szStringBinding; // RPC client binding string
+static bool serverInit = false;        // if true, server was started
+static bool clientInit = false;        // if true, client was bound
+
+// server process information
+static STARTUPINFO         si;
+static PROCESS_INFORMATION pi;
+
+//=============================================================================
+//
+// RPC Memory Management
+//
+
+void __RPC_FAR * __RPC_USER midl_user_allocate(size_t size)
+{
+   return malloc(size);
+}
+
+void __RPC_USER midl_user_free(void __RPC_FAR *p)
+{
+   free(p);
+}
+
+//=============================================================================
+//
+// RPC Wrappers
+//
+
+//
+// CHECK_RPC_STATUS
+//
+// If either server or client initialization failed, we don't try to make any
+// RPC calls.
+//
+#define CHECK_RPC_STATUS()        \
+   if(!serverInit || !clientInit) \
+      return false
+
+#define MIDIRPC_MAXTRIES 50 // This number * 10 is the amount of time you can try to wait for.
+
+static bool I_MidiRPCWaitForServer()
+{
+   int tries = 0;
+   while(RpcMgmtIsServerListening(hMidiRPCBinding) != RPC_S_OK)
+   {
+      i_haltimer.Sleep(10);
+      if(++tries >= MIDIRPC_MAXTRIES)
+         return false;
+   }
+   return true;
+}
+
+//
+// I_MidiRPCRegisterSong
+//
+// Prepare the RPC MIDI engine to receive new song data, and transmit the song
+// data to the server process.
+//
+bool I_MidiRPCRegisterSong(void *data, int size)
+{
+   unsigned int rpcSize = static_cast<unsigned int>(size);
+
+   CHECK_RPC_STATUS();
+
+   RpcTryExcept
+   {
+      MidiRPC_PrepareNewSong();
+
+      // TODO: Try passing it as one chunk; if this ends up not working, 
+      // I'll have to stream it in as smaller divisions.
+      MidiRPC_AddChunk(rpcSize, static_cast<byte *>(data));
+   }
+   RpcExcept(1)
+   {
+      DEBUGOUT("I_MidiRPCRegisterSong failed");
+      return false;
+   }
+   RpcEndExcept
+
+   DEBUGOUT("I_MidiRPCRegisterSong succeeded");
+   return true;
+}
+
+//
+// I_MidiRPCPlaySong
+//
+// Tell the RPC server to start playing a song.
+//
+bool I_MidiRPCPlaySong(bool looping)
+{
+   CHECK_RPC_STATUS();
+
+   RpcTryExcept
+   {
+      MidiRPC_PlaySong(looping ? TRUE : FALSE);
+   }
+   RpcExcept(1)
+   {
+      DEBUGOUT("I_MidiRPCPlaySong failed");
+      return false;
+   }
+   RpcEndExcept
+
+   DEBUGOUT("I_MidiRPCPlaySong succeeded");
+   return true;
+}
+
+// 
+// I_MidiRPCStopSong
+//
+// Tell the RPC server to stop any currently playing song.
+//
+bool I_MidiRPCStopSong()
+{
+   CHECK_RPC_STATUS();
+
+   RpcTryExcept
+   {
+      MidiRPC_StopSong();
+   }
+   RpcExcept(1)
+   {
+      DEBUGOUT("I_MidiRPCStopSong failed");
+      return false;
+   }
+   RpcEndExcept
+
+   DEBUGOUT("I_MidiRPCStopSong succeeded");
+   return true;
+}
+
+//
+// I_MidiRPCSetVolume
+//
+// Change the volume level of music played by the RPC midi server.
+//
+bool I_MidiRPCSetVolume(int volume)
+{
+   CHECK_RPC_STATUS();
+   
+   RpcTryExcept
+   {
+      MidiRPC_ChangeVolume(volume);
+   }
+   RpcExcept(1)
+   {
+      DEBUGOUT("I_MidiRPCSetVolume failed");
+      return false;
+   }
+   RpcEndExcept
+
+   DEBUGOUT("I_MidiRPCSetVolume succeeded");
+   return true;
+}
+
+//
+// I_MidiRPCPauseSong
+//
+// Pause the music being played by the server. In actuality, due to SDL_mixer
+// limitations, this just temporarily sets the volume to zero.
+//
+bool I_MidiRPCPauseSong()
+{
+   CHECK_RPC_STATUS();
+
+   RpcTryExcept
+   {
+      MidiRPC_PauseSong();
+   }
+   RpcExcept(1)
+   {
+      DEBUGOUT("I_MidiRPCPauseSong failed");
+      return false;
+   }
+   RpcEndExcept
+
+   DEBUGOUT("I_MidiRPCPauseSong succeeded");
+   return true;
+}
+
+//
+// I_MidiRPCResumeSong
+//
+// Resume a song after having paused it.
+//
+bool I_MidiRPCResumeSong()
+{
+   CHECK_RPC_STATUS();
+
+   RpcTryExcept
+   {
+      MidiRPC_ResumeSong();
+   }
+   RpcExcept(1)
+   {
+      DEBUGOUT("I_MidiRPCResumeSong failed");
+      return false;
+   }
+   RpcEndExcept
+
+   DEBUGOUT("I_MidiRPCResumeSong succeeded");
+   return true;
+}
+
+//=============================================================================
+//
+// Public Interface
+//
+
+//
+// I_MidiRPCInitServer
+//
+// Start up the RPC MIDI server.
+//
+bool I_MidiRPCInitServer()
+{
+   struct stat sbuf;
+   char filename[MAX_PATH+1];
+
+   memset(filename, 0, sizeof(filename));
+   GetModuleFileName(NULL, filename, MAX_PATH);
+
+   qstring module;
+
+   module = filename;
+   module.removeFileSpec();
+   module.pathConcatenate("midiproc.exe");
+   DEBUGOUT(module.constPtr());
+
+   // Look for executable file
+   if(stat(module.constPtr(), &sbuf))
+   {
+      DEBUGOUT("Could not find midiproc");
+      return false;
+   }
+
+   si.cb = sizeof(si);
+
+   BOOL result = CreateProcess(module.constPtr(), NULL, NULL, NULL, FALSE,
+                               0, NULL, NULL, &si, &pi);
+
+   if(result)
+   {
+      DEBUGOUT("RPC server started");
+      serverInit = true;
+   }
+   else
+      DEBUGOUT("CreateProcess failed to start midiproc");
+
+   return !!result;
+}
+
+//
+// I_MidiRPCInitClient
+//
+// Initialize client RPC bindings and bind to the server.
+//
+bool I_MidiRPCInitClient()
+{
+   RPC_STATUS status;
+
+   // If server didn't start, client cannot be bound.
+   if(!serverInit)
+      return false;
+
+   // Compose binding string
+   status =
+      RpcStringBindingCompose
+      (
+         NULL,
+         (RPC_CSTR)("ncalrpc"),
+         NULL,
+         (RPC_CSTR)("2d4dc2f9-ce90-4080-8a00-1cb819086970"),
+         NULL,
+         &szStringBinding
+      );
+
+   if(status)
+   {
+      DEBUGOUT("RPC binding composition failed");
+      return false;
+   }
+
+   // Create binding handle
+   status = RpcBindingFromStringBinding(szStringBinding, &hMidiRPCBinding);
+
+   if(status)
+   {
+      DEBUGOUT("RPC client binding failed");
+      return false;
+   }
+
+   DEBUGOUT("RPC client initialized");
+   clientInit = true;
+
+   return I_MidiRPCWaitForServer();
+}
+
+//
+// I_MidiRPCClientShutDown
+//
+// Shutdown the RPC Client
+//
+void I_MidiRPCClientShutDown()
+{
+   // stop the server
+   if(serverInit)
+   {
+      RpcTryExcept
+      {
+         MidiRPC_StopServer();
+      }
+      RpcExcept(1)
+      {
+         DEBUGOUT("Exception thrown when stopping RPC server");
+      }
+      RpcEndExcept
+
+      serverInit = false;
+   }
+
+   if(szStringBinding)
+   {
+      RpcStringFree(&szStringBinding);
+      szStringBinding = NULL;
+   }
+
+   if(hMidiRPCBinding)
+   {
+      RpcBindingFree(&hMidiRPCBinding);
+      hMidiRPCBinding = NULL;
+   }
+
+   clientInit = false;
+}
+
+//
+// I_MidiRPCReady
+//
+// Returns true if both server and client initialized successfully.
+//
+bool I_MidiRPCReady()
+{
+   CHECK_RPC_STATUS();
+
+   return true;
+}
+
+#endif
+
+// EOF
+
+
--- a/src/i_midirpc.cpp
+++ /dev/null
@@ -1,398 +1,0 @@
-// Emacs style mode select   -*- C++ -*-
-//-----------------------------------------------------------------------------
-//
-// Copyright (C) 2013 James Haley et al.
-//
-// 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.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this program.  If not, see http://www.gnu.org/licenses/
-//
-//----------------------------------------------------------------------------
-//
-// DESCRIPTION:
-//
-// Client Interface to RPC Midi Server
-//
-//-----------------------------------------------------------------------------
-
-#ifdef EE_FEATURE_MIDIRPC
-
-#include <windows.h>
-#include "midiproc.h"
-
-#include "../hal/i_timer.h"
-#include "../m_qstr.h"
-
-#if defined(_DEBUG) && defined(EE_RPC_DEBUG)
-#define DEBUGOUT(s) puts(s)
-#else
-#define DEBUGOUT(s)
-#endif
-
-//=============================================================================
-//
-// Data
-//
-
-static unsigned char *szStringBinding; // RPC client binding string
-static bool serverInit = false;        // if true, server was started
-static bool clientInit = false;        // if true, client was bound
-
-// server process information
-static STARTUPINFO         si;
-static PROCESS_INFORMATION pi;
-
-//=============================================================================
-//
-// RPC Memory Management
-//
-
-void __RPC_FAR * __RPC_USER midl_user_allocate(size_t size)
-{
-   return malloc(size);
-}
-
-void __RPC_USER midl_user_free(void __RPC_FAR *p)
-{
-   free(p);
-}
-
-//=============================================================================
-//
-// RPC Wrappers
-//
-
-//
-// CHECK_RPC_STATUS
-//
-// If either server or client initialization failed, we don't try to make any
-// RPC calls.
-//
-#define CHECK_RPC_STATUS()        \
-   if(!serverInit || !clientInit) \
-      return false
-
-#define MIDIRPC_MAXTRIES 50 // This number * 10 is the amount of time you can try to wait for.
-
-static bool I_MidiRPCWaitForServer()
-{
-   int tries = 0;
-   while(RpcMgmtIsServerListening(hMidiRPCBinding) != RPC_S_OK)
-   {
-      i_haltimer.Sleep(10);
-      if(++tries >= MIDIRPC_MAXTRIES)
-         return false;
-   }
-   return true;
-}
-
-//
-// I_MidiRPCRegisterSong
-//
-// Prepare the RPC MIDI engine to receive new song data, and transmit the song
-// data to the server process.
-//
-bool I_MidiRPCRegisterSong(void *data, int size)
-{
-   unsigned int rpcSize = static_cast<unsigned int>(size);
-
-   CHECK_RPC_STATUS();
-
-   RpcTryExcept
-   {
-      MidiRPC_PrepareNewSong();
-
-      // TODO: Try passing it as one chunk; if this ends up not working, 
-      // I'll have to stream it in as smaller divisions.
-      MidiRPC_AddChunk(rpcSize, static_cast<byte *>(data));
-   }
-   RpcExcept(1)
-   {
-      DEBUGOUT("I_MidiRPCRegisterSong failed");
-      return false;
-   }
-   RpcEndExcept
-
-   DEBUGOUT("I_MidiRPCRegisterSong succeeded");
-   return true;
-}
-
-//
-// I_MidiRPCPlaySong
-//
-// Tell the RPC server to start playing a song.
-//
-bool I_MidiRPCPlaySong(bool looping)
-{
-   CHECK_RPC_STATUS();
-
-   RpcTryExcept
-   {
-      MidiRPC_PlaySong(looping ? TRUE : FALSE);
-   }
-   RpcExcept(1)
-   {
-      DEBUGOUT("I_MidiRPCPlaySong failed");
-      return false;
-   }
-   RpcEndExcept
-
-   DEBUGOUT("I_MidiRPCPlaySong succeeded");
-   return true;
-}
-
-// 
-// I_MidiRPCStopSong
-//
-// Tell the RPC server to stop any currently playing song.
-//
-bool I_MidiRPCStopSong()
-{
-   CHECK_RPC_STATUS();
-
-   RpcTryExcept
-   {
-      MidiRPC_StopSong();
-   }
-   RpcExcept(1)
-   {
-      DEBUGOUT("I_MidiRPCStopSong failed");
-      return false;
-   }
-   RpcEndExcept
-
-   DEBUGOUT("I_MidiRPCStopSong succeeded");
-   return true;
-}
-
-//
-// I_MidiRPCSetVolume
-//
-// Change the volume level of music played by the RPC midi server.
-//
-bool I_MidiRPCSetVolume(int volume)
-{
-   CHECK_RPC_STATUS();
-   
-   RpcTryExcept
-   {
-      MidiRPC_ChangeVolume(volume);
-   }
-   RpcExcept(1)
-   {
-      DEBUGOUT("I_MidiRPCSetVolume failed");
-      return false;
-   }
-   RpcEndExcept
-
-   DEBUGOUT("I_MidiRPCSetVolume succeeded");
-   return true;
-}
-
-//
-// I_MidiRPCPauseSong
-//
-// Pause the music being played by the server. In actuality, due to SDL_mixer
-// limitations, this just temporarily sets the volume to zero.
-//
-bool I_MidiRPCPauseSong()
-{
-   CHECK_RPC_STATUS();
-
-   RpcTryExcept
-   {
-      MidiRPC_PauseSong();
-   }
-   RpcExcept(1)
-   {
-      DEBUGOUT("I_MidiRPCPauseSong failed");
-      return false;
-   }
-   RpcEndExcept
-
-   DEBUGOUT("I_MidiRPCPauseSong succeeded");
-   return true;
-}
-
-//
-// I_MidiRPCResumeSong
-//
-// Resume a song after having paused it.
-//
-bool I_MidiRPCResumeSong()
-{
-   CHECK_RPC_STATUS();
-
-   RpcTryExcept
-   {
-      MidiRPC_ResumeSong();
-   }
-   RpcExcept(1)
-   {
-      DEBUGOUT("I_MidiRPCResumeSong failed");
-      return false;
-   }
-   RpcEndExcept
-
-   DEBUGOUT("I_MidiRPCResumeSong succeeded");
-   return true;
-}
-
-//=============================================================================
-//
-// Public Interface
-//
-
-//
-// I_MidiRPCInitServer
-//
-// Start up the RPC MIDI server.
-//
-bool I_MidiRPCInitServer()
-{
-   struct stat sbuf;
-   char filename[MAX_PATH+1];
-
-   memset(filename, 0, sizeof(filename));
-   GetModuleFileName(NULL, filename, MAX_PATH);
-
-   qstring module;
-
-   module = filename;
-   module.removeFileSpec();
-   module.pathConcatenate("midiproc.exe");
-   DEBUGOUT(module.constPtr());
-
-   // Look for executable file
-   if(stat(module.constPtr(), &sbuf))
-   {
-      DEBUGOUT("Could not find midiproc");
-      return false;
-   }
-
-   si.cb = sizeof(si);
-
-   BOOL result = CreateProcess(module.constPtr(), NULL, NULL, NULL, FALSE,
-                               0, NULL, NULL, &si, &pi);
-
-   if(result)
-   {
-      DEBUGOUT("RPC server started");
-      serverInit = true;
-   }
-   else
-      DEBUGOUT("CreateProcess failed to start midiproc");
-
-   return !!result;
-}
-
-//
-// I_MidiRPCInitClient
-//
-// Initialize client RPC bindings and bind to the server.
-//
-bool I_MidiRPCInitClient()
-{
-   RPC_STATUS status;
-
-   // If server didn't start, client cannot be bound.
-   if(!serverInit)
-      return false;
-
-   // Compose binding string
-   status =
-      RpcStringBindingCompose
-      (
-         NULL,
-         (RPC_CSTR)("ncalrpc"),
-         NULL,
-         (RPC_CSTR)("2d4dc2f9-ce90-4080-8a00-1cb819086970"),
-         NULL,
-         &szStringBinding
-      );
-
-   if(status)
-   {
-      DEBUGOUT("RPC binding composition failed");
-      return false;
-   }
-
-   // Create binding handle
-   status = RpcBindingFromStringBinding(szStringBinding, &hMidiRPCBinding);
-
-   if(status)
-   {
-      DEBUGOUT("RPC client binding failed");
-      return false;
-   }
-
-   DEBUGOUT("RPC client initialized");
-   clientInit = true;
-
-   return I_MidiRPCWaitForServer();
-}
-
-//
-// I_MidiRPCClientShutDown
-//
-// Shutdown the RPC Client
-//
-void I_MidiRPCClientShutDown()
-{
-   // stop the server
-   if(serverInit)
-   {
-      RpcTryExcept
-      {
-         MidiRPC_StopServer();
-      }
-      RpcExcept(1)
-      {
-         DEBUGOUT("Exception thrown when stopping RPC server");
-      }
-      RpcEndExcept
-
-      serverInit = false;
-   }
-
-   if(szStringBinding)
-   {
-      RpcStringFree(&szStringBinding);
-      szStringBinding = NULL;
-   }
-
-   if(hMidiRPCBinding)
-   {
-      RpcBindingFree(&hMidiRPCBinding);
-      hMidiRPCBinding = NULL;
-   }
-
-   clientInit = false;
-}
-
-//
-// I_MidiRPCReady
-//
-// Returns true if both server and client initialized successfully.
-//
-bool I_MidiRPCReady()
-{
-   CHECK_RPC_STATUS();
-
-   return true;
-}
-
-#endif
-
-// EOF
-
-
--- a/src/i_midirpc.h
+++ b/src/i_midirpc.h
@@ -1,12 +1,10 @@
-// Emacs style mode select   -*- C++ -*-
-//-----------------------------------------------------------------------------
 //
-// Copyright (C) 2013 James Haley et al.
+// Copyright(C) 2013 James Haley et al.
 //
-// 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.
+// 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 2
+// of the License, or (at your option) any later version.
 //
 // This program is distributed in the hope that it will be useful,
 // but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,19 +11,9 @@
 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 // GNU General Public License for more details.
 //
-// You should have received a copy of the GNU General Public License
-// along with this program.  If not, see http://www.gnu.org/licenses/
-//
-// Additional terms and conditions compatible with the GPLv3 apply. See the
-// file COPYING-EE for details.
-//
-//----------------------------------------------------------------------------
-//
 // DESCRIPTION:
+//     Client Interface to RPC Midi Server
 //
-// Client Interface to RPC Midi Server
-//
-//-----------------------------------------------------------------------------
 
 #ifndef I_MIDIRPC_H__
 #define I_MIDIRPC_H__