changeset 428:15ca2ea93a30 trunk

[svn] Sync with upstream CVS. This implements RIX playback.
author chainsaw
date Sat, 14 Jan 2006 07:27:13 -0800
parents f61e69a1a376
children e9569b4111b4
files Plugins/Input/adplug/core/Makefile.am Plugins/Input/adplug/core/adplug.cpp Plugins/Input/adplug/core/analopl.cpp Plugins/Input/adplug/core/analopl.h Plugins/Input/adplug/core/diskopl.cpp Plugins/Input/adplug/core/diskopl.h Plugins/Input/adplug/core/dro.cpp Plugins/Input/adplug/core/dro.h Plugins/Input/adplug/core/emuopl.cpp Plugins/Input/adplug/core/emuopl.h Plugins/Input/adplug/core/hybrid.cpp Plugins/Input/adplug/core/imf.cpp Plugins/Input/adplug/core/imf.h Plugins/Input/adplug/core/kemuopl.h Plugins/Input/adplug/core/mid.cpp Plugins/Input/adplug/core/mid.h Plugins/Input/adplug/core/msc.cpp Plugins/Input/adplug/core/msc.h Plugins/Input/adplug/core/opl.h Plugins/Input/adplug/core/psi.cpp Plugins/Input/adplug/core/psi.h Plugins/Input/adplug/core/rat.cpp Plugins/Input/adplug/core/rat.h Plugins/Input/adplug/core/raw.cpp Plugins/Input/adplug/core/raw.h Plugins/Input/adplug/core/realopl.cpp Plugins/Input/adplug/core/realopl.h Plugins/Input/adplug/core/rix.cpp Plugins/Input/adplug/core/rix.h Plugins/Input/adplug/core/silentopl.h Plugins/Input/adplug/core/temuopl.cpp Plugins/Input/adplug/core/temuopl.h
diffstat 32 files changed, 2008 insertions(+), 662 deletions(-) [+]
line wrap: on
line diff
--- a/Plugins/Input/adplug/core/Makefile.am	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/Makefile.am	Sat Jan 14 07:27:13 2006 -0800
@@ -5,7 +5,8 @@
 players.cpp protrack.cpp a2m.cpp adtrack.cpp amd.cpp bam.cpp d00.cpp dfm.cpp dmo.cpp \
 hsp.cpp ksm.cpp mad.cpp mid.cpp mkj.cpp cff.cpp dtm.cpp fmc.cpp mtk.cpp rad.cpp raw.cpp \
 sa2.cpp s3m.cpp xad.cpp flash.cpp bmf.cpp hybrid.cpp hyp.cpp psi.cpp rat.cpp u6m.cpp \
-rol.cpp xsm.cpp adlibemu.c dro.cpp lds.cpp middata.h
+rol.cpp xsm.cpp adlibemu.c dro.cpp lds.cpp mididata.h realopl.cpp analopl.cpp \
+temuopl.cpp msc.cpp rix.cpp
 
 # This is a hack. Throughout AdPlug, stricmp() is used to do caseless string
 # comparations. UNIX libc's don't support stricmp(), but do support the BSD
@@ -17,6 +18,7 @@
 a2m.h amd.h bam.h d00.h dfm.h hsc.h hsp.h imf.h ksm.h lds.h mid.h mkj.h mtk.h \
 protrack.h rad.h raw.h sa2.h sng.h u6m.h player.h fmc.h mad.h xad.h bmf.h \
 flash.h hyp.h psi.h rat.h hybrid.h rol.h adtrack.h cff.h dtm.h fprovide.h \
-database.h players.h xsm.h adlibemu.h kemuopl.h dro.h dmo.h s3m.h
+database.h players.h xsm.h adlibemu.h kemuopl.h dro.h dmo.h s3m.h realopl.h \
+analopl.h temuopl.h msc.h rix.h
 
 INCLUDES = $(BINIO_CFLAGS) -I$(top_builddir)/intl -I$(top_srcdir)
--- a/Plugins/Input/adplug/core/adplug.cpp	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/adplug.cpp	Sat Jan 14 07:27:13 2006 -0800
@@ -42,7 +42,7 @@
 #include "mid.h"
 #include "mkj.h"
 #include "cff.h"
-#include "dmo.h" 	 
+#include "dmo.h"
 #include "s3m.h"
 #include "dtm.h"
 #include "fmc.h"
@@ -61,10 +61,12 @@
 #include "rol.h"
 #include "xsm.h"
 #include "dro.h"
+#include "msc.h"
+#include "rix.h"
 
 /***** Defines *****/
 
-#define VERSION		"1.5.1"		// AdPlug library version string
+#define VERSION		"1.6"		// AdPlug library version string
 
 /***** CAdPlug *****/
 
@@ -104,6 +106,8 @@
   CPlayerDesc(CrolPlayer::factory, "Adlib Visual Composer", ".rol\0"),
   CPlayerDesc(CxsmPlayer::factory, "eXtra Simple Music", ".xsm\0"),
   CPlayerDesc(CdroPlayer::factory, "DOSBox Raw OPL", ".dro\0"),
+  CPlayerDesc(CmscPlayer::factory, "Adlib MSC Player", ".msc\0"),
+  CPlayerDesc(CrixPlayer::factory, "Softstar RIX OPL Music", ".rix\0"),
   CPlayerDesc()
 };
 
--- a/Plugins/Input/adplug/core/analopl.cpp	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/analopl.cpp	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999, 2000, 2001 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -16,152 +16,52 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- *
- * analopl.cpp - Spectrum analyzing hardware OPL, by Simon Peter (dn.tlp@gmx.net)
+ * analopl.cpp - Spectrum analyzing hardware OPL, by Simon Peter <dn.tlp@gmx.net>
  */
 
-#include <conio.h>
 #include "analopl.h"
 
-#ifdef _MSC_VER
-	#define INP		_inp
-	#define OUTP	_outp
-#elif defined(__WATCOMC__)
-	#define INP		inp
-	#define OUTP	outp
-#endif
-
-#define SHORTDELAY		6					// short delay in I/O port-reads after OPL hardware output
-#define LONGDELAY		35					// long delay in I/O port-reads after OPL hardware output
-
-// the 9 operators as expected by the OPL2
-static const unsigned char op_table[9] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0a, 0x10, 0x11, 0x12};
-
-CAnalopl::CAnalopl(unsigned short initport): adlport(initport), hardvol(0), bequiet(false), nowrite(false)
-{
-	int i;
-
-	for(i=0;i<22;i++) {
-		hardvols[i][0] = 0;
-		hardvols[i][1] = 0;
-	}
-	for(i=0;i<9;i++) {
-		keyregs[i][0] = 0;
-		keyregs[i][1] = 0;
-	}
-}
-
-bool CAnalopl::detect()
+CAnalopl::CAnalopl(unsigned short initport)
+  : CRealopl(initport)
 {
-	unsigned char stat1,stat2,i;
-
-	hardwrite(4,0x60); hardwrite(4,0x80);
-	stat1 = INP(adlport);
-	hardwrite(2,0xff); hardwrite(4,0x21);
-	for(i=0;i<80;i++)			// wait for adlib
-		INP(adlport);
-	stat2 = INP(adlport);
-	hardwrite(4,0x60); hardwrite(4,0x80);
-
-	if(((stat1 & 0xe0) == 0) && ((stat2 & 0xe0) == 0xc0))
-		return true;
-	else
-		return false;
-}
-
-void CAnalopl::setvolume(int volume)
-{
-	int i;
-
-	hardvol = volume;
-	for(i=0;i<9;i++) {
-		hardwrite(0x43+op_table[i],((hardvols[op_table[i]+3][0] & 63) + volume) > 63 ? 63 : hardvols[op_table[i]+3][0] + volume);
-		if(hardvols[i][1] & 1)	// modulator too?
-			hardwrite(0x40+op_table[i],((hardvols[op_table[i]][0] & 63) + volume) > 63 ? 63 : hardvols[op_table[i]][0] + volume);
-	}
-}
-
-void CAnalopl::setquiet(bool quiet)
-{
-	bequiet = quiet;
-
-	if(quiet) {
-		oldvol = hardvol;
-		setvolume(63);
-	} else
-		setvolume(oldvol);
-}
-
-void CAnalopl::hardwrite(int reg, int val)
-{
-	int i;
-
-	OUTP(adlport,reg);							// set register
-	for(i=0;i<SHORTDELAY;i++)					// wait for adlib
-		INP(adlport);
-	OUTP(adlport+1,val);						// set value
-	for(i=0;i<LONGDELAY;i++)					// wait for adlib
-		INP(adlport);
+  for(int i = 0; i < 9; i++) {
+    keyregs[0][i][0] = 0;
+    keyregs[0][i][1] = 0;
+    keyregs[1][i][0] = 0;
+    keyregs[1][i][1] = 0;
+  }
 }
 
 void CAnalopl::write(int reg, int val)
 {
-	int i;
-
-	if(nowrite)
-		return;
+  if(nowrite) return;
 
-	if(reg >= 0xb0 && reg <= 0xb8) {
-		if(!keyregs[reg - 0xb0][0] && (val & 32))
-			keyregs[reg - 0xb0][1] = 1;
-		else
-			keyregs[reg - 0xb0][1] = 0;
-		keyregs[reg - 0xb0][0] = val & 32;
-		if(bequiet)	// filter all key-on commands
-			val &= ~32;
-	}
-	if(reg >= 0x40 && reg <= 0x55)				// cache volumes
-		hardvols[reg-0x40][0] = val;
-	if(reg >= 0xc0 && reg <= 0xc8)
-		hardvols[reg-0xc0][1] = val;
-	if(hardvol)									// reduce volume
-		for(i=0;i<9;i++) {
-			if(reg == 0x43 + op_table[i])
-				val = ((val & 63) + hardvol) > 63 ? 63 : val + hardvol;
-			else
-				if((reg == 0x40 + op_table[i]) && (hardvols[i][1] & 1))
-					val = ((val & 63) + hardvol) > 63 ? 63 : val + hardvol;
-		}
+  if(reg >= 0xb0 && reg <= 0xb8) {
+    if(!keyregs[currChip][reg - 0xb0][0] && (val & 32))
+      keyregs[currChip][reg - 0xb0][1] = 1;
+    else
+      keyregs[currChip][reg - 0xb0][1] = 0;
+    keyregs[currChip][reg - 0xb0][0] = val & 32;
+  }
 
-	hardwrite(reg,val);
+  CRealopl::write(reg, val);
 }
 
-void CAnalopl::init()
+int CAnalopl::getcarriervol(unsigned int v, unsigned int c)
 {
-	int i;
-
-	for (i=0;i<9;i++) {				// stop instruments
-		hardwrite(0xb0 + i,0);				// key off
-		hardwrite(0x80 + op_table[i],0xff);	// fastest release
-	}
-	hardwrite(0xbd,0);	// clear misc. register
+  return (hardvols[c][op_table[v]+3][0] & 63);
 }
 
-int CAnalopl::getcarriervol(unsigned int v)
+int CAnalopl::getmodulatorvol(unsigned int v, unsigned int c)
 {
-	return (hardvols[op_table[v]+3][0] & 63);
+  return (hardvols[c][op_table[v]][0] & 63);
 }
 
-int CAnalopl::getmodulatorvol(unsigned int v)
-{
-	return (hardvols[op_table[v]][0] & 63);
-}
-
-bool CAnalopl::getkeyon(unsigned int v)
+bool CAnalopl::getkeyon(unsigned int v, unsigned int c)
 {
-	if(keyregs[v][1]) {
-		keyregs[v][1] = 0;
-		return true;
-	} else
-		return false;
+  if(keyregs[c][v][1]) {
+    keyregs[c][v][1] = 0;
+    return true;
+  } else
+    return false;
 }
--- a/Plugins/Input/adplug/core/analopl.h	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/analopl.h	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999, 2000, 2001 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -16,49 +16,29 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- *
- * analopl.h - Spectrum analyzing hardware OPL, by Simon Peter (dn.tlp@gmx.net)
+ * analopl.h - Spectrum analyzing hardware OPL, by Simon Peter <dn.tlp@gmx.net>
  */
 
-#ifndef H_ANALOPL_DEFINED
-#define H_ANALOPL_DEFINED
+#ifndef H_ADPLUG_ANALOPL
+#define H_ADPLUG_ANALOPL
 
-#include "opl.h"
+#include "realopl.h"
 
-#define DFL_ADLIBPORT	0x388		// default adlib baseport
-
-class CAnalopl: public Copl
+class CAnalopl: public CRealopl
 {
-public:
-	CAnalopl(unsigned short initport = DFL_ADLIBPORT);	// initport = OPL2 hardware baseport
-
-	bool detect();						// returns true if adlib compatible board is found, else false
-	void setvolume(int volume);			// set adlib master volume (0 - 63) 0 = loudest, 63 = softest
-	void setquiet(bool quiet = true);	// sets the OPL2 quiet, while still writing to the registers
-	void setport(unsigned short port)	// set new OPL2 hardware baseport
-	{ adlport = port; };
-	void setnowrite(bool nw = true)		// set hardware write status
-	{ nowrite = nw; };
+ public:
+  CAnalopl(unsigned short initport = DFL_ADLIBPORT);	// initport = OPL2 hardware baseport
 
-	int getvolume()						// get adlib master volume
-	{ return hardvol; };
-	int getcarriervol(unsigned int v);			// get carrier volume of adlib voice v
-	int getmodulatorvol(unsigned int v);		// get modulator volume of adlib voice v
-	bool getkeyon(unsigned int v);
-
-	// template methods
-	void write(int reg, int val);
-	void init();
+  // get carrier volume of adlib voice v on chip c
+  int getcarriervol(unsigned int v, unsigned int c = 0);
+  // get modulator volume of adlib voice v on chip c
+  int getmodulatorvol(unsigned int v, unsigned int c = 0);
+  bool getkeyon(unsigned int v, unsigned int c = 0);
 
-private:
-	void hardwrite(int reg, int val);	// write to OPL2 hardware registers
+  void write(int reg, int val);
 
-	unsigned short	adlport;			// adlib hardware baseport
-	int				hardvol,oldvol;		// hardware master volume
-	bool			bequiet;			// quiet status cache
-	char			hardvols[22][2];	// volume cache
-	unsigned char	keyregs[9][2];			// shadow key register
-	bool			nowrite;			// don't write to hardware, if true
+ protected:
+  unsigned char	keyregs[2][9][2];		// shadow key register
 };
 
 #endif
--- a/Plugins/Input/adplug/core/diskopl.cpp	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/diskopl.cpp	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999, 2000, 2001 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -16,63 +16,75 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- *
  * diskopl.cpp - Disk Writer OPL, by Simon Peter <dn.tlp@gmx.net>
  */
 
 #include "diskopl.h"
 
-static const unsigned short note_table[12] = {363,385,408,432,458,485,514,544,577,611,647,686};
-static const unsigned char op_table[9] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0a, 0x10, 0x11, 0x12};
+//static const unsigned short note_table[12] = {363,385,408,432,458,485,514,544,577,611,647,686};
+const unsigned char CDiskopl::op_table[9] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0a, 0x10, 0x11, 0x12};
 
-CDiskopl::CDiskopl(std::string filename): old_freq(0.0f), del(1), nowrite(false)
+CDiskopl::CDiskopl(std::string filename)
+  : old_freq(0.0f), del(1), nowrite(false)
 {
-	unsigned short clock = 0xffff;
-	f = fopen(filename.c_str(),"wb");
-	fwrite("RAWADATA",8,1,f);
-	fwrite(&clock,sizeof(clock),1,f);
+  unsigned short clock = 0xffff;
+
+  currType = TYPE_OPL3;
+  f = fopen(filename.c_str(),"wb");
+  fwrite("RAWADATA",8,1,f);
+  fwrite(&clock,sizeof(clock),1,f);
 }
 
 CDiskopl::~CDiskopl()
 {
-	fclose(f);
+  fclose(f);
 }
 
 void CDiskopl::update(CPlayer *p)
 {
-	unsigned short	clock;
-	unsigned int	wait;
+  unsigned short	clock;
+  unsigned int		wait;
 
-	if(p->getrefresh() != old_freq) {
-		old_freq = p->getrefresh();
-		del = wait = (unsigned int)(18.2f / old_freq);
-		clock = (unsigned short)(1192737/(old_freq*(wait+1)));
-		fputc(0,f); fputc(2,f);
-		fwrite(&clock,2,1,f);
-	}
-	if(!nowrite) {
-		fputc(del+1,f);
-		fputc(0,f);
-	}
+  if(p->getrefresh() != old_freq) {
+    old_freq = p->getrefresh();
+    del = wait = (unsigned int)(18.2f / old_freq);
+    clock = (unsigned short)(1192737/(old_freq*(wait+1)));
+    fputc(0,f); fputc(2,f);
+    fwrite(&clock,2,1,f);
+  }
+  if(!nowrite) {
+    fputc(del+1,f);
+    fputc(0,f);
+  }
+}
+
+void CDiskopl::setchip(int n)
+{
+  Copl::setchip(n);
+
+  if(!nowrite) {
+    fputc(currChip + 1, f);
+    fputc(2, f);
+  }
 }
 
 void CDiskopl::write(int reg, int val)
 {
-	if(!nowrite)
-		diskwrite(reg,val);
+  if(!nowrite)
+    diskwrite(reg,val);
 }
 
 void CDiskopl::init()
 {
-	for (int i=0;i<9;i++) {				// stop instruments
-		diskwrite(0xb0 + i,0);				// key off
-		diskwrite(0x80 + op_table[i],0xff);	// fastest release
-	}
-	diskwrite(0xbd,0);	// clear misc. register
+  for (int i=0;i<9;i++) {	// stop instruments
+    diskwrite(0xb0 + i,0);		// key off
+    diskwrite(0x80 + op_table[i],0xff);	// fastest release
+  }
+  diskwrite(0xbd,0);	// clear misc. register
 }
 
 void CDiskopl::diskwrite(int reg, int val)
 {
-	fputc(val,f);
-	fputc(reg,f);
+  fputc(val,f);
+  fputc(reg,f);
 }
--- a/Plugins/Input/adplug/core/diskopl.h	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/diskopl.h	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999, 2000, 2001 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -16,7 +16,6 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- *
  * diskopl.h - Disk Writer OPL, by Simon Peter <dn.tlp@gmx.net>
  */
 
@@ -27,23 +26,27 @@
 
 class CDiskopl: public Copl
 {
-public:
-	CDiskopl(std::string filename);
-	virtual ~CDiskopl();
+ public:
+  CDiskopl(std::string filename);
+  virtual ~CDiskopl();
 
-	void update(CPlayer *p);			// write to file
-	void setnowrite(bool nw = true)		// set file write status
-	{ nowrite = nw; };
+  void update(CPlayer *p);			// write to file
+  void setnowrite(bool nw = true)		// set file write status
+    { nowrite = nw; };
+
+  void setchip(int n);
 
-	// template methods
-	void write(int reg, int val);
-	void init();
+  // template methods
+  void write(int reg, int val);
+  void init();
+
+ private:
+  static const unsigned char	op_table[9];
 
-private:
-	void diskwrite(int reg, int val);
+  FILE		*f;
+  float		old_freq;
+  unsigned char	del;
+  bool		nowrite;			// don't write to file, if true
 
-	FILE			*f;
-	float			old_freq;
-	unsigned char	del;
-	bool			nowrite;			// don't write to file, if true
+  void diskwrite(int reg, int val);
 };
--- a/Plugins/Input/adplug/core/dro.cpp	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/dro.cpp	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -18,9 +18,12 @@
  *
  * dro.c - DOSBox Raw OPL Player by Sjoerd van der Berg <harekiet@zophar.net>
  *
- * NOTES:
- * OPL3 and second opl2 writes are ignored
-  */
+ * upgraded by matthew gambrell <zeromus@zeromus.org>
+ * 
+ * NOTES: 3-oct-04: the DRO format is not yet finalized. beware.
+ */
+
+#include <stdio.h>
 
 #include "dro.h"
 
@@ -31,69 +34,96 @@
   return new CdroPlayer(newopl);
 }
 
+CdroPlayer::CdroPlayer(Copl *newopl)
+  : CPlayer(newopl), data(0)
+{
+  if(opl->gettype() == Copl::TYPE_OPL2)
+    opl3_mode = 0;
+  else
+    opl3_mode = 1;
+}
+
 bool CdroPlayer::load(const std::string &filename, const CFileProvider &fp)
 {
-	binistream *f = fp.open(filename); if(!f) return false;
-	char id[8];unsigned long i;
+  binistream *f = fp.open(filename); if(!f) return false;
+  char id[8];
+  unsigned long i;
 
-	// file validation section
-	f->readString(id, 8);
-	if(strncmp(id,"DBRAWOPL",8)) { fp.close (f); return false; }
+  // file validation section
+  f->readString(id, 8);
+  if(strncmp(id,"DBRAWOPL",8)) { fp.close (f); return false; }
+  int version = f->readInt(4);	// not very useful just yet
+  if(version != 0x10000) { fp.close(f); return false; }
 
-	// load section
-	mstotal = f->readInt(4);	// Total milliseconds in file
-	length = f->readInt(4);		// Total data bytes in file
-	mode = (OplMode)f->readInt(1);		// Type of opl data this can contain
-	data = new unsigned char [length];
-	for (i=0;i<length;i++) 
-		data[i]=f->readInt(1);
-	fp.close(f);
-	rewind(0);
-	return true;
+  // load section
+  mstotal = f->readInt(4);	// Total milliseconds in file
+  length = f->readInt(4);	// Total data bytes in file
+  f->ignore(1);			// Type of opl data this can contain - ignored
+  data = new unsigned char [length];
+  for (i=0;i<length;i++) 
+    data[i]=f->readInt(1);
+  fp.close(f);
+  rewind(0);
+  return true;
 }
 
 bool CdroPlayer::update()
 {
-	if (delay>500) {
-		delay-=500;
-		return true;
-	} else delay=0;
-	while (pos < length) 
-	{	
-		unsigned char cmd = data[pos++];
-		switch(cmd) {
-		case 0: 
-			delay = 1 + data[pos++];
-			return true;
-		case 1: 
-			delay = 1 + data[pos] + (data[pos+1]<<8);
-			pos+=2;
-			return true;
-		case 2:
-			index = 0;
-			break;
-		case 3:
-			index = 0;
-			break;
-		default:
-		  if(!index)
-		    opl->write(cmd,data[pos++]);
-		  break;
-		}
-	}
-	return pos<length;
+  if (delay>500) {
+    delay-=500;
+    return true;
+  } else
+    delay=0;
+
+  while (pos < length) {
+    unsigned char cmd = data[pos++];
+    switch(cmd) {
+    case 0: 
+      delay = 1 + data[pos++];
+      return true;
+    case 1: 
+      delay = 1 + data[pos] + (data[pos+1]<<8);
+      pos+=2;
+      return true;
+    case 2:
+      index = 0;
+      opl->setchip(0);
+      break;
+    case 3:
+      index = 1;
+      opl->setchip(1);
+      break;
+    default:
+      if(cmd==4) cmd = data[pos++]; //data override
+      if(index == 0 || opl3_mode)
+	opl->write(cmd,data[pos++]);
+      break;
+    }
+  }
+
+  return pos<length;
 }
 
 void CdroPlayer::rewind(int subsong)
 {
-	delay=1;
-	pos = index = 0; 
-	opl->init(); 
-	opl->write(1,32);	// go to OPL2 mode
+  delay=1; 
+  pos = index = 0; 
+  opl->init(); 
+
+  //dro assumes all registers are initialized to 0
+  //registers not initialized to 0 will be corrected
+  //in the data stream
+  for(int i=0;i<256;i++)
+    opl->write(i,0);
+	
+  opl->setchip(1);
+  for(int i=0;i<256;i++)
+    opl->write(i,0);
+  opl->setchip(0);
 }
 
 float CdroPlayer::getrefresh()
 {
-	if (delay > 500) return 1000 / 500;
-	else return 1000 / (double)delay;
+  if (delay > 500) return 1000 / 500;
+  else return 1000 / (double)delay;
 }
--- a/Plugins/Input/adplug/core/dro.h	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/dro.h	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -23,30 +23,30 @@
 
 class CdroPlayer: public CPlayer
 {
-public:
+ public:
   static CPlayer *factory(Copl *newopl);
 
-	CdroPlayer(Copl *newopl)
-		: CPlayer(newopl), data(0)
-	{ };
-	~CdroPlayer()
-	{ if(data) delete [] data; };
+  CdroPlayer(Copl *newopl);
+  ~CdroPlayer()
+    {
+      if(data)
+	delete [] data;
+    }
 
-	bool load(const std::string &filename, const CFileProvider &fp);
-	bool update();
-	void rewind(int subsong);
-	float getrefresh();
+  bool load(const std::string &filename, const CFileProvider &fp);
+  bool update();
+  void rewind(int subsong);
+  float getrefresh();
 
-	std::string gettype()
-	{ return std::string("DOSBox Raw OPL"); };
+  std::string gettype()
+    {
+      return std::string("DOSBox Raw OPL");
+    }
 
-protected:
-	unsigned char *data;
-	unsigned long pos,length;
-	unsigned long msdone,mstotal;
-	unsigned short delay;
-	unsigned char index;
-	enum OplMode {
-		ModeOPL2,ModeOPL3,ModeDUALOPL2
-	} mode;
+ protected:
+  unsigned char *data;
+  unsigned long pos,length;
+  unsigned long msdone,mstotal;
+  unsigned short delay;
+  unsigned char index, opl3_mode;
 };
--- a/Plugins/Input/adplug/core/emuopl.cpp	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/emuopl.cpp	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * AdPlug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2002 Simon Peter <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -22,54 +22,126 @@
 #include "emuopl.h"
 
 CEmuopl::CEmuopl(int rate, bool bit16, bool usestereo)
-  : use16bit(bit16), stereo(usestereo)
+  : use16bit(bit16), stereo(usestereo), mixbufSamples(0)
 {
-  opl = OPLCreate(OPL_TYPE_YM3812, 3579545, rate);
+  opl[0] = OPLCreate(OPL_TYPE_YM3812, 3579545, rate);
+  opl[1] = OPLCreate(OPL_TYPE_YM3812, 3579545, rate);
+
+  currType = TYPE_DUAL_OPL2;
+
+  init();
 }
 
 CEmuopl::~CEmuopl()
 {
-  OPLDestroy(opl);
+  OPLDestroy(opl[0]); OPLDestroy(opl[1]);
+
+  if(mixbufSamples) {
+    delete [] mixbuf0;
+    delete [] mixbuf1;
+  }
 }
 
 void CEmuopl::update(short *buf, int samples)
 {
-	int i;
+  int i;
 
-	if(use16bit) {
-		YM3812UpdateOne(opl,buf,samples);
+  //ensure that our mix buffers are adequately sized
+  if(mixbufSamples < samples) {
+    if(mixbufSamples) { delete[] mixbuf0; delete[] mixbuf1; }
+    mixbufSamples = samples;
+
+    //*2 = make room for stereo, if we need it
+    mixbuf0 = new short[samples*2]; 
+    mixbuf1 = new short[samples*2];
+  }
 
-		if(stereo)
-			for(i=samples-1;i>=0;i--) {
-				buf[i*2] = buf[i];
-				buf[i*2+1] = buf[i];
-			}
-	} else {
-		short *tempbuf = new short[stereo ? samples*2 : samples];
-		int i;
+  //data should be rendered to outbuf
+  //tempbuf should be used as a temporary buffer
+  //if we are supposed to generate 16bit output,
+  //then outbuf may point directly to the actual waveform output "buf"
+  //if we are supposed to generate 8bit output,
+  //then outbuf cannot point to "buf" (because there will not be enough room)
+  //and so it must point to a mixbuf instead--
+  //it will be reduced to 8bit and put in "buf" later
+  short *outbuf;
+  short *tempbuf=mixbuf0;
+  short *tempbuf2=mixbuf1;
+  if(use16bit) outbuf = buf;
+  else outbuf = mixbuf1;
+  //...there is a potentially confusing situation where mixbuf1 can be aliased.
+  //beware. it is a little loony.
+
+  //all of the following rendering code produces 16bit output
+
+  switch(currType) {
+  case TYPE_OPL2:
+    //for opl2 mode:
+    //render chip0 to the output buffer
+    YM3812UpdateOne(opl[0],outbuf,samples);
 
-		YM3812UpdateOne(opl,tempbuf,samples);
+    //if we are supposed to output stereo,
+    //then we need to dup the mono channel
+    if(stereo)
+      for(i=samples-1;i>=0;i--) {
+	outbuf[i*2] = outbuf[i];
+	outbuf[i*2+1] = outbuf[i];
+      }
+    break;
+
+  case TYPE_OPL3:	// unsupported
+    break;
+
+  case TYPE_DUAL_OPL2:
+    //for dual opl2 mode:
+    //render each chip to a different tempbuffer
+    YM3812UpdateOne(opl[0],tempbuf2,samples);
+    YM3812UpdateOne(opl[1],tempbuf,samples);
 
-		if(stereo)
-			for(i=samples-1;i>=0;i--) {
-				tempbuf[i*2] = tempbuf[i];
-				tempbuf[i*2+1] = tempbuf[i];
-			}
+    //output stereo:
+    //then we need to interleave the two buffers
+    if(stereo){
+      //first, spread tempbuf's samples across left channel
+      //left channel
+      for(i=0;i<samples;i++)
+	outbuf[i*2] = tempbuf2[i];
+      //next, insert the samples from tempbuf2 into right channel
+      for(i=0;i<samples;i++)
+	outbuf[i*2+1] = tempbuf[i];
+    } else
+      //output mono:
+      //then we need to mix the two buffers into buf
+      for(i=0;i<samples;i++)
+	outbuf[i] = (tempbuf[i]>>1) + (tempbuf2[i]>>1);
+    break;
+  }
 
-		for(i=0;i<(stereo ? samples*2 : samples);i++)
-			((char *)buf)[i] = (tempbuf[i] >> 8) ^ 0x80;
-
-		delete [] tempbuf;
-	}
+  //now reduce to 8bit if we need to
+  if(!use16bit)
+    for(i=0;i<(stereo ? samples*2 : samples);i++)
+      ((char *)buf)[i] = (outbuf[i] >> 8) ^ 0x80;
 }
 
 void CEmuopl::write(int reg, int val)
 {
-  OPLWrite(opl,0,reg);
-  OPLWrite(opl,1,val);
+  switch(currType){
+  case TYPE_OPL2:
+  case TYPE_DUAL_OPL2:
+    OPLWrite(opl[currChip], 0, reg);
+    OPLWrite(opl[currChip], 1, val);
+    break;
+  case TYPE_OPL3:	// unsupported
+    break;
+  }
 }
 
 void CEmuopl::init()
 {
-  OPLResetChip(opl);
+  OPLResetChip(opl[0]); OPLResetChip(opl[1]);
+  currChip = 0;
 }
+
+void CEmuopl::settype(ChipType type)
+{
+  currType = type;
+}
--- a/Plugins/Input/adplug/core/emuopl.h	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/emuopl.h	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -29,19 +29,21 @@
 
 class CEmuopl: public Copl
 {
-public:
-	CEmuopl(int rate, bool bit16, bool usestereo);	// rate = sample rate
-	virtual ~CEmuopl();
+ public:
+  CEmuopl(int rate, bool bit16, bool usestereo);	// rate = sample rate
+  virtual ~CEmuopl();
 
-	void update(short *buf, int samples);	// fill buffer
+  void update(short *buf, int samples);			// fill buffer
+  void write(int reg, int val);
 
-	// template methods
-	void write(int reg, int val);
-	void init();
+  void init();
+  void settype(ChipType type);
 
-private:
-	bool	use16bit,stereo;
-	FM_OPL	*opl;				// holds emulator data
+ private:
+  bool		use16bit, stereo;
+  FM_OPL	*opl[2];				// OPL2 emulator data
+  short		*mixbuf0, *mixbuf1;
+  int		mixbufSamples;
 };
 
 #endif
--- a/Plugins/Input/adplug/core/hybrid.cpp	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/hybrid.cpp	Sat Jan 14 07:27:13 2006 -0800
@@ -132,8 +132,9 @@
   // process channels
   for(i=0;i<9;i++)
   {
+    unsigned char *pos = &tune[0xADE + (hyb.order[hyb.order_pos*9 + i] * 64 * 2) + (patpos * 2)];
     // read event
-    unsigned short event = *(unsigned short *)&tune[0xADE + (hyb.order[hyb.order_pos*9 + i] * 64 * 2) + (patpos * 2)];
+    unsigned short event = (pos[1] << 8) + pos[0];
 
 #ifdef DEBUG
    AdPlug_LogWrite("track %02X, channel %02X, event %04X:\n", hyb.order[hyb.order_pos*9 + i], i, event );
--- a/Plugins/Input/adplug/core/imf.cpp	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/imf.cpp	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 Simon Peter <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -90,7 +90,7 @@
       f->seek(-4, binio::Add);
     else
       f->seek(-2, binio::Add);
-    size = flsize / 4;
+    size = (flsize - mfsize) / 4;
   } else		// file has got a footer
     size = fsize / 4;
 
@@ -101,13 +101,20 @@
   }
 
   // read footer, if any
-  if(fsize && (fsize < flsize - 2 - mfsize)) {
-    unsigned long footerlen = flsize - fsize - 2 - mfsize;
+  if(fsize && (fsize < flsize - 2 - mfsize))
+    if(f->readInt(1) == 0x1a) {
+      // Adam Nielsen's footer format
+      track_name = f->readString();
+      author_name = f->readString();
+      remarks = f->readString();
+    } else {
+      // Generic footer
+      unsigned long footerlen = flsize - fsize - 2 - mfsize;
 
-    footer = new char[footerlen + 1];
-    f->readString(footer, footerlen);
-    footer[footerlen] = '\0';	// Make ASCIIZ string
-  }
+      footer = new char[footerlen + 1];
+      f->readString(footer, footerlen);
+      footer[footerlen] = '\0';	// Make ASCIIZ string
+    }
 
   rate = getrate(f);
   fp.close(f);
@@ -152,6 +159,21 @@
   return title;
 }
 
+std::string CimfPlayer::getdesc()
+{
+  std::string	desc;
+
+  if(footer)
+    desc = std::string(footer);
+
+  if(!remarks.empty() && footer)
+    desc += "\n\n";
+
+  desc += remarks;
+
+  return desc;
+}
+
 /*** private methods *************************************/
 
 float CimfPlayer::getrate(binistream *f)
--- a/Plugins/Input/adplug/core/imf.h	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/imf.h	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 Simon Peter <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -31,29 +31,30 @@
 
 	CimfPlayer(Copl *newopl)
 	  : CPlayer(newopl), footer(0), data(0)
-	{ }
+	  { }
 	~CimfPlayer()
-	{ if(data) delete [] data; if(footer) delete [] footer; };
+	  { if(data) delete [] data; if(footer) delete [] footer; };
 
 	bool load(const std::string &filename, const CFileProvider &fp);
 	bool update();
 	void rewind(int subsong);
 	float getrefresh()
-	{ return timer; };
+	  { return timer; };
 
 	std::string gettype()
-	{ return std::string("IMF File Format"); }
+	  { return std::string("IMF File Format"); }
 	std::string gettitle();
-	std::string getdesc()
-	{ if(footer) return std::string(footer); else return std::string(); }
+	std::string getauthor()
+	  { return author_name; }
+	std::string getdesc();
 
 protected:
-	unsigned long	pos,size;
+	unsigned long	pos, size;
 	unsigned short	del;
 	bool		songend;
-	float		rate,timer;
+	float		rate, timer;
 	char		*footer;
-	std::string	track_name, game_name;
+	std::string	track_name, game_name, author_name, remarks;
 
 	struct Sdata {
 		unsigned char	reg, val;
--- a/Plugins/Input/adplug/core/kemuopl.h	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/kemuopl.h	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -35,6 +35,7 @@
     : use16bit(bit16), stereo(usestereo)
     {
       adlibinit(rate, usestereo ? 2 : 1, bit16 ? 2 : 1);
+      currType = TYPE_OPL2;
     };
 
   void update(short *buf, int samples)
@@ -47,7 +48,8 @@
   // template methods
   void write(int reg, int val)
     {
-      adlib0(reg, val);
+      if(currChip == 0)
+	adlib0(reg, val);
     };
 
   void init() {};
--- a/Plugins/Input/adplug/core/mid.cpp	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/mid.cpp	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -17,7 +17,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  *
- * MIDI & MIDI-like file player - Last Update: 8/16/2000
+ * MIDI & MIDI-like file player - Last Update: 10/15/2005
  *                  by Phil Hassey - www.imitationpickles.org
  *                                   philhassey@hotmail.com
  *
@@ -57,9 +57,12 @@
  *                               I think some of them are supposed to be
  *                               played at the same time, but I'm not sure
  *                               when.
- *  8/16/200:
+ * 8/16/2000:
  *      Status:  LAA: now EGA and VGA lucas games work pretty well
  *
+ * 10/15/2005: Changes by Simon Peter
+ *	Added rhythm mode support for CMF format.
+ *
  * Other acknowledgements:
  *  Allegro - for the midi instruments and the midi volume table
  *  SCUMM Revisited - for getting the .LAA / .MIDs out of those
@@ -75,15 +78,59 @@
 #include "mid.h"
 #include "mididata.h"
 
+/*#define TESTING*/
+#ifdef TESTING
+#define midiprintf printf
+#else
 void CmidPlayer::midiprintf(char *format, ...)
     {
     }
+#endif
+
+#define LUCAS_STYLE   1
+#define CMF_STYLE     2
+#define MIDI_STYLE    4
+#define SIERRA_STYLE  8
+
+// AdLib melodic and rhythm mode defines
+#define ADLIB_MELODIC	0
+#define ADLIB_RYTHM	1
+
+// File types
+#define FILE_LUCAS      1
+#define FILE_MIDI       2
+#define FILE_CMF        3
+#define FILE_SIERRA     4
+#define FILE_ADVSIERRA  5
+#define FILE_OLDLUCAS   6
+
+// AdLib standard operator table
+const unsigned char CmidPlayer::adlib_opadd[] = {0x00  ,0x01 ,0x02  ,0x08  ,0x09  ,0x0A  ,0x10 ,0x11  ,0x12};
+
+// dunno
+const int CmidPlayer::ops[] = {0x20,0x20,0x40,0x40,0x60,0x60,0x80,0x80,0xe0,0xe0,0xc0};
+
+// map CMF drum channels 12 - 15 to corresponding AdLib drum operators
+// bass drum (channel 11) not mapped, cause it's handled like a normal instrument
+const int CmidPlayer::map_chan[] = { 0x14, 0x12, 0x15, 0x11 };
+
+// Standard AdLib frequency table
+const int CmidPlayer::fnums[] = { 0x16b,0x181,0x198,0x1b0,0x1ca,0x1e5,0x202,0x220,0x241,0x263,0x287,0x2ae };
+
+// Map CMF drum channels 11 - 15 to corresponding AdLib drum channels
+const int CmidPlayer::percussion_map[] = { 6, 7, 8, 8, 7 };
 
 CPlayer *CmidPlayer::factory(Copl *newopl)
 {
   return new CmidPlayer(newopl);
 }
 
+CmidPlayer::CmidPlayer(Copl *newopl)
+  : CPlayer(newopl), author(&emptystr), title(&emptystr), remarks(&emptystr),
+    emptystr('\0'), flen(0), data(0)
+{
+}
+
 unsigned char CmidPlayer::datalook(long pos)
 {
     if (pos<0 || pos >= flen) return(0);
@@ -130,14 +177,6 @@
 	return(v);
 }
 
-#define LUCAS_STYLE   1
-#define CMF_STYLE     2
-#define MIDI_STYLE    4
-#define SIERRA_STYLE  8
-
-#define ADLIB_MELODIC	0
-#define ADLIB_RYTHM	1
-
 bool CmidPlayer::load_sierra_ins(const std::string &fname, const CFileProvider &fp)
 {
     long i,j,k,l;
@@ -241,13 +280,6 @@
     doing=1;
 }
 
-#define FILE_LUCAS      1
-#define FILE_MIDI       2
-#define FILE_CMF        3
-#define FILE_SIERRA     4
-#define FILE_ADVSIERRA  5
-#define FILE_OLDLUCAS   6
-
 bool CmidPlayer::load(const std::string &filename, const CFileProvider &fp)
 {
     binistream *f = fp.open(filename); if(!f) return false;
@@ -297,13 +329,10 @@
 
 void CmidPlayer::midi_write_adlib(unsigned int r, unsigned char v)
 {
-	opl->write(r,v);
-    adlib_data[r]=v;
+  opl->write(r,v);
+  adlib_data[r]=v;
 }
 
-unsigned char adlib_opadd[] = {0x00  ,0x01 ,0x02  ,0x08  ,0x09  ,0x0A  ,0x10 ,0x11  ,0x12};
-int ops[] = {0x20,0x20,0x40,0x40,0x60,0x60,0x80,0x80,0xe0,0xe0,0xc0};
-
 void CmidPlayer::midi_fm_instrument(int voice, unsigned char *inst)
 {
     if ((adlib_style&SIERRA_STYLE)!=0)
@@ -350,6 +379,18 @@
     midi_write_adlib(0xc0+voice,inst[10]);
 }
 
+void CmidPlayer::midi_fm_percussion(int ch, unsigned char *inst)
+{
+  int	opadd = map_chan[ch - 12];
+
+  midi_write_adlib(0x20 + opadd, inst[0]);
+  midi_write_adlib(0x40 + opadd, inst[2]);
+  midi_write_adlib(0x60 + opadd, inst[4]);
+  midi_write_adlib(0x80 + opadd, inst[6]);
+  midi_write_adlib(0xe0 + opadd, inst[8]);
+  midi_write_adlib(0xc0 + opadd, inst[10]);
+}
+
 void CmidPlayer::midi_fm_volume(int voice, int volume)
 {
     int vol;
@@ -361,8 +402,7 @@
     if ((adlib_style&LUCAS_STYLE)!=0)
         {
         if ((adlib_data[0xc0+voice]&1)==1)
-            midi_write_adlib(0x40+adlib_opadd[voice], (unsigned 
-char)((63-vol) |
+            midi_write_adlib(0x40+adlib_opadd[voice], (unsigned char)((63-vol) |
             (adlib_data[0x40+adlib_opadd[voice]]&0xc0)));
         midi_write_adlib(0x43+adlib_opadd[voice], (unsigned char)((63-vol) |
             (adlib_data[0x43+adlib_opadd[voice]]&0xc0)));
@@ -370,8 +410,7 @@
         else
         {
         if ((adlib_data[0xc0+voice]&1)==1)
-            midi_write_adlib(0x40+adlib_opadd[voice], (unsigned 
-char)((63-vol) |
+            midi_write_adlib(0x40+adlib_opadd[voice], (unsigned char)((63-vol) |
             (adlib_data[0x40+adlib_opadd[voice]]&0xc0)));
         midi_write_adlib(0x43+adlib_opadd[voice], (unsigned char)((63-vol) |
            (adlib_data[0x43+adlib_opadd[voice]]&0xc0)));
@@ -379,11 +418,6 @@
     }
 }
 
-
-int fnums[] = {
-0x16b,0x181,0x198,0x1b0,0x1ca,0x1e5,0x202,0x220,0x241,0x263,0x287,0x2ae
-		  };
-
 void CmidPlayer::midi_fm_playnote(int voice, int note, int volume)
 {
     int freq=fnums[note%12];
@@ -393,7 +427,7 @@
     midi_fm_volume(voice,volume);
     midi_write_adlib(0xa0+voice,(unsigned char)(freq&0xff));
 
-	c=((freq&0x300) >> 8)+(oct<<2) + (1<<5);
+	c=((freq&0x300) >> 8)+(oct<<2) + (adlib_mode == ADLIB_MELODIC || voice < 6 ? (1<<5) : 0);
     midi_write_adlib(0xb0+voice,(unsigned char)c);
 }
 
@@ -408,6 +442,9 @@
 void CmidPlayer::midi_fm_reset()
 {
     int i;
+
+    opl->init();
+
     for (i=0; i<256; i++)
         midi_write_adlib(i,0);
 
@@ -419,7 +456,7 @@
 {
     long w,v,note,vel,ctrl,nv,x,l,lnum;
     int i=0,j,c;
-    int on,onl;
+    int on,onl,numchan;
     unsigned char ins[11];
     int ret;
 
@@ -473,44 +510,42 @@
               //  doing=0;
                 note=getnext(1); vel=getnext(1);
 
+		if(adlib_mode == ADLIB_RYTHM)
+		  numchan = 6;
+		else
+		  numchan = 9;
+
                 if (ch[c].on!=0)
                 {
-                for (i=0; i<9; i++)
+		  for (i=0; i<18; i++)
                     chp[i][2]++;
 
-                j=0;
-                on=-1;onl=0;
-                for (i=0; i<9; i++)
-                    if (chp[i][0]==-1 && chp[i][2]>onl)
-                        { onl=chp[i][2]; on=i; j=1; }
+		  if(c < 11 || adlib_mode == ADLIB_MELODIC) {
+		    j=0;
+		    on=-1;onl=0;
+		    for (i=0; i<numchan; i++)
+		      if (chp[i][0]==-1 && chp[i][2]>onl)
+			{ onl=chp[i][2]; on=i; j=1; }
 
-                if (on==-1)
-                    {
-                    onl=0;
-                    for (i=0; i<9; i++)
-                        if (chp[i][2]>onl)
-                            { onl=chp[i][2]; on=i; }
-                    }
+		    if (on==-1)
+		      {
+			onl=0;
+			for (i=0; i<numchan; i++)
+			  if (chp[i][2]>onl)
+			    { onl=chp[i][2]; on=i; }
+		      }
 
-                 if (j==0)
-                    midi_fm_endnote(on);
+		    if (j==0)
+		      midi_fm_endnote(on);
+		  } else
+		    on = percussion_map[c - 11];
 
                  if (vel!=0 && ch[c].inum>=0 && ch[c].inum<128)
                     {
                     if (adlib_mode == ADLIB_MELODIC || c < 12)
-                        midi_fm_instrument(on,ch[c].ins);
-                        else
-                        {
-                        //the following fails to be effective
-                        //at doing rythm sounds .. (cmf blah)
-                        ins[0]=ins[1]=ch[c].ins[0];
-                        ins[2]=ins[3]=ch[c].ins[2];
-                        ins[4]=ins[5]=ch[c].ins[4];
-                        ins[6]=ins[7]=ch[c].ins[6];
-                        ins[8]=ins[9]=ch[c].ins[8];
-                        ins[10]=ch[c].ins[10]|1;
-                        midi_fm_instrument(on,ins);
-                        }
+		      midi_fm_instrument(on,ch[c].ins);
+		    else
+ 		      midi_fm_percussion(c, ch[c].ins);
 
                     if ((adlib_style&MIDI_STYLE)!=0)
                         {
@@ -527,10 +562,16 @@
                         nv=vel;
                         }
 
-                    midi_fm_playnote(on,note+ch[c].nshift,nv*2);
+		    midi_fm_playnote(on,note+ch[c].nshift,nv*2);
                     chp[on][0]=c;
                     chp[on][1]=note;
                     chp[on][2]=0;
+
+		    if(adlib_mode == ADLIB_RYTHM && c >= 11) {
+		      midi_write_adlib(0xbd, adlib_data[0xbd] & ~(0x10 >> (c - 11)));
+		      midi_write_adlib(0xbd, adlib_data[0xbd] | (0x10 >> (c - 11)));
+		    }
+
                     }
                     else
                     {
@@ -576,17 +617,22 @@
                         break;
                     case 0x67:
                         midiprintf ("\n\nhere:%d\n\n",vel);
-                        if ((adlib_style&CMF_STYLE)!=0)
-                            adlib_mode=vel;  // this gets faked - no mode change
+                        if ((adlib_style&CMF_STYLE)!=0) {
+			  adlib_mode=vel;
+			  if(adlib_mode == ADLIB_RYTHM)
+			    midi_write_adlib(0xbd, adlib_data[0xbd] | (1 << 5));
+			  else
+			    midi_write_adlib(0xbd, adlib_data[0xbd] & ~(1 << 5));
+			}
                         break;
                     }
                 break;
             case 0xc0: /*patch change*/
-				x=getnext(1);
-                ch[c].inum=x;
-                for (j=0; j<11; j++)
-                    ch[c].ins[j]=myinsbank[ch[c].inum][j];
-                break;
+	      x=getnext(1);
+	      ch[c].inum=x;
+	      for (j=0; j<11; j++)
+		ch[c].ins[j]=myinsbank[ch[c].inum][j];
+	      break;
             case 0xd0: /*chanel touch*/
                 x=getnext(1);
                 break;
@@ -599,11 +645,11 @@
                     {
                     case 0xf0:
                     case 0xf7: /*sysex*/
-						l=getval();
-                        if (datalook(pos+l)==0xf7)
-							i=1;
-                        midiprintf("{%d}",l);
-                        midiprintf("\n");
+		      l=getval();
+		      if (datalook(pos+l)==0xf7)
+			i=1;
+		      midiprintf("{%d}",l);
+		      midiprintf("\n");
 
                         if (datalook(pos)==0x7d &&
                             datalook(pos+1)==0x10 &&
@@ -1019,7 +1065,7 @@
                 }
 
     doing=1;
-	opl->init();
+    midi_fm_reset();
 }
 
 std::string CmidPlayer::gettype()
--- a/Plugins/Input/adplug/core/mid.h	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/mid.h	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -26,86 +26,87 @@
 public:
   static CPlayer *factory(Copl *newopl);
 
-	CmidPlayer(Copl *newopl)
-		: CPlayer(newopl), author(&emptystr), title(&emptystr),
-	  remarks(&emptystr), emptystr('\0'), flen(0), data(0)
-	{ };
-	~CmidPlayer()
-	{ if(data) delete [] data; };
+  CmidPlayer(Copl *newopl);
+  ~CmidPlayer()
+    { if(data) delete [] data; }
+
+  bool load(const std::string &filename, const CFileProvider &fp);
+  bool update();
+  void rewind(int subsong);
+  float getrefresh();
 
-	bool load(const std::string &filename, const CFileProvider &fp);
-	bool update();
-	void rewind(int subsong);
-	float getrefresh();
+  std::string gettype();
+  std::string gettitle()
+    { return std::string(title); }
+  std::string getauthor()
+    { return std::string(author); }
+  std::string getdesc()
+    { return std::string(remarks); }
+  unsigned int getinstruments()
+    { return tins; }
+  unsigned int getsubsongs()
+    { return subsongs; }
 
-	std::string gettype();
-	std::string gettitle()
-	{ return std::string(title); };
-	std::string getauthor()
-	{ return std::string(author); };
-	std::string getdesc()
-	{ return std::string(remarks); };
-	unsigned int getinstruments()
-	{ return tins; };
-	unsigned int getsubsongs()
-	{ return subsongs; };
+ protected:
+  static const unsigned char adlib_opadd[];
+  static const int ops[], map_chan[], fnums[], percussion_map[];
 
-protected:
-	struct midi_channel {
-		int inum;
-		unsigned char ins[11];
-		int vol;
-		int nshift;
-		int on;
-	};
+  struct midi_channel {
+    int inum;
+    unsigned char ins[11];
+    int vol;
+    int nshift;
+    int on;
+  };
 
-	struct midi_track {
-		unsigned long tend;
-		unsigned long spos;
-		unsigned long pos;
-		unsigned long iwait;
-		int on;
-		unsigned char pv;
-	};
+  struct midi_track {
+    unsigned long tend;
+    unsigned long spos;
+    unsigned long pos;
+    unsigned long iwait;
+    int on;
+    unsigned char pv;
+  };
 
-    char *author,*title,*remarks,emptystr;
-    long flen;
-    unsigned long pos;
-    unsigned long sierra_pos; //sierras gotta be special.. :>
-    int subsongs;
-    unsigned char *data;
+  char *author,*title,*remarks,emptystr;
+  long flen;
+  unsigned long pos;
+  unsigned long sierra_pos; //sierras gotta be special.. :>
+  int subsongs;
+  unsigned char *data;
 
-    unsigned char adlib_data[256];
-    int adlib_style;
-    int adlib_mode;
-    unsigned char myinsbank[128][16], smyinsbank[128][16];
-    midi_channel ch[16];
-    int chp[9][3];
+  unsigned char adlib_data[256];
+  int adlib_style;
+  int adlib_mode;
+  unsigned char myinsbank[128][16], smyinsbank[128][16];
+  midi_channel ch[16];
+  int chp[18][3];
 
-    long deltas;
-    long msqtr;
+  long deltas;
+  long msqtr;
 
-    midi_track track[16];
-    unsigned int curtrack;
+  midi_track track[16];
+  unsigned int curtrack;
 
-    float fwait;
-    unsigned long iwait;
-    int doing;
+  float fwait;
+  unsigned long iwait;
+  int doing;
 
-    int type,tins,stins;
+  int type,tins,stins;
 
-private:
-	bool load_sierra_ins(const std::string &fname, const CFileProvider &fp);
-	void midiprintf(char *format, ...);
-	unsigned char datalook(long pos);
-	unsigned long getnexti(unsigned long num);
-	unsigned long getnext(unsigned long num);
-	unsigned long getval();
-	void sierra_next_section();
-	void midi_write_adlib(unsigned int r, unsigned char v);
-	void midi_fm_instrument(int voice, unsigned char *inst);
-	void midi_fm_volume(int voice, int volume);
-	void midi_fm_playnote(int voice, int note, int volume);
-	void midi_fm_endnote(int voice);
-	void midi_fm_reset();
+ private:
+  bool load_sierra_ins(const std::string &fname, const CFileProvider &fp);
+  void midiprintf(char *format, ...);
+  unsigned char datalook(long pos);
+  unsigned long getnexti(unsigned long num);
+  unsigned long getnext(unsigned long num);
+  unsigned long getval();
+  void sierra_next_section();
+  void midi_write_adlib(unsigned int r, unsigned char v);
+  void midi_fm_instrument(int voice, unsigned char *inst);
+  void midi_fm_percussion(int ch, unsigned char *inst);
+  void midi_fm_volume(int voice, int volume);
+  void midi_fm_playnote(int voice, int note, int volume);
+  void midi_fm_endnote(int voice);
+  void midi_fm_reset();
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/msc.cpp	Sat Jan 14 07:27:13 2006 -0800
@@ -0,0 +1,322 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * msc.c - MSC Player by Lubomir Bulej (pallas@kadan.cz)
+ */
+
+#include <stdio.h>
+
+#include "msc.h"
+
+const unsigned char CmscPlayer::msc_signature [MSC_SIGN_LEN] = {
+	'C', 'e', 'r', 'e', 's', ' ', '\x13', ' ',
+	'M', 'S', 'C', 'p', 'l', 'a', 'y', ' ' };
+
+
+/*** public methods *************************************/
+
+CPlayer *
+CmscPlayer::factory (Copl * newopl)
+{
+	return new CmscPlayer (newopl);
+}
+
+	
+CmscPlayer::CmscPlayer (Copl * newopl) : CPlayer (newopl) {
+	desc = NULL;
+	msc_data = NULL;
+	raw_data = NULL;
+	nr_blocks = 0;
+}
+
+
+CmscPlayer::~CmscPlayer ()
+{
+	if (raw_data != NULL)
+		delete [] raw_data;
+	
+	if (msc_data != NULL) {
+		// free compressed blocks
+		for (int blk_num = 0; blk_num < nr_blocks; blk_num++) {
+			if (msc_data [blk_num].mb_data != NULL)
+				delete [] msc_data [blk_num].mb_data;
+		}
+		
+		delete [] msc_data;
+	}
+	
+	if (desc != NULL)
+		delete [] desc;
+}
+
+
+bool 
+CmscPlayer::load (const std::string & filename, const CFileProvider & fp)
+{
+	binistream * 	bf;
+	msc_header	hdr;
+
+	// open and validate the file
+	bf = fp.open (filename);
+	if (! bf)
+		return false;
+	
+	if (! load_header (bf, & hdr)) {
+		fp.close (bf);
+		return false;
+	}
+	
+	// get stuff from the header
+	version = hdr.mh_ver;
+	timer_div = hdr.mh_timer;
+	nr_blocks = hdr.mh_nr_blocks;
+	block_len = hdr.mh_block_len;
+	
+	if (! nr_blocks) {
+		fp.close (bf);
+		return false;
+	}
+	
+	// load compressed data blocks
+	msc_data = new msc_block [nr_blocks];
+	raw_data = new u8 [block_len];
+
+	for (int blk_num = 0; blk_num < nr_blocks; blk_num++) {
+		msc_block blk;
+		
+		blk.mb_length = bf->readInt (2);
+		blk.mb_data = new u8 [blk.mb_length];
+		for (int oct_num = 0; oct_num < blk.mb_length; oct_num++) {
+			blk.mb_data [oct_num] = bf->readInt (1);
+		}
+		
+		msc_data [blk_num] = blk;
+	}
+	
+	// clean up & initialize
+	fp.close (bf);
+	rewind (0);
+	
+	return true;	
+}
+
+
+bool 
+CmscPlayer::update ()
+{
+	// output data
+	while (! delay) {
+		u8	cmnd;
+		u8	data;
+
+		// decode data
+		if (! decode_octet (& cmnd))
+			return false;
+			
+		if (! decode_octet (& data))
+			return false;
+			
+		// check for special commands
+		switch (cmnd) {
+		
+		// delay
+		case 0xff:
+			delay = 1 + (u8) (data - 1);
+			break;
+		
+		// play command & data
+		default:
+			opl->write (cmnd, data);
+			
+		} // command switch
+	} // play pass
+	
+	
+	// count delays
+	if (delay)
+		delay--;
+	
+	// advance player position
+	play_pos++;
+	return true;
+}
+
+
+void 
+CmscPlayer::rewind (int subsong)
+{
+	// reset state
+	dec_prefix = 0;
+	block_num = 0;
+	block_pos = 0;
+	play_pos = 0;
+	raw_pos = 0;
+	delay = 0;
+	
+	// init the OPL chip and go to OPL2 mode
+	opl->init (); 
+	opl->write (1, 32);
+}
+
+
+float 
+CmscPlayer::getrefresh ()
+{
+	// PC timer oscillator frequency / wait register
+	return 1193180 / (float) (timer_div ? timer_div : 0xffff);
+}
+
+std::string
+CmscPlayer::gettype ()
+{
+	char vstr [40];
+	
+	snprintf (vstr, sizeof (vstr), "AdLib MSCplay (version %d)", version);
+	return std::string (vstr);
+}
+
+
+/*** private methods *************************************/
+
+bool 
+CmscPlayer::load_header (binistream * bf, msc_header * hdr)
+{
+	// check signature
+	bf->readString ((char *) hdr->mh_sign, sizeof (hdr->mh_sign));
+	if (memcmp (msc_signature, hdr->mh_sign, MSC_SIGN_LEN) != 0)
+		return false;
+
+	// check version
+	hdr->mh_ver = bf->readInt (2);
+	if (hdr->mh_ver != 0)
+		return false;
+
+	bf->readString ((char *) hdr->mh_desc, sizeof (hdr->mh_desc));
+	hdr->mh_timer = bf->readInt (2);
+	hdr->mh_nr_blocks = bf->readInt (2);
+	hdr->mh_block_len = bf->readInt (2);
+	return true;
+}
+
+
+bool
+CmscPlayer::decode_octet (u8 * output)
+{
+	msc_block blk;			// compressed data block
+	
+	if (block_num >= nr_blocks)
+		return false;
+		
+	blk = msc_data [block_num];
+	while (1) {
+		u8 	octet;		// decoded octet
+		u8	len_corr;	// length correction
+		
+		// advance to next block if necessary
+		if (block_pos >= blk.mb_length && dec_len == 0) {
+			block_num++;
+			if (block_num >= nr_blocks)
+				return false;
+				
+			blk = msc_data [block_num];
+			block_pos = 0;
+			raw_pos = 0;
+		}
+		
+		// decode the compressed music data
+		switch (dec_prefix) {
+		
+		// decode prefix
+		case 155:
+		case 175:
+			octet = blk.mb_data [block_pos++];
+			if (octet == 0) {
+				// invalid prefix, output original
+				octet = dec_prefix;
+				dec_prefix = 0;
+				break;
+			}
+			
+			// isolate length and distance
+			dec_len = (octet & 0x0F);
+			len_corr = 2;
+
+			dec_dist = (octet & 0xF0) >> 4;
+			if (dec_prefix == 155)
+				dec_dist++;
+				
+			// next decode step for respective prefix type
+			dec_prefix++;
+			continue;
+			
+
+		// check for extended length
+		case 156:
+			if (dec_len == 15)
+				dec_len += blk.mb_data [block_pos++];
+
+			// add length correction and go for copy mode
+			dec_len += len_corr;
+			dec_prefix = 255;
+			continue;
+			
+			
+		// get extended distance
+		case 176:
+			dec_dist += 17 + 16 * blk.mb_data [block_pos++];
+			len_corr = 3;
+			
+			// check for extended length
+			dec_prefix = 156;
+			continue;
+			
+			
+		// prefix copy mode
+		case 255:
+			octet = raw_data [raw_pos - dec_dist];
+			
+			dec_len--;
+			if (dec_len == 0) {
+				// back to normal mode
+				dec_prefix = 0;
+			}
+			
+			break;
+
+			
+		// normal mode
+		default:
+			octet = blk.mb_data [block_pos++];
+			if (octet == 155 || octet == 175) {
+				// it's a prefix, restart
+				dec_prefix = octet;
+				continue;
+			}
+		} // prefix switch
+
+			
+		// output the octet
+		if (output != NULL)
+			*output = octet;
+			
+		raw_data [raw_pos++] = octet;
+		break;
+	}; // decode pass
+
+	return true;
+}	
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/msc.h	Sat Jan 14 07:27:13 2006 -0800
@@ -0,0 +1,90 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * msc.h - MSC Player by Lubomir Bulej (pallas@kadan.cz)
+ */
+
+#include "player.h"
+
+#define MSC_SIGN_LEN	16
+#define MSC_DESC_LEN	64
+
+class CmscPlayer: public CPlayer
+{
+public:
+	static CPlayer * factory (Copl * newopl);
+
+	CmscPlayer (Copl * newopl);
+	~CmscPlayer ();
+	
+	bool load (const std::string &filename, const CFileProvider &fp);
+	bool update ();
+	void rewind (int subsong);
+	float getrefresh ();
+
+	std::string gettype ();
+
+
+protected:
+	typedef unsigned char	u8;
+	typedef	unsigned short	u16;
+
+	struct msc_header {
+		u8 	mh_sign [MSC_SIGN_LEN];
+		u16	mh_ver;
+		u8	mh_desc [MSC_DESC_LEN];
+		u16	mh_timer;
+		u16	mh_nr_blocks;
+		u16	mh_block_len;
+	};
+
+	struct msc_block {
+		u16	mb_length;
+		u8 *	mb_data;
+	};
+	
+	
+	// file data
+	char *		desc;		// song desctiption
+	unsigned short	version;	// file version
+	unsigned short	nr_blocks;	// number of music blocks
+	unsigned short	block_len;	// maximal block length
+	unsigned short	timer_div;	// timer divisor
+	msc_block *	msc_data;	// compressed music data
+	
+	// decoder state
+	unsigned long	block_num;	// active block
+	unsigned long	block_pos;	// position in block
+	unsigned long	raw_pos;	// position in data buffer
+	u8 *		raw_data;	// decompression buffer
+
+	u8 		dec_prefix;	// prefix / state
+	int		dec_dist;	// prefix distance
+	unsigned int	dec_len;	// prefix length
+	
+	// player state
+	unsigned char 	delay;		// active delay
+	unsigned long	play_pos;	// player position
+	
+
+private:
+	static const u8 msc_signature [MSC_SIGN_LEN];
+
+	bool load_header (binistream * bf, msc_header * hdr);
+	bool decode_octet (u8 * output);
+};
--- a/Plugins/Input/adplug/core/opl.h	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/opl.h	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -16,7 +16,7 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * opl.h - OPL base class declaration, by Simon Peter <dn.tlp@gmx.net>
+ * opl.h - OPL base class, by Simon Peter <dn.tlp@gmx.net>
  */
 
 #ifndef H_ADPLUG_OPL
@@ -24,11 +24,37 @@
 
 class Copl
 {
-public:
-	virtual void write(int reg, int val) = 0;		// combined register select + data write
-	virtual void init(void) = 0;				// reinitialize OPL chip
+ public:
+  typedef enum {
+    TYPE_OPL2, TYPE_OPL3, TYPE_DUAL_OPL2
+  } ChipType;
+
+  Copl()
+    : currChip(0), currType(TYPE_OPL2)
+    {
+    }
 
-	virtual void update(short *buf, int samples) {};	// Emulation only: fill buffer
+  virtual void write(int reg, int val) = 0;	// combined register select + data write
+  virtual void setchip(int n)			// select OPL chip
+    {
+      if(n < 2)
+	currChip = n;
+    }
+
+  virtual void init(void) = 0;			// reinitialize OPL chip(s)
+
+  // return this OPL chip's type
+  ChipType gettype()
+    {
+      return currType;
+    }
+
+  // Emulation only: fill buffer
+  virtual void update(short *buf, int samples) {}
+
+ protected:
+  int		currChip;		// currently selected OPL chip number
+  ChipType	currType;		// this OPL chip's type
 };
 
 #endif
--- a/Plugins/Input/adplug/core/psi.cpp	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/psi.cpp	Sat Jan 14 07:27:13 2006 -0800
@@ -69,13 +69,20 @@
   opl_write(0x08, 0x00);
   opl_write(0xBD, 0x00);
 
+  // get header
+  header.instr_ptr = (tune[1] << 8) + tune[0];
+  header.seq_ptr = (tune[3] << 8) + tune[2];
+
   // define instruments
-  psi.instr_table = (unsigned short *)&tune[((psi_header *)&tune[0])->instr_ptr];
+  psi.instr_table = &tune[header.instr_ptr];
 
   for(int i=0; i<8; i++)
   {
-    for(int j=0; j<11; j++)
-      opl_write(psi_adlib_registers[i*11 + j],tune[psi.instr_table[i] + j]);
+    for(int j=0; j<11; j++) {
+      unsigned short inspos = (psi.instr_table[i * 2 + 1] << 8) + psi.instr_table[i * 2];
+
+      opl_write(psi_adlib_registers[i*11 + j],tune[inspos + j]);
+    }
 
     opl_write(0xA0+i, 0x00);
     opl_write(0xB0+i, 0x00);
@@ -86,7 +93,7 @@
   }
 
   // calculate sequence pointer
-  psi.seq_table = (unsigned short *)&tune[((psi_header *)&tune[0])->seq_ptr];
+  psi.seq_table = &tune[header.seq_ptr];
 }
 
 void CxadpsiPlayer::xadplayer_update()
@@ -95,7 +102,7 @@
 
   for(int i=0; i<8; i++)
   {
-    ptr = psi.seq_table[i<<1];
+    ptr = (psi.seq_table[(i<<1) * 2 + 1] << 8) + psi.seq_table[(i<<1) * 2];
 
     psi.note_curdelay[i]--;
 
@@ -112,7 +119,7 @@
       // end of sequence ?
       if (!event)
       {
-        ptr = psi.seq_table[(i<<1) + 1];
+	ptr = (psi.seq_table[(i<<1) * 2 + 3] << 8) + psi.seq_table[(i<<1) * 2 + 2];
 
         event = tune[ptr++];
 #ifdef DEBUG
@@ -148,7 +155,8 @@
       opl_write(0xB0+i, (note >> 8) + ((event >> 2) & 0xFC));
 
       // save position
-      psi.seq_table[i<<1] = ptr;
+      psi.seq_table[(i<<1) * 2] = ptr & 0xff;
+      psi.seq_table[(i<<1) * 2 + 1] = ptr >> 8;
     }
   }
 }
--- a/Plugins/Input/adplug/core/psi.h	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/psi.h	Sat Jan 14 07:27:13 2006 -0800
@@ -34,12 +34,12 @@
   {
     unsigned short  instr_ptr;
     unsigned short  seq_ptr;
-  };
+  } header;
 
   struct
   {
-    unsigned short  *instr_table;
-    unsigned short  *seq_table;
+    unsigned char   *instr_table;
+    unsigned char   *seq_table;
     unsigned char   note_delay[9];
     unsigned char   note_curdelay[9];
     unsigned char   looping[9];
--- a/Plugins/Input/adplug/core/rat.cpp	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/rat.cpp	Sat Jan 14 07:27:13 2006 -0800
@@ -72,7 +72,8 @@
   rat.inst = (rat_instrument *)&tune[0x140];
 
   // load pattern data
-  unsigned char *event_ptr = &tune[rat.hdr.patseg << 4];
+  unsigned short patseg = (rat.hdr.patseg[1] << 8) + rat.hdr.patseg[0];
+  unsigned char *event_ptr = &tune[patseg << 4];
 
   for(int i=0;i<rat.hdr.numpat;i++)
     for(int j=0;j<64;j++)
@@ -181,7 +182,8 @@
         opl_write(0xE0+rat_adlib_bases[i+9], rat.inst[ins].car_wave);
 
         // octave/frequency
-        unsigned short freq = rat.inst[ins].freq * rat_notes[event.note & 0x0F] / 0x20AB;
+	unsigned short insfreq = (rat.inst[ins].freq[1] << 8) + rat.inst[ins].freq[0];
+        unsigned short freq = insfreq * rat_notes[event.note & 0x0F] / 0x20AB;
 
         opl_write(0xA0+i, freq & 0xFF);
         opl_write(0xB0+i, (freq >> 8) | ((event.note & 0xF0) >> 2) | 0x20);
--- a/Plugins/Input/adplug/core/rat.h	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/rat.h	Sat Jan 14 07:27:13 2006 -0800
@@ -50,7 +50,7 @@
     unsigned char   volume;
     unsigned char   speed;
     unsigned char   reserved_32[12];
-    unsigned short  patseg;
+    unsigned char   patseg[2];
   };
 
   struct rat_event
@@ -64,7 +64,7 @@
 
   struct rat_instrument
   {
-    unsigned short  freq;
+    unsigned char   freq[2];
     unsigned char   reserved_2[2];
     unsigned char   mod_ctrl;
     unsigned char   car_ctrl;
--- a/Plugins/Input/adplug/core/raw.cpp	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/raw.cpp	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -17,9 +17,6 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  * raw.c - RAW Player by Simon Peter <dn.tlp@gmx.net>
- *
- * NOTES:
- * OPL3 register writes are ignored (not possible with AdLib).
  */
 
 #include "raw.h"
@@ -76,7 +73,7 @@
 	speed = data[pos].param + (data[pos].command << 8);
 	setspeed = true;
       } else
-	opl3 = data[pos].param - 1;
+	opl->setchip(data[pos].param - 1);
       break;
     case 0xff:
       if(data[pos].param == 0xff) {
@@ -86,8 +83,7 @@
       }
       break;
     default:
-      if(!opl3)
-	opl->write(data[pos].command,data[pos].param);
+      opl->write(data[pos].command,data[pos].param);
       break;
     }
   } while(data[pos++].command || setspeed);
@@ -97,8 +93,8 @@
 
 void CrawPlayer::rewind(int subsong)
 {
-  pos = del = opl3 = 0; speed = clock; songend = false;
-  opl->init(); opl->write(1,32);	// go to OPL2 mode
+  pos = del = 0; speed = clock; songend = false;
+  opl->init(); opl->write(1, 32);	// go to 9 channel mode
 }
 
 float CrawPlayer::getrefresh()
--- a/Plugins/Input/adplug/core/raw.h	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/raw.h	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -42,11 +42,11 @@
 
 protected:
 	struct Tdata {
-		unsigned char param,command;
+		unsigned char param, command;
 	} *data;
 
-	unsigned long pos,length;
-	unsigned short clock,speed;
-	unsigned char del,opl3;
+	unsigned long pos, length;
+	unsigned short clock, speed;
+	unsigned char del;
 	bool songend;
 };
--- a/Plugins/Input/adplug/core/realopl.cpp	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/realopl.cpp	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999, 2000, 2001 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -16,143 +16,189 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- *
- * realopl.cpp - Real hardware OPL, by Simon Peter (dn.tlp@gmx.net)
+ * realopl.cpp - Real hardware OPL, by Simon Peter <dn.tlp@gmx.net>
  */
 
-#include <conio.h>
-#include "realopl.h"
-
-#ifdef _MSC_VER
-	#define INP		_inp
-	#define OUTP	_outp
-#elif defined(__WATCOMC__)
-	#define INP		inp
-	#define OUTP	outp
+#ifdef _MSC_VER			// Microsoft Visual C++
+#	include <conio.h>
+#	define INP	_inp
+#	define OUTP	_outp
+#elif defined(__WATCOMC__)	// Watcom C/C++ and OpenWatcom
+#	include <conio.h>
+#	define INP	inp
+#	define OUTP	outp
+#elif defined(WIN32) && defined(__MSVCRT__) && defined(__MINGW32__)
+/*
+int __cdecl _inp(unsigned short);
+int __cdecl _outp(unsigned short, int);
+#	define INP	_inp
+#	define OUTP	_outp
+*/
+#	define INP		inb
+#	define OUTP(reg, val)	outb(val, reg)
+#else				// no support on other platforms
+#	define INP(reg)		0
+#	define OUTP(reg, val)
 #endif
 
-/* 
- * chris: TODO: This isn't quite right.  According to Jeff Lee's doc:
- *
- *    "After writing to the register port, you must wait twelve cycles before
- *   sending the data; after writing the data, eighty-four cycles must elapse
- *   before any other sound card operation may be performed.
- *
- * | The AdLib manual gives the wait times in microseconds: three point three
- * | (3.3) microseconds for the address, and twenty-three (23) microseconds
- * | for the data.
- * |
- * | The most accurate method of producing the delay is to read the register
- * | port six times after writing to the register port, and read the register
- * | port thirty-five times after writing to the data port."
- *
- *
- * In other words, the delay constants represented by {SHORT|LONG}DELAY below 
- * aren't given in microseconds, but rather direct reads (INB) from the Adlib 
- * I/O ports.
- *
- * Translation: SHORTDELAY should be 6, and LONGDELAY is just fine.  :-)
- */
+#include "realopl.h"
+
+#define SHORTDELAY		6	// short delay in I/O port-reads after OPL hardware output
+#define LONGDELAY		35	// long delay in I/O port-reads after OPL hardware output
+
+const unsigned char CRealopl::op_table[9] =
+  {0x00, 0x01, 0x02, 0x08, 0x09, 0x0a, 0x10, 0x11, 0x12};
+
+#if defined(WIN32) && defined(__MINGW32__)
+static __inline unsigned char
+inb (unsigned short int port)
+{
+  unsigned char _v;
+
+  __asm__ __volatile__ ("inb %w1,%0":"=a" (_v):"Nd" (port));
+  return _v;
+}
+
+static __inline void
+outb (unsigned char value, unsigned short int port)
+{
+  __asm__ __volatile__ ("outb %b0,%w1": :"a" (value), "Nd" (port));
+}
+#endif
 
-#define SHORTDELAY		6					// short delay in I/O port-reads after OPL hardware output
-#define LONGDELAY		35					// long delay in I/O port-reads after OPL hardware output
+CRealopl::CRealopl(unsigned short initport)
+  : adlport(initport), hardvol(0), bequiet(false), nowrite(false)
+{
+  for(int i=0;i<22;i++) {
+    hardvols[0][i][0] = 0;
+    hardvols[0][i][1] = 0;
+    hardvols[1][i][0] = 0;
+    hardvols[1][i][1] = 0;
+  }
 
-// the 9 operators as expected by the OPL2
-static const unsigned char op_table[9] = {0x00, 0x01, 0x02, 0x08, 0x09, 0x0a, 0x10, 0x11, 0x12};
+  currType = TYPE_OPL3;
+}
 
-CRealopl::CRealopl(unsigned short initport): adlport(initport), hardvol(0), bequiet(false), nowrite(false)
+bool CRealopl::harddetect()
 {
-	for(int i=0;i<22;i++) {
-		hardvols[i][0] = 0;
-		hardvols[i][1] = 0;
-	}
+  unsigned char		stat1, stat2, i;
+  unsigned short	adp = (currChip == 0 ? adlport : adlport + 2);
+
+  hardwrite(4,0x60); hardwrite(4,0x80);
+  stat1 = INP(adp);
+  hardwrite(2,0xff); hardwrite(4,0x21);
+  for(i=0;i<80;i++)			// wait for adlib
+    INP(adp);
+  stat2 = INP(adp);
+  hardwrite(4,0x60); hardwrite(4,0x80);
+
+  if(((stat1 & 0xe0) == 0) && ((stat2 & 0xe0) == 0xc0))
+    return true;
+  else
+    return false;
 }
 
 bool CRealopl::detect()
 {
-	unsigned char stat1,stat2,i;
+  unsigned char	stat;
+
+  setchip(0);
+  if(harddetect()) {
+    // is at least OPL2, check for OPL3
+    currType = TYPE_OPL2;
 
-	hardwrite(4,0x60); hardwrite(4,0x80);
-	stat1 = INP(adlport);
-	hardwrite(2,0xff); hardwrite(4,0x21);
-	for(i=0;i<80;i++)			// wait for adlib
-		INP(adlport);
-	stat2 = INP(adlport);
-	hardwrite(4,0x60); hardwrite(4,0x80);
+    stat = INP(adlport);
+    if(stat & 6) {
+      // not OPL3, try dual-OPL2
+      setchip(1);
+      if(harddetect())
+	currType = TYPE_DUAL_OPL2;
+    } else
+      currType = TYPE_OPL3;
 
-	if(((stat1 & 0xe0) == 0) && ((stat2 & 0xe0) == 0xc0))
-		return true;
-	else
-		return false;
+    setchip(0);
+    return true;
+  } else
+    return false;
 }
 
 void CRealopl::setvolume(int volume)
 {
-	int i;
+  int i, j;
 
-	hardvol = volume;
-	for(i=0;i<9;i++) {
-		hardwrite(0x43+op_table[i],((hardvols[op_table[i]+3][0] & 63) + volume) > 63 ? 63 : hardvols[op_table[i]+3][0] + volume);
-		if(hardvols[i][1] & 1)	// modulator too?
-			hardwrite(0x40+op_table[i],((hardvols[op_table[i]][0] & 63) + volume) > 63 ? 63 : hardvols[op_table[i]][0] + volume);
-	}
+  hardvol = volume;
+  for(j = 0; j < 2; j++)
+    for(i = 0; i < 9; i++) {
+      hardwrite(0x43+op_table[i],((hardvols[j][op_table[i]+3][0] & 63) + volume) > 63 ? 63 : hardvols[j][op_table[i]+3][0] + volume);
+      if(hardvols[j][i][1] & 1)	// modulator too?
+	hardwrite(0x40+op_table[i],((hardvols[j][op_table[i]][0] & 63) + volume) > 63 ? 63 : hardvols[j][op_table[i]][0] + volume);
+    }
 }
 
 void CRealopl::setquiet(bool quiet)
 {
-	bequiet = quiet;
+  bequiet = quiet;
 
-	if(quiet) {
-		oldvol = hardvol;
-		setvolume(63);
-	} else
-		setvolume(oldvol);
+  if(quiet) {
+    oldvol = hardvol;
+    setvolume(63);
+  } else
+    setvolume(oldvol);
 }
 
 void CRealopl::hardwrite(int reg, int val)
 {
-	int i;
+  int 			i;
+  unsigned short	adp = (currChip == 0 ? adlport : adlport + 2);
 
-	OUTP(adlport,reg);							// set register
-	for(i=0;i<SHORTDELAY;i++)					// wait for adlib
-		INP(adlport);
-	OUTP(adlport+1,val);						// set value
-	for(i=0;i<LONGDELAY;i++)					// wait for adlib
-		INP(adlport);
+  OUTP(adp,reg);		// set register
+  for(i=0;i<SHORTDELAY;i++)	// wait for adlib
+    INP(adp);
+  OUTP(adp+1,val);		// set value
+  for(i=0;i<LONGDELAY;i++)	// wait for adlib
+    INP(adp);
 }
 
 void CRealopl::write(int reg, int val)
 {
-	int i;
+  int i;
 
-	if(nowrite)
-		return;
+  if(nowrite)
+    return;
+
+  if(currType == TYPE_OPL2 && currChip > 0)
+    return;
 
-	if(bequiet && (reg >= 0xb0 && reg <= 0xb8))	// filter all key-on commands
-		val &= ~32;
-	if(reg >= 0x40 && reg <= 0x55)				// cache volumes
-		hardvols[reg-0x40][0] = val;
-	if(reg >= 0xc0 && reg <= 0xc8)
-		hardvols[reg-0xc0][1] = val;
-	if(hardvol)									// reduce volume
-		for(i=0;i<9;i++) {
-			if(reg == 0x43 + op_table[i])
-				val = ((val & 63) + hardvol) > 63 ? 63 : val + hardvol;
-			else
-				if((reg == 0x40 + op_table[i]) && (hardvols[i][1] & 1))
-					val = ((val & 63) + hardvol) > 63 ? 63 : val + hardvol;
-		}
+  if(bequiet && (reg >= 0xb0 && reg <= 0xb8))	// filter all key-on commands
+    val &= ~32;
+  if(reg >= 0x40 && reg <= 0x55)		// cache volumes
+    hardvols[currChip][reg-0x40][0] = val;
+  if(reg >= 0xc0 && reg <= 0xc8)
+    hardvols[currChip][reg-0xc0][1] = val;
+  if(hardvol)					// reduce volume
+    for(i=0;i<9;i++) {
+      if(reg == 0x43 + op_table[i])
+	val = ((val & 63) + hardvol) > 63 ? 63 : val + hardvol;
+      else
+	if((reg == 0x40 + op_table[i]) && (hardvols[currChip][i][1] & 1))
+	  val = ((val & 63) + hardvol) > 63 ? 63 : val + hardvol;
+    }
 
-	hardwrite(reg,val);
+  hardwrite(reg,val);
 }
 
 void CRealopl::init()
 {
-	int i;
+  int i, j;
+
+  for(j = 0; j < 2; j++) {
+    setchip(j);
 
-	for (i=0;i<9;i++) {				// stop instruments
-		hardwrite(0xb0 + i,0);				// key off
-		hardwrite(0x80 + op_table[i],0xff);	// fastest release
-	}
-	hardwrite(0xbd,0);	// clear misc. register
+    for(i=0;i<9;i++) {				// stop instruments
+      hardwrite(0xb0 + i,0);			// key off
+      hardwrite(0x80 + op_table[i],0xff);	// fastest release
+    }
+
+    hardwrite(0xbd,0);	// clear misc. register
+  }
 }
--- a/Plugins/Input/adplug/core/realopl.h	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/realopl.h	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * AdPlug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2002 Simon Peter <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -19,36 +19,54 @@
  * realopl.h - Real hardware OPL, by Simon Peter <dn.tlp@gmx.net>
  */
 
+#ifndef H_ADPLUG_REALOPL
+#define H_ADPLUG_REALOPL
+
 #include "opl.h"
 
 #define DFL_ADLIBPORT	0x388		// default adlib baseport
 
 class CRealopl: public Copl
 {
-public:	
-	CRealopl(unsigned short initport = DFL_ADLIBPORT);	// initport = OPL2 hardware baseport
+ public:	
+  CRealopl(unsigned short initport = DFL_ADLIBPORT);	// initport = OPL2 hardware baseport
 
-	bool detect();					// returns true if adlib compatible board is found, else false
-	void setvolume(int volume);			// set adlib master volume (0 - 63) 0 = loudest, 63 = softest
-	void setquiet(bool quiet = true);	// sets the OPL2 quiet, while still writing to the registers
-	void setport(unsigned short port)	// set new OPL2 hardware baseport
-	{ adlport = port; };
-	void setnowrite(bool nw = true)		// set hardware write status
-	{ nowrite = nw; };
+  bool detect();			// returns true if adlib compatible board is found, else false
+  void setvolume(int volume);		// set adlib master volume (0 - 63) 0 = loudest, 63 = softest
+  void setquiet(bool quiet = true);	// sets the OPL2 quiet, while still writing to the registers
+  void setport(unsigned short port)	// set new OPL2 hardware baseport
+    {
+      adlport = port;
+    }
+  void setnowrite(bool nw = true)	// set hardware write status
+    {
+      nowrite = nw;
+    }
 
-	int getvolume()						// get adlib master volume
-	{ return hardvol; };
+  int getvolume()			// get adlib master volume
+    {
+      return hardvol;
+    }
 
-	// template methods
-	void write(int reg, int val);
-	void init();
-
-private:
-	void hardwrite(int reg, int val);	// write to OPL2 hardware registers
+  // template methods
+  void write(int reg, int val);
+  void init();
+  void settype(ChipType type)
+    {
+      currType = type;
+    }
 
-	unsigned short	adlport;			// adlib hardware baseport
-	int				hardvol,oldvol;		// hardware master volume
-	bool			bequiet;			// quiet status cache
-	char			hardvols[22][2];	// volume cache
-	bool			nowrite;			// don't write to hardware, if true
+ protected:
+  void hardwrite(int reg, int val);		// write to OPL2 hardware registers
+  bool harddetect();				// do real hardware detection
+
+  static const unsigned char op_table[9];	// the 9 operators as expected by the OPL2
+
+  unsigned short	adlport;		// adlib hardware baseport
+  int			hardvol, oldvol;	// hardware master volume
+  bool			bequiet;		// quiet status cache
+  char			hardvols[2][22][2];	// volume cache
+  bool			nowrite;		// don't write to hardware, if true
 };
+
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/rix.cpp	Sat Jan 14 07:27:13 2006 -0800
@@ -0,0 +1,509 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * rix.c - Dayu OPL Format Player by palxex <palxex@163.com/palxex.ys168.com>
+ */
+
+#include "rix.h"
+#include <binfile.h>
+
+const unsigned char CrixPlayer::adflag[] = {0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,1,1,1};
+const unsigned char CrixPlayer::reg_data[] = {0,1,2,3,4,5,8,9,10,11,12,13,16,17,18,19,20,21};
+const unsigned char CrixPlayer::ad_C0_offs[] = {0,1,2,0,1,2,3,4,5,3,4,5,6,7,8,6,7,8};
+const unsigned char CrixPlayer::modify[] = {0,3,1,4,2,5,6,9,7,10,8,11,12,15,13,16,14,17,12,\
+								 15,16,0,14,0,17,0,13,0};
+const unsigned char CrixPlayer::bd_reg_data[] = {\
+						0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x08,0x04,0x02,0x01,\
+						0x00,0x01,0x01,0x03,0x0F,0x05,0x00,0x01,0x03,0x0F,0x00,\
+						0x00,0x00,0x01,0x00,0x00,0x01,0x01,0x0F,0x07,0x00,0x02,\
+						0x04,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x0A,\
+						0x04,0x00,0x08,0x0C,0x0B,0x00,0x00,0x00,0x01,0x00,0x00,\
+						0x00,0x00,0x0D,0x04,0x00,0x06,0x0F,0x00,0x00,0x00,0x00,\
+						0x01,0x00,0x00,0x0C,0x00,0x0F,0x0B,0x00,0x08,0x05,0x00,\
+						0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x0F,0x0B,0x00,\
+						0x07,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,\
+						0x0F,0x0B,0x00,0x05,0x05,0x00,0x00,0x00,0x00,0x00,0x00,\
+						0x00,0x01,0x00,0x0F,0x0B,0x00,0x07,0x05,0x00,0x00,0x00,\
+						0x00,0x00,0x00};
+unsigned char CrixPlayer::for40reg[] = {0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,\
+								0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F};
+unsigned short CrixPlayer::mus_time = 0x4268;
+/*** public methods *************************************/
+CPlayer *CrixPlayer::factory(Copl *newopl)
+{
+  return new CrixPlayer(newopl);
+}
+
+bool CrixPlayer::load(const std::string &filename, const CFileProvider &fp)
+{
+	binistream *f = fp.open(filename); if(!f) return false;
+	unsigned long i=0;
+
+	if(f->readInt(2)!=0x55aa)	{fp.close(f);return false;	}
+	buf_addr[i++]=0xaa;buf_addr[i++]=0x55;
+	while(!f->eof())
+		buf_addr[i++]=f->readInt(1);
+	length=i;
+	fp.close(f);
+	set_new_int();
+	data_initial();
+	while(!dro_end)
+		int_08h_entry();
+
+	length=T;
+	mode = (OplMode)1;		// Type of opl data this can contain
+	
+//	binofstream *g=new binofstream(filename+string(".dro"));
+//	g->writeString("DBRAWOPL",8);
+//	g->writeInt(mstotal,4);
+//	g->writeInt(length+1,4);
+//	g->writeInt(1,1);
+//	for(int t=0;t<length;t++)
+//		g->writeInt(dro[t],1);
+//	g->close();
+//	delete g;
+
+	rewind(0);
+	return true;
+}
+
+bool CrixPlayer::update()
+{
+	if (delay>500) {
+		delay-=500;
+		return true;
+	} else delay=1;
+	while (pos < length) 
+	{	
+		unsigned char cmd = dro[pos++];
+		switch(cmd) {
+		case 0: 
+			delay = 1 + dro[pos++];
+			return true;
+		case 1: 
+			delay = 1 + dro[pos] + (dro[pos+1]<<8);
+			pos+=2;
+			return true;
+		case 2:
+			index = 0;
+			opl->setchip(0);
+			break;
+		case 3:
+			index = 1;
+			opl->setchip(1);
+			break;
+		default:
+		  if(index == 0 || opl3_mode)
+		    opl->write(cmd,dro[pos++]);
+		  break;
+		}
+	}
+	return pos<length;
+}
+
+void CrixPlayer::rewind(int subsong)
+{
+	delay=1;
+	pos = index = 0; 
+	opl->init(); 
+	opl->write(1,32);	// go to OPL2 mode
+}
+
+float CrixPlayer::getrefresh()
+{
+	if (delay > 500) return 1000 / 500;
+	else return 1000 / (double)delay;
+}
+
+/*------------------Implemention----------------------------*/
+inline void CrixPlayer::set_new_int()
+{
+	if(!ad_initial()) exit(1);
+	prep_int();
+}
+/*----------------------------------------------------------*/
+inline void CrixPlayer::Pause()
+{
+	register unsigned short i;
+	pause_flag = 1;
+	for(i=0;i<11;i++)
+	switch_ad_bd(i);
+}
+/*----------------------------------------------------------*/
+inline void CrixPlayer::ad_a0b0l_reg_(unsigned short index,unsigned short p2,unsigned short p3)
+{
+	unsigned short i = p2+a0b0_data2[index];
+	a0b0_data4[index] = p3;
+	a0b0_data3[index] = p2;
+}
+inline void CrixPlayer::data_initial()
+{
+	rhythm = buf_addr[2];
+	mus_block = (buf_addr[0x0D]<<8)+buf_addr[0x0C];
+	ins_block = (buf_addr[0x09]<<8)+buf_addr[0x08];
+	I = mus_block+1;
+	if(rhythm != 0)
+	{
+//		ad_a0b0_reg(6);
+//		ad_a0b0_reg(7);
+//		ad_a0b0_reg(8);
+		ad_a0b0l_reg_(8,0x18,0);
+		ad_a0b0l_reg_(7,0x1F,0);
+	}
+	bd_modify = 0;
+//	ad_bd_reg();
+	band = 0; music_on = 1;
+}
+/*----------------------------------------------------------*/
+inline unsigned short CrixPlayer::ad_initial()
+{
+  register unsigned short i,j,k = 0;
+  for(i=0;i<25;i++) crc_trans(i,i*4);
+  for(i=0;i<8;i++)
+  for(j=0;j<12;j++)
+  {
+	 a0b0_data5[k] = i;
+	 addrs_head[k] = j;
+	 k++;
+  }
+  //ad_bd_reg();
+  //ad_08_reg();
+  //for(i=0;i<9;i++) ad_a0b0_reg(i);
+  e0_reg_flag = 0x20;
+  //for(i=0;i<18;i++) ad_bop(0xE0+reg_data[i],0);
+  //ad_bop(1,e0_reg_flag);
+  return 1;//ad_test();
+}
+/*----------------------------------------------------------*/
+inline void CrixPlayer::crc_trans(unsigned short index,unsigned short v)
+{
+	register unsigned short i;
+	unsigned int res; unsigned short low;
+	res = strm_and_fr(v);
+	low = res;
+	buffer[index*12] = (low+4)>>3;
+	for(i=1;i<=11;i++)
+	{
+		res *= 1.06;
+		buffer[index*12+i] = res>>3;
+	}
+}
+
+/*----------------------------------------------------------*/
+inline void CrixPlayer::prep_int()
+{
+	mutex = 0;
+}
+/*----------------------------------------------------------*/
+inline void CrixPlayer::ad_bop(unsigned short reg,unsigned short value)
+{
+	dro[T++]=reg;dro[T++]=value;
+}
+/*------------------------------------------------------*/
+inline unsigned short CrixPlayer::ad_test()   /* Test the SoundCard */
+{
+	ad_bop(0x04,0x60);
+	ad_bop(0x04,0x80);
+	ad_bop(0x02,0xFF);
+	ad_bop(0x04,0x21);
+	ad_bop(0x04,0x60);
+	ad_bop(0x04,0x80);
+	return 1;
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::int_08h_entry()
+{
+        unsigned short band_sus = 1;
+        while(band_sus)
+        {
+                if(sustain <= 0 && mutex == 0)
+                {
+                        mutex++;
+                        band_sus = rix_proc();
+                        if(band_sus) sustain += band_sus * 1.06;
+							mstotal+=sustain;
+							dro[T++]=(sustain>=0x100?1:0);
+							dro[T++]=sustain&0xff;
+							if(sustain>=0x100)
+								dro[T++]=(sustain>>8)&0xff;
+                        mutex--;
+                        if(band_sus == 0)
+						{
+							dro_end=1;
+							break;
+						}
+				}
+				else
+				{
+						if(band_sus) sustain -= 14; /* aging */
+						break;
+				}
+        }
+}
+/*--------------------------------------------------------------*/
+inline unsigned short CrixPlayer::rix_proc()
+{
+	unsigned char ctrl = 0;
+	if(music_on == 0||pause_flag == 1) return 0;
+	band = 0;
+	while(buf_addr[I] != 0x80 && I<length-1)
+	{
+		band_low = buf_addr[I-1];
+		ctrl = buf_addr[I]; I+=2;
+		switch(ctrl&0xF0)
+		{
+			case 0x90:  rix_get_ins(); rix_90_pro(ctrl&0x0F); break;
+			case 0xA0:  rix_A0_pro(ctrl&0x0F,((unsigned short)band_low)<<6); break;
+			case 0xB0:  rix_B0_pro(ctrl&0x0F,band_low); break;
+			case 0xC0:  switch_ad_bd(ctrl&0x0F);
+							if(band_low != 0) rix_C0_pro(ctrl&0x0F,band_low);
+							break;
+			default:    band = (ctrl<<8)+band_low; break;
+		}
+		if(band != 0) return band;
+	}
+	music_ctrl();
+	I = mus_block+1;
+	band = 0; music_on = 1;
+	return 0;
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::rix_get_ins()
+{
+	memcpy(insbuf,(&buf_addr[ins_block])+(band_low<<6),56);
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::rix_90_pro(unsigned short ctrl_l)
+{
+	if(rhythm == 0 || ctrl_l < 6)
+	{
+		ins_to_reg(modify[ctrl_l*2],insbuf,insbuf[26]);
+		ins_to_reg(modify[ctrl_l*2+1],insbuf+13,insbuf[27]);
+		return;
+	}
+	else
+	{
+		if(ctrl_l > 6)
+		{
+			ins_to_reg(modify[ctrl_l*2+6],insbuf,insbuf[26]);
+			return;
+		}
+		else
+		{
+			ins_to_reg(12,insbuf,insbuf[26]);
+			ins_to_reg(15,insbuf+13,insbuf[27]);
+			return;
+		}
+	}
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::rix_A0_pro(unsigned short ctrl_l,unsigned short index)
+{
+	if(rhythm == 0 || ctrl_l <= 6)
+	{
+		prepare_a0b0(ctrl_l,index>0x3FFF?0x3FFF:index);
+		ad_a0b0l_reg(ctrl_l,a0b0_data3[ctrl_l],a0b0_data4[ctrl_l]);
+	}
+	else return;
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::prepare_a0b0(unsigned short index,unsigned short v)  /* important !*/
+{
+	short high = 0,low = 0; unsigned int res;
+	low = ((unsigned short)(v-0x2000))*0x19;
+	high = ((short)v)<0x2000?0xFFFF:0;
+	if(low == 0xFF && high == 0) return;
+	res = ((((unsigned int)high)<<16)|low)/0x2000;
+	low = res&0xFFFF;
+	if(low < 0)
+	{
+		low = 0x18-low; high = (signed short)low<0?0xFFFF:0;
+		res = high; res<<=16; res+=low;
+		low = ((signed short)res)/(signed short)0xFFE7;
+		a0b0_data2[index] = low;
+		low = res;
+		res = low - 0x18;
+		high = (signed short)res%0x19;
+		low = (signed short)res/0x19;
+		if(high != 0) {low = 0x19; low = low-high;}
+	}
+	else
+	{
+		res = high = low;
+		low = (signed short)res/(signed short)0x19;
+		a0b0_data2[index] = low;
+		res = high;
+		low = (signed short)res%(signed short)0x19;
+	}
+	low = (signed short)low*(signed short)0x18;
+	displace[index] = low;
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::ad_a0b0l_reg(unsigned short index,unsigned short p2,unsigned short p3)
+{
+	unsigned short data; unsigned short i = p2+a0b0_data2[index];
+	a0b0_data4[index] = p3;
+	a0b0_data3[index] = p2;
+	i = ((signed short)i<=0x5F?i:0x5F);
+	i = ((signed short)i>=0?i:0);
+	data = buffer[addrs_head[i]+displace[index]/2];
+	ad_bop(0xA0+index,data);
+	data = a0b0_data5[i]*4+(p3<1?0:0x20)+((data>>8)&3);
+	ad_bop(0xB0+index,data);
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::rix_B0_pro(unsigned short ctrl_l,unsigned short index)
+{
+	register int temp = 0;
+	if(rhythm == 0 || ctrl_l < 6) temp = modify[ctrl_l*2+1];
+	else
+	{
+		temp = ctrl_l > 6?ctrl_l*2:ctrl_l*2+1;
+		temp = modify[temp+6];
+	}
+	for40reg[temp] = index>0x7F?0x7F:index;
+	ad_40_reg(temp);
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::rix_C0_pro(unsigned short ctrl_l,unsigned short index)
+{
+	register unsigned short i = index>=12?index-12:0;
+	if(ctrl_l < 6 || rhythm == 0)
+	{
+		ad_a0b0l_reg(ctrl_l,i,1);
+		return;
+	}
+	else
+	{
+		if(ctrl_l != 6)
+		{
+			if(ctrl_l == 8)
+			{
+				ad_a0b0l_reg(ctrl_l,i,0);
+				ad_a0b0l_reg(7,i+7,0);
+			}
+		}
+		else ad_a0b0l_reg(ctrl_l,i,0);
+		bd_modify |= bd_reg_data[ctrl_l];
+		ad_bd_reg();
+		return;
+	}
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::switch_ad_bd(unsigned short index)
+{
+
+	if(rhythm == 0 || index < 6) ad_a0b0l_reg(index,a0b0_data3[index],0);
+	else
+	{
+		bd_modify &= (~bd_reg_data[index]),
+		ad_bd_reg();
+	}
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::ins_to_reg(unsigned short index,unsigned short* insb,unsigned short value)
+{
+	register unsigned short i;
+	for(i=0;i<13;i++) reg_bufs[index].v[i] = insb[i];
+	reg_bufs[index].v[13] = value&3;
+	ad_bd_reg(),ad_08_reg(),
+	ad_40_reg(index),ad_C0_reg(index),ad_60_reg(index),
+	ad_80_reg(index),ad_20_reg(index),ad_E0_reg(index);
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::ad_E0_reg(unsigned short index)
+{
+	unsigned short data = e0_reg_flag == 0?0:(reg_bufs[index].v[13]&3);
+	ad_bop(0xE0+reg_data[index],data);
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::ad_20_reg(unsigned short index)
+{
+	unsigned short data = (reg_bufs[index].v[9] < 1?0:0x80);
+	data += (reg_bufs[index].v[10] < 1?0:0x40);
+	data += (reg_bufs[index].v[5] < 1?0:0x20);
+	data += (reg_bufs[index].v[11] < 1?0:0x10);
+	data += (reg_bufs[index].v[1]&0x0F);
+	ad_bop(0x20+reg_data[index],data);
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::ad_80_reg(unsigned short index)
+{
+	unsigned short data = (reg_bufs[index].v[7]&0x0F),temp = reg_bufs[index].v[4];
+	data |= (temp << 4);
+	ad_bop(0x80+reg_data[index],data);
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::ad_60_reg(unsigned short index)
+{
+	unsigned short data = reg_bufs[index].v[6]&0x0F,temp = reg_bufs[index].v[3];
+	data |= (temp << 4);
+	ad_bop(0x60+reg_data[index],data);
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::ad_C0_reg(unsigned short index)
+{
+	unsigned short data = reg_bufs[index].v[2];
+	if(adflag[index] == 1) return;
+	data *= 2,
+	data |= (reg_bufs[index].v[12] < 1?1:0);
+	ad_bop(0xC0+ad_C0_offs[index],data);
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::ad_40_reg(unsigned short index)
+{
+	unsigned int res = 0;
+	unsigned short data = 0,temp = reg_bufs[index].v[0];
+	data = 0x3F - (0x3F & reg_bufs[index].v[8]),
+	data *= for40reg[index],
+	data *= 2,
+	data += 0x7F,
+	res = data;
+	data = res/0xFE,
+	data -= 0x3F,
+	data = -data,
+	data |= temp<<6;
+	ad_bop(0x40+reg_data[index],data);
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::ad_bd_reg()
+{
+	unsigned short data = rhythm < 1? 0:0x20;
+	data |= bd_modify;
+	ad_bop(0xBD,data);
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::ad_a0b0_reg(unsigned short index)
+{
+	ad_bop(0xA0+index,0);
+	ad_bop(0xB0+index,0);
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::music_ctrl()
+{
+	register int i;
+	music_on = 0;
+	for(i=0;i<11;i++)
+	switch_ad_bd(i);
+}
+/*----------------------------------------------------------------------*/
+inline unsigned int CrixPlayer::strm_and_fr(unsigned short parm)
+{
+	return ((unsigned int)parm*6+10000)*0.27461678223;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/rix.h	Sat Jan 14 07:27:13 2006 -0800
@@ -0,0 +1,130 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * rix.h - Dayu OPL Format Player by palxex <palxex@163.com/palxex.ys168.com> 
+ */
+
+#include "player.h"
+
+class CrixPlayer: public CPlayer
+{
+public:
+  static CPlayer *factory(Copl *newopl);
+
+	CrixPlayer(Copl *newopl)
+		: CPlayer(newopl),I(0),T(0),mus_block(0),ins_block(0),rhythm(0),mutex(0),music_on(0),
+		  pause_flag(0),band(0),band_low(0),e0_reg_flag(0),bd_modify(0),sustain(0),dro_end(0)
+	{
+	//	memset(buffer,0,97948);
+		int i=0,j=i*3;
+		unsigned long t=9;
+
+		if(opl->gettype() == Copl::TYPE_OPL2)
+		  opl3_mode = 0;
+		else
+		  opl3_mode = 1;
+	};
+	~CrixPlayer()
+	{};
+
+	bool load(const std::string &filename, const CFileProvider &fp);
+	bool update();
+	void rewind(int subsong);
+	float getrefresh();
+
+	std::string gettype()
+	{ return std::string("Softstar RIX OPL Music Format"); };
+
+	typedef struct {unsigned char v[14];}ADDT;
+
+protected:	
+	unsigned char dro[64000];
+	unsigned char buf_addr[655360];  /* rix files' buffer */
+	unsigned short buffer[300];
+	unsigned short a0b0_data2[11];
+	unsigned char a0b0_data3[18];
+	unsigned char a0b0_data4[18];
+	unsigned char a0b0_data5[96];
+	unsigned char addrs_head[96];
+	unsigned short insbuf[28];
+	unsigned short displace[11];
+	ADDT reg_bufs[18];
+	unsigned long pos,length;
+	unsigned long msdone,mstotal;
+	unsigned short delay;
+	unsigned char index, opl3_mode;
+	enum OplMode {
+		ModeOPL2,ModeOPL3,ModeDUALOPL2
+	} mode;
+
+	static const unsigned char adflag[18];
+	static const unsigned char reg_data[18];
+	static const unsigned char ad_C0_offs[18];
+	static const unsigned char modify[28];
+	static const unsigned char bd_reg_data[124];
+	static unsigned char for40reg[18];
+	static unsigned short mus_time;
+	unsigned int I,T;
+	unsigned short mus_block;
+	unsigned short ins_block;
+	unsigned char rhythm;
+	unsigned char mutex;
+	unsigned char music_on;
+	unsigned char pause_flag;
+	unsigned short band;
+	unsigned char band_low;
+	unsigned short e0_reg_flag;
+	unsigned char bd_modify;
+	int sustain;
+	int dro_end;
+
+	#define ad_08_reg() ad_bop(8,0)    /**/
+	inline void ad_20_reg(unsigned short);              /**/
+	inline void ad_40_reg(unsigned short);              /**/
+	inline void ad_60_reg(unsigned short);              /**/
+	inline void ad_80_reg(unsigned short);              /**/
+	inline void ad_a0b0_reg(unsigned short);            /**/
+	inline void ad_a0b0l_reg(unsigned short,unsigned short,unsigned short); /**/
+	inline void ad_a0b0l_reg_(unsigned short,unsigned short,unsigned short); /**/
+	inline void ad_bd_reg();                  /**/
+	inline void ad_bop(unsigned short,unsigned short);                     /**/
+	inline void ad_C0_reg(unsigned short);              /**/
+	inline void ad_E0_reg(unsigned short);              /**/
+	inline unsigned short ad_initial();                 /**/
+	inline unsigned short ad_test();                    /**/
+	inline void crc_trans(unsigned short,unsigned short);         /**/
+	inline void data_initial();               /* done */
+	inline void init();                       /**/
+	inline void ins_to_reg(unsigned short,unsigned short*,unsigned short);  /**/
+	inline void int_08h_entry();    /**/
+	inline void music_ctrl();                 /**/
+	inline void Pause();                      /**/
+	inline void prep_int();                   /**/
+	inline void prepare_a0b0(unsigned short,unsigned short);      /**/
+	inline void rix_90_pro(unsigned short);             /**/
+	inline void rix_A0_pro(unsigned short,unsigned short);        /**/
+	inline void rix_B0_pro(unsigned short,unsigned short);        /**/
+	inline void rix_C0_pro(unsigned short,unsigned short);        /**/
+	inline void rix_get_ins();                /**/
+	inline unsigned short rix_proc();                   /**/
+	inline void set_new_int();
+	inline void set_speed(unsigned short);              /**/
+	inline void set_time(unsigned short);               /**/
+	inline void switch_ad_bd(unsigned short);           /**/
+	inline unsigned int strm_and_fr(unsigned short);               /* done */
+};
--- a/Plugins/Input/adplug/core/silentopl.h	Sat Jan 14 05:40:19 2006 -0800
+++ b/Plugins/Input/adplug/core/silentopl.h	Sat Jan 14 07:27:13 2006 -0800
@@ -1,6 +1,6 @@
 /*
  * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999, 2000, 2001 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * Copyright (C) 1999 - 2005 Simon Peter, <dn.tlp@gmx.net>, et al.
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -16,7 +16,6 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- *
  * silentopl.h - Silent OPL device, by Simon Peter (dn.tlp@gmx.net)
  */
 
@@ -25,6 +24,6 @@
 class CSilentopl: public Copl
 {
 public:
-	void write(int reg, int val) { };
-	void init() { };
+	void write(int reg, int val) {}
+	void init() {}
 };
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/temuopl.cpp	Sat Jan 14 07:27:13 2006 -0800
@@ -0,0 +1,75 @@
+/*
+ * AdPlug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2004 Simon Peter <dn.tlp@gmx.net>, et al.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * temuopl.cpp - Tatsuyuki Satoh's OPL2 emulator, by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include "temuopl.h"
+
+CTemuopl::CTemuopl(int rate, bool bit16, bool usestereo)
+  : use16bit(bit16), stereo(usestereo)
+{
+  opl = OPLCreate(OPL_TYPE_YM3812, 3579545, rate);
+}
+
+CTemuopl::~CTemuopl()
+{
+  OPLDestroy(opl);
+}
+
+void CTemuopl::update(short *buf, int samples)
+{
+  int i;
+
+  if(use16bit) {
+    YM3812UpdateOne(opl,buf,samples);
+
+    if(stereo)
+      for(i=samples-1;i>=0;i--) {
+	buf[i*2] = buf[i];
+	buf[i*2+1] = buf[i];
+      }
+  } else {
+    short *tempbuf = new short[stereo ? samples*2 : samples];
+    int i;
+
+    YM3812UpdateOne(opl,tempbuf,samples);
+
+    if(stereo)
+      for(i=samples-1;i>=0;i--) {
+	tempbuf[i*2] = tempbuf[i];
+	tempbuf[i*2+1] = tempbuf[i];
+      }
+
+    for(i=0;i<(stereo ? samples*2 : samples);i++)
+      ((char *)buf)[i] = (tempbuf[i] >> 8) ^ 0x80;
+
+    delete [] tempbuf;
+  }
+}
+
+void CTemuopl::write(int reg, int val)
+{
+  OPLWrite(opl,0,reg);
+  OPLWrite(opl,1,val);
+}
+
+void CTemuopl::init()
+{
+  OPLResetChip(opl);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/temuopl.h	Sat Jan 14 07:27:13 2006 -0800
@@ -0,0 +1,47 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2004 Simon Peter, <dn.tlp@gmx.net>, et al.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library 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
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * temuopl.h - Tatsuyuki Satoh's OPL2 emulator, by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#ifndef H_ADPLUG_TEMUOPL
+#define H_ADPLUG_TEMUOPL
+
+#include "opl.h"
+extern "C" {
+#include "fmopl.h"
+}
+
+class CTemuopl: public Copl
+{
+ public:
+  CTemuopl(int rate, bool bit16, bool usestereo);	// rate = sample rate
+  virtual ~CTemuopl();
+
+  void update(short *buf, int samples);	// fill buffer
+
+  // template methods
+  void write(int reg, int val);
+  void init();
+
+ private:
+  bool		use16bit,stereo;
+  FM_OPL	*opl;			// holds emulator data
+};
+
+#endif