shithub: duke3d

Download patch

ref: b625cffaaaddff5d84483382c083652dac1394f3
parent: 0517615df8ab283df2f09ab29f15827f26914b58
author: unknown <fabien@fabien-PC.(none)>
date: Sat Dec 15 11:27:41 EST 2012

Removed Windows specifc code in Music engine: Relying fully on SDL_Mixer now.

--- a/Game/Game.vcxproj
+++ b/Game/Game.vcxproj
@@ -127,6 +127,7 @@
     <ClCompile Include="src\global.c" />
     <ClCompile Include="src\keyboard.c" />
     <ClCompile Include="src\menues.c" />
+    <ClCompile Include="src\midi\sdl_midi.c" />
     <ClCompile Include="src\player.c" />
     <ClCompile Include="src\premap.c" />
     <ClCompile Include="src\rts.c" />
@@ -133,8 +134,6 @@
     <ClCompile Include="src\scriplib.c" />
     <ClCompile Include="src\sector.c" />
     <ClCompile Include="src\sounds.c" />
-    <ClCompile Include="src\midi\win_midiout.cpp" />
-    <ClCompile Include="src\midi\xmidi.cpp" />
     <ClCompile Include="src\audiolib\dsl.c" />
     <ClCompile Include="src\audiolib\fx_man.c">
       <ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)%(Filename)1.obj</ObjectFileName>
@@ -172,9 +171,6 @@
     <ClInclude Include="src\sounds.h" />
     <ClInclude Include="src\types.h" />
     <ClInclude Include="src\util_lib.h" />
-    <ClInclude Include="src\midi\databuf.h" />
-    <ClInclude Include="src\midi\win_midiout.h" />
-    <ClInclude Include="src\midi\xmidi.h" />
     <ClInclude Include="src\audiolib\assert.h" />
     <ClInclude Include="src\_functio.h" />
     <ClInclude Include="src\console.h" />
--- a/Game/Game.vcxproj.filters
+++ b/Game/Game.vcxproj.filters
@@ -68,12 +68,6 @@
     <ClCompile Include="src\sounds.c">
       <Filter>Source Files</Filter>
     </ClCompile>
-    <ClCompile Include="src\midi\win_midiout.cpp">
-      <Filter>Midi</Filter>
-    </ClCompile>
-    <ClCompile Include="src\midi\xmidi.cpp">
-      <Filter>Midi</Filter>
-    </ClCompile>
     <ClCompile Include="src\audiolib\dsl.c">
       <Filter>Audiolib</Filter>
     </ClCompile>
@@ -110,6 +104,9 @@
     <ClCompile Include="src\cvars.c">
       <Filter>Console Source</Filter>
     </ClCompile>
+    <ClCompile Include="src\midi\sdl_midi.c">
+      <Filter>Midi</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="src\_rts.h">
@@ -171,15 +168,6 @@
     </ClInclude>
     <ClInclude Include="src\util_lib.h">
       <Filter>Header Files</Filter>
-    </ClInclude>
-    <ClInclude Include="src\midi\databuf.h">
-      <Filter>Midi</Filter>
-    </ClInclude>
-    <ClInclude Include="src\midi\win_midiout.h">
-      <Filter>Midi</Filter>
-    </ClInclude>
-    <ClInclude Include="src\midi\xmidi.h">
-      <Filter>Midi</Filter>
     </ClInclude>
     <ClInclude Include="src\audiolib\assert.h">
       <Filter>Audiolib</Filter>
--- a/Game/src/audiolib/music.h
+++ b/Game/src/audiolib/music.h
@@ -31,7 +31,7 @@
 #ifndef __MUSIC_H
 #define __MUSIC_H
 
-#include "duke3d.h"
+#include "../duke3d.h"
 
 #include "sndcards.h"
 
@@ -81,7 +81,7 @@
 void  MUSIC_Continue( void );
 void  MUSIC_Pause( void );
 int   MUSIC_StopSong( void );
-int   MUSIC_PlaySong( char *song, int loopflag );
+int   MUSIC_PlaySong( uint8_t* songData, int loopflag );
 void  MUSIC_SetContext( int context );
 int   MUSIC_GetContext( void );
 void  MUSIC_SetSongTick( uint32_t PositionInTicks );
--- a/Game/src/midi/databuf.h
+++ /dev/null
@@ -1,230 +1,0 @@
-/*
- *  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 Library General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  aint32_t with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
-
-#ifndef DATA_H
-#define DATA_H
-
-#ifdef _WIN32
-   #include "../../../Engine/src/windows/inttypes.h"
-#else
-   #include <inttypes.h>
-#endif
-
-#ifndef ALPHA_LINUX_CXX
-#  include <cstdio>
-#  include <cstring>
-#endif
-#ifdef MACOS
-#  include <cassert>
-#endif
-#include <fstream>
-#include <iomanip>
-
-
-/*
-typedef uint8_t  uint8;
-typedef unsigned short uint16;
-typedef uint32_t uint32;
-
-typedef int8_t sint8;
-typedef signed short sint16;
-typedef int32_t sint32;
-*/
-
-class DataSource
-{
-protected:
-	union uint_float {
-		uint32_t	i;
-		float	f;
-	};
-
-public:
-	DataSource() {};
-	virtual ~DataSource() {};
-	
-	virtual unsigned int read1() =0;
-	virtual uint16_t read2() =0;
-	virtual uint16_t read2high() =0;
-	virtual uint32_t read4() =0;
-	virtual uint32_t read4high() =0;
-	virtual float readf() =0;
-	virtual void read(uint8_t  *, int32_t) =0;
-	
-	virtual void write1(uint32_t) =0;
-	virtual void write2(uint16_t) =0;
-	virtual void write2high(uint16_t) =0;
-	virtual void write4(uint32_t) =0;
-	virtual void write4high(uint32_t) =0;
-	virtual void writef(float) =0;
-	virtual void write(uint8_t  *, int) =0;
-	
-	virtual void seek(unsigned int) =0;
-	virtual void skip(int) =0;
-	virtual unsigned int getSize() =0;
-	virtual unsigned int getPos() =0;
-};
-
-class BufferDataSource: public DataSource
-{
-protected:
-	/* const solely so that no-one accidentally modifies it.
-		data is being passed 'non-const' anyway */
-	const uint8_t  *buf;
-	uint8_t  *buf_ptr;
-	int32_t size;
-public:
-	BufferDataSource(uint8_t  *data, unsigned int len)
-	{
-		// data can be NULL if len is also 0
-//		assert(data!=0 || len==0);
-		buf = buf_ptr = reinterpret_cast<uint8_t *>(data);
-		size = len;
-	};
-	
-	void load(uint8_t  *data, unsigned int len)
-	{
-		// data can be NULL if len is also 0
-		//assert(data!=0 || len==0);
-		buf = buf_ptr = reinterpret_cast<uint8_t *>(data);
-		size = len;
-	};
-	
-	virtual ~BufferDataSource() {};
-	
-	virtual unsigned int read1() 
-	{ 
-		uint8_t  b0;
-		b0 = static_cast<uint8_t >(*buf_ptr++);
-		return (b0);
-	};
-	
-	virtual uint16_t read2()
-	{
-		uint8_t  b0, b1;
-		b0 = static_cast<uint8_t >(*buf_ptr++);
-		b1 = static_cast<uint8_t >(*buf_ptr++);
-		return (b0 | (b1 << 8));
-	};
-	
-	virtual uint16_t read2high()
-	{
-		uint8_t  b0, b1;
-		b1 = static_cast<uint8_t >(*buf_ptr++);
-		b0 = static_cast<uint8_t >(*buf_ptr++);
-		return (b0 | (b1 << 8));
-	};
-	
-	virtual uint32_t read4()
-	{
-		uint8_t  b0, b1, b2, b3;
-		b0 = static_cast<uint8_t >(*buf_ptr++);
-		b1 = static_cast<uint8_t >(*buf_ptr++);
-		b2 = static_cast<uint8_t >(*buf_ptr++);
-		b3 = static_cast<uint8_t >(*buf_ptr++);
-		return (b0 | (b1<<8) | (b2<<16) | (b3<<24));
-	};
-	
-	virtual uint32_t read4high()
-	{
-		uint8_t  b0, b1, b2, b3;
-		b3 = static_cast<uint8_t >(*buf_ptr++);
-		b2 = static_cast<uint8_t >(*buf_ptr++);
-		b1 = static_cast<uint8_t >(*buf_ptr++);
-		b0 = static_cast<uint8_t >(*buf_ptr++);
-		return (b0 | (b1<<8) | (b2<<16) | (b3<<24));
-	};
-	
-	virtual float readf()
-	{
-		uint8_t  b0, b1, b2, b3;
-		b0 = static_cast<uint8_t >(*buf_ptr++);
-		b1 = static_cast<uint8_t >(*buf_ptr++);
-		b2 = static_cast<uint8_t >(*buf_ptr++);
-		b3 = static_cast<uint8_t >(*buf_ptr++);
-		uint_float	uif;
-		uif.i = (b0 | (b1<<8) | (b2<<16) | (b3<<24));
-		return uif.f;
-	};
-	
-	void read(uint8_t  *b, int len) {
-		memcpy(b, buf_ptr, len);
-		buf_ptr += len;
-	};
-	
-	virtual void write1(unsigned int val)
-	{
-		*buf_ptr++ = val & 0xff;
-	};
-	
-	virtual void write2(uint16_t val)
-	{
-		*buf_ptr++ = val & 0xff;
-		*buf_ptr++ = (val>>8) & 0xff;
-	};
-
-	virtual void write2high(uint16_t val)
-	{
-		*buf_ptr++ = (val>>8) & 0xff;
-		*buf_ptr++ = val & 0xff;
-	};
-
-	
-	virtual void write4(uint32_t val)
-	{
-		*buf_ptr++ = val & 0xff;
-		*buf_ptr++ = (val>>8) & 0xff;
-		*buf_ptr++ = (val>>16)&0xff;
-		*buf_ptr++ = (val>>24)&0xff;
-	};
-	
-	virtual void write4high(uint32_t val)
-	{
-		*buf_ptr++ = (val>>24)&0xff;
-		*buf_ptr++ = (val>>16)&0xff;
-		*buf_ptr++ = (val>>8) & 0xff;
-		*buf_ptr++ = val & 0xff;
-	};
-
-	virtual void writef(float val)
-	{
-		uint_float	uif;
-		uif.f = val;
-		*buf_ptr++ = uif.i & 0xff;
-		*buf_ptr++ = (uif.i>>8) & 0xff;
-		*buf_ptr++ = (uif.i>>16)&0xff;
-		*buf_ptr++ = (uif.i>>24)&0xff;
-	};
-	
-	virtual void write(uint8_t  *b, int32_t len)
-	{
-		memcpy(buf_ptr, b, len);
-		buf_ptr += len;
-	};
-	
-	virtual void seek(unsigned int pos) { buf_ptr = const_cast<uint8_t  *>(buf)+pos; };
-	
-	virtual void skip(int pos) { buf_ptr += pos; };
-	
-	virtual unsigned int getSize() { return size; };
-	
-	virtual unsigned int getPos() { return (buf_ptr-buf); };
-	
-	uint8_t  *getPtr() { return buf_ptr; };
-};
-
-
-#endif
--- a/Game/src/midi/win_midiout.cpp
+++ /dev/null
@@ -1,1287 +1,0 @@
-/*
-Copyright (C) 2000, 2001, 2002  Ryan Nunn
-
-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
-aint32_t with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-*/
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#if (__GNUG__ >= 2) && (!defined WIN32)
-#  pragma interface
-#endif
-
-//Windows-specific code
-#ifdef WIN32
-
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
-#endif
-
-// These will prevent inclusion of mmsystem sections
-#define MMNODRV         // Installable driver support
-#define MMNOSOUND       // Sound support
-#define MMNOWAVE        // Waveform support
-#define MMNOAUX         // Auxiliary audio support
-#define MMNOMIXER       // Mixer support
-#define MMNOTIMER       // Timer support
-#define MMNOJOY         // Joystick support
-#define MMNOMCI         // MCI support
-#define MMNOMMIO        // Multimedia file I/O support
-
-#include <windows.h>
-#include <mmsystem.h>
-#include <winbase.h>
-
-#include <string>
-#include <iostream>
-#include <cstdio>
-#include <cstdlib>
-#include <cstdarg>
-#include <cstring>
-#include <cassert>
-
-#include "win_midiout.h"
-#include "SDL_mixer.h"
-
-#define W32MO_THREAD_COM_READY			0
-#define W32MO_THREAD_COM_PLAY			1
-#define W32MO_THREAD_COM_STOP			2
-#define W32MO_THREAD_COM_INIT			3
-#define W32MO_THREAD_COM_INIT_FAILED	4
-#define W32MO_THREAD_COM_EXIT			-1
-
-const unsigned short Windows_MidiOut::centre_value = 0x2000;
-const uint8_t  Windows_MidiOut::fine_value = centre_value & 127;
-const uint8_t  Windows_MidiOut::coarse_value = centre_value >> 7;
-const unsigned short Windows_MidiOut::combined_value = (coarse_value << 8) | fine_value;
-
-#define MUSIC_STATUS_IDLE    0
-#define MUSIC_STATUS_PLAYING 1
-
-uint8_t  nMusicState = MUSIC_STATUS_IDLE;
-
-Mix_Music *music;
-
-//#define DO_SMP_TEST
-
-#ifdef DO_SMP_TEST
-#define giveinfo() std::cerr << __FILE__ << ":" << __LINE__ << std::endl; std::cerr.flush();
-#else
-#define giveinfo()
-#endif
-
-using std::string;
-using std::cout;
-using std::cerr;
-using std::endl;
-
-
-Windows_MidiOut::Windows_MidiOut() : 
-dev_num(-1), 
-new_volume(-1)
-{
-	giveinfo();
-	InterlockedExchange (&playing, false);
-	InterlockedExchange (&s_playing, false);
-	InterlockedExchange (&is_available, false);
-	giveinfo();
-	init_device();
-	giveinfo();
-}
-
-Windows_MidiOut::~Windows_MidiOut()
-{
-	giveinfo();
-	if (!is_available) return;
-
-	giveinfo();
-	while (thread_com != W32MO_THREAD_COM_READY) Sleep (1);
-	
-	giveinfo();
-	InterlockedExchange (&thread_com, W32MO_THREAD_COM_EXIT);
-
-	giveinfo();
-	int count = 0;
-	
-	giveinfo();
-	while (count < 100)
-	{
-		giveinfo();
-		DWORD code;
-		GetExitCodeThread (thread_handle, &code);
-		
-		giveinfo();
-		// Wait 1 MS before trying again
-		if (code == STILL_ACTIVE) Sleep (10);
-		else break;
-		giveinfo();
-		
-		count++;
-	}
-
-	// We waited a second and it still didn't terminate
-	giveinfo();
-	if (count == 100 && is_available)
-		TerminateThread (thread_handle, 1);
-
-	giveinfo();
-	InterlockedExchange (&is_available, false);
-	giveinfo();
-}
-
-void Windows_MidiOut::init_device()
-{
-	string s;
-		
-	// Opened, lets open the thread
-	giveinfo();
-	InterlockedExchange (&thread_com, W32MO_THREAD_COM_INIT);
-	
-	// Get Win32 Midi Device num
-	dev_num = get_MusicDevice();//0;//MidiDevice;//0;//-1;
-
-	giveinfo();
-	thread_handle = (HANDLE*) CreateThread (NULL, 0, thread_start, this, 0, &thread_id);
-	
-	giveinfo();
-	while (thread_com == W32MO_THREAD_COM_INIT) Sleep (1);
-
-	giveinfo();
-	if (thread_com == W32MO_THREAD_COM_INIT_FAILED) cerr << "Failure to initialize midi playing thread" << endl;
-	giveinfo();
-}
-
-DWORD __stdcall Windows_MidiOut::thread_start(void *data)
-{
-	giveinfo();
-	Windows_MidiOut *ptr=static_cast<Windows_MidiOut *>(data);
-	giveinfo();
-	return ptr->thread_main();
-}
-
-DWORD Windows_MidiOut::thread_main()
-{
-	int i;
-	thread_data = NULL;
-	giveinfo();
-	InterlockedExchange (&playing, false);
-	InterlockedExchange (&s_playing, false);
-
-	giveinfo();
-
-	// List all the midi devices.
-	MIDIOUTCAPS caps;
-	int32_t dev_count = (signed long) midiOutGetNumDevs(); 
-	std::cout << dev_count << " Midi Devices Detected" << endl;
-	std::cout << "Listing midi devices:" << endl;
-
-	for (i = -1; i < dev_count; i++)
-	{
-		midiOutGetDevCaps ((UINT) i, &caps, sizeof(caps));
-		std::cout << i << ": " << caps.szPname << endl;
-	}
-
-	if (dev_num < -1 || dev_num >= dev_count)
-	{
-		std::cerr << "Warning Midi device in config is out of range." << endl;
-		dev_num = -1;
-	}
-	midiOutGetDevCaps ((UINT) dev_num, &caps, sizeof(caps));
-	std::cout << "Using device " << dev_num << ": "<< caps.szPname << endl;
-
-	UINT mmsys_err = midiOutOpen (&midi_port, dev_num, 0, 0, 0);
-
-	giveinfo();
-	if (mmsys_err != MMSYSERR_NOERROR)
-	{
-		char  buf[512];
-
-		giveinfo();
-		midiOutGetErrorText(mmsys_err, buf, 512);
-		cerr << "Unable to open device: " << buf << endl;
-		giveinfo();
-		InterlockedExchange (&thread_com, W32MO_THREAD_COM_INIT_FAILED);
-		giveinfo();
-		return 1;
-	}
-	giveinfo();
-	InterlockedExchange (&is_available, true);
-	
-//	SetThreadPriority (thread_handle, THREAD_PRIORITY_HIGHEST);
-	giveinfo();
-	SetThreadPriority (thread_handle, THREAD_PRIORITY_TIME_CRITICAL);
-	
-	giveinfo();
-	InterlockedExchange (&thread_com, W32MO_THREAD_COM_READY);
-	InterlockedExchange (&sfx_com, W32MO_THREAD_COM_READY);
-
-	giveinfo();
-	thread_play();
-	giveinfo();
-
-	giveinfo();
-	Sleep(100);
-	midiOutClose (midi_port);
-	Sleep(100);
-	giveinfo();
-	giveinfo();
-	return 0;
-}
-
-void Windows_MidiOut::thread_play ()
-{
-	int				repeat = false;
-	uint32_t			aim = 0;
-	int32_t			diff = 0;
-	uint32_t			last_tick = 0;
-	XMIDIEventList	*evntlist = NULL;
-	midi_event		*event = NULL;
-	NoteStack		notes_on;
-	midi_event		*note = NULL;
-
-	//
-	// Xmidi Looping
-	//
-
-	// The for loop event
-	midi_event	*loop_event[XMIDI_MAX_FOR_LOOP_COUNT];
-
-	// The amount of times we have left that we can loop
-	int		loop_count[XMIDI_MAX_FOR_LOOP_COUNT];
-
-	// The level of the loop we are currently in
-	int		loop_num = -1;		
-
-	giveinfo();
-
-	int				s_track = 0;
-	uint32_t			s_aim = 0;
-	int32_t			s_diff = 0;
-	uint32_t			s_last_tick = 0;
-	NoteStack		s_notes_on;
-	XMIDIEventList	*s_evntlist = NULL;
-	midi_event		*s_event = NULL;
-
-	giveinfo();
-
-	vol_multi = 0xFF;
-
-	// Play while there isn't a message waiting
-	while (1)
-	{
-		if (thread_com == W32MO_THREAD_COM_EXIT && !playing && !s_playing) break;
-		
-		// Volume settings
-		if (new_volume != -1) {
-			vol_multi = new_volume;
-			new_volume = -1;
-
-			for (int i = 0; i < 16; i++) {
-				uint32_t message = i;
-				message |= MIDI_STATUS_CONTROLLER << 4;
-				message |= 7 << 8;
-				message |= ((volumes[i] * vol_multi)/0xFF)<<16;
-				midiOutShortMsg (midi_port,  message);
-			}
-		}
-
-		if (thread_com == W32MO_THREAD_COM_STOP)
-		{
-			giveinfo();
-			InterlockedExchange (&playing, FALSE);
-			InterlockedExchange (&thread_com, W32MO_THREAD_COM_READY);
-
-			// Handle note off's here
-			while (note = notes_on.Pop())
-				midiOutShortMsg (midi_port, note->status + (note->data[0] << 8));
-
-			giveinfo();
-		 	// Clean up
-			for (int i = 0; i < 16; i++) reset_channel (i); 
-
-			midiOutReset (midi_port);
-			giveinfo();
-			if (evntlist) evntlist->DecerementCounter();
-			giveinfo();
-			evntlist = NULL;
-			event = NULL;
-			giveinfo();
-
-			// If stop was requested, we are ready to receive another song
-
-			loop_num = -1;
-
-			wmoInitClock ();
-			last_tick = 0;
-		}
-
-		// Handle note off's here
-		while (note = notes_on.PopTime(wmoGetRealTime()))
-			midiOutShortMsg (midi_port, note->status + (note->data[0] << 8));
-
-		while (note = s_notes_on.PopTime(wmoGetRealTime()))
-			midiOutShortMsg (midi_port, note->status + (note->data[0] << 8));
-
-		while (event && thread_com != W32MO_THREAD_COM_STOP)
-		{
-	 		aim = (event->time-last_tick)*50;
-			diff = aim - wmoGetTime ();
-
-			if (diff > 0) break;
-
-			last_tick = event->time;
-			wmoAddOffset(aim);
-		
-				// XMIDI For Loop
-			if ((event->status >> 4) == MIDI_STATUS_CONTROLLER && event->data[0] == XMIDI_CONTROLLER_FOR_LOOP)
-			{
-				if (loop_num < XMIDI_MAX_FOR_LOOP_COUNT) loop_num++;
-
-				loop_count[loop_num] = event->data[1];
-				loop_event[loop_num] = event;
-
-			}	// XMIDI Next/Break
-			else if ((event->status >> 4) == MIDI_STATUS_CONTROLLER && event->data[0] == XMIDI_CONTROLLER_NEXT_BREAK)
-			{
-				if (loop_num != -1)
-				{
-					if (event->data[1] < 64)
-					{
-						loop_num--;
-					}
-				}
-				event = NULL;
-
-			}	// XMIDI Callback Trigger
-			else if ((event->status >> 4) == MIDI_STATUS_CONTROLLER && event->data[0] == XMIDI_CONTROLLER_CALLBACK_TRIG)
-			{
-				// TODO
-			}	// Not SysEx
-			else if (event->status < 0xF0)
-			{
-				unsigned int type = event->status >> 4;
-				uint32_t data = event->data[0] | (event->data[1] << 8);
-
-				// Channel volume
-				if (type == MIDI_STATUS_CONTROLLER && event->data[0] == 0x7) {
-					volumes[event->status &0xF] = event->data[1];
-					data = event->data[0] | (((event->data[1] * vol_multi)/0xFF)<<8);
-				}
-
-				if ((type != MIDI_STATUS_NOTE_ON || event->data[1]) && type != MIDI_STATUS_NOTE_OFF) {
-					if (type == MIDI_STATUS_NOTE_ON) {
-						notes_on.Remove(event);
-						notes_on.Push (event, event->duration * 50 + wmoGetStart());
-					}
-
-					midiOutShortMsg (midi_port, event->status | (data<<8));
-				}
-			}
-		
-		 	if (event) event = event->next;
-	
-	 		if (!event || thread_com != W32MO_THREAD_COM_READY)
-		 	{
-				bool clean = !repeat || (thread_com != W32MO_THREAD_COM_READY) || last_tick == 0;
-
-		 		if (clean)
-		 		{
-					InterlockedExchange (&playing, FALSE);
-					if (thread_com == W32MO_THREAD_COM_STOP)
-						InterlockedExchange (&thread_com, W32MO_THREAD_COM_READY);
-
-					// Handle note off's here
-					while (note = notes_on.Pop())
-						midiOutShortMsg (midi_port, note->status + (note->data[0] << 8));
-
-		 			// Clean up
-					for (int i = 0; i < 16; i++) reset_channel (i); 
-					midiOutReset (midi_port);
-					if (evntlist) evntlist->DecerementCounter();
-					evntlist = NULL;
-					event = NULL;
-
-					loop_num = -1;
-					wmoInitClock ();
-		 		}
-
-				last_tick = 0;
-
-				if (evntlist)
-				{
-	 				if (loop_num == -1) event = evntlist->events;
-					else
-					{
-						event = loop_event[loop_num]->next;
-						last_tick = loop_event[loop_num]->time;
-
-						if (loop_count[loop_num])
-							if (!--loop_count[loop_num])
-								loop_num--;
-					}
-				}
-		 	}
-		}
-
-
-		// Got issued a music play command
-		// set up the music playing routine
-		if (thread_com == W32MO_THREAD_COM_PLAY)
-		{
-			// Handle note off's here
-			while (note = notes_on.Pop())
-				midiOutShortMsg (midi_port, note->status + (note->data[0] << 8));
-
-			// Manual Reset since I don't trust midiOutReset()
-			giveinfo();
-			for (int i = 0; i < 16; i++) reset_channel (i);
-			midiOutReset (midi_port);
-
-			if (evntlist) evntlist->DecerementCounter();
-			evntlist = NULL;
-			event = NULL;
-			InterlockedExchange (&playing, FALSE);
-
-			// Make sure that the data exists
-			giveinfo();
-			while (!thread_data) Sleep(1);
-			
-			giveinfo();
-			evntlist = thread_data->list;
-			repeat = thread_data->repeat;
-
-			giveinfo();
-			InterlockedExchange ((LONG*) &thread_data, (LONG) NULL);
-			giveinfo();
-			InterlockedExchange (&thread_com, W32MO_THREAD_COM_READY);
-			
-			giveinfo();
-			if (evntlist) event = evntlist->events;
-			else event = 0;
-
-			giveinfo();
-			last_tick = 0;
-			
-			giveinfo();
-			wmoInitClock ();
-	
-			// Reset XMIDI Looping
-			loop_num = -1;
-
-			giveinfo();
-			InterlockedExchange (&playing, true);
-		}
-
-	 	if (s_event)
-	 	{
-	 		s_aim = (s_event->time-s_last_tick)*50;
-			s_diff = s_aim - wmoGetSFXTime ();
-	 	}
-	 	else 
-	 		s_diff = 1;
-	
-		if (s_diff <= 0)
-		{
-			s_last_tick = s_event->time;
-			wmoAddSFXOffset(s_aim);
-		
-			// Not SysEx
-			if ((s_event->status >> 4) != MIDI_STATUS_SYSEX)
-			{
-				int type = s_event->status >> 4;
-
-				if ((type != MIDI_STATUS_NOTE_ON || s_event->data[1]) && type != MIDI_STATUS_NOTE_OFF) {
-					if (type == MIDI_STATUS_NOTE_ON) {
-						s_notes_on.Remove(s_event);
-						s_notes_on.Push (s_event, s_event->duration * 50 + wmoGetSFXStart());
-					}
-
-					midiOutShortMsg (midi_port, s_event->status + (s_event->data[0] << 8) + (s_event->data[1] << 16));
-				}
-				s_track |= 1 << (s_event->status & 0xF);
-			}
-
-		 	s_event = s_event->next;
-		}
-	 	if (s_evntlist && (!s_event || thread_com == W32MO_THREAD_COM_EXIT || sfx_com != W32MO_THREAD_COM_READY))
-		{
-		 	// Play all the remaining note offs 
-			while (note = s_notes_on.Pop())
-				midiOutShortMsg (midi_port, note->status + (note->data[0] << 8));
-		 	
-		 	// Also reset the played tracks
-			for (int i = 0; i < 16; i++) if ((s_track >> i)&1) reset_channel (i);
-
-			s_evntlist->DecerementCounter();
-			s_evntlist = NULL;
-			s_event = NULL;
-			InterlockedExchange (&s_playing, false);
-			if (sfx_com != W32MO_THREAD_COM_PLAY) InterlockedExchange (&sfx_com, W32MO_THREAD_COM_READY);
-		}
-
-		// Got issued a sound effect play command
-		// set up the sound effect playing routine
-		if (!s_evntlist && sfx_com == W32MO_THREAD_COM_PLAY)
-		{
-			giveinfo();
-			cout << "Play sfx command" << endl;
-
-		 	// Play all the remaining note offs 
-			while (note = s_notes_on.Pop())
-				midiOutShortMsg (midi_port, note->status + (note->data[0] << 8));
-
-			// Make sure that the data exists
-			while (!sfx_data) Sleep(1);
-			
-			giveinfo();
-			s_evntlist = sfx_data->list;
-
-			giveinfo();
-			InterlockedExchange ((LONG*) &sfx_data, (LONG) NULL);
-			InterlockedExchange (&sfx_com, W32MO_THREAD_COM_READY);
-			giveinfo();
-			
-			if (s_evntlist) s_event = s_evntlist->events;
-			else s_event = 0;
-
-			giveinfo();
-	
-			s_last_tick = 0;
-			
-			giveinfo();
-			wmoInitSFXClock ();
-
-			giveinfo();
-			InterlockedExchange (&s_playing, true);
-			
-			giveinfo();
-			// Reset thet track counter
-			s_track = 0;
-		}
-
-	 	if (event)
-	 	{
-	 		aim = (event->time-last_tick)*50;
-			diff = aim - wmoGetTime ();
-	 	}
-	 	else 
-	 		diff = 6;
-
-	 	if (s_event)
-	 	{
-	 		s_aim = (s_event->time-s_last_tick)*50;
-			s_diff = s_aim - wmoGetSFXTime ();
-	 	}
-	 	else 
-	 		s_diff = 6;
-
-		//std::cout << sfx_com << endl;
-
-		if (diff > 5 && s_diff > 5) Sleep (1);
-	}
-	// Handle note off's here
-	while (note = notes_on.Pop())
-		midiOutShortMsg (midi_port, note->status + (note->data[0] << 8));
-
-	// Play all the remaining note offs 
-	while (note = s_notes_on.PopTime(wmoGetRealTime()))
-		midiOutShortMsg (midi_port, note->status + (note->data[0] << 8));
-
-	if (evntlist) evntlist->DecerementCounter();
-	evntlist = NULL;
-	if (s_evntlist) s_evntlist->DecerementCounter();
-	s_evntlist = NULL;
-	for (int i = 0; i < 16; i++) reset_channel (i); 
-	midiOutReset (midi_port);
-	InterlockedExchange (&new_volume, -1);
-}
-
-void Windows_MidiOut::reset_channel (int i)
-{
-	// Pitch Wheel
-	midiOutShortMsg (midi_port, i | (MIDI_STATUS_PITCH_WHEEL << 4) | (combined_value << 8));
-	
-	// All controllers off
-	midiOutShortMsg (midi_port, i | (MIDI_STATUS_CONTROLLER << 4) | (121 << 8));
-
-	// All notes off
-	midiOutShortMsg (midi_port, i | (MIDI_STATUS_CONTROLLER << 4) | (123 << 8));
-
-	// Bank Select
-	midiOutShortMsg (midi_port, i | (MIDI_STATUS_PROG_CHANGE << 4) | (0 << 8));
-	midiOutShortMsg (midi_port, i | (MIDI_STATUS_CONTROLLER << 4) | (0 << 8));
-	midiOutShortMsg (midi_port, i | (MIDI_STATUS_CONTROLLER << 4) | (32 << 8));
-
-	// Modulation Wheel
-	midiOutShortMsg (midi_port, i | (MIDI_STATUS_CONTROLLER << 4) | (1 << 8) | (coarse_value << 16));
-	midiOutShortMsg (midi_port, i | (MIDI_STATUS_CONTROLLER << 4) | (33 << 8) | (fine_value << 16));
-	
-	// Volume
-	volumes[i] = coarse_value;
-	midiOutShortMsg (midi_port, i | (MIDI_STATUS_CONTROLLER << 4) | (7 << 8) | (((coarse_value*vol_multi)/0xFF) << 16));
-	midiOutShortMsg (midi_port, i | (MIDI_STATUS_CONTROLLER << 4) | (39 << 8) | (fine_value << 16));
-
-	// Pan
-	midiOutShortMsg (midi_port, i | (MIDI_STATUS_CONTROLLER << 4) | (8 << 8) | (coarse_value << 16));
-	midiOutShortMsg (midi_port, i | (MIDI_STATUS_CONTROLLER << 4) | (40 << 8) | (fine_value << 16));
-
-	// Balance
-	midiOutShortMsg (midi_port, i | (MIDI_STATUS_CONTROLLER << 4) | (10 << 8) | (coarse_value << 16));
-	midiOutShortMsg (midi_port, i | (MIDI_STATUS_CONTROLLER << 4) | (42 << 8) | (fine_value << 16));
-
-	// Effects (Reverb)
-	midiOutShortMsg (midi_port, i | (MIDI_STATUS_CONTROLLER << 4) | (91 << 8));
-
-	// Chorus
-	midiOutShortMsg (midi_port, i | (MIDI_STATUS_CONTROLLER << 4) | (93 << 8));
-}
-
-void Windows_MidiOut::start_track (XMIDIEventList *xmidi, bool repeat)
-{
-	giveinfo();
-	if (!is_available)
-		init_device();
-
-	giveinfo();
-	if (!is_available)
-		return;
-
-	giveinfo();
-	while (thread_com != W32MO_THREAD_COM_READY) Sleep (1);
-	
-	giveinfo();
-	xmidi->IncerementCounter();
-	data.list = xmidi;
-	data.repeat = repeat;
-//	xmidi->Write("winmidi_out.mid");
-	
-	giveinfo();
-	InterlockedExchange ((LONG*) &thread_data, (LONG) &data);
-	giveinfo();
-	InterlockedExchange (&thread_com, W32MO_THREAD_COM_PLAY);
-	giveinfo();
-}
-
-void Windows_MidiOut::start_sfx(XMIDIEventList *xmidi)
-{
-	giveinfo();
-	if (!is_available)
-		init_device();
-
-	giveinfo();
-	if (!is_available)
-		return;
-	
-	giveinfo();
-	while (sfx_com != W32MO_THREAD_COM_READY) Sleep (1);
-
-	giveinfo();
-	xmidi->IncerementCounter();
-	sdata.list = xmidi;
-	sdata.repeat;
-	
-	giveinfo();
-	InterlockedExchange ((LONG*) &sfx_data, (LONG) &sdata);
-	giveinfo();
-	InterlockedExchange (&sfx_com, W32MO_THREAD_COM_PLAY);
-	giveinfo();
-}
-
-
-void Windows_MidiOut::stop_track(void)
-{
-	giveinfo();
-	if (!is_available)
-		return;
-
-	giveinfo();
-	if (!playing) return;
-
-	giveinfo();
-	while (thread_com != W32MO_THREAD_COM_READY) Sleep (1);
-	giveinfo();
-	InterlockedExchange (&thread_com, W32MO_THREAD_COM_STOP);
-	giveinfo();
-	while (thread_com != W32MO_THREAD_COM_READY) Sleep (1);
-	giveinfo();
-}
-
-void Windows_MidiOut::stop_sfx(void)
-{
-	giveinfo();
-	if (!is_available)
-		return;
-
-	giveinfo();
-	if (!s_playing) return;
-
-	giveinfo();
-	while (sfx_com != W32MO_THREAD_COM_READY) Sleep (1);
-	giveinfo();
-	InterlockedExchange (&sfx_com, W32MO_THREAD_COM_STOP);
-	giveinfo();
-}
-
-bool Windows_MidiOut::is_playing(void)
-{
-	giveinfo();
-	return playing!=0;
-}
-
-const char  *Windows_MidiOut::copyright(void)
-{
-	giveinfo();
-	return "Internal Win32 Midiout Midi Player for Pentagram. Version 1.2a";
-}
-
-//
-// PSMDEX - Pentagram Streaming Midi Driver Extensions
-//
-
-int Windows_MidiOut::max_streams()
-{
-	return 1;
-}
-
-void Windows_MidiOut::start_stream(int str_num, XMIDIEventList *eventlist, bool repeat, bool activate, int vol)
-{
-	stop_track();
-	set_volume(0, vol);
-	start_track(eventlist, repeat);
-}
-
-void Windows_MidiOut::activate_stream(int str_num)
-{
-
-}
-
-void Windows_MidiOut::stop_stream(int str_num)
-{
-	stop_track();
-}
-
-void Windows_MidiOut::set_volume(int str_num, int level)
-{
-	if (!is_available) return;
-
-	while (new_volume != -1) Sleep (1);
-	InterlockedExchange (&new_volume, level);
-}
-
-bool Windows_MidiOut::is_playing(int str_num)
-{
-	return is_playing();
-}
-
-int Windows_MidiOut::get_active()
-{ 
-	return 0;
-}
-
-extern "C"
-{
-    #include "../duke3d.h"
-
-    int get_MusicDevice()
-    {
-        return MusicDevice;
-    }
-}
-
-extern "C"
-{
-
-// The music functions...
-
-#include "../duke3d.h"
-#include "cache1d.h"
-
-static char  warningMessage[80];
-static char  errorMessage[80];
-
-char  *MUSIC_ErrorString(int ErrorNumber)
-{
-    switch (ErrorNumber)
-    {
-        case MUSIC_Warning:
-            return(warningMessage);
-
-        case MUSIC_Error:
-            return(errorMessage);
-
-        case MUSIC_Ok:
-            return("OK; no error.");
-
-        case MUSIC_ASSVersion:
-            return("Incorrect sound library version.");
-
-        case MUSIC_SoundCardError:
-            return("General sound card error.");
-
-        case MUSIC_InvalidCard:
-            return("Invalid sound card.");
-
-        case MUSIC_MidiError:
-            return("MIDI error.");
-
-        case MUSIC_MPU401Error:
-            return("MPU401 error.");
-
-        case MUSIC_TaskManError:
-            return("Task Manager error.");
-
-        case MUSIC_FMNotDetected:
-            return("FM not detected error.");
-
-        case MUSIC_DPMI_Error:
-            return("DPMI error.");
-
-        default:
-            return("Unknown error.");
-    } // switch
-
-    assert(0);    // shouldn't hit this point.
-    return(NULL);
-} // MUSIC_ErrorString
-
-
-static int music_initialized = 0, ext_music_initialized = 1;
-static int music_context = 0;
-static int music_loopflag = MUSIC_PlayOnce;
-static Windows_MidiOut *midi_device = NULL;
-
-extern void musdebug(const char  *fmt, ...);
-extern void init_debugging(void);
-extern void setWarningMessage(const char  *msg);
-extern void setErrorMessage(const char  *msg);
-extern int MUSIC_ErrorCode;
-#define __FX_TRUE  (1 == 1)
-#define __FX_FALSE (!__FX_TRUE)
-
-#pragma message (" The win_midi code is temp until the SDL midi code functions properly ")
-
-#pragma message (" STUBBED musdebug ")
-void musdebug(const char  *fmt, ...)
-{
-#if 0
-    va_list ap;
-
-    if (false)
-    {
-        fprintf(debug_file, "DUKEMUS: ");
-        va_start(ap, fmt);
-        vfprintf(debug_file, fmt, ap);
-        va_end(ap);
-        fprintf(debug_file, "\n");
-        fflush(debug_file);
-    } // if
-#endif
-} // snddebug
-
-#pragma message (" STUBBED setErrorMessage ")
-static void setErrorMessage(const char  *msg)
-{
-#if 0
-    strncpy(errorMessage, msg, sizeof (errorMessage));
-    // strncpy() doesn't add the null uint8_t  if there isn't room...
-    errorMessage[sizeof (errorMessage) - 1] = '\0';
-    snddebug("Error message set to [%s].", errorMessage);
-#endif
-} // setErrorMessage
-
-#pragma message (" STUBBED init_debugging ")
-static void init_debugging(void)
-{
-
-}
-
-
-int MUSIC_Init(int SoundCard, int Address)
-{
-    init_debugging();
-
-    musdebug("INIT! card=>%d, address=>%d...", SoundCard, Address);
-
-    if (music_initialized)
-    {
-        setErrorMessage("Music system is already initialized.");
-        return(MUSIC_Error);
-    } // if
-    
-    music_initialized = 1;
-	
-	midi_device = new Windows_MidiOut();
-
-	if(Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 1024)==-1) {
-	    printf("Mix_OpenAudio: %s\n", Mix_GetError());
-	}
-	else {
-	    ext_music_initialized = 1;
-	}
-
-    
-    return(MUSIC_Ok);
-} // MUSIC_Init
-
-
-int MUSIC_Shutdown(void)
-{
-    musdebug("shutting down sound subsystem.");
-
-    if ((!music_initialized) && (!ext_music_initialized))
-    {
-        setErrorMessage("Music system is not currently initialized.");
-        return(MUSIC_Error);
-    } // if
-
-    if(midi_device)
-	delete midi_device;
-	midi_device = 0;
-    music_context = 0;
-    music_initialized = 0;
-    music_loopflag = MUSIC_PlayOnce;
-
-    nMusicState = MUSIC_STATUS_IDLE;
-    
-	return(MUSIC_Ok);
-} // MUSIC_Shutdown
-
-
-void MUSIC_SetMaxFMMidiChannel(int channel)
-{
-    musdebug("STUB ... MUSIC_SetMaxFMMidiChannel(%d).\n", channel);
-} // MUSIC_SetMaxFMMidiChannel
-
-
-void MUSIC_SetVolume(int volume)
-{
-	if(midi_device)
-	midi_device->set_volume(0,volume);
-
-	if (ext_music_initialized == 1)
-	Mix_VolumeMusic((int)(volume / 2));
-
-}
-
-void MUSIC_SetMidiChannelVolume(int channel, int volume)
-{
-    musdebug("STUB ... MUSIC_SetMidiChannelVolume(%d, %d).\n", channel, volume);
-} // MUSIC_SetMidiChannelVolume
-
-
-void MUSIC_ResetMidiChannelVolumes(void)
-{
-    musdebug("STUB ... MUSIC_ResetMidiChannelVolumes().\n");
-} // MUSIC_ResetMidiChannelVolumes
-
-
-int MUSIC_GetVolume(void)
-{
-	if(midi_device)
-	return midi_device->vol_multi;
-	else
-	return 0;
-} // MUSIC_GetVolume
-
-
-void MUSIC_SetLoopFlag(int loopflag)
-{
-    music_loopflag = loopflag;
-} // MUSIC_SetLoopFlag
-
-
-int MUSIC_SongPlaying(void)
-{
-    if (ext_music_initialized)
-	{
-	 return((Mix_PlayingMusic()) ? __FX_TRUE : __FX_FALSE);
-	}
-	else
-	{
-		if(midi_device)
-			return midi_device->is_playing()?__FX_TRUE : __FX_FALSE;
-		else
-			return __FX_FALSE;
-	}
-
-} // MUSIC_SongPlaying
-
-
-void MUSIC_Continue(void)
-{
-    if (Mix_PausedMusic())
-        Mix_ResumeMusic();
-    //else if (music_songdata)
-      //  MUSIC_PlaySong(music_songdata, MUSIC_PlayOnce);
-} // MUSIC_Continue
-
-
-void MUSIC_Pause(void)
-{
-    Mix_PauseMusic();
-} // MUSIC_Pause
-
-
-int MUSIC_StopSong(void)
-{
-    if ( (Mix_PlayingMusic()) || (Mix_PausedMusic()) )
-	{
-        Mix_HaltMusic();
-
-		if (music) Mix_FreeMusic(music);
-		
-		nMusicState = MUSIC_STATUS_IDLE;
-	}
-    
-	if(midi_device) midi_device->stop_stream(0);
-
-    return(MUSIC_Ok);
-} // MUSIC_StopSong
-
-       
-int MUSIC_PlaySong(char  *songFilename, int loopflag)
-{
-    int32_t GRPFileHandle;
-    SDL_RWops *rw;
-
-    MUSIC_StopSong();
-
-    //music_songdata = song;
-
-    // !!! FIXME: This could be a problem...SDL/SDL_mixer wants a RWops, which
-    // !!! FIXME:  is an i/o abstraction. Since we already have the MIDI data
-    // !!! FIXME:  in memory, we fake it with a memory-based RWops. None of
-    // !!! FIXME:  this is a problem, except the RWops wants to know how big
-    // !!! FIXME:  its memory block is (so it can do things like seek on an
-    // !!! FIXME:  offset from the end of the block), and since we don't have
-    // !!! FIXME:  this information, we have to give it SOMETHING.
-
-   
-	if(midi_device)
-	midi_device->stop_stream(0);
-
-	BufferDataSource mid_data((uint8_t *)song, 1024 * 1024);
-	XMIDI		midfile(&mid_data, XMIDI_CONVERT_EMIDI_GM);
-	XMIDIEventList *eventlist = midfile.GetEventList(0);
-	if (eventlist) 
-	{
-		if(midi_device)
-		midi_device->start_track(eventlist, loopflag?true:false);
-	}
-    
-//STUBBED("Need to use PlaySongROTT.  :(");
-
-    return(MUSIC_Ok);
-} // MUSIC_PlaySong
-
-int MUSIC_PlayExtSong(char  *fn)
-{
-    MUSIC_StopSong();
-
-	if(midi_device)
-	midi_device->stop_stream(0);
-
-    music = Mix_LoadMUS(fn);
-	if(!music) 
-	{
-		printf("Mix_LoadMUS(\"%s\"): %s\n", fn, Mix_GetError());
-		nMusicState = MUSIC_STATUS_IDLE;
-	}
-	else
-	{
-		
-		if(Mix_PlayMusic(music, -1)==-1) 
-		{
-			printf("Mix_PlayMusic: %s\n", Mix_GetError());
-    		nMusicState = MUSIC_STATUS_IDLE;
-		}
-		else 
-		{
-			nMusicState = MUSIC_STATUS_PLAYING;
-		}
-	}
-    
-    return(MUSIC_Ok);
-
-} 
-
-
-extern uint8_t  ApogeePath[256];
-
-static void CheckAndPlayMusicType(const char * szName, const char * szType)
-{
-
-	char  fpath[1024] = {'\0'};
-
-	// Is this a TC?
-	if(game_dir[0] != '\0')
-	{
-		
-	   sprintf(fpath, "%s\\%s%s", game_dir, szName, szType);
-	}
-	else
-	{
-		// FIX_00010: Hi resolution tunes (*.ogg files) are now first searched in .\tunes\ 
-		// and then searched in the main folder. Allows a better separation of files
-		// OGG tunes are NOT required. They are only used if found else normal
-		// MIDI files are used by default for music		
-
-	   sprintf(fpath, "%s\\%s%s", HIRESMUSICPATH, szName, szType);
-	   if (!SafeFileExists(fpath))
-			sprintf(fpath, "%s%s", szName, szType);
-	}
-
-	// Play MP3 file if available
-	if (nMusicState == MUSIC_STATUS_IDLE) 
-	{
-	    //If it exists let's play it.
-	   if (SafeFileExists(fpath)) 
-	   {
-		   MUSIC_PlayExtSong(fpath);
-	   }
-	}
-}
-
-// Duke3D-specific.  --ryan.
-void PlayMusic(char  *fn)
-{
-	short      fp;
-    int32_t        l;
-	char  *cfn;
-	char  *buffer;
-	uint8_t  fpath[19] = {'\0'};
-
-	cfn = fn;
-
-	//GetOnlyNameOfFile(cfn);
-	buffer = strtok(cfn, ".");
-
-	CheckAndPlayMusicType(buffer, ".ogg");
-	CheckAndPlayMusicType(buffer, ".mp3");
-	CheckAndPlayMusicType(buffer, ".mod");
-	CheckAndPlayMusicType(buffer, ".s3m");
-	CheckAndPlayMusicType(buffer, ".it");
-	CheckAndPlayMusicType(buffer, ".xm");
-	CheckAndPlayMusicType(buffer, ".wav");
-
-	// else fall back to the midis.
-	if (nMusicState == MUSIC_STATUS_IDLE) 
-	{
-		if(MusicToggle == 0) return;
-		if(MusicDevice == NumSoundCards) return;
-		if(eightytwofifty && numplayers > 1) return;
-
-		fp = kopen4load(fn,0);
-
-		if(fp == -1) return;
-
-		l = kfilelength( fp );
-		if(l >= 72000)
-		{
-	        kclose(fp);
-			return;
-		}
-
-		kread( fp, MusicPtr, l);
-		kclose( fp );
-		MUSIC_PlaySong( (uint8_t *)MusicPtr, MUSIC_LoopSong );
-	}
-}
-
-
-void MUSIC_SetContext(int context)
-{
-    musdebug("STUB ... MUSIC_SetContext().\n");
-    music_context = context;
-} // MUSIC_SetContext
-
-
-int MUSIC_GetContext(void)
-{
-    return(music_context);
-} // MUSIC_GetContext
-
-
-void MUSIC_SetSongTick(uint32_t PositionInTicks)
-{
-    musdebug("STUB ... MUSIC_SetSongTick().\n");
-} // MUSIC_SetSongTick
-
-
-void MUSIC_SetSongTime(uint32_t milliseconds)
-{
-    musdebug("STUB ... MUSIC_SetSongTime().\n");
-}// MUSIC_SetSongTime
-
-
-void MUSIC_SetSongPosition(int measure, int beat, int tick)
-{
-    musdebug("STUB ... MUSIC_SetSongPosition().\n");
-} // MUSIC_SetSongPosition
-
-
-void MUSIC_GetSongPosition(songposition *pos)
-{
-    musdebug("STUB ... MUSIC_GetSongPosition().\n");
-} // MUSIC_GetSongPosition
-
-
-void MUSIC_GetSongLength(songposition *pos)
-{
-    musdebug("STUB ... MUSIC_GetSongLength().\n");
-} // MUSIC_GetSongLength
-
-
-int MUSIC_FadeVolume(int tovolume, int milliseconds)
-{
- //   Mix_FadeOutMusic(milliseconds);
-    return(MUSIC_Ok);
-} // MUSIC_FadeVolume
-
-
-int MUSIC_FadeActive(void)
-{
-   // return((Mix_FadingMusic() == MIX_FADING_OUT) ? __FX_TRUE : __FX_FALSE);
-	return __FX_FALSE;
-} // MUSIC_FadeActive
-
-
-void MUSIC_StopFade(void)
-{
-    musdebug("STUB ... MUSIC_StopFade().\n");
-} // MUSIC_StopFade
-
-
-void MUSIC_RerouteMidiChannel(int channel, int cdecl ( *function )( int event, int c1, int c2 ))
-{
-    musdebug("STUB ... MUSIC_RerouteMidiChannel().\n");
-} // MUSIC_RerouteMidiChannel
-
-
-void MUSIC_RegisterTimbreBank(uint8_t  *timbres)
-{
-    musdebug("STUB ... MUSIC_RegisterTimbreBank().\n");
-} // MUSIC_RegisterTimbreBank
-
-
-// end of fx_man.c ...
-
-}
-
-
-
-#endif
--- a/Game/src/midi/win_midiout.h
+++ /dev/null
@@ -1,159 +1,0 @@
-/*
-Copyright (C) 2000, 2001, 2002  Ryan Nunn
-
-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
-aint32_t with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-*/
-
-#ifndef WIN_MIDIOUT_H
-#define WIN_MIDIOUT_H
-
-
-
-#if (__GNUG__ >= 2) && (!defined WIN32)
-#  pragma interface
-#endif
-
-#ifdef WIN32
-
-#ifndef WIN32_LEAN_AND_MEAN
-#define WIN32_LEAN_AND_MEAN
-#endif
-
-// These will prevent inclusion of mmsystem sections
-#define MMNODRV         // Installable driver support
-#define MMNOSOUND       // Sound support
-#define MMNOWAVE        // Waveform support
-#define MMNOAUX         // Auxiliary audio support
-#define MMNOMIXER       // Mixer support
-#define MMNOTIMER       // Timer support
-#define MMNOJOY         // Joystick support
-#define MMNOMCI         // MCI support
-#define MMNOMMIO        // Multimedia file I/O support
-
-#include <windows.h>
-#include <mmsystem.h>
-#include "xmidi.h"
-
-#ifdef _WIN32
-   #include "../../Engine/src/windows/inttypes.h"
-   #define inline
-#else
-   #include <inttypes.h>
-#endif
-
-class	Windows_MidiOut
-{
-public:
-	virtual void		start_track(XMIDIEventList *, bool repeat);
-	virtual void		start_sfx(XMIDIEventList *);
-	virtual void		stop_track(void);
-	virtual void		stop_sfx(void);
-	virtual bool		is_playing(void);
-	virtual const char 	*copyright(void);
-
-	// PSMDEX - Pentagram Streaming Midi Driver Extensions
-	virtual int			max_streams();
-	virtual void		start_stream(int str_num, XMIDIEventList *, bool repeat, bool activate, int vol);
-	virtual void		activate_stream(int str_num);
-	virtual void		stop_stream(int str_num);
-	virtual void		set_volume(int str_num, int level);
-	virtual bool		is_playing(int str_num);
-	virtual int			get_active();
-
-	Windows_MidiOut();
-	virtual ~Windows_MidiOut();
-
-//private:
-
-	struct mid_data {
-		XMIDIEventList	*list;
-		bool			repeat;
-	};
-
-	static const unsigned short	centre_value;
-	static const uint8_t 	fine_value;
-	static const uint8_t 	coarse_value;
-	static const unsigned short	combined_value;
-
-	signed int	dev_num;
-	HMIDIOUT	midi_port;
-	
-	HANDLE	 	*thread_handle;
-	DWORD		thread_id;
-
-	// Thread communicatoins
-	LONG		is_available;
-	LONG		playing;
-	LONG		s_playing;
-	LONG		thread_com;
-	LONG		sfx_com;
-
-	LONG		new_volume;
-	LONG		volumes[16];
-	LONG		vol_multi;
-
-	mid_data *thread_data;
-	mid_data *sfx_data;
-
-	mid_data data;
-	mid_data sdata;
-
-	// Methods
-	static DWORD __stdcall thread_start(void *data);
-	void init_device();
-	DWORD thread_main();
-	void thread_play ();
-	void reset_channel (int i);
-
-	// Microsecond Clock
-	uint32_t start;
-	uint32_t sfx_start;
-
-	inline void wmoInitClock ()
-	{ start = GetTickCount()*6; }
-
-	inline void wmoAddOffset (uint32_t offset)
-	{ start += offset; }
-
-	inline uint32_t wmoGetTime ()
-	{ return GetTickCount()*6 - start; }
-
-	inline uint32_t wmoGetStart ()
-	{ return start; }
-
-	inline uint32_t wmoGetRealTime ()
-	{ return GetTickCount()*6; }
-
-	inline void wmoInitSFXClock ()
-	{ sfx_start = GetTickCount()*6; }
-
-	inline void wmoAddSFXOffset (uint32_t offset)
-	{ sfx_start += offset; }
-
-	inline uint32_t wmoGetSFXTime ()
-	{ return GetTickCount()*6 - sfx_start; }
-
-	inline uint32_t wmoGetSFXStart ()
-	{ return sfx_start; }
-};
-
-#endif //WIN32
-
-extern "C"
-{
-    int get_MusicDevice();
-}
-
-#endif //WIN_MIDIOUT_H
--- a/Game/src/midi/xmidi.cpp
+++ /dev/null
@@ -1,1567 +1,0 @@
-/*
- *
- * 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
- * aint32_t with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
- *
- */
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#ifndef ALPHA_LINUX_CXX
-#  include <cassert>
-#  include <cstdio>
-#  include <cmath>
-#  include <iostream>
-#  include <cmath>
-#endif
-#include "xmidi.h"
-
-using std::cerr;
-using std::endl;
-using std::string;
-
-// Here's a bit of joy: WIN32 isn't SMP safe if we use operator new and delete.
-// On the other hand, nothing else is thread-safe if we use malloc()/free().
-// So, we wrap the implementations and use malloc()/calloc()/free() for WIN32, and
-// the C++ thread-safe allocator for other platforms.
-
-template<class T>
-inline T* Malloc(size_t num=1)
-{
-#ifdef WIN32
-	return static_cast<T*>(malloc(num));
-#else
-	return static_cast<T*>(::operator new(num));
-#endif
-}
-
-template<class T>
-inline T* Calloc(size_t num=1,size_t sz=0)
-{
-	if(!sz)
-		sz=sizeof(T);
-#ifdef WIN32
-	return static_cast<T*>(calloc(num,sz));
-#else
-	size_t	total=sz*num;
-	T *tmp=Malloc<T>(total);
-	std::memset(tmp,0,total);
-	return tmp;
-#endif
-}
-
-inline void	Free(void *ptr)
-{
-#ifdef WIN32
-	free(ptr);
-#else
-	::operator delete(ptr);
-#endif
-}
-
-// This is used to correct incorrect patch, vol and pan changes in midi files
-// The bias is just a value to used to work out if a vol and pan beint32_t with a 
-// patch change. This is to ensure that the default state of a midi file is with
-// the tracks centred, unless the first patch change says otherwise.
-#define PATCH_VOL_PAN_BIAS	5
-
-
-// This is a default set of patches to convert from MT32 to GM
-// The index is the MT32 Patch nubmer and the value is the GM Patch
-// This is only suitable for music that doesn'tdo timbre changes
-// XMIDIs that contain Timbre changes will not convert properly
-const uint8_t  XMIDI::mt32asgm[128] = {
-	0,	// 0	Piano 1
-	1,	// 1	Piano 2
-	2,	// 2	Piano 3 (synth)
-	4,	// 3	EPiano 1
-	4,	// 4	EPiano 2
-	5,	// 5	EPiano 3
-	5,	// 6	EPiano 4
-	3,	// 7	Honkytonk
-	16,	// 8	Organ 1
-	17,	// 9	Organ 2
-	18,	// 10	Organ 3
-	16,	// 11	Organ 4
-	19,	// 12	Pipe Organ 1
-	19,	// 13	Pipe Organ 2
-	19,	// 14	Pipe Organ 3
-	21,	// 15	Accordion
-	6,	// 16	Harpsichord 1
-	6,	// 17	Harpsichord 2
-	6,	// 18	Harpsichord 3
-	7,	// 19	Clavinet 1
-	7,	// 20	Clavinet 2
-	7,	// 21	Clavinet 3
-	8,	// 22	Celesta 1
-	8,	// 23	Celesta 2
-	62,	// 24	Synthbrass 1 (62)
-	63,	// 25	Synthbrass 2 (63)
-	62,	// 26	Synthbrass 3 Bank 8
-	63,	// 27	Synthbrass 4 Bank 8
-	38,	// 28	Synthbass 1
-	39,	// 29	Synthbass 2
-	38,	// 30	Synthbass 3 Bank 8
-	39,	// 31	Synthbass 4 Bank 8
-	88,	// 32	Fantasy
-	90,	// 33	Harmonic Pan - No equiv closest is polysynth(90) :(
-	52,	// 34	Choral ?? Currently set to SynthVox(54). Should it be ChoirAhhs(52)???
-	92,	// 35	Glass
-	97,	// 36	Soundtrack
-	99,	// 37	Atmosphere
-	14,	// 38	Warmbell, sounds kind of like crystal(98) perhaps Tubular Bells(14) would be better. It is!
-	54,	// 39	FunnyVox, sounds alot like Bagpipe(109) and Shania(111)
-	98,	// 40	EchoBell, no real equiv, sounds like Crystal(98)
-	96,	// 41	IceRain
-	68,	// 42	Oboe 2001, no equiv, just patching it to normal oboe(68)
-	95,	// 43	EchoPans, no equiv, setting to SweepPad
-	81,	// 44	DoctorSolo Bank 8
-	87,	// 45	SchoolDaze, no real equiv
-	112,	// 46	Bell Singer
-	80,	// 47	SquareWave
-	48,	// 48	Strings 1
-	48,	// 49	Strings 2 - should be 49
-	44,	// 50	Strings 3 (Synth) - Experimental set to Tremollo Strings - should be 50
-	45,	// 51	Pizzicato Strings
-	40,	// 52	Violin 1
-	40,	// 53	Violin 2 ? Viola
-	42,	// 54	Cello 1
-	42,	// 55	Cello 2
-	43,	// 56	Contrabass
-	46,	// 57	Harp 1
-	46,	// 58	Harp 2
-	24,	// 59	Guitar 1 (Nylon)
-	25,	// 60	Guitar 2 (Steel)
-	26,	// 61	Elec Guitar 1
-	27,	// 62	Elec Guitar 2
-	104,	// 63	Sitar
-	32,	// 64	Acou Bass 1
-	32,	// 65	Acou Bass 2
-	33,	// 66	Elec Bass 1
-	34,	// 67	Elec Bass 2
-	36,	// 68	Slap Bass 1
-	37,	// 69	Slap Bass 2
-	35,	// 70	Fretless Bass 1
-	35,	// 71	Fretless Bass 2
-	73,	// 72	Flute 1
-	73,	// 73	Flute 2
-	72,	// 74	Piccolo 1
-	72,	// 75	Piccolo 2
-	74,	// 76	Recorder
-	75,	// 77	Pan Pipes
-	64,	// 78	Sax 1
-	65,	// 79	Sax 2
-	66,	// 80	Sax 3
-	67,	// 81	Sax 4
-	71,	// 82	Clarinet 1
-	71,	// 83	Clarinet 2
-	68,	// 84	Oboe
-	69,	// 85	English Horn (Cor Anglais)
-	70,	// 86	Bassoon
-	22,	// 87	Harmonica
-	56,	// 88	Trumpet 1
-	56,	// 89	Trumpet 2
-	57,	// 90	Trombone 1
-	57,	// 91	Trombone 2
-	60,	// 92	French Horn 1
-	60,	// 93	French Horn 2
-	58,	// 94	Tuba	
-	61,	// 95	Brass Section 1
-	61,	// 96	Brass Section 2
-	11,	// 97	Vibes 1
-	11,	// 98	Vibes 2
-	99,	// 99	Syn Mallet Bank 1
-	112,	// 100	WindBell no real equiv Set to TinkleBell(112)
-	9,	// 101	Glockenspiel
-	14,	// 102	Tubular Bells
-	13,	// 103	Xylophone
-	12,	// 104	Marimba
-	107,	// 105	Koto
-	111,	// 106	Sho?? set to Shanai(111)
-	77,	// 107	Shakauhachi
-	78,	// 108	Whistle 1
-	78,	// 109	Whistle 2
-	76,	// 110	Bottle Blow
-	76,	// 111	Breathpipe no real equiv set to bottle blow(76)
-	47,	// 112	Timpani
-	117,	// 113	Melodic Tom
-	116,	// 114	Deap Snare no equiv, set to Taiko(116)
-	118,	// 115	Electric Perc 1
-	118,	// 116	Electric Perc 2
-	116,	// 117	Taiko
-	115,	// 118	Taiko Rim, no real equiv, set to Woodblock(115)
-	119,	// 119	Cymbal, no real equiv, set to reverse cymbal(119)
-	115,	// 120	Castanets, no real equiv, in GM set to Woodblock(115)
-	112,	// 121	Triangle, no real equiv, set to TinkleBell(112)
-	55,	// 122	Orchestral Hit
-	124,	// 123	Telephone
-	123,	// 124	BirdTweet
-	94,	// 125	Big Notes Pad no equiv, set to halo pad (94)
-	98,	// 126	Water Bell set to Crystal Pad(98)
-	121	// 127	Jungle Tune set to Breath Noise
-};
-
-// Same as above, except include patch changes
-// so GS instruments can be used
-const uint8_t  XMIDI::mt32asgs[256] = {
-	0, 0,	// 0	Piano 1
-	1, 0,	// 1	Piano 2
-	2, 0,	// 2	Piano 3 (synth)
-	4, 0,	// 3	EPiano 1
-	4, 0,	// 4	EPiano 2
-	5, 0,	// 5	EPiano 3
-	5, 0,	// 6	EPiano 4
-	3, 0,	// 7	Honkytonk
-	16, 0,	// 8	Organ 1
-	17, 0,	// 9	Organ 2
-	18, 0,	// 10	Organ 3
-	16, 0,	// 11	Organ 4
-	19, 0,	// 12	Pipe Organ 1
-	19, 0,	// 13	Pipe Organ 2
-	19, 0,	// 14	Pipe Organ 3
-	21, 0,	// 15	Accordion
-	6, 0,	// 16	Harpsichord 1
-	6, 0,	// 17	Harpsichord 2
-	6, 0,	// 18	Harpsichord 3
-	7, 0,	// 19	Clavinet 1
-	7, 0,	// 20	Clavinet 2
-	7, 0,	// 21	Clavinet 3
-	8, 0,	// 22	Celesta 1
-	8, 0,	// 23	Celesta 2
-	62, 0,	// 24	Synthbrass 1 (62)
-	63, 0,	// 25	Synthbrass 2 (63)
-	62, 0,	// 26	Synthbrass 3 Bank 8
-	63, 0,	// 27	Synthbrass 4 Bank 8
-	38, 0,	// 28	Synthbass 1
-	39, 0,	// 29	Synthbass 2
-	38, 0,	// 30	Synthbass 3 Bank 8
-	39, 0,	// 31	Synthbass 4 Bank 8
-	88, 0,	// 32	Fantasy
-	90, 0,	// 33	Harmonic Pan - No equiv closest is polysynth(90) :(
-	52, 0,	// 34	Choral ?? Currently set to SynthVox(54). Should it be ChoirAhhs(52)???
-	92, 0,	// 35	Glass
-	97, 0,	// 36	Soundtrack
-	99, 0,	// 37	Atmosphere
-	14, 0,	// 38	Warmbell, sounds kind of like crystal(98) perhaps Tubular Bells(14) would be better. It is!
-	54, 0,	// 39	FunnyVox, sounds alot like Bagpipe(109) and Shania(111)
-	98, 0,	// 40	EchoBell, no real equiv, sounds like Crystal(98)
-	96, 0,	// 41	IceRain
-	68, 0,	// 42	Oboe 2001, no equiv, just patching it to normal oboe(68)
-	95, 0,	// 43	EchoPans, no equiv, setting to SweepPad
-	81, 0,	// 44	DoctorSolo Bank 8
-	87, 0,	// 45	SchoolDaze, no real equiv
-	112, 0,	// 46	Bell Singer
-	80, 0,	// 47	SquareWave
-	48, 0,	// 48	Strings 1
-	48, 0,	// 49	Strings 2 - should be 49
-	44, 0,	// 50	Strings 3 (Synth) - Experimental set to Tremollo Strings - should be 50
-	45, 0,	// 51	Pizzicato Strings
-	40, 0,	// 52	Violin 1
-	40, 0,	// 53	Violin 2 ? Viola
-	42, 0,	// 54	Cello 1
-	42, 0,	// 55	Cello 2
-	43, 0,	// 56	Contrabass
-	46, 0,	// 57	Harp 1
-	46, 0,	// 58	Harp 2
-	24, 0,	// 59	Guitar 1 (Nylon)
-	25, 0,	// 60	Guitar 2 (Steel)
-	26, 0,	// 61	Elec Guitar 1
-	27, 0,	// 62	Elec Guitar 2
-	104, 0,	// 63	Sitar
-	32, 0,	// 64	Acou Bass 1
-	32, 0,	// 65	Acou Bass 2
-	33, 0,	// 66	Elec Bass 1
-	34, 0,	// 67	Elec Bass 2
-	36, 0,	// 68	Slap Bass 1
-	37, 0,	// 69	Slap Bass 2
-	35, 0,	// 70	Fretless Bass 1
-	35, 0,	// 71	Fretless Bass 2
-	73, 0,	// 72	Flute 1
-	73, 0,	// 73	Flute 2
-	72, 0,	// 74	Piccolo 1
-	72, 0,	// 75	Piccolo 2
-	74, 0,	// 76	Recorder
-	75, 0,	// 77	Pan Pipes
-	64, 0,	// 78	Sax 1
-	65, 0,	// 79	Sax 2
-	66, 0,	// 80	Sax 3
-	67, 0,	// 81	Sax 4
-	71, 0,	// 82	Clarinet 1
-	71, 0,	// 83	Clarinet 2
-	68, 0,	// 84	Oboe
-	69, 0,	// 85	English Horn (Cor Anglais)
-	70, 0,	// 86	Bassoon
-	22, 0,	// 87	Harmonica
-	56, 0,	// 88	Trumpet 1
-	56, 0,	// 89	Trumpet 2
-	57, 0,	// 90	Trombone 1
-	57, 0,	// 91	Trombone 2
-	60, 0,	// 92	French Horn 1
-	60, 0,	// 93	French Horn 2
-	58, 0,	// 94	Tuba	
-	61, 0,	// 95	Brass Section 1
-	61, 0,	// 96	Brass Section 2
-	11, 0,	// 97	Vibes 1
-	11, 0,	// 98	Vibes 2
-	99, 0,	// 99	Syn Mallet Bank 1
-	112, 0,	// 100	WindBell no real equiv Set to TinkleBell(112)
-	9, 0,	// 101	Glockenspiel
-	14, 0,	// 102	Tubular Bells
-	13, 0,	// 103	Xylophone
-	12, 0,	// 104	Marimba
-	107, 0,	// 105	Koto
-	111, 0,	// 106	Sho?? set to Shanai(111)
-	77, 0,	// 107	Shakauhachi
-	78, 0,	// 108	Whistle 1
-	78, 0,	// 109	Whistle 2
-	76, 0,	// 110	Bottle Blow
-	76, 0,	// 111	Breathpipe no real equiv set to bottle blow(76)
-	47, 0,	// 112	Timpani
-	117, 0,	// 113	Melodic Tom
-	116, 0,	// 114	Deap Snare no equiv, set to Taiko(116)
-	118, 0,	// 115	Electric Perc 1
-	118, 0,	// 116	Electric Perc 2
-	116, 0,	// 117	Taiko
-	115, 0,	// 118	Taiko Rim, no real equiv, set to Woodblock(115)
-	119, 0,	// 119	Cymbal, no real equiv, set to reverse cymbal(119)
-	115, 0,	// 120	Castanets, no real equiv, in GM set to Woodblock(115)
-	112, 0,	// 121	Triangle, no real equiv, set to TinkleBell(112)
-	55, 0,	// 122	Orchestral Hit
-	124, 0,	// 123	Telephone
-	123, 0,	// 124	BirdTweet
-	94, 0,	// 125	Big Notes Pad no equiv, set to halo pad (94)
-	98, 0,	// 126	Water Bell set to Crystal Pad(98)
-	121, 0	// 127	Jungle Tune set to Breath Noise
-};
-
-// Constructor
-XMIDI::XMIDI(DataSource *source, int pconvert) : events(NULL),
-						convert_type(pconvert), is_emidi(false),
-						do_reverb(false), do_chorus(false)
-{
-	if (convert_type == XMIDI_CONVERT_EMIDI_GM)
-	{
-		is_emidi = true;
-		convert_type = XMIDI_CONVERT_NOCONVERSION;
-	}
-
-	memset(bank127,0,sizeof(bank127));
-	
-	ExtractTracks (source);
-}
-
-XMIDI::~XMIDI()
-{
-	if (events)
-	{
-		for (int i=0; i < num_tracks; i++) {
-			events[i]->DecerementCounter();
-			events[i] = NULL;
-		}
-		//delete [] events;
-		Free(events);
-	}
-}
-
-XMIDIEventList *XMIDI::GetEventList (uint32_t track)
-{
-	if (!events)
-	{
-		cerr << "No midi data in loaded." << endl;
-		return 0;
-	}
-
-	if (track >= num_tracks)
-	{
-		cerr << "Can't retrieve MIDI data, track out of range" << endl;
-		return 0;
-	}
-
-	return events[track];
-}
-
-// Sets current to the new event and updates list
-void XMIDI::CreateNewEvent (int time)
-{
-	if (!list)
-	{
-		list = current = Calloc<midi_event>(); //new midi_event;
-		if (time > 0)
-			current->time = time;
-		return;
-	}
-
-	if (time < 0 || list->time > time)
-	{
-		midi_event *event = Calloc<midi_event>(); //new midi_event;
-		event->next = list;
-		list = current = event;
-		return;
-	}
-
-	if (!current || current->time > time)
-		current = list;
-
-	while (current->next)
-	{
-		if (current->next->time > time)
-		{
-			midi_event *event = Calloc<midi_event>(); //new midi_event;
-			
-			event->next = current->next;
-			current->next = event;
-			current = event;
-			current->time = time;
-			return;
-		}
-		
-		current = current->next;
-	}
-
-	current->next = Calloc<midi_event>(); //new midi_event;
-	current = current->next;
-	current->time = time;
-}
-
-//
-// GetVLQ
-//
-// Get a Conventional Variable Length Quantity
-//
-int XMIDI::GetVLQ (DataSource *source, uint32_t &quant)
-{
-	int i;
-	quant = 0;
-	unsigned int data;
-
-	for (i = 0; i < 4; i++)
-	{
-		data = source->read1();
-		quant <<= 7;
-		quant |= data & 0x7F;
-
-		if (!(data & 0x80))
-		{
-			i++;
-			break;
-		}
-
-	}
-	return i;
-}
-
-//
-// GetVLQ2
-//
-// Get a XMIDI Variable Length Quantity
-//
-int XMIDI::GetVLQ2 (DataSource *source, uint32_t &quant)
-{
-	int i;
-	quant = 0;
-	int data = 0;
-	
-	for (i = 0; i < 4; i++)
-	{
-		data = source->read1();
-		if (data & 0x80)
-		{
-			source->skip(-1);
-			break;
-		}
-		quant += data;
-	}
-	return i;
-}
-
-//
-// MovePatchVolAndPan.
-//
-// Well, this is just a modified version of what that method used to do. This
-// is a massive optimization. Speed up should be quite impressive
-//
-void XMIDI::ApplyFirstState(first_state &fs, int chan_mask)
-{
-	for (int channel = 0; channel < 16; channel++)
-	{
-		midi_event *patch = fs.patch[channel];
-		midi_event *vol = fs.vol[channel];
-		midi_event *pan = fs.pan[channel];
-		midi_event *bank = fs.bank[channel];
-		midi_event *reverb = NULL;
-		midi_event *chorus = NULL;
-		midi_event *temp;
-
-		// Got no patch change, return and don't try fixing it
-		if (!patch || !(chan_mask & 1 << channel)) continue;
-#if 0
-		std::cout << "Channel: " << channel+1 << std::endl;
-		std::cout << "Patch: " << (unsigned int) patch->data[0] << " @ " << patch->time << std::endl;
-		if (bank) std::cout << " Bank: " << (unsigned int) bank->data[1] << " @ " << bank->time << std::endl;
-		if (vol) std::cout << "  Vol: " << (unsigned int) vol->data[1] << " @ " << vol->time << std::endl;
-		if (pan) std::cout << "  Pan: " << ((signed int) pan->data[1])-64 << " @ " << pan->time << std::endl;
-		std::cout << std::endl;
-#endif
-
-		// Copy Patch Change Event
-		temp = patch;
-		patch = Calloc<midi_event>(); //new midi_event;
-		patch->time = temp->time;
-		patch->status = channel|(MIDI_STATUS_PROG_CHANGE << 4);
-		patch->data[0] = temp->data[0];
-
-		// Copy Volume
-		if (vol && (vol->time > patch->time+PATCH_VOL_PAN_BIAS || vol->time < patch->time-PATCH_VOL_PAN_BIAS))
-			vol = NULL;
-
-		temp = vol;
-		vol = Calloc<midi_event>(); //new midi_event;
-		vol->status = channel|(MIDI_STATUS_CONTROLLER << 4);
-		vol->data[0] = 7;
-
-		if (!temp)
-		{
-			vol->data[1] = 90;
-		}
-		else
-			vol->data[1] = temp->data[1];
-
-
-		// Copy Bank
-		if (bank && (bank->time > patch->time+PATCH_VOL_PAN_BIAS || bank->time < patch->time-PATCH_VOL_PAN_BIAS))
-			bank = NULL;
-
-		temp = bank;
-		
-		bank = Calloc<midi_event>(); //new midi_event;
-		bank->status = channel|(MIDI_STATUS_CONTROLLER << 4);
-
-		if (!temp)
-			bank->data[1] = 0;
-		else
-			bank->data[1] = temp->data[1];
-
-		// Copy Pan
-		if (pan && (pan->time > patch->time+PATCH_VOL_PAN_BIAS || pan->time < patch->time-PATCH_VOL_PAN_BIAS))
-			pan = NULL;
-
-		temp = pan;
-		pan = Calloc<midi_event>(); //new midi_event;
-		pan->status = channel|(MIDI_STATUS_CONTROLLER << 4);
-		pan->data[0] = 10;
-
-		if (!temp)
-			pan->data[1] = 64;
-		else
-			pan->data[1] = temp->data[1];
-
-		if (do_reverb)
-		{
-			reverb = Calloc<midi_event>(); //new midi_event;
-			reverb->status = channel|(MIDI_STATUS_CONTROLLER << 4);
-			reverb->data[0] = 91;
-			reverb->data[1] = reverb_value;
-		}
-
-		if (do_chorus)
-		{
-			chorus = Calloc<midi_event>(); //new midi_event;
-			chorus->status = channel|(MIDI_STATUS_CONTROLLER << 4);
-			chorus->data[0] = 93;
-			chorus->data[1] = chorus_value;
-		}
-
-		vol->time = 0;
-		pan->time = 0;
-		patch->time = 0;
-		bank->time = 0;
-		
-		if (do_reverb && do_chorus) reverb->next = chorus;
-		else if (do_reverb) reverb->next = bank;
-		if (do_chorus) chorus->next = bank;
-		bank->next = vol;
-		vol->next = pan;
-		pan->next = patch;
-		
-		patch->next = list;
-		if (do_reverb) list = reverb;
-		else if (do_chorus) list = chorus;
-		else list = bank;
-	}
-}
-
-
-//
-// AdjustTimings
-//
-// It converts the midi's to use 120 Hz timing, and also calcs the duration of
-// the notes. It also strips the tempo events, and adds it's own
-//
-// This is used by Midi's ONLY! It will do nothing with Xmidi
-//
-void XMIDI::AdjustTimings(uint32_t ppqn)
-{
-	uint32_t		tempo = 500000;
-	uint32_t		time_prev = 0;
-	uint32_t		hs_rem = 0;
-	uint32_t		hs     = 0;
-
-	ppqn *= 10000;
-
-	// Virtual playing
-	NoteStack notes;
-
-	for (midi_event	*event = list; event; event = event->next) {
-
-			// Note 64 bit int is required because multiplication by tempo can
-			// require 52 bits in some circumstances
-
-			uint64_t aim = event->time - time_prev;
-			aim *= tempo;
-
-			hs_rem += aim%ppqn;
-			hs += aim/ppqn;
-			hs += hs_rem/ppqn;
-			hs_rem %= ppqn;
-
-			time_prev = event->time;
-			event->time = (hs*6)/5 + (6*hs_rem)/(5*ppqn);
-				
-			// Note on and note off handling
-			if (event->status <= 0x9F) {
-
-				// Add if it's a note on and remove if it's a note off
-				if ((event->status>>4) == MIDI_STATUS_NOTE_ON && event->data[1]) 
-					notes.Push(event);
-				else {
-					midi_event *prev = notes.FindAndPop(event);
-					if (prev) prev->duration = event->time - prev->time;
-				}
-
-			}
-			else if (event->status == 0xFF && event->data[0] == 0x51) {
-
-				tempo = (event->buffer[0] << 16) +
-					(event->buffer[1] << 8) +
-					event->buffer[2];
-					
-				event->buffer[0] = 0x07;
-				event->buffer[1] = 0xA1;
-				event->buffer[2] = 0x20;
-			}
-	}
-
-	//std::cout << "Max Polyphony: " << notes.GetMaxPolyphony() << std::endl;
-	static const uint8_t  tempo_buf[5] = { 0x51, 0x03, 0x07, 0xA1, 0x20 };
-	BufferDataSource ds((uint8_t  *)tempo_buf, 5);
-	current = list;
-	ConvertSystemMessage (0, 0xFF,&ds);
-}
-
-
-// Converts Events
-//
-// Source is at the first data byte
-// size 1 is single data byte (ConvertEvent Only)
-// size 2 is dual data byte
-// size 3 is XMI Note on (ConvertNote only)
-// Returns bytes converted
-//
-// ConvertNote is used for Note On's and Note offs
-// ConvertSystemMessage is used for SysEx events and Meta events
-// ConvertEvent is used for everything else
-
-int XMIDI::ConvertEvent (const int time, uint8_t  status, DataSource *source, const int size, first_state &fs)
-{
-	int	data;
-
-	data = source->read1();
-
-	// Little hacks for EMIDI
-
-	if (use_emidi_112 && (status >> 4) == MIDI_STATUS_PROG_CHANGE)
-	{
-		// Discard all normal program changes if we are using emidi 112
-		return 1;
-	}
-	else if (is_emidi && (status >> 4) == MIDI_STATUS_CONTROLLER && data == EMIDI_CONTROLLER_PROGRAM_CHANGE)
-	{
-		// Convert it into a normal program change event
-		use_emidi_112 = true;
-		status = (status&0x0F) | (MIDI_STATUS_PROG_CHANGE<<4);
-		data = source->read1();
-		source->skip(-1);
-	}
-
-	if (use_emidi_113 && (status >> 4) ==  MIDI_STATUS_CONTROLLER && data == 7)
-	{
-		// Discard all normal volume changes if we are using emidi 113
-		source->skip(1);
-		return 2;
-	}
-	else if (is_emidi && (status >> 4) == MIDI_STATUS_CONTROLLER && data == EMIDI_CONTROLLER_VOLUME)
-	{
-		// Convert it into a normal program change event
-		use_emidi_113 = true;
-		data = 7;
-	}
-
-
-	// Bank changes are handled here
-	if ((status >> 4) == 0xB && data == 0)
-	{
-		data = source->read1();
-		
-		bank127[status&0xF] = false;
-		
-		if (convert_type == XMIDI_CONVERT_MT32_TO_GM || convert_type == XMIDI_CONVERT_MT32_TO_GS
-			|| convert_type == XMIDI_CONVERT_MT32_TO_GS127)
-			return 2;
-
-		CreateNewEvent (time);
-		current->status = status;
-		current->data[0] = 0;
-		current->data[1] = data;
-
-		// Set the bank
-		if (!fs.bank[status&0xF] || fs.bank[status&0xF]->time > time) fs.bank[status&0xF] = current;
-
-		if (convert_type == XMIDI_CONVERT_GS127_TO_GS && data == 127)
-			bank127[status&0xF] = true;
-
-		return 2;
-	}
-
-	// Handling for patch change mt32 conversion, probably should go elsewhere
-	if ((status >> 4) == 0xC && (status&0xF) != 9 && convert_type != XMIDI_CONVERT_NOCONVERSION)
-	{
-		if (convert_type == XMIDI_CONVERT_MT32_TO_GM)
-		{
-			data = mt32asgm[data];
-		}
-		else if ((convert_type == XMIDI_CONVERT_GS127_TO_GS && bank127[status&0xF]) ||
-				convert_type == XMIDI_CONVERT_MT32_TO_GS)
-		{
-			CreateNewEvent (time);
-			current->status = 0xB0 | (status&0xF);
-			current->data[0] = 0;
-			current->data[1] = mt32asgs[data*2+1];
-
-			data = mt32asgs[data*2];
-
-			// Set the bank
-			if (!fs.bank[status&0xF] || fs.bank[status&0xF]->time > time) fs.bank[status&0xF] = current;
-		}
-		else if (convert_type == XMIDI_CONVERT_MT32_TO_GS127)
-		{
-			CreateNewEvent (time);
-			current->status = 0xB0 | (status&0xF);
-			current->data[0] = 0;
-			current->data[1] = 127;
-
-			// Set the bank
-			if (!fs.bank[status&0xF] || fs.bank[status&0xF]->time > time) fs.bank[status&0xF] = current;
-		}
-	}// Disable patch changes on Track 10 is doing a conversion
-	else if ((status >> 4) == 0xC && (status&0xF) == 9 && convert_type != XMIDI_CONVERT_NOCONVERSION)
-	{
-		return size;
-	}
-
-	CreateNewEvent (time);
-	current->status = status;
-
-	current->data[0] = data;
-
-	// Check for patch change, and update fs if req
-	if ((status >> 4) == 0xC) {
-		if (!fs.patch[status&0xF] || fs.patch[status&0xF]->time > time)
-			fs.patch[status&0xF] = current;
-	}
-	// Controllers
-	else if ((status >> 4) == 0xB) {
-		// Volume
-		if (current->data[0] == 7) {
-			if (!fs.vol[status&0xF] || fs.vol[status&0xF]->time > time)
-				fs.vol[status&0xF] = current;
-		}
-		// Pan
-		else if (current->data[0] == 10) {
-			if (!fs.pan[status&0xF] || fs.pan[status&0xF]->time > time)
-				fs.pan[status&0xF] = current;
-		}
-	}
-
-	if (size == 1)
-		return 1;
-
-	current->data[1] = source->read1();
-
-	return 2;
-}
-
-int XMIDI::ConvertNote (const int time, const uint8_t  status, DataSource *source, const int size)
-{
-	uint32_t	delta = 0;
-	int	data;
-
-	data = source->read1();
-
-	CreateNewEvent (time);
-	current->status = status;
-
-	current->data[0] = data;
-	current->data[1] = source->read1();
-
-	if (size == 2)
-		return 2;
-
-	// XMI Note On handling
-
-	// Get the duration
-	int i = GetVLQ (source, delta);
-	
-	// Set the duration
-	current->duration = delta;
-
-	// This is an optimization
-	midi_event *prev = current;
-		
-	// Create a note off
-	CreateNewEvent (time+delta);
-
-	current->status = status;
-	current->data[0] = data;
-	current->data[1] = 0;
-	
-	// Optimization
-	current = prev;
-
-	return i + 2;
-}
-
-// Simple routine to convert system messages
-int XMIDI::ConvertSystemMessage (const int time, const uint8_t  status, DataSource *source)
-{
-	int i=0;
-	
-	CreateNewEvent (time);
-	current->status = status;
-	
-	// Handling of Meta events
-	if (status == 0xFF)
-	{
-		current->data[0] = source->read1();
-		i++;	
-	}
-
-	i += GetVLQ (source, current->len);
-
-	if (!current->len)
-	{
-		current->buffer = NULL;
-		return i;
-	}
-	
-	current->buffer = Malloc<uint8_t >(current->len);
-
-	source->read (reinterpret_cast<uint8_t  *>(current->buffer), current->len);
-
-	return i+current->len;
-}
-
-// XMIDI and Midi to List. Returns bit mask of channels used
-int XMIDI::ConvertFiletoList (DataSource *source, const bool is_xmi, first_state &fs)
-{
-	int 	time = 0;			// 120th of a second
-	uint32_t 	data;
-	int		end = 0;
-	uint32_t	status = 0;
-	int		play_size = 2;
-	int		file_size = source->getSize();
-	int		retval = 0;
-
-	if (is_xmi) play_size = 3;
-
-	use_emidi_112 = false;
-	use_emidi_113 = false;
-
-	while (!end && source->getPos() < file_size)
-	{
-		if (!is_xmi)
-		{
-			GetVLQ (source, data);
-			time += data;
-
-			data = source->read1();
-		
-			if (data >= 0x80)
-			{
-				status = data;
-			}
-			else
-				source->skip (-1);
-		}	
-		else
-		{
-			GetVLQ2 (source, data);
-			time += data;
-
-			status = source->read1();
-		}
-
-		switch (status >> 4)
-		{
-			case MIDI_STATUS_NOTE_ON:
-			retval |= 1 << (status & 0xF);
-			ConvertNote (time, status, source, play_size);
-			break;
-
-			case MIDI_STATUS_NOTE_OFF:
-			ConvertNote (time, status, source, 2);
-			break;
-
-			// 2 byte data
-
-			case MIDI_STATUS_CONTROLLER:
-			if (is_emidi)
-			{
-				data = source->read1();
-				if (data == EMIDI_CONTROLLER_TRACK_DESIGNATION)
-				{
-					data = source->read1();
-
-					// Only convert 0 and 127 tracks
-					if (data == 0 || data == 127) continue;
-
-					// Discard all others
-					return 0;
-				}
-				else if (data == EMIDI_CONTROLLER_TRACK_EXCLUSION)
-				{
-					data = source->read1();
-
-					// It's not for some other track
-					if (data != 0) continue;
-
-					// Uh oh, this track is not for 0
-					return 0;
-				}
-				source->skip (-1);
-			}
-			// We can convert like normal
-			
-			case MIDI_STATUS_AFTERTOUCH:
-			case MIDI_STATUS_PITCH_WHEEL:
-			if (is_emidi && (status >> 4))
-			ConvertEvent (time, status, source, 2, fs);
-			break;
-			
-
-			// 1 byte data
-			case MIDI_STATUS_PROG_CHANGE:
-			case MIDI_STATUS_PRESSURE:
-			ConvertEvent (time, status, source, 1, fs);
-			break;
-			
-
-			case MIDI_STATUS_SYSEX:
-			if (status == 0xFF)
-			{
-				int	pos = source->getPos();
-				uint32_t	data = source->read1();
-				
-				if (data == 0x2F)					// End, of track
-					end = 1;
-				else if (data == 0x51 && is_xmi)	// XMIDI doesn't use tempo
-				{
-					GetVLQ (source, data);
-					source->skip(data);
-					break;
-				}
-				
-				source->seek (pos);
-			}
-			ConvertSystemMessage (time, status, source);
-			break;
-
-			default:
-			break;
-		}
-
-	}
-
-	return retval;
-}
-
-// Assumes correct xmidi
-int XMIDI::ExtractTracksFromXmi (DataSource *source)
-{
-	int				num = 0;
-	uint32_t			len = 0;
-	uint8_t 			buf[32];
-
-	first_state	fs;
-
-	while (source->getPos() < source->getSize() && num != num_tracks)
-	{
-		// Read first 4 bytes of name
-		source->read (buf, 4);
-		len = source->read4high();
-
-		// Skip the FORM entries
-		if (!memcmp(buf,"FORM",4))
-		{
-			source->skip (4);
-			source->read (buf, 4);
-			len = source->read4high();
-		}
-
-		if (memcmp(buf,"EVNT",4))
-		{
-			source->skip ((len+1)&~1);
-			continue;
-		}
-
-		list = NULL;
-		memset(&fs, 0, sizeof(fs));
-
-		int begin = source->getPos ();
-
-		// Convert it
-		int chan_mask = ConvertFiletoList (source, true, fs);
-
-		// Apply the first state
-		ApplyFirstState(fs, chan_mask);
-
-		// Add tempo
-		static const uint8_t  tempo_buf[5] = { 0x51, 0x03, 0x07, 0xA1, 0x20 };
-		BufferDataSource ds((uint8_t  *)tempo_buf, 5);
-		current = list;
-		ConvertSystemMessage (0, 0xFF,&ds);
-
-		// Set the list
-		events[num]->events = list;
-
-		// Increment Counter
-		num++;
-
-		// go to start of next track
-		source->seek (begin + ((len+1)&~1));
-	}
-
-	// Return how many were converted
-	return num;
-}
-
-int XMIDI::ExtractTracksFromMid (DataSource *source, const uint32_t ppqn, const int num_tracks, const bool type1)
-{
-	int			num = 0;
-	uint32_t		len = 0;
-	uint8_t 		buf[32];
-	int			chan_mask = 0;
-
-	first_state	fs;
-	memset(&fs, 0, sizeof(fs));
-
-	list = NULL;
-
-	while (source->getPos() < source->getSize() && num != num_tracks)
-	{
-		// Read first 4 bytes of name
-		source->read (buf, 4);
-		len = source->read4high();
-
-		if (memcmp(buf,"MTrk",4))
-		{
-			source->skip (len);
-			continue;
-		}
-
-		int begin = source->getPos ();
-
-		// Convert it
-		chan_mask |= ConvertFiletoList (source, false, fs);
-
-		if (!type1) {
-			ApplyFirstState(fs, chan_mask);
-			AdjustTimings(ppqn);
-			events[num]->events = list;
-			list = NULL;
-			memset(&fs, 0, sizeof(fs));
-			chan_mask = 0;
-		}
-		
-		// Increment Counter
-		num++;		
-		source->seek (begin+len);
-	}
-
-	if (type1) { 
-		ApplyFirstState(fs, chan_mask);
-		AdjustTimings(ppqn);
-		events[0]->events = list;
-		return num == num_tracks ? 1 : 0;
-	}
-
-	// Return how many were converted
-	return num;
-}
-
-int XMIDI::ExtractTracks (DataSource *source)
-{
-	uint32_t		i = 0;
-	int		start;
-	uint32_t		len;
-	uint32_t		chunk_len;
-	int 		count;
-	uint8_t 		buf[32];
-
-	string s;
-	
-	do_reverb = false;
-	reverb_value = 0;
-	do_chorus = true;
-	chorus_value = 0;
-
-
-	// Read first 4 bytes of header
-	source->read (buf, 4);
-
-	// Could be XMIDI
-	if (!memcmp (buf, "FORM", 4))
-	{
-		// Read length of 
-		len = source->read4high();
-
-		start = source->getPos();
-		
-		// Read 4 bytes of type
-		source->read (buf, 4);
-
-		// XDIRless XMIDI, we can handle them here.
-		if (!memcmp (buf, "XMID", 4))
-		{	
-			cerr << "Warning: XMIDI doesn't have XDIR" << endl;
-			num_tracks = 1;
-			
-		} // Not an XMIDI that we recognise
-		else if (memcmp (buf, "XDIR", 4))
-		{	
-			cerr << "Not a recognised XMID" << endl;
-			return 0;
-			
-		} // Seems Valid
-		else 
-		{
-			num_tracks = 0;
-		
-			for (i = 4; i < len; i++)
-			{
-				// Read 4 bytes of type
-				source->read (buf, 4);
-
-				// Read length of chunk
-				chunk_len = source->read4high();
-			
-				// Add eight bytes
-				i+=8;
-				
-				if (memcmp (buf, "INFO", 4))
-				{	
-					// Must allign
-					source->skip((chunk_len+1)&~1);
-					i+= (chunk_len+1)&~1;
-					continue;
-				}
-
-				// Must be at least 2 bytes long
-				if (chunk_len < 2)
-					break;
-				
-				num_tracks = source->read2();
-				break;
-			}
-		
-			// Didn't get to fill the header
-			if (num_tracks == 0)
-			{
-				cerr << "Not a valid XMID" << endl;
-				return 0;
-			}
-		
-			// Ok now to start part 2
-			// Goto the right place
-			source->seek (start+((len+1)&~1));
-		
-			// Read 4 bytes of type
-			source->read (buf, 4);
-
-			// Not an XMID
-			if (memcmp (buf, "CAT ", 4))
-			{
-				cerr << "Not a recognised XMID (" << buf[0] << buf[1] << buf[2] << buf[3] << ") should be (CAT )" << endl;
-				return 0;	
-			}
-			
-			// Now read length of this track
-			len = source->read4high();
-			
-			// Read 4 bytes of type
-			source->read (buf, 4);
-
-			// Not an XMID
-			if (memcmp (buf, "XMID", 4))
-			{
-				cerr << "Not a recognised XMID (" << buf[0] << buf[1] << buf[2] << buf[3] << ") should be (XMID)" << endl;
-				return 0;	
-			}
-
-		}
-
-		// Ok it's an XMID, so pass it to the ExtractCode
-
-		events = Calloc<XMIDIEventList*>(num_tracks); //new midi_event *[info.tracks];
-		
-		for (i = 0; i < num_tracks; i++)
-			events[i] = Calloc<XMIDIEventList>();
-
-		count = ExtractTracksFromXmi (source);
-
-		if (count != num_tracks)
-		{
-			cerr << "Error: unable to extract all (" << num_tracks << ") tracks specified from XMIDI. Only ("<< count << ")" << endl;
-			
-			int i = 0;
-			
-			for (i = 0; i < num_tracks; i++) {
-				events[i]->DecerementCounter();
-				events[i] = NULL;
-			}
-			
-			//delete [] events;
-			Free (events);
-			
-			return 0;		
-		}
-
-		return 1;
-		
-	}// Definately a Midi
-	else if (!memcmp (buf, "MThd", 4))
-	{
-		// Simple read length of header
-		len = source->read4high();
-
-		if (len < 6)
-		{
-			cerr << "Not a valid MIDI" << endl;
-			return 0;
-		}
-
-		int type = source->read2high();
-		
-		int actual_num = num_tracks = source->read2high();
-
-		// Type 1 only has 1 track, even though it says it has more
-		if (type == 1) num_tracks = 1;
-
-		events = Calloc<XMIDIEventList*>(num_tracks); //new midi_event *[info.tracks];
-		const uint32_t ppqn = source->read2high();
-
-		for (i = 0; i < num_tracks; i++)
-			events[i] = Calloc<XMIDIEventList>();
-		
-		count = ExtractTracksFromMid (source, ppqn, actual_num, type == 1);
-
-		if (count != num_tracks)
-		{
-			cerr << "Error: unable to extract all (" << num_tracks << ") tracks specified from MIDI. Only ("<< count << ")" << endl;
-			
-			for (i = 0; i < num_tracks; i++) {
-				events[i]->DecerementCounter();
-				events[i] = NULL;
-			}
-			
-			Free (events);
-			
-			return 0;
-				
-		}
-
-		return 1;
-		
-	}// A RIFF Midi, just pass the source back to this function at the start of the midi file
-	else if (!memcmp (buf, "RIFF", 4))
-	{
-		// Read len
-		len = source->read4();
-
-		// Read 4 bytes of type
-		source->read (buf, 4);
-		
-		// Not an RMID
-		if (memcmp (buf, "RMID", 4))
-		{
-			cerr << "Invalid RMID" << endl;
-			return 0;
-		}
-
-		// Is a RMID
-
-		for (i = 4; i < len; i++)
-		{
-			// Read 4 bytes of type
-			source->read (buf, 4);
-			
-			chunk_len = source->read4();
-			
-			i+=8;
-				
-			if (memcmp (buf, "data", 4))
-			{	
-				// Must allign
-				source->skip ((chunk_len+1)&~1);
-				i+= (chunk_len+1)&~1;
-				continue;
-			}
-			
-			return ExtractTracks (source);
-
-		}
-		
-		cerr << "Failed to find midi data in RIFF Midi" << endl;
-		return 0;
-	}
-	
-	return 0;	
-}
-
-//
-// XMIDIEventList stuff
-//
-int	XMIDIEventList::Write (const uint8_t  *filename)
-{
-//	FILE *file = fopen (filename, "wb"); // DARKE FIXME
-//	FileDataSource ds(file);
-//	int ret = Write(&ds);
-//	fclose (file);
-//	return ret;
-	return 0;
-}
-
-int XMIDIEventList::Write (DataSource *dest)
-{
-	int len = 0;
-	
-	if (!events)
-	{
-		cerr << "No midi data in loaded." << endl;
-		return 0;
-	}
-
-	// This is so if using buffer datasource, the caller can know how big to make the buffer
-	if (!dest)
-	{
-		// Header is 14 bytes int32_t and add the rest as well
-		len = ConvertListToMTrk (NULL);
-		return 14 + len;
-	}
-		
-	dest->write1 ('M');
-	dest->write1 ('T');
-	dest->write1 ('h');
-	dest->write1 ('d');
-	
-	dest->write4high (6);
-
-	dest->write2high (0);
-	dest->write2high (1);
-	dest->write2high (60);	// The PPQN
-		
-	len = ConvertListToMTrk (dest);
-
-	return len + 14;
-}
-
-//
-// PutVLQ
-//
-// Write a Conventional Variable Length Quantity
-//
-int XMIDIEventList::PutVLQ(DataSource *dest, uint32_t value)
-{
-	int buffer;
-	int i = 1;
-	buffer = value & 0x7F;
-	while (value >>= 7)
-	{
-		buffer <<= 8;
-		buffer |= ((value & 0x7F) | 0x80);
-		i++;
-	}
-	if (!dest) return i;
-	for (int j = 0; j < i; j++)
-	{
-		dest->write1(buffer & 0xFF);
-		buffer >>= 8;
-	}
-	
-	return i;
-}
-
-// Converts and event list to a MTrk
-// Returns bytes of the array
-// buf can be NULL
-uint32_t XMIDIEventList::ConvertListToMTrk (DataSource *dest)
-{
-	int time = 0;
-	int lasttime = 0;
-	midi_event	*event;
-	uint32_t	delta;
-	uint8_t 	last_status = 0;
-	uint32_t 	i = 8;
-	uint32_t 	j;
-	uint32_t	size_pos=0;
-
-	if (dest)
-	{
-		dest->write1('M');
-		dest->write1('T');
-		dest->write1('r');
-		dest->write1('k');
-
-		size_pos = dest->getPos();
-		dest->skip(4);
-	}
-
-	for (event = events; event; event=event->next)
-	{
-		// We don't write the end of stream marker here, we'll do it later
-		if (event->status == 0xFF && event->data[0] == 0x2f) {
-			lasttime = event->time;
-			continue;
-		}
-
-		delta = (event->time - time);
-		time = event->time;
-
-		i += PutVLQ (dest, delta);
-
-		if ((event->status != last_status) || (event->status >= 0xF0))
-		{
-			if (dest) dest->write1(event->status);
-			i++;
-		}
-		
-		last_status = event->status;
-		
-		switch (event->status >> 4)
-		{
-			// 2 bytes data
-			// Note off, Note on, Aftertouch, Controller and Pitch Wheel
-			case 0x8: case 0x9: case 0xA: case 0xB: case 0xE:
-			if (dest)
-			{
-				dest->write1(event->data[0]);
-				dest->write1(event->data[1]);
-			}
-			i += 2;
-			break;
-			
-
-			// 1 bytes data
-			// Program Change and Channel Pressure
-			case 0xC: case 0xD:
-			if (dest) dest->write1(event->data[0]);
-			i++;
-			break;
-			
-
-			// Variable length
-			// SysEx
-			case 0xF:
-			if (event->status == 0xFF)
-			{
-				if (dest) dest->write1(event->data[0]);
-				i++;
-			}
-	
-			i += PutVLQ (dest, event->len);
-			
-			if (event->len)
-			{
-				for (j = 0; j < event->len; j++)
-				{
-					if (dest) dest->write1(event->buffer[j]); 
-					i++;
-				}
-			}
-
-			break;
-			
-
-			// Never occur
-			default:
-			cerr << "Not supposed to see this" << endl;
-			break;
-		}
-	}
-
-	// Write out end of stream marker
-	if (lasttime > time) i += PutVLQ (dest, lasttime-time);
-	else i += PutVLQ (dest, 0);
-	if (dest) {
-		dest->write1(0xFF);
-		dest->write1(0x2F);
-	}
-	i += 2+PutVLQ (dest, 0);
-
-	if (dest)
-	{
-		int cur_pos = dest->getPos();
-		dest->seek (size_pos);
-		dest->write4high (i-8);
-		dest->seek (cur_pos);
-	}
-	return i;
-}
-
-
-void XMIDIEventList::DeleteEventList (midi_event *mlist)
-{
-	midi_event *event;
-	midi_event *next;
-	
-	next = mlist;
-	event = mlist;
-
-	while ((event = next))
-	{
-		next = event->next;
-		// We only do this with sysex
-		if ((event->status>>4) == 0xF && event->buffer) Free (event->buffer);
-		Free (event);
-	}
-}
-
-void XMIDIEventList::DecerementCounter()
-{
-	if (--counter < 0) {
-		DeleteEventList(events);
-		Free(this);
-	}
-}
--- a/Game/src/midi/xmidi.h
+++ /dev/null
@@ -1,306 +1,0 @@
-/*
-Copyright (C) 2000  Ryan Nunn
-
-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
-aint32_t with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-*/
-
-// Tab Size = 4
-
-#ifndef __XMIDI_h_
-#define __XMIDI_h_
-
-#include <string>
-//#include "common_types.h"
-#include "databuf.h"
-
-
-// Conversion types for Midi files
-#define XMIDI_CONVERT_NOCONVERSION		0
-#define XMIDI_CONVERT_MT32_TO_GM		1
-#define XMIDI_CONVERT_MT32_TO_GS		2
-#define XMIDI_CONVERT_MT32_TO_GS127		3
-#define XMIDI_CONVERT_OGG               4
-#define XMIDI_CONVERT_GS127_TO_GS		5
-#define XMIDI_CONVERT_EMIDI_GM			6	// For Duke3D! Selects General Midi tracks
-
-// Midi Status Bytes
-#define MIDI_STATUS_NOTE_OFF	0x8
-#define MIDI_STATUS_NOTE_ON		0x9
-#define MIDI_STATUS_AFTERTOUCH	0xA
-#define MIDI_STATUS_CONTROLLER	0xB
-#define MIDI_STATUS_PROG_CHANGE	0xC
-#define MIDI_STATUS_PRESSURE	0xD
-#define MIDI_STATUS_PITCH_WHEEL	0xE
-#define MIDI_STATUS_SYSEX		0xF
-
-// XMIDI Controllers
-#define XMIDI_CONTROLLER_CHAN_LOCK			0x6e	// Channel Lock
-#define XMIDI_CONTROLLER_CHAN_LOCK_PROT		0x6f	// Channel Lock Protect
-#define XMIDI_CONTROLLER_VOICE_PROT			0x70	// Voice Protect
-#define XMIDI_CONTROLLER_TIMBRE_PROT		0x71	// Timbre Protect
-#define XMIDI_CONTROLLER_BANK_CHANGE		0x72	// Bank Change
-#define XMIDI_CONTROLLER_IND_CTRL_PREFIX	0x73	// Indirect Controller Prefix
-#define XMIDI_CONTROLLER_FOR_LOOP			0x74	// For Loop
-#define XMIDI_CONTROLLER_NEXT_BREAK			0x75	// Next/Break
-#define XMIDI_CONTROLLER_CLEAR_BB_COUNT		0x76	// Clear Beat/Bar Count
-#define XMIDI_CONTROLLER_CALLBACK_TRIG		0x77	// Callback Trigger
-#define XMIDI_CONTROLLER_SEQ_BRANCH_INDEX	0x78	// Sequence Branch Index
-
-#define EMIDI_CONTROLLER_TRACK_DESIGNATION	110		// Track Designation
-#define EMIDI_CONTROLLER_TRACK_EXCLUSION	111		// Track Exclusion
-#define EMIDI_CONTROLLER_PROGRAM_CHANGE		112		// Program Change
-#define EMIDI_CONTROLLER_VOLUME				113		// Volume
-#define EMIDI_CONTROLLER_LOOP_BEGIN			XMIDI_CONTROLLER_FOR_LOOP
-#define EMIDI_CONTROLLER_LOOP_END			XMIDI_CONTROLLER_NEXT_BREAK
-
-
-// Maximum number of for loops we'll allow (used by win_midiout)
-#define XMIDI_MAX_FOR_LOOP_COUNT	128
-
-template <class T> class GammaTable;
-
-struct midi_event
-{
-	int				time;
-	uint8_t 	status;
-
-	uint8_t 	data[2];
-
-	uint32_t			len;		// Length of SysEx Data
-	uint8_t 	*buffer;	// SysEx Data
-	int				duration;	// Duration of note (120 Hz)
-	midi_event		*next_note;	// The next note on the stack
-	uint32_t			note_time;	// Time note stops playing (6000th of second)
-	midi_event	*next;
-};
-
-class NoteStack {
-	midi_event		*notes;		// Top of the stack
-	int				polyphony;
-	int				max_polyphony;
-public:
-
-	NoteStack() : notes(0), polyphony(0), max_polyphony(0) { }
-
-	// Just clear it. Don't care about what's actually in it
-	void clear() {
-		notes=0;
-		polyphony=0;
-		max_polyphony=0;
-	}
-
-	// Pops the top of the stack if its off_time is <= time (6000th of second)
-	inline midi_event *PopTime(uint32_t time) {
-		if (notes && notes->note_time <= time)  {
-			midi_event *note = notes;
-			notes = note->next_note;
-			note->next_note = 0;
-			polyphony--;
-			return note;
-		}
-
-		return 0;
-	}
-
-	// Pops the top of the stack
-	inline midi_event *Pop() {
-		if (notes)  {
-			midi_event *note = notes;
-			notes = note->next_note;
-			note->next_note = 0;
-			polyphony--;
-			return note;
-		}
-
-		return 0;
-	}
-
-	// Pops the top of the stack
-	inline midi_event *Remove(midi_event *event) {
-		midi_event *prev = 0;
-		midi_event *note = notes;
-		while (note) {
-
-			if (note == event) {
-				if (prev) prev->next_note = note->next_note;
-				else notes = note->next_note;
-				note->next_note = 0;
-				polyphony--;
-				return note;
-			}
-			prev = note;
-			note = note->next_note;
-		}
-		return 0;
-	}
-
-	// Finds the note that has same pitch and channel, and pops it
-	inline midi_event *FindAndPop(midi_event *event) {
-
-		midi_event *prev = 0;
-		midi_event *note = notes;
-		while (note) {
-
-			if ((note->status & 0xF) == (event->status & 0xF) && note->data[0] == event->data[0]) {
-				if (prev) prev->next_note = note->next_note;
-				else notes = note->next_note;
-				note->next_note = 0;
-				polyphony--;
-				return note;
-			}
-			prev = note;
-			note = note->next_note;
-		}
-		return 0;
-	}
-
-	// Pushes a note onto the top of the stack
-	inline void Push(midi_event *event) {
-		event->next_note = notes;
-		notes = event;
-		polyphony++;
-		if (max_polyphony < polyphony) max_polyphony = polyphony;
-	}
-
-
-	inline void Push(midi_event *event, uint32_t time) {
-		event->note_time = time;
-		event->next_note = 0;
-
-		polyphony++;
-		if (max_polyphony < polyphony) max_polyphony = polyphony;
-
-		if (!notes || time <= notes->note_time) {
-			event->next_note = notes;
-			notes = event;
-		}
-		else {
-			midi_event *prev = notes;
-			while (prev) {
-				midi_event *note = prev->next_note;
-
-				if (!note || time <= note->note_time) {
-					event->next_note = note;
-					prev->next_note = event;
-					return;
-				}
-				prev = note;
-			}
-		}
-	}
-
-	inline int GetPolyphony() {
-		return polyphony;
-	}
-
-	inline int GetMaxPolyphony() {
-		return max_polyphony;
-	}
-};
-
-class XMIDIEventList 
-{
-	int				counter;
-	
-	// Helper funcs for Write
-	int				PutVLQ(DataSource *dest, uint32_t value);
-	uint32_t			ConvertListToMTrk (DataSource *dest);
-
-	static void		DeleteEventList (midi_event *list);
-
-public:
-	midi_event		*events;
-
-	// Write this list to a file/buffer
-	int				Write (const uint8_t  *filename);	
-	int				Write (DataSource *dest);	
-
-	// Increments the counter
-	void			IncerementCounter () { counter++; }
-
-	// Decrement the counter and delete the event list, if possible
-	void			DecerementCounter ();
-};
-
-class   XMIDI
-{
-protected:
-	uint16_t				num_tracks;
-
-private:
-	XMIDIEventList		**events;
-
-	midi_event			*list;
-	midi_event			*current;
-	midi_event			*notes_on;
-	
-	const static uint8_t 	mt32asgm[128];
-	const static uint8_t 	mt32asgs[256];
-	bool 				bank127[16];
-	int					convert_type;
-
-	bool				is_emidi;
-	bool				use_emidi_112;
-	bool				use_emidi_113;
-	
-	bool				do_reverb;
-	bool				do_chorus;
-	int					chorus_value;
-	int					reverb_value;
-
-public:
-	XMIDI(DataSource *source, int pconvert);
-	~XMIDI();
-
-	int number_of_tracks() { return num_tracks; }
-
-	// External Event list functions
-	XMIDIEventList *GetEventList (uint32_t track);
-
-	// Not yet implimented
-	// int apply_patch (int track, DataSource *source);
-
-private:
-	XMIDI(); // No default constructor
-    
-    struct first_state {			// Status,	Data[0]
-		midi_event		*patch[16];	// 0xC
-		midi_event		*bank[16];	// 0xB,		0
-		midi_event		*pan[16];	// 0xB,		7
-		midi_event		*vol[16];	// 0xB,		10
-	};
-
-	// List manipulation
-	void CreateNewEvent (int time);
-
-	// Variable length quantity
-	int GetVLQ (DataSource *source, uint32_t &quant);
-	int GetVLQ2 (DataSource *source, uint32_t &quant);
-
-	void AdjustTimings(uint32_t ppqn);	// This is used by Midi's ONLY!
-	void ApplyFirstState(first_state &fs, int chan_mask);
-
-	int ConvertNote (const int time, const uint8_t  status, DataSource *source, const int size);
-	int ConvertEvent (const int time, uint8_t  status, DataSource *source, const int size, first_state& fs);
-	int ConvertSystemMessage (const int time, const uint8_t  status, DataSource *source);
-
-	int ConvertFiletoList (DataSource *source, const bool is_xmi, first_state& fs);
-
-	int ExtractTracksFromXmi (DataSource *source);
-	int ExtractTracksFromMid (DataSource *source, const uint32_t ppqn, const int num_tracks, const bool type1);
-	
-	int ExtractTracks (DataSource *source);
-};
-#endif