changeset 1713:a4d7227231e3 trunk

[svn] More .cpp -> .cxx. Noticed by Chainsaw. Shame on me that I forgot some ;).
author js
date Sat, 16 Sep 2006 07:33:28 -0700
parents 2e7c9f6d9923
children 1d2539762092
files ChangeLog Plugins/Input/adplug/core/Makefile.in Plugins/Input/adplug/core/a2m.cpp Plugins/Input/adplug/core/a2m.cxx Plugins/Input/adplug/core/adl.cpp Plugins/Input/adplug/core/adl.cxx Plugins/Input/adplug/core/adplug.cpp Plugins/Input/adplug/core/adplug.cxx Plugins/Input/adplug/core/adtrack.cpp Plugins/Input/adplug/core/adtrack.cxx Plugins/Input/adplug/core/amd.cpp Plugins/Input/adplug/core/amd.cxx Plugins/Input/adplug/core/bam.cpp Plugins/Input/adplug/core/bam.cxx Plugins/Input/adplug/core/bmf.cpp Plugins/Input/adplug/core/bmf.cxx Plugins/Input/adplug/core/cff.cpp Plugins/Input/adplug/core/cff.cxx Plugins/Input/adplug/core/d00.cpp Plugins/Input/adplug/core/d00.cxx Plugins/Input/adplug/core/database.cpp Plugins/Input/adplug/core/database.cxx Plugins/Input/adplug/core/dfm.cpp Plugins/Input/adplug/core/dfm.cxx Plugins/Input/adplug/core/diskopl.cpp Plugins/Input/adplug/core/diskopl.cxx Plugins/Input/adplug/core/dmo.cpp Plugins/Input/adplug/core/dmo.cxx Plugins/Input/adplug/core/dro.cpp Plugins/Input/adplug/core/dro.cxx Plugins/Input/adplug/core/dtm.cpp Plugins/Input/adplug/core/dtm.cxx Plugins/Input/adplug/core/emuopl.cpp Plugins/Input/adplug/core/emuopl.cxx Plugins/Input/adplug/core/flash.cpp Plugins/Input/adplug/core/flash.cxx Plugins/Input/adplug/core/fmc.cpp Plugins/Input/adplug/core/fmc.cxx Plugins/Input/adplug/core/fprovide.cpp Plugins/Input/adplug/core/fprovide.cxx Plugins/Input/adplug/core/hsc.cpp Plugins/Input/adplug/core/hsc.cxx Plugins/Input/adplug/core/hsp.cpp Plugins/Input/adplug/core/hsp.cxx Plugins/Input/adplug/core/hybrid.cpp Plugins/Input/adplug/core/hybrid.cxx Plugins/Input/adplug/core/hyp.cpp Plugins/Input/adplug/core/hyp.cxx Plugins/Input/adplug/core/imf.cpp Plugins/Input/adplug/core/imf.cxx Plugins/Input/adplug/core/ksm.cpp Plugins/Input/adplug/core/ksm.cxx Plugins/Input/adplug/core/lds.cpp Plugins/Input/adplug/core/lds.cxx Plugins/Input/adplug/core/mad.cpp Plugins/Input/adplug/core/mad.cxx Plugins/Input/adplug/core/mid.cpp Plugins/Input/adplug/core/mid.cxx Plugins/Input/adplug/core/mkj.cpp Plugins/Input/adplug/core/mkj.cxx Plugins/Input/adplug/core/msc.cpp Plugins/Input/adplug/core/msc.cxx Plugins/Input/adplug/core/mtk.cpp Plugins/Input/adplug/core/mtk.cxx Plugins/Input/adplug/core/player.cpp Plugins/Input/adplug/core/player.cxx Plugins/Input/adplug/core/players.cpp Plugins/Input/adplug/core/players.cxx Plugins/Input/adplug/core/protrack.cpp Plugins/Input/adplug/core/protrack.cxx Plugins/Input/adplug/core/psi.cpp Plugins/Input/adplug/core/psi.cxx Plugins/Input/adplug/core/rad.cpp Plugins/Input/adplug/core/rad.cxx Plugins/Input/adplug/core/rat.cpp Plugins/Input/adplug/core/rat.cxx Plugins/Input/adplug/core/raw.cpp Plugins/Input/adplug/core/raw.cxx Plugins/Input/adplug/core/rix.cpp Plugins/Input/adplug/core/rix.cxx Plugins/Input/adplug/core/rol.cpp Plugins/Input/adplug/core/rol.cxx Plugins/Input/adplug/core/s3m.cpp Plugins/Input/adplug/core/s3m.cxx Plugins/Input/adplug/core/sa2.cpp Plugins/Input/adplug/core/sa2.cxx Plugins/Input/adplug/core/sng.cpp Plugins/Input/adplug/core/sng.cxx Plugins/Input/adplug/core/temuopl.cpp Plugins/Input/adplug/core/temuopl.cxx Plugins/Input/adplug/core/u6m.cpp Plugins/Input/adplug/core/u6m.cxx Plugins/Input/adplug/core/xad.cpp Plugins/Input/adplug/core/xad.cxx Plugins/Input/adplug/core/xsm.cpp Plugins/Input/adplug/core/xsm.cxx Plugins/Input/modplug/Makefile.in Plugins/Input/modplug/archive/Makefile.in Plugins/Input/modplug/archive/arch_bz2.cpp Plugins/Input/modplug/archive/arch_bz2.cxx Plugins/Input/modplug/archive/arch_gzip.cpp Plugins/Input/modplug/archive/arch_gzip.cxx Plugins/Input/modplug/archive/arch_rar.cpp Plugins/Input/modplug/archive/arch_rar.cxx Plugins/Input/modplug/archive/arch_raw.cpp Plugins/Input/modplug/archive/arch_raw.cxx Plugins/Input/modplug/archive/arch_zip.cpp Plugins/Input/modplug/archive/arch_zip.cxx Plugins/Input/modplug/archive/archive.cpp Plugins/Input/modplug/archive/archive.cxx Plugins/Input/modplug/archive/open.cpp Plugins/Input/modplug/archive/open.cxx Plugins/Input/modplug/gui/Makefile.in Plugins/Input/modplug/gui/callbacks.cpp Plugins/Input/modplug/gui/callbacks.cxx Plugins/Input/modplug/gui/interface.cpp Plugins/Input/modplug/gui/interface.cxx Plugins/Input/modplug/gui/main.cpp Plugins/Input/modplug/gui/main.cxx Plugins/Input/modplug/gui/support.cpp Plugins/Input/modplug/gui/support.cxx Plugins/Input/modplug/modplugbmp.cpp Plugins/Input/modplug/modplugbmp.cxx Plugins/Input/modplug/plugin.cpp Plugins/Input/modplug/plugin.cxx
diffstat 125 files changed, 19481 insertions(+), 19472 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Sep 16 07:18:18 2006 -0700
+++ b/ChangeLog	Sat Sep 16 07:33:28 2006 -0700
@@ -1,3 +1,12 @@
+2006-09-16 14:18:18 +0000  Tony Vroon <chainsaw@gentoo.org>
+  revision [2361]
+  Use the VFS layer.
+
+  Changes:        Modified:
+  +10 -10         trunk/Plugins/Input/console/abstract_file.cxx  
+  +11 -10         trunk/Plugins/Input/console/abstract_file.h  
+
+
 2006-09-16 04:36:31 +0000  Yoshiki Yazawa <yaz@cc.rim.or.jp>
   revision [2359]
   - no more busy loop if a file in playlist disappears.
--- a/Plugins/Input/adplug/core/Makefile.in	Sat Sep 16 07:18:18 2006 -0700
+++ b/Plugins/Input/adplug/core/Makefile.in	Sat Sep 16 07:33:28 2006 -0700
@@ -3,13 +3,13 @@
 
 OBJECTIVE_LIBS_NOINST = libadplugcore.a
 
-SOURCES = adplug.cpp emuopl.cpp fmopl.c diskopl.cpp debug.c fprovide.cpp \
-player.cpp database.cpp hsc.cpp sng.cpp imf.cpp 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 temuopl.cpp msc.cpp rix.cpp \
-adl.cpp
+SOURCES = adplug.cxx emuopl.cxx fmopl.c diskopl.cxx debug.c fprovide.cxx \
+player.cxx database.cxx hsc.cxx sng.cxx imf.cxx players.cxx protrack.cxx \
+a2m.cxx adtrack.cxx amd.cxx bam.cxx d00.cxx dfm.cxx dmo.cxx hsp.cxx ksm.cxx \
+mad.cxx mid.cxx mkj.cxx cff.cxx dtm.cxx fmc.cxx mtk.cxx rad.cxx raw.cxx \
+sa2.cxx s3m.cxx xad.cxx flash.cxx bmf.cxx hybrid.cxx hyp.cxx psi.cxx rat.cxx \
+u6m.cxx rol.cxx xsm.cxx adlibemu.c dro.cxx lds.cxx temuopl.cxx msc.cxx rix.cxx \
+adl.cxx
 
 noinst_HEADERS = adplug.h emuopl.h fmopl.h silentopl.h opl.h diskopl.h \
 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 \
@@ -21,6 +21,6 @@
 CXXFLAGS += $(PICFLAGS) $(BINIO_CFLAGS) -I../../../../intl -I../../../.. -Dstricmp=strcasecmp
 CFLAGS += $(PICFLAGS) $(BINIO_CFLAGS) -I../../../../intl -I../../../.. -Dstricmp=strcasecmp
 
-OBJECTS = ${SOURCES:.c=.o} ${SOURCES:.cpp=.o}
+OBJECTS = ${SOURCES:.c=.o} ${SOURCES:.cxx=.o}
 
 include ../../../../mk/objective.mk
--- a/Plugins/Input/adplug/core/a2m.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,449 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * a2m.cpp - A2M Loader by Simon Peter <dn.tlp@gmx.net>
- *
- * NOTES:
- * This loader detects and loads version 1, 4, 5 & 8 files.
- *
- * version 1-4 files:
- * Following commands are ignored:
- * FF1 - FF9, FAx - FEx
- *
- * version 5-8 files:
- * Instrument panning is ignored. Flags byte is ignored.
- * Following commands are ignored:
- * Gxy, Hxy, Kxy - &xy
- */
-
-#include "a2m.h"
-
-const unsigned int Ca2mLoader::MAXFREQ = 2000,
-Ca2mLoader::MINCOPY = ADPLUG_A2M_MINCOPY,
-Ca2mLoader::MAXCOPY = ADPLUG_A2M_MAXCOPY,
-Ca2mLoader::COPYRANGES = ADPLUG_A2M_COPYRANGES,
-Ca2mLoader::CODESPERRANGE = ADPLUG_A2M_CODESPERRANGE,
-Ca2mLoader::TERMINATE = 256,
-Ca2mLoader::FIRSTCODE = ADPLUG_A2M_FIRSTCODE,
-Ca2mLoader::MAXCHAR = FIRSTCODE + COPYRANGES * CODESPERRANGE - 1,
-Ca2mLoader::SUCCMAX = MAXCHAR + 1,
-Ca2mLoader::TWICEMAX = ADPLUG_A2M_TWICEMAX,
-Ca2mLoader::ROOT = 1, Ca2mLoader::MAXBUF = 42 * 1024,
-Ca2mLoader::MAXDISTANCE = 21389, Ca2mLoader::MAXSIZE = 21389 + MAXCOPY;
-
-const unsigned short Ca2mLoader::bitvalue[14] =
-  {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192};
-
-const signed short Ca2mLoader::copybits[COPYRANGES] =
-  {4, 6, 8, 10, 12, 14};
-
-const signed short Ca2mLoader::copymin[COPYRANGES] =
-  {0, 16, 80, 336, 1360, 5456};
-
-CPlayer *Ca2mLoader::factory(Copl *newopl)
-{
-  return new Ca2mLoader(newopl);
-}
-
-bool Ca2mLoader::load(const std::string &filename, const CFileProvider &fp)
-{
-  binistream *f = fp.open(filename); if(!f) return false;
-  struct {
-    char id[10];
-    unsigned long crc;
-    unsigned char version,numpats;
-  } ch;
-  int i,j,k,t;
-  unsigned int l;
-  unsigned char *org = 0, *orgptr;
-  unsigned long alength;
-  unsigned short len[9], *secdata, *secptr;
-  const unsigned char convfx[16] = {0,1,2,23,24,3,5,4,6,9,17,13,11,19,7,14};
-  const unsigned char convinf1[16] = {0,1,2,6,7,8,9,4,5,3,10,11,12,13,14,15};
-  const unsigned char newconvfx[] = {0,1,2,3,4,5,6,23,24,21,10,11,17,13,7,19,
-				     255,255,22,25,255,15,255,255,255,255,255,
-				     255,255,255,255,255,255,255,255,14,255};
-
-  // read header
-  f->readString(ch.id, 10); ch.crc = f->readInt(4);
-  ch.version = f->readInt(1); ch.numpats = f->readInt(1);
-
-  // file validation section
-  if(strncmp(ch.id,"_A2module_",10) || (ch.version != 1 && ch.version != 5 &&
-					ch.version != 4 && ch.version != 8)) {
-    fp.close(f);
-    return false;
-  }
-
-  // load, depack & convert section
-  nop = ch.numpats; length = 128; restartpos = 0; activechan = 0xffff;
-  if(ch.version == 1 || ch.version == 4) {
-    for(i=0;i<5;i++) len[i] = f->readInt(2);
-    t = 9;
-  } else {
-    for(i=0;i<9;i++) len[i] = f->readInt(2);
-    t = 18;
-  }
-
-  // block 0
-  secdata = new unsigned short [len[0] / 2];
-  if(ch.version == 1 || ch.version == 5) {
-    for(i=0;i<len[0]/2;i++) secdata[i] = f->readInt(2);
-    org = new unsigned char [MAXBUF]; orgptr = org;
-    sixdepak(secdata,org,len[0]);
-  } else {
-    orgptr = (unsigned char *)secdata;
-    for(i=0;i<len[0];i++) orgptr[i] = f->readInt(1);
-  }
-  memcpy(songname,orgptr,43); orgptr += 43;
-  memcpy(author,orgptr,43); orgptr += 43;
-  memcpy(instname,orgptr,250*33); orgptr += 250*33;
-  for(i=0;i<250;i++) {	// instruments
-    inst[i].data[0] = *(orgptr+i*13+10);
-    inst[i].data[1] = *(orgptr+i*13);
-    inst[i].data[2] = *(orgptr+i*13+1);
-    inst[i].data[3] = *(orgptr+i*13+4);
-    inst[i].data[4] = *(orgptr+i*13+5);
-    inst[i].data[5] = *(orgptr+i*13+6);
-    inst[i].data[6] = *(orgptr+i*13+7);
-    inst[i].data[7] = *(orgptr+i*13+8);
-    inst[i].data[8] = *(orgptr+i*13+9);
-    inst[i].data[9] = *(orgptr+i*13+2);
-    inst[i].data[10] = *(orgptr+i*13+3);
-    if(ch.version == 1 || ch.version == 4)
-      inst[i].misc = *(orgptr+i*13+11);
-    else
-      inst[i].misc = 0;
-    inst[i].slide = *(orgptr+i*13+12);
-  }
-
-  orgptr += 250*13;
-  memcpy(order,orgptr,128); orgptr += 128;
-  bpm = *orgptr; orgptr += 1;
-  initspeed = *orgptr;
-  // v5-8 files have an additional flag byte here
-  if(ch.version == 1 || ch.version == 5)
-    delete [] org;
-  delete [] secdata;
-
-  // blocks 1-4 or 1-8
-  alength = len[1];
-  for(i=0;i<(ch.version == 1 || ch.version == 4 ? ch.numpats/16 : ch.numpats/8);i++)
-    alength += len[i+2];
-
-  secdata = new unsigned short [alength / 2];
-  if(ch.version == 1 || ch.version == 5) {
-    for(l=0;l<alength/2;l++) secdata[l] = f->readInt(2);
-    org = new unsigned char [MAXBUF * (ch.numpats / (ch.version == 1 ? 16 : 8) + 1)];
-    orgptr = org; secptr = secdata;
-    orgptr += sixdepak(secptr,orgptr,len[1]); secptr += len[1] / 2;
-    if(ch.version == 1) {
-      if(ch.numpats > 16)
-	orgptr += sixdepak(secptr,orgptr,len[2]); secptr += len[2] / 2;
-      if(ch.numpats > 32)
-	orgptr += sixdepak(secptr,orgptr,len[3]); secptr += len[3] / 2;
-      if(ch.numpats > 48)
-	sixdepak(secptr,orgptr,len[4]);
-    } else {
-      if(ch.numpats > 8)
-	orgptr += sixdepak(secptr,orgptr,len[2]); secptr += len[2] / 2;
-      if(ch.numpats > 16)
-	orgptr += sixdepak(secptr,orgptr,len[3]); secptr += len[3] / 2;
-      if(ch.numpats > 24)
-	orgptr += sixdepak(secptr,orgptr,len[4]); secptr += len[4] / 2;
-      if(ch.numpats > 32)
-	orgptr += sixdepak(secptr,orgptr,len[5]); secptr += len[5] / 2;
-      if(ch.numpats > 40)
-	orgptr += sixdepak(secptr,orgptr,len[6]); secptr += len[6] / 2;
-      if(ch.numpats > 48)
-	orgptr += sixdepak(secptr,orgptr,len[7]); secptr += len[7] / 2;
-      if(ch.numpats > 56)
-	sixdepak(secptr,orgptr,len[8]);
-    }
-    delete [] secdata;
-  } else {
-    org = (unsigned char *)secdata;
-    for(l=0;l<alength;l++) org[l] = f->readInt(1);
-  }
-
-  for(i=0;i<64*9;i++)		// patterns
-    trackord[i/9][i%9] = i+1;
-
-  if(ch.version == 1 || ch.version == 4) {
-    for(i=0;i<ch.numpats;i++)
-      for(j=0;j<64;j++)
-	for(k=0;k<9;k++) {
-	  tracks[i*9+k][j].note = org[i*64*t*4+j*t*4+k*4] == 255 ? 127 : org[i*64*t*4+j*t*4+k*4];
-	  tracks[i*9+k][j].inst = org[i*64*t*4+j*t*4+k*4+1];
-	  tracks[i*9+k][j].command = convfx[org[i*64*t*4+j*t*4+k*4+2]];
-	  tracks[i*9+k][j].param2 = org[i*64*t*4+j*t*4+k*4+3] & 0x0f;
-	  if(tracks[i*9+k][j].command != 14)
-	    tracks[i*9+k][j].param1 = org[i*64*t*4+j*t*4+k*4+3] >> 4;
-	  else {
-	    tracks[i*9+k][j].param1 = convinf1[org[i*64*t*4+j*t*4+k*4+3] >> 4];
-	    if(tracks[i*9+k][j].param1 == 15 && !tracks[i*9+k][j].param2) {	// convert key-off
-	      tracks[i*9+k][j].command = 8;
-	      tracks[i*9+k][j].param1 = 0;
-	      tracks[i*9+k][j].param2 = 0;
-	    }
-	  }
-	  if(tracks[i*9+k][j].command == 14) {
-	    switch(tracks[i*9+k][j].param1) {
-	    case 2: // convert define waveform
-	      tracks[i*9+k][j].command = 25;
-	      tracks[i*9+k][j].param1 = tracks[i*9+k][j].param2;
-	      tracks[i*9+k][j].param2 = 0xf;
-	      break;
-	    case 8: // convert volume slide up
-	      tracks[i*9+k][j].command = 26;
-	      tracks[i*9+k][j].param1 = tracks[i*9+k][j].param2;
-	      tracks[i*9+k][j].param2 = 0;
-	      break;
-	    case 9: // convert volume slide down
-	      tracks[i*9+k][j].command = 26;
-	      tracks[i*9+k][j].param1 = 0;
-	      break;
-	    }
-	  }
-	}
-  } else {
-    for(i=0;i<ch.numpats;i++)
-      for(j=0;j<9;j++)
-	for(k=0;k<64;k++) {
-	  tracks[i*9+j][k].note = org[i*64*t*4+j*64*4+k*4] == 255 ? 127 : org[i*64*t*4+j*64*4+k*4];
-	  tracks[i*9+j][k].inst = org[i*64*t*4+j*64*4+k*4+1];
-	  tracks[i*9+j][k].command = newconvfx[org[i*64*t*4+j*64*4+k*4+2]];
-	  tracks[i*9+j][k].param1 = org[i*64*t*4+j*64*4+k*4+3] >> 4;
-	  tracks[i*9+j][k].param2 = org[i*64*t*4+j*64*4+k*4+3] & 0x0f;
-	}
-  }
-
-  if(ch.version == 1 || ch.version == 5)
-    delete [] org;
-  else
-    delete [] secdata;
-  fp.close(f);
-  rewind(0);
-  return true;
-}
-
-float Ca2mLoader::getrefresh()
-{
-	if(tempo != 18)
-		return (float) (tempo);
-	else
-		return 18.2f;
-}
-
-/*** private methods *************************************/
-
-void Ca2mLoader::inittree()
-{
-	unsigned short i;
-
-	for(i=2;i<=TWICEMAX;i++) {
-		dad[i] = i / 2;
-		freq[i] = 1;
-	}
-
-	for(i=1;i<=MAXCHAR;i++) {
-		leftc[i] = 2 * i;
-		rghtc[i] = 2 * i + 1;
-	}
-}
-
-void Ca2mLoader::updatefreq(unsigned short a,unsigned short b)
-{
-	do {
-		freq[dad[a]] = freq[a] + freq[b];
-		a = dad[a];
-		if(a != ROOT)
-			if(leftc[dad[a]] == a)
-				b = rghtc[dad[a]];
-			else
-				b = leftc[dad[a]];
-	} while(a != ROOT);
-
-	if(freq[ROOT] == MAXFREQ)
-		for(a=1;a<=TWICEMAX;a++)
-			freq[a] >>= 1;
-}
-
-void Ca2mLoader::updatemodel(unsigned short code)
-{
-	unsigned short a=code+SUCCMAX,b,c,code1,code2;
-
-	freq[a]++;
-	if(dad[a] != ROOT) {
-		code1 = dad[a];
-		if(leftc[code1] == a)
-			updatefreq(a,rghtc[code1]);
-		else
-			updatefreq(a,leftc[code1]);
-
-		do {
-			code2 = dad[code1];
-			if(leftc[code2] == code1)
-				b = rghtc[code2];
-			else
-				b = leftc[code2];
-
-			if(freq[a] > freq[b]) {
-				if(leftc[code2] == code1)
-					rghtc[code2] = a;
-				else
-					leftc[code2] = a;
-
-				if(leftc[code1] == a) {
-					leftc[code1] = b;
-					c = rghtc[code1];
-				} else {
-					rghtc[code1] = b;
-					c = leftc[code1];
-				}
-
-				dad[b] = code1;
-				dad[a] = code2;
-				updatefreq(b,c);
-				a = b;
-			}
-
-			a = dad[a];
-			code1 = dad[a];
-		} while(code1 != ROOT);
-	}
-}
-
-unsigned short Ca2mLoader::inputcode(unsigned short bits)
-{
-	unsigned short i,code=0;
-
-	for(i=1;i<=bits;i++) {
-		if(!ibitcount) {
-			if(ibitcount == MAXBUF)
-				ibufcount = 0;
-			ibitbuffer = wdbuf[ibufcount];
-			ibufcount++;
-			ibitcount = 15;
-		} else
-			ibitcount--;
-
-		if(ibitbuffer > 0x7fff)
-			code |= bitvalue[i-1];
-		ibitbuffer <<= 1;
-	}
-
-	return code;
-}
-
-unsigned short Ca2mLoader::uncompress()
-{
-	unsigned short a=1;
-
-	do {
-		if(!ibitcount) {
-			if(ibufcount == MAXBUF)
-				ibufcount = 0;
-			ibitbuffer = wdbuf[ibufcount];
-			ibufcount++;
-			ibitcount = 15;
-		} else
-			ibitcount--;
-
-		if(ibitbuffer > 0x7fff)
-			a = rghtc[a];
-		else
-			a = leftc[a];
-		ibitbuffer <<= 1;
-	} while(a <= MAXCHAR);
-
-	a -= SUCCMAX;
-	updatemodel(a);
-	return a;
-}
-
-void Ca2mLoader::decode()
-{
-	unsigned short i,j,k,t,c,count=0,dist,len,index;
-
-	inittree();
-	c = uncompress();
-
-	while(c != TERMINATE) {
-		if(c < 256) {
-			obuf[obufcount] = (unsigned char)c;
-			obufcount++;
-			if(obufcount == MAXBUF) {
-				output_size = MAXBUF;
-				obufcount = 0;
-			}
-
-			buf[count] = (unsigned char)c;
-			count++;
-			if(count == MAXSIZE)
-				count = 0;
-		} else {
-			t = c - FIRSTCODE;
-			index = t / CODESPERRANGE;
-			len = t + MINCOPY - index * CODESPERRANGE;
-			dist = inputcode(copybits[index]) + len + copymin[index];
-
-			j = count;
-			k = count - dist;
-			if(count < dist)
-				k += MAXSIZE;
-
-			for(i=0;i<=len-1;i++) {
-				obuf[obufcount] = buf[k];
-				obufcount++;
-				if(obufcount == MAXBUF) {
-					output_size = MAXBUF;
-					obufcount = 0;
-				}
-
-				buf[j] = buf[k];
-				j++; k++;
-				if(j == MAXSIZE) j = 0;
-				if(k == MAXSIZE) k = 0;
-			}
-
-			count += len;
-			if(count >= MAXSIZE)
-				count -= MAXSIZE;
-		}
-		c = uncompress();
-	}
-	output_size = obufcount;
-}
-
-unsigned short Ca2mLoader::sixdepak(unsigned short *source, unsigned char *dest,
-				    unsigned short size)
-{
-	if((unsigned int)size + 4096 > MAXBUF)
-		return 0;
-
-	buf = new unsigned char [MAXSIZE];
-	input_size = size;
-	ibitcount = 0; ibitbuffer = 0;
-	obufcount = 0; ibufcount = 0;
-	wdbuf = source; obuf = dest;
-
-	decode();
-	delete [] buf;
-	return output_size;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/a2m.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,449 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * a2m.cpp - A2M Loader by Simon Peter <dn.tlp@gmx.net>
+ *
+ * NOTES:
+ * This loader detects and loads version 1, 4, 5 & 8 files.
+ *
+ * version 1-4 files:
+ * Following commands are ignored:
+ * FF1 - FF9, FAx - FEx
+ *
+ * version 5-8 files:
+ * Instrument panning is ignored. Flags byte is ignored.
+ * Following commands are ignored:
+ * Gxy, Hxy, Kxy - &xy
+ */
+
+#include "a2m.h"
+
+const unsigned int Ca2mLoader::MAXFREQ = 2000,
+Ca2mLoader::MINCOPY = ADPLUG_A2M_MINCOPY,
+Ca2mLoader::MAXCOPY = ADPLUG_A2M_MAXCOPY,
+Ca2mLoader::COPYRANGES = ADPLUG_A2M_COPYRANGES,
+Ca2mLoader::CODESPERRANGE = ADPLUG_A2M_CODESPERRANGE,
+Ca2mLoader::TERMINATE = 256,
+Ca2mLoader::FIRSTCODE = ADPLUG_A2M_FIRSTCODE,
+Ca2mLoader::MAXCHAR = FIRSTCODE + COPYRANGES * CODESPERRANGE - 1,
+Ca2mLoader::SUCCMAX = MAXCHAR + 1,
+Ca2mLoader::TWICEMAX = ADPLUG_A2M_TWICEMAX,
+Ca2mLoader::ROOT = 1, Ca2mLoader::MAXBUF = 42 * 1024,
+Ca2mLoader::MAXDISTANCE = 21389, Ca2mLoader::MAXSIZE = 21389 + MAXCOPY;
+
+const unsigned short Ca2mLoader::bitvalue[14] =
+  {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192};
+
+const signed short Ca2mLoader::copybits[COPYRANGES] =
+  {4, 6, 8, 10, 12, 14};
+
+const signed short Ca2mLoader::copymin[COPYRANGES] =
+  {0, 16, 80, 336, 1360, 5456};
+
+CPlayer *Ca2mLoader::factory(Copl *newopl)
+{
+  return new Ca2mLoader(newopl);
+}
+
+bool Ca2mLoader::load(const std::string &filename, const CFileProvider &fp)
+{
+  binistream *f = fp.open(filename); if(!f) return false;
+  struct {
+    char id[10];
+    unsigned long crc;
+    unsigned char version,numpats;
+  } ch;
+  int i,j,k,t;
+  unsigned int l;
+  unsigned char *org = 0, *orgptr;
+  unsigned long alength;
+  unsigned short len[9], *secdata, *secptr;
+  const unsigned char convfx[16] = {0,1,2,23,24,3,5,4,6,9,17,13,11,19,7,14};
+  const unsigned char convinf1[16] = {0,1,2,6,7,8,9,4,5,3,10,11,12,13,14,15};
+  const unsigned char newconvfx[] = {0,1,2,3,4,5,6,23,24,21,10,11,17,13,7,19,
+				     255,255,22,25,255,15,255,255,255,255,255,
+				     255,255,255,255,255,255,255,255,14,255};
+
+  // read header
+  f->readString(ch.id, 10); ch.crc = f->readInt(4);
+  ch.version = f->readInt(1); ch.numpats = f->readInt(1);
+
+  // file validation section
+  if(strncmp(ch.id,"_A2module_",10) || (ch.version != 1 && ch.version != 5 &&
+					ch.version != 4 && ch.version != 8)) {
+    fp.close(f);
+    return false;
+  }
+
+  // load, depack & convert section
+  nop = ch.numpats; length = 128; restartpos = 0; activechan = 0xffff;
+  if(ch.version == 1 || ch.version == 4) {
+    for(i=0;i<5;i++) len[i] = f->readInt(2);
+    t = 9;
+  } else {
+    for(i=0;i<9;i++) len[i] = f->readInt(2);
+    t = 18;
+  }
+
+  // block 0
+  secdata = new unsigned short [len[0] / 2];
+  if(ch.version == 1 || ch.version == 5) {
+    for(i=0;i<len[0]/2;i++) secdata[i] = f->readInt(2);
+    org = new unsigned char [MAXBUF]; orgptr = org;
+    sixdepak(secdata,org,len[0]);
+  } else {
+    orgptr = (unsigned char *)secdata;
+    for(i=0;i<len[0];i++) orgptr[i] = f->readInt(1);
+  }
+  memcpy(songname,orgptr,43); orgptr += 43;
+  memcpy(author,orgptr,43); orgptr += 43;
+  memcpy(instname,orgptr,250*33); orgptr += 250*33;
+  for(i=0;i<250;i++) {	// instruments
+    inst[i].data[0] = *(orgptr+i*13+10);
+    inst[i].data[1] = *(orgptr+i*13);
+    inst[i].data[2] = *(orgptr+i*13+1);
+    inst[i].data[3] = *(orgptr+i*13+4);
+    inst[i].data[4] = *(orgptr+i*13+5);
+    inst[i].data[5] = *(orgptr+i*13+6);
+    inst[i].data[6] = *(orgptr+i*13+7);
+    inst[i].data[7] = *(orgptr+i*13+8);
+    inst[i].data[8] = *(orgptr+i*13+9);
+    inst[i].data[9] = *(orgptr+i*13+2);
+    inst[i].data[10] = *(orgptr+i*13+3);
+    if(ch.version == 1 || ch.version == 4)
+      inst[i].misc = *(orgptr+i*13+11);
+    else
+      inst[i].misc = 0;
+    inst[i].slide = *(orgptr+i*13+12);
+  }
+
+  orgptr += 250*13;
+  memcpy(order,orgptr,128); orgptr += 128;
+  bpm = *orgptr; orgptr += 1;
+  initspeed = *orgptr;
+  // v5-8 files have an additional flag byte here
+  if(ch.version == 1 || ch.version == 5)
+    delete [] org;
+  delete [] secdata;
+
+  // blocks 1-4 or 1-8
+  alength = len[1];
+  for(i=0;i<(ch.version == 1 || ch.version == 4 ? ch.numpats/16 : ch.numpats/8);i++)
+    alength += len[i+2];
+
+  secdata = new unsigned short [alength / 2];
+  if(ch.version == 1 || ch.version == 5) {
+    for(l=0;l<alength/2;l++) secdata[l] = f->readInt(2);
+    org = new unsigned char [MAXBUF * (ch.numpats / (ch.version == 1 ? 16 : 8) + 1)];
+    orgptr = org; secptr = secdata;
+    orgptr += sixdepak(secptr,orgptr,len[1]); secptr += len[1] / 2;
+    if(ch.version == 1) {
+      if(ch.numpats > 16)
+	orgptr += sixdepak(secptr,orgptr,len[2]); secptr += len[2] / 2;
+      if(ch.numpats > 32)
+	orgptr += sixdepak(secptr,orgptr,len[3]); secptr += len[3] / 2;
+      if(ch.numpats > 48)
+	sixdepak(secptr,orgptr,len[4]);
+    } else {
+      if(ch.numpats > 8)
+	orgptr += sixdepak(secptr,orgptr,len[2]); secptr += len[2] / 2;
+      if(ch.numpats > 16)
+	orgptr += sixdepak(secptr,orgptr,len[3]); secptr += len[3] / 2;
+      if(ch.numpats > 24)
+	orgptr += sixdepak(secptr,orgptr,len[4]); secptr += len[4] / 2;
+      if(ch.numpats > 32)
+	orgptr += sixdepak(secptr,orgptr,len[5]); secptr += len[5] / 2;
+      if(ch.numpats > 40)
+	orgptr += sixdepak(secptr,orgptr,len[6]); secptr += len[6] / 2;
+      if(ch.numpats > 48)
+	orgptr += sixdepak(secptr,orgptr,len[7]); secptr += len[7] / 2;
+      if(ch.numpats > 56)
+	sixdepak(secptr,orgptr,len[8]);
+    }
+    delete [] secdata;
+  } else {
+    org = (unsigned char *)secdata;
+    for(l=0;l<alength;l++) org[l] = f->readInt(1);
+  }
+
+  for(i=0;i<64*9;i++)		// patterns
+    trackord[i/9][i%9] = i+1;
+
+  if(ch.version == 1 || ch.version == 4) {
+    for(i=0;i<ch.numpats;i++)
+      for(j=0;j<64;j++)
+	for(k=0;k<9;k++) {
+	  tracks[i*9+k][j].note = org[i*64*t*4+j*t*4+k*4] == 255 ? 127 : org[i*64*t*4+j*t*4+k*4];
+	  tracks[i*9+k][j].inst = org[i*64*t*4+j*t*4+k*4+1];
+	  tracks[i*9+k][j].command = convfx[org[i*64*t*4+j*t*4+k*4+2]];
+	  tracks[i*9+k][j].param2 = org[i*64*t*4+j*t*4+k*4+3] & 0x0f;
+	  if(tracks[i*9+k][j].command != 14)
+	    tracks[i*9+k][j].param1 = org[i*64*t*4+j*t*4+k*4+3] >> 4;
+	  else {
+	    tracks[i*9+k][j].param1 = convinf1[org[i*64*t*4+j*t*4+k*4+3] >> 4];
+	    if(tracks[i*9+k][j].param1 == 15 && !tracks[i*9+k][j].param2) {	// convert key-off
+	      tracks[i*9+k][j].command = 8;
+	      tracks[i*9+k][j].param1 = 0;
+	      tracks[i*9+k][j].param2 = 0;
+	    }
+	  }
+	  if(tracks[i*9+k][j].command == 14) {
+	    switch(tracks[i*9+k][j].param1) {
+	    case 2: // convert define waveform
+	      tracks[i*9+k][j].command = 25;
+	      tracks[i*9+k][j].param1 = tracks[i*9+k][j].param2;
+	      tracks[i*9+k][j].param2 = 0xf;
+	      break;
+	    case 8: // convert volume slide up
+	      tracks[i*9+k][j].command = 26;
+	      tracks[i*9+k][j].param1 = tracks[i*9+k][j].param2;
+	      tracks[i*9+k][j].param2 = 0;
+	      break;
+	    case 9: // convert volume slide down
+	      tracks[i*9+k][j].command = 26;
+	      tracks[i*9+k][j].param1 = 0;
+	      break;
+	    }
+	  }
+	}
+  } else {
+    for(i=0;i<ch.numpats;i++)
+      for(j=0;j<9;j++)
+	for(k=0;k<64;k++) {
+	  tracks[i*9+j][k].note = org[i*64*t*4+j*64*4+k*4] == 255 ? 127 : org[i*64*t*4+j*64*4+k*4];
+	  tracks[i*9+j][k].inst = org[i*64*t*4+j*64*4+k*4+1];
+	  tracks[i*9+j][k].command = newconvfx[org[i*64*t*4+j*64*4+k*4+2]];
+	  tracks[i*9+j][k].param1 = org[i*64*t*4+j*64*4+k*4+3] >> 4;
+	  tracks[i*9+j][k].param2 = org[i*64*t*4+j*64*4+k*4+3] & 0x0f;
+	}
+  }
+
+  if(ch.version == 1 || ch.version == 5)
+    delete [] org;
+  else
+    delete [] secdata;
+  fp.close(f);
+  rewind(0);
+  return true;
+}
+
+float Ca2mLoader::getrefresh()
+{
+	if(tempo != 18)
+		return (float) (tempo);
+	else
+		return 18.2f;
+}
+
+/*** private methods *************************************/
+
+void Ca2mLoader::inittree()
+{
+	unsigned short i;
+
+	for(i=2;i<=TWICEMAX;i++) {
+		dad[i] = i / 2;
+		freq[i] = 1;
+	}
+
+	for(i=1;i<=MAXCHAR;i++) {
+		leftc[i] = 2 * i;
+		rghtc[i] = 2 * i + 1;
+	}
+}
+
+void Ca2mLoader::updatefreq(unsigned short a,unsigned short b)
+{
+	do {
+		freq[dad[a]] = freq[a] + freq[b];
+		a = dad[a];
+		if(a != ROOT)
+			if(leftc[dad[a]] == a)
+				b = rghtc[dad[a]];
+			else
+				b = leftc[dad[a]];
+	} while(a != ROOT);
+
+	if(freq[ROOT] == MAXFREQ)
+		for(a=1;a<=TWICEMAX;a++)
+			freq[a] >>= 1;
+}
+
+void Ca2mLoader::updatemodel(unsigned short code)
+{
+	unsigned short a=code+SUCCMAX,b,c,code1,code2;
+
+	freq[a]++;
+	if(dad[a] != ROOT) {
+		code1 = dad[a];
+		if(leftc[code1] == a)
+			updatefreq(a,rghtc[code1]);
+		else
+			updatefreq(a,leftc[code1]);
+
+		do {
+			code2 = dad[code1];
+			if(leftc[code2] == code1)
+				b = rghtc[code2];
+			else
+				b = leftc[code2];
+
+			if(freq[a] > freq[b]) {
+				if(leftc[code2] == code1)
+					rghtc[code2] = a;
+				else
+					leftc[code2] = a;
+
+				if(leftc[code1] == a) {
+					leftc[code1] = b;
+					c = rghtc[code1];
+				} else {
+					rghtc[code1] = b;
+					c = leftc[code1];
+				}
+
+				dad[b] = code1;
+				dad[a] = code2;
+				updatefreq(b,c);
+				a = b;
+			}
+
+			a = dad[a];
+			code1 = dad[a];
+		} while(code1 != ROOT);
+	}
+}
+
+unsigned short Ca2mLoader::inputcode(unsigned short bits)
+{
+	unsigned short i,code=0;
+
+	for(i=1;i<=bits;i++) {
+		if(!ibitcount) {
+			if(ibitcount == MAXBUF)
+				ibufcount = 0;
+			ibitbuffer = wdbuf[ibufcount];
+			ibufcount++;
+			ibitcount = 15;
+		} else
+			ibitcount--;
+
+		if(ibitbuffer > 0x7fff)
+			code |= bitvalue[i-1];
+		ibitbuffer <<= 1;
+	}
+
+	return code;
+}
+
+unsigned short Ca2mLoader::uncompress()
+{
+	unsigned short a=1;
+
+	do {
+		if(!ibitcount) {
+			if(ibufcount == MAXBUF)
+				ibufcount = 0;
+			ibitbuffer = wdbuf[ibufcount];
+			ibufcount++;
+			ibitcount = 15;
+		} else
+			ibitcount--;
+
+		if(ibitbuffer > 0x7fff)
+			a = rghtc[a];
+		else
+			a = leftc[a];
+		ibitbuffer <<= 1;
+	} while(a <= MAXCHAR);
+
+	a -= SUCCMAX;
+	updatemodel(a);
+	return a;
+}
+
+void Ca2mLoader::decode()
+{
+	unsigned short i,j,k,t,c,count=0,dist,len,index;
+
+	inittree();
+	c = uncompress();
+
+	while(c != TERMINATE) {
+		if(c < 256) {
+			obuf[obufcount] = (unsigned char)c;
+			obufcount++;
+			if(obufcount == MAXBUF) {
+				output_size = MAXBUF;
+				obufcount = 0;
+			}
+
+			buf[count] = (unsigned char)c;
+			count++;
+			if(count == MAXSIZE)
+				count = 0;
+		} else {
+			t = c - FIRSTCODE;
+			index = t / CODESPERRANGE;
+			len = t + MINCOPY - index * CODESPERRANGE;
+			dist = inputcode(copybits[index]) + len + copymin[index];
+
+			j = count;
+			k = count - dist;
+			if(count < dist)
+				k += MAXSIZE;
+
+			for(i=0;i<=len-1;i++) {
+				obuf[obufcount] = buf[k];
+				obufcount++;
+				if(obufcount == MAXBUF) {
+					output_size = MAXBUF;
+					obufcount = 0;
+				}
+
+				buf[j] = buf[k];
+				j++; k++;
+				if(j == MAXSIZE) j = 0;
+				if(k == MAXSIZE) k = 0;
+			}
+
+			count += len;
+			if(count >= MAXSIZE)
+				count -= MAXSIZE;
+		}
+		c = uncompress();
+	}
+	output_size = obufcount;
+}
+
+unsigned short Ca2mLoader::sixdepak(unsigned short *source, unsigned char *dest,
+				    unsigned short size)
+{
+	if((unsigned int)size + 4096 > MAXBUF)
+		return 0;
+
+	buf = new unsigned char [MAXSIZE];
+	input_size = size;
+	ibitcount = 0; ibitbuffer = 0;
+	obufcount = 0; ibufcount = 0;
+	wdbuf = source; obuf = dest;
+
+	decode();
+	delete [] buf;
+	return output_size;
+}
--- a/Plugins/Input/adplug/core/adl.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2427 +0,0 @@
-/*
- * adl.cpp - ADL player adaption by Simon Peter <dn.tlp@gmx.net>
- *
- * Original ADL player by Torbjorn Andersson and Johannes Schickel
- * 'lordhoto' <lordhoto at scummvm dot org> of the ScummVM project.
- */
-
-/* ScummVM - Scumm Interpreter
- *
- * This file is licensed under both GPL and LGPL
- * Copyright (C) 2006 The ScummVM project
- * Copyright (C) 2006 Torbjorn Andersson and Johannes Schickel
- *
- * GPL License
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * LPGL License
- *
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- */
-
-#include <inttypes.h>
-#include <stdarg.h>
-#include <assert.h>
-
-#include "adl.h"
-#include "debug.h"
-
-#ifdef ADL_DEBUG
-#	define warning(...)		AdPlug_LogWrite(__VA_ARGS__); \
-AdPlug_LogWrite("\n")
-
-#	define debugC(i1, i2, ...)	AdPlug_LogWrite(__VA_ARGS__); \
-AdPlug_LogWrite("\n")
-#else
-#	define kDebugLevelSound	1
-
-static inline void warning(const char *str, ...)
-{
-}
-
-static inline void debugC(int i1, int i2, const char *str, ...)
-{
-}
-#endif
-
-// #define warning(...)
-// #define debugC(i1, i2, ...)
-
-#define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0])))
-
-// Basic Adlib Programming:
-// http://www.gamedev.net/reference/articles/article446.asp
-
-#define CALLBACKS_PER_SECOND 72
-
-typedef uint8_t	uint8;
-typedef int8_t	int8;
-typedef uint16_t	uint16;
-typedef int16_t	int16;
-typedef uint32_t	uint32;
-typedef int32_t	int32;
-typedef uint8_t	byte;
-
-static inline uint16 READ_LE_UINT16(const void *ptr) {
-  const byte *b = (const byte *)ptr;
-  return (b[1] << 8) + b[0];
-}
-
-static inline uint16 READ_BE_UINT16(const void *ptr) {
-  const byte *b = (const byte *)ptr;
-  return (b[0] << 8) + b[1];
-}
-
-class AdlibDriver {
-public:
-  AdlibDriver(Copl *opl);
-  ~AdlibDriver();
-
-  int callback(int opcode, ...);
-  void callback();
-
-  // AudioStream API
-  // 	int readBuffer(int16 *buffer, const int numSamples) {
-  // 		int32 samplesLeft = numSamples;
-  // 		memset(buffer, 0, sizeof(int16) * numSamples);
-  // 		while (samplesLeft) {
-  // 			if (!_samplesTillCallback) {
-  // 				callback();
-  // 				_samplesTillCallback = _samplesPerCallback;
-  // 				_samplesTillCallbackRemainder += _samplesPerCallbackRemainder;
-  // 				if (_samplesTillCallbackRemainder >= CALLBACKS_PER_SECOND) {
-  // 					_samplesTillCallback++;
-  // 					_samplesTillCallbackRemainder -= CALLBACKS_PER_SECOND;
-  // 				}
-  // 			}
-
-  // 			int32 render = MIN(samplesLeft, _samplesTillCallback);
-  // 			samplesLeft -= render;
-  // 			_samplesTillCallback -= render;
-  // 			YM3812UpdateOne(_adlib, buffer, render);
-  // 			buffer += render;
-  // 		}
-  // 		return numSamples;
-  // 	}
-
-  bool isStereo() const { return false; }
-  bool endOfData() const { return false; }
-  // 	int getRate() const { return _mixer->getOutputRate(); }
-
-  struct OpcodeEntry {
-    typedef int (AdlibDriver::*DriverOpcode)(va_list &list);
-    DriverOpcode function;
-    const char *name;
-  };
-
-  void setupOpcodeList();
-  const OpcodeEntry *_opcodeList;
-  int _opcodesEntries;
-
-  int snd_ret0x100(va_list &list);
-  int snd_ret0x1983(va_list &list);
-  int snd_initDriver(va_list &list);
-  int snd_deinitDriver(va_list &list);
-  int snd_setSoundData(va_list &list);
-  int snd_unkOpcode1(va_list &list);
-  int snd_startSong(va_list &list);
-  int snd_unkOpcode2(va_list &list);
-  int snd_unkOpcode3(va_list &list);
-  int snd_readByte(va_list &list);
-  int snd_writeByte(va_list &list);
-  int snd_getSoundTrigger(va_list &list);
-  int snd_unkOpcode4(va_list &list);
-  int snd_dummy(va_list &list);
-  int snd_getNullvar4(va_list &list);
-  int snd_setNullvar3(va_list &list);
-  int snd_setFlag(va_list &list);
-  int snd_clearFlag(va_list &list);
-
-  // These variables have not yet been named, but some of them are partly
-  // known nevertheless:
-  //
-  // unk16 - Sound-related. Possibly some sort of pitch bend.
-  // unk18 - Sound-effect. Used for secondaryEffect1()
-  // unk19 - Sound-effect. Used for secondaryEffect1()
-  // unk20 - Sound-effect. Used for secondaryEffect1()
-  // unk21 - Sound-effect. Used for secondaryEffect1()
-  // unk22 - Sound-effect. Used for secondaryEffect1()
-  // unk29 - Sound-effect. Used for primaryEffect1()
-  // unk30 - Sound-effect. Used for primaryEffect1()
-  // unk31 - Sound-effect. Used for primaryEffect1()
-  // unk32 - Sound-effect. Used for primaryEffect2()
-  // unk33 - Sound-effect. Used for primaryEffect2()
-  // unk34 - Sound-effect. Used for primaryEffect2()
-  // unk35 - Sound-effect. Used for primaryEffect2()
-  // unk36 - Sound-effect. Used for primaryEffect2()
-  // unk37 - Sound-effect. Used for primaryEffect2()
-  // unk38 - Sound-effect. Used for primaryEffect2()
-  // unk39 - Currently unused, except for updateCallback56()
-  // unk40 - Currently unused, except for updateCallback56()
-  // unk41 - Sound-effect. Used for primaryEffect2()
-
-  struct Channel {
-    uint8 opExtraLevel2;
-    uint8 *dataptr;
-    uint8 duration;
-    uint8 repeatCounter;
-    int8 baseOctave;
-    uint8 priority;
-    uint8 dataptrStackPos;
-    uint8 *dataptrStack[4];
-    int8 baseNote;
-    uint8 unk29;
-    uint8 unk31;
-    uint16 unk30;
-    uint16 unk37;
-    uint8 unk33;
-    uint8 unk34;
-    uint8 unk35;
-    uint8 unk36;
-    uint8 unk32;
-    uint8 unk41;
-    uint8 unk38;
-    uint8 opExtraLevel1;
-    uint8 spacing2;
-    uint8 baseFreq;
-    uint8 tempo;
-    uint8 position;
-    uint8 regAx;
-    uint8 regBx;
-    typedef void (AdlibDriver::*Callback)(Channel&);
-    Callback primaryEffect;
-    Callback secondaryEffect;
-    uint8 fractionalSpacing;
-    uint8 opLevel1;
-    uint8 opLevel2;
-    uint8 opExtraLevel3;
-    uint8 twoChan;
-    uint8 unk39;	
-    uint8 unk40;
-    uint8 spacing1;
-    uint8 durationRandomness;
-    uint8 unk19;
-    uint8 unk18;
-    int8 unk20;
-    int8 unk21;
-    uint8 unk22;
-    uint16 offset;
-    uint8 tempoReset;
-    uint8 rawNote;
-    int8 unk16;
-  };
-
-  void primaryEffect1(Channel &channel);
-  void primaryEffect2(Channel &channel);
-  void secondaryEffect1(Channel &channel);
-
-  void resetAdlibState();
-  void writeOPL(byte reg, byte val);
-  void initChannel(Channel &channel);
-  void noteOff(Channel &channel);
-  void unkOutput2(uint8 num);
-
-  uint16 getRandomNr();
-  void setupDuration(uint8 duration, Channel &channel);
-
-  void setupNote(uint8 rawNote, Channel &channel, bool flag = false);
-  void setupInstrument(uint8 regOffset, uint8 *dataptr, Channel &channel);
-  void noteOn(Channel &channel);
-
-  void adjustVolume(Channel &channel);
-
-  uint8 calculateOpLevel1(Channel &channel);
-  uint8 calculateOpLevel2(Channel &channel);
-
-  uint16 checkValue(int16 val) {
-    if (val < 0)
-      val = 0;
-    else if (val > 0x3F)
-      val = 0x3F;
-    return val;
-  }
-
-  // The sound data has at least two lookup tables:
-  //
-  // * One for programs, starting at offset 0.
-  // * One for instruments, starting at offset 500.
-
-  uint8 *getProgram(int progId) {
-    return _soundData + READ_LE_UINT16(_soundData + 2 * progId);
-  }
-
-  uint8 *getInstrument(int instrumentId) {
-    return _soundData + READ_LE_UINT16(_soundData + 500 + 2 * instrumentId);
-  }
-
-  void setupPrograms();
-  void executePrograms();
-
-  struct ParserOpcode {
-    typedef int (AdlibDriver::*POpcode)(uint8 *&dataptr, Channel &channel, uint8 value);
-    POpcode function;
-    const char *name;
-  };
-
-  void setupParserOpcodeTable();
-  const ParserOpcode *_parserOpcodeTable;
-  int _parserOpcodeTableSize;
-
-  int update_setRepeat(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_checkRepeat(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setupProgram(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setNoteSpacing(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_jump(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_jumpToSubroutine(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_returnFromSubroutine(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setBaseOctave(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_stopChannel(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_playRest(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_writeAdlib(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setupNoteAndDuration(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setBaseNote(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setupSecondaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_stopOtherChannel(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_waitForEndOfProgram(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setupInstrument(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setupPrimaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_removePrimaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setBaseFreq(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setupPrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setPriority(uint8 *&dataptr, Channel &channel, uint8 value);
-  int updateCallback23(uint8 *&dataptr, Channel &channel, uint8 value);
-  int updateCallback24(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setExtraLevel1(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setupDuration(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_playNote(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setFractionalNoteSpacing(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setTempo(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_removeSecondaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setChannelTempo(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setExtraLevel3(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setExtraLevel2(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_changeExtraLevel2(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setAMDepth(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setVibratoDepth(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_changeExtraLevel1(uint8 *&dataptr, Channel &channel, uint8 value);
-  int updateCallback38(uint8 *&dataptr, Channel &channel, uint8 value);
-  int updateCallback39(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_removePrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value);
-  int updateCallback41(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_resetToGlobalTempo(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_nop1(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setDurationRandomness(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_changeChannelTempo(uint8 *&dataptr, Channel &channel, uint8 value);
-  int updateCallback46(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_nop2(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setupRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_playRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_removeRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value);
-  int updateCallback51(uint8 *&dataptr, Channel &channel, uint8 value);
-  int updateCallback52(uint8 *&dataptr, Channel &channel, uint8 value);
-  int updateCallback53(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setSoundTrigger(uint8 *&dataptr, Channel &channel, uint8 value);
-  int update_setTempoReset(uint8 *&dataptr, Channel &channel, uint8 value);
-  int updateCallback56(uint8 *&dataptr, Channel &channel, uint8 value);
-
-  // These variables have not yet been named, but some of them are partly
-  // known nevertheless:
-  //
-  // _unkValue1      - Unknown. Used for updating _unkValue2
-  // _unkValue2      - Unknown. Used for updating _unkValue4
-  // _unkValue3      - Unknown. Used for updating _unkValue2
-  // _unkValue4      - Unknown. Used for updating _unkValue5
-  // _unkValue5      - Unknown. Used for controlling updateCallback24().
-  // _unkValue6      - Unknown. Rhythm section volume?
-  // _unkValue7      - Unknown. Rhythm section volume?
-  // _unkValue8      - Unknown. Rhythm section volume?
-  // _unkValue9      - Unknown. Rhythm section volume?
-  // _unkValue10     - Unknown. Rhythm section volume?
-  // _unkValue11     - Unknown. Rhythm section volume?
-  // _unkValue12     - Unknown. Rhythm section volume?
-  // _unkValue13     - Unknown. Rhythm section volume?
-  // _unkValue14     - Unknown. Rhythm section volume?
-  // _unkValue15     - Unknown. Rhythm section volume?
-  // _unkValue16     - Unknown. Rhythm section volume?
-  // _unkValue17     - Unknown. Rhythm section volume?
-  // _unkValue18     - Unknown. Rhythm section volume?
-  // _unkValue19     - Unknown. Rhythm section volume?
-  // _unkValue20     - Unknown. Rhythm section volume?
-  // _unkTable[]     - Probably frequences for the 12-tone scale.
-  // _unkTable2[]    - Unknown. Currently only used by updateCallback46()
-  // _unkTable2_1[]  - One of the tables in _unkTable2[]
-  // _unkTable2_2[]  - One of the tables in _unkTable2[]
-  // _unkTable2_3[]  - One of the tables in _unkTable2[]
-
-  int32 _samplesPerCallback;
-  int32 _samplesPerCallbackRemainder;
-  int32 _samplesTillCallback;
-  int32 _samplesTillCallbackRemainder;
-
-  int _lastProcessed;
-  int8 _flagTrigger;
-  int _curChannel;
-  uint8 _soundTrigger;
-  int _soundsPlaying;
-
-  uint16 _rnd;
-
-  uint8 _unkValue1;
-  uint8 _unkValue2;
-  uint8 _unkValue3;
-  uint8 _unkValue4;
-  uint8 _unkValue5;
-  uint8 _unkValue6;
-  uint8 _unkValue7;
-  uint8 _unkValue8;
-  uint8 _unkValue9;
-  uint8 _unkValue10;
-  uint8 _unkValue11;
-  uint8 _unkValue12;
-  uint8 _unkValue13;
-  uint8 _unkValue14;
-  uint8 _unkValue15;
-  uint8 _unkValue16;
-  uint8 _unkValue17;
-  uint8 _unkValue18;
-  uint8 _unkValue19;
-  uint8 _unkValue20;
-
-  int _flags;
-
-  uint8 *_soundData;
-
-  uint8 _soundIdTable[0x10];
-  Channel _channels[10];
-
-  uint8 _vibratoAndAMDepthBits;
-  uint8 _rhythmSectionBits;
-
-  uint8 _curRegOffset;
-  uint8 _tempo;
-
-  const uint8 *_tablePtr1;
-  const uint8 *_tablePtr2;
-
-  static const uint8 _regOffset[];
-  static const uint16 _unkTable[];
-  static const uint8 *_unkTable2[];
-  static const uint8 _unkTable2_1[];
-  static const uint8 _unkTable2_2[];
-  static const uint8 _unkTable2_3[];
-  static const uint8 _unkTables[][32];
-
-  Copl *opl;
-};
-
-AdlibDriver::AdlibDriver(Copl *newopl)
-  : opl(newopl)
-{
-  setupOpcodeList();
-  setupParserOpcodeTable();
-
-  // 	_mixer = mixer;
-
-  _flags = 0;
-  // 	_adlib = makeAdlibOPL(getRate());
-  // 	assert(_adlib);
-
-  memset(_channels, 0, sizeof(_channels));
-  _soundData = 0;
-
-  _vibratoAndAMDepthBits = _curRegOffset = 0;
-
-  _lastProcessed = _flagTrigger = _curChannel = _rhythmSectionBits = 0;
-  _soundsPlaying = 0;
-  _rnd = 0x1234;
-
-  _tempo = 0;
-  _soundTrigger = 0;
-
-  _unkValue3 = 0xFF;
-  _unkValue1 = _unkValue2 = _unkValue4 = _unkValue5 = 0;
-  _unkValue6 = _unkValue7 = _unkValue8 = _unkValue9 = _unkValue10 = 0;
-  _unkValue11 = _unkValue12 = _unkValue13 = _unkValue14 = _unkValue15 =
-    _unkValue16 = _unkValue17 = _unkValue18 = _unkValue19 = _unkValue20 = 0;
-
-  _tablePtr1 = _tablePtr2 = 0;
-
-  // 	_mixer->setupPremix(this);
-
-  // 	_samplesPerCallback = getRate() / CALLBACKS_PER_SECOND;
-  // 	_samplesPerCallbackRemainder = getRate() % CALLBACKS_PER_SECOND;
-  _samplesTillCallback = 0;
-  _samplesTillCallbackRemainder = 0;
-}
-
-AdlibDriver::~AdlibDriver() {
-  // 	_mixer->setupPremix(0);
-  // 	OPLDestroy(_adlib);
-  // 	_adlib = 0;
-}
-
-int AdlibDriver::callback(int opcode, ...) {
-  // 	lock();
-  if (opcode >= _opcodesEntries || opcode < 0) {
-    warning("AdlibDriver: calling unknown opcode '%d'", opcode);
-    return 0;
-  }
-
-  debugC(9, kDebugLevelSound, "Calling opcode '%s' (%d)", _opcodeList[opcode].name, opcode);
-
-  va_list args;
-  va_start(args, opcode);
-  int returnValue = (this->*(_opcodeList[opcode].function))(args);
-  va_end(args);
-  // 	unlock();
-  return returnValue;
-}
-
-// Opcodes
-
-int AdlibDriver::snd_ret0x100(va_list &list) {
-  return 0x100;
-}
-
-int AdlibDriver::snd_ret0x1983(va_list &list) {
-  return 0x1983;
-}
-
-int AdlibDriver::snd_initDriver(va_list &list) {
-  _lastProcessed = _soundsPlaying = 0;
-  resetAdlibState();
-  return 0;
-}
-
-int AdlibDriver::snd_deinitDriver(va_list &list) {
-  resetAdlibState();
-  return 0;
-}
-
-int AdlibDriver::snd_setSoundData(va_list &list) {
-  if (_soundData) {
-    delete [] _soundData;
-    _soundData = 0;
-  }
-  _soundData = va_arg(list, uint8*);
-  return 0;
-}
-
-int AdlibDriver::snd_unkOpcode1(va_list &list) {
-  warning("unimplemented snd_unkOpcode1");
-  return 0;
-}
-
-int AdlibDriver::snd_startSong(va_list &list) {
-  int songId = va_arg(list, int);
-  _flags |= 8;
-  _flagTrigger = 1;
-
-  uint8 *ptr = getProgram(songId);
-  uint8 chan = *ptr;
-
-  if ((songId << 1) != 0) {
-    if (chan == 9) {
-      if (_flags & 2)
-	return 0;
-    } else {
-      if (_flags & 1)
-	return 0;
-    }
-  }
-
-  _soundIdTable[_soundsPlaying++] = songId;
-  _soundsPlaying &= 0x0F;
-
-  return 0;
-}
-
-int AdlibDriver::snd_unkOpcode2(va_list &list) {
-  warning("unimplemented snd_unkOpcode2");
-  return 0;
-}
-
-int AdlibDriver::snd_unkOpcode3(va_list &list) {
-  int value = va_arg(list, int);
-  int loop = value;
-  if (value < 0) {
-    value = 0;
-    loop = 9;
-  }
-  loop -= value;
-  ++loop;
-
-  while (loop--) {
-    _curChannel = value;
-    Channel &channel = _channels[_curChannel];
-    channel.priority = 0;
-    channel.dataptr = 0;
-    if (value != 9) {
-      noteOff(channel);
-    }
-    ++value;
-  }
-
-  return 0;
-}
-
-int AdlibDriver::snd_readByte(va_list &list) {
-  int a = va_arg(list, int);
-  int b = va_arg(list, int);
-  uint8 *ptr = getProgram(a) + b;
-  return *ptr;
-}
-
-int AdlibDriver::snd_writeByte(va_list &list) {
-  int a = va_arg(list, int);
-  int b = va_arg(list, int);
-  int c = va_arg(list, int);
-  uint8 *ptr = getProgram(a) + b;
-  uint8 oldValue = *ptr;
-  *ptr = (uint8)c;
-  return oldValue;
-}
-
-int AdlibDriver::snd_getSoundTrigger(va_list &list) {
-  return _soundTrigger;
-}
-
-int AdlibDriver::snd_unkOpcode4(va_list &list) {
-  warning("unimplemented snd_unkOpcode4");
-  return 0;
-}
-
-int AdlibDriver::snd_dummy(va_list &list) {
-  return 0;
-}
-
-int AdlibDriver::snd_getNullvar4(va_list &list) {
-  warning("unimplemented snd_getNullvar4");
-  return 0;
-}
-
-int AdlibDriver::snd_setNullvar3(va_list &list) {
-  warning("unimplemented snd_setNullvar3");
-  return 0;
-}
-
-int AdlibDriver::snd_setFlag(va_list &list) {
-  int oldFlags = _flags;
-  _flags |= va_arg(list, int);
-  return oldFlags;
-}
-
-int AdlibDriver::snd_clearFlag(va_list &list) {
-  int oldFlags = _flags;
-  _flags &= ~(va_arg(list, int));
-  return oldFlags;
-}
-
-// timer callback
-
-void AdlibDriver::callback() {
-  // 	lock();
-  --_flagTrigger;
-  if (_flagTrigger < 0)
-    _flags &= ~8;
-  setupPrograms();
-  executePrograms();
-
-  uint8 temp = _unkValue3;
-  _unkValue3 += _tempo;
-  if (_unkValue3 < temp) {
-    if (!(--_unkValue2)) {
-      _unkValue2 = _unkValue1;
-      ++_unkValue4;
-    }
-  }
-  // 	unlock();
-}
-
-void AdlibDriver::setupPrograms() {
-  while (_lastProcessed != _soundsPlaying) {
-    uint8 *ptr = getProgram(_soundIdTable[_lastProcessed]);
-    uint8 chan = *ptr++;
-    uint8 priority = *ptr++;
-
-    // Only start this sound if its priority is higher than the one
-    // already playing.
-
-    Channel &channel = _channels[chan];
-
-    if (priority >= channel.priority) {
-      initChannel(channel);
-      channel.priority = priority;
-      channel.dataptr = ptr;
-      channel.tempo = 0xFF;
-      channel.position = 0xFF;
-      channel.duration = 1;
-      unkOutput2(chan);
-    }
-
-    ++_lastProcessed;
-    _lastProcessed &= 0x0F;
-  }
-}
-
-// A few words on opcode parsing and timing:
-//
-// First of all, We simulate a timer callback 72 times per second. Each timeout
-// we update each channel that has something to play.
-//
-// Each channel has its own individual tempo, which is added to its position.
-// This will frequently cause the position to "wrap around" but that is
-// intentional. In fact, it's the signal to go ahead and do more stuff with
-// that channel.
-//
-// Each channel also has a duration, indicating how much time is left on the
-// its current task. This duration is decreased by one. As long as it still has
-// not reached zero, the only thing that can happen is that the note is turned
-// off depending on manual or automatic note spacing. Once the duration reaches
-// zero, a new set of musical opcodes are executed.
-//
-// An opcode is one byte, followed by a variable number of parameters. Since
-// most opcodes have at least one one-byte parameter, we read that as well. Any
-// opcode that doesn't have that one parameter is responsible for moving the
-// data pointer back again.
-//
-// If the most significant bit of the opcode is 1, it's a function; call it.
-// The opcode functions return either 0 (continue), 1 (stop) or 2 (stop, and do
-// not run the effects callbacks).
-//
-// If the most significant bit of the opcode is 0, it's a note, and the first
-// parameter is its duration. (There are cases where the duration is modified
-// but that's an exception.) The note opcode is assumed to return 1, and is the
-// last opcode unless its duration is zero.
-//
-// Finally, most of the times that the callback is called, it will invoke the
-// effects callbacks. The final opcode in a set can prevent this, if it's a
-// function and it returns anything other than 1.
-
-void AdlibDriver::executePrograms() {
-  // Each channel runs its own program. There are ten channels: One for
-  // each Adlib channel (0-8), plus one "control channel" (9) which is
-  // the one that tells the other channels what to do. 
-
-  for (_curChannel = 9; _curChannel >= 0; --_curChannel) {
-    int result = 1;
-
-    if (!_channels[_curChannel].dataptr) {
-      continue;
-    }
-	
-    Channel &channel = _channels[_curChannel];
-    _curRegOffset = _regOffset[_curChannel];
-
-    if (channel.tempoReset) {
-      channel.tempo = _tempo;
-    }
-
-    uint8 backup = channel.position;
-    channel.position += channel.tempo;
-    if (channel.position < backup) {
-      if (--channel.duration) {
-	if (channel.duration == channel.spacing2)
-	  noteOff(channel);
-	if (channel.duration == channel.spacing1 && _curChannel != 9)
-	  noteOff(channel);
-      } else {
-	// An opcode is not allowed to modify its own
-	// data pointer except through the 'dataptr'
-	// parameter. To enforce that, we have to work
-	// on a copy of the data pointer.
-	//
-	// This fixes a subtle music bug where the
-	// wrong music would play when getting the
-	// quill in Kyra 1.
-	uint8 *dataptr = channel.dataptr;
-	while (dataptr) {
-	  uint8 opcode = *dataptr++;
-	  uint8 param = *dataptr++;
-
-	  if (opcode & 0x80) {
-	    opcode &= 0x7F;
-	    if (opcode >= _parserOpcodeTableSize)
-	      opcode = _parserOpcodeTableSize - 1;
-	    debugC(9, kDebugLevelSound, "Calling opcode '%s' (%d) (channel: %d)", _parserOpcodeTable[opcode].name, opcode, _curChannel);
-	    result = (this->*(_parserOpcodeTable[opcode].function))(dataptr, channel, param);
-	    channel.dataptr = dataptr;
-	    if (result)
-	      break;
-	  } else {
-	    debugC(9, kDebugLevelSound, "Note on opcode 0x%02X (duration: %d) (channel: %d)", opcode, param, _curChannel);
-	    setupNote(opcode, channel);
-	    noteOn(channel);
-	    setupDuration(param, channel);
-	    if (param) {
-	      channel.dataptr = dataptr;
-	      break;
-	    }
-	  }
-	}
-      }
-    }
-
-    if (result == 1) {
-      if (channel.primaryEffect)
-	(this->*(channel.primaryEffect))(channel);
-      if (channel.secondaryEffect)
-	(this->*(channel.secondaryEffect))(channel);
-    }
-  }
-}
-
-// 
-
-void AdlibDriver::resetAdlibState() {
-  debugC(9, kDebugLevelSound, "resetAdlibState()");
-  _rnd = 0x1234;
-
-  // Authorize the control of the waveforms
-  writeOPL(0x01, 0x20);
-
-  // Select FM music mode
-  writeOPL(0x08, 0x00);
-
-  // I would guess the main purpose of this is to turn off the rhythm,
-  // thus allowing us to use 9 melodic voices instead of 6.
-  writeOPL(0xBD, 0x00);
-
-  int loop = 10;
-  while (loop--) {
-    if (loop != 9) {
-      // Silence the channel
-      writeOPL(0x40 + _regOffset[loop], 0x3F);
-      writeOPL(0x43 + _regOffset[loop], 0x3F);
-    }
-    initChannel(_channels[loop]);
-  }
-}
-
-// Old calling style: output0x388(0xABCD)
-// New calling style: writeOPL(0xAB, 0xCD)
-
-void AdlibDriver::writeOPL(byte reg, byte val) {
-  opl->write(reg, val);
-}
-
-void AdlibDriver::initChannel(Channel &channel) {
-  debugC(9, kDebugLevelSound, "initChannel(%lu)", (long)(&channel - _channels));
-  memset(&channel.dataptr, 0, sizeof(Channel) - ((char*)&channel.dataptr - (char*)&channel));
-
-  channel.tempo = 0xFF;
-  channel.priority = 0;
-  // normally here are nullfuncs but we set 0 for now
-  channel.primaryEffect = 0;
-  channel.secondaryEffect = 0;
-  channel.spacing1 = 1;
-}
-
-void AdlibDriver::noteOff(Channel &channel) {
-  debugC(9, kDebugLevelSound, "noteOff(%lu)", (long)(&channel - _channels));
-
-  // The control channel has no corresponding Adlib channel
-
-  if (_curChannel >= 9)
-    return;
-
-  // When the rhythm section is enabled, channels 6, 7 and 8 are special.
-
-  if (_rhythmSectionBits && _curChannel >= 6)
-    return;
-
-  // This means the "Key On" bit will always be 0
-  channel.regBx &= 0xDF;
-
-  // Octave / F-Number / Key-On
-  writeOPL(0xB0 + _curChannel, channel.regBx);
-}
-
-void AdlibDriver::unkOutput2(uint8 chan) {
-  debugC(9, kDebugLevelSound, "unkOutput2(%d)", chan);
-
-  // The control channel has no corresponding Adlib channel
-
-  if (chan >= 9)
-    return;
-
-  // I believe this has to do with channels 6, 7, and 8 being special
-  // when Adlib's rhythm section is enabled.
-
-  if (_rhythmSectionBits && chan >= 6)
-    return;
-
-  uint8 offset = _regOffset[chan];
-
-  // The channel is cleared: First the attack/delay rate, then the
-  // sustain level/release rate, and finally the note is turned off.
-
-  writeOPL(0x60 + offset, 0xFF);
-  writeOPL(0x63 + offset, 0xFF);
-
-  writeOPL(0x80 + offset, 0xFF);
-  writeOPL(0x83 + offset, 0xFF);
-
-  writeOPL(0xB0 + chan, 0x00);
-
-  // ...and then the note is turned on again, with whatever value is
-  // still lurking in the A0 + chan register, but everything else -
-  // including the two most significant frequency bit, and the octave -
-  // set to zero.
-  //
-  // This is very strange behaviour, and causes problems with the ancient
-  // FMOPL code we borrowed from AdPlug. I've added a workaround. See
-  // fmopl.cpp for more details.
-  //
-  // More recent versions of the MAME FMOPL don't seem to have this
-  // problem, but cannot currently be used because of licensing and
-  // performance issues.
-  //
-  // Ken Silverman's Adlib emulator (which can be found on his Web page -
-  // http://www.advsys.net/ken - and as part of AdPlug) also seems to be
-  // immune, but is apparently not as feature complete as MAME's.
-
-  writeOPL(0xB0 + chan, 0x20);
-}
-
-// I believe this is a random number generator. It actually does seem to
-// generate an even distribution of almost all numbers from 0 through 65535,
-// though in my tests some numbers were never generated.
-
-uint16 AdlibDriver::getRandomNr() {
-  _rnd += 0x9248;
-  uint16 lowBits = _rnd & 7;
-  _rnd >>= 3;
-  _rnd |= (lowBits << 13);
-  return _rnd;
-}
-
-void AdlibDriver::setupDuration(uint8 duration, Channel &channel) {
-  debugC(9, kDebugLevelSound, "setupDuration(%d, %lu)", duration, (long)(&channel - _channels));
-  if (channel.durationRandomness) {
-    channel.duration = duration + (getRandomNr() & channel.durationRandomness);
-    return;
-  }
-  if (channel.fractionalSpacing) {
-    channel.spacing2 = (duration >> 3) * channel.fractionalSpacing;
-  }
-  channel.duration = duration;
-}
-
-// This function may or may not play the note. It's usually followed by a call
-// to noteOn(), which will always play the current note.
-
-void AdlibDriver::setupNote(uint8 rawNote, Channel &channel, bool flag) {
-  debugC(9, kDebugLevelSound, "setupNote(%d, %lu)", rawNote, (long)(&channel - _channels));
-
-  channel.rawNote = rawNote;
-
-  int8 note = (rawNote & 0x0F) + channel.baseNote;
-  int8 octave = ((rawNote + channel.baseOctave) >> 4) & 0x0F;
-
-  // There are only twelve notes. If we go outside that, we have to
-  // adjust the note and octave.
-
-  if (note >= 12) {
-    note -= 12;
-    octave++;
-  } else if (note < 0) {
-    note += 12;
-    octave--;
-  }
-
-  // The calculation of frequency looks quite different from the original
-  // disassembly at a first glance, but when you consider that the
-  // largest possible value would be 0x0246 + 0xFF + 0x47 (and that's if
-  // baseFreq is unsigned), freq is still a 10-bit value, just as it
-  // should be to fit in the Ax and Bx registers.
-  //
-  // If it were larger than that, it could have overflowed into the
-  // octave bits, and that could possibly have been used in some sound.
-  // But as it is now, I can't see any way it would happen.
-
-  uint16 freq = _unkTable[note] + channel.baseFreq;
-
-  // When called from callback 41, the behaviour is slightly different:
-  // We adjust the frequency, even when channel.unk16 is 0.
-
-  if (channel.unk16 || flag) {
-    const uint8 *table;
-
-    if (channel.unk16 >= 0) {
-      table = _unkTables[(channel.rawNote & 0x0F) + 2];
-      freq += table[channel.unk16];
-    } else {
-      table = _unkTables[channel.rawNote & 0x0F];
-      freq -= table[-channel.unk16];
-    }
-  }
-
-  channel.regAx = freq & 0xFF;
-  channel.regBx = (channel.regBx & 0x20) | (octave << 2) | ((freq >> 8) & 0x03);
-
-  // Keep the note on or off
-  writeOPL(0xA0 + _curChannel, channel.regAx);
-  writeOPL(0xB0 + _curChannel, channel.regBx);
-}
-
-void AdlibDriver::setupInstrument(uint8 regOffset, uint8 *dataptr, Channel &channel) {
-  debugC(9, kDebugLevelSound, "setupInstrument(%d, %p, %lu)", regOffset, (const void *)dataptr, (long)(&channel - _channels));
-  // Amplitude Modulation / Vibrato / Envelope Generator Type /
-  // Keyboard Scaling Rate / Modulator Frequency Multiple
-  writeOPL(0x20 + regOffset, *dataptr++);
-  writeOPL(0x23 + regOffset, *dataptr++);
-
-  uint8 temp = *dataptr++;
-
-  // Feedback / Algorithm
-
-  // It is very likely that _curChannel really does refer to the same
-  // channel as regOffset, but there's only one Cx register per channel.
-
-  writeOPL(0xC0 + _curChannel, temp);
-
-  // The algorithm bit. I don't pretend to understand this fully, but
-  // "If set to 0, operator 1 modulates operator 2. In this case,
-  // operator 2 is the only one producing sound. If set to 1, both
-  // operators produce sound directly. Complex sounds are more easily
-  // created if the algorithm is set to 0."
-
-  channel.twoChan = temp & 1;
-
-  // Waveform Select
-  writeOPL(0xE0 + regOffset, *dataptr++);
-  writeOPL(0xE3 + regOffset, *dataptr++);
-
-  channel.opLevel1 = *dataptr++;
-  channel.opLevel2 = *dataptr++;
-
-  // Level Key Scaling / Total Level
-  writeOPL(0x40 + regOffset, calculateOpLevel1(channel));
-  writeOPL(0x43 + regOffset, calculateOpLevel2(channel));
-
-  // Attack Rate / Decay Rate
-  writeOPL(0x60 + regOffset, *dataptr++);
-  writeOPL(0x63 + regOffset, *dataptr++);
-
-  // Sustain Level / Release Rate
-  writeOPL(0x80 + regOffset, *dataptr++);
-  writeOPL(0x83 + regOffset, *dataptr++);
-}
-
-// Apart from playing the note, this function also updates the variables for
-// primary effect 2.
-
-void AdlibDriver::noteOn(Channel &channel) {
-  debugC(9, kDebugLevelSound, "noteOn(%lu)", (long)(&channel - _channels));
-
-  // The "note on" bit is set, and the current note is played.
-
-  channel.regBx |= 0x20;
-  writeOPL(0xB0 + _curChannel, channel.regBx);
-
-  int8 shift = 9 - channel.unk33;
-  uint16 temp = channel.regAx | (channel.regBx << 8);
-  channel.unk37 = ((temp & 0x3FF) >> shift) & 0xFF;
-  channel.unk38 = channel.unk36;
-}
-
-void AdlibDriver::adjustVolume(Channel &channel) {
-  debugC(9, kDebugLevelSound, "adjustVolume(%lu)", (long)(&channel - _channels));
-  // Level Key Scaling / Total Level
-
-  writeOPL(0x43 + _regOffset[_curChannel], calculateOpLevel2(channel));
-  if (channel.twoChan)
-    writeOPL(0x40 + _regOffset[_curChannel], calculateOpLevel1(channel));
-}
-
-// This is presumably only used for some sound effects, e.g. Malcolm blowing up
-// the trees in the intro (but not the effect where he "booby-traps" the big
-// tree) and turning Kallak to stone. Related functions and variables:
-//
-// update_setupPrimaryEffect1()
-//    - Initialises unk29, unk30 and unk31
-//    - unk29 is not further modified
-//    - unk30 is not further modified, except by update_removePrimaryEffect1()
-//
-// update_removePrimaryEffect1()
-//    - Deinitialises unk30
-//
-// unk29 - determines how often the notes are played
-// unk30 - modifies the frequency
-// unk31 - determines how often the notes are played
-
-void AdlibDriver::primaryEffect1(Channel &channel) {
-  debugC(9, kDebugLevelSound, "Calling primaryEffect1 (channel: %d)", _curChannel);
-  uint8 temp = channel.unk31;
-  channel.unk31 += channel.unk29;
-  if (channel.unk31 >= temp)
-    return;
-
-  // Initialise unk1 to the current frequency
-  uint16 unk1 = ((channel.regBx & 3) << 8) | channel.regAx;
-
-  // This is presumably to shift the "note on" bit so far to the left
-  // that it won't be affected by any of the calculations below.
-  uint16 unk2 = ((channel.regBx & 0x20) << 8) | (channel.regBx & 0x1C);
-
-  int16 unk3 = (int16)channel.unk30;
-
-  if (unk3 >= 0) {
-    unk1 += unk3;
-    if (unk1 >= 734) {
-      // The new frequency is too high. Shift it down and go
-      // up one octave.
-      unk1 >>= 1;
-      if (!(unk1 & 0x3FF))
-	++unk1;
-      unk2 = (unk2 & 0xFF00) | ((unk2 + 4) & 0xFF);
-      unk2 &= 0xFF1C;
-    }
-  } else {
-    unk1 += unk3;
-    if (unk1 < 388) {
-      // The new frequency is too low. Shift it up and go
-      // down one octave.
-      unk1 <<= 1;
-      if (!(unk1 & 0x3FF))
-	--unk1;
-      unk2 = (unk2 & 0xFF00) | ((unk2 - 4) & 0xFF);
-      unk2 &= 0xFF1C;
-    }
-  }
-
-  // Make sure that the new frequency is still a 10-bit value.
-  unk1 &= 0x3FF;
-
-  writeOPL(0xA0 + _curChannel, unk1 & 0xFF);
-  channel.regAx = unk1 & 0xFF;
-
-  // Shift down the "note on" bit again.
-  uint8 value = unk1 >> 8;
-  value |= (unk2 >> 8) & 0xFF;
-  value |= unk2 & 0xFF;
-
-  writeOPL(0xB0 + _curChannel, value);
-  channel.regBx = value;
-}
-
-// This is presumably only used for some sound effects, e.g. Malcolm entering
-// and leaving Kallak's hut. Related functions and variables:
-//
-// update_setupPrimaryEffect2()
-//    - Initialises unk32, unk33, unk34, unk35 and unk36
-//    - unk32 is not further modified
-//    - unk33 is not further modified
-//    - unk34 is a countdown that gets reinitialised to unk35 on zero
-//    - unk35 is based on unk34 and not further modified
-//    - unk36 is not further modified
-//
-// noteOn()
-//    - Plays the current note
-//    - Updates unk37 with a new (lower?) frequency
-//    - Copies unk36 to unk38. The unk38 variable is a countdown.
-//
-// unk32 - determines how often the notes are played
-// unk33 - modifies the frequency
-// unk34 - countdown, updates frequency on zero
-// unk35 - initialiser for unk34 countdown
-// unk36 - initialiser for unk38 countdown
-// unk37 - frequency
-// unk38 - countdown, begins playing on zero
-// unk41 - determines how often the notes are played
-//
-// Note that unk41 is never initialised. Not that it should matter much, but it
-// is a bit sloppy.
-
-void AdlibDriver::primaryEffect2(Channel &channel) {
-  debugC(9, kDebugLevelSound, "Calling primaryEffect2 (channel: %d)", _curChannel);
-  if (channel.unk38) {
-    --channel.unk38;
-    return;
-  }
-
-  uint8 temp = channel.unk41;
-  channel.unk41 += channel.unk32;
-  if (channel.unk41 < temp) {
-    uint16 unk1 = channel.unk37;
-    if (!(--channel.unk34)) {
-      unk1 ^= 0xFFFF;
-      ++unk1;
-      channel.unk37 = unk1;
-      channel.unk34 = channel.unk35;
-    }
-
-    uint16 unk2 = (channel.regAx | (channel.regBx << 8)) & 0x3FF;
-    unk2 += unk1;
-		
-    channel.regAx = unk2 & 0xFF;
-    channel.regBx = (channel.regBx & 0xFC) | (unk2 >> 8);
-
-    // Octave / F-Number / Key-On
-    writeOPL(0xA0 + _curChannel, channel.regAx);
-    writeOPL(0xB0 + _curChannel, channel.regBx);
-  }
-}
-
-// I don't know where this is used. The same operation is performed several
-// times on the current channel, using a chunk of the _soundData[] buffer for
-// parameters. The parameters are used starting at the end of the chunk.
-//
-// Since we use _curRegOffset to specify the final register, it's quite
-// unlikely that this function is ever used to play notes. It's probably only
-// used to modify the sound. Another thing that supports this idea is that it
-// can be combined with any of the effects callbacks above.
-//
-// Related functions and variables:
-//
-// update_setupSecondaryEffect1()
-//    - Initialies unk18, unk19, unk20, unk21, unk22 and offset
-//    - unk19 is not further modified
-//    - unk20 is not further modified
-//    - unk22 is not further modified
-//    - offset is not further modified
-//
-// unk18 -  determines how often the operation is performed
-// unk19 -  determines how often the operation is performed
-// unk20 -  the start index into the data chunk
-// unk21 -  the current index into the data chunk
-// unk22 -  the operation to perform
-// offset - the offset to the data chunk
-
-void AdlibDriver::secondaryEffect1(Channel &channel) {
-  debugC(9, kDebugLevelSound, "Calling secondaryEffect1 (channel: %d)", _curChannel);
-  uint8 temp = channel.unk18;
-  channel.unk18 += channel.unk19;
-  if (channel.unk18 < temp) {
-    if (--channel.unk21 < 0) {
-      channel.unk21 = channel.unk20;
-    }
-    writeOPL(channel.unk22 + _curRegOffset, _soundData[channel.offset + channel.unk21]);
-  }
-}
-
-uint8 AdlibDriver::calculateOpLevel1(Channel &channel) {
-  int8 value = channel.opLevel1 & 0x3F;
-
-  if (channel.twoChan) {
-    value += channel.opExtraLevel1;
-    value += channel.opExtraLevel2;
-    value += channel.opExtraLevel3;
-  }
-
-  // Preserve the scaling level bits from opLevel1
-
-  return checkValue(value) | (channel.opLevel1 & 0xC0);
-}
-
-uint8 AdlibDriver::calculateOpLevel2(Channel &channel) {
-  int8 value = channel.opLevel2 & 0x3F;
-
-  value += channel.opExtraLevel1;
-  value += channel.opExtraLevel2;
-  value += channel.opExtraLevel3;
-
-  // Preserve the scaling level bits from opLevel2
-
-  return checkValue(value) | (channel.opLevel2 & 0xC0);
-}
-
-// parser opcodes
-
-int AdlibDriver::update_setRepeat(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.repeatCounter = value;
-  return 0;
-}
-
-int AdlibDriver::update_checkRepeat(uint8 *&dataptr, Channel &channel, uint8 value) {
-  ++dataptr;
-  if (--channel.repeatCounter) {
-    int16 add = READ_LE_UINT16(dataptr - 2);
-    dataptr += add;
-  }
-  return 0;
-}
-
-int AdlibDriver::update_setupProgram(uint8 *&dataptr, Channel &channel, uint8 value) {
-  if (value == 0xFF)
-    return 0;
-
-  uint8 *ptr = getProgram(value);
-  uint8 chan = *ptr++;
-  uint8 priority = *ptr++;
-
-  Channel &channel2 = _channels[chan];
-
-  if (priority >= channel2.priority) {
-    _flagTrigger = 1;
-    _flags |= 8;
-    initChannel(channel2);
-    channel2.priority = priority;
-    channel2.dataptr = ptr;
-    channel2.tempo = 0xFF;
-    channel2.position = 0xFF;
-    channel2.duration = 1;
-    unkOutput2(chan);
-  }
-
-  return 0;
-}
-
-int AdlibDriver::update_setNoteSpacing(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.spacing1 = value;
-  return 0;
-}
-
-int AdlibDriver::update_jump(uint8 *&dataptr, Channel &channel, uint8 value) {
-  --dataptr;
-  int16 add = READ_LE_UINT16(dataptr); dataptr += 2;
-  dataptr += add;
-  return 0;
-}
-
-int AdlibDriver::update_jumpToSubroutine(uint8 *&dataptr, Channel &channel, uint8 value) {
-  --dataptr;
-  int16 add = READ_LE_UINT16(dataptr); dataptr += 2;
-  channel.dataptrStack[channel.dataptrStackPos++] = dataptr;
-  dataptr += add;
-  return 0;
-}
-
-int AdlibDriver::update_returnFromSubroutine(uint8 *&dataptr, Channel &channel, uint8 value) {
-  dataptr = channel.dataptrStack[--channel.dataptrStackPos];
-  return 0;
-}
-
-int AdlibDriver::update_setBaseOctave(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.baseOctave = value;
-  return 0;
-}
-
-int AdlibDriver::update_stopChannel(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.priority = 0;
-  if (_curChannel != 9) {
-    noteOff(channel);
-  }
-  dataptr = 0;
-  return 2;
-}
-
-int AdlibDriver::update_playRest(uint8 *&dataptr, Channel &channel, uint8 value) {
-  setupDuration(value, channel);
-  noteOff(channel);
-  return (value != 0);
-}
-
-int AdlibDriver::update_writeAdlib(uint8 *&dataptr, Channel &channel, uint8 value) {
-  writeOPL(value, *dataptr++);
-  return 0;
-}
-
-int AdlibDriver::update_setupNoteAndDuration(uint8 *&dataptr, Channel &channel, uint8 value) {
-  setupNote(value, channel);
-  value = *dataptr++;
-  setupDuration(value, channel);
-  return (value != 0);
-}
-
-int AdlibDriver::update_setBaseNote(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.baseNote = value;
-  return 0;
-}
-
-int AdlibDriver::update_setupSecondaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.unk18 = value;
-  channel.unk19 = value;
-  channel.unk20 = channel.unk21 = *dataptr++;
-  channel.unk22 = *dataptr++;
-  channel.offset = READ_LE_UINT16(dataptr); dataptr += 2;
-  channel.secondaryEffect = &AdlibDriver::secondaryEffect1;
-  return 0;
-}
-
-int AdlibDriver::update_stopOtherChannel(uint8 *&dataptr, Channel &channel, uint8 value) {
-  Channel &channel2 = _channels[value];
-  channel2.duration = 0;
-  channel2.priority = 0;
-  channel2.dataptr = 0;
-  return 0;
-}
-
-int AdlibDriver::update_waitForEndOfProgram(uint8 *&dataptr, Channel &channel, uint8 value) {
-  uint8 *ptr = getProgram(value);
-  uint8 chan = *ptr;
-
-  if (!_channels[chan].dataptr) {
-    return 0;
-  }
-
-  dataptr -= 2;
-  return 2;
-}
-
-int AdlibDriver::update_setupInstrument(uint8 *&dataptr, Channel &channel, uint8 value) {
-  setupInstrument(_curRegOffset, getInstrument(value), channel);
-  return 0;
-}
-
-int AdlibDriver::update_setupPrimaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.unk29 = value;
-  channel.unk30 = READ_BE_UINT16(dataptr);
-  dataptr += 2;
-  channel.primaryEffect = &AdlibDriver::primaryEffect1;
-  channel.unk31 = 0xFF;
-  return 0;
-}
-
-int AdlibDriver::update_removePrimaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value) {
-  --dataptr;
-  channel.primaryEffect = 0;
-  channel.unk30 = 0;
-  return 0;
-}
-
-int AdlibDriver::update_setBaseFreq(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.baseFreq = value;
-  return 0;
-}
-
-int AdlibDriver::update_setupPrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.unk32 = value;
-  channel.unk33 = *dataptr++;
-  uint8 temp = *dataptr++;
-  channel.unk34 = temp + 1;
-  channel.unk35 = temp << 1;
-  channel.unk36 = *dataptr++;
-  channel.primaryEffect = &AdlibDriver::primaryEffect2;
-  return 0;
-}
-
-int AdlibDriver::update_setPriority(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.priority = value;
-  return 0;
-}
-
-int AdlibDriver::updateCallback23(uint8 *&dataptr, Channel &channel, uint8 value) {
-  value >>= 1;
-  _unkValue1 = _unkValue2 = value;
-  _unkValue3 = 0xFF;
-  _unkValue4 = _unkValue5 = 0;
-  return 0;
-}
-
-int AdlibDriver::updateCallback24(uint8 *&dataptr, Channel &channel, uint8 value) {
-  if (_unkValue5) {
-    if (_unkValue4 & value) {
-      _unkValue5 = 0;
-      return 0;
-    }
-  }
-
-  if (!(value & _unkValue4)) {
-    ++_unkValue5;
-  }
-
-  dataptr -= 2;
-  channel.duration = 1;
-  return 2;
-}
-
-int AdlibDriver::update_setExtraLevel1(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.opExtraLevel1 = value;
-  adjustVolume(channel);
-  return 0;
-}
-
-int AdlibDriver::update_setupDuration(uint8 *&dataptr, Channel &channel, uint8 value) {
-  setupDuration(value, channel);
-  return (value != 0);
-}
-
-int AdlibDriver::update_playNote(uint8 *&dataptr, Channel &channel, uint8 value) {
-  setupDuration(value, channel);
-  noteOn(channel);
-  return (value != 0);
-}
-
-int AdlibDriver::update_setFractionalNoteSpacing(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.fractionalSpacing = value & 7;
-  return 0;
-}
-
-int AdlibDriver::update_setTempo(uint8 *&dataptr, Channel &channel, uint8 value) {
-  _tempo = value;
-  return 0;
-}
-
-int AdlibDriver::update_removeSecondaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value) {
-  --dataptr;
-  channel.secondaryEffect = 0;
-  return 0;
-}
-
-int AdlibDriver::update_setChannelTempo(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.tempo = value;
-  return 0;
-}
-
-int AdlibDriver::update_setExtraLevel3(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.opExtraLevel3 = value;
-  return 0;
-}
-
-int AdlibDriver::update_setExtraLevel2(uint8 *&dataptr, Channel &channel, uint8 value) {
-  int channelBackUp = _curChannel;
-
-  _curChannel = value;
-  Channel &channel2 = _channels[value];
-  channel2.opExtraLevel2 = *dataptr++;
-  adjustVolume(channel2);
-
-  _curChannel = channelBackUp;
-  return 0;
-}
-
-int AdlibDriver::update_changeExtraLevel2(uint8 *&dataptr, Channel &channel, uint8 value) {
-  int channelBackUp = _curChannel;
-
-  _curChannel = value;
-  Channel &channel2 = _channels[value];
-  channel2.opExtraLevel2 += *dataptr++;
-  adjustVolume(channel2);
-
-  _curChannel = channelBackUp;
-  return 0;
-}
-
-// Apart from initialising to zero, these two functions are the only ones that
-// modify _vibratoAndAMDepthBits.
-
-int AdlibDriver::update_setAMDepth(uint8 *&dataptr, Channel &channel, uint8 value) {
-  if (value & 1)
-    _vibratoAndAMDepthBits |= 0x80;
-  else
-    _vibratoAndAMDepthBits &= 0x7F;
-
-  writeOPL(0xBD, _vibratoAndAMDepthBits);
-  return 0;
-}
-
-int AdlibDriver::update_setVibratoDepth(uint8 *&dataptr, Channel &channel, uint8 value) {
-  if (value & 1)
-    _vibratoAndAMDepthBits |= 0x40;
-  else
-    _vibratoAndAMDepthBits &= 0xBF;
-
-  writeOPL(0xBD, _vibratoAndAMDepthBits);
-  return 0;
-}
-
-int AdlibDriver::update_changeExtraLevel1(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.opExtraLevel1 += value;
-  adjustVolume(channel);
-  return 0;
-}
-
-int AdlibDriver::updateCallback38(uint8 *&dataptr, Channel &channel, uint8 value) {
-  int channelBackUp = _curChannel;
-
-  _curChannel = value;
-  Channel &channel2 = _channels[value];
-  channel2.duration = channel2.priority = 0;
-  channel2.dataptr = 0;
-  channel2.opExtraLevel2 = 0;
-
-  if (value != 9) {
-    uint8 outValue = _regOffset[value];
-
-    // Feedback strength / Connection type
-    writeOPL(0xC0 + _curChannel, 0x00);
-
-    // Key scaling level / Operator output level
-    writeOPL(0x43 + outValue, 0x3F);
-
-    // Sustain Level / Release Rate
-    writeOPL(0x83 + outValue, 0xFF);
-
-    // Key On / Octave / Frequency
-    writeOPL(0xB0 + _curChannel, 0x00);
-  }
-
-  _curChannel = channelBackUp;
-  return 0;
-}
-
-int AdlibDriver::updateCallback39(uint8 *&dataptr, Channel &channel, uint8 value) {
-  uint16 unk = *dataptr++;
-  unk |= value << 8;
-  unk &= getRandomNr();
-
-  uint16 unk2 = ((channel.regBx & 0x1F) << 8) | channel.regAx;
-  unk2 += unk;
-  unk2 |= ((channel.regBx & 0x20) << 8);
-
-  // Frequency
-  writeOPL(0xA0 + _curChannel, unk2 & 0xFF);
-
-  // Key On / Octave / Frequency
-  writeOPL(0xB0 + _curChannel, (unk2 & 0xFF00) >> 8);
-
-  return 0;
-}
-
-int AdlibDriver::update_removePrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value) {
-  --dataptr;
-  channel.primaryEffect = 0;
-  return 0;
-}
-
-int AdlibDriver::updateCallback41(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.unk16 = value;
-  setupNote(channel.rawNote, channel, true);
-  return 0;
-}
-
-int AdlibDriver::update_resetToGlobalTempo(uint8 *&dataptr, Channel &channel, uint8 value) {
-  --dataptr;
-  channel.tempo = _tempo;
-  return 0;
-}
-
-int AdlibDriver::update_nop1(uint8 *&dataptr, Channel &channel, uint8 value) {
-  --dataptr;
-  return 0;
-}
-
-int AdlibDriver::update_setDurationRandomness(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.durationRandomness = value;
-  return 0;
-}
-
-int AdlibDriver::update_changeChannelTempo(uint8 *&dataptr, Channel &channel, uint8 value) {
-  int tempo = channel.tempo + (int8)value;
-
-  if (tempo <= 0)
-    tempo = 1;
-  else if (tempo > 255)
-    tempo = 255;
-
-  channel.tempo = tempo;
-  return 0;
-}
-
-int AdlibDriver::updateCallback46(uint8 *&dataptr, Channel &channel, uint8 value) {
-  uint8 entry = *dataptr++;
-  _tablePtr1 = _unkTable2[entry++];
-  _tablePtr2 = _unkTable2[entry];
-  if (value == 2) {
-    // Frequency
-    writeOPL(0xA0, _tablePtr2[0]);
-  }
-  return 0;
-}
-
-// TODO: This is really the same as update_nop1(), so they should be combined
-//       into one single update_nop().
-
-int AdlibDriver::update_nop2(uint8 *&dataptr, Channel &channel, uint8 value) {
-  --dataptr;
-  return 0;
-}
-
-int AdlibDriver::update_setupRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value) {
-  int channelBackUp = _curChannel;
-  int regOffsetBackUp = _curRegOffset;
-
-  _curChannel = 6;
-  _curRegOffset = _regOffset[6];
-
-  setupInstrument(_curRegOffset, getInstrument(value), channel);
-  _unkValue6 = channel.opLevel2;
-
-  _curChannel = 7;
-  _curRegOffset = _regOffset[7];
-
-  setupInstrument(_curRegOffset, getInstrument(*dataptr++), channel);
-  _unkValue7 = channel.opLevel1;
-  _unkValue8 = channel.opLevel2;
-
-  _curChannel = 8;
-  _curRegOffset = _regOffset[8];
-
-  setupInstrument(_curRegOffset, getInstrument(*dataptr++), channel);
-  _unkValue9 = channel.opLevel1;
-  _unkValue10 = channel.opLevel2;
-
-  // Octave / F-Number / Key-On for channels 6, 7 and 8
-
-  _channels[6].regBx = *dataptr++ & 0x2F;
-  writeOPL(0xB6, _channels[6].regBx);
-  writeOPL(0xA6, *dataptr++);
-
-  _channels[7].regBx = *dataptr++ & 0x2F;
-  writeOPL(0xB7, _channels[7].regBx);
-  writeOPL(0xA7, *dataptr++);
-
-  _channels[8].regBx = *dataptr++ & 0x2F;
-  writeOPL(0xB8, _channels[8].regBx);
-  writeOPL(0xA8, *dataptr++);
-
-  _rhythmSectionBits = 0x20;
-
-  _curRegOffset = regOffsetBackUp;
-  _curChannel = channelBackUp;
-  return 0;
-}
-
-int AdlibDriver::update_playRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value) {
-  // Any instrument that we want to play, and which was already playing,
-  // is temporarily keyed off. Instruments that were off already, or
-  // which we don't want to play, retain their old on/off status. This is
-  // probably so that the instrument's envelope is played from its
-  // beginning again...
-
-  writeOPL(0xBD, (_rhythmSectionBits & ~(value & 0x1F)) | 0x20);
-
-  // ...but since we only set the rhythm instrument bits, and never clear
-  // them (until the entire rhythm section is disabled), I'm not sure how
-  // useful the cleverness above is. We could perhaps simply turn off all
-  // the rhythm instruments instead.
-
-  _rhythmSectionBits |= value;
-
-  writeOPL(0xBD, _vibratoAndAMDepthBits | 0x20 | _rhythmSectionBits);
-  return 0;
-}
-
-int AdlibDriver::update_removeRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value) {
-  --dataptr;
-  _rhythmSectionBits = 0;
-
-  // All the rhythm bits are cleared. The AM and Vibrato depth bits
-  // remain unchanged.
-
-  writeOPL(0xBD, _vibratoAndAMDepthBits);
-  return 0;
-}
-
-int AdlibDriver::updateCallback51(uint8 *&dataptr, Channel &channel, uint8 value) {
-  uint8 value2 = *dataptr++;
-
-  if (value & 1) {
-    _unkValue12 = value2;
-
-    // Channel 7, op1: Level Key Scaling / Total Level
-    writeOPL(0x51, checkValue(value2 + _unkValue7 + _unkValue11 + _unkValue12));
-  }
-
-  if (value & 2) {
-    _unkValue14 = value2;
-
-    // Channel 8, op2: Level Key Scaling / Total Level
-    writeOPL(0x55, checkValue(value2 + _unkValue10 + _unkValue13 + _unkValue14));
-  }
-
-  if (value & 4) {
-    _unkValue15 = value2;
-
-    // Channel 8, op1: Level Key Scaling / Total Level
-    writeOPL(0x52, checkValue(value2 + _unkValue9 + _unkValue16 + _unkValue15));
-  }
-
-  if (value & 8) {
-    _unkValue18 = value2;
-
-    // Channel 7, op2: Level Key Scaling / Total Level
-    writeOPL(0x54, checkValue(value2 + _unkValue8 + _unkValue17 + _unkValue18));
-  }
-
-  if (value & 16) {
-    _unkValue20 = value2;
-
-    // Channel 6, op2: Level Key Scaling / Total Level
-    writeOPL(0x53, checkValue(value2 + _unkValue6 + _unkValue19 + _unkValue20));
-  }
-
-  return 0;
-}
-
-int AdlibDriver::updateCallback52(uint8 *&dataptr, Channel &channel, uint8 value) {
-  uint8 value2 = *dataptr++;
-
-  if (value & 1) {
-    _unkValue11 = checkValue(value2 + _unkValue7 + _unkValue11 + _unkValue12);
-
-    // Channel 7, op1: Level Key Scaling / Total Level
-    writeOPL(0x51, _unkValue11);
-  }
-
-  if (value & 2) {
-    _unkValue13 = checkValue(value2 + _unkValue10 + _unkValue13 + _unkValue14);
-
-    // Channel 8, op2: Level Key Scaling / Total Level
-    writeOPL(0x55, _unkValue13);
-  }
-
-  if (value & 4) {
-    _unkValue16 = checkValue(value2 + _unkValue9 + _unkValue16 + _unkValue15);
-
-    // Channel 8, op1: Level Key Scaling / Total Level
-    writeOPL(0x52, _unkValue16);
-  }
-
-  if (value & 8) {
-    _unkValue17 = checkValue(value2 + _unkValue8 + _unkValue17 + _unkValue18);
-
-    // Channel 7, op2: Level Key Scaling / Total Level
-    writeOPL(0x54, _unkValue17);
-  }
-
-  if (value & 16) {
-    _unkValue19 = checkValue(value2 + _unkValue6 + _unkValue19 + _unkValue20);
-
-    // Channel 6, op2: Level Key Scaling / Total Level
-    writeOPL(0x53, _unkValue19);
-  }
-
-  return 0;
-}
-
-int AdlibDriver::updateCallback53(uint8 *&dataptr, Channel &channel, uint8 value) {
-  uint8 value2 = *dataptr++;
-
-  if (value & 1) {
-    _unkValue11 = value2;
-
-    // Channel 7, op1: Level Key Scaling / Total Level
-    writeOPL(0x51, checkValue(value2 + _unkValue7 + _unkValue12));
-  }
-
-  if (value & 2) {
-    _unkValue13 = value2;
-
-    // Channel 8, op2: Level Key Scaling / Total Level
-    writeOPL(0x55, checkValue(value2 + _unkValue10 + _unkValue14));
-  }
-
-  if (value & 4) {
-    _unkValue16 = value2;
-
-    // Channel 8, op1: Level Key Scaling / Total Level
-    writeOPL(0x52, checkValue(value2 + _unkValue9 + _unkValue15));
-  }
-
-  if (value & 8) {
-    _unkValue17 = value2;
-
-    // Channel 7, op2: Level Key Scaling / Total Level
-    writeOPL(0x54, checkValue(value2 + _unkValue8 + _unkValue18));
-  }
-
-  if (value & 16) {
-    _unkValue19 = value2;
-
-    // Channel 6, op2: Level Key Scaling / Total Level
-    writeOPL(0x53, checkValue(value2 + _unkValue6 + _unkValue20));
-  }
-
-  return 0;
-}
-
-int AdlibDriver::update_setSoundTrigger(uint8 *&dataptr, Channel &channel, uint8 value) {
-  _soundTrigger = value;
-  return 0;
-}
-
-int AdlibDriver::update_setTempoReset(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.tempoReset = value;
-  return 0;
-}
-
-int AdlibDriver::updateCallback56(uint8 *&dataptr, Channel &channel, uint8 value) {
-  channel.unk39 = value;
-  channel.unk40 = *dataptr++;
-  return 0;
-}
-
-// static res
-
-#define COMMAND(x) { &AdlibDriver::x, #x }
-
-void AdlibDriver::setupOpcodeList() {
-  static const OpcodeEntry opcodeList[] = {
-    COMMAND(snd_ret0x100),
-    COMMAND(snd_ret0x1983),
-    COMMAND(snd_initDriver),
-    COMMAND(snd_deinitDriver),
-    COMMAND(snd_setSoundData),
-    COMMAND(snd_unkOpcode1),
-    COMMAND(snd_startSong),
-    COMMAND(snd_unkOpcode2),
-    COMMAND(snd_unkOpcode3),
-    COMMAND(snd_readByte),
-    COMMAND(snd_writeByte),
-    COMMAND(snd_getSoundTrigger),
-    COMMAND(snd_unkOpcode4),
-    COMMAND(snd_dummy),
-    COMMAND(snd_getNullvar4),
-    COMMAND(snd_setNullvar3),
-    COMMAND(snd_setFlag),
-    COMMAND(snd_clearFlag)
-  };
-
-  _opcodeList = opcodeList;
-  _opcodesEntries = ARRAYSIZE(opcodeList);
-}
-
-void AdlibDriver::setupParserOpcodeTable() {
-  static const ParserOpcode parserOpcodeTable[] = {
-    // 0
-    COMMAND(update_setRepeat),
-    COMMAND(update_checkRepeat),
-    COMMAND(update_setupProgram),
-    COMMAND(update_setNoteSpacing),
-
-    // 4
-    COMMAND(update_jump),
-    COMMAND(update_jumpToSubroutine),
-    COMMAND(update_returnFromSubroutine),
-    COMMAND(update_setBaseOctave),
-
-    // 8
-    COMMAND(update_stopChannel),
-    COMMAND(update_playRest),
-    COMMAND(update_writeAdlib),
-    COMMAND(update_setupNoteAndDuration),
-
-    // 12
-    COMMAND(update_setBaseNote),
-    COMMAND(update_setupSecondaryEffect1),
-    COMMAND(update_stopOtherChannel),
-    COMMAND(update_waitForEndOfProgram),
-
-    // 16
-    COMMAND(update_setupInstrument),
-    COMMAND(update_setupPrimaryEffect1),
-    COMMAND(update_removePrimaryEffect1),
-    COMMAND(update_setBaseFreq),
-
-    // 20
-    COMMAND(update_stopChannel),
-    COMMAND(update_setupPrimaryEffect2),
-    COMMAND(update_stopChannel),
-    COMMAND(update_stopChannel),
-
-    // 24
-    COMMAND(update_stopChannel),
-    COMMAND(update_stopChannel),
-    COMMAND(update_setPriority),
-    COMMAND(update_stopChannel),
-
-    // 28
-    COMMAND(updateCallback23),
-    COMMAND(updateCallback24),
-    COMMAND(update_setExtraLevel1),
-    COMMAND(update_stopChannel),
-
-    // 32
-    COMMAND(update_setupDuration),
-    COMMAND(update_playNote),
-    COMMAND(update_stopChannel),
-    COMMAND(update_stopChannel),
-
-    // 36
-    COMMAND(update_setFractionalNoteSpacing),
-    COMMAND(update_stopChannel),
-    COMMAND(update_setTempo),
-    COMMAND(update_removeSecondaryEffect1),
-
-    // 40
-    COMMAND(update_stopChannel),
-    COMMAND(update_setChannelTempo),
-    COMMAND(update_stopChannel),
-    COMMAND(update_setExtraLevel3),
-
-    // 44
-    COMMAND(update_setExtraLevel2),
-    COMMAND(update_changeExtraLevel2),
-    COMMAND(update_setAMDepth),
-    COMMAND(update_setVibratoDepth),
-
-    // 48
-    COMMAND(update_changeExtraLevel1),
-    COMMAND(update_stopChannel),
-    COMMAND(update_stopChannel),
-    COMMAND(updateCallback38),
-
-    // 52
-    COMMAND(update_stopChannel),
-    COMMAND(updateCallback39),
-    COMMAND(update_removePrimaryEffect2),
-    COMMAND(update_stopChannel),
-
-    // 56
-    COMMAND(update_stopChannel),
-    COMMAND(updateCallback41),
-    COMMAND(update_resetToGlobalTempo),
-    COMMAND(update_nop1),
-
-    // 60
-    COMMAND(update_setDurationRandomness),
-    COMMAND(update_changeChannelTempo),
-    COMMAND(update_stopChannel),
-    COMMAND(updateCallback46),
-
-    // 64
-    COMMAND(update_nop2),
-    COMMAND(update_setupRhythmSection),
-    COMMAND(update_playRhythmSection),
-    COMMAND(update_removeRhythmSection),
-
-    // 68
-    COMMAND(updateCallback51),
-    COMMAND(updateCallback52),
-    COMMAND(updateCallback53),
-    COMMAND(update_setSoundTrigger),
-
-    // 72
-    COMMAND(update_setTempoReset),
-    COMMAND(updateCallback56),
-    COMMAND(update_stopChannel)
-  };
-
-  _parserOpcodeTable = parserOpcodeTable;
-  _parserOpcodeTableSize = ARRAYSIZE(parserOpcodeTable);
-}
-#undef COMMAND
-
-// This table holds the register offset for operator 1 for each of the nine
-// channels. To get the register offset for operator 2, simply add 3.
-
-const uint8 AdlibDriver::_regOffset[] = {
-  0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11,
-  0x12
-};
-
-// Given the size of this table, and the range of its values, it's probably the
-// F-Numbers (10 bits) for the notes of the 12-tone scale. However, it does not
-// match the table in the Adlib documentation I've seen.
-
-const uint16 AdlibDriver::_unkTable[] = {
-  0x0134, 0x0147, 0x015A, 0x016F, 0x0184, 0x019C, 0x01B4, 0x01CE, 0x01E9,
-  0x0207, 0x0225, 0x0246
-};
-
-// These tables are currently only used by updateCallback46(), which only ever
-// uses the first element of one of the sub-tables.
-
-const uint8 *AdlibDriver::_unkTable2[] = {
-  AdlibDriver::_unkTable2_1,
-  AdlibDriver::_unkTable2_2,
-  AdlibDriver::_unkTable2_1,
-  AdlibDriver::_unkTable2_2,
-  AdlibDriver::_unkTable2_3,
-  AdlibDriver::_unkTable2_2
-};
-
-const uint8 AdlibDriver::_unkTable2_1[] = {
-  0x50, 0x50, 0x4F, 0x4F, 0x4E, 0x4E, 0x4D, 0x4D,
-  0x4C, 0x4C, 0x4B, 0x4B, 0x4A, 0x4A, 0x49, 0x49,
-  0x48, 0x48, 0x47, 0x47, 0x46, 0x46, 0x45, 0x45,
-  0x44, 0x44, 0x43, 0x43, 0x42, 0x42, 0x41, 0x41,
-  0x40, 0x40, 0x3F, 0x3F, 0x3E, 0x3E, 0x3D, 0x3D,
-  0x3C, 0x3C, 0x3B, 0x3B, 0x3A, 0x3A, 0x39, 0x39,
-  0x38, 0x38, 0x37, 0x37, 0x36, 0x36, 0x35, 0x35,
-  0x34, 0x34, 0x33, 0x33, 0x32, 0x32, 0x31, 0x31,
-  0x30, 0x30, 0x2F, 0x2F, 0x2E, 0x2E, 0x2D, 0x2D,
-  0x2C, 0x2C, 0x2B, 0x2B, 0x2A, 0x2A, 0x29, 0x29,
-  0x28, 0x28, 0x27, 0x27, 0x26, 0x26, 0x25, 0x25,
-  0x24, 0x24, 0x23, 0x23, 0x22, 0x22, 0x21, 0x21,
-  0x20, 0x20, 0x1F, 0x1F, 0x1E, 0x1E, 0x1D, 0x1D,
-  0x1C, 0x1C, 0x1B, 0x1B, 0x1A, 0x1A, 0x19, 0x19,
-  0x18, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15,
-  0x14, 0x14, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11,
-  0x10, 0x10
-};
-
-// no don't ask me WHY this table exsits!
-const uint8 AdlibDriver::_unkTable2_2[] = {
-  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
-  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
-  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
-  0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
-  0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
-  0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
-  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
-  0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
-  0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
-  0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
-  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
-  0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x6F,
-  0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
-  0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
-  0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
-  0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F
-};
-
-const uint8 AdlibDriver::_unkTable2_3[] = {
-  0x40, 0x40, 0x40, 0x3F, 0x3F, 0x3F, 0x3E, 0x3E,
-  0x3E, 0x3D, 0x3D, 0x3D, 0x3C, 0x3C, 0x3C, 0x3B,
-  0x3B, 0x3B, 0x3A, 0x3A, 0x3A, 0x39, 0x39, 0x39,
-  0x38, 0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36,
-  0x36, 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x33,
-  0x33, 0x33, 0x32, 0x32, 0x32, 0x31, 0x31, 0x31,
-  0x30, 0x30, 0x30, 0x2F, 0x2F, 0x2F, 0x2E, 0x2E,
-  0x2E, 0x2D, 0x2D, 0x2D, 0x2C, 0x2C, 0x2C, 0x2B,
-  0x2B, 0x2B, 0x2A, 0x2A, 0x2A, 0x29, 0x29, 0x29,
-  0x28, 0x28, 0x28, 0x27, 0x27, 0x27, 0x26, 0x26,
-  0x26, 0x25, 0x25, 0x25, 0x24, 0x24, 0x24, 0x23,
-  0x23, 0x23, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21,
-  0x20, 0x20, 0x20, 0x1F, 0x1F, 0x1F, 0x1E, 0x1E,
-  0x1E, 0x1D, 0x1D, 0x1D, 0x1C, 0x1C, 0x1C, 0x1B,
-  0x1B, 0x1B, 0x1A, 0x1A, 0x1A, 0x19, 0x19, 0x19,
-  0x18, 0x18, 0x18, 0x17, 0x17, 0x17, 0x16, 0x16,
-  0x16, 0x15
-};
-
-// This table is used to modify the frequency of the notes, depending on the
-// note value and unk16. In theory, we could very well try to access memory
-// outside this table, but in reality that probably won't happen.
-//
-// This could be some sort of pitch bend, but I have yet to see it used for
-// anything so it's hard to say.
-
-const uint8 AdlibDriver::_unkTables[][32] = {
-  // 0
-  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08,
-    0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
-    0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x19,
-    0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21 },
-  // 1
-  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x07, 0x09,
-    0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11,
-    0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x1A,
-    0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x22, 0x24 },
-  // 2
-  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x09,
-    0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12, 0x13,
-    0x14, 0x15, 0x16, 0x17, 0x19, 0x1A, 0x1C, 0x1D,
-    0x1E, 0x1F, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26 },
-  // 3
-  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0A,
-    0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12, 0x13,
-    0x14, 0x15, 0x16, 0x17, 0x18, 0x1A, 0x1C, 0x1D,
-    0x1E, 0x1F, 0x20, 0x21, 0x23, 0x25, 0x27, 0x28 },
-  // 4
-  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0A,
-    0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x13, 0x15,
-    0x16, 0x17, 0x18, 0x19, 0x1B, 0x1D, 0x1F, 0x20,
-    0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x28, 0x2A },
-  // 5
-  { 0x00, 0x01, 0x02, 0x03, 0x05, 0x07, 0x09, 0x0B,
-    0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15,
-    0x16, 0x17, 0x18, 0x19, 0x1B, 0x1D, 0x1F, 0x20,
-    0x21, 0x22, 0x23, 0x25, 0x27, 0x29, 0x2B, 0x2D },
-  // 6
-  { 0x00, 0x01, 0x02, 0x03, 0x05, 0x07, 0x09, 0x0B,
-    0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15,
-    0x16, 0x17, 0x18, 0x1A, 0x1C, 0x1E, 0x21, 0x24,
-    0x25, 0x26, 0x27, 0x29, 0x2B, 0x2D, 0x2F, 0x30 },
-  // 7
-  { 0x00, 0x01, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C,
-    0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x18,
-    0x19, 0x1A, 0x1C, 0x1D, 0x1F, 0x21, 0x23, 0x25,
-    0x26, 0x27, 0x29, 0x2B, 0x2D, 0x2F, 0x30, 0x32 },
-  // 8
-  { 0x00, 0x01, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0D,
-    0x0E, 0x0F, 0x10, 0x11, 0x12, 0x14, 0x17, 0x1A,
-    0x19, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x25, 0x28,
-    0x29, 0x2A, 0x2B, 0x2D, 0x2F, 0x31, 0x33, 0x35 },
-  // 9
-  { 0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0E,
-    0x0F, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1B,
-    0x1C, 0x1D, 0x1E, 0x20, 0x22, 0x24, 0x26, 0x29,
-    0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x39 },
-  // 10
-  { 0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0E,
-    0x0F, 0x10, 0x12, 0x14, 0x16, 0x19, 0x1B, 0x1E,
-    0x1F, 0x21, 0x23, 0x25, 0x27, 0x29, 0x2B, 0x2D,
-    0x2E, 0x2F, 0x31, 0x32, 0x34, 0x36, 0x39, 0x3C },
-  // 11
-  { 0x00, 0x01, 0x03, 0x05, 0x07, 0x0A, 0x0C, 0x0F,
-    0x10, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1E,
-    0x1F, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2B, 0x2E,
-    0x2F, 0x30, 0x32, 0x34, 0x36, 0x39, 0x3C, 0x3F },
-  // 12
-  { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0B, 0x0D, 0x10,
-    0x11, 0x12, 0x14, 0x16, 0x18, 0x1B, 0x1E, 0x21,
-    0x22, 0x23, 0x25, 0x27, 0x29, 0x2C, 0x2F, 0x32,
-    0x33, 0x34, 0x36, 0x38, 0x3B, 0x34, 0x41, 0x44 },
-  // 13
-  { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0B, 0x0D, 0x11,
-    0x12, 0x13, 0x15, 0x17, 0x1A, 0x1D, 0x20, 0x23,
-    0x24, 0x25, 0x27, 0x29, 0x2C, 0x2F, 0x32, 0x35,
-    0x36, 0x37, 0x39, 0x3B, 0x3E, 0x41, 0x44, 0x47 }
-};
-
-// #pragma mark -
-
-// At the time of writing, the only known case where Kyra 1 uses sound triggers
-// is in the castle, to cycle between three different songs.
-
-const int CadlPlayer::_kyra1SoundTriggers[] = {
-  0, 4, 5, 3
-};
-
-const int CadlPlayer::_kyra1NumSoundTriggers = ARRAYSIZE(CadlPlayer::_kyra1SoundTriggers);
-
-CadlPlayer::CadlPlayer(Copl *newopl)
-  : CPlayer(newopl), numsubsongs(0), _trackEntries(), _soundDataPtr(0)
-{
-  memset(_trackEntries, 0, sizeof(_trackEntries));
-  _driver = new AdlibDriver(newopl);
-  assert(_driver);
-
-  _sfxPlayingSound = -1;
-  // 	_soundFileLoaded = "";
-
-  _soundTriggers = _kyra1SoundTriggers;
-  _numSoundTriggers = _kyra1NumSoundTriggers;
-
-  init();
-}
-
-CadlPlayer::~CadlPlayer() {
-  delete [] _soundDataPtr;
-  delete _driver;
-}
-
-bool CadlPlayer::init() {
-  _driver->callback(2);
-  _driver->callback(16, int(4));
-  return true;
-}
-
-void CadlPlayer::process() {
-  uint8 trigger = _driver->callback(11);
-
-  if (trigger < _numSoundTriggers) {
-    int soundId = _soundTriggers[trigger];
-
-    if (soundId) {
-      playTrack(soundId);
-    }
-  } else {
-    warning("Unknown sound trigger %d", trigger);
-    // TODO: At this point, we really want to clear the trigger...
-  }
-}
-
-// void CadlPlayer::setVolume(int volume) {
-// }
-
-// int CadlPlayer::getVolume() {
-// 	return 0;
-// }
-
-// void CadlPlayer::loadMusicFile(const char *file) {
-// 	loadSoundFile(file);
-// }
-
-void CadlPlayer::playTrack(uint8 track) {
-  play(track);
-}
-
-// void CadlPlayer::haltTrack() {
-// 	unk1();
-// 	unk2();
-// 	//_engine->_system->delayMillis(3 * 60);
-// }
-
-void CadlPlayer::playSoundEffect(uint8_t track) {
-  play(track);
-}
-
-void CadlPlayer::play(uint8_t track) {
-  uint8 soundId = _trackEntries[track];
-  if ((int8)soundId == -1 || !_soundDataPtr)
-    return;
-  soundId &= 0xFF;
-  _driver->callback(16, 0);
-  // 	while ((_driver->callback(16, 0) & 8)) {
-  // We call the system delay and not the game delay to avoid concurrency issues.
-  // 		_engine->_system->delayMillis(10);
-  // 	}
-  if (_sfxPlayingSound != -1) {
-    // Restore the sounds's normal values.
-    _driver->callback(10, _sfxPlayingSound, int(1), int(_sfxPriority));
-    _driver->callback(10, _sfxPlayingSound, int(3), int(_sfxFourthByteOfSong));
-    _sfxPlayingSound = -1;
-  }
-
-  int chan = _driver->callback(9, soundId, int(0));
-
-  if (chan != 9) {
-    _sfxPlayingSound = soundId;
-    _sfxPriority = _driver->callback(9, soundId, int(1));
-    _sfxFourthByteOfSong = _driver->callback(9, soundId, int(3));
-
-    // In the cases I've seen, the mysterious fourth byte has been
-    // the parameter for the update_setExtraLevel3() callback.
-    //
-    // The extra level is part of the channels "total level", which
-    // is a six-bit value where larger values means softer volume.
-    //
-    // So what seems to be happening here is that sounds which are
-    // started by this function are given a slightly lower priority
-    // and a slightly higher (i.e. softer) extra level 3 than they
-    // would have if they were started from anywhere else. Strange.
-
-    int newVal = ((((-_sfxFourthByteOfSong) + 63) * 0xFF) >> 8) & 0xFF;
-    newVal = -newVal + 63;
-    _driver->callback(10, soundId, int(3), newVal);
-    newVal = ((_sfxPriority * 0xFF) >> 8) & 0xFF;
-    _driver->callback(10, soundId, int(1), newVal);
-  }
-
-  _driver->callback(6, soundId);
-}
-
-// void CadlPlayer::beginFadeOut() {
-// 	playSoundEffect(1);
-// }
-
-bool CadlPlayer::load(const std::string &filename, const CFileProvider &fp)
-{
-  binistream	*f = fp.open(filename);
-
-  // file validation section
-  if(!f || !fp.extension(filename, ".adl")) {
-    fp.close(f);
-    return false;
-  }
-
-  // 	if (_soundFileLoaded == file)
-  // 		return;
-
-  // 	if (_soundDataPtr) {
-  // 		haltTrack();
-  // 	}
-
-  uint8 *file_data = 0; uint32 file_size = 0;
-
-  // 	char filename[25];
-  // 	sprintf(filename, "%s.ADL", file);
-
-  // 	file_data = _engine->resource()->fileData(filename, &file_size);
-  // 	if (!file_data) {
-  // 		warning("Couldn't find music file: '%s'", filename);
-  // 		return;
-  // 	}
-
-  unk2();
-  unk1();
-
-  file_size = fp.filesize(f);
-  file_data = new uint8 [file_size];
-  f->readString((char *)file_data, file_size);
-
-  _driver->callback(8, int(-1));
-  _soundDataPtr = 0;
-
-  uint8 *p = file_data;
-  memcpy(_trackEntries, p, 120*sizeof(uint8));
-  p += 120;
-
-  int soundDataSize = file_size - 120;
-
-  _soundDataPtr = new uint8[soundDataSize];
-  assert(_soundDataPtr);
-
-  memcpy(_soundDataPtr, p, soundDataSize*sizeof(uint8));
-
-  delete [] file_data;
-  file_data = p = 0;
-  file_size = 0;
-
-  _driver->callback(4, _soundDataPtr);
-
-  // 	_soundFileLoaded = file;
-
-  for(int i = 0; i < 200; i++)
-    if(_trackEntries[i] != 0xff)
-      numsubsongs = i + 1;
-
-  fp.close(f);
-  return true;
-}
-
-void CadlPlayer::rewind(int subsong)
-{
-  opl->init();
-  opl->write(1,32);
-  playSoundEffect(subsong);
-  cursubsong = subsong;
-  update();
-}
-
-unsigned int CadlPlayer::getsubsongs()
-{
-  return numsubsongs;
-}
-
-bool CadlPlayer::update()
-{
-  bool songend = true;
-
-//   if(_trackEntries[cursubsong] == 0xff)
-//     return false;
-
-  _driver->callback();
-
-  for(int i = 0; i < 10; i++)
-    if(_driver->_channels[i].dataptr != NULL)
-      songend = false;
-
-  return !songend;
-}
-
-void CadlPlayer::unk1() {
-  playSoundEffect(0);
-  //_engine->_system->delayMillis(5 * 60);
-}
-
-void CadlPlayer::unk2() {
-  playSoundEffect(0);
-}
-
-CPlayer *CadlPlayer::factory(Copl *newopl)
-{
-  return new CadlPlayer(newopl);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/adl.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,2427 @@
+/*
+ * adl.cpp - ADL player adaption by Simon Peter <dn.tlp@gmx.net>
+ *
+ * Original ADL player by Torbjorn Andersson and Johannes Schickel
+ * 'lordhoto' <lordhoto at scummvm dot org> of the ScummVM project.
+ */
+
+/* ScummVM - Scumm Interpreter
+ *
+ * This file is licensed under both GPL and LGPL
+ * Copyright (C) 2006 The ScummVM project
+ * Copyright (C) 2006 Torbjorn Andersson and Johannes Schickel
+ *
+ * GPL License
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * LPGL License
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#include <inttypes.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#include "adl.h"
+#include "debug.h"
+
+#ifdef ADL_DEBUG
+#	define warning(...)		AdPlug_LogWrite(__VA_ARGS__); \
+AdPlug_LogWrite("\n")
+
+#	define debugC(i1, i2, ...)	AdPlug_LogWrite(__VA_ARGS__); \
+AdPlug_LogWrite("\n")
+#else
+#	define kDebugLevelSound	1
+
+static inline void warning(const char *str, ...)
+{
+}
+
+static inline void debugC(int i1, int i2, const char *str, ...)
+{
+}
+#endif
+
+// #define warning(...)
+// #define debugC(i1, i2, ...)
+
+#define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0])))
+
+// Basic Adlib Programming:
+// http://www.gamedev.net/reference/articles/article446.asp
+
+#define CALLBACKS_PER_SECOND 72
+
+typedef uint8_t	uint8;
+typedef int8_t	int8;
+typedef uint16_t	uint16;
+typedef int16_t	int16;
+typedef uint32_t	uint32;
+typedef int32_t	int32;
+typedef uint8_t	byte;
+
+static inline uint16 READ_LE_UINT16(const void *ptr) {
+  const byte *b = (const byte *)ptr;
+  return (b[1] << 8) + b[0];
+}
+
+static inline uint16 READ_BE_UINT16(const void *ptr) {
+  const byte *b = (const byte *)ptr;
+  return (b[0] << 8) + b[1];
+}
+
+class AdlibDriver {
+public:
+  AdlibDriver(Copl *opl);
+  ~AdlibDriver();
+
+  int callback(int opcode, ...);
+  void callback();
+
+  // AudioStream API
+  // 	int readBuffer(int16 *buffer, const int numSamples) {
+  // 		int32 samplesLeft = numSamples;
+  // 		memset(buffer, 0, sizeof(int16) * numSamples);
+  // 		while (samplesLeft) {
+  // 			if (!_samplesTillCallback) {
+  // 				callback();
+  // 				_samplesTillCallback = _samplesPerCallback;
+  // 				_samplesTillCallbackRemainder += _samplesPerCallbackRemainder;
+  // 				if (_samplesTillCallbackRemainder >= CALLBACKS_PER_SECOND) {
+  // 					_samplesTillCallback++;
+  // 					_samplesTillCallbackRemainder -= CALLBACKS_PER_SECOND;
+  // 				}
+  // 			}
+
+  // 			int32 render = MIN(samplesLeft, _samplesTillCallback);
+  // 			samplesLeft -= render;
+  // 			_samplesTillCallback -= render;
+  // 			YM3812UpdateOne(_adlib, buffer, render);
+  // 			buffer += render;
+  // 		}
+  // 		return numSamples;
+  // 	}
+
+  bool isStereo() const { return false; }
+  bool endOfData() const { return false; }
+  // 	int getRate() const { return _mixer->getOutputRate(); }
+
+  struct OpcodeEntry {
+    typedef int (AdlibDriver::*DriverOpcode)(va_list &list);
+    DriverOpcode function;
+    const char *name;
+  };
+
+  void setupOpcodeList();
+  const OpcodeEntry *_opcodeList;
+  int _opcodesEntries;
+
+  int snd_ret0x100(va_list &list);
+  int snd_ret0x1983(va_list &list);
+  int snd_initDriver(va_list &list);
+  int snd_deinitDriver(va_list &list);
+  int snd_setSoundData(va_list &list);
+  int snd_unkOpcode1(va_list &list);
+  int snd_startSong(va_list &list);
+  int snd_unkOpcode2(va_list &list);
+  int snd_unkOpcode3(va_list &list);
+  int snd_readByte(va_list &list);
+  int snd_writeByte(va_list &list);
+  int snd_getSoundTrigger(va_list &list);
+  int snd_unkOpcode4(va_list &list);
+  int snd_dummy(va_list &list);
+  int snd_getNullvar4(va_list &list);
+  int snd_setNullvar3(va_list &list);
+  int snd_setFlag(va_list &list);
+  int snd_clearFlag(va_list &list);
+
+  // These variables have not yet been named, but some of them are partly
+  // known nevertheless:
+  //
+  // unk16 - Sound-related. Possibly some sort of pitch bend.
+  // unk18 - Sound-effect. Used for secondaryEffect1()
+  // unk19 - Sound-effect. Used for secondaryEffect1()
+  // unk20 - Sound-effect. Used for secondaryEffect1()
+  // unk21 - Sound-effect. Used for secondaryEffect1()
+  // unk22 - Sound-effect. Used for secondaryEffect1()
+  // unk29 - Sound-effect. Used for primaryEffect1()
+  // unk30 - Sound-effect. Used for primaryEffect1()
+  // unk31 - Sound-effect. Used for primaryEffect1()
+  // unk32 - Sound-effect. Used for primaryEffect2()
+  // unk33 - Sound-effect. Used for primaryEffect2()
+  // unk34 - Sound-effect. Used for primaryEffect2()
+  // unk35 - Sound-effect. Used for primaryEffect2()
+  // unk36 - Sound-effect. Used for primaryEffect2()
+  // unk37 - Sound-effect. Used for primaryEffect2()
+  // unk38 - Sound-effect. Used for primaryEffect2()
+  // unk39 - Currently unused, except for updateCallback56()
+  // unk40 - Currently unused, except for updateCallback56()
+  // unk41 - Sound-effect. Used for primaryEffect2()
+
+  struct Channel {
+    uint8 opExtraLevel2;
+    uint8 *dataptr;
+    uint8 duration;
+    uint8 repeatCounter;
+    int8 baseOctave;
+    uint8 priority;
+    uint8 dataptrStackPos;
+    uint8 *dataptrStack[4];
+    int8 baseNote;
+    uint8 unk29;
+    uint8 unk31;
+    uint16 unk30;
+    uint16 unk37;
+    uint8 unk33;
+    uint8 unk34;
+    uint8 unk35;
+    uint8 unk36;
+    uint8 unk32;
+    uint8 unk41;
+    uint8 unk38;
+    uint8 opExtraLevel1;
+    uint8 spacing2;
+    uint8 baseFreq;
+    uint8 tempo;
+    uint8 position;
+    uint8 regAx;
+    uint8 regBx;
+    typedef void (AdlibDriver::*Callback)(Channel&);
+    Callback primaryEffect;
+    Callback secondaryEffect;
+    uint8 fractionalSpacing;
+    uint8 opLevel1;
+    uint8 opLevel2;
+    uint8 opExtraLevel3;
+    uint8 twoChan;
+    uint8 unk39;	
+    uint8 unk40;
+    uint8 spacing1;
+    uint8 durationRandomness;
+    uint8 unk19;
+    uint8 unk18;
+    int8 unk20;
+    int8 unk21;
+    uint8 unk22;
+    uint16 offset;
+    uint8 tempoReset;
+    uint8 rawNote;
+    int8 unk16;
+  };
+
+  void primaryEffect1(Channel &channel);
+  void primaryEffect2(Channel &channel);
+  void secondaryEffect1(Channel &channel);
+
+  void resetAdlibState();
+  void writeOPL(byte reg, byte val);
+  void initChannel(Channel &channel);
+  void noteOff(Channel &channel);
+  void unkOutput2(uint8 num);
+
+  uint16 getRandomNr();
+  void setupDuration(uint8 duration, Channel &channel);
+
+  void setupNote(uint8 rawNote, Channel &channel, bool flag = false);
+  void setupInstrument(uint8 regOffset, uint8 *dataptr, Channel &channel);
+  void noteOn(Channel &channel);
+
+  void adjustVolume(Channel &channel);
+
+  uint8 calculateOpLevel1(Channel &channel);
+  uint8 calculateOpLevel2(Channel &channel);
+
+  uint16 checkValue(int16 val) {
+    if (val < 0)
+      val = 0;
+    else if (val > 0x3F)
+      val = 0x3F;
+    return val;
+  }
+
+  // The sound data has at least two lookup tables:
+  //
+  // * One for programs, starting at offset 0.
+  // * One for instruments, starting at offset 500.
+
+  uint8 *getProgram(int progId) {
+    return _soundData + READ_LE_UINT16(_soundData + 2 * progId);
+  }
+
+  uint8 *getInstrument(int instrumentId) {
+    return _soundData + READ_LE_UINT16(_soundData + 500 + 2 * instrumentId);
+  }
+
+  void setupPrograms();
+  void executePrograms();
+
+  struct ParserOpcode {
+    typedef int (AdlibDriver::*POpcode)(uint8 *&dataptr, Channel &channel, uint8 value);
+    POpcode function;
+    const char *name;
+  };
+
+  void setupParserOpcodeTable();
+  const ParserOpcode *_parserOpcodeTable;
+  int _parserOpcodeTableSize;
+
+  int update_setRepeat(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_checkRepeat(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setupProgram(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setNoteSpacing(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_jump(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_jumpToSubroutine(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_returnFromSubroutine(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setBaseOctave(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_stopChannel(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_playRest(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_writeAdlib(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setupNoteAndDuration(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setBaseNote(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setupSecondaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_stopOtherChannel(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_waitForEndOfProgram(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setupInstrument(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setupPrimaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_removePrimaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setBaseFreq(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setupPrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setPriority(uint8 *&dataptr, Channel &channel, uint8 value);
+  int updateCallback23(uint8 *&dataptr, Channel &channel, uint8 value);
+  int updateCallback24(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setExtraLevel1(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setupDuration(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_playNote(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setFractionalNoteSpacing(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setTempo(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_removeSecondaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setChannelTempo(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setExtraLevel3(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setExtraLevel2(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_changeExtraLevel2(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setAMDepth(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setVibratoDepth(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_changeExtraLevel1(uint8 *&dataptr, Channel &channel, uint8 value);
+  int updateCallback38(uint8 *&dataptr, Channel &channel, uint8 value);
+  int updateCallback39(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_removePrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value);
+  int updateCallback41(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_resetToGlobalTempo(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_nop1(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setDurationRandomness(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_changeChannelTempo(uint8 *&dataptr, Channel &channel, uint8 value);
+  int updateCallback46(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_nop2(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setupRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_playRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_removeRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value);
+  int updateCallback51(uint8 *&dataptr, Channel &channel, uint8 value);
+  int updateCallback52(uint8 *&dataptr, Channel &channel, uint8 value);
+  int updateCallback53(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setSoundTrigger(uint8 *&dataptr, Channel &channel, uint8 value);
+  int update_setTempoReset(uint8 *&dataptr, Channel &channel, uint8 value);
+  int updateCallback56(uint8 *&dataptr, Channel &channel, uint8 value);
+
+  // These variables have not yet been named, but some of them are partly
+  // known nevertheless:
+  //
+  // _unkValue1      - Unknown. Used for updating _unkValue2
+  // _unkValue2      - Unknown. Used for updating _unkValue4
+  // _unkValue3      - Unknown. Used for updating _unkValue2
+  // _unkValue4      - Unknown. Used for updating _unkValue5
+  // _unkValue5      - Unknown. Used for controlling updateCallback24().
+  // _unkValue6      - Unknown. Rhythm section volume?
+  // _unkValue7      - Unknown. Rhythm section volume?
+  // _unkValue8      - Unknown. Rhythm section volume?
+  // _unkValue9      - Unknown. Rhythm section volume?
+  // _unkValue10     - Unknown. Rhythm section volume?
+  // _unkValue11     - Unknown. Rhythm section volume?
+  // _unkValue12     - Unknown. Rhythm section volume?
+  // _unkValue13     - Unknown. Rhythm section volume?
+  // _unkValue14     - Unknown. Rhythm section volume?
+  // _unkValue15     - Unknown. Rhythm section volume?
+  // _unkValue16     - Unknown. Rhythm section volume?
+  // _unkValue17     - Unknown. Rhythm section volume?
+  // _unkValue18     - Unknown. Rhythm section volume?
+  // _unkValue19     - Unknown. Rhythm section volume?
+  // _unkValue20     - Unknown. Rhythm section volume?
+  // _unkTable[]     - Probably frequences for the 12-tone scale.
+  // _unkTable2[]    - Unknown. Currently only used by updateCallback46()
+  // _unkTable2_1[]  - One of the tables in _unkTable2[]
+  // _unkTable2_2[]  - One of the tables in _unkTable2[]
+  // _unkTable2_3[]  - One of the tables in _unkTable2[]
+
+  int32 _samplesPerCallback;
+  int32 _samplesPerCallbackRemainder;
+  int32 _samplesTillCallback;
+  int32 _samplesTillCallbackRemainder;
+
+  int _lastProcessed;
+  int8 _flagTrigger;
+  int _curChannel;
+  uint8 _soundTrigger;
+  int _soundsPlaying;
+
+  uint16 _rnd;
+
+  uint8 _unkValue1;
+  uint8 _unkValue2;
+  uint8 _unkValue3;
+  uint8 _unkValue4;
+  uint8 _unkValue5;
+  uint8 _unkValue6;
+  uint8 _unkValue7;
+  uint8 _unkValue8;
+  uint8 _unkValue9;
+  uint8 _unkValue10;
+  uint8 _unkValue11;
+  uint8 _unkValue12;
+  uint8 _unkValue13;
+  uint8 _unkValue14;
+  uint8 _unkValue15;
+  uint8 _unkValue16;
+  uint8 _unkValue17;
+  uint8 _unkValue18;
+  uint8 _unkValue19;
+  uint8 _unkValue20;
+
+  int _flags;
+
+  uint8 *_soundData;
+
+  uint8 _soundIdTable[0x10];
+  Channel _channels[10];
+
+  uint8 _vibratoAndAMDepthBits;
+  uint8 _rhythmSectionBits;
+
+  uint8 _curRegOffset;
+  uint8 _tempo;
+
+  const uint8 *_tablePtr1;
+  const uint8 *_tablePtr2;
+
+  static const uint8 _regOffset[];
+  static const uint16 _unkTable[];
+  static const uint8 *_unkTable2[];
+  static const uint8 _unkTable2_1[];
+  static const uint8 _unkTable2_2[];
+  static const uint8 _unkTable2_3[];
+  static const uint8 _unkTables[][32];
+
+  Copl *opl;
+};
+
+AdlibDriver::AdlibDriver(Copl *newopl)
+  : opl(newopl)
+{
+  setupOpcodeList();
+  setupParserOpcodeTable();
+
+  // 	_mixer = mixer;
+
+  _flags = 0;
+  // 	_adlib = makeAdlibOPL(getRate());
+  // 	assert(_adlib);
+
+  memset(_channels, 0, sizeof(_channels));
+  _soundData = 0;
+
+  _vibratoAndAMDepthBits = _curRegOffset = 0;
+
+  _lastProcessed = _flagTrigger = _curChannel = _rhythmSectionBits = 0;
+  _soundsPlaying = 0;
+  _rnd = 0x1234;
+
+  _tempo = 0;
+  _soundTrigger = 0;
+
+  _unkValue3 = 0xFF;
+  _unkValue1 = _unkValue2 = _unkValue4 = _unkValue5 = 0;
+  _unkValue6 = _unkValue7 = _unkValue8 = _unkValue9 = _unkValue10 = 0;
+  _unkValue11 = _unkValue12 = _unkValue13 = _unkValue14 = _unkValue15 =
+    _unkValue16 = _unkValue17 = _unkValue18 = _unkValue19 = _unkValue20 = 0;
+
+  _tablePtr1 = _tablePtr2 = 0;
+
+  // 	_mixer->setupPremix(this);
+
+  // 	_samplesPerCallback = getRate() / CALLBACKS_PER_SECOND;
+  // 	_samplesPerCallbackRemainder = getRate() % CALLBACKS_PER_SECOND;
+  _samplesTillCallback = 0;
+  _samplesTillCallbackRemainder = 0;
+}
+
+AdlibDriver::~AdlibDriver() {
+  // 	_mixer->setupPremix(0);
+  // 	OPLDestroy(_adlib);
+  // 	_adlib = 0;
+}
+
+int AdlibDriver::callback(int opcode, ...) {
+  // 	lock();
+  if (opcode >= _opcodesEntries || opcode < 0) {
+    warning("AdlibDriver: calling unknown opcode '%d'", opcode);
+    return 0;
+  }
+
+  debugC(9, kDebugLevelSound, "Calling opcode '%s' (%d)", _opcodeList[opcode].name, opcode);
+
+  va_list args;
+  va_start(args, opcode);
+  int returnValue = (this->*(_opcodeList[opcode].function))(args);
+  va_end(args);
+  // 	unlock();
+  return returnValue;
+}
+
+// Opcodes
+
+int AdlibDriver::snd_ret0x100(va_list &list) {
+  return 0x100;
+}
+
+int AdlibDriver::snd_ret0x1983(va_list &list) {
+  return 0x1983;
+}
+
+int AdlibDriver::snd_initDriver(va_list &list) {
+  _lastProcessed = _soundsPlaying = 0;
+  resetAdlibState();
+  return 0;
+}
+
+int AdlibDriver::snd_deinitDriver(va_list &list) {
+  resetAdlibState();
+  return 0;
+}
+
+int AdlibDriver::snd_setSoundData(va_list &list) {
+  if (_soundData) {
+    delete [] _soundData;
+    _soundData = 0;
+  }
+  _soundData = va_arg(list, uint8*);
+  return 0;
+}
+
+int AdlibDriver::snd_unkOpcode1(va_list &list) {
+  warning("unimplemented snd_unkOpcode1");
+  return 0;
+}
+
+int AdlibDriver::snd_startSong(va_list &list) {
+  int songId = va_arg(list, int);
+  _flags |= 8;
+  _flagTrigger = 1;
+
+  uint8 *ptr = getProgram(songId);
+  uint8 chan = *ptr;
+
+  if ((songId << 1) != 0) {
+    if (chan == 9) {
+      if (_flags & 2)
+	return 0;
+    } else {
+      if (_flags & 1)
+	return 0;
+    }
+  }
+
+  _soundIdTable[_soundsPlaying++] = songId;
+  _soundsPlaying &= 0x0F;
+
+  return 0;
+}
+
+int AdlibDriver::snd_unkOpcode2(va_list &list) {
+  warning("unimplemented snd_unkOpcode2");
+  return 0;
+}
+
+int AdlibDriver::snd_unkOpcode3(va_list &list) {
+  int value = va_arg(list, int);
+  int loop = value;
+  if (value < 0) {
+    value = 0;
+    loop = 9;
+  }
+  loop -= value;
+  ++loop;
+
+  while (loop--) {
+    _curChannel = value;
+    Channel &channel = _channels[_curChannel];
+    channel.priority = 0;
+    channel.dataptr = 0;
+    if (value != 9) {
+      noteOff(channel);
+    }
+    ++value;
+  }
+
+  return 0;
+}
+
+int AdlibDriver::snd_readByte(va_list &list) {
+  int a = va_arg(list, int);
+  int b = va_arg(list, int);
+  uint8 *ptr = getProgram(a) + b;
+  return *ptr;
+}
+
+int AdlibDriver::snd_writeByte(va_list &list) {
+  int a = va_arg(list, int);
+  int b = va_arg(list, int);
+  int c = va_arg(list, int);
+  uint8 *ptr = getProgram(a) + b;
+  uint8 oldValue = *ptr;
+  *ptr = (uint8)c;
+  return oldValue;
+}
+
+int AdlibDriver::snd_getSoundTrigger(va_list &list) {
+  return _soundTrigger;
+}
+
+int AdlibDriver::snd_unkOpcode4(va_list &list) {
+  warning("unimplemented snd_unkOpcode4");
+  return 0;
+}
+
+int AdlibDriver::snd_dummy(va_list &list) {
+  return 0;
+}
+
+int AdlibDriver::snd_getNullvar4(va_list &list) {
+  warning("unimplemented snd_getNullvar4");
+  return 0;
+}
+
+int AdlibDriver::snd_setNullvar3(va_list &list) {
+  warning("unimplemented snd_setNullvar3");
+  return 0;
+}
+
+int AdlibDriver::snd_setFlag(va_list &list) {
+  int oldFlags = _flags;
+  _flags |= va_arg(list, int);
+  return oldFlags;
+}
+
+int AdlibDriver::snd_clearFlag(va_list &list) {
+  int oldFlags = _flags;
+  _flags &= ~(va_arg(list, int));
+  return oldFlags;
+}
+
+// timer callback
+
+void AdlibDriver::callback() {
+  // 	lock();
+  --_flagTrigger;
+  if (_flagTrigger < 0)
+    _flags &= ~8;
+  setupPrograms();
+  executePrograms();
+
+  uint8 temp = _unkValue3;
+  _unkValue3 += _tempo;
+  if (_unkValue3 < temp) {
+    if (!(--_unkValue2)) {
+      _unkValue2 = _unkValue1;
+      ++_unkValue4;
+    }
+  }
+  // 	unlock();
+}
+
+void AdlibDriver::setupPrograms() {
+  while (_lastProcessed != _soundsPlaying) {
+    uint8 *ptr = getProgram(_soundIdTable[_lastProcessed]);
+    uint8 chan = *ptr++;
+    uint8 priority = *ptr++;
+
+    // Only start this sound if its priority is higher than the one
+    // already playing.
+
+    Channel &channel = _channels[chan];
+
+    if (priority >= channel.priority) {
+      initChannel(channel);
+      channel.priority = priority;
+      channel.dataptr = ptr;
+      channel.tempo = 0xFF;
+      channel.position = 0xFF;
+      channel.duration = 1;
+      unkOutput2(chan);
+    }
+
+    ++_lastProcessed;
+    _lastProcessed &= 0x0F;
+  }
+}
+
+// A few words on opcode parsing and timing:
+//
+// First of all, We simulate a timer callback 72 times per second. Each timeout
+// we update each channel that has something to play.
+//
+// Each channel has its own individual tempo, which is added to its position.
+// This will frequently cause the position to "wrap around" but that is
+// intentional. In fact, it's the signal to go ahead and do more stuff with
+// that channel.
+//
+// Each channel also has a duration, indicating how much time is left on the
+// its current task. This duration is decreased by one. As long as it still has
+// not reached zero, the only thing that can happen is that the note is turned
+// off depending on manual or automatic note spacing. Once the duration reaches
+// zero, a new set of musical opcodes are executed.
+//
+// An opcode is one byte, followed by a variable number of parameters. Since
+// most opcodes have at least one one-byte parameter, we read that as well. Any
+// opcode that doesn't have that one parameter is responsible for moving the
+// data pointer back again.
+//
+// If the most significant bit of the opcode is 1, it's a function; call it.
+// The opcode functions return either 0 (continue), 1 (stop) or 2 (stop, and do
+// not run the effects callbacks).
+//
+// If the most significant bit of the opcode is 0, it's a note, and the first
+// parameter is its duration. (There are cases where the duration is modified
+// but that's an exception.) The note opcode is assumed to return 1, and is the
+// last opcode unless its duration is zero.
+//
+// Finally, most of the times that the callback is called, it will invoke the
+// effects callbacks. The final opcode in a set can prevent this, if it's a
+// function and it returns anything other than 1.
+
+void AdlibDriver::executePrograms() {
+  // Each channel runs its own program. There are ten channels: One for
+  // each Adlib channel (0-8), plus one "control channel" (9) which is
+  // the one that tells the other channels what to do. 
+
+  for (_curChannel = 9; _curChannel >= 0; --_curChannel) {
+    int result = 1;
+
+    if (!_channels[_curChannel].dataptr) {
+      continue;
+    }
+	
+    Channel &channel = _channels[_curChannel];
+    _curRegOffset = _regOffset[_curChannel];
+
+    if (channel.tempoReset) {
+      channel.tempo = _tempo;
+    }
+
+    uint8 backup = channel.position;
+    channel.position += channel.tempo;
+    if (channel.position < backup) {
+      if (--channel.duration) {
+	if (channel.duration == channel.spacing2)
+	  noteOff(channel);
+	if (channel.duration == channel.spacing1 && _curChannel != 9)
+	  noteOff(channel);
+      } else {
+	// An opcode is not allowed to modify its own
+	// data pointer except through the 'dataptr'
+	// parameter. To enforce that, we have to work
+	// on a copy of the data pointer.
+	//
+	// This fixes a subtle music bug where the
+	// wrong music would play when getting the
+	// quill in Kyra 1.
+	uint8 *dataptr = channel.dataptr;
+	while (dataptr) {
+	  uint8 opcode = *dataptr++;
+	  uint8 param = *dataptr++;
+
+	  if (opcode & 0x80) {
+	    opcode &= 0x7F;
+	    if (opcode >= _parserOpcodeTableSize)
+	      opcode = _parserOpcodeTableSize - 1;
+	    debugC(9, kDebugLevelSound, "Calling opcode '%s' (%d) (channel: %d)", _parserOpcodeTable[opcode].name, opcode, _curChannel);
+	    result = (this->*(_parserOpcodeTable[opcode].function))(dataptr, channel, param);
+	    channel.dataptr = dataptr;
+	    if (result)
+	      break;
+	  } else {
+	    debugC(9, kDebugLevelSound, "Note on opcode 0x%02X (duration: %d) (channel: %d)", opcode, param, _curChannel);
+	    setupNote(opcode, channel);
+	    noteOn(channel);
+	    setupDuration(param, channel);
+	    if (param) {
+	      channel.dataptr = dataptr;
+	      break;
+	    }
+	  }
+	}
+      }
+    }
+
+    if (result == 1) {
+      if (channel.primaryEffect)
+	(this->*(channel.primaryEffect))(channel);
+      if (channel.secondaryEffect)
+	(this->*(channel.secondaryEffect))(channel);
+    }
+  }
+}
+
+// 
+
+void AdlibDriver::resetAdlibState() {
+  debugC(9, kDebugLevelSound, "resetAdlibState()");
+  _rnd = 0x1234;
+
+  // Authorize the control of the waveforms
+  writeOPL(0x01, 0x20);
+
+  // Select FM music mode
+  writeOPL(0x08, 0x00);
+
+  // I would guess the main purpose of this is to turn off the rhythm,
+  // thus allowing us to use 9 melodic voices instead of 6.
+  writeOPL(0xBD, 0x00);
+
+  int loop = 10;
+  while (loop--) {
+    if (loop != 9) {
+      // Silence the channel
+      writeOPL(0x40 + _regOffset[loop], 0x3F);
+      writeOPL(0x43 + _regOffset[loop], 0x3F);
+    }
+    initChannel(_channels[loop]);
+  }
+}
+
+// Old calling style: output0x388(0xABCD)
+// New calling style: writeOPL(0xAB, 0xCD)
+
+void AdlibDriver::writeOPL(byte reg, byte val) {
+  opl->write(reg, val);
+}
+
+void AdlibDriver::initChannel(Channel &channel) {
+  debugC(9, kDebugLevelSound, "initChannel(%lu)", (long)(&channel - _channels));
+  memset(&channel.dataptr, 0, sizeof(Channel) - ((char*)&channel.dataptr - (char*)&channel));
+
+  channel.tempo = 0xFF;
+  channel.priority = 0;
+  // normally here are nullfuncs but we set 0 for now
+  channel.primaryEffect = 0;
+  channel.secondaryEffect = 0;
+  channel.spacing1 = 1;
+}
+
+void AdlibDriver::noteOff(Channel &channel) {
+  debugC(9, kDebugLevelSound, "noteOff(%lu)", (long)(&channel - _channels));
+
+  // The control channel has no corresponding Adlib channel
+
+  if (_curChannel >= 9)
+    return;
+
+  // When the rhythm section is enabled, channels 6, 7 and 8 are special.
+
+  if (_rhythmSectionBits && _curChannel >= 6)
+    return;
+
+  // This means the "Key On" bit will always be 0
+  channel.regBx &= 0xDF;
+
+  // Octave / F-Number / Key-On
+  writeOPL(0xB0 + _curChannel, channel.regBx);
+}
+
+void AdlibDriver::unkOutput2(uint8 chan) {
+  debugC(9, kDebugLevelSound, "unkOutput2(%d)", chan);
+
+  // The control channel has no corresponding Adlib channel
+
+  if (chan >= 9)
+    return;
+
+  // I believe this has to do with channels 6, 7, and 8 being special
+  // when Adlib's rhythm section is enabled.
+
+  if (_rhythmSectionBits && chan >= 6)
+    return;
+
+  uint8 offset = _regOffset[chan];
+
+  // The channel is cleared: First the attack/delay rate, then the
+  // sustain level/release rate, and finally the note is turned off.
+
+  writeOPL(0x60 + offset, 0xFF);
+  writeOPL(0x63 + offset, 0xFF);
+
+  writeOPL(0x80 + offset, 0xFF);
+  writeOPL(0x83 + offset, 0xFF);
+
+  writeOPL(0xB0 + chan, 0x00);
+
+  // ...and then the note is turned on again, with whatever value is
+  // still lurking in the A0 + chan register, but everything else -
+  // including the two most significant frequency bit, and the octave -
+  // set to zero.
+  //
+  // This is very strange behaviour, and causes problems with the ancient
+  // FMOPL code we borrowed from AdPlug. I've added a workaround. See
+  // fmopl.cpp for more details.
+  //
+  // More recent versions of the MAME FMOPL don't seem to have this
+  // problem, but cannot currently be used because of licensing and
+  // performance issues.
+  //
+  // Ken Silverman's Adlib emulator (which can be found on his Web page -
+  // http://www.advsys.net/ken - and as part of AdPlug) also seems to be
+  // immune, but is apparently not as feature complete as MAME's.
+
+  writeOPL(0xB0 + chan, 0x20);
+}
+
+// I believe this is a random number generator. It actually does seem to
+// generate an even distribution of almost all numbers from 0 through 65535,
+// though in my tests some numbers were never generated.
+
+uint16 AdlibDriver::getRandomNr() {
+  _rnd += 0x9248;
+  uint16 lowBits = _rnd & 7;
+  _rnd >>= 3;
+  _rnd |= (lowBits << 13);
+  return _rnd;
+}
+
+void AdlibDriver::setupDuration(uint8 duration, Channel &channel) {
+  debugC(9, kDebugLevelSound, "setupDuration(%d, %lu)", duration, (long)(&channel - _channels));
+  if (channel.durationRandomness) {
+    channel.duration = duration + (getRandomNr() & channel.durationRandomness);
+    return;
+  }
+  if (channel.fractionalSpacing) {
+    channel.spacing2 = (duration >> 3) * channel.fractionalSpacing;
+  }
+  channel.duration = duration;
+}
+
+// This function may or may not play the note. It's usually followed by a call
+// to noteOn(), which will always play the current note.
+
+void AdlibDriver::setupNote(uint8 rawNote, Channel &channel, bool flag) {
+  debugC(9, kDebugLevelSound, "setupNote(%d, %lu)", rawNote, (long)(&channel - _channels));
+
+  channel.rawNote = rawNote;
+
+  int8 note = (rawNote & 0x0F) + channel.baseNote;
+  int8 octave = ((rawNote + channel.baseOctave) >> 4) & 0x0F;
+
+  // There are only twelve notes. If we go outside that, we have to
+  // adjust the note and octave.
+
+  if (note >= 12) {
+    note -= 12;
+    octave++;
+  } else if (note < 0) {
+    note += 12;
+    octave--;
+  }
+
+  // The calculation of frequency looks quite different from the original
+  // disassembly at a first glance, but when you consider that the
+  // largest possible value would be 0x0246 + 0xFF + 0x47 (and that's if
+  // baseFreq is unsigned), freq is still a 10-bit value, just as it
+  // should be to fit in the Ax and Bx registers.
+  //
+  // If it were larger than that, it could have overflowed into the
+  // octave bits, and that could possibly have been used in some sound.
+  // But as it is now, I can't see any way it would happen.
+
+  uint16 freq = _unkTable[note] + channel.baseFreq;
+
+  // When called from callback 41, the behaviour is slightly different:
+  // We adjust the frequency, even when channel.unk16 is 0.
+
+  if (channel.unk16 || flag) {
+    const uint8 *table;
+
+    if (channel.unk16 >= 0) {
+      table = _unkTables[(channel.rawNote & 0x0F) + 2];
+      freq += table[channel.unk16];
+    } else {
+      table = _unkTables[channel.rawNote & 0x0F];
+      freq -= table[-channel.unk16];
+    }
+  }
+
+  channel.regAx = freq & 0xFF;
+  channel.regBx = (channel.regBx & 0x20) | (octave << 2) | ((freq >> 8) & 0x03);
+
+  // Keep the note on or off
+  writeOPL(0xA0 + _curChannel, channel.regAx);
+  writeOPL(0xB0 + _curChannel, channel.regBx);
+}
+
+void AdlibDriver::setupInstrument(uint8 regOffset, uint8 *dataptr, Channel &channel) {
+  debugC(9, kDebugLevelSound, "setupInstrument(%d, %p, %lu)", regOffset, (const void *)dataptr, (long)(&channel - _channels));
+  // Amplitude Modulation / Vibrato / Envelope Generator Type /
+  // Keyboard Scaling Rate / Modulator Frequency Multiple
+  writeOPL(0x20 + regOffset, *dataptr++);
+  writeOPL(0x23 + regOffset, *dataptr++);
+
+  uint8 temp = *dataptr++;
+
+  // Feedback / Algorithm
+
+  // It is very likely that _curChannel really does refer to the same
+  // channel as regOffset, but there's only one Cx register per channel.
+
+  writeOPL(0xC0 + _curChannel, temp);
+
+  // The algorithm bit. I don't pretend to understand this fully, but
+  // "If set to 0, operator 1 modulates operator 2. In this case,
+  // operator 2 is the only one producing sound. If set to 1, both
+  // operators produce sound directly. Complex sounds are more easily
+  // created if the algorithm is set to 0."
+
+  channel.twoChan = temp & 1;
+
+  // Waveform Select
+  writeOPL(0xE0 + regOffset, *dataptr++);
+  writeOPL(0xE3 + regOffset, *dataptr++);
+
+  channel.opLevel1 = *dataptr++;
+  channel.opLevel2 = *dataptr++;
+
+  // Level Key Scaling / Total Level
+  writeOPL(0x40 + regOffset, calculateOpLevel1(channel));
+  writeOPL(0x43 + regOffset, calculateOpLevel2(channel));
+
+  // Attack Rate / Decay Rate
+  writeOPL(0x60 + regOffset, *dataptr++);
+  writeOPL(0x63 + regOffset, *dataptr++);
+
+  // Sustain Level / Release Rate
+  writeOPL(0x80 + regOffset, *dataptr++);
+  writeOPL(0x83 + regOffset, *dataptr++);
+}
+
+// Apart from playing the note, this function also updates the variables for
+// primary effect 2.
+
+void AdlibDriver::noteOn(Channel &channel) {
+  debugC(9, kDebugLevelSound, "noteOn(%lu)", (long)(&channel - _channels));
+
+  // The "note on" bit is set, and the current note is played.
+
+  channel.regBx |= 0x20;
+  writeOPL(0xB0 + _curChannel, channel.regBx);
+
+  int8 shift = 9 - channel.unk33;
+  uint16 temp = channel.regAx | (channel.regBx << 8);
+  channel.unk37 = ((temp & 0x3FF) >> shift) & 0xFF;
+  channel.unk38 = channel.unk36;
+}
+
+void AdlibDriver::adjustVolume(Channel &channel) {
+  debugC(9, kDebugLevelSound, "adjustVolume(%lu)", (long)(&channel - _channels));
+  // Level Key Scaling / Total Level
+
+  writeOPL(0x43 + _regOffset[_curChannel], calculateOpLevel2(channel));
+  if (channel.twoChan)
+    writeOPL(0x40 + _regOffset[_curChannel], calculateOpLevel1(channel));
+}
+
+// This is presumably only used for some sound effects, e.g. Malcolm blowing up
+// the trees in the intro (but not the effect where he "booby-traps" the big
+// tree) and turning Kallak to stone. Related functions and variables:
+//
+// update_setupPrimaryEffect1()
+//    - Initialises unk29, unk30 and unk31
+//    - unk29 is not further modified
+//    - unk30 is not further modified, except by update_removePrimaryEffect1()
+//
+// update_removePrimaryEffect1()
+//    - Deinitialises unk30
+//
+// unk29 - determines how often the notes are played
+// unk30 - modifies the frequency
+// unk31 - determines how often the notes are played
+
+void AdlibDriver::primaryEffect1(Channel &channel) {
+  debugC(9, kDebugLevelSound, "Calling primaryEffect1 (channel: %d)", _curChannel);
+  uint8 temp = channel.unk31;
+  channel.unk31 += channel.unk29;
+  if (channel.unk31 >= temp)
+    return;
+
+  // Initialise unk1 to the current frequency
+  uint16 unk1 = ((channel.regBx & 3) << 8) | channel.regAx;
+
+  // This is presumably to shift the "note on" bit so far to the left
+  // that it won't be affected by any of the calculations below.
+  uint16 unk2 = ((channel.regBx & 0x20) << 8) | (channel.regBx & 0x1C);
+
+  int16 unk3 = (int16)channel.unk30;
+
+  if (unk3 >= 0) {
+    unk1 += unk3;
+    if (unk1 >= 734) {
+      // The new frequency is too high. Shift it down and go
+      // up one octave.
+      unk1 >>= 1;
+      if (!(unk1 & 0x3FF))
+	++unk1;
+      unk2 = (unk2 & 0xFF00) | ((unk2 + 4) & 0xFF);
+      unk2 &= 0xFF1C;
+    }
+  } else {
+    unk1 += unk3;
+    if (unk1 < 388) {
+      // The new frequency is too low. Shift it up and go
+      // down one octave.
+      unk1 <<= 1;
+      if (!(unk1 & 0x3FF))
+	--unk1;
+      unk2 = (unk2 & 0xFF00) | ((unk2 - 4) & 0xFF);
+      unk2 &= 0xFF1C;
+    }
+  }
+
+  // Make sure that the new frequency is still a 10-bit value.
+  unk1 &= 0x3FF;
+
+  writeOPL(0xA0 + _curChannel, unk1 & 0xFF);
+  channel.regAx = unk1 & 0xFF;
+
+  // Shift down the "note on" bit again.
+  uint8 value = unk1 >> 8;
+  value |= (unk2 >> 8) & 0xFF;
+  value |= unk2 & 0xFF;
+
+  writeOPL(0xB0 + _curChannel, value);
+  channel.regBx = value;
+}
+
+// This is presumably only used for some sound effects, e.g. Malcolm entering
+// and leaving Kallak's hut. Related functions and variables:
+//
+// update_setupPrimaryEffect2()
+//    - Initialises unk32, unk33, unk34, unk35 and unk36
+//    - unk32 is not further modified
+//    - unk33 is not further modified
+//    - unk34 is a countdown that gets reinitialised to unk35 on zero
+//    - unk35 is based on unk34 and not further modified
+//    - unk36 is not further modified
+//
+// noteOn()
+//    - Plays the current note
+//    - Updates unk37 with a new (lower?) frequency
+//    - Copies unk36 to unk38. The unk38 variable is a countdown.
+//
+// unk32 - determines how often the notes are played
+// unk33 - modifies the frequency
+// unk34 - countdown, updates frequency on zero
+// unk35 - initialiser for unk34 countdown
+// unk36 - initialiser for unk38 countdown
+// unk37 - frequency
+// unk38 - countdown, begins playing on zero
+// unk41 - determines how often the notes are played
+//
+// Note that unk41 is never initialised. Not that it should matter much, but it
+// is a bit sloppy.
+
+void AdlibDriver::primaryEffect2(Channel &channel) {
+  debugC(9, kDebugLevelSound, "Calling primaryEffect2 (channel: %d)", _curChannel);
+  if (channel.unk38) {
+    --channel.unk38;
+    return;
+  }
+
+  uint8 temp = channel.unk41;
+  channel.unk41 += channel.unk32;
+  if (channel.unk41 < temp) {
+    uint16 unk1 = channel.unk37;
+    if (!(--channel.unk34)) {
+      unk1 ^= 0xFFFF;
+      ++unk1;
+      channel.unk37 = unk1;
+      channel.unk34 = channel.unk35;
+    }
+
+    uint16 unk2 = (channel.regAx | (channel.regBx << 8)) & 0x3FF;
+    unk2 += unk1;
+		
+    channel.regAx = unk2 & 0xFF;
+    channel.regBx = (channel.regBx & 0xFC) | (unk2 >> 8);
+
+    // Octave / F-Number / Key-On
+    writeOPL(0xA0 + _curChannel, channel.regAx);
+    writeOPL(0xB0 + _curChannel, channel.regBx);
+  }
+}
+
+// I don't know where this is used. The same operation is performed several
+// times on the current channel, using a chunk of the _soundData[] buffer for
+// parameters. The parameters are used starting at the end of the chunk.
+//
+// Since we use _curRegOffset to specify the final register, it's quite
+// unlikely that this function is ever used to play notes. It's probably only
+// used to modify the sound. Another thing that supports this idea is that it
+// can be combined with any of the effects callbacks above.
+//
+// Related functions and variables:
+//
+// update_setupSecondaryEffect1()
+//    - Initialies unk18, unk19, unk20, unk21, unk22 and offset
+//    - unk19 is not further modified
+//    - unk20 is not further modified
+//    - unk22 is not further modified
+//    - offset is not further modified
+//
+// unk18 -  determines how often the operation is performed
+// unk19 -  determines how often the operation is performed
+// unk20 -  the start index into the data chunk
+// unk21 -  the current index into the data chunk
+// unk22 -  the operation to perform
+// offset - the offset to the data chunk
+
+void AdlibDriver::secondaryEffect1(Channel &channel) {
+  debugC(9, kDebugLevelSound, "Calling secondaryEffect1 (channel: %d)", _curChannel);
+  uint8 temp = channel.unk18;
+  channel.unk18 += channel.unk19;
+  if (channel.unk18 < temp) {
+    if (--channel.unk21 < 0) {
+      channel.unk21 = channel.unk20;
+    }
+    writeOPL(channel.unk22 + _curRegOffset, _soundData[channel.offset + channel.unk21]);
+  }
+}
+
+uint8 AdlibDriver::calculateOpLevel1(Channel &channel) {
+  int8 value = channel.opLevel1 & 0x3F;
+
+  if (channel.twoChan) {
+    value += channel.opExtraLevel1;
+    value += channel.opExtraLevel2;
+    value += channel.opExtraLevel3;
+  }
+
+  // Preserve the scaling level bits from opLevel1
+
+  return checkValue(value) | (channel.opLevel1 & 0xC0);
+}
+
+uint8 AdlibDriver::calculateOpLevel2(Channel &channel) {
+  int8 value = channel.opLevel2 & 0x3F;
+
+  value += channel.opExtraLevel1;
+  value += channel.opExtraLevel2;
+  value += channel.opExtraLevel3;
+
+  // Preserve the scaling level bits from opLevel2
+
+  return checkValue(value) | (channel.opLevel2 & 0xC0);
+}
+
+// parser opcodes
+
+int AdlibDriver::update_setRepeat(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.repeatCounter = value;
+  return 0;
+}
+
+int AdlibDriver::update_checkRepeat(uint8 *&dataptr, Channel &channel, uint8 value) {
+  ++dataptr;
+  if (--channel.repeatCounter) {
+    int16 add = READ_LE_UINT16(dataptr - 2);
+    dataptr += add;
+  }
+  return 0;
+}
+
+int AdlibDriver::update_setupProgram(uint8 *&dataptr, Channel &channel, uint8 value) {
+  if (value == 0xFF)
+    return 0;
+
+  uint8 *ptr = getProgram(value);
+  uint8 chan = *ptr++;
+  uint8 priority = *ptr++;
+
+  Channel &channel2 = _channels[chan];
+
+  if (priority >= channel2.priority) {
+    _flagTrigger = 1;
+    _flags |= 8;
+    initChannel(channel2);
+    channel2.priority = priority;
+    channel2.dataptr = ptr;
+    channel2.tempo = 0xFF;
+    channel2.position = 0xFF;
+    channel2.duration = 1;
+    unkOutput2(chan);
+  }
+
+  return 0;
+}
+
+int AdlibDriver::update_setNoteSpacing(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.spacing1 = value;
+  return 0;
+}
+
+int AdlibDriver::update_jump(uint8 *&dataptr, Channel &channel, uint8 value) {
+  --dataptr;
+  int16 add = READ_LE_UINT16(dataptr); dataptr += 2;
+  dataptr += add;
+  return 0;
+}
+
+int AdlibDriver::update_jumpToSubroutine(uint8 *&dataptr, Channel &channel, uint8 value) {
+  --dataptr;
+  int16 add = READ_LE_UINT16(dataptr); dataptr += 2;
+  channel.dataptrStack[channel.dataptrStackPos++] = dataptr;
+  dataptr += add;
+  return 0;
+}
+
+int AdlibDriver::update_returnFromSubroutine(uint8 *&dataptr, Channel &channel, uint8 value) {
+  dataptr = channel.dataptrStack[--channel.dataptrStackPos];
+  return 0;
+}
+
+int AdlibDriver::update_setBaseOctave(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.baseOctave = value;
+  return 0;
+}
+
+int AdlibDriver::update_stopChannel(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.priority = 0;
+  if (_curChannel != 9) {
+    noteOff(channel);
+  }
+  dataptr = 0;
+  return 2;
+}
+
+int AdlibDriver::update_playRest(uint8 *&dataptr, Channel &channel, uint8 value) {
+  setupDuration(value, channel);
+  noteOff(channel);
+  return (value != 0);
+}
+
+int AdlibDriver::update_writeAdlib(uint8 *&dataptr, Channel &channel, uint8 value) {
+  writeOPL(value, *dataptr++);
+  return 0;
+}
+
+int AdlibDriver::update_setupNoteAndDuration(uint8 *&dataptr, Channel &channel, uint8 value) {
+  setupNote(value, channel);
+  value = *dataptr++;
+  setupDuration(value, channel);
+  return (value != 0);
+}
+
+int AdlibDriver::update_setBaseNote(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.baseNote = value;
+  return 0;
+}
+
+int AdlibDriver::update_setupSecondaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.unk18 = value;
+  channel.unk19 = value;
+  channel.unk20 = channel.unk21 = *dataptr++;
+  channel.unk22 = *dataptr++;
+  channel.offset = READ_LE_UINT16(dataptr); dataptr += 2;
+  channel.secondaryEffect = &AdlibDriver::secondaryEffect1;
+  return 0;
+}
+
+int AdlibDriver::update_stopOtherChannel(uint8 *&dataptr, Channel &channel, uint8 value) {
+  Channel &channel2 = _channels[value];
+  channel2.duration = 0;
+  channel2.priority = 0;
+  channel2.dataptr = 0;
+  return 0;
+}
+
+int AdlibDriver::update_waitForEndOfProgram(uint8 *&dataptr, Channel &channel, uint8 value) {
+  uint8 *ptr = getProgram(value);
+  uint8 chan = *ptr;
+
+  if (!_channels[chan].dataptr) {
+    return 0;
+  }
+
+  dataptr -= 2;
+  return 2;
+}
+
+int AdlibDriver::update_setupInstrument(uint8 *&dataptr, Channel &channel, uint8 value) {
+  setupInstrument(_curRegOffset, getInstrument(value), channel);
+  return 0;
+}
+
+int AdlibDriver::update_setupPrimaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.unk29 = value;
+  channel.unk30 = READ_BE_UINT16(dataptr);
+  dataptr += 2;
+  channel.primaryEffect = &AdlibDriver::primaryEffect1;
+  channel.unk31 = 0xFF;
+  return 0;
+}
+
+int AdlibDriver::update_removePrimaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value) {
+  --dataptr;
+  channel.primaryEffect = 0;
+  channel.unk30 = 0;
+  return 0;
+}
+
+int AdlibDriver::update_setBaseFreq(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.baseFreq = value;
+  return 0;
+}
+
+int AdlibDriver::update_setupPrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.unk32 = value;
+  channel.unk33 = *dataptr++;
+  uint8 temp = *dataptr++;
+  channel.unk34 = temp + 1;
+  channel.unk35 = temp << 1;
+  channel.unk36 = *dataptr++;
+  channel.primaryEffect = &AdlibDriver::primaryEffect2;
+  return 0;
+}
+
+int AdlibDriver::update_setPriority(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.priority = value;
+  return 0;
+}
+
+int AdlibDriver::updateCallback23(uint8 *&dataptr, Channel &channel, uint8 value) {
+  value >>= 1;
+  _unkValue1 = _unkValue2 = value;
+  _unkValue3 = 0xFF;
+  _unkValue4 = _unkValue5 = 0;
+  return 0;
+}
+
+int AdlibDriver::updateCallback24(uint8 *&dataptr, Channel &channel, uint8 value) {
+  if (_unkValue5) {
+    if (_unkValue4 & value) {
+      _unkValue5 = 0;
+      return 0;
+    }
+  }
+
+  if (!(value & _unkValue4)) {
+    ++_unkValue5;
+  }
+
+  dataptr -= 2;
+  channel.duration = 1;
+  return 2;
+}
+
+int AdlibDriver::update_setExtraLevel1(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.opExtraLevel1 = value;
+  adjustVolume(channel);
+  return 0;
+}
+
+int AdlibDriver::update_setupDuration(uint8 *&dataptr, Channel &channel, uint8 value) {
+  setupDuration(value, channel);
+  return (value != 0);
+}
+
+int AdlibDriver::update_playNote(uint8 *&dataptr, Channel &channel, uint8 value) {
+  setupDuration(value, channel);
+  noteOn(channel);
+  return (value != 0);
+}
+
+int AdlibDriver::update_setFractionalNoteSpacing(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.fractionalSpacing = value & 7;
+  return 0;
+}
+
+int AdlibDriver::update_setTempo(uint8 *&dataptr, Channel &channel, uint8 value) {
+  _tempo = value;
+  return 0;
+}
+
+int AdlibDriver::update_removeSecondaryEffect1(uint8 *&dataptr, Channel &channel, uint8 value) {
+  --dataptr;
+  channel.secondaryEffect = 0;
+  return 0;
+}
+
+int AdlibDriver::update_setChannelTempo(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.tempo = value;
+  return 0;
+}
+
+int AdlibDriver::update_setExtraLevel3(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.opExtraLevel3 = value;
+  return 0;
+}
+
+int AdlibDriver::update_setExtraLevel2(uint8 *&dataptr, Channel &channel, uint8 value) {
+  int channelBackUp = _curChannel;
+
+  _curChannel = value;
+  Channel &channel2 = _channels[value];
+  channel2.opExtraLevel2 = *dataptr++;
+  adjustVolume(channel2);
+
+  _curChannel = channelBackUp;
+  return 0;
+}
+
+int AdlibDriver::update_changeExtraLevel2(uint8 *&dataptr, Channel &channel, uint8 value) {
+  int channelBackUp = _curChannel;
+
+  _curChannel = value;
+  Channel &channel2 = _channels[value];
+  channel2.opExtraLevel2 += *dataptr++;
+  adjustVolume(channel2);
+
+  _curChannel = channelBackUp;
+  return 0;
+}
+
+// Apart from initialising to zero, these two functions are the only ones that
+// modify _vibratoAndAMDepthBits.
+
+int AdlibDriver::update_setAMDepth(uint8 *&dataptr, Channel &channel, uint8 value) {
+  if (value & 1)
+    _vibratoAndAMDepthBits |= 0x80;
+  else
+    _vibratoAndAMDepthBits &= 0x7F;
+
+  writeOPL(0xBD, _vibratoAndAMDepthBits);
+  return 0;
+}
+
+int AdlibDriver::update_setVibratoDepth(uint8 *&dataptr, Channel &channel, uint8 value) {
+  if (value & 1)
+    _vibratoAndAMDepthBits |= 0x40;
+  else
+    _vibratoAndAMDepthBits &= 0xBF;
+
+  writeOPL(0xBD, _vibratoAndAMDepthBits);
+  return 0;
+}
+
+int AdlibDriver::update_changeExtraLevel1(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.opExtraLevel1 += value;
+  adjustVolume(channel);
+  return 0;
+}
+
+int AdlibDriver::updateCallback38(uint8 *&dataptr, Channel &channel, uint8 value) {
+  int channelBackUp = _curChannel;
+
+  _curChannel = value;
+  Channel &channel2 = _channels[value];
+  channel2.duration = channel2.priority = 0;
+  channel2.dataptr = 0;
+  channel2.opExtraLevel2 = 0;
+
+  if (value != 9) {
+    uint8 outValue = _regOffset[value];
+
+    // Feedback strength / Connection type
+    writeOPL(0xC0 + _curChannel, 0x00);
+
+    // Key scaling level / Operator output level
+    writeOPL(0x43 + outValue, 0x3F);
+
+    // Sustain Level / Release Rate
+    writeOPL(0x83 + outValue, 0xFF);
+
+    // Key On / Octave / Frequency
+    writeOPL(0xB0 + _curChannel, 0x00);
+  }
+
+  _curChannel = channelBackUp;
+  return 0;
+}
+
+int AdlibDriver::updateCallback39(uint8 *&dataptr, Channel &channel, uint8 value) {
+  uint16 unk = *dataptr++;
+  unk |= value << 8;
+  unk &= getRandomNr();
+
+  uint16 unk2 = ((channel.regBx & 0x1F) << 8) | channel.regAx;
+  unk2 += unk;
+  unk2 |= ((channel.regBx & 0x20) << 8);
+
+  // Frequency
+  writeOPL(0xA0 + _curChannel, unk2 & 0xFF);
+
+  // Key On / Octave / Frequency
+  writeOPL(0xB0 + _curChannel, (unk2 & 0xFF00) >> 8);
+
+  return 0;
+}
+
+int AdlibDriver::update_removePrimaryEffect2(uint8 *&dataptr, Channel &channel, uint8 value) {
+  --dataptr;
+  channel.primaryEffect = 0;
+  return 0;
+}
+
+int AdlibDriver::updateCallback41(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.unk16 = value;
+  setupNote(channel.rawNote, channel, true);
+  return 0;
+}
+
+int AdlibDriver::update_resetToGlobalTempo(uint8 *&dataptr, Channel &channel, uint8 value) {
+  --dataptr;
+  channel.tempo = _tempo;
+  return 0;
+}
+
+int AdlibDriver::update_nop1(uint8 *&dataptr, Channel &channel, uint8 value) {
+  --dataptr;
+  return 0;
+}
+
+int AdlibDriver::update_setDurationRandomness(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.durationRandomness = value;
+  return 0;
+}
+
+int AdlibDriver::update_changeChannelTempo(uint8 *&dataptr, Channel &channel, uint8 value) {
+  int tempo = channel.tempo + (int8)value;
+
+  if (tempo <= 0)
+    tempo = 1;
+  else if (tempo > 255)
+    tempo = 255;
+
+  channel.tempo = tempo;
+  return 0;
+}
+
+int AdlibDriver::updateCallback46(uint8 *&dataptr, Channel &channel, uint8 value) {
+  uint8 entry = *dataptr++;
+  _tablePtr1 = _unkTable2[entry++];
+  _tablePtr2 = _unkTable2[entry];
+  if (value == 2) {
+    // Frequency
+    writeOPL(0xA0, _tablePtr2[0]);
+  }
+  return 0;
+}
+
+// TODO: This is really the same as update_nop1(), so they should be combined
+//       into one single update_nop().
+
+int AdlibDriver::update_nop2(uint8 *&dataptr, Channel &channel, uint8 value) {
+  --dataptr;
+  return 0;
+}
+
+int AdlibDriver::update_setupRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value) {
+  int channelBackUp = _curChannel;
+  int regOffsetBackUp = _curRegOffset;
+
+  _curChannel = 6;
+  _curRegOffset = _regOffset[6];
+
+  setupInstrument(_curRegOffset, getInstrument(value), channel);
+  _unkValue6 = channel.opLevel2;
+
+  _curChannel = 7;
+  _curRegOffset = _regOffset[7];
+
+  setupInstrument(_curRegOffset, getInstrument(*dataptr++), channel);
+  _unkValue7 = channel.opLevel1;
+  _unkValue8 = channel.opLevel2;
+
+  _curChannel = 8;
+  _curRegOffset = _regOffset[8];
+
+  setupInstrument(_curRegOffset, getInstrument(*dataptr++), channel);
+  _unkValue9 = channel.opLevel1;
+  _unkValue10 = channel.opLevel2;
+
+  // Octave / F-Number / Key-On for channels 6, 7 and 8
+
+  _channels[6].regBx = *dataptr++ & 0x2F;
+  writeOPL(0xB6, _channels[6].regBx);
+  writeOPL(0xA6, *dataptr++);
+
+  _channels[7].regBx = *dataptr++ & 0x2F;
+  writeOPL(0xB7, _channels[7].regBx);
+  writeOPL(0xA7, *dataptr++);
+
+  _channels[8].regBx = *dataptr++ & 0x2F;
+  writeOPL(0xB8, _channels[8].regBx);
+  writeOPL(0xA8, *dataptr++);
+
+  _rhythmSectionBits = 0x20;
+
+  _curRegOffset = regOffsetBackUp;
+  _curChannel = channelBackUp;
+  return 0;
+}
+
+int AdlibDriver::update_playRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value) {
+  // Any instrument that we want to play, and which was already playing,
+  // is temporarily keyed off. Instruments that were off already, or
+  // which we don't want to play, retain their old on/off status. This is
+  // probably so that the instrument's envelope is played from its
+  // beginning again...
+
+  writeOPL(0xBD, (_rhythmSectionBits & ~(value & 0x1F)) | 0x20);
+
+  // ...but since we only set the rhythm instrument bits, and never clear
+  // them (until the entire rhythm section is disabled), I'm not sure how
+  // useful the cleverness above is. We could perhaps simply turn off all
+  // the rhythm instruments instead.
+
+  _rhythmSectionBits |= value;
+
+  writeOPL(0xBD, _vibratoAndAMDepthBits | 0x20 | _rhythmSectionBits);
+  return 0;
+}
+
+int AdlibDriver::update_removeRhythmSection(uint8 *&dataptr, Channel &channel, uint8 value) {
+  --dataptr;
+  _rhythmSectionBits = 0;
+
+  // All the rhythm bits are cleared. The AM and Vibrato depth bits
+  // remain unchanged.
+
+  writeOPL(0xBD, _vibratoAndAMDepthBits);
+  return 0;
+}
+
+int AdlibDriver::updateCallback51(uint8 *&dataptr, Channel &channel, uint8 value) {
+  uint8 value2 = *dataptr++;
+
+  if (value & 1) {
+    _unkValue12 = value2;
+
+    // Channel 7, op1: Level Key Scaling / Total Level
+    writeOPL(0x51, checkValue(value2 + _unkValue7 + _unkValue11 + _unkValue12));
+  }
+
+  if (value & 2) {
+    _unkValue14 = value2;
+
+    // Channel 8, op2: Level Key Scaling / Total Level
+    writeOPL(0x55, checkValue(value2 + _unkValue10 + _unkValue13 + _unkValue14));
+  }
+
+  if (value & 4) {
+    _unkValue15 = value2;
+
+    // Channel 8, op1: Level Key Scaling / Total Level
+    writeOPL(0x52, checkValue(value2 + _unkValue9 + _unkValue16 + _unkValue15));
+  }
+
+  if (value & 8) {
+    _unkValue18 = value2;
+
+    // Channel 7, op2: Level Key Scaling / Total Level
+    writeOPL(0x54, checkValue(value2 + _unkValue8 + _unkValue17 + _unkValue18));
+  }
+
+  if (value & 16) {
+    _unkValue20 = value2;
+
+    // Channel 6, op2: Level Key Scaling / Total Level
+    writeOPL(0x53, checkValue(value2 + _unkValue6 + _unkValue19 + _unkValue20));
+  }
+
+  return 0;
+}
+
+int AdlibDriver::updateCallback52(uint8 *&dataptr, Channel &channel, uint8 value) {
+  uint8 value2 = *dataptr++;
+
+  if (value & 1) {
+    _unkValue11 = checkValue(value2 + _unkValue7 + _unkValue11 + _unkValue12);
+
+    // Channel 7, op1: Level Key Scaling / Total Level
+    writeOPL(0x51, _unkValue11);
+  }
+
+  if (value & 2) {
+    _unkValue13 = checkValue(value2 + _unkValue10 + _unkValue13 + _unkValue14);
+
+    // Channel 8, op2: Level Key Scaling / Total Level
+    writeOPL(0x55, _unkValue13);
+  }
+
+  if (value & 4) {
+    _unkValue16 = checkValue(value2 + _unkValue9 + _unkValue16 + _unkValue15);
+
+    // Channel 8, op1: Level Key Scaling / Total Level
+    writeOPL(0x52, _unkValue16);
+  }
+
+  if (value & 8) {
+    _unkValue17 = checkValue(value2 + _unkValue8 + _unkValue17 + _unkValue18);
+
+    // Channel 7, op2: Level Key Scaling / Total Level
+    writeOPL(0x54, _unkValue17);
+  }
+
+  if (value & 16) {
+    _unkValue19 = checkValue(value2 + _unkValue6 + _unkValue19 + _unkValue20);
+
+    // Channel 6, op2: Level Key Scaling / Total Level
+    writeOPL(0x53, _unkValue19);
+  }
+
+  return 0;
+}
+
+int AdlibDriver::updateCallback53(uint8 *&dataptr, Channel &channel, uint8 value) {
+  uint8 value2 = *dataptr++;
+
+  if (value & 1) {
+    _unkValue11 = value2;
+
+    // Channel 7, op1: Level Key Scaling / Total Level
+    writeOPL(0x51, checkValue(value2 + _unkValue7 + _unkValue12));
+  }
+
+  if (value & 2) {
+    _unkValue13 = value2;
+
+    // Channel 8, op2: Level Key Scaling / Total Level
+    writeOPL(0x55, checkValue(value2 + _unkValue10 + _unkValue14));
+  }
+
+  if (value & 4) {
+    _unkValue16 = value2;
+
+    // Channel 8, op1: Level Key Scaling / Total Level
+    writeOPL(0x52, checkValue(value2 + _unkValue9 + _unkValue15));
+  }
+
+  if (value & 8) {
+    _unkValue17 = value2;
+
+    // Channel 7, op2: Level Key Scaling / Total Level
+    writeOPL(0x54, checkValue(value2 + _unkValue8 + _unkValue18));
+  }
+
+  if (value & 16) {
+    _unkValue19 = value2;
+
+    // Channel 6, op2: Level Key Scaling / Total Level
+    writeOPL(0x53, checkValue(value2 + _unkValue6 + _unkValue20));
+  }
+
+  return 0;
+}
+
+int AdlibDriver::update_setSoundTrigger(uint8 *&dataptr, Channel &channel, uint8 value) {
+  _soundTrigger = value;
+  return 0;
+}
+
+int AdlibDriver::update_setTempoReset(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.tempoReset = value;
+  return 0;
+}
+
+int AdlibDriver::updateCallback56(uint8 *&dataptr, Channel &channel, uint8 value) {
+  channel.unk39 = value;
+  channel.unk40 = *dataptr++;
+  return 0;
+}
+
+// static res
+
+#define COMMAND(x) { &AdlibDriver::x, #x }
+
+void AdlibDriver::setupOpcodeList() {
+  static const OpcodeEntry opcodeList[] = {
+    COMMAND(snd_ret0x100),
+    COMMAND(snd_ret0x1983),
+    COMMAND(snd_initDriver),
+    COMMAND(snd_deinitDriver),
+    COMMAND(snd_setSoundData),
+    COMMAND(snd_unkOpcode1),
+    COMMAND(snd_startSong),
+    COMMAND(snd_unkOpcode2),
+    COMMAND(snd_unkOpcode3),
+    COMMAND(snd_readByte),
+    COMMAND(snd_writeByte),
+    COMMAND(snd_getSoundTrigger),
+    COMMAND(snd_unkOpcode4),
+    COMMAND(snd_dummy),
+    COMMAND(snd_getNullvar4),
+    COMMAND(snd_setNullvar3),
+    COMMAND(snd_setFlag),
+    COMMAND(snd_clearFlag)
+  };
+
+  _opcodeList = opcodeList;
+  _opcodesEntries = ARRAYSIZE(opcodeList);
+}
+
+void AdlibDriver::setupParserOpcodeTable() {
+  static const ParserOpcode parserOpcodeTable[] = {
+    // 0
+    COMMAND(update_setRepeat),
+    COMMAND(update_checkRepeat),
+    COMMAND(update_setupProgram),
+    COMMAND(update_setNoteSpacing),
+
+    // 4
+    COMMAND(update_jump),
+    COMMAND(update_jumpToSubroutine),
+    COMMAND(update_returnFromSubroutine),
+    COMMAND(update_setBaseOctave),
+
+    // 8
+    COMMAND(update_stopChannel),
+    COMMAND(update_playRest),
+    COMMAND(update_writeAdlib),
+    COMMAND(update_setupNoteAndDuration),
+
+    // 12
+    COMMAND(update_setBaseNote),
+    COMMAND(update_setupSecondaryEffect1),
+    COMMAND(update_stopOtherChannel),
+    COMMAND(update_waitForEndOfProgram),
+
+    // 16
+    COMMAND(update_setupInstrument),
+    COMMAND(update_setupPrimaryEffect1),
+    COMMAND(update_removePrimaryEffect1),
+    COMMAND(update_setBaseFreq),
+
+    // 20
+    COMMAND(update_stopChannel),
+    COMMAND(update_setupPrimaryEffect2),
+    COMMAND(update_stopChannel),
+    COMMAND(update_stopChannel),
+
+    // 24
+    COMMAND(update_stopChannel),
+    COMMAND(update_stopChannel),
+    COMMAND(update_setPriority),
+    COMMAND(update_stopChannel),
+
+    // 28
+    COMMAND(updateCallback23),
+    COMMAND(updateCallback24),
+    COMMAND(update_setExtraLevel1),
+    COMMAND(update_stopChannel),
+
+    // 32
+    COMMAND(update_setupDuration),
+    COMMAND(update_playNote),
+    COMMAND(update_stopChannel),
+    COMMAND(update_stopChannel),
+
+    // 36
+    COMMAND(update_setFractionalNoteSpacing),
+    COMMAND(update_stopChannel),
+    COMMAND(update_setTempo),
+    COMMAND(update_removeSecondaryEffect1),
+
+    // 40
+    COMMAND(update_stopChannel),
+    COMMAND(update_setChannelTempo),
+    COMMAND(update_stopChannel),
+    COMMAND(update_setExtraLevel3),
+
+    // 44
+    COMMAND(update_setExtraLevel2),
+    COMMAND(update_changeExtraLevel2),
+    COMMAND(update_setAMDepth),
+    COMMAND(update_setVibratoDepth),
+
+    // 48
+    COMMAND(update_changeExtraLevel1),
+    COMMAND(update_stopChannel),
+    COMMAND(update_stopChannel),
+    COMMAND(updateCallback38),
+
+    // 52
+    COMMAND(update_stopChannel),
+    COMMAND(updateCallback39),
+    COMMAND(update_removePrimaryEffect2),
+    COMMAND(update_stopChannel),
+
+    // 56
+    COMMAND(update_stopChannel),
+    COMMAND(updateCallback41),
+    COMMAND(update_resetToGlobalTempo),
+    COMMAND(update_nop1),
+
+    // 60
+    COMMAND(update_setDurationRandomness),
+    COMMAND(update_changeChannelTempo),
+    COMMAND(update_stopChannel),
+    COMMAND(updateCallback46),
+
+    // 64
+    COMMAND(update_nop2),
+    COMMAND(update_setupRhythmSection),
+    COMMAND(update_playRhythmSection),
+    COMMAND(update_removeRhythmSection),
+
+    // 68
+    COMMAND(updateCallback51),
+    COMMAND(updateCallback52),
+    COMMAND(updateCallback53),
+    COMMAND(update_setSoundTrigger),
+
+    // 72
+    COMMAND(update_setTempoReset),
+    COMMAND(updateCallback56),
+    COMMAND(update_stopChannel)
+  };
+
+  _parserOpcodeTable = parserOpcodeTable;
+  _parserOpcodeTableSize = ARRAYSIZE(parserOpcodeTable);
+}
+#undef COMMAND
+
+// This table holds the register offset for operator 1 for each of the nine
+// channels. To get the register offset for operator 2, simply add 3.
+
+const uint8 AdlibDriver::_regOffset[] = {
+  0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11,
+  0x12
+};
+
+// Given the size of this table, and the range of its values, it's probably the
+// F-Numbers (10 bits) for the notes of the 12-tone scale. However, it does not
+// match the table in the Adlib documentation I've seen.
+
+const uint16 AdlibDriver::_unkTable[] = {
+  0x0134, 0x0147, 0x015A, 0x016F, 0x0184, 0x019C, 0x01B4, 0x01CE, 0x01E9,
+  0x0207, 0x0225, 0x0246
+};
+
+// These tables are currently only used by updateCallback46(), which only ever
+// uses the first element of one of the sub-tables.
+
+const uint8 *AdlibDriver::_unkTable2[] = {
+  AdlibDriver::_unkTable2_1,
+  AdlibDriver::_unkTable2_2,
+  AdlibDriver::_unkTable2_1,
+  AdlibDriver::_unkTable2_2,
+  AdlibDriver::_unkTable2_3,
+  AdlibDriver::_unkTable2_2
+};
+
+const uint8 AdlibDriver::_unkTable2_1[] = {
+  0x50, 0x50, 0x4F, 0x4F, 0x4E, 0x4E, 0x4D, 0x4D,
+  0x4C, 0x4C, 0x4B, 0x4B, 0x4A, 0x4A, 0x49, 0x49,
+  0x48, 0x48, 0x47, 0x47, 0x46, 0x46, 0x45, 0x45,
+  0x44, 0x44, 0x43, 0x43, 0x42, 0x42, 0x41, 0x41,
+  0x40, 0x40, 0x3F, 0x3F, 0x3E, 0x3E, 0x3D, 0x3D,
+  0x3C, 0x3C, 0x3B, 0x3B, 0x3A, 0x3A, 0x39, 0x39,
+  0x38, 0x38, 0x37, 0x37, 0x36, 0x36, 0x35, 0x35,
+  0x34, 0x34, 0x33, 0x33, 0x32, 0x32, 0x31, 0x31,
+  0x30, 0x30, 0x2F, 0x2F, 0x2E, 0x2E, 0x2D, 0x2D,
+  0x2C, 0x2C, 0x2B, 0x2B, 0x2A, 0x2A, 0x29, 0x29,
+  0x28, 0x28, 0x27, 0x27, 0x26, 0x26, 0x25, 0x25,
+  0x24, 0x24, 0x23, 0x23, 0x22, 0x22, 0x21, 0x21,
+  0x20, 0x20, 0x1F, 0x1F, 0x1E, 0x1E, 0x1D, 0x1D,
+  0x1C, 0x1C, 0x1B, 0x1B, 0x1A, 0x1A, 0x19, 0x19,
+  0x18, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15,
+  0x14, 0x14, 0x13, 0x13, 0x12, 0x12, 0x11, 0x11,
+  0x10, 0x10
+};
+
+// no don't ask me WHY this table exsits!
+const uint8 AdlibDriver::_unkTable2_2[] = {
+  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+  0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+  0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+  0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
+  0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+  0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
+  0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+  0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
+  0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+  0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
+  0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+  0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x6F,
+  0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+  0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
+  0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+  0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F
+};
+
+const uint8 AdlibDriver::_unkTable2_3[] = {
+  0x40, 0x40, 0x40, 0x3F, 0x3F, 0x3F, 0x3E, 0x3E,
+  0x3E, 0x3D, 0x3D, 0x3D, 0x3C, 0x3C, 0x3C, 0x3B,
+  0x3B, 0x3B, 0x3A, 0x3A, 0x3A, 0x39, 0x39, 0x39,
+  0x38, 0x38, 0x38, 0x37, 0x37, 0x37, 0x36, 0x36,
+  0x36, 0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x33,
+  0x33, 0x33, 0x32, 0x32, 0x32, 0x31, 0x31, 0x31,
+  0x30, 0x30, 0x30, 0x2F, 0x2F, 0x2F, 0x2E, 0x2E,
+  0x2E, 0x2D, 0x2D, 0x2D, 0x2C, 0x2C, 0x2C, 0x2B,
+  0x2B, 0x2B, 0x2A, 0x2A, 0x2A, 0x29, 0x29, 0x29,
+  0x28, 0x28, 0x28, 0x27, 0x27, 0x27, 0x26, 0x26,
+  0x26, 0x25, 0x25, 0x25, 0x24, 0x24, 0x24, 0x23,
+  0x23, 0x23, 0x22, 0x22, 0x22, 0x21, 0x21, 0x21,
+  0x20, 0x20, 0x20, 0x1F, 0x1F, 0x1F, 0x1E, 0x1E,
+  0x1E, 0x1D, 0x1D, 0x1D, 0x1C, 0x1C, 0x1C, 0x1B,
+  0x1B, 0x1B, 0x1A, 0x1A, 0x1A, 0x19, 0x19, 0x19,
+  0x18, 0x18, 0x18, 0x17, 0x17, 0x17, 0x16, 0x16,
+  0x16, 0x15
+};
+
+// This table is used to modify the frequency of the notes, depending on the
+// note value and unk16. In theory, we could very well try to access memory
+// outside this table, but in reality that probably won't happen.
+//
+// This could be some sort of pitch bend, but I have yet to see it used for
+// anything so it's hard to say.
+
+const uint8 AdlibDriver::_unkTables[][32] = {
+  // 0
+  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x08,
+    0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10,
+    0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x19,
+    0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21 },
+  // 1
+  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x07, 0x09,
+    0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11,
+    0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x1A,
+    0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x22, 0x24 },
+  // 2
+  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x09,
+    0x0A, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12, 0x13,
+    0x14, 0x15, 0x16, 0x17, 0x19, 0x1A, 0x1C, 0x1D,
+    0x1E, 0x1F, 0x20, 0x21, 0x22, 0x24, 0x25, 0x26 },
+  // 3
+  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0A,
+    0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x12, 0x13,
+    0x14, 0x15, 0x16, 0x17, 0x18, 0x1A, 0x1C, 0x1D,
+    0x1E, 0x1F, 0x20, 0x21, 0x23, 0x25, 0x27, 0x28 },
+  // 4
+  { 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x08, 0x0A,
+    0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x11, 0x13, 0x15,
+    0x16, 0x17, 0x18, 0x19, 0x1B, 0x1D, 0x1F, 0x20,
+    0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x28, 0x2A },
+  // 5
+  { 0x00, 0x01, 0x02, 0x03, 0x05, 0x07, 0x09, 0x0B,
+    0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15,
+    0x16, 0x17, 0x18, 0x19, 0x1B, 0x1D, 0x1F, 0x20,
+    0x21, 0x22, 0x23, 0x25, 0x27, 0x29, 0x2B, 0x2D },
+  // 6
+  { 0x00, 0x01, 0x02, 0x03, 0x05, 0x07, 0x09, 0x0B,
+    0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15,
+    0x16, 0x17, 0x18, 0x1A, 0x1C, 0x1E, 0x21, 0x24,
+    0x25, 0x26, 0x27, 0x29, 0x2B, 0x2D, 0x2F, 0x30 },
+  // 7
+  { 0x00, 0x01, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C,
+    0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x13, 0x15, 0x18,
+    0x19, 0x1A, 0x1C, 0x1D, 0x1F, 0x21, 0x23, 0x25,
+    0x26, 0x27, 0x29, 0x2B, 0x2D, 0x2F, 0x30, 0x32 },
+  // 8
+  { 0x00, 0x01, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0D,
+    0x0E, 0x0F, 0x10, 0x11, 0x12, 0x14, 0x17, 0x1A,
+    0x19, 0x1A, 0x1C, 0x1E, 0x20, 0x22, 0x25, 0x28,
+    0x29, 0x2A, 0x2B, 0x2D, 0x2F, 0x31, 0x33, 0x35 },
+  // 9
+  { 0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0E,
+    0x0F, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1B,
+    0x1C, 0x1D, 0x1E, 0x20, 0x22, 0x24, 0x26, 0x29,
+    0x2A, 0x2C, 0x2E, 0x30, 0x32, 0x34, 0x36, 0x39 },
+  // 10
+  { 0x00, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0E,
+    0x0F, 0x10, 0x12, 0x14, 0x16, 0x19, 0x1B, 0x1E,
+    0x1F, 0x21, 0x23, 0x25, 0x27, 0x29, 0x2B, 0x2D,
+    0x2E, 0x2F, 0x31, 0x32, 0x34, 0x36, 0x39, 0x3C },
+  // 11
+  { 0x00, 0x01, 0x03, 0x05, 0x07, 0x0A, 0x0C, 0x0F,
+    0x10, 0x11, 0x13, 0x15, 0x17, 0x19, 0x1B, 0x1E,
+    0x1F, 0x20, 0x22, 0x24, 0x26, 0x28, 0x2B, 0x2E,
+    0x2F, 0x30, 0x32, 0x34, 0x36, 0x39, 0x3C, 0x3F },
+  // 12
+  { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0B, 0x0D, 0x10,
+    0x11, 0x12, 0x14, 0x16, 0x18, 0x1B, 0x1E, 0x21,
+    0x22, 0x23, 0x25, 0x27, 0x29, 0x2C, 0x2F, 0x32,
+    0x33, 0x34, 0x36, 0x38, 0x3B, 0x34, 0x41, 0x44 },
+  // 13
+  { 0x00, 0x02, 0x04, 0x06, 0x08, 0x0B, 0x0D, 0x11,
+    0x12, 0x13, 0x15, 0x17, 0x1A, 0x1D, 0x20, 0x23,
+    0x24, 0x25, 0x27, 0x29, 0x2C, 0x2F, 0x32, 0x35,
+    0x36, 0x37, 0x39, 0x3B, 0x3E, 0x41, 0x44, 0x47 }
+};
+
+// #pragma mark -
+
+// At the time of writing, the only known case where Kyra 1 uses sound triggers
+// is in the castle, to cycle between three different songs.
+
+const int CadlPlayer::_kyra1SoundTriggers[] = {
+  0, 4, 5, 3
+};
+
+const int CadlPlayer::_kyra1NumSoundTriggers = ARRAYSIZE(CadlPlayer::_kyra1SoundTriggers);
+
+CadlPlayer::CadlPlayer(Copl *newopl)
+  : CPlayer(newopl), numsubsongs(0), _trackEntries(), _soundDataPtr(0)
+{
+  memset(_trackEntries, 0, sizeof(_trackEntries));
+  _driver = new AdlibDriver(newopl);
+  assert(_driver);
+
+  _sfxPlayingSound = -1;
+  // 	_soundFileLoaded = "";
+
+  _soundTriggers = _kyra1SoundTriggers;
+  _numSoundTriggers = _kyra1NumSoundTriggers;
+
+  init();
+}
+
+CadlPlayer::~CadlPlayer() {
+  delete [] _soundDataPtr;
+  delete _driver;
+}
+
+bool CadlPlayer::init() {
+  _driver->callback(2);
+  _driver->callback(16, int(4));
+  return true;
+}
+
+void CadlPlayer::process() {
+  uint8 trigger = _driver->callback(11);
+
+  if (trigger < _numSoundTriggers) {
+    int soundId = _soundTriggers[trigger];
+
+    if (soundId) {
+      playTrack(soundId);
+    }
+  } else {
+    warning("Unknown sound trigger %d", trigger);
+    // TODO: At this point, we really want to clear the trigger...
+  }
+}
+
+// void CadlPlayer::setVolume(int volume) {
+// }
+
+// int CadlPlayer::getVolume() {
+// 	return 0;
+// }
+
+// void CadlPlayer::loadMusicFile(const char *file) {
+// 	loadSoundFile(file);
+// }
+
+void CadlPlayer::playTrack(uint8 track) {
+  play(track);
+}
+
+// void CadlPlayer::haltTrack() {
+// 	unk1();
+// 	unk2();
+// 	//_engine->_system->delayMillis(3 * 60);
+// }
+
+void CadlPlayer::playSoundEffect(uint8_t track) {
+  play(track);
+}
+
+void CadlPlayer::play(uint8_t track) {
+  uint8 soundId = _trackEntries[track];
+  if ((int8)soundId == -1 || !_soundDataPtr)
+    return;
+  soundId &= 0xFF;
+  _driver->callback(16, 0);
+  // 	while ((_driver->callback(16, 0) & 8)) {
+  // We call the system delay and not the game delay to avoid concurrency issues.
+  // 		_engine->_system->delayMillis(10);
+  // 	}
+  if (_sfxPlayingSound != -1) {
+    // Restore the sounds's normal values.
+    _driver->callback(10, _sfxPlayingSound, int(1), int(_sfxPriority));
+    _driver->callback(10, _sfxPlayingSound, int(3), int(_sfxFourthByteOfSong));
+    _sfxPlayingSound = -1;
+  }
+
+  int chan = _driver->callback(9, soundId, int(0));
+
+  if (chan != 9) {
+    _sfxPlayingSound = soundId;
+    _sfxPriority = _driver->callback(9, soundId, int(1));
+    _sfxFourthByteOfSong = _driver->callback(9, soundId, int(3));
+
+    // In the cases I've seen, the mysterious fourth byte has been
+    // the parameter for the update_setExtraLevel3() callback.
+    //
+    // The extra level is part of the channels "total level", which
+    // is a six-bit value where larger values means softer volume.
+    //
+    // So what seems to be happening here is that sounds which are
+    // started by this function are given a slightly lower priority
+    // and a slightly higher (i.e. softer) extra level 3 than they
+    // would have if they were started from anywhere else. Strange.
+
+    int newVal = ((((-_sfxFourthByteOfSong) + 63) * 0xFF) >> 8) & 0xFF;
+    newVal = -newVal + 63;
+    _driver->callback(10, soundId, int(3), newVal);
+    newVal = ((_sfxPriority * 0xFF) >> 8) & 0xFF;
+    _driver->callback(10, soundId, int(1), newVal);
+  }
+
+  _driver->callback(6, soundId);
+}
+
+// void CadlPlayer::beginFadeOut() {
+// 	playSoundEffect(1);
+// }
+
+bool CadlPlayer::load(const std::string &filename, const CFileProvider &fp)
+{
+  binistream	*f = fp.open(filename);
+
+  // file validation section
+  if(!f || !fp.extension(filename, ".adl")) {
+    fp.close(f);
+    return false;
+  }
+
+  // 	if (_soundFileLoaded == file)
+  // 		return;
+
+  // 	if (_soundDataPtr) {
+  // 		haltTrack();
+  // 	}
+
+  uint8 *file_data = 0; uint32 file_size = 0;
+
+  // 	char filename[25];
+  // 	sprintf(filename, "%s.ADL", file);
+
+  // 	file_data = _engine->resource()->fileData(filename, &file_size);
+  // 	if (!file_data) {
+  // 		warning("Couldn't find music file: '%s'", filename);
+  // 		return;
+  // 	}
+
+  unk2();
+  unk1();
+
+  file_size = fp.filesize(f);
+  file_data = new uint8 [file_size];
+  f->readString((char *)file_data, file_size);
+
+  _driver->callback(8, int(-1));
+  _soundDataPtr = 0;
+
+  uint8 *p = file_data;
+  memcpy(_trackEntries, p, 120*sizeof(uint8));
+  p += 120;
+
+  int soundDataSize = file_size - 120;
+
+  _soundDataPtr = new uint8[soundDataSize];
+  assert(_soundDataPtr);
+
+  memcpy(_soundDataPtr, p, soundDataSize*sizeof(uint8));
+
+  delete [] file_data;
+  file_data = p = 0;
+  file_size = 0;
+
+  _driver->callback(4, _soundDataPtr);
+
+  // 	_soundFileLoaded = file;
+
+  for(int i = 0; i < 200; i++)
+    if(_trackEntries[i] != 0xff)
+      numsubsongs = i + 1;
+
+  fp.close(f);
+  return true;
+}
+
+void CadlPlayer::rewind(int subsong)
+{
+  opl->init();
+  opl->write(1,32);
+  playSoundEffect(subsong);
+  cursubsong = subsong;
+  update();
+}
+
+unsigned int CadlPlayer::getsubsongs()
+{
+  return numsubsongs;
+}
+
+bool CadlPlayer::update()
+{
+  bool songend = true;
+
+//   if(_trackEntries[cursubsong] == 0xff)
+//     return false;
+
+  _driver->callback();
+
+  for(int i = 0; i < 10; i++)
+    if(_driver->_channels[i].dataptr != NULL)
+      songend = false;
+
+  return !songend;
+}
+
+void CadlPlayer::unk1() {
+  playSoundEffect(0);
+  //_engine->_system->delayMillis(5 * 60);
+}
+
+void CadlPlayer::unk2() {
+  playSoundEffect(0);
+}
+
+CPlayer *CadlPlayer::factory(Copl *newopl)
+{
+  return new CadlPlayer(newopl);
+}
--- a/Plugins/Input/adplug/core/adplug.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,185 +0,0 @@
-/*
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * adplug.cpp - CAdPlug utility class, by Simon Peter <dn.tlp@gmx.net>
- */
-
-#include <string>
-#include <binfile.h>
-
-#include "adplug.h"
-#include "debug.h"
-
-/***** Replayer includes *****/
-
-#include "hsc.h"
-#include "amd.h"
-#include "a2m.h"
-#include "imf.h"
-#include "sng.h"
-#include "adtrack.h"
-#include "bam.h"
-#include "d00.h"
-#include "dfm.h"
-#include "hsp.h"
-#include "ksm.h"
-#include "mad.h"
-#include "mid.h"
-#include "mkj.h"
-#include "cff.h"
-#include "dmo.h"
-#include "s3m.h"
-#include "dtm.h"
-#include "fmc.h"
-#include "mtk.h"
-#include "rad.h"
-#include "raw.h"
-#include "sa2.h"
-#include "bmf.h"
-#include "flash.h"
-#include "hybrid.h"
-#include "hyp.h"
-#include "psi.h"
-#include "rat.h"
-#include "lds.h"
-#include "u6m.h"
-#include "rol.h"
-#include "xsm.h"
-#include "dro.h"
-#include "msc.h"
-#include "rix.h"
-#include "adl.h"
-
-/***** Defines *****/
-
-#define VERSION		"1.6"		// AdPlug library version string
-
-/***** CAdPlug *****/
-
-// List of all players that come with the standard AdPlug distribution
-const CPlayerDesc CAdPlug::allplayers[] = {
-  CPlayerDesc(ChscPlayer::factory, "HSC-Tracker", ".hsc\0"),
-  CPlayerDesc(CsngPlayer::factory, "SNGPlay", ".sng\0"),
-  CPlayerDesc(CimfPlayer::factory, "Apogee IMF", ".imf\0.wlf\0.adlib\0"),
-  CPlayerDesc(Ca2mLoader::factory, "Adlib Tracker 2", ".a2m\0"),
-  CPlayerDesc(CadtrackLoader::factory, "Adlib Tracker", ".sng\0"),
-  CPlayerDesc(CamdLoader::factory, "AMUSIC", ".amd\0"),
-  CPlayerDesc(CbamPlayer::factory, "Bob's Adlib Music", ".bam\0"),
-  CPlayerDesc(Cd00Player::factory, "Packed EdLib", ".d00\0"),
-  CPlayerDesc(CdfmLoader::factory, "Digital-FM", ".dfm\0"),
-  CPlayerDesc(ChspLoader::factory, "HSC Packed", ".hsp\0"),
-  CPlayerDesc(CksmPlayer::factory, "Ken Silverman Music", ".ksm\0"),
-  CPlayerDesc(CmadLoader::factory, "Mlat Adlib Tracker", ".mad\0"),
-  CPlayerDesc(CmidPlayer::factory, "MIDI", ".cmf\0.sci\0.laa\0"),
-  CPlayerDesc(CmkjPlayer::factory, "MKJamz", ".mkj\0"),
-  CPlayerDesc(CcffLoader::factory, "Boomtracker", ".cff\0"),
-  CPlayerDesc(CdmoLoader::factory, "TwinTeam", ".dmo\0"),
-  CPlayerDesc(Cs3mPlayer::factory, "Scream Tracker 3", ".s3m\0"),
-  CPlayerDesc(CdtmLoader::factory, "DeFy Adlib Tracker", ".dtm\0"),
-  CPlayerDesc(CfmcLoader::factory, "Faust Music Creator", ".sng\0"),
-  CPlayerDesc(CmtkLoader::factory, "MPU-401 Trakker", ".mtk\0"),
-  CPlayerDesc(CradLoader::factory, "Reality Adlib Tracker", ".rad\0"),
-  CPlayerDesc(CrawPlayer::factory, "RdosPlay RAW", ".raw\0"),
-  CPlayerDesc(Csa2Loader::factory, "Surprise! Adlib Tracker", ".sat\0.sa2\0"),
-  CPlayerDesc(CxadbmfPlayer::factory, "BMF Adlib Tracker", ".xad\0"),
-  CPlayerDesc(CxadflashPlayer::factory, "Flash", ".xad\0"),
-  CPlayerDesc(CxadhybridPlayer::factory, "Hybrid", ".xad\0"),
-  CPlayerDesc(CxadhypPlayer::factory, "Hypnosis", ".xad\0"),
-  CPlayerDesc(CxadpsiPlayer::factory, "PSI", ".xad\0"),
-  CPlayerDesc(CxadratPlayer::factory, "rat", ".xad\0"),
-  CPlayerDesc(CldsPlayer::factory, "LOUDNESS Sound System", ".lds\0"),
-  CPlayerDesc(Cu6mPlayer::factory, "Ultima 6 Music", ".m\0"),
-  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(CadlPlayer::factory, "Westwood ADL", ".adl\0"),
-  CPlayerDesc()
-};
-
-const CPlayers &CAdPlug::init_players(const CPlayerDesc pd[])
-{
-  static CPlayers	initplayers;
-  unsigned int		i;
-
-  for(i = 0; pd[i].factory; i++)
-    initplayers.push_back(&pd[i]);
-
-  return initplayers;
-}
-
-const CPlayers CAdPlug::players = CAdPlug::init_players(CAdPlug::allplayers);
-CAdPlugDatabase *CAdPlug::database = 0;
-
-CPlayer *CAdPlug::factory(const std::string &fn, Copl *opl, const CPlayers &pl,
-			  const CFileProvider &fp)
-{
-  CPlayer			*p;
-  CPlayers::const_iterator	i;
-  unsigned int			j;
-
-  AdPlug_LogWrite("*** CAdPlug::factory(\"%s\",opl,fp) ***\n", fn.c_str());
-
-  // Try a direct hit by file extension
-  for(i = pl.begin(); i != pl.end(); i++)
-    for(j = 0; (*i)->get_extension(j); j++)
-      if(fp.extension(fn, (*i)->get_extension(j))) {
-	AdPlug_LogWrite("Trying direct hit: %s\n", (*i)->filetype.c_str());
-	if((p = (*i)->factory(opl)))
-	  if(p->load(fn, fp)) {
-	    AdPlug_LogWrite("got it!\n");
-	    AdPlug_LogWrite("--- CAdPlug::factory ---\n");
-	    return p;
-	  } else
-	    delete p;
-      }
-
-  // Try all players, one by one
-  for(i = pl.begin(); i != pl.end(); i++) {
-    AdPlug_LogWrite("Trying: %s\n", (*i)->filetype.c_str());
-    if((p = (*i)->factory(opl)))
-      if(p->load(fn, fp)) {
-        AdPlug_LogWrite("got it!\n");
-        AdPlug_LogWrite("--- CAdPlug::factory ---\n");
-	return p;
-      } else
-	delete p;
-  }
-
-  // Unknown file
-  AdPlug_LogWrite("End of list!\n");
-  AdPlug_LogWrite("--- CAdPlug::factory ---\n");
-  return 0;
-}
-
-void CAdPlug::set_database(CAdPlugDatabase *db)
-{
-  database = db;
-}
-
-std::string CAdPlug::get_version()
-{
-  return std::string(VERSION);
-}
-
-void CAdPlug::debug_output(const std::string &filename)
-{
-  AdPlug_LogFile(filename.c_str());
-  AdPlug_LogWrite("CAdPlug::debug_output(\"%s\"): Redirected.\n",filename.c_str());
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/adplug.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,185 @@
+/*
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * adplug.cpp - CAdPlug utility class, by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include <string>
+#include <binfile.h>
+
+#include "adplug.h"
+#include "debug.h"
+
+/***** Replayer includes *****/
+
+#include "hsc.h"
+#include "amd.h"
+#include "a2m.h"
+#include "imf.h"
+#include "sng.h"
+#include "adtrack.h"
+#include "bam.h"
+#include "d00.h"
+#include "dfm.h"
+#include "hsp.h"
+#include "ksm.h"
+#include "mad.h"
+#include "mid.h"
+#include "mkj.h"
+#include "cff.h"
+#include "dmo.h"
+#include "s3m.h"
+#include "dtm.h"
+#include "fmc.h"
+#include "mtk.h"
+#include "rad.h"
+#include "raw.h"
+#include "sa2.h"
+#include "bmf.h"
+#include "flash.h"
+#include "hybrid.h"
+#include "hyp.h"
+#include "psi.h"
+#include "rat.h"
+#include "lds.h"
+#include "u6m.h"
+#include "rol.h"
+#include "xsm.h"
+#include "dro.h"
+#include "msc.h"
+#include "rix.h"
+#include "adl.h"
+
+/***** Defines *****/
+
+#define VERSION		"1.6"		// AdPlug library version string
+
+/***** CAdPlug *****/
+
+// List of all players that come with the standard AdPlug distribution
+const CPlayerDesc CAdPlug::allplayers[] = {
+  CPlayerDesc(ChscPlayer::factory, "HSC-Tracker", ".hsc\0"),
+  CPlayerDesc(CsngPlayer::factory, "SNGPlay", ".sng\0"),
+  CPlayerDesc(CimfPlayer::factory, "Apogee IMF", ".imf\0.wlf\0.adlib\0"),
+  CPlayerDesc(Ca2mLoader::factory, "Adlib Tracker 2", ".a2m\0"),
+  CPlayerDesc(CadtrackLoader::factory, "Adlib Tracker", ".sng\0"),
+  CPlayerDesc(CamdLoader::factory, "AMUSIC", ".amd\0"),
+  CPlayerDesc(CbamPlayer::factory, "Bob's Adlib Music", ".bam\0"),
+  CPlayerDesc(Cd00Player::factory, "Packed EdLib", ".d00\0"),
+  CPlayerDesc(CdfmLoader::factory, "Digital-FM", ".dfm\0"),
+  CPlayerDesc(ChspLoader::factory, "HSC Packed", ".hsp\0"),
+  CPlayerDesc(CksmPlayer::factory, "Ken Silverman Music", ".ksm\0"),
+  CPlayerDesc(CmadLoader::factory, "Mlat Adlib Tracker", ".mad\0"),
+  CPlayerDesc(CmidPlayer::factory, "MIDI", ".cmf\0.sci\0.laa\0"),
+  CPlayerDesc(CmkjPlayer::factory, "MKJamz", ".mkj\0"),
+  CPlayerDesc(CcffLoader::factory, "Boomtracker", ".cff\0"),
+  CPlayerDesc(CdmoLoader::factory, "TwinTeam", ".dmo\0"),
+  CPlayerDesc(Cs3mPlayer::factory, "Scream Tracker 3", ".s3m\0"),
+  CPlayerDesc(CdtmLoader::factory, "DeFy Adlib Tracker", ".dtm\0"),
+  CPlayerDesc(CfmcLoader::factory, "Faust Music Creator", ".sng\0"),
+  CPlayerDesc(CmtkLoader::factory, "MPU-401 Trakker", ".mtk\0"),
+  CPlayerDesc(CradLoader::factory, "Reality Adlib Tracker", ".rad\0"),
+  CPlayerDesc(CrawPlayer::factory, "RdosPlay RAW", ".raw\0"),
+  CPlayerDesc(Csa2Loader::factory, "Surprise! Adlib Tracker", ".sat\0.sa2\0"),
+  CPlayerDesc(CxadbmfPlayer::factory, "BMF Adlib Tracker", ".xad\0"),
+  CPlayerDesc(CxadflashPlayer::factory, "Flash", ".xad\0"),
+  CPlayerDesc(CxadhybridPlayer::factory, "Hybrid", ".xad\0"),
+  CPlayerDesc(CxadhypPlayer::factory, "Hypnosis", ".xad\0"),
+  CPlayerDesc(CxadpsiPlayer::factory, "PSI", ".xad\0"),
+  CPlayerDesc(CxadratPlayer::factory, "rat", ".xad\0"),
+  CPlayerDesc(CldsPlayer::factory, "LOUDNESS Sound System", ".lds\0"),
+  CPlayerDesc(Cu6mPlayer::factory, "Ultima 6 Music", ".m\0"),
+  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(CadlPlayer::factory, "Westwood ADL", ".adl\0"),
+  CPlayerDesc()
+};
+
+const CPlayers &CAdPlug::init_players(const CPlayerDesc pd[])
+{
+  static CPlayers	initplayers;
+  unsigned int		i;
+
+  for(i = 0; pd[i].factory; i++)
+    initplayers.push_back(&pd[i]);
+
+  return initplayers;
+}
+
+const CPlayers CAdPlug::players = CAdPlug::init_players(CAdPlug::allplayers);
+CAdPlugDatabase *CAdPlug::database = 0;
+
+CPlayer *CAdPlug::factory(const std::string &fn, Copl *opl, const CPlayers &pl,
+			  const CFileProvider &fp)
+{
+  CPlayer			*p;
+  CPlayers::const_iterator	i;
+  unsigned int			j;
+
+  AdPlug_LogWrite("*** CAdPlug::factory(\"%s\",opl,fp) ***\n", fn.c_str());
+
+  // Try a direct hit by file extension
+  for(i = pl.begin(); i != pl.end(); i++)
+    for(j = 0; (*i)->get_extension(j); j++)
+      if(fp.extension(fn, (*i)->get_extension(j))) {
+	AdPlug_LogWrite("Trying direct hit: %s\n", (*i)->filetype.c_str());
+	if((p = (*i)->factory(opl)))
+	  if(p->load(fn, fp)) {
+	    AdPlug_LogWrite("got it!\n");
+	    AdPlug_LogWrite("--- CAdPlug::factory ---\n");
+	    return p;
+	  } else
+	    delete p;
+      }
+
+  // Try all players, one by one
+  for(i = pl.begin(); i != pl.end(); i++) {
+    AdPlug_LogWrite("Trying: %s\n", (*i)->filetype.c_str());
+    if((p = (*i)->factory(opl)))
+      if(p->load(fn, fp)) {
+        AdPlug_LogWrite("got it!\n");
+        AdPlug_LogWrite("--- CAdPlug::factory ---\n");
+	return p;
+      } else
+	delete p;
+  }
+
+  // Unknown file
+  AdPlug_LogWrite("End of list!\n");
+  AdPlug_LogWrite("--- CAdPlug::factory ---\n");
+  return 0;
+}
+
+void CAdPlug::set_database(CAdPlugDatabase *db)
+{
+  database = db;
+}
+
+std::string CAdPlug::get_version()
+{
+  return std::string(VERSION);
+}
+
+void CAdPlug::debug_output(const std::string &filename)
+{
+  AdPlug_LogFile(filename.c_str());
+  AdPlug_LogWrite("CAdPlug::debug_output(\"%s\"): Redirected.\n",filename.c_str());
+}
--- a/Plugins/Input/adplug/core/adtrack.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,176 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * adtrack.cpp - Adlib Tracker 1.0 Loader by Simon Peter <dn.tlp@gmx.net>
- *
- * NOTES:
- * The original Adlib Tracker 1.0 is behaving a little different from the
- * official spec: The 'octave' integer from the instrument file is stored
- * "minus 1" from the actual value, underflowing from 0 to 0xffff.
- *
- * I also noticed that my player is playing everything transposed a few tones
- * higher than the original tracker. As far as i can see, my player perfectly
- * follows the official spec, so it "must" be the tracker that does something
- * wrong here...
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "adtrack.h"
-#include "debug.h"
-
-/*** Public methods ***/
-
-CPlayer *CadtrackLoader::factory(Copl *newopl)
-{
-  return new CadtrackLoader(newopl);
-}
-
-bool CadtrackLoader::load(const std::string &filename, const CFileProvider &fp)
-{
-  binistream *f = fp.open(filename); if(!f) return false;
-  binistream *instf;
-  char note[2];
-  unsigned short rwp;
-  unsigned char chp, octave, pnote = 0;
-  int i,j;
-  AdTrackInst myinst;
-
-  // file validation
-  if(!fp.extension(filename, ".sng") || fp.filesize(f) != 36000)
-    { fp.close(f); return false; }
-
-  // check for instruments file
-  std::string instfilename(filename, 0, filename.find_last_of('.'));
-  instfilename += ".ins";
-  AdPlug_LogWrite("CadtrackLoader::load(,\"%s\"): Checking for \"%s\"...\n",
-		  filename.c_str(), instfilename.c_str());
-  instf = fp.open(instfilename);
-  if(!instf || fp.filesize(instf) != 468) { fp.close(f); return false; }
-
-  // give CmodPlayer a hint on what we're up to
-  realloc_patterns(1,1000,9); realloc_instruments(9); realloc_order(1);
-  init_trackord(); flags = NoKeyOn;
-  (*order) = 0; length = 1; restartpos = 0; bpm = 120; initspeed = 3;
-
-  // load instruments from instruments file
-  for(i=0;i<9;i++) {
-    for(j=0;j<2;j++) {
-      myinst.op[j].appampmod = instf->readInt(2);
-      myinst.op[j].appvib = instf->readInt(2);
-      myinst.op[j].maintsuslvl = instf->readInt(2);
-      myinst.op[j].keybscale = instf->readInt(2);
-      myinst.op[j].octave = instf->readInt(2);
-      myinst.op[j].freqrisevollvldn = instf->readInt(2);
-      myinst.op[j].softness = instf->readInt(2);
-      myinst.op[j].attack = instf->readInt(2);
-      myinst.op[j].decay = instf->readInt(2);
-      myinst.op[j].release = instf->readInt(2);
-      myinst.op[j].sustain = instf->readInt(2);
-      myinst.op[j].feedback = instf->readInt(2);
-      myinst.op[j].waveform = instf->readInt(2);
-    }
-    convert_instrument(i, &myinst);
-  }
-  fp.close(instf);
-
-  // load file
-  for(rwp=0;rwp<1000;rwp++)
-    for(chp=0;chp<9;chp++) {
-      // read next record
-      f->readString(note, 2); octave = f->readInt(1); f->ignore();
-      switch(*note) {
-      case 'C': if(note[1] == '#') pnote = 2; else pnote = 1; break;
-      case 'D': if(note[1] == '#') pnote = 4; else pnote = 3; break;
-      case 'E': pnote = 5; break;
-      case 'F': if(note[1] == '#') pnote = 7; else pnote = 6; break;
-      case 'G': if(note[1] == '#') pnote = 9; else pnote = 8; break;
-      case 'A': if(note[1] == '#') pnote = 11; else pnote = 10; break;
-      case 'B': pnote = 12; break;
-      case '\0':
-	if(note[1] == '\0')
-	  tracks[chp][rwp].note = 127;
-	else {
-	  fp.close(f);
-	  return false;
-	}
-	break;
-      default: fp.close(f); return false;
-      }
-      if((*note) != '\0') {
-	tracks[chp][rwp].note = pnote + (octave * 12);
-	tracks[chp][rwp].inst = chp + 1;
-      }
-    }
-
-  fp.close(f);
-  rewind(0);
-  return true;
-}
-
-float CadtrackLoader::getrefresh()
-{
-  return 18.2f;
-}
-
-/*** Private methods ***/
-
-void CadtrackLoader::convert_instrument(unsigned int n, AdTrackInst *i)
-{
-  // Carrier "Amp Mod / Vib / Env Type / KSR / Multiple" register
-  inst[n].data[2] = i->op[Carrier].appampmod ? 1 << 7 : 0;
-  inst[n].data[2] += i->op[Carrier].appvib ? 1 << 6 : 0;
-  inst[n].data[2] += i->op[Carrier].maintsuslvl ? 1 << 5 : 0;
-  inst[n].data[2] += i->op[Carrier].keybscale ? 1 << 4 : 0;
-  inst[n].data[2] += (i->op[Carrier].octave + 1) & 0xffff; // Bug in original tracker
-  // Modulator...
-  inst[n].data[1] = i->op[Modulator].appampmod ? 1 << 7 : 0;
-  inst[n].data[1] += i->op[Modulator].appvib ? 1 << 6 : 0;
-  inst[n].data[1] += i->op[Modulator].maintsuslvl ? 1 << 5 : 0;
-  inst[n].data[1] += i->op[Modulator].keybscale ? 1 << 4 : 0;
-  inst[n].data[1] += (i->op[Modulator].octave + 1) & 0xffff; // Bug in original tracker
-
-  // Carrier "Key Scaling / Level" register
-  inst[n].data[10] = (i->op[Carrier].freqrisevollvldn & 3) << 6;
-  inst[n].data[10] += i->op[Carrier].softness & 63;
-  // Modulator...
-  inst[n].data[9] = (i->op[Modulator].freqrisevollvldn & 3) << 6;
-  inst[n].data[9] += i->op[Modulator].softness & 63;
-
-  // Carrier "Attack / Decay" register
-  inst[n].data[4] = (i->op[Carrier].attack & 0x0f) << 4;
-  inst[n].data[4] += i->op[Carrier].decay & 0x0f;
-  // Modulator...
-  inst[n].data[3] = (i->op[Modulator].attack & 0x0f) << 4;
-  inst[n].data[3] += i->op[Modulator].decay & 0x0f;
-
-  // Carrier "Release / Sustain" register
-  inst[n].data[6] = (i->op[Carrier].release & 0x0f) << 4;
-  inst[n].data[6] += i->op[Carrier].sustain & 0x0f;
-  // Modulator...
-  inst[n].data[5] = (i->op[Modulator].release & 0x0f) << 4;
-  inst[n].data[5] += i->op[Modulator].sustain & 0x0f;
-
-  // Channel "Feedback / Connection" register
-  inst[n].data[0] = (i->op[Carrier].feedback & 7) << 1;
-
-  // Carrier/Modulator "Wave Select" registers
-  inst[n].data[8] = i->op[Carrier].waveform & 3;
-  inst[n].data[7] = i->op[Modulator].waveform & 3;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/adtrack.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,176 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * adtrack.cpp - Adlib Tracker 1.0 Loader by Simon Peter <dn.tlp@gmx.net>
+ *
+ * NOTES:
+ * The original Adlib Tracker 1.0 is behaving a little different from the
+ * official spec: The 'octave' integer from the instrument file is stored
+ * "minus 1" from the actual value, underflowing from 0 to 0xffff.
+ *
+ * I also noticed that my player is playing everything transposed a few tones
+ * higher than the original tracker. As far as i can see, my player perfectly
+ * follows the official spec, so it "must" be the tracker that does something
+ * wrong here...
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "adtrack.h"
+#include "debug.h"
+
+/*** Public methods ***/
+
+CPlayer *CadtrackLoader::factory(Copl *newopl)
+{
+  return new CadtrackLoader(newopl);
+}
+
+bool CadtrackLoader::load(const std::string &filename, const CFileProvider &fp)
+{
+  binistream *f = fp.open(filename); if(!f) return false;
+  binistream *instf;
+  char note[2];
+  unsigned short rwp;
+  unsigned char chp, octave, pnote = 0;
+  int i,j;
+  AdTrackInst myinst;
+
+  // file validation
+  if(!fp.extension(filename, ".sng") || fp.filesize(f) != 36000)
+    { fp.close(f); return false; }
+
+  // check for instruments file
+  std::string instfilename(filename, 0, filename.find_last_of('.'));
+  instfilename += ".ins";
+  AdPlug_LogWrite("CadtrackLoader::load(,\"%s\"): Checking for \"%s\"...\n",
+		  filename.c_str(), instfilename.c_str());
+  instf = fp.open(instfilename);
+  if(!instf || fp.filesize(instf) != 468) { fp.close(f); return false; }
+
+  // give CmodPlayer a hint on what we're up to
+  realloc_patterns(1,1000,9); realloc_instruments(9); realloc_order(1);
+  init_trackord(); flags = NoKeyOn;
+  (*order) = 0; length = 1; restartpos = 0; bpm = 120; initspeed = 3;
+
+  // load instruments from instruments file
+  for(i=0;i<9;i++) {
+    for(j=0;j<2;j++) {
+      myinst.op[j].appampmod = instf->readInt(2);
+      myinst.op[j].appvib = instf->readInt(2);
+      myinst.op[j].maintsuslvl = instf->readInt(2);
+      myinst.op[j].keybscale = instf->readInt(2);
+      myinst.op[j].octave = instf->readInt(2);
+      myinst.op[j].freqrisevollvldn = instf->readInt(2);
+      myinst.op[j].softness = instf->readInt(2);
+      myinst.op[j].attack = instf->readInt(2);
+      myinst.op[j].decay = instf->readInt(2);
+      myinst.op[j].release = instf->readInt(2);
+      myinst.op[j].sustain = instf->readInt(2);
+      myinst.op[j].feedback = instf->readInt(2);
+      myinst.op[j].waveform = instf->readInt(2);
+    }
+    convert_instrument(i, &myinst);
+  }
+  fp.close(instf);
+
+  // load file
+  for(rwp=0;rwp<1000;rwp++)
+    for(chp=0;chp<9;chp++) {
+      // read next record
+      f->readString(note, 2); octave = f->readInt(1); f->ignore();
+      switch(*note) {
+      case 'C': if(note[1] == '#') pnote = 2; else pnote = 1; break;
+      case 'D': if(note[1] == '#') pnote = 4; else pnote = 3; break;
+      case 'E': pnote = 5; break;
+      case 'F': if(note[1] == '#') pnote = 7; else pnote = 6; break;
+      case 'G': if(note[1] == '#') pnote = 9; else pnote = 8; break;
+      case 'A': if(note[1] == '#') pnote = 11; else pnote = 10; break;
+      case 'B': pnote = 12; break;
+      case '\0':
+	if(note[1] == '\0')
+	  tracks[chp][rwp].note = 127;
+	else {
+	  fp.close(f);
+	  return false;
+	}
+	break;
+      default: fp.close(f); return false;
+      }
+      if((*note) != '\0') {
+	tracks[chp][rwp].note = pnote + (octave * 12);
+	tracks[chp][rwp].inst = chp + 1;
+      }
+    }
+
+  fp.close(f);
+  rewind(0);
+  return true;
+}
+
+float CadtrackLoader::getrefresh()
+{
+  return 18.2f;
+}
+
+/*** Private methods ***/
+
+void CadtrackLoader::convert_instrument(unsigned int n, AdTrackInst *i)
+{
+  // Carrier "Amp Mod / Vib / Env Type / KSR / Multiple" register
+  inst[n].data[2] = i->op[Carrier].appampmod ? 1 << 7 : 0;
+  inst[n].data[2] += i->op[Carrier].appvib ? 1 << 6 : 0;
+  inst[n].data[2] += i->op[Carrier].maintsuslvl ? 1 << 5 : 0;
+  inst[n].data[2] += i->op[Carrier].keybscale ? 1 << 4 : 0;
+  inst[n].data[2] += (i->op[Carrier].octave + 1) & 0xffff; // Bug in original tracker
+  // Modulator...
+  inst[n].data[1] = i->op[Modulator].appampmod ? 1 << 7 : 0;
+  inst[n].data[1] += i->op[Modulator].appvib ? 1 << 6 : 0;
+  inst[n].data[1] += i->op[Modulator].maintsuslvl ? 1 << 5 : 0;
+  inst[n].data[1] += i->op[Modulator].keybscale ? 1 << 4 : 0;
+  inst[n].data[1] += (i->op[Modulator].octave + 1) & 0xffff; // Bug in original tracker
+
+  // Carrier "Key Scaling / Level" register
+  inst[n].data[10] = (i->op[Carrier].freqrisevollvldn & 3) << 6;
+  inst[n].data[10] += i->op[Carrier].softness & 63;
+  // Modulator...
+  inst[n].data[9] = (i->op[Modulator].freqrisevollvldn & 3) << 6;
+  inst[n].data[9] += i->op[Modulator].softness & 63;
+
+  // Carrier "Attack / Decay" register
+  inst[n].data[4] = (i->op[Carrier].attack & 0x0f) << 4;
+  inst[n].data[4] += i->op[Carrier].decay & 0x0f;
+  // Modulator...
+  inst[n].data[3] = (i->op[Modulator].attack & 0x0f) << 4;
+  inst[n].data[3] += i->op[Modulator].decay & 0x0f;
+
+  // Carrier "Release / Sustain" register
+  inst[n].data[6] = (i->op[Carrier].release & 0x0f) << 4;
+  inst[n].data[6] += i->op[Carrier].sustain & 0x0f;
+  // Modulator...
+  inst[n].data[5] = (i->op[Modulator].release & 0x0f) << 4;
+  inst[n].data[5] += i->op[Modulator].sustain & 0x0f;
+
+  // Channel "Feedback / Connection" register
+  inst[n].data[0] = (i->op[Carrier].feedback & 7) << 1;
+
+  // Carrier/Modulator "Wave Select" registers
+  inst[n].data[8] = i->op[Carrier].waveform & 3;
+  inst[n].data[7] = i->op[Modulator].waveform & 3;
+}
--- a/Plugins/Input/adplug/core/amd.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * amd.cpp - AMD Loader by Simon Peter <dn.tlp@gmx.net>
- */
-
-#include <string.h>
-
-#include "amd.h"
-#include "debug.h"
-
-CPlayer *CamdLoader::factory(Copl *newopl)
-{
-  return new CamdLoader(newopl);
-}
-
-bool CamdLoader::load(const std::string &filename, const CFileProvider &fp)
-{
-        binistream *f = fp.open(filename); if(!f) return false;
-	struct {
-		char id[9];
-		unsigned char version;
-	} header;
-	int i, j, k, t, numtrax, maxi = 0;
-	unsigned char buf, buf2, buf3;
-	const unsigned char convfx[10] = {0,1,2,9,17,11,13,18,3,14};
-  const unsigned char convvol[64] = {
-    0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 0xa, 0xa, 0xb,
-    0xc, 0xc, 0xd, 0xe, 0xe, 0xf, 0x10, 0x10, 0x11, 0x12, 0x13, 0x14, 0x14,
-    0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21,
-    0x22, 0x23, 0x25, 0x26, 0x28, 0x29, 0x2b, 0x2d, 0x2e, 0x30, 0x32, 0x35,
-    0x37, 0x3a, 0x3c, 0x3f
-  };
-
-	// file validation section
-	if(fp.filesize(f) < 1072) { fp.close(f); return false; }
-	f->seek(1062); f->readString(header.id, 9);
-	header.version = f->readInt(1);
-	if(strncmp(header.id, "<o\xefQU\xeeRoR", 9) &&
-	   strncmp(header.id, "MaDoKaN96", 9)) { fp.close(f); return false; }
-
-	// load section
-	memset(inst, 0, sizeof(inst));
-	f->seek(0);
-	f->readString(songname, sizeof(songname));
-	f->readString(author, sizeof(author));
-	for(i = 0; i < 26; i++) {
-		f->readString(instname[i], 23);
-		for(j = 0; j < 11; j++) inst[i].data[j] = f->readInt(1);
-	}
-	length = f->readInt(1); nop = f->readInt(1) + 1;
-	for(i=0;i<128;i++) order[i] = f->readInt(1);
-	f->seek(10, binio::Add);
-	if(header.version == 0x10) {	// unpacked module
-	maxi = nop * 9;
-		for(i=0;i<64*9;i++)
-			trackord[i/9][i%9] = i+1;
-		t = 0;
-		while(!f->ateof()) {
-			for(j=0;j<64;j++)
-				for(i=t;i<t+9;i++) {
-					buf = f->readInt(1);
-					tracks[i][j].param2 = (buf&127) % 10;
-					tracks[i][j].param1 = (buf&127) / 10;
-					buf = f->readInt(1);
-					tracks[i][j].inst = buf >> 4;
-					tracks[i][j].command = buf & 0x0f;
-					buf = f->readInt(1);
-					if(buf >> 4)	// fix bug in AMD save routine
-						tracks[i][j].note = ((buf & 14) >> 1) * 12 + (buf >> 4);
-					else
-						tracks[i][j].note = 0;
-					tracks[i][j].inst += (buf & 1) << 4;
-				}
-			t += 9;
-		}
-	} else {						// packed module
-		for(i=0;i<nop;i++)
-		  for(j=0;j<9;j++)
-		    trackord[i][j] = f->readInt(2) + 1;
-		numtrax = f->readInt(2);
-		for(k=0;k<numtrax;k++) {
-			i = f->readInt(2);
-			if(i > 575) i = 575;	// fix corrupted modules
-			maxi = (i + 1 > maxi ? i + 1 : maxi);
-			j = 0;
-			do {
-				buf = f->readInt(1);
-				if(buf & 128) {
-					for(t = j; t < j + (buf & 127) && t < 64; t++) {
-						tracks[i][t].command = 0;
-						tracks[i][t].inst = 0;
-						tracks[i][t].note = 0;
-						tracks[i][t].param1 = 0;
-						tracks[i][t].param2 = 0;
-					}
-					j += buf & 127;
-					continue;
-				}
-				tracks[i][j].param2 = buf % 10;
-				tracks[i][j].param1 = buf / 10;
-				buf = f->readInt(1);
-				tracks[i][j].inst = buf >> 4;
-				tracks[i][j].command = buf & 0x0f;
-				buf = f->readInt(1);
-				if(buf >> 4)	// fix bug in AMD save routine
-					tracks[i][j].note = ((buf & 14) >> 1) * 12 + (buf >> 4);
-				else
-					tracks[i][j].note = 0;
-				tracks[i][j].inst += (buf & 1) << 4;
-				j++;
-			} while(j<64);
-		}
-	}
-	fp.close(f);
-
-	// convert to protracker replay data
-	bpm = 50; restartpos = 0; activechan = 0xffff; flags = Decimal;
-	for(i=0;i<26;i++) {	// convert instruments
-		buf = inst[i].data[0];
-		buf2 = inst[i].data[1];
-		inst[i].data[0] = inst[i].data[10];
-		inst[i].data[1] = buf;
-		buf = inst[i].data[2];
-		inst[i].data[2] = inst[i].data[5];
-		buf3 = inst[i].data[3];
-		inst[i].data[3] = buf;
-		buf = inst[i].data[4];
-		inst[i].data[4] = inst[i].data[7];
-		inst[i].data[5] = buf3;
-		buf3 = inst[i].data[6];
-		inst[i].data[6] = inst[i].data[8];
-		inst[i].data[7] = buf;
-		inst[i].data[8] = inst[i].data[9];
-		inst[i].data[9] = buf2;
-		inst[i].data[10] = buf3;
-		for(j=0;j<23;j++)	// convert names
-			if(instname[i][j] == '\xff')
-				instname[i][j] = '\x20';
-	}
-  for(i=0;i<maxi;i++)	// convert patterns
-		for(j=0;j<64;j++) {
-			tracks[i][j].command = convfx[tracks[i][j].command];
-			// extended command
-			if(tracks[i][j].command == 14) {
-				if(tracks[i][j].param1 == 2) {
-					tracks[i][j].command = 10;
-					tracks[i][j].param1 = tracks[i][j].param2;
-					tracks[i][j].param2 = 0;
-				}
-
-				if(tracks[i][j].param1 == 3) {
-					tracks[i][j].command = 10;
-					tracks[i][j].param1 = 0;
-				}
-			}
-
-      // fix volume
-      if(tracks[i][j].command == 17) {
-	int vol = convvol[tracks[i][j].param1 * 10 + tracks[i][j].param2];
-
-	if(vol > 63) vol = 63;
-	tracks[i][j].param1 = vol / 10;
-	tracks[i][j].param2 = vol % 10;
-      }
-		}
-
-	rewind(0);
-	return true;
-}
-
-float CamdLoader::getrefresh()
-{
-	if(tempo)
-		return (float) (tempo);
-	else
-		return 18.2f;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/amd.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,193 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * amd.cpp - AMD Loader by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include <string.h>
+
+#include "amd.h"
+#include "debug.h"
+
+CPlayer *CamdLoader::factory(Copl *newopl)
+{
+  return new CamdLoader(newopl);
+}
+
+bool CamdLoader::load(const std::string &filename, const CFileProvider &fp)
+{
+        binistream *f = fp.open(filename); if(!f) return false;
+	struct {
+		char id[9];
+		unsigned char version;
+	} header;
+	int i, j, k, t, numtrax, maxi = 0;
+	unsigned char buf, buf2, buf3;
+	const unsigned char convfx[10] = {0,1,2,9,17,11,13,18,3,14};
+  const unsigned char convvol[64] = {
+    0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 9, 0xa, 0xa, 0xb,
+    0xc, 0xc, 0xd, 0xe, 0xe, 0xf, 0x10, 0x10, 0x11, 0x12, 0x13, 0x14, 0x14,
+    0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21,
+    0x22, 0x23, 0x25, 0x26, 0x28, 0x29, 0x2b, 0x2d, 0x2e, 0x30, 0x32, 0x35,
+    0x37, 0x3a, 0x3c, 0x3f
+  };
+
+	// file validation section
+	if(fp.filesize(f) < 1072) { fp.close(f); return false; }
+	f->seek(1062); f->readString(header.id, 9);
+	header.version = f->readInt(1);
+	if(strncmp(header.id, "<o\xefQU\xeeRoR", 9) &&
+	   strncmp(header.id, "MaDoKaN96", 9)) { fp.close(f); return false; }
+
+	// load section
+	memset(inst, 0, sizeof(inst));
+	f->seek(0);
+	f->readString(songname, sizeof(songname));
+	f->readString(author, sizeof(author));
+	for(i = 0; i < 26; i++) {
+		f->readString(instname[i], 23);
+		for(j = 0; j < 11; j++) inst[i].data[j] = f->readInt(1);
+	}
+	length = f->readInt(1); nop = f->readInt(1) + 1;
+	for(i=0;i<128;i++) order[i] = f->readInt(1);
+	f->seek(10, binio::Add);
+	if(header.version == 0x10) {	// unpacked module
+	maxi = nop * 9;
+		for(i=0;i<64*9;i++)
+			trackord[i/9][i%9] = i+1;
+		t = 0;
+		while(!f->ateof()) {
+			for(j=0;j<64;j++)
+				for(i=t;i<t+9;i++) {
+					buf = f->readInt(1);
+					tracks[i][j].param2 = (buf&127) % 10;
+					tracks[i][j].param1 = (buf&127) / 10;
+					buf = f->readInt(1);
+					tracks[i][j].inst = buf >> 4;
+					tracks[i][j].command = buf & 0x0f;
+					buf = f->readInt(1);
+					if(buf >> 4)	// fix bug in AMD save routine
+						tracks[i][j].note = ((buf & 14) >> 1) * 12 + (buf >> 4);
+					else
+						tracks[i][j].note = 0;
+					tracks[i][j].inst += (buf & 1) << 4;
+				}
+			t += 9;
+		}
+	} else {						// packed module
+		for(i=0;i<nop;i++)
+		  for(j=0;j<9;j++)
+		    trackord[i][j] = f->readInt(2) + 1;
+		numtrax = f->readInt(2);
+		for(k=0;k<numtrax;k++) {
+			i = f->readInt(2);
+			if(i > 575) i = 575;	// fix corrupted modules
+			maxi = (i + 1 > maxi ? i + 1 : maxi);
+			j = 0;
+			do {
+				buf = f->readInt(1);
+				if(buf & 128) {
+					for(t = j; t < j + (buf & 127) && t < 64; t++) {
+						tracks[i][t].command = 0;
+						tracks[i][t].inst = 0;
+						tracks[i][t].note = 0;
+						tracks[i][t].param1 = 0;
+						tracks[i][t].param2 = 0;
+					}
+					j += buf & 127;
+					continue;
+				}
+				tracks[i][j].param2 = buf % 10;
+				tracks[i][j].param1 = buf / 10;
+				buf = f->readInt(1);
+				tracks[i][j].inst = buf >> 4;
+				tracks[i][j].command = buf & 0x0f;
+				buf = f->readInt(1);
+				if(buf >> 4)	// fix bug in AMD save routine
+					tracks[i][j].note = ((buf & 14) >> 1) * 12 + (buf >> 4);
+				else
+					tracks[i][j].note = 0;
+				tracks[i][j].inst += (buf & 1) << 4;
+				j++;
+			} while(j<64);
+		}
+	}
+	fp.close(f);
+
+	// convert to protracker replay data
+	bpm = 50; restartpos = 0; activechan = 0xffff; flags = Decimal;
+	for(i=0;i<26;i++) {	// convert instruments
+		buf = inst[i].data[0];
+		buf2 = inst[i].data[1];
+		inst[i].data[0] = inst[i].data[10];
+		inst[i].data[1] = buf;
+		buf = inst[i].data[2];
+		inst[i].data[2] = inst[i].data[5];
+		buf3 = inst[i].data[3];
+		inst[i].data[3] = buf;
+		buf = inst[i].data[4];
+		inst[i].data[4] = inst[i].data[7];
+		inst[i].data[5] = buf3;
+		buf3 = inst[i].data[6];
+		inst[i].data[6] = inst[i].data[8];
+		inst[i].data[7] = buf;
+		inst[i].data[8] = inst[i].data[9];
+		inst[i].data[9] = buf2;
+		inst[i].data[10] = buf3;
+		for(j=0;j<23;j++)	// convert names
+			if(instname[i][j] == '\xff')
+				instname[i][j] = '\x20';
+	}
+  for(i=0;i<maxi;i++)	// convert patterns
+		for(j=0;j<64;j++) {
+			tracks[i][j].command = convfx[tracks[i][j].command];
+			// extended command
+			if(tracks[i][j].command == 14) {
+				if(tracks[i][j].param1 == 2) {
+					tracks[i][j].command = 10;
+					tracks[i][j].param1 = tracks[i][j].param2;
+					tracks[i][j].param2 = 0;
+				}
+
+				if(tracks[i][j].param1 == 3) {
+					tracks[i][j].command = 10;
+					tracks[i][j].param1 = 0;
+				}
+			}
+
+      // fix volume
+      if(tracks[i][j].command == 17) {
+	int vol = convvol[tracks[i][j].param1 * 10 + tracks[i][j].param2];
+
+	if(vol > 63) vol = 63;
+	tracks[i][j].param1 = vol / 10;
+	tracks[i][j].param2 = vol % 10;
+      }
+		}
+
+	rewind(0);
+	return true;
+}
+
+float CamdLoader::getrefresh()
+{
+	if(tempo)
+		return (float) (tempo);
+	else
+		return 18.2f;
+}
--- a/Plugins/Input/adplug/core/bam.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,203 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * bam.cpp - Bob's Adlib Music Player, by Simon Peter <dn.tlp@gmx.net>
- *
- * NOTES:
- * In my player, the loop counter is stored with the label. This can be
- * dangerous for some situations (see below), but there shouldn't be any BAM
- * files triggering this situation.
- *
- * From SourceForge Bug #476088:
- * -----------------------------
- * Using just one loop counter for each label, my player can't
- * handle files that loop twice to the same label (if that's at
- * all possible with BAM). Imagine the following situation:
- * 
- * ... [*] ---- [<- *] ---- [<- *] ...
- *  ^   ^    ^     ^     ^     ^    ^
- *  |   |    |     |     |     |    |
- *  +---|----+-----|-----+-----|----+--- normal song data
- *      +----------|-----------|-------- label 1
- *                 +-----------+-------- loop points to label 1
- * 
- * both loop points loop to the same label. Storing the loop 
- * count with the label would cause chaos with the counter, 
- * when the player executes the inner jump.
- * ------------------
- * Not to worry. my reference implementation of BAM does not
- * support the multiple loop situation you describe, and
- * neither do any BAM-creation programs. Then both loops point
- * to the same label, the inner loop's counter is just allowed
- * to clobber the outer loop's counter. No stack is neccisary.
- */
-
-#include <string.h>
-#include "bam.h"
-
-const unsigned short CbamPlayer::freq[] = {172,182,193,205,217,230,243,258,274,
-290,307,326,345,365,387,410,435,460,489,517,547,580,614,651,1369,1389,1411,
-1434,1459,1484,1513,1541,1571,1604,1638,1675,2393,2413,2435,2458,2483,2508,
-2537,2565,2595,2628,2662,2699,3417,3437,3459,3482,3507,3532,3561,3589,3619,
-3652,3686,3723,4441,4461,4483,4506,4531,4556,4585,4613,4643,4676,4710,4747,
-5465,5485,5507,5530,5555,5580,5609,5637,5667,5700,5734,5771,6489,6509,6531,
-6554,6579,6604,6633,6661,6691,6724,6758,6795,7513,7533,7555,7578,7603,7628,
-7657,7685,7715,7748,7782,7819,7858,7898,7942,7988,8037,8089,8143,8191,8191,
-8191,8191,8191,8191,8191,8191,8191,8191,8191,8191};
-
-CPlayer *CbamPlayer::factory(Copl *newopl)
-{
-  return new CbamPlayer(newopl);
-}
-
-bool CbamPlayer::load(const std::string &filename, const CFileProvider &fp)
-{
-        binistream *f = fp.open(filename); if(!f) return false;
-	char id[4];
-	unsigned int i;
-
-	size = fp.filesize(f) - 4;	// filesize minus header
-	f->readString(id, 4);
-	if(strncmp(id,"CBMF",4)) { fp.close(f); return false; }
-
-	song = new unsigned char [size];
-	for(i = 0; i < size; i++) song[i] = f->readInt(1);
-
-	fp.close(f);
-	rewind(0);
-	return true;
-}
-
-bool CbamPlayer::update()
-{
-	unsigned char	cmd,c;
-
-	if(del) {
-		del--;
-		return !songend;
-	}
-
-	if(pos >= size) {	// EOF detection
-		pos = 0;
-		songend = true;
-	}
-
-	while(song[pos] < 128) {
-		cmd = song[pos] & 240;
-		c = song[pos] & 15;
-		switch(cmd) {
-		case 0:		// stop song
-			pos = 0;
-			songend = true;
-			break;
-		case 16:	// start note
-			if(c < 9) {
-				opl->write(0xa0 + c, freq[song[++pos]] & 255);
-				opl->write(0xb0 + c, (freq[song[pos]] >> 8) + 32);
-			} else
-				pos++;
-			pos++;
-			break;
-		case 32:	// stop note
-			if(c < 9)
-				opl->write(0xb0 + c, 0);
-			pos++;
-			break;
-		case 48:	// define instrument
-			if(c < 9) {
-				opl->write(0x20 + op_table[c],song[pos+1]);
-				opl->write(0x23 + op_table[c],song[pos+2]);
-				opl->write(0x40 + op_table[c],song[pos+3]);
-				opl->write(0x43 + op_table[c],song[pos+4]);
-				opl->write(0x60 + op_table[c],song[pos+5]);
-				opl->write(0x63 + op_table[c],song[pos+6]);
-				opl->write(0x80 + op_table[c],song[pos+7]);
-				opl->write(0x83 + op_table[c],song[pos+8]);
-				opl->write(0xe0 + op_table[c],song[pos+9]);
-				opl->write(0xe3 + op_table[c],song[pos+10]);
-				opl->write(0xc0 + c,song[pos+11]);
-			}
-			pos += 12;
-			break;
-		case 80:	// set label
-			label[c].target = ++pos;
-			label[c].defined = true;
-			break;
-		case 96:	// jump
-			if(label[c].defined)
-				switch(song[pos+1]) {
-				case 254:	// infinite loop
-					if(label[c].defined) {
-						pos = label[c].target;
-						songend = true;
-						break;
-					}
-					// fall through...
-				case 255:	// chorus
-					if(!chorus && label[c].defined) {
-						chorus = true;
-						gosub = pos + 2;
-						pos = label[c].target;
-						break;
-					}
-					// fall through...
-				case 0:		// end of loop
-					pos += 2;
-					break;
-				default:	// finite loop
-					if(!label[c].count) {	// loop elapsed
-						label[c].count = 255;
-						pos += 2;
-						break;
-					}
-					if(label[c].count < 255)	// loop defined
-						label[c].count--;
-					else						// loop undefined
-						label[c].count = song[pos+1] - 1;
-					pos = label[c].target;
-					break;
-				}
-			break;
-		case 112:	// end of chorus
-			if(chorus) {
-				pos = gosub;
-				chorus = false;
-			} else
-				pos++;
-			break;
-		default:	// reserved command (skip)
-			pos++;
-			break;
-		}
-	}
-	if(song[pos] >= 128) {		// wait
-		del = song[pos] - 127;
-		pos++;
-	}
-	return !songend;
-}
-
-void CbamPlayer::rewind(int subsong)
-{
-        int i;
-
-	pos = 0; songend = false; del = 0; gosub = 0; chorus = false;
-	memset(label, 0, sizeof(label)); label[0].defined = true;
-	for(i = 0; i < 16; i++) label[i].count = 255;	// 255 = undefined
-	opl->init(); opl->write(1,32);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/bam.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,203 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * bam.cpp - Bob's Adlib Music Player, by Simon Peter <dn.tlp@gmx.net>
+ *
+ * NOTES:
+ * In my player, the loop counter is stored with the label. This can be
+ * dangerous for some situations (see below), but there shouldn't be any BAM
+ * files triggering this situation.
+ *
+ * From SourceForge Bug #476088:
+ * -----------------------------
+ * Using just one loop counter for each label, my player can't
+ * handle files that loop twice to the same label (if that's at
+ * all possible with BAM). Imagine the following situation:
+ * 
+ * ... [*] ---- [<- *] ---- [<- *] ...
+ *  ^   ^    ^     ^     ^     ^    ^
+ *  |   |    |     |     |     |    |
+ *  +---|----+-----|-----+-----|----+--- normal song data
+ *      +----------|-----------|-------- label 1
+ *                 +-----------+-------- loop points to label 1
+ * 
+ * both loop points loop to the same label. Storing the loop 
+ * count with the label would cause chaos with the counter, 
+ * when the player executes the inner jump.
+ * ------------------
+ * Not to worry. my reference implementation of BAM does not
+ * support the multiple loop situation you describe, and
+ * neither do any BAM-creation programs. Then both loops point
+ * to the same label, the inner loop's counter is just allowed
+ * to clobber the outer loop's counter. No stack is neccisary.
+ */
+
+#include <string.h>
+#include "bam.h"
+
+const unsigned short CbamPlayer::freq[] = {172,182,193,205,217,230,243,258,274,
+290,307,326,345,365,387,410,435,460,489,517,547,580,614,651,1369,1389,1411,
+1434,1459,1484,1513,1541,1571,1604,1638,1675,2393,2413,2435,2458,2483,2508,
+2537,2565,2595,2628,2662,2699,3417,3437,3459,3482,3507,3532,3561,3589,3619,
+3652,3686,3723,4441,4461,4483,4506,4531,4556,4585,4613,4643,4676,4710,4747,
+5465,5485,5507,5530,5555,5580,5609,5637,5667,5700,5734,5771,6489,6509,6531,
+6554,6579,6604,6633,6661,6691,6724,6758,6795,7513,7533,7555,7578,7603,7628,
+7657,7685,7715,7748,7782,7819,7858,7898,7942,7988,8037,8089,8143,8191,8191,
+8191,8191,8191,8191,8191,8191,8191,8191,8191,8191};
+
+CPlayer *CbamPlayer::factory(Copl *newopl)
+{
+  return new CbamPlayer(newopl);
+}
+
+bool CbamPlayer::load(const std::string &filename, const CFileProvider &fp)
+{
+        binistream *f = fp.open(filename); if(!f) return false;
+	char id[4];
+	unsigned int i;
+
+	size = fp.filesize(f) - 4;	// filesize minus header
+	f->readString(id, 4);
+	if(strncmp(id,"CBMF",4)) { fp.close(f); return false; }
+
+	song = new unsigned char [size];
+	for(i = 0; i < size; i++) song[i] = f->readInt(1);
+
+	fp.close(f);
+	rewind(0);
+	return true;
+}
+
+bool CbamPlayer::update()
+{
+	unsigned char	cmd,c;
+
+	if(del) {
+		del--;
+		return !songend;
+	}
+
+	if(pos >= size) {	// EOF detection
+		pos = 0;
+		songend = true;
+	}
+
+	while(song[pos] < 128) {
+		cmd = song[pos] & 240;
+		c = song[pos] & 15;
+		switch(cmd) {
+		case 0:		// stop song
+			pos = 0;
+			songend = true;
+			break;
+		case 16:	// start note
+			if(c < 9) {
+				opl->write(0xa0 + c, freq[song[++pos]] & 255);
+				opl->write(0xb0 + c, (freq[song[pos]] >> 8) + 32);
+			} else
+				pos++;
+			pos++;
+			break;
+		case 32:	// stop note
+			if(c < 9)
+				opl->write(0xb0 + c, 0);
+			pos++;
+			break;
+		case 48:	// define instrument
+			if(c < 9) {
+				opl->write(0x20 + op_table[c],song[pos+1]);
+				opl->write(0x23 + op_table[c],song[pos+2]);
+				opl->write(0x40 + op_table[c],song[pos+3]);
+				opl->write(0x43 + op_table[c],song[pos+4]);
+				opl->write(0x60 + op_table[c],song[pos+5]);
+				opl->write(0x63 + op_table[c],song[pos+6]);
+				opl->write(0x80 + op_table[c],song[pos+7]);
+				opl->write(0x83 + op_table[c],song[pos+8]);
+				opl->write(0xe0 + op_table[c],song[pos+9]);
+				opl->write(0xe3 + op_table[c],song[pos+10]);
+				opl->write(0xc0 + c,song[pos+11]);
+			}
+			pos += 12;
+			break;
+		case 80:	// set label
+			label[c].target = ++pos;
+			label[c].defined = true;
+			break;
+		case 96:	// jump
+			if(label[c].defined)
+				switch(song[pos+1]) {
+				case 254:	// infinite loop
+					if(label[c].defined) {
+						pos = label[c].target;
+						songend = true;
+						break;
+					}
+					// fall through...
+				case 255:	// chorus
+					if(!chorus && label[c].defined) {
+						chorus = true;
+						gosub = pos + 2;
+						pos = label[c].target;
+						break;
+					}
+					// fall through...
+				case 0:		// end of loop
+					pos += 2;
+					break;
+				default:	// finite loop
+					if(!label[c].count) {	// loop elapsed
+						label[c].count = 255;
+						pos += 2;
+						break;
+					}
+					if(label[c].count < 255)	// loop defined
+						label[c].count--;
+					else						// loop undefined
+						label[c].count = song[pos+1] - 1;
+					pos = label[c].target;
+					break;
+				}
+			break;
+		case 112:	// end of chorus
+			if(chorus) {
+				pos = gosub;
+				chorus = false;
+			} else
+				pos++;
+			break;
+		default:	// reserved command (skip)
+			pos++;
+			break;
+		}
+	}
+	if(song[pos] >= 128) {		// wait
+		del = song[pos] - 127;
+		pos++;
+	}
+	return !songend;
+}
+
+void CbamPlayer::rewind(int subsong)
+{
+        int i;
+
+	pos = 0; songend = false; del = 0; gosub = 0; chorus = false;
+	memset(label, 0, sizeof(label)); label[0].defined = true;
+	for(i = 0; i < 16; i++) label[i].count = 255;	// 255 = undefined
+	opl->init(); opl->write(1,32);
+}
--- a/Plugins/Input/adplug/core/bmf.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,596 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * [xad] BMF player, by Riven the Mage <riven@ok.ru>
- */
-
-/*
-    - discovery -
-
-  file(s) : GAMESNET.COM
-     type : GamesNet advertising intro
-     tune : by (?)The Brain [Razor 1911]
-   player : ver.0.9b by Hammer
-
-  file(s) : 2FAST4U.COM
-     type : Ford Knox BBStro
-     tune : by The Brain [Razor 1911]
-   player : ver.1.1 by ?
-  comment : in original player at 9th channel the feedback adlib register is not C8 but C6.
-
-  file(s) : DATURA.COM
-     type : Datura BBStro
-     tune : by The Brain [Razor 1911]
-   player : ver.1.2 by ?
-  comment : inaccurate replaying, because constant outport; in original player it can be 380 or 382.
-*/
-
-#include "bmf.h"
-#include "debug.h"
-
-const unsigned char CxadbmfPlayer::bmf_adlib_registers[117] =
-{
-  0x20, 0x23, 0x40, 0x43, 0x60, 0x63, 0x80, 0x83, 0xA0, 0xB0, 0xC0, 0xE0, 0xE3,
-  0x21, 0x24, 0x41, 0x44, 0x61, 0x64, 0x81, 0x84, 0xA1, 0xB1, 0xC1, 0xE1, 0xE4,
-  0x22, 0x25, 0x42, 0x45, 0x62, 0x65, 0x82, 0x85, 0xA2, 0xB2, 0xC2, 0xE2, 0xE5,
-  0x28, 0x2B, 0x48, 0x4B, 0x68, 0x6B, 0x88, 0x8B, 0xA3, 0xB3, 0xC3, 0xE8, 0xEB,
-  0x29, 0x2C, 0x49, 0x4C, 0x69, 0x6C, 0x89, 0x8C, 0xA4, 0xB4, 0xC4, 0xE9, 0xEC,
-  0x2A, 0x2D, 0x4A, 0x4D, 0x6A, 0x6D, 0x8A, 0x8D, 0xA5, 0xB5, 0xC5, 0xEA, 0xED,
-  0x30, 0x33, 0x50, 0x53, 0x70, 0x73, 0x90, 0x93, 0xA6, 0xB6, 0xC6, 0xF0, 0xF3,
-  0x31, 0x34, 0x51, 0x54, 0x71, 0x74, 0x91, 0x94, 0xA7, 0xB7, 0xC7, 0xF1, 0xF4,
-  0x32, 0x35, 0x52, 0x55, 0x72, 0x75, 0x92, 0x95, 0xA8, 0xB8, 0xC8, 0xF2, 0xF5
-};
-
-const unsigned short CxadbmfPlayer::bmf_notes[12] =
-{
-  0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287
-};
-
-/* for 1.1 */
-const unsigned short CxadbmfPlayer::bmf_notes_2[12] =
-{
-  0x159, 0x16D, 0x183, 0x19A, 0x1B2, 0x1CC, 0x1E8, 0x205, 0x223, 0x244, 0x267, 0x28B
-};
-
-const unsigned char CxadbmfPlayer::bmf_default_instrument[13] =
-{
-  0x01, 0x01, 0x3F, 0x3F, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-CPlayer *CxadbmfPlayer::factory(Copl *newopl)
-{
-  return new CxadbmfPlayer(newopl);
-}
-
-bool CxadbmfPlayer::xadplayer_load()
-{
-  unsigned short ptr = 0;
-  int i;
-
-  if(xad.fmt != BMF)
-    return false;
-
-#ifdef DEBUG
-  AdPlug_LogWrite("\nbmf_load():\n\n");
-#endif
-  if (!strncmp((char *)&tune[0],"BMF1.2",6))
-  {
-    bmf.version = BMF1_2;
-    bmf.timer = 70.0f;
-  }
-  else if (!strncmp((char *)&tune[0],"BMF1.1",6))
-  {
-    bmf.version = BMF1_1;
-    bmf.timer = 60.0f;
-  }
-  else
-  {
-    bmf.version = BMF0_9B;
-    bmf.timer = 18.2f;
-  }
-
-  // copy title & author
-  if (bmf.version > BMF0_9B)
-  {
-    ptr = 6;
-
-    strncpy(bmf.title,(char *)&tune[ptr],36);
-
-    while (tune[ptr]) { ptr++; }
-	ptr++;
-
-    strncpy(bmf.author,(char *)&tune[ptr],36);
-
-    while (tune[ptr]) { ptr++; }
-	ptr++;
-  }
-  else
-  {
-    strncpy(bmf.title,xad.title,36);
-    strncpy(bmf.author,xad.author,36);
-  }
-
-  // speed
-  if (bmf.version > BMF0_9B)
-    bmf.speed = tune[ptr++];
-  else
-    bmf.speed = ((tune[ptr++] << 8) / 3) >> 8; // strange, yeh ?
-
-  // load instruments
-  if (bmf.version > BMF0_9B)
-  {
-    unsigned long iflags = (tune[ptr] << 24) | (tune[ptr+1] << 16) | (tune[ptr+2] << 8) | tune[ptr+3];
-    ptr+=4;
-
-    for(i=0;i<32;i++)
-      if (iflags & (1 << (31-i)))
-	  {
-        strcpy(bmf.instruments[i].name, (char *)&tune[ptr]);
-        memcpy(bmf.instruments[i].data, &tune[ptr+11], 13);
-        ptr += 24;
-	  }
-      else
-	  {
-        bmf.instruments[i].name[0] = 0;
-		
-        if (bmf.version == BMF1_1)
-		  for(int j=0;j<13;j++)
-			bmf.instruments[i].data[j] = bmf_default_instrument[j];
-        else
-		  for(int j=0;j<13;j++)
-			bmf.instruments[i].data[j] = 0;
-	  }
-  }
-  else
-  {
-    ptr = 6;
-
-    for(i=0;i<32;i++)
-    {
-      bmf.instruments[i].name[0] = 0;
-      memcpy(bmf.instruments[tune[ptr]].data, &tune[ptr+2],13); // bug no.1 (no instrument-table-end detection)
-      ptr+=15;
-    }
-  }
-  
-  // load streams
-  if (bmf.version > BMF0_9B)
-  {
-    unsigned long sflags = (tune[ptr] << 24) | (tune[ptr+1] << 16) | (tune[ptr+2] << 8) | tune[ptr+3];
-    ptr+=4;
-
-    for(i=0;i<9;i++)
-      if (sflags & (1 << (31-i)))
-        ptr+=__bmf_convert_stream(&tune[ptr],i);
-      else
-        bmf.streams[i][0].cmd = 0xFF;
-  }
-  else
-  {
-    for(i=0;i<tune[5];i++)
-      ptr+=__bmf_convert_stream(&tune[ptr],i);
-
-	for(i=tune[5];i<9;i++)
-      bmf.streams[i][0].cmd = 0xFF;
-  }
-
-  return true;
-}
-
-void CxadbmfPlayer::xadplayer_rewind(int subsong)
-{
-  int i,j;
-
-  for(i=0; i<9; i++)
-  {
-    bmf.channel[i].stream_position = 0;
-    bmf.channel[i].delay = 0;
-    bmf.channel[i].loop_position = 0;
-    bmf.channel[i].loop_counter = 0;
-  }
-
-  plr.speed = bmf.speed;
-#ifdef DEBUG
-  AdPlug_LogWrite("speed: %x\n",plr.speed);
-#endif
-
-  bmf.active_streams = 9;
-
-  // OPL initialization
-  if (bmf.version > BMF0_9B)
-  {
-    opl_write(0x01, 0x20);
-    
-    /* 1.1 */
-    if (bmf.version == BMF1_1)
-      for(i=0;i<9;i++)
-        for(j=0;j<13;j++)
-          opl_write(bmf_adlib_registers[13*i+j], bmf_default_instrument[j]);
-    /* 1.2 */
-    else if (bmf.version == BMF1_2)
-      for(i=0x20; i<0x100; i++)
-        opl_write(i,0xFF); // very interesting, really!
-  }
-
-  /* ALL */
-
-  opl_write(0x08, 0x00);
-  opl_write(0xBD, 0xC0);
-}
-
-void CxadbmfPlayer::xadplayer_update()
-{
-  for(int i=0;i<9;i++)
-    if (bmf.channel[i].stream_position != 0xFFFF)
-    if (bmf.channel[i].delay)
-      bmf.channel[i].delay--;
-	else
-	{
-#ifdef DEBUG
-   AdPlug_LogWrite("channel %02X:\n", i);
-#endif
-      bmf_event event;
-
-      // process so-called cross-events
-  	  while (true)
-	  {
-        memcpy(&event, &bmf.streams[i][bmf.channel[i].stream_position], sizeof(bmf_event));
-#ifdef DEBUG
-   AdPlug_LogWrite("%02X %02X %02X %02X %02X %02X\n",
-		   event.note,event.delay,event.volume,event.instrument,
-		   event.cmd,event.cmd_data);
-#endif
-
-        if (event.cmd == 0xFF)
-		{
-          bmf.channel[i].stream_position = 0xFFFF;
-          bmf.active_streams--;
-          break;
-		}
-        else if (event.cmd == 0xFE)
-		{
-          bmf.channel[i].loop_position = bmf.channel[i].stream_position+1;
-          bmf.channel[i].loop_counter = event.cmd_data;
-		}
-        else if (event.cmd == 0xFD)
-		{
-          if (bmf.channel[i].loop_counter)
-          {
-            bmf.channel[i].stream_position = bmf.channel[i].loop_position-1;
-            bmf.channel[i].loop_counter--;
-          }
-		}
-        else
-          break;
-
-        bmf.channel[i].stream_position++;
-	  } // while (true)
-
-      // process normal event
-      unsigned short pos = bmf.channel[i].stream_position;
-
-      if (pos != 0xFFFF)
-      {
-        bmf.channel[i].delay = bmf.streams[i][pos].delay;
-
-        // command ?
-        if (bmf.streams[i][pos].cmd)
-		{
-          unsigned char cmd = bmf.streams[i][pos].cmd;
-
-          // 0x01: Set Modulator Volume
-          if (cmd == 0x01)
-		  {
-            unsigned char reg = bmf_adlib_registers[13*i+2];
-
-            opl_write(reg, (adlib[reg] | 0x3F) - bmf.streams[i][pos].cmd_data);
-		  }
-          // 0x10: Set Speed
-		  else if (cmd == 0x10)
-		  {
-            plr.speed = bmf.streams[i][pos].cmd_data;
-		    plr.speed_counter = plr.speed;
-		  }
-		} // if (bmf.streams[i][pos].cmd)
-
-        // instrument ?
-        if (bmf.streams[i][pos].instrument)
-		{
-          unsigned char ins = bmf.streams[i][pos].instrument-1;
-
-          if (bmf.version != BMF1_1)
-            opl_write(0xB0+i, adlib[0xB0+i] & 0xDF);
-
-          for(int j=0;j<13;j++)
-            opl_write(bmf_adlib_registers[i*13+j], bmf.instruments[ins].data[j]);
-		} // if (bmf.streams[i][pos].instrument)
-
-        // volume ?
-        if (bmf.streams[i][pos].volume)
-		{
-          unsigned char vol = bmf.streams[i][pos].volume-1;
-          unsigned char reg = bmf_adlib_registers[13*i+3];
-
-          opl_write(reg, (adlib[reg] | 0x3F) - vol);
-		} // if (bmf.streams[i][pos].volume)
-
-	    // note ?
-        if (bmf.streams[i][pos].note)
-		{
-          unsigned short note = bmf.streams[i][pos].note;
-          unsigned short freq = 0;
-
-          // mute channel
-          opl_write(0xB0+i, adlib[0xB0+i] & 0xDF);
-
-          // get frequency
-          if (bmf.version == BMF1_1)
-          {
-            if (note <= 0x60)
-              freq = bmf_notes_2[--note % 12];
-          }
-          else
-		  {
-            if (note != 0x7F)
-              freq = bmf_notes[--note % 12];
-		  }
-
-          // play note
-		  if (freq)
-          {
-            opl_write(0xB0+i, (freq >> 8) | ((note / 12) << 2) | 0x20);
-            opl_write(0xA0+i, freq & 0xFF);
-          }
-		} // if (bmf.streams[i][pos].note)
-
-        bmf.channel[i].stream_position++;
-      } // if (pos != 0xFFFF)
-
-	} // if (!bmf.channel[i].delay)
-
-  // is module loop ?
-  if (!bmf.active_streams)
-  {
-    for(int j=0;j<9;j++)
-      bmf.channel[j].stream_position = 0;
-
-	bmf.active_streams = 9;
-
-    plr.looping = 1;
-  }
-}
-
-float CxadbmfPlayer::xadplayer_getrefresh()
-{
-  return bmf.timer;
-}
-
-std::string CxadbmfPlayer::xadplayer_gettype()
-{
-  return std::string("xad: BMF Adlib Tracker");
-}
-
-std::string CxadbmfPlayer::xadplayer_gettitle()
-{
-  return std::string(bmf.title);
-}
-
-std::string CxadbmfPlayer::xadplayer_getauthor()
-{
-  return std::string(bmf.author);
-}
-
-unsigned int CxadbmfPlayer::xadplayer_getinstruments()
-{
-  return 32;
-}
-
-std::string CxadbmfPlayer::xadplayer_getinstrument(unsigned int i)
-{
-  return std::string(bmf.instruments[i].name);
-}
-
-/* -------- Internal Functions ---------------------------- */
-
-int CxadbmfPlayer::__bmf_convert_stream(unsigned char *stream, int channel)
-{
-#ifdef DEBUG
-  AdPlug_LogWrite("channel %02X (note,delay,volume,instrument,command,command_data):\n",channel);
-  unsigned char *last = stream;
-#endif
-  unsigned char *stream_start = stream;
-
-  int pos = 0;
-
-  while (true)
-  {
-    memset(&bmf.streams[channel][pos], 0, sizeof(bmf_event));
-
-    bool is_cmd = false;
-
-    if (*stream == 0xFE)
-	{
-      // 0xFE -> 0xFF: End of Stream
-      bmf.streams[channel][pos].cmd = 0xFF;
-
-	  stream++;
-
-      break;
-	}
-    else if (*stream == 0xFC)
-	{
-      // 0xFC -> 0xFE xx: Save Loop Position
-      bmf.streams[channel][pos].cmd = 0xFE;
-      bmf.streams[channel][pos].cmd_data = (*(stream+1) & ((bmf.version == BMF0_9B) ? 0x7F : 0x3F)) - 1;
-
-	  stream+=2;
-    }
-    else if (*stream == 0x7D)
-	{
-      // 0x7D -> 0xFD: Loop Saved Position
-      bmf.streams[channel][pos].cmd = 0xFD;
-
-	  stream++;
-	}
-	else
-    {
-      if (*stream & 0x80)                           
-      {
-		if (*(stream+1) & 0x80)
-        {
-		  if (*(stream+1) & 0x40)
-          {
-            // byte0: 1aaaaaaa = NOTE
-            bmf.streams[channel][pos].note = *stream & 0x7F;
-            // byte1: 11bbbbbb = DELAY
-            bmf.streams[channel][pos].delay = *(stream+1) & 0x3F;
-            // byte2: cccccccc = COMMAND
-
-            stream+=2;
-
-            is_cmd = true;
-          }
-		  else
-          {
-            // byte0: 1aaaaaaa = NOTE
-            bmf.streams[channel][pos].note = *stream & 0x7F;
-            // byte1: 11bbbbbb = DELAY
-            bmf.streams[channel][pos].delay = *(stream+1) & 0x3F;
-
-			stream+=2;
-          } // if (*(stream+1) & 0x40)
-		}
-        else
-        {
-          // byte0: 1aaaaaaa = NOTE
-          bmf.streams[channel][pos].note = *stream & 0x7F;
-          // byte1: 0bbbbbbb = COMMAND
-
-          stream++;
-
-          is_cmd = true;
-        } // if (*(stream+1) & 0x80)
-	  }
-	  else
-      {
-        // byte0: 0aaaaaaa = NOTE
-        bmf.streams[channel][pos].note = *stream & 0x7F;
-
-		stream++;
-      } // if (*stream & 0x80)
-    } // if (*stream == 0xFE)
-
-	// is command ?
-    if (is_cmd)
-    {
-
-      /* ALL */
-
-      if ((0x20 <= *stream) && (*stream <= 0x3F))
-      {
-        // 0x20 or higher; 0x3F or lower: Set Instrument 
-        bmf.streams[channel][pos].instrument = *stream - 0x20 + 1;
-
-		stream++;
-      }
-      else if (0x40 <= *stream)
-      {
-        // 0x40 or higher: Set Volume
-        bmf.streams[channel][pos].volume = *stream - 0x40 + 1;
-
-		stream++;
-      }
-      else
-      {
-
-        /* 0.9b */
-
-        if (bmf.version == BMF0_9B)
-        if (*stream < 0x20)
-		{
-          // 0x1F or lower: ?
-		  stream++;
-		}
-
-        /* 1.2 */
-
-        if (bmf.version == BMF1_2)
-        if (*stream == 0x01)
-		{
-          // 0x01: Set Modulator Volume -> 0x01
-          bmf.streams[channel][pos].cmd = 0x01;
-          bmf.streams[channel][pos].cmd_data = *(stream+1);
-
-		  stream+=2;
-		}
-        else if (*stream == 0x02)
-		{
-          // 0x02: ?
-		  stream+=2;
-		}
-        else if (*stream == 0x03)
-		{
-          // 0x03: ?
-		  stream+=2;
-		}
-        else if (*stream == 0x04)
-		{
-          // 0x04: Set Speed -> 0x10
-          bmf.streams[channel][pos].cmd = 0x10;
-          bmf.streams[channel][pos].cmd_data = *(stream+1);
-
-          stream+=2;
-		}
-        else if (*stream == 0x05)
-		{
-          // 0x05: Set Carrier Volume (port 380)
-          bmf.streams[channel][pos].volume = *(stream+1) + 1;
-
-		  stream+=2;
-		}
-        else if (*stream == 0x06)
-		{
-          // 0x06: Set Carrier Volume (port 382)
-          bmf.streams[channel][pos].volume = *(stream+1) + 1;
-
-		  stream+=2;
-		} // if (bmf.version == BMF1_2)
-
-      } // if ((0x20 <= *stream) && (*stream <= 0x3F))
-
-    } // if (is_cmd)
-
-#ifdef DEBUG
-   AdPlug_LogWrite("%02X %02X %02X %02X %02X %02X  <----  ", 
-			bmf.streams[channel][pos].note,	
-			bmf.streams[channel][pos].delay,
-			bmf.streams[channel][pos].volume, 
-			bmf.streams[channel][pos].instrument,
-			bmf.streams[channel][pos].cmd, 
-			bmf.streams[channel][pos].cmd_data
-		   );
-   for(int zz=0;zz<(stream-last);zz++)
-     AdPlug_LogWrite("%02X ",last[zz]);
-   AdPlug_LogWrite("\n");
-   last=stream;
-#endif
-    pos++;
-  } // while (true)
-
-  return (stream - stream_start);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/bmf.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,596 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * [xad] BMF player, by Riven the Mage <riven@ok.ru>
+ */
+
+/*
+    - discovery -
+
+  file(s) : GAMESNET.COM
+     type : GamesNet advertising intro
+     tune : by (?)The Brain [Razor 1911]
+   player : ver.0.9b by Hammer
+
+  file(s) : 2FAST4U.COM
+     type : Ford Knox BBStro
+     tune : by The Brain [Razor 1911]
+   player : ver.1.1 by ?
+  comment : in original player at 9th channel the feedback adlib register is not C8 but C6.
+
+  file(s) : DATURA.COM
+     type : Datura BBStro
+     tune : by The Brain [Razor 1911]
+   player : ver.1.2 by ?
+  comment : inaccurate replaying, because constant outport; in original player it can be 380 or 382.
+*/
+
+#include "bmf.h"
+#include "debug.h"
+
+const unsigned char CxadbmfPlayer::bmf_adlib_registers[117] =
+{
+  0x20, 0x23, 0x40, 0x43, 0x60, 0x63, 0x80, 0x83, 0xA0, 0xB0, 0xC0, 0xE0, 0xE3,
+  0x21, 0x24, 0x41, 0x44, 0x61, 0x64, 0x81, 0x84, 0xA1, 0xB1, 0xC1, 0xE1, 0xE4,
+  0x22, 0x25, 0x42, 0x45, 0x62, 0x65, 0x82, 0x85, 0xA2, 0xB2, 0xC2, 0xE2, 0xE5,
+  0x28, 0x2B, 0x48, 0x4B, 0x68, 0x6B, 0x88, 0x8B, 0xA3, 0xB3, 0xC3, 0xE8, 0xEB,
+  0x29, 0x2C, 0x49, 0x4C, 0x69, 0x6C, 0x89, 0x8C, 0xA4, 0xB4, 0xC4, 0xE9, 0xEC,
+  0x2A, 0x2D, 0x4A, 0x4D, 0x6A, 0x6D, 0x8A, 0x8D, 0xA5, 0xB5, 0xC5, 0xEA, 0xED,
+  0x30, 0x33, 0x50, 0x53, 0x70, 0x73, 0x90, 0x93, 0xA6, 0xB6, 0xC6, 0xF0, 0xF3,
+  0x31, 0x34, 0x51, 0x54, 0x71, 0x74, 0x91, 0x94, 0xA7, 0xB7, 0xC7, 0xF1, 0xF4,
+  0x32, 0x35, 0x52, 0x55, 0x72, 0x75, 0x92, 0x95, 0xA8, 0xB8, 0xC8, 0xF2, 0xF5
+};
+
+const unsigned short CxadbmfPlayer::bmf_notes[12] =
+{
+  0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287
+};
+
+/* for 1.1 */
+const unsigned short CxadbmfPlayer::bmf_notes_2[12] =
+{
+  0x159, 0x16D, 0x183, 0x19A, 0x1B2, 0x1CC, 0x1E8, 0x205, 0x223, 0x244, 0x267, 0x28B
+};
+
+const unsigned char CxadbmfPlayer::bmf_default_instrument[13] =
+{
+  0x01, 0x01, 0x3F, 0x3F, 0x00, 0x00, 0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+CPlayer *CxadbmfPlayer::factory(Copl *newopl)
+{
+  return new CxadbmfPlayer(newopl);
+}
+
+bool CxadbmfPlayer::xadplayer_load()
+{
+  unsigned short ptr = 0;
+  int i;
+
+  if(xad.fmt != BMF)
+    return false;
+
+#ifdef DEBUG
+  AdPlug_LogWrite("\nbmf_load():\n\n");
+#endif
+  if (!strncmp((char *)&tune[0],"BMF1.2",6))
+  {
+    bmf.version = BMF1_2;
+    bmf.timer = 70.0f;
+  }
+  else if (!strncmp((char *)&tune[0],"BMF1.1",6))
+  {
+    bmf.version = BMF1_1;
+    bmf.timer = 60.0f;
+  }
+  else
+  {
+    bmf.version = BMF0_9B;
+    bmf.timer = 18.2f;
+  }
+
+  // copy title & author
+  if (bmf.version > BMF0_9B)
+  {
+    ptr = 6;
+
+    strncpy(bmf.title,(char *)&tune[ptr],36);
+
+    while (tune[ptr]) { ptr++; }
+	ptr++;
+
+    strncpy(bmf.author,(char *)&tune[ptr],36);
+
+    while (tune[ptr]) { ptr++; }
+	ptr++;
+  }
+  else
+  {
+    strncpy(bmf.title,xad.title,36);
+    strncpy(bmf.author,xad.author,36);
+  }
+
+  // speed
+  if (bmf.version > BMF0_9B)
+    bmf.speed = tune[ptr++];
+  else
+    bmf.speed = ((tune[ptr++] << 8) / 3) >> 8; // strange, yeh ?
+
+  // load instruments
+  if (bmf.version > BMF0_9B)
+  {
+    unsigned long iflags = (tune[ptr] << 24) | (tune[ptr+1] << 16) | (tune[ptr+2] << 8) | tune[ptr+3];
+    ptr+=4;
+
+    for(i=0;i<32;i++)
+      if (iflags & (1 << (31-i)))
+	  {
+        strcpy(bmf.instruments[i].name, (char *)&tune[ptr]);
+        memcpy(bmf.instruments[i].data, &tune[ptr+11], 13);
+        ptr += 24;
+	  }
+      else
+	  {
+        bmf.instruments[i].name[0] = 0;
+		
+        if (bmf.version == BMF1_1)
+		  for(int j=0;j<13;j++)
+			bmf.instruments[i].data[j] = bmf_default_instrument[j];
+        else
+		  for(int j=0;j<13;j++)
+			bmf.instruments[i].data[j] = 0;
+	  }
+  }
+  else
+  {
+    ptr = 6;
+
+    for(i=0;i<32;i++)
+    {
+      bmf.instruments[i].name[0] = 0;
+      memcpy(bmf.instruments[tune[ptr]].data, &tune[ptr+2],13); // bug no.1 (no instrument-table-end detection)
+      ptr+=15;
+    }
+  }
+  
+  // load streams
+  if (bmf.version > BMF0_9B)
+  {
+    unsigned long sflags = (tune[ptr] << 24) | (tune[ptr+1] << 16) | (tune[ptr+2] << 8) | tune[ptr+3];
+    ptr+=4;
+
+    for(i=0;i<9;i++)
+      if (sflags & (1 << (31-i)))
+        ptr+=__bmf_convert_stream(&tune[ptr],i);
+      else
+        bmf.streams[i][0].cmd = 0xFF;
+  }
+  else
+  {
+    for(i=0;i<tune[5];i++)
+      ptr+=__bmf_convert_stream(&tune[ptr],i);
+
+	for(i=tune[5];i<9;i++)
+      bmf.streams[i][0].cmd = 0xFF;
+  }
+
+  return true;
+}
+
+void CxadbmfPlayer::xadplayer_rewind(int subsong)
+{
+  int i,j;
+
+  for(i=0; i<9; i++)
+  {
+    bmf.channel[i].stream_position = 0;
+    bmf.channel[i].delay = 0;
+    bmf.channel[i].loop_position = 0;
+    bmf.channel[i].loop_counter = 0;
+  }
+
+  plr.speed = bmf.speed;
+#ifdef DEBUG
+  AdPlug_LogWrite("speed: %x\n",plr.speed);
+#endif
+
+  bmf.active_streams = 9;
+
+  // OPL initialization
+  if (bmf.version > BMF0_9B)
+  {
+    opl_write(0x01, 0x20);
+    
+    /* 1.1 */
+    if (bmf.version == BMF1_1)
+      for(i=0;i<9;i++)
+        for(j=0;j<13;j++)
+          opl_write(bmf_adlib_registers[13*i+j], bmf_default_instrument[j]);
+    /* 1.2 */
+    else if (bmf.version == BMF1_2)
+      for(i=0x20; i<0x100; i++)
+        opl_write(i,0xFF); // very interesting, really!
+  }
+
+  /* ALL */
+
+  opl_write(0x08, 0x00);
+  opl_write(0xBD, 0xC0);
+}
+
+void CxadbmfPlayer::xadplayer_update()
+{
+  for(int i=0;i<9;i++)
+    if (bmf.channel[i].stream_position != 0xFFFF)
+    if (bmf.channel[i].delay)
+      bmf.channel[i].delay--;
+	else
+	{
+#ifdef DEBUG
+   AdPlug_LogWrite("channel %02X:\n", i);
+#endif
+      bmf_event event;
+
+      // process so-called cross-events
+  	  while (true)
+	  {
+        memcpy(&event, &bmf.streams[i][bmf.channel[i].stream_position], sizeof(bmf_event));
+#ifdef DEBUG
+   AdPlug_LogWrite("%02X %02X %02X %02X %02X %02X\n",
+		   event.note,event.delay,event.volume,event.instrument,
+		   event.cmd,event.cmd_data);
+#endif
+
+        if (event.cmd == 0xFF)
+		{
+          bmf.channel[i].stream_position = 0xFFFF;
+          bmf.active_streams--;
+          break;
+		}
+        else if (event.cmd == 0xFE)
+		{
+          bmf.channel[i].loop_position = bmf.channel[i].stream_position+1;
+          bmf.channel[i].loop_counter = event.cmd_data;
+		}
+        else if (event.cmd == 0xFD)
+		{
+          if (bmf.channel[i].loop_counter)
+          {
+            bmf.channel[i].stream_position = bmf.channel[i].loop_position-1;
+            bmf.channel[i].loop_counter--;
+          }
+		}
+        else
+          break;
+
+        bmf.channel[i].stream_position++;
+	  } // while (true)
+
+      // process normal event
+      unsigned short pos = bmf.channel[i].stream_position;
+
+      if (pos != 0xFFFF)
+      {
+        bmf.channel[i].delay = bmf.streams[i][pos].delay;
+
+        // command ?
+        if (bmf.streams[i][pos].cmd)
+		{
+          unsigned char cmd = bmf.streams[i][pos].cmd;
+
+          // 0x01: Set Modulator Volume
+          if (cmd == 0x01)
+		  {
+            unsigned char reg = bmf_adlib_registers[13*i+2];
+
+            opl_write(reg, (adlib[reg] | 0x3F) - bmf.streams[i][pos].cmd_data);
+		  }
+          // 0x10: Set Speed
+		  else if (cmd == 0x10)
+		  {
+            plr.speed = bmf.streams[i][pos].cmd_data;
+		    plr.speed_counter = plr.speed;
+		  }
+		} // if (bmf.streams[i][pos].cmd)
+
+        // instrument ?
+        if (bmf.streams[i][pos].instrument)
+		{
+          unsigned char ins = bmf.streams[i][pos].instrument-1;
+
+          if (bmf.version != BMF1_1)
+            opl_write(0xB0+i, adlib[0xB0+i] & 0xDF);
+
+          for(int j=0;j<13;j++)
+            opl_write(bmf_adlib_registers[i*13+j], bmf.instruments[ins].data[j]);
+		} // if (bmf.streams[i][pos].instrument)
+
+        // volume ?
+        if (bmf.streams[i][pos].volume)
+		{
+          unsigned char vol = bmf.streams[i][pos].volume-1;
+          unsigned char reg = bmf_adlib_registers[13*i+3];
+
+          opl_write(reg, (adlib[reg] | 0x3F) - vol);
+		} // if (bmf.streams[i][pos].volume)
+
+	    // note ?
+        if (bmf.streams[i][pos].note)
+		{
+          unsigned short note = bmf.streams[i][pos].note;
+          unsigned short freq = 0;
+
+          // mute channel
+          opl_write(0xB0+i, adlib[0xB0+i] & 0xDF);
+
+          // get frequency
+          if (bmf.version == BMF1_1)
+          {
+            if (note <= 0x60)
+              freq = bmf_notes_2[--note % 12];
+          }
+          else
+		  {
+            if (note != 0x7F)
+              freq = bmf_notes[--note % 12];
+		  }
+
+          // play note
+		  if (freq)
+          {
+            opl_write(0xB0+i, (freq >> 8) | ((note / 12) << 2) | 0x20);
+            opl_write(0xA0+i, freq & 0xFF);
+          }
+		} // if (bmf.streams[i][pos].note)
+
+        bmf.channel[i].stream_position++;
+      } // if (pos != 0xFFFF)
+
+	} // if (!bmf.channel[i].delay)
+
+  // is module loop ?
+  if (!bmf.active_streams)
+  {
+    for(int j=0;j<9;j++)
+      bmf.channel[j].stream_position = 0;
+
+	bmf.active_streams = 9;
+
+    plr.looping = 1;
+  }
+}
+
+float CxadbmfPlayer::xadplayer_getrefresh()
+{
+  return bmf.timer;
+}
+
+std::string CxadbmfPlayer::xadplayer_gettype()
+{
+  return std::string("xad: BMF Adlib Tracker");
+}
+
+std::string CxadbmfPlayer::xadplayer_gettitle()
+{
+  return std::string(bmf.title);
+}
+
+std::string CxadbmfPlayer::xadplayer_getauthor()
+{
+  return std::string(bmf.author);
+}
+
+unsigned int CxadbmfPlayer::xadplayer_getinstruments()
+{
+  return 32;
+}
+
+std::string CxadbmfPlayer::xadplayer_getinstrument(unsigned int i)
+{
+  return std::string(bmf.instruments[i].name);
+}
+
+/* -------- Internal Functions ---------------------------- */
+
+int CxadbmfPlayer::__bmf_convert_stream(unsigned char *stream, int channel)
+{
+#ifdef DEBUG
+  AdPlug_LogWrite("channel %02X (note,delay,volume,instrument,command,command_data):\n",channel);
+  unsigned char *last = stream;
+#endif
+  unsigned char *stream_start = stream;
+
+  int pos = 0;
+
+  while (true)
+  {
+    memset(&bmf.streams[channel][pos], 0, sizeof(bmf_event));
+
+    bool is_cmd = false;
+
+    if (*stream == 0xFE)
+	{
+      // 0xFE -> 0xFF: End of Stream
+      bmf.streams[channel][pos].cmd = 0xFF;
+
+	  stream++;
+
+      break;
+	}
+    else if (*stream == 0xFC)
+	{
+      // 0xFC -> 0xFE xx: Save Loop Position
+      bmf.streams[channel][pos].cmd = 0xFE;
+      bmf.streams[channel][pos].cmd_data = (*(stream+1) & ((bmf.version == BMF0_9B) ? 0x7F : 0x3F)) - 1;
+
+	  stream+=2;
+    }
+    else if (*stream == 0x7D)
+	{
+      // 0x7D -> 0xFD: Loop Saved Position
+      bmf.streams[channel][pos].cmd = 0xFD;
+
+	  stream++;
+	}
+	else
+    {
+      if (*stream & 0x80)                           
+      {
+		if (*(stream+1) & 0x80)
+        {
+		  if (*(stream+1) & 0x40)
+          {
+            // byte0: 1aaaaaaa = NOTE
+            bmf.streams[channel][pos].note = *stream & 0x7F;
+            // byte1: 11bbbbbb = DELAY
+            bmf.streams[channel][pos].delay = *(stream+1) & 0x3F;
+            // byte2: cccccccc = COMMAND
+
+            stream+=2;
+
+            is_cmd = true;
+          }
+		  else
+          {
+            // byte0: 1aaaaaaa = NOTE
+            bmf.streams[channel][pos].note = *stream & 0x7F;
+            // byte1: 11bbbbbb = DELAY
+            bmf.streams[channel][pos].delay = *(stream+1) & 0x3F;
+
+			stream+=2;
+          } // if (*(stream+1) & 0x40)
+		}
+        else
+        {
+          // byte0: 1aaaaaaa = NOTE
+          bmf.streams[channel][pos].note = *stream & 0x7F;
+          // byte1: 0bbbbbbb = COMMAND
+
+          stream++;
+
+          is_cmd = true;
+        } // if (*(stream+1) & 0x80)
+	  }
+	  else
+      {
+        // byte0: 0aaaaaaa = NOTE
+        bmf.streams[channel][pos].note = *stream & 0x7F;
+
+		stream++;
+      } // if (*stream & 0x80)
+    } // if (*stream == 0xFE)
+
+	// is command ?
+    if (is_cmd)
+    {
+
+      /* ALL */
+
+      if ((0x20 <= *stream) && (*stream <= 0x3F))
+      {
+        // 0x20 or higher; 0x3F or lower: Set Instrument 
+        bmf.streams[channel][pos].instrument = *stream - 0x20 + 1;
+
+		stream++;
+      }
+      else if (0x40 <= *stream)
+      {
+        // 0x40 or higher: Set Volume
+        bmf.streams[channel][pos].volume = *stream - 0x40 + 1;
+
+		stream++;
+      }
+      else
+      {
+
+        /* 0.9b */
+
+        if (bmf.version == BMF0_9B)
+        if (*stream < 0x20)
+		{
+          // 0x1F or lower: ?
+		  stream++;
+		}
+
+        /* 1.2 */
+
+        if (bmf.version == BMF1_2)
+        if (*stream == 0x01)
+		{
+          // 0x01: Set Modulator Volume -> 0x01
+          bmf.streams[channel][pos].cmd = 0x01;
+          bmf.streams[channel][pos].cmd_data = *(stream+1);
+
+		  stream+=2;
+		}
+        else if (*stream == 0x02)
+		{
+          // 0x02: ?
+		  stream+=2;
+		}
+        else if (*stream == 0x03)
+		{
+          // 0x03: ?
+		  stream+=2;
+		}
+        else if (*stream == 0x04)
+		{
+          // 0x04: Set Speed -> 0x10
+          bmf.streams[channel][pos].cmd = 0x10;
+          bmf.streams[channel][pos].cmd_data = *(stream+1);
+
+          stream+=2;
+		}
+        else if (*stream == 0x05)
+		{
+          // 0x05: Set Carrier Volume (port 380)
+          bmf.streams[channel][pos].volume = *(stream+1) + 1;
+
+		  stream+=2;
+		}
+        else if (*stream == 0x06)
+		{
+          // 0x06: Set Carrier Volume (port 382)
+          bmf.streams[channel][pos].volume = *(stream+1) + 1;
+
+		  stream+=2;
+		} // if (bmf.version == BMF1_2)
+
+      } // if ((0x20 <= *stream) && (*stream <= 0x3F))
+
+    } // if (is_cmd)
+
+#ifdef DEBUG
+   AdPlug_LogWrite("%02X %02X %02X %02X %02X %02X  <----  ", 
+			bmf.streams[channel][pos].note,	
+			bmf.streams[channel][pos].delay,
+			bmf.streams[channel][pos].volume, 
+			bmf.streams[channel][pos].instrument,
+			bmf.streams[channel][pos].cmd, 
+			bmf.streams[channel][pos].cmd_data
+		   );
+   for(int zz=0;zz<(stream-last);zz++)
+     AdPlug_LogWrite("%02X ",last[zz]);
+   AdPlug_LogWrite("\n");
+   last=stream;
+#endif
+    pos++;
+  } // while (true)
+
+  return (stream - stream_start);
+}
--- a/Plugins/Input/adplug/core/cff.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,507 +0,0 @@
-/*
-  AdPlug - Replayer for many OPL2/OPL3 audio file formats.
-  Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-  cff.cpp - BoomTracker loader by Riven the Mage <riven@ok.ru>
-*/
-/*
-  NOTE: Conversion of slides is not 100% accurate. Original volume slides
-  have effect on carrier volume only. Also, original arpeggio, frequency & volume
-  slides use previous effect data instead of current.
-*/
-
-#include <stdlib.h>
-
-#include "cff.h"
-
-/* -------- Public Methods -------------------------------- */
-
-CPlayer *CcffLoader::factory(Copl *newopl)
-{
-  return new CcffLoader(newopl);
-}
-
-bool CcffLoader::load(const std::string &filename, const CFileProvider &fp)
-{
-        binistream *f = fp.open(filename); if(!f) return false;
-	const unsigned char conv_inst[11] = { 2,1,10,9,4,3,6,5,0,8,7 };
-	const unsigned short conv_note[12] = { 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287, 0x2AE };
-
-	int i,j,k,t=0;
-
-	// '<CUD-FM-File>' - signed ?
-	f->readString(header.id, 16);
-	header.version = f->readInt(1); header.size = f->readInt(2);
-	header.packed = f->readInt(1); f->readString((char *)header.reserved, 12);
-	if (memcmp(header.id,"<CUD-FM-File>""\x1A\xDE\xE0",16))
-	  { fp.close(f); return false; }
-
-	unsigned char *module = new unsigned char [0x10000];
-
-	// packed ?
-	if (header.packed)
-	{
-		cff_unpacker *unpacker = new cff_unpacker;
-
-		unsigned char *packed_module = new unsigned char [header.size + 4];
-
-		memset(packed_module,0,header.size + 4);
-
-		f->readString((char *)packed_module, header.size);
-		fp.close(f);
-
-		if (!unpacker->unpack(packed_module,module))
-		{
-			delete unpacker;
-			delete packed_module;
-			delete module;
-			return false;
-		}
-
-		delete unpacker;
-		delete packed_module;
-
-		if (memcmp(&module[0x5E1],"CUD-FM-File - SEND A POSTCARD -",31))
-		{
-			delete module;
-			return false;
-		}
-	}
-	else
-	{
-		f->readString((char *)module, header.size);
-		fp.close(f);
-	}
-
-	// init CmodPlayer
-	realloc_instruments(47);
-	realloc_order(64);
-	realloc_patterns(36,64,9);
-	init_notetable(conv_note);
-	init_trackord();
-
-	// load instruments
-	for (i=0;i<47;i++)
-	{
-		memcpy(&instruments[i],&module[i*32],sizeof(cff_instrument));
-
-		for (j=0;j<11;j++)
-			inst[i].data[conv_inst[j]] = instruments[i].data[j];
-
-		instruments[i].name[20] = 0;
-	}
-
-	// number of patterns
-	nop = module[0x5E0];
-
-	// load title & author
-	memcpy(song_title,&module[0x614],20);
-	memcpy(song_author,&module[0x600],20);
-
-	// load order
-	memcpy(order,&module[0x628],64);
-
-	// load tracks
-	for (i=0;i<nop;i++)
-	{
-		unsigned char old_event_byte2[9];
-
-		memset(old_event_byte2,0,9);
-
-		for (j=0;j<9;j++)
-		{
-			for (k=0;k<64;k++)
-			{
-				cff_event *event = (cff_event *)&module[0x669 + ((i*64+k)*9+j)*3];
-
-				// convert note
-				if (event->byte0 == 0x6D)
-					tracks[t][k].note = 127;
-				else
-					if (event->byte0)
-						tracks[t][k].note = event->byte0;
-
-				if (event->byte2)
-					old_event_byte2[j] = event->byte2;
-
-				// convert effect
-				switch (event->byte1)
-				{
-					case 'I': // set instrument
-						tracks[t][k].inst = event->byte2 + 1;
-						tracks[t][k].param1 = tracks[t][k].param2 = 0;
-						break;
-
-					case 'H': // set tempo
-						tracks[t][k].command = 7;
-						if (event->byte2 < 16)
-						{
-							tracks[t][k].param1 = 0x07;
-	  						tracks[t][k].param2 = 0x0D;
-						}
-						break;
-
-					case 'A': // set speed
-						tracks[t][k].command = 19;
-						tracks[t][k].param1  = event->byte2 >> 4;
-						tracks[t][k].param2  = event->byte2 & 15;
-						break;
-
-					case 'L': // pattern break
-						tracks[t][k].command = 13;
-						tracks[t][k].param1  = event->byte2 >> 4;
-						tracks[t][k].param2  = event->byte2 & 15;
-						break;
-
-					case 'K': // order jump
-						tracks[t][k].command = 11;
-						tracks[t][k].param1  = event->byte2 >> 4;
-						tracks[t][k].param2  = event->byte2 & 15;
-						break;
-
-					case 'M': // set vibrato/tremolo
-						tracks[t][k].command = 27;
-						tracks[t][k].param1  = event->byte2 >> 4;
-						tracks[t][k].param2  = event->byte2 & 15;
-						break;
-
-					case 'C': // set modulator volume
-						tracks[t][k].command = 21;
-						tracks[t][k].param1 = (0x3F - event->byte2) >> 4;
-						tracks[t][k].param2 = (0x3F - event->byte2) & 15;
-						break;
-
-					case 'G': // set carrier volume
-						tracks[t][k].command = 22;
-						tracks[t][k].param1 = (0x3F - event->byte2) >> 4;
-						tracks[t][k].param2 = (0x3F - event->byte2) & 15;
-						break;
-
-					case 'B': // set carrier waveform
-						tracks[t][k].command = 25;
-						tracks[t][k].param1  = event->byte2;
-						tracks[t][k].param2  = 0x0F;
-						break;
-
-					case 'E': // fine frequency slide down
-						tracks[t][k].command = 24;
-						tracks[t][k].param1  = old_event_byte2[j] >> 4;
-						tracks[t][k].param2  = old_event_byte2[j] & 15;
-						break;
-
-					case 'F': // fine frequency slide up
-						tracks[t][k].command = 23;
-						tracks[t][k].param1  = old_event_byte2[j] >> 4;
-						tracks[t][k].param2  = old_event_byte2[j] & 15;
-						break;
-
-					case 'D': // fine volume slide
-						tracks[t][k].command = 14;
-						if (old_event_byte2[j] & 15)
-						{
-							// slide down
-							tracks[t][k].param1 = 5;
-							tracks[t][k].param2 = old_event_byte2[j] & 15;
-						}
-						else
-						{
-							// slide up
-							tracks[t][k].param1 = 4;
-							tracks[t][k].param2 = old_event_byte2[j] >> 4;
-						}
-						break;
-
-					case 'J': // arpeggio
-						tracks[t][k].param1  = old_event_byte2[j] >> 4;
-						tracks[t][k].param2  = old_event_byte2[j] & 15;
-						break;
-				}
-			}
-
-			t++;
-		}
-	}
-
-	delete [] module;
-
-	// order loop
-	restartpos = 0;
-
-	// order length
-	for (i=0;i<64;i++)
-	{
-		if (order[i] >= 0x80)
-		{
-			length = i;
-			break;
-		}
-	}
-
-	// default tempo
-	bpm = 0x7D;
-
-	rewind(0);
-
-	return true;	
-}
-
-void CcffLoader::rewind(int subsong)
-{
-	CmodPlayer::rewind(subsong);
-
-	// default instruments
-	for (int i=0;i<9;i++)
-	{
-		channel[i].inst = i;
-
-		channel[i].vol1 = 63 - (inst[i].data[10] & 63);
-		channel[i].vol2 = 63 - (inst[i].data[9] & 63);
-	}
-}
-
-std::string CcffLoader::gettype()
-{
-	if (header.packed)
-		return std::string("BoomTracker 4, packed");
-	else
-		return std::string("BoomTracker 4");
-}
-
-std::string CcffLoader::gettitle()
-{
-	return std::string(song_title,20);
-}
-
-std::string CcffLoader::getauthor()
-{
-	return std::string(song_author,20);
-}
-
-std::string CcffLoader::getinstrument(unsigned int n)
-{
-	return std::string(instruments[n].name);
-}
-
-unsigned int CcffLoader::getinstruments()
-{
-	return 47;
-}
-
-/* -------- Private Methods ------------------------------- */
-
-#ifdef _WIN32
-#pragma warning(disable:4244)
-#pragma warning(disable:4018)
-#endif
-
-/*
-  Lempel-Ziv-Tyr ;-)
-*/
-long CcffLoader::cff_unpacker::unpack(unsigned char *ibuf, unsigned char *obuf)
-{
-	if (memcmp(ibuf,"YsComp""\x07""CUD1997""\x1A\x04",16))
-		return 0;
-
-	input = ibuf + 16;
-	output = obuf;
-
-	output_length = 0;
-
-	heap = (unsigned char *)malloc(0x10000);
-	dictionary = (unsigned char **)malloc(sizeof(unsigned char *)*0x8000);
-
-	memset(heap,0,0x10000);
-	memset(dictionary,0,0x8000);
-
-	cleanup();
-  if(!startup())
-    goto out;
-
-	// LZW
-	while (1)
-	{
-		new_code = get_code();
-
-		// 0x00: end of data
-		if (new_code == 0)
-			break;
-
-		// 0x01: end of block
-		if (new_code == 1)
-		{
-			cleanup();
-			if(!startup())
-				goto out;
-
-			continue;
-		}
-
-		// 0x02: expand code length
-		if (new_code == 2)
-		{
-			code_length++;
-
-			continue;
-		}
-
-		// 0x03: RLE
-		if (new_code == 3)
-		{
-			unsigned char old_code_length = code_length;
-
-			code_length = 2;
-
-			unsigned char repeat_length = get_code() + 1;
-
-			code_length = 4 << get_code();
-
-			unsigned long repeat_counter = get_code();
-
-			if(output_length + repeat_counter * repeat_length > 0x10000) {
-				output_length = 0;
-				goto out;
-			}
-
-			for (unsigned int i=0;i<repeat_counter*repeat_length;i++)
-				output[output_length++] = output[output_length - repeat_length];
-
-			code_length = old_code_length;
-
-			if(!startup())
-				goto out;
-
-			continue;
-		}
-
-		if (new_code >= (0x104 + dictionary_length))
-		{
-			// dictionary <- old.code.string + old.code.char
-			the_string[++the_string[0]] = the_string[1];
-		}
-		else
-		{
-			// dictionary <- old.code.string + new.code.char
-			unsigned char temp_string[256];
-
-			translate_code(new_code,temp_string);
-
-			the_string[++the_string[0]] = temp_string[1];
-		}
-
-		expand_dictionary(the_string);
-
-		// output <- new.code.string
-		translate_code(new_code,the_string);
-
-			if(output_length + the_string[0] > 0x10000) {
-				output_length = 0;
-				goto out;
-			}
-
-		for (int i=0;i<the_string[0];i++)
-			output[output_length++] = the_string[i+1];
-
-		old_code = new_code;
-	}
-
- out:
-	free(heap);
-	free(dictionary);
-	return output_length;
-}
-
-unsigned long CcffLoader::cff_unpacker::get_code()
-{
-	unsigned long code;
-
-	while (bits_left < code_length)
-	{
-		bits_buffer |= ((*input++) << bits_left);
-		bits_left += 8;
-	}
-
-	code = bits_buffer & ((1 << code_length) - 1);
-
-	bits_buffer >>= code_length;
-	bits_left -= code_length;
-
-	return code;
-}
-
-void CcffLoader::cff_unpacker::translate_code(unsigned long code, unsigned char *string)
-{
-	unsigned char translated_string[256];
-
-	if (code >= 0x104)
-	{
-		memcpy(translated_string,dictionary[code - 0x104],(*(dictionary[code - 0x104])) + 1);
-	}
-	else
-	{
-		translated_string[0] = 1;
-		translated_string[1] = (code - 4) & 0xFF;
-	}
-
-	memcpy(string,translated_string,256);
-}
-
-void CcffLoader::cff_unpacker::cleanup()
-{
-	code_length = 9;
-
-	bits_buffer = 0;
-	bits_left = 0;
-
-	heap_length = 0;
-	dictionary_length = 0;
-}
-
-int CcffLoader::cff_unpacker::startup()
-{
-	old_code = get_code();
-
-	translate_code(old_code,the_string);
-
-  if(output_length + the_string[0] > 0x10000) {
-    output_length = 0;
-    return 0;
-  }
-
-	for (int i=0;i<the_string[0];i++)
-		output[output_length++] = the_string[i+1];
-
-  return 1;
-}
-
-void CcffLoader::cff_unpacker::expand_dictionary(unsigned char *string)
-{
-	if (string[0] >= 0xF0)
-		return;
-
-	memcpy(&heap[heap_length],string,string[0] + 1);
-
-	dictionary[dictionary_length] = &heap[heap_length];
-
-	dictionary_length++;
-
-	heap_length += (string[0] + 1);
-}
-
-#ifdef _WIN32
-#pragma warning(default:4244)
-#pragma warning(default:4018)
-#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/cff.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,507 @@
+/*
+  AdPlug - Replayer for many OPL2/OPL3 audio file formats.
+  Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  cff.cpp - BoomTracker loader by Riven the Mage <riven@ok.ru>
+*/
+/*
+  NOTE: Conversion of slides is not 100% accurate. Original volume slides
+  have effect on carrier volume only. Also, original arpeggio, frequency & volume
+  slides use previous effect data instead of current.
+*/
+
+#include <stdlib.h>
+
+#include "cff.h"
+
+/* -------- Public Methods -------------------------------- */
+
+CPlayer *CcffLoader::factory(Copl *newopl)
+{
+  return new CcffLoader(newopl);
+}
+
+bool CcffLoader::load(const std::string &filename, const CFileProvider &fp)
+{
+        binistream *f = fp.open(filename); if(!f) return false;
+	const unsigned char conv_inst[11] = { 2,1,10,9,4,3,6,5,0,8,7 };
+	const unsigned short conv_note[12] = { 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287, 0x2AE };
+
+	int i,j,k,t=0;
+
+	// '<CUD-FM-File>' - signed ?
+	f->readString(header.id, 16);
+	header.version = f->readInt(1); header.size = f->readInt(2);
+	header.packed = f->readInt(1); f->readString((char *)header.reserved, 12);
+	if (memcmp(header.id,"<CUD-FM-File>""\x1A\xDE\xE0",16))
+	  { fp.close(f); return false; }
+
+	unsigned char *module = new unsigned char [0x10000];
+
+	// packed ?
+	if (header.packed)
+	{
+		cff_unpacker *unpacker = new cff_unpacker;
+
+		unsigned char *packed_module = new unsigned char [header.size + 4];
+
+		memset(packed_module,0,header.size + 4);
+
+		f->readString((char *)packed_module, header.size);
+		fp.close(f);
+
+		if (!unpacker->unpack(packed_module,module))
+		{
+			delete unpacker;
+			delete packed_module;
+			delete module;
+			return false;
+		}
+
+		delete unpacker;
+		delete packed_module;
+
+		if (memcmp(&module[0x5E1],"CUD-FM-File - SEND A POSTCARD -",31))
+		{
+			delete module;
+			return false;
+		}
+	}
+	else
+	{
+		f->readString((char *)module, header.size);
+		fp.close(f);
+	}
+
+	// init CmodPlayer
+	realloc_instruments(47);
+	realloc_order(64);
+	realloc_patterns(36,64,9);
+	init_notetable(conv_note);
+	init_trackord();
+
+	// load instruments
+	for (i=0;i<47;i++)
+	{
+		memcpy(&instruments[i],&module[i*32],sizeof(cff_instrument));
+
+		for (j=0;j<11;j++)
+			inst[i].data[conv_inst[j]] = instruments[i].data[j];
+
+		instruments[i].name[20] = 0;
+	}
+
+	// number of patterns
+	nop = module[0x5E0];
+
+	// load title & author
+	memcpy(song_title,&module[0x614],20);
+	memcpy(song_author,&module[0x600],20);
+
+	// load order
+	memcpy(order,&module[0x628],64);
+
+	// load tracks
+	for (i=0;i<nop;i++)
+	{
+		unsigned char old_event_byte2[9];
+
+		memset(old_event_byte2,0,9);
+
+		for (j=0;j<9;j++)
+		{
+			for (k=0;k<64;k++)
+			{
+				cff_event *event = (cff_event *)&module[0x669 + ((i*64+k)*9+j)*3];
+
+				// convert note
+				if (event->byte0 == 0x6D)
+					tracks[t][k].note = 127;
+				else
+					if (event->byte0)
+						tracks[t][k].note = event->byte0;
+
+				if (event->byte2)
+					old_event_byte2[j] = event->byte2;
+
+				// convert effect
+				switch (event->byte1)
+				{
+					case 'I': // set instrument
+						tracks[t][k].inst = event->byte2 + 1;
+						tracks[t][k].param1 = tracks[t][k].param2 = 0;
+						break;
+
+					case 'H': // set tempo
+						tracks[t][k].command = 7;
+						if (event->byte2 < 16)
+						{
+							tracks[t][k].param1 = 0x07;
+	  						tracks[t][k].param2 = 0x0D;
+						}
+						break;
+
+					case 'A': // set speed
+						tracks[t][k].command = 19;
+						tracks[t][k].param1  = event->byte2 >> 4;
+						tracks[t][k].param2  = event->byte2 & 15;
+						break;
+
+					case 'L': // pattern break
+						tracks[t][k].command = 13;
+						tracks[t][k].param1  = event->byte2 >> 4;
+						tracks[t][k].param2  = event->byte2 & 15;
+						break;
+
+					case 'K': // order jump
+						tracks[t][k].command = 11;
+						tracks[t][k].param1  = event->byte2 >> 4;
+						tracks[t][k].param2  = event->byte2 & 15;
+						break;
+
+					case 'M': // set vibrato/tremolo
+						tracks[t][k].command = 27;
+						tracks[t][k].param1  = event->byte2 >> 4;
+						tracks[t][k].param2  = event->byte2 & 15;
+						break;
+
+					case 'C': // set modulator volume
+						tracks[t][k].command = 21;
+						tracks[t][k].param1 = (0x3F - event->byte2) >> 4;
+						tracks[t][k].param2 = (0x3F - event->byte2) & 15;
+						break;
+
+					case 'G': // set carrier volume
+						tracks[t][k].command = 22;
+						tracks[t][k].param1 = (0x3F - event->byte2) >> 4;
+						tracks[t][k].param2 = (0x3F - event->byte2) & 15;
+						break;
+
+					case 'B': // set carrier waveform
+						tracks[t][k].command = 25;
+						tracks[t][k].param1  = event->byte2;
+						tracks[t][k].param2  = 0x0F;
+						break;
+
+					case 'E': // fine frequency slide down
+						tracks[t][k].command = 24;
+						tracks[t][k].param1  = old_event_byte2[j] >> 4;
+						tracks[t][k].param2  = old_event_byte2[j] & 15;
+						break;
+
+					case 'F': // fine frequency slide up
+						tracks[t][k].command = 23;
+						tracks[t][k].param1  = old_event_byte2[j] >> 4;
+						tracks[t][k].param2  = old_event_byte2[j] & 15;
+						break;
+
+					case 'D': // fine volume slide
+						tracks[t][k].command = 14;
+						if (old_event_byte2[j] & 15)
+						{
+							// slide down
+							tracks[t][k].param1 = 5;
+							tracks[t][k].param2 = old_event_byte2[j] & 15;
+						}
+						else
+						{
+							// slide up
+							tracks[t][k].param1 = 4;
+							tracks[t][k].param2 = old_event_byte2[j] >> 4;
+						}
+						break;
+
+					case 'J': // arpeggio
+						tracks[t][k].param1  = old_event_byte2[j] >> 4;
+						tracks[t][k].param2  = old_event_byte2[j] & 15;
+						break;
+				}
+			}
+
+			t++;
+		}
+	}
+
+	delete [] module;
+
+	// order loop
+	restartpos = 0;
+
+	// order length
+	for (i=0;i<64;i++)
+	{
+		if (order[i] >= 0x80)
+		{
+			length = i;
+			break;
+		}
+	}
+
+	// default tempo
+	bpm = 0x7D;
+
+	rewind(0);
+
+	return true;	
+}
+
+void CcffLoader::rewind(int subsong)
+{
+	CmodPlayer::rewind(subsong);
+
+	// default instruments
+	for (int i=0;i<9;i++)
+	{
+		channel[i].inst = i;
+
+		channel[i].vol1 = 63 - (inst[i].data[10] & 63);
+		channel[i].vol2 = 63 - (inst[i].data[9] & 63);
+	}
+}
+
+std::string CcffLoader::gettype()
+{
+	if (header.packed)
+		return std::string("BoomTracker 4, packed");
+	else
+		return std::string("BoomTracker 4");
+}
+
+std::string CcffLoader::gettitle()
+{
+	return std::string(song_title,20);
+}
+
+std::string CcffLoader::getauthor()
+{
+	return std::string(song_author,20);
+}
+
+std::string CcffLoader::getinstrument(unsigned int n)
+{
+	return std::string(instruments[n].name);
+}
+
+unsigned int CcffLoader::getinstruments()
+{
+	return 47;
+}
+
+/* -------- Private Methods ------------------------------- */
+
+#ifdef _WIN32
+#pragma warning(disable:4244)
+#pragma warning(disable:4018)
+#endif
+
+/*
+  Lempel-Ziv-Tyr ;-)
+*/
+long CcffLoader::cff_unpacker::unpack(unsigned char *ibuf, unsigned char *obuf)
+{
+	if (memcmp(ibuf,"YsComp""\x07""CUD1997""\x1A\x04",16))
+		return 0;
+
+	input = ibuf + 16;
+	output = obuf;
+
+	output_length = 0;
+
+	heap = (unsigned char *)malloc(0x10000);
+	dictionary = (unsigned char **)malloc(sizeof(unsigned char *)*0x8000);
+
+	memset(heap,0,0x10000);
+	memset(dictionary,0,0x8000);
+
+	cleanup();
+  if(!startup())
+    goto out;
+
+	// LZW
+	while (1)
+	{
+		new_code = get_code();
+
+		// 0x00: end of data
+		if (new_code == 0)
+			break;
+
+		// 0x01: end of block
+		if (new_code == 1)
+		{
+			cleanup();
+			if(!startup())
+				goto out;
+
+			continue;
+		}
+
+		// 0x02: expand code length
+		if (new_code == 2)
+		{
+			code_length++;
+
+			continue;
+		}
+
+		// 0x03: RLE
+		if (new_code == 3)
+		{
+			unsigned char old_code_length = code_length;
+
+			code_length = 2;
+
+			unsigned char repeat_length = get_code() + 1;
+
+			code_length = 4 << get_code();
+
+			unsigned long repeat_counter = get_code();
+
+			if(output_length + repeat_counter * repeat_length > 0x10000) {
+				output_length = 0;
+				goto out;
+			}
+
+			for (unsigned int i=0;i<repeat_counter*repeat_length;i++)
+				output[output_length++] = output[output_length - repeat_length];
+
+			code_length = old_code_length;
+
+			if(!startup())
+				goto out;
+
+			continue;
+		}
+
+		if (new_code >= (0x104 + dictionary_length))
+		{
+			// dictionary <- old.code.string + old.code.char
+			the_string[++the_string[0]] = the_string[1];
+		}
+		else
+		{
+			// dictionary <- old.code.string + new.code.char
+			unsigned char temp_string[256];
+
+			translate_code(new_code,temp_string);
+
+			the_string[++the_string[0]] = temp_string[1];
+		}
+
+		expand_dictionary(the_string);
+
+		// output <- new.code.string
+		translate_code(new_code,the_string);
+
+			if(output_length + the_string[0] > 0x10000) {
+				output_length = 0;
+				goto out;
+			}
+
+		for (int i=0;i<the_string[0];i++)
+			output[output_length++] = the_string[i+1];
+
+		old_code = new_code;
+	}
+
+ out:
+	free(heap);
+	free(dictionary);
+	return output_length;
+}
+
+unsigned long CcffLoader::cff_unpacker::get_code()
+{
+	unsigned long code;
+
+	while (bits_left < code_length)
+	{
+		bits_buffer |= ((*input++) << bits_left);
+		bits_left += 8;
+	}
+
+	code = bits_buffer & ((1 << code_length) - 1);
+
+	bits_buffer >>= code_length;
+	bits_left -= code_length;
+
+	return code;
+}
+
+void CcffLoader::cff_unpacker::translate_code(unsigned long code, unsigned char *string)
+{
+	unsigned char translated_string[256];
+
+	if (code >= 0x104)
+	{
+		memcpy(translated_string,dictionary[code - 0x104],(*(dictionary[code - 0x104])) + 1);
+	}
+	else
+	{
+		translated_string[0] = 1;
+		translated_string[1] = (code - 4) & 0xFF;
+	}
+
+	memcpy(string,translated_string,256);
+}
+
+void CcffLoader::cff_unpacker::cleanup()
+{
+	code_length = 9;
+
+	bits_buffer = 0;
+	bits_left = 0;
+
+	heap_length = 0;
+	dictionary_length = 0;
+}
+
+int CcffLoader::cff_unpacker::startup()
+{
+	old_code = get_code();
+
+	translate_code(old_code,the_string);
+
+  if(output_length + the_string[0] > 0x10000) {
+    output_length = 0;
+    return 0;
+  }
+
+	for (int i=0;i<the_string[0];i++)
+		output[output_length++] = the_string[i+1];
+
+  return 1;
+}
+
+void CcffLoader::cff_unpacker::expand_dictionary(unsigned char *string)
+{
+	if (string[0] >= 0xF0)
+		return;
+
+	memcpy(&heap[heap_length],string,string[0] + 1);
+
+	dictionary[dictionary_length] = &heap[heap_length];
+
+	dictionary_length++;
+
+	heap_length += (string[0] + 1);
+}
+
+#ifdef _WIN32
+#pragma warning(default:4244)
+#pragma warning(default:4018)
+#endif
--- a/Plugins/Input/adplug/core/d00.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,538 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * d00.c - D00 Player by Simon Peter <dn.tlp@gmx.net>
- *
- * NOTES:
- * Sorry for the goto's, but the code looks so much nicer now.
- * I tried it with while loops but it was just a mess. If you
- * can come up with a nicer solution, just tell me.
- *
- * BUGS:
- * Hard restart SR is sometimes wrong
- */
-
-#include <string.h>
-#include <stdio.h>
-#include <inttypes.h>
-
-#include "debug.h"
-#include "d00.h"
-
-#define HIBYTE(val)	(val >> 8)
-#define LOBYTE(val)	(val & 0xff)
-
-static const unsigned short notetable[12] =	// D00 note table
-  {340,363,385,408,432,458,485,514,544,577,611,647};
-
-static inline uint16_t LE_WORD(const uint16_t *val)
-{
-  const uint8_t *b = (const uint8_t *)val;
-  return (b[1] << 8) + b[0];
-}
-
-/*** public methods *************************************/
-
-CPlayer *Cd00Player::factory(Copl *newopl)
-{
-  return new Cd00Player(newopl);
-}
-
-bool Cd00Player::load(const std::string &filename, const CFileProvider &fp)
-{
-  binistream	*f = fp.open(filename); if(!f) return false;
-  d00header	*checkhead;
-  d00header1	*ch;
-  unsigned long	filesize;
-  int		i,ver1=0;
-  char		*str;
-
-  // file validation section
-  checkhead = new d00header;
-  f->readString((char *)checkhead, sizeof(d00header));
-
-  // Check for version 2-4 header
-  if(strncmp(checkhead->id,"JCH\x26\x02\x66",6) || checkhead->type ||
-     !checkhead->subsongs || checkhead->soundcard) {
-    // Check for version 0 or 1 header (and .d00 file extension)
-    delete checkhead;
-    if(!fp.extension(filename, ".d00")) { fp.close(f); return false; }
-    ch = new d00header1;
-    f->seek(0); f->readString((char *)ch, sizeof(d00header1));
-    if(ch->version > 1 || !ch->subsongs)
-      { delete ch; fp.close(f); return false; }
-    delete ch;
-    ver1 = 1;
-  } else
-    delete checkhead;
-
-  AdPlug_LogWrite("Cd00Player::load(f,\"%s\"): %s format D00 file detected!\n",
-		  filename.c_str(), ver1 ? "Old" : "New");
-
-  // load section
-  filesize = fp.filesize(f); f->seek(0);
-  filedata = new char [filesize + 1];			// 1 byte is needed for old-style DataInfo block
-  f->readString((char *)filedata, filesize);
-  fp.close(f);
-  if(!ver1) {	// version 2 and above
-    header = (struct d00header *)filedata;
-    version = header->version;
-    datainfo = (char *)filedata + LE_WORD(&header->infoptr);
-    inst = (struct Sinsts *)((char *)filedata + LE_WORD(&header->instptr));
-    seqptr = (unsigned short *)((char *)filedata + LE_WORD(&header->seqptr));
-    for(i=31;i>=0;i--)	// erase whitespace
-      if(header->songname[i] == ' ')
-	header->songname[i] = '\0';
-      else
-	break;
-    for(i=31;i>=0;i--)
-      if(header->author[i] == ' ')
-	header->author[i] = '\0';
-      else
-	break;
-  } else {	// version 1
-    header1 = (struct d00header1 *)filedata;
-    version = header1->version;
-    datainfo = (char *)filedata + LE_WORD(&header1->infoptr);
-    inst = (struct Sinsts *)((char *)filedata + LE_WORD(&header1->instptr));
-    seqptr = (unsigned short *)((char *)filedata + LE_WORD(&header1->seqptr));
-  }
-  switch(version) {
-  case 0:
-    levpuls = 0;
-    spfx = 0;
-    header1->speed = 70;		// v0 files default to 70Hz
-    break;
-  case 1:
-    levpuls = (struct Slevpuls *)((char *)filedata + LE_WORD(&header1->lpulptr));
-    spfx = 0;
-    break;
-  case 2:
-    levpuls = (struct Slevpuls *)((char *)filedata + LE_WORD(&header->spfxptr));
-    spfx = 0;
-    break;
-  case 3:
-    spfx = 0;
-    levpuls = 0;
-    break;
-  case 4:
-    spfx = (struct Sspfx *)((char *)filedata + LE_WORD(&header->spfxptr));
-    levpuls = 0;
-    break;
-  }
-  if((str = strstr(datainfo,"\xff\xff")))
-    while((*str == '\xff' || *str == ' ') && str >= datainfo) {
-      *str = '\0'; str--;
-    }
-  else	// old-style block
-    memset((char *)filedata+filesize,0,1);
-
-  rewind(0);
-  return true;
-}
-
-bool Cd00Player::update()
-{
-  unsigned char	c,cnt,trackend=0,fx,note;
-  unsigned short ord,*patt,buf,fxop,pattpos;
-
-  // effect handling (timer dependant)
-  for(c=0;c<9;c++) {
-    channel[c].slideval += channel[c].slide; setfreq(c);	// sliding
-    vibrato(c);	// vibrato
-
-    if(channel[c].spfx != 0xffff) {	// SpFX
-      if(channel[c].fxdel)
-	channel[c].fxdel--;
-      else {
-	channel[c].spfx = LE_WORD(&spfx[channel[c].spfx].ptr);
-	channel[c].fxdel = spfx[channel[c].spfx].duration;
-	channel[c].inst = LE_WORD(&spfx[channel[c].spfx].instnr) & 0xfff;
-	if(spfx[channel[c].spfx].modlev != 0xff)
-	  channel[c].modvol = spfx[channel[c].spfx].modlev;
-	setinst(c);
-	if(LE_WORD(&spfx[channel[c].spfx].instnr) & 0x8000)	// locked frequency
-	  note = spfx[channel[c].spfx].halfnote;
-	else							// unlocked frequency
-	  note = spfx[channel[c].spfx].halfnote + channel[c].note;
-	channel[c].freq = notetable[note%12] + ((note/12) << 10);
-	setfreq(c);
-      }
-      channel[c].modvol += spfx[channel[c].spfx].modlevadd; channel[c].modvol &= 63;
-      setvolume(c);
-    }
-
-    if(channel[c].levpuls != 0xff)	// Levelpuls
-      if(channel[c].frameskip)
-	channel[c].frameskip--;
-      else {
-	channel[c].frameskip = inst[channel[c].inst].timer;
-	if(channel[c].fxdel)
-	  channel[c].fxdel--;
-	else {
-	  channel[c].levpuls = levpuls[channel[c].levpuls].ptr - 1;
-	  channel[c].fxdel = levpuls[channel[c].levpuls].duration;
-	  if(levpuls[channel[c].levpuls].level != 0xff)
-	    channel[c].modvol = levpuls[channel[c].levpuls].level;
-	}
-	channel[c].modvol += levpuls[channel[c].levpuls].voladd; channel[c].modvol &= 63;
-	setvolume(c);
-      }
-  }
-
-  // song handling
-  for(c=0;c<9;c++)
-    if(version < 3 ? channel[c].del : channel[c].del <= 0x7f) {
-      if(version == 4)	// v4: hard restart SR
-	if(channel[c].del == inst[channel[c].inst].timer)
-	  if(channel[c].nextnote)
-	    opl->write(0x83 + op_table[c], inst[channel[c].inst].sr);
-      if(version < 3)
-	channel[c].del--;
-      else
-	if(channel[c].speed)
-	  channel[c].del += channel[c].speed;
-	else {
-	  channel[c].seqend = 1;
-	  continue;
-	}
-    } else {
-      if(channel[c].speed) {
-	if(version < 3)
-	  channel[c].del = channel[c].speed;
-	else {
-	  channel[c].del &= 0x7f;
-	  channel[c].del += channel[c].speed;
-	}
-      } else {
-	channel[c].seqend = 1;
-	continue;
-      }
-      if(channel[c].rhcnt) {	// process pending REST/HOLD events
-	channel[c].rhcnt--;
-	continue;
-      }
-    readorder:	// process arrangement (orderlist)
-      ord = LE_WORD(&channel[c].order[channel[c].ordpos]);
-      switch(ord) {
-      case 0xfffe: channel[c].seqend = 1; continue;	// end of arrangement stream
-      case 0xffff:		// jump to order
-	channel[c].ordpos = LE_WORD(&channel[c].order[channel[c].ordpos + 1]);
-	channel[c].seqend = 1;
-	goto readorder;
-      default:
-	if(ord >= 0x9000) {	// set speed
-	  channel[c].speed = ord & 0xff;
-	  ord = LE_WORD(&channel[c].order[channel[c].ordpos - 1]);
-	  channel[c].ordpos++;
-	} else
-	  if(ord >= 0x8000) {	// transpose track
-	    channel[c].transpose = ord & 0xff;
-	    if(ord & 0x100)
-	      channel[c].transpose = -channel[c].transpose;
-	    ord = LE_WORD(&channel[c].order[++channel[c].ordpos]);
-	  }
-	patt = (unsigned short *)((char *)filedata + LE_WORD(&seqptr[ord]));
-	break;
-      }
-    readseq:	// process sequence (pattern)
-      if(!version)	// v0: always initialize rhcnt
-	channel[c].rhcnt = channel[c].irhcnt;
-      pattpos = LE_WORD(&patt[channel[c].pattpos]);
-      if(pattpos == 0xffff) {	// pattern ended?
-	channel[c].pattpos = 0;
-	channel[c].ordpos++;
-	goto readorder;
-      }
-      cnt = HIBYTE(pattpos);
-      note = LOBYTE(pattpos);
-      fx = pattpos >> 12;
-      fxop = pattpos & 0x0fff;
-      channel[c].pattpos++; pattpos = LE_WORD(&patt[channel[c].pattpos]);
-      channel[c].nextnote = LOBYTE(pattpos) & 0x7f;
-      if(version ? cnt < 0x40 : !fx) {	// note event
-	switch(note) {
-	case 0:						// REST event
-	case 0x80:
-	  if(!note || version) {
-	    channel[c].key = 0;
-	    setfreq(c);
-	  }
-	  // fall through...
-	case 0x7e:					// HOLD event
-	  if(version)
-	    channel[c].rhcnt = cnt;
-	  channel[c].nextnote = 0;
-	  break;
-	default:					// play note
-	  // restart fx
-	  channel[c].slideval = 0; channel[c].slide = 0; channel[c].vibdepth = 0;
-
-	  if(version) {	// note handling for v1 and above
-	    if(note > 0x80)	// locked note (no channel transpose)
-	      note -= 0x80;
-	    else			// unlocked note
-	      note += channel[c].transpose;
-	    channel[c].note = note;	// remember note for SpFX
-
-	    if(channel[c].ispfx != 0xffff && cnt < 0x20) {	// reset SpFX
-	      channel[c].spfx = channel[c].ispfx;
-	      if(LE_WORD(&spfx[channel[c].spfx].instnr) & 0x8000)	// locked frequency
-		note = spfx[channel[c].spfx].halfnote;
-	      else												// unlocked frequency
-		note += spfx[channel[c].spfx].halfnote;
-	      channel[c].inst = LE_WORD(&spfx[channel[c].spfx].instnr) & 0xfff;
-	      channel[c].fxdel = spfx[channel[c].spfx].duration;
-	      if(spfx[channel[c].spfx].modlev != 0xff)
-		channel[c].modvol = spfx[channel[c].spfx].modlev;
-	      else
-		channel[c].modvol = inst[channel[c].inst].data[7] & 63;
-	    }
-
-	    if(channel[c].ilevpuls != 0xff && cnt < 0x20) {	// reset LevelPuls
-	      channel[c].levpuls = channel[c].ilevpuls;
-	      channel[c].fxdel = levpuls[channel[c].levpuls].duration;
-	      channel[c].frameskip = inst[channel[c].inst].timer;
-	      if(levpuls[channel[c].levpuls].level != 0xff)
-		channel[c].modvol = levpuls[channel[c].levpuls].level;
-	      else
-		channel[c].modvol = inst[channel[c].inst].data[7] & 63;
-	    }
-
-	    channel[c].freq = notetable[note%12] + ((note/12) << 10);
-	    if(cnt < 0x20)	// normal note
-	      playnote(c);
-	    else {			// tienote
-	      setfreq(c);
-	      cnt -= 0x20;	// make count proper
-	    }
-	    channel[c].rhcnt = cnt;
-	  } else {	// note handling for v0
-	    if(cnt < 2)	// unlocked note
-	      note += channel[c].transpose;
-	    channel[c].note = note;
-
-	    channel[c].freq = notetable[note%12] + ((note/12) << 10);
-	    if(cnt == 1)	// tienote
-	      setfreq(c);
-	    else			// normal note
-	      playnote(c);
-	  }
-	  break;
-	}
-	continue;	// event is complete
-      } else {		// effect event
-	switch(fx) {
-	case 6:		// Cut/Stop Voice
-	  buf = channel[c].inst;
-	  channel[c].inst = 0;
-	  playnote(c);
-	  channel[c].inst = buf;
-	  channel[c].rhcnt = fxop;
-	  continue;	// no note follows this event
-	case 7:		// Vibrato
-	  channel[c].vibspeed = fxop & 0xff;
-	  channel[c].vibdepth = fxop >> 8;
-	  channel[c].trigger = fxop >> 9;
-	  break;
-	case 8:		// v0: Duration
-	  if(!version)
-	    channel[c].irhcnt = fxop;
-	  break;
-	case 9:		// New Level
-	  channel[c].vol = fxop & 63;
-	  if(channel[c].vol + channel[c].cvol < 63)	// apply channel volume
-	    channel[c].vol += channel[c].cvol;
-	  else
-	    channel[c].vol = 63;
-	  setvolume(c);
-	  break;
-	case 0xb:	// v4: Set SpFX
-	  if(version == 4)
-	    channel[c].ispfx = fxop;
-	  break;
-	case 0xc:	// Set Instrument
-	  channel[c].ispfx = 0xffff;
-	  channel[c].spfx = 0xffff;
-	  channel[c].inst = fxop;
-	  channel[c].modvol = inst[fxop].data[7] & 63;
-	  if(version < 3 && version && inst[fxop].tunelev)	// Set LevelPuls
-	    channel[c].ilevpuls = inst[fxop].tunelev - 1;
-	  else {
-	    channel[c].ilevpuls = 0xff;
-	    channel[c].levpuls = 0xff;
-	  }
-	  break;
-	case 0xd:	// Slide up
-	  channel[c].slide = fxop;
-	  break;
-	case 0xe:	// Slide down
-	  channel[c].slide = -fxop;
-	  break;
-	}
-	goto readseq;	// event is incomplete, note follows
-      }
-    }
-
-  for(c=0;c<9;c++)
-    if(channel[c].seqend)
-      trackend++;
-  if(trackend == 9)
-    songend = 1;
-
-  return !songend;
-}
-
-void Cd00Player::rewind(int subsong)
-{
-  struct Stpoin {
-    unsigned short ptr[9];
-    unsigned char volume[9],dummy[5];
-  } *tpoin;
-  int i;
-
-  if(version > 1) {	// do nothing if subsong > number of subsongs
-    if(subsong >= header->subsongs)
-      return;
-  } else
-    if(subsong >= header1->subsongs)
-      return;
-
-  memset(channel,0,sizeof(channel));
-  if(version > 1)
-    tpoin = (struct Stpoin *)((char *)filedata + LE_WORD(&header->tpoin));
-  else
-    tpoin = (struct Stpoin *)((char *)filedata + LE_WORD(&header1->tpoin));
-  for(i=0;i<9;i++) {
-    if(LE_WORD(&tpoin[subsong].ptr[i])) {	// track enabled
-      channel[i].speed = LE_WORD((unsigned short *)
-				 ((char *)filedata + LE_WORD(&tpoin[subsong].ptr[i])));
-      channel[i].order = (unsigned short *)
-	((char *)filedata + LE_WORD(&tpoin[subsong].ptr[i]) + 2);
-    } else {					// track disabled
-      channel[i].speed = 0;
-      channel[i].order = 0;
-    }
-    channel[i].ispfx = 0xffff; channel[i].spfx = 0xffff;	// no SpFX
-    channel[i].ilevpuls = 0xff; channel[i].levpuls = 0xff;	// no LevelPuls
-    channel[i].cvol = tpoin[subsong].volume[i] & 0x7f;	// our player may savely ignore bit 7
-    channel[i].vol = channel[i].cvol;			// initialize volume
-  }
-  songend = 0;
-  opl->init(); opl->write(1,32);	// reset OPL chip
-}
-
-std::string Cd00Player::gettype()
-{
-  char	tmpstr[40];
-
-  sprintf(tmpstr,"EdLib packed (version %d)",version > 1 ? header->version : header1->version);
-  return std::string(tmpstr);
-}
-
-float Cd00Player::getrefresh()
-{
-  if(version > 1)
-    return header->speed;
-  else
-    return header1->speed;
-}
-
-unsigned int Cd00Player::getsubsongs()
-{
-  if(version <= 1)	// return number of subsongs
-    return header1->subsongs;
-  else
-    return header->subsongs;
-}
-
-/*** private methods *************************************/
-
-void Cd00Player::setvolume(unsigned char chan)
-{
-  unsigned char	op = op_table[chan];
-  unsigned short	insnr = channel[chan].inst;
-
-  opl->write(0x43 + op,(int)(63-((63-(inst[insnr].data[2] & 63))/63.0)*(63-channel[chan].vol)) +
-	     (inst[insnr].data[2] & 192));
-  if(inst[insnr].data[10] & 1)
-    opl->write(0x40 + op,(int)(63-((63-channel[chan].modvol)/63.0)*(63-channel[chan].vol)) +
-	       (inst[insnr].data[7] & 192));
-  else
-    opl->write(0x40 + op,channel[chan].modvol + (inst[insnr].data[7] & 192));
-}
-
-void Cd00Player::setfreq(unsigned char chan)
-{
-  unsigned short freq = channel[chan].freq;
-
-  if(version == 4)	// v4: apply instrument finetune
-    freq += inst[channel[chan].inst].tunelev;
-
-  freq += channel[chan].slideval;
-  opl->write(0xa0 + chan, freq & 255);
-  if(channel[chan].key)
-    opl->write(0xb0 + chan, ((freq >> 8) & 31) | 32);
-  else
-    opl->write(0xb0 + chan, (freq >> 8) & 31);
-}
-
-void Cd00Player::setinst(unsigned char chan)
-{
-  unsigned char	op = op_table[chan];
-  unsigned short	insnr = channel[chan].inst;
-
-  // set instrument data
-  opl->write(0x63 + op, inst[insnr].data[0]);
-  opl->write(0x83 + op, inst[insnr].data[1]);
-  opl->write(0x23 + op, inst[insnr].data[3]);
-  opl->write(0xe3 + op, inst[insnr].data[4]);
-  opl->write(0x60 + op, inst[insnr].data[5]);
-  opl->write(0x80 + op, inst[insnr].data[6]);
-  opl->write(0x20 + op, inst[insnr].data[8]);
-  opl->write(0xe0 + op, inst[insnr].data[9]);
-  if(version)
-    opl->write(0xc0 + chan, inst[insnr].data[10]);
-  else
-    opl->write(0xc0 + chan, (inst[insnr].data[10] << 1) + (inst[insnr].tunelev & 1));
-}
-
-void Cd00Player::playnote(unsigned char chan)
-{
-  // set misc vars & play
-  opl->write(0xb0 + chan, 0);	// stop old note
-  setinst(chan);
-  channel[chan].key = 1;
-  setfreq(chan);
-  setvolume(chan);
-}
-
-void Cd00Player::vibrato(unsigned char chan)
-{
-  if(!channel[chan].vibdepth)
-    return;
-
-  if(channel[chan].trigger)
-    channel[chan].trigger--;
-  else {
-    channel[chan].trigger = channel[chan].vibdepth;
-    channel[chan].vibspeed = -channel[chan].vibspeed;
-  }
-  channel[chan].freq += channel[chan].vibspeed;
-  setfreq(chan);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/d00.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,538 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * d00.c - D00 Player by Simon Peter <dn.tlp@gmx.net>
+ *
+ * NOTES:
+ * Sorry for the goto's, but the code looks so much nicer now.
+ * I tried it with while loops but it was just a mess. If you
+ * can come up with a nicer solution, just tell me.
+ *
+ * BUGS:
+ * Hard restart SR is sometimes wrong
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <inttypes.h>
+
+#include "debug.h"
+#include "d00.h"
+
+#define HIBYTE(val)	(val >> 8)
+#define LOBYTE(val)	(val & 0xff)
+
+static const unsigned short notetable[12] =	// D00 note table
+  {340,363,385,408,432,458,485,514,544,577,611,647};
+
+static inline uint16_t LE_WORD(const uint16_t *val)
+{
+  const uint8_t *b = (const uint8_t *)val;
+  return (b[1] << 8) + b[0];
+}
+
+/*** public methods *************************************/
+
+CPlayer *Cd00Player::factory(Copl *newopl)
+{
+  return new Cd00Player(newopl);
+}
+
+bool Cd00Player::load(const std::string &filename, const CFileProvider &fp)
+{
+  binistream	*f = fp.open(filename); if(!f) return false;
+  d00header	*checkhead;
+  d00header1	*ch;
+  unsigned long	filesize;
+  int		i,ver1=0;
+  char		*str;
+
+  // file validation section
+  checkhead = new d00header;
+  f->readString((char *)checkhead, sizeof(d00header));
+
+  // Check for version 2-4 header
+  if(strncmp(checkhead->id,"JCH\x26\x02\x66",6) || checkhead->type ||
+     !checkhead->subsongs || checkhead->soundcard) {
+    // Check for version 0 or 1 header (and .d00 file extension)
+    delete checkhead;
+    if(!fp.extension(filename, ".d00")) { fp.close(f); return false; }
+    ch = new d00header1;
+    f->seek(0); f->readString((char *)ch, sizeof(d00header1));
+    if(ch->version > 1 || !ch->subsongs)
+      { delete ch; fp.close(f); return false; }
+    delete ch;
+    ver1 = 1;
+  } else
+    delete checkhead;
+
+  AdPlug_LogWrite("Cd00Player::load(f,\"%s\"): %s format D00 file detected!\n",
+		  filename.c_str(), ver1 ? "Old" : "New");
+
+  // load section
+  filesize = fp.filesize(f); f->seek(0);
+  filedata = new char [filesize + 1];			// 1 byte is needed for old-style DataInfo block
+  f->readString((char *)filedata, filesize);
+  fp.close(f);
+  if(!ver1) {	// version 2 and above
+    header = (struct d00header *)filedata;
+    version = header->version;
+    datainfo = (char *)filedata + LE_WORD(&header->infoptr);
+    inst = (struct Sinsts *)((char *)filedata + LE_WORD(&header->instptr));
+    seqptr = (unsigned short *)((char *)filedata + LE_WORD(&header->seqptr));
+    for(i=31;i>=0;i--)	// erase whitespace
+      if(header->songname[i] == ' ')
+	header->songname[i] = '\0';
+      else
+	break;
+    for(i=31;i>=0;i--)
+      if(header->author[i] == ' ')
+	header->author[i] = '\0';
+      else
+	break;
+  } else {	// version 1
+    header1 = (struct d00header1 *)filedata;
+    version = header1->version;
+    datainfo = (char *)filedata + LE_WORD(&header1->infoptr);
+    inst = (struct Sinsts *)((char *)filedata + LE_WORD(&header1->instptr));
+    seqptr = (unsigned short *)((char *)filedata + LE_WORD(&header1->seqptr));
+  }
+  switch(version) {
+  case 0:
+    levpuls = 0;
+    spfx = 0;
+    header1->speed = 70;		// v0 files default to 70Hz
+    break;
+  case 1:
+    levpuls = (struct Slevpuls *)((char *)filedata + LE_WORD(&header1->lpulptr));
+    spfx = 0;
+    break;
+  case 2:
+    levpuls = (struct Slevpuls *)((char *)filedata + LE_WORD(&header->spfxptr));
+    spfx = 0;
+    break;
+  case 3:
+    spfx = 0;
+    levpuls = 0;
+    break;
+  case 4:
+    spfx = (struct Sspfx *)((char *)filedata + LE_WORD(&header->spfxptr));
+    levpuls = 0;
+    break;
+  }
+  if((str = strstr(datainfo,"\xff\xff")))
+    while((*str == '\xff' || *str == ' ') && str >= datainfo) {
+      *str = '\0'; str--;
+    }
+  else	// old-style block
+    memset((char *)filedata+filesize,0,1);
+
+  rewind(0);
+  return true;
+}
+
+bool Cd00Player::update()
+{
+  unsigned char	c,cnt,trackend=0,fx,note;
+  unsigned short ord,*patt,buf,fxop,pattpos;
+
+  // effect handling (timer dependant)
+  for(c=0;c<9;c++) {
+    channel[c].slideval += channel[c].slide; setfreq(c);	// sliding
+    vibrato(c);	// vibrato
+
+    if(channel[c].spfx != 0xffff) {	// SpFX
+      if(channel[c].fxdel)
+	channel[c].fxdel--;
+      else {
+	channel[c].spfx = LE_WORD(&spfx[channel[c].spfx].ptr);
+	channel[c].fxdel = spfx[channel[c].spfx].duration;
+	channel[c].inst = LE_WORD(&spfx[channel[c].spfx].instnr) & 0xfff;
+	if(spfx[channel[c].spfx].modlev != 0xff)
+	  channel[c].modvol = spfx[channel[c].spfx].modlev;
+	setinst(c);
+	if(LE_WORD(&spfx[channel[c].spfx].instnr) & 0x8000)	// locked frequency
+	  note = spfx[channel[c].spfx].halfnote;
+	else							// unlocked frequency
+	  note = spfx[channel[c].spfx].halfnote + channel[c].note;
+	channel[c].freq = notetable[note%12] + ((note/12) << 10);
+	setfreq(c);
+      }
+      channel[c].modvol += spfx[channel[c].spfx].modlevadd; channel[c].modvol &= 63;
+      setvolume(c);
+    }
+
+    if(channel[c].levpuls != 0xff)	// Levelpuls
+      if(channel[c].frameskip)
+	channel[c].frameskip--;
+      else {
+	channel[c].frameskip = inst[channel[c].inst].timer;
+	if(channel[c].fxdel)
+	  channel[c].fxdel--;
+	else {
+	  channel[c].levpuls = levpuls[channel[c].levpuls].ptr - 1;
+	  channel[c].fxdel = levpuls[channel[c].levpuls].duration;
+	  if(levpuls[channel[c].levpuls].level != 0xff)
+	    channel[c].modvol = levpuls[channel[c].levpuls].level;
+	}
+	channel[c].modvol += levpuls[channel[c].levpuls].voladd; channel[c].modvol &= 63;
+	setvolume(c);
+      }
+  }
+
+  // song handling
+  for(c=0;c<9;c++)
+    if(version < 3 ? channel[c].del : channel[c].del <= 0x7f) {
+      if(version == 4)	// v4: hard restart SR
+	if(channel[c].del == inst[channel[c].inst].timer)
+	  if(channel[c].nextnote)
+	    opl->write(0x83 + op_table[c], inst[channel[c].inst].sr);
+      if(version < 3)
+	channel[c].del--;
+      else
+	if(channel[c].speed)
+	  channel[c].del += channel[c].speed;
+	else {
+	  channel[c].seqend = 1;
+	  continue;
+	}
+    } else {
+      if(channel[c].speed) {
+	if(version < 3)
+	  channel[c].del = channel[c].speed;
+	else {
+	  channel[c].del &= 0x7f;
+	  channel[c].del += channel[c].speed;
+	}
+      } else {
+	channel[c].seqend = 1;
+	continue;
+      }
+      if(channel[c].rhcnt) {	// process pending REST/HOLD events
+	channel[c].rhcnt--;
+	continue;
+      }
+    readorder:	// process arrangement (orderlist)
+      ord = LE_WORD(&channel[c].order[channel[c].ordpos]);
+      switch(ord) {
+      case 0xfffe: channel[c].seqend = 1; continue;	// end of arrangement stream
+      case 0xffff:		// jump to order
+	channel[c].ordpos = LE_WORD(&channel[c].order[channel[c].ordpos + 1]);
+	channel[c].seqend = 1;
+	goto readorder;
+      default:
+	if(ord >= 0x9000) {	// set speed
+	  channel[c].speed = ord & 0xff;
+	  ord = LE_WORD(&channel[c].order[channel[c].ordpos - 1]);
+	  channel[c].ordpos++;
+	} else
+	  if(ord >= 0x8000) {	// transpose track
+	    channel[c].transpose = ord & 0xff;
+	    if(ord & 0x100)
+	      channel[c].transpose = -channel[c].transpose;
+	    ord = LE_WORD(&channel[c].order[++channel[c].ordpos]);
+	  }
+	patt = (unsigned short *)((char *)filedata + LE_WORD(&seqptr[ord]));
+	break;
+      }
+    readseq:	// process sequence (pattern)
+      if(!version)	// v0: always initialize rhcnt
+	channel[c].rhcnt = channel[c].irhcnt;
+      pattpos = LE_WORD(&patt[channel[c].pattpos]);
+      if(pattpos == 0xffff) {	// pattern ended?
+	channel[c].pattpos = 0;
+	channel[c].ordpos++;
+	goto readorder;
+      }
+      cnt = HIBYTE(pattpos);
+      note = LOBYTE(pattpos);
+      fx = pattpos >> 12;
+      fxop = pattpos & 0x0fff;
+      channel[c].pattpos++; pattpos = LE_WORD(&patt[channel[c].pattpos]);
+      channel[c].nextnote = LOBYTE(pattpos) & 0x7f;
+      if(version ? cnt < 0x40 : !fx) {	// note event
+	switch(note) {
+	case 0:						// REST event
+	case 0x80:
+	  if(!note || version) {
+	    channel[c].key = 0;
+	    setfreq(c);
+	  }
+	  // fall through...
+	case 0x7e:					// HOLD event
+	  if(version)
+	    channel[c].rhcnt = cnt;
+	  channel[c].nextnote = 0;
+	  break;
+	default:					// play note
+	  // restart fx
+	  channel[c].slideval = 0; channel[c].slide = 0; channel[c].vibdepth = 0;
+
+	  if(version) {	// note handling for v1 and above
+	    if(note > 0x80)	// locked note (no channel transpose)
+	      note -= 0x80;
+	    else			// unlocked note
+	      note += channel[c].transpose;
+	    channel[c].note = note;	// remember note for SpFX
+
+	    if(channel[c].ispfx != 0xffff && cnt < 0x20) {	// reset SpFX
+	      channel[c].spfx = channel[c].ispfx;
+	      if(LE_WORD(&spfx[channel[c].spfx].instnr) & 0x8000)	// locked frequency
+		note = spfx[channel[c].spfx].halfnote;
+	      else												// unlocked frequency
+		note += spfx[channel[c].spfx].halfnote;
+	      channel[c].inst = LE_WORD(&spfx[channel[c].spfx].instnr) & 0xfff;
+	      channel[c].fxdel = spfx[channel[c].spfx].duration;
+	      if(spfx[channel[c].spfx].modlev != 0xff)
+		channel[c].modvol = spfx[channel[c].spfx].modlev;
+	      else
+		channel[c].modvol = inst[channel[c].inst].data[7] & 63;
+	    }
+
+	    if(channel[c].ilevpuls != 0xff && cnt < 0x20) {	// reset LevelPuls
+	      channel[c].levpuls = channel[c].ilevpuls;
+	      channel[c].fxdel = levpuls[channel[c].levpuls].duration;
+	      channel[c].frameskip = inst[channel[c].inst].timer;
+	      if(levpuls[channel[c].levpuls].level != 0xff)
+		channel[c].modvol = levpuls[channel[c].levpuls].level;
+	      else
+		channel[c].modvol = inst[channel[c].inst].data[7] & 63;
+	    }
+
+	    channel[c].freq = notetable[note%12] + ((note/12) << 10);
+	    if(cnt < 0x20)	// normal note
+	      playnote(c);
+	    else {			// tienote
+	      setfreq(c);
+	      cnt -= 0x20;	// make count proper
+	    }
+	    channel[c].rhcnt = cnt;
+	  } else {	// note handling for v0
+	    if(cnt < 2)	// unlocked note
+	      note += channel[c].transpose;
+	    channel[c].note = note;
+
+	    channel[c].freq = notetable[note%12] + ((note/12) << 10);
+	    if(cnt == 1)	// tienote
+	      setfreq(c);
+	    else			// normal note
+	      playnote(c);
+	  }
+	  break;
+	}
+	continue;	// event is complete
+      } else {		// effect event
+	switch(fx) {
+	case 6:		// Cut/Stop Voice
+	  buf = channel[c].inst;
+	  channel[c].inst = 0;
+	  playnote(c);
+	  channel[c].inst = buf;
+	  channel[c].rhcnt = fxop;
+	  continue;	// no note follows this event
+	case 7:		// Vibrato
+	  channel[c].vibspeed = fxop & 0xff;
+	  channel[c].vibdepth = fxop >> 8;
+	  channel[c].trigger = fxop >> 9;
+	  break;
+	case 8:		// v0: Duration
+	  if(!version)
+	    channel[c].irhcnt = fxop;
+	  break;
+	case 9:		// New Level
+	  channel[c].vol = fxop & 63;
+	  if(channel[c].vol + channel[c].cvol < 63)	// apply channel volume
+	    channel[c].vol += channel[c].cvol;
+	  else
+	    channel[c].vol = 63;
+	  setvolume(c);
+	  break;
+	case 0xb:	// v4: Set SpFX
+	  if(version == 4)
+	    channel[c].ispfx = fxop;
+	  break;
+	case 0xc:	// Set Instrument
+	  channel[c].ispfx = 0xffff;
+	  channel[c].spfx = 0xffff;
+	  channel[c].inst = fxop;
+	  channel[c].modvol = inst[fxop].data[7] & 63;
+	  if(version < 3 && version && inst[fxop].tunelev)	// Set LevelPuls
+	    channel[c].ilevpuls = inst[fxop].tunelev - 1;
+	  else {
+	    channel[c].ilevpuls = 0xff;
+	    channel[c].levpuls = 0xff;
+	  }
+	  break;
+	case 0xd:	// Slide up
+	  channel[c].slide = fxop;
+	  break;
+	case 0xe:	// Slide down
+	  channel[c].slide = -fxop;
+	  break;
+	}
+	goto readseq;	// event is incomplete, note follows
+      }
+    }
+
+  for(c=0;c<9;c++)
+    if(channel[c].seqend)
+      trackend++;
+  if(trackend == 9)
+    songend = 1;
+
+  return !songend;
+}
+
+void Cd00Player::rewind(int subsong)
+{
+  struct Stpoin {
+    unsigned short ptr[9];
+    unsigned char volume[9],dummy[5];
+  } *tpoin;
+  int i;
+
+  if(version > 1) {	// do nothing if subsong > number of subsongs
+    if(subsong >= header->subsongs)
+      return;
+  } else
+    if(subsong >= header1->subsongs)
+      return;
+
+  memset(channel,0,sizeof(channel));
+  if(version > 1)
+    tpoin = (struct Stpoin *)((char *)filedata + LE_WORD(&header->tpoin));
+  else
+    tpoin = (struct Stpoin *)((char *)filedata + LE_WORD(&header1->tpoin));
+  for(i=0;i<9;i++) {
+    if(LE_WORD(&tpoin[subsong].ptr[i])) {	// track enabled
+      channel[i].speed = LE_WORD((unsigned short *)
+				 ((char *)filedata + LE_WORD(&tpoin[subsong].ptr[i])));
+      channel[i].order = (unsigned short *)
+	((char *)filedata + LE_WORD(&tpoin[subsong].ptr[i]) + 2);
+    } else {					// track disabled
+      channel[i].speed = 0;
+      channel[i].order = 0;
+    }
+    channel[i].ispfx = 0xffff; channel[i].spfx = 0xffff;	// no SpFX
+    channel[i].ilevpuls = 0xff; channel[i].levpuls = 0xff;	// no LevelPuls
+    channel[i].cvol = tpoin[subsong].volume[i] & 0x7f;	// our player may savely ignore bit 7
+    channel[i].vol = channel[i].cvol;			// initialize volume
+  }
+  songend = 0;
+  opl->init(); opl->write(1,32);	// reset OPL chip
+}
+
+std::string Cd00Player::gettype()
+{
+  char	tmpstr[40];
+
+  sprintf(tmpstr,"EdLib packed (version %d)",version > 1 ? header->version : header1->version);
+  return std::string(tmpstr);
+}
+
+float Cd00Player::getrefresh()
+{
+  if(version > 1)
+    return header->speed;
+  else
+    return header1->speed;
+}
+
+unsigned int Cd00Player::getsubsongs()
+{
+  if(version <= 1)	// return number of subsongs
+    return header1->subsongs;
+  else
+    return header->subsongs;
+}
+
+/*** private methods *************************************/
+
+void Cd00Player::setvolume(unsigned char chan)
+{
+  unsigned char	op = op_table[chan];
+  unsigned short	insnr = channel[chan].inst;
+
+  opl->write(0x43 + op,(int)(63-((63-(inst[insnr].data[2] & 63))/63.0)*(63-channel[chan].vol)) +
+	     (inst[insnr].data[2] & 192));
+  if(inst[insnr].data[10] & 1)
+    opl->write(0x40 + op,(int)(63-((63-channel[chan].modvol)/63.0)*(63-channel[chan].vol)) +
+	       (inst[insnr].data[7] & 192));
+  else
+    opl->write(0x40 + op,channel[chan].modvol + (inst[insnr].data[7] & 192));
+}
+
+void Cd00Player::setfreq(unsigned char chan)
+{
+  unsigned short freq = channel[chan].freq;
+
+  if(version == 4)	// v4: apply instrument finetune
+    freq += inst[channel[chan].inst].tunelev;
+
+  freq += channel[chan].slideval;
+  opl->write(0xa0 + chan, freq & 255);
+  if(channel[chan].key)
+    opl->write(0xb0 + chan, ((freq >> 8) & 31) | 32);
+  else
+    opl->write(0xb0 + chan, (freq >> 8) & 31);
+}
+
+void Cd00Player::setinst(unsigned char chan)
+{
+  unsigned char	op = op_table[chan];
+  unsigned short	insnr = channel[chan].inst;
+
+  // set instrument data
+  opl->write(0x63 + op, inst[insnr].data[0]);
+  opl->write(0x83 + op, inst[insnr].data[1]);
+  opl->write(0x23 + op, inst[insnr].data[3]);
+  opl->write(0xe3 + op, inst[insnr].data[4]);
+  opl->write(0x60 + op, inst[insnr].data[5]);
+  opl->write(0x80 + op, inst[insnr].data[6]);
+  opl->write(0x20 + op, inst[insnr].data[8]);
+  opl->write(0xe0 + op, inst[insnr].data[9]);
+  if(version)
+    opl->write(0xc0 + chan, inst[insnr].data[10]);
+  else
+    opl->write(0xc0 + chan, (inst[insnr].data[10] << 1) + (inst[insnr].tunelev & 1));
+}
+
+void Cd00Player::playnote(unsigned char chan)
+{
+  // set misc vars & play
+  opl->write(0xb0 + chan, 0);	// stop old note
+  setinst(chan);
+  channel[chan].key = 1;
+  setfreq(chan);
+  setvolume(chan);
+}
+
+void Cd00Player::vibrato(unsigned char chan)
+{
+  if(!channel[chan].vibdepth)
+    return;
+
+  if(channel[chan].trigger)
+    channel[chan].trigger--;
+  else {
+    channel[chan].trigger = channel[chan].vibdepth;
+    channel[chan].vibspeed = -channel[chan].vibspeed;
+  }
+  channel[chan].freq += channel[chan].vibspeed;
+  setfreq(chan);
+}
--- a/Plugins/Input/adplug/core/database.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,426 +0,0 @@
-/*
- * AdPlug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (c) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * database.cpp - AdPlug database class
- * Copyright (c) 2002 Riven the Mage <riven@ok.ru>
- * Copyright (c) 2002, 2003, 2006 Simon Peter <dn.tlp@gmx.net>
- */
-
-#include <binio.h>
-#include <binfile.h>
-#include <string.h>
-
-#include "database.h"
-
-#define DB_FILEID_V10	"AdPlug Module Information Database 1.0\x10"
-
-/***** CAdPlugDatabase *****/
-
-const unsigned short CAdPlugDatabase::hash_radix = 0xfff1;	// should be prime
-
-CAdPlugDatabase::CAdPlugDatabase()
-  : linear_index(0), linear_logic_length(0), linear_length(0)
-{
-  db_linear = new DB_Bucket * [hash_radix];
-  db_hashed = new DB_Bucket * [hash_radix];
-  memset(db_linear, 0, sizeof(DB_Bucket *) * hash_radix);
-  memset(db_hashed, 0, sizeof(DB_Bucket *) * hash_radix);
-}
-
-CAdPlugDatabase::~CAdPlugDatabase()
-{
-  unsigned long i;
-
-  for(i = 0; i < linear_length; i++)
-    delete db_linear[i];
-
-  delete [] db_linear;
-  delete [] db_hashed;
-}
-
-bool CAdPlugDatabase::load(std::string db_name)
-{
-  binifstream f(db_name);
-  if(f.error()) return false;
-  return load(f);
-}
-
-bool CAdPlugDatabase::load(binistream &f)
-{
-  unsigned int idlen = strlen(DB_FILEID_V10);
-  char *id = new char [idlen];
-  unsigned long length;
-
-  // Open database as little endian with IEEE floats
-  f.setFlag(binio::BigEndian, false); f.setFlag(binio::FloatIEEE);
-
-  f.readString(id,idlen);
-  if(memcmp(id,DB_FILEID_V10,idlen)) {
-    delete [] id;
-    return false;
-  }
-  delete [] id;
-  length = f.readInt(4);
-
-  // read records
-  for(unsigned long i = 0; i < length; i++)
-    insert(CRecord::factory(f));
-
-  return true;
-}
-
-bool CAdPlugDatabase::save(std::string db_name)
-{
-  binofstream f(db_name);
-  if(f.error()) return false;
-  return save(f);
-}
-
-bool CAdPlugDatabase::save(binostream &f)
-{
-  unsigned long i;
-
-  // Save database as little endian with IEEE floats
-  f.setFlag(binio::BigEndian, false); f.setFlag(binio::FloatIEEE);
-
-  f.writeString(DB_FILEID_V10);
-  f.writeInt(linear_logic_length, 4);
-
-  // write records
-  for(i = 0; i < linear_length; i++)
-    if(!db_linear[i]->deleted)
-      db_linear[i]->record->write(f);
-
-  return true;
-}
-
-CAdPlugDatabase::CRecord *CAdPlugDatabase::search(CKey const &key)
-{
-  if(lookup(key)) return get_record(); else return 0;
-}
-
-bool CAdPlugDatabase::lookup(CKey const &key)
-{
-  unsigned long index = make_hash(key);
-  if(!db_hashed[index]) return false;
-
-  // immediate hit ?
-  DB_Bucket *bucket = db_hashed[index];
-
-  if(!bucket->deleted && bucket->record->key == key) {
-    linear_index = bucket->index;
-    return true;
-  }
-
-  // in-chain hit ?
-  bucket = db_hashed[index]->chain;
-
-  while(bucket) {
-    if(!bucket->deleted && bucket->record->key == key) {
-      linear_index = bucket->index;
-      return true;
-    }
-
-    bucket = bucket->chain;
-  }
-
-  return false;
-}
-
-bool CAdPlugDatabase::insert(CRecord *record)
-{
-  long index;
-
-  // sanity checks
-  if(!record) return false;			// null-pointer given
-  if(linear_length == hash_radix) return false;	// max. db size exceeded
-  if(lookup(record->key)) return false;		// record already in db
-
-  // make bucket
-  DB_Bucket *bucket = new DB_Bucket(linear_length, record);
-  if(!bucket) return false;
-
-  // add to linear list
-  db_linear[linear_length] = bucket;
-  linear_logic_length++; linear_length++;
-
-  // add to hashed list
-  index = make_hash(record->key);
-
-  if(!db_hashed[index])	// First entry in hashtable
-    db_hashed[index] = bucket;
-  else {		// Add entry in chained list
-    DB_Bucket *chain = db_hashed[index];
-
-    while(chain->chain) chain = chain->chain;
-    chain->chain = bucket;
-  }
-
-  return true;
-}
-
-void CAdPlugDatabase::wipe(CRecord *record)
-{
-  if(!lookup(record->key)) return;
-  wipe();
-}
-
-void CAdPlugDatabase::wipe()
-{
-  if(!linear_length) return;
-
-  DB_Bucket *bucket = db_linear[linear_index];
-
-  if(!bucket->deleted) {
-    delete bucket->record;
-    linear_logic_length--;
-    bucket->deleted = true;
-  }
-}
-
-CAdPlugDatabase::CRecord *CAdPlugDatabase::get_record()
-{
-  if(!linear_length) return 0;
-  return db_linear[linear_index]->record;
-}
-
-bool CAdPlugDatabase::go_forward()
-{
-  if(linear_index + 1 < linear_length) {
-    linear_index++;
-    return true;
-  } else
-    return false;
-}
-
-bool CAdPlugDatabase::go_backward()
-{
-  if(!linear_index) return false;
-  linear_index--;
-  return true;
-}
-
-void CAdPlugDatabase::goto_begin()
-{	
-  if(linear_length) linear_index = 0;
-}
-
-void CAdPlugDatabase::goto_end()
-{
-  if(linear_length) linear_index = linear_length - 1;
-}
-
-inline unsigned long CAdPlugDatabase::make_hash(CKey const &key)
-{
-  return (key.crc32 + key.crc16) % hash_radix;
-}
-
-/***** CAdPlugDatabase::DB_Bucket *****/
-
-CAdPlugDatabase::DB_Bucket::DB_Bucket(unsigned long nindex, CRecord *newrecord, DB_Bucket *newchain)
-  : index(nindex), deleted(false), chain(newchain), record(newrecord)
-{
-}
-
-CAdPlugDatabase::DB_Bucket::~DB_Bucket()
-{
-  if(!deleted) delete record;
-}
-
-/***** CAdPlugDatabase::CRecord *****/
-
-CAdPlugDatabase::CRecord *CAdPlugDatabase::CRecord::factory(RecordType type)
-{
-  switch(type) {
-  case Plain: return new CPlainRecord;
-  case SongInfo: return new CInfoRecord;
-  case ClockSpeed: return new CClockRecord;
-  default: return 0;
-  }
-}
-
-CAdPlugDatabase::CRecord *CAdPlugDatabase::CRecord::factory(binistream &in)
-{
-  RecordType	type;
-  unsigned long	size;
-  CRecord	*rec;
-
-  type = (RecordType)in.readInt(1); size = in.readInt(4);
-  rec = factory(type);
-
-  if(rec) {
-    rec->key.crc16 = in.readInt(2); rec->key.crc32 = in.readInt(4);
-    rec->filetype = in.readString('\0'); rec->comment = in.readString('\0');
-    rec->read_own(in);
-    return rec;
-  } else {
-    // skip this record, cause we don't know about it
-    in.seek(size, binio::Add);
-    return 0;
-  }
-}
-
-void CAdPlugDatabase::CRecord::write(binostream &out)
-{
-  out.writeInt(type, 1);
-  out.writeInt(get_size() + filetype.length() + comment.length() + 8, 4);
-  out.writeInt(key.crc16, 2); out.writeInt(key.crc32, 4);
-  out.writeString(filetype); out.writeInt('\0', 1);
-  out.writeString(comment); out.writeInt('\0', 1);
-
-  write_own(out);
-}
-
-bool CAdPlugDatabase::CRecord::user_read(std::istream &in, std::ostream &out)
-{
-  return user_read_own(in, out);
-}
-
-bool CAdPlugDatabase::CRecord::user_write(std::ostream &out)
-{
-  out << "Record type: ";
-  switch(type) {
-  case Plain: out << "Plain"; break;
-  case SongInfo: out << "SongInfo"; break;
-  case ClockSpeed: out << "ClockSpeed"; break;
-  default: out << "*** Unknown ***"; break;
-  }
-  out << std::endl;
-  out << "Key: " << std::hex << key.crc16 << ":" << key.crc32 << std::dec << std::endl;
-  out << "File type: " << filetype << std::endl;
-  out << "Comment: " << comment << std::endl;
-
-  return user_write_own(out);
-}
-
-/***** CAdPlugDatabase::CRecord::CKey *****/
-
-CAdPlugDatabase::CKey::CKey(binistream &buf)
-{
-  make(buf);
-}
-
-bool CAdPlugDatabase::CKey::operator==(const CKey &key)
-{
-  return ((crc16 == key.crc16) && (crc32 == key.crc32));
-}
-
-void CAdPlugDatabase::CKey::make(binistream &buf)
-// Key is CRC16:CRC32 pair. CRC16 and CRC32 calculation routines (c) Zhengxi
-{
-  static const unsigned short magic16 = 0xa001;
-  static const unsigned long  magic32 = 0xedb88320;
-
-  crc16 = 0; crc32 = ~0;
-
-  while(!buf.eof())
-    {
-      unsigned char byte = buf.readInt(1);
-
-      for (int j=0;j<8;j++)
-	{
-	  if ((crc16 ^ byte) & 1)
-	    crc16 = (crc16 >> 1) ^ magic16;
-	  else
-	    crc16 >>= 1;
-
-	  if ((crc32 ^ byte) & 1)
-	    crc32 = (crc32 >> 1) ^ magic32;
-	  else
-	    crc32 >>= 1;
-
-	  byte >>= 1;
-	}
-    }
-
-  crc16 &= 0xffff;
-  crc32  = ~crc32;
-}
-
-/***** CInfoRecord *****/
-
-CInfoRecord::CInfoRecord()
-{
-  type = SongInfo;
-}
-
-void CInfoRecord::read_own(binistream &in)
-{
-  title = in.readString('\0');
-  author = in.readString('\0');
-}
-
-void CInfoRecord::write_own(binostream &out)
-{
-  out.writeString(title); out.writeInt('\0', 1);
-  out.writeString(author); out.writeInt('\0', 1);
-}
-
-unsigned long CInfoRecord::get_size()
-{
-  return title.length() + author.length() + 2;
-}
-
-bool CInfoRecord::user_read_own(std::istream &in, std::ostream &out)
-{
-  out << "Title: "; in >> title;
-  out << "Author: "; in >> author;
-  return true;
-}
-
-bool CInfoRecord::user_write_own(std::ostream &out)
-{
-  out << "Title: " << title << std::endl;
-  out << "Author: " << author << std::endl;
-  return true;
-}
-
-/***** CClockRecord *****/
-
-CClockRecord::CClockRecord()
-  : clock(0.0f)
-{
-  type = ClockSpeed;
-}
-
-void CClockRecord::read_own(binistream &in)
-{
-  clock = in.readFloat(binio::Single);
-}
-
-void CClockRecord::write_own(binostream &out)
-{
-  out.writeFloat(clock, binio::Single);
-}
-
-unsigned long CClockRecord::get_size()
-{
-  return 4;
-}
-
-bool CClockRecord::user_read_own(std::istream &in, std::ostream &out)
-{
-  out << "Clockspeed: "; in >> clock;
-  return true;
-}
-
-bool CClockRecord::user_write_own(std::ostream &out)
-{
-  out << "Clock speed: " << clock << " Hz" << std::endl;
-  return true;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/database.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,426 @@
+/*
+ * AdPlug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (c) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * database.cpp - AdPlug database class
+ * Copyright (c) 2002 Riven the Mage <riven@ok.ru>
+ * Copyright (c) 2002, 2003, 2006 Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include <binio.h>
+#include <binfile.h>
+#include <string.h>
+
+#include "database.h"
+
+#define DB_FILEID_V10	"AdPlug Module Information Database 1.0\x10"
+
+/***** CAdPlugDatabase *****/
+
+const unsigned short CAdPlugDatabase::hash_radix = 0xfff1;	// should be prime
+
+CAdPlugDatabase::CAdPlugDatabase()
+  : linear_index(0), linear_logic_length(0), linear_length(0)
+{
+  db_linear = new DB_Bucket * [hash_radix];
+  db_hashed = new DB_Bucket * [hash_radix];
+  memset(db_linear, 0, sizeof(DB_Bucket *) * hash_radix);
+  memset(db_hashed, 0, sizeof(DB_Bucket *) * hash_radix);
+}
+
+CAdPlugDatabase::~CAdPlugDatabase()
+{
+  unsigned long i;
+
+  for(i = 0; i < linear_length; i++)
+    delete db_linear[i];
+
+  delete [] db_linear;
+  delete [] db_hashed;
+}
+
+bool CAdPlugDatabase::load(std::string db_name)
+{
+  binifstream f(db_name);
+  if(f.error()) return false;
+  return load(f);
+}
+
+bool CAdPlugDatabase::load(binistream &f)
+{
+  unsigned int idlen = strlen(DB_FILEID_V10);
+  char *id = new char [idlen];
+  unsigned long length;
+
+  // Open database as little endian with IEEE floats
+  f.setFlag(binio::BigEndian, false); f.setFlag(binio::FloatIEEE);
+
+  f.readString(id,idlen);
+  if(memcmp(id,DB_FILEID_V10,idlen)) {
+    delete [] id;
+    return false;
+  }
+  delete [] id;
+  length = f.readInt(4);
+
+  // read records
+  for(unsigned long i = 0; i < length; i++)
+    insert(CRecord::factory(f));
+
+  return true;
+}
+
+bool CAdPlugDatabase::save(std::string db_name)
+{
+  binofstream f(db_name);
+  if(f.error()) return false;
+  return save(f);
+}
+
+bool CAdPlugDatabase::save(binostream &f)
+{
+  unsigned long i;
+
+  // Save database as little endian with IEEE floats
+  f.setFlag(binio::BigEndian, false); f.setFlag(binio::FloatIEEE);
+
+  f.writeString(DB_FILEID_V10);
+  f.writeInt(linear_logic_length, 4);
+
+  // write records
+  for(i = 0; i < linear_length; i++)
+    if(!db_linear[i]->deleted)
+      db_linear[i]->record->write(f);
+
+  return true;
+}
+
+CAdPlugDatabase::CRecord *CAdPlugDatabase::search(CKey const &key)
+{
+  if(lookup(key)) return get_record(); else return 0;
+}
+
+bool CAdPlugDatabase::lookup(CKey const &key)
+{
+  unsigned long index = make_hash(key);
+  if(!db_hashed[index]) return false;
+
+  // immediate hit ?
+  DB_Bucket *bucket = db_hashed[index];
+
+  if(!bucket->deleted && bucket->record->key == key) {
+    linear_index = bucket->index;
+    return true;
+  }
+
+  // in-chain hit ?
+  bucket = db_hashed[index]->chain;
+
+  while(bucket) {
+    if(!bucket->deleted && bucket->record->key == key) {
+      linear_index = bucket->index;
+      return true;
+    }
+
+    bucket = bucket->chain;
+  }
+
+  return false;
+}
+
+bool CAdPlugDatabase::insert(CRecord *record)
+{
+  long index;
+
+  // sanity checks
+  if(!record) return false;			// null-pointer given
+  if(linear_length == hash_radix) return false;	// max. db size exceeded
+  if(lookup(record->key)) return false;		// record already in db
+
+  // make bucket
+  DB_Bucket *bucket = new DB_Bucket(linear_length, record);
+  if(!bucket) return false;
+
+  // add to linear list
+  db_linear[linear_length] = bucket;
+  linear_logic_length++; linear_length++;
+
+  // add to hashed list
+  index = make_hash(record->key);
+
+  if(!db_hashed[index])	// First entry in hashtable
+    db_hashed[index] = bucket;
+  else {		// Add entry in chained list
+    DB_Bucket *chain = db_hashed[index];
+
+    while(chain->chain) chain = chain->chain;
+    chain->chain = bucket;
+  }
+
+  return true;
+}
+
+void CAdPlugDatabase::wipe(CRecord *record)
+{
+  if(!lookup(record->key)) return;
+  wipe();
+}
+
+void CAdPlugDatabase::wipe()
+{
+  if(!linear_length) return;
+
+  DB_Bucket *bucket = db_linear[linear_index];
+
+  if(!bucket->deleted) {
+    delete bucket->record;
+    linear_logic_length--;
+    bucket->deleted = true;
+  }
+}
+
+CAdPlugDatabase::CRecord *CAdPlugDatabase::get_record()
+{
+  if(!linear_length) return 0;
+  return db_linear[linear_index]->record;
+}
+
+bool CAdPlugDatabase::go_forward()
+{
+  if(linear_index + 1 < linear_length) {
+    linear_index++;
+    return true;
+  } else
+    return false;
+}
+
+bool CAdPlugDatabase::go_backward()
+{
+  if(!linear_index) return false;
+  linear_index--;
+  return true;
+}
+
+void CAdPlugDatabase::goto_begin()
+{	
+  if(linear_length) linear_index = 0;
+}
+
+void CAdPlugDatabase::goto_end()
+{
+  if(linear_length) linear_index = linear_length - 1;
+}
+
+inline unsigned long CAdPlugDatabase::make_hash(CKey const &key)
+{
+  return (key.crc32 + key.crc16) % hash_radix;
+}
+
+/***** CAdPlugDatabase::DB_Bucket *****/
+
+CAdPlugDatabase::DB_Bucket::DB_Bucket(unsigned long nindex, CRecord *newrecord, DB_Bucket *newchain)
+  : index(nindex), deleted(false), chain(newchain), record(newrecord)
+{
+}
+
+CAdPlugDatabase::DB_Bucket::~DB_Bucket()
+{
+  if(!deleted) delete record;
+}
+
+/***** CAdPlugDatabase::CRecord *****/
+
+CAdPlugDatabase::CRecord *CAdPlugDatabase::CRecord::factory(RecordType type)
+{
+  switch(type) {
+  case Plain: return new CPlainRecord;
+  case SongInfo: return new CInfoRecord;
+  case ClockSpeed: return new CClockRecord;
+  default: return 0;
+  }
+}
+
+CAdPlugDatabase::CRecord *CAdPlugDatabase::CRecord::factory(binistream &in)
+{
+  RecordType	type;
+  unsigned long	size;
+  CRecord	*rec;
+
+  type = (RecordType)in.readInt(1); size = in.readInt(4);
+  rec = factory(type);
+
+  if(rec) {
+    rec->key.crc16 = in.readInt(2); rec->key.crc32 = in.readInt(4);
+    rec->filetype = in.readString('\0'); rec->comment = in.readString('\0');
+    rec->read_own(in);
+    return rec;
+  } else {
+    // skip this record, cause we don't know about it
+    in.seek(size, binio::Add);
+    return 0;
+  }
+}
+
+void CAdPlugDatabase::CRecord::write(binostream &out)
+{
+  out.writeInt(type, 1);
+  out.writeInt(get_size() + filetype.length() + comment.length() + 8, 4);
+  out.writeInt(key.crc16, 2); out.writeInt(key.crc32, 4);
+  out.writeString(filetype); out.writeInt('\0', 1);
+  out.writeString(comment); out.writeInt('\0', 1);
+
+  write_own(out);
+}
+
+bool CAdPlugDatabase::CRecord::user_read(std::istream &in, std::ostream &out)
+{
+  return user_read_own(in, out);
+}
+
+bool CAdPlugDatabase::CRecord::user_write(std::ostream &out)
+{
+  out << "Record type: ";
+  switch(type) {
+  case Plain: out << "Plain"; break;
+  case SongInfo: out << "SongInfo"; break;
+  case ClockSpeed: out << "ClockSpeed"; break;
+  default: out << "*** Unknown ***"; break;
+  }
+  out << std::endl;
+  out << "Key: " << std::hex << key.crc16 << ":" << key.crc32 << std::dec << std::endl;
+  out << "File type: " << filetype << std::endl;
+  out << "Comment: " << comment << std::endl;
+
+  return user_write_own(out);
+}
+
+/***** CAdPlugDatabase::CRecord::CKey *****/
+
+CAdPlugDatabase::CKey::CKey(binistream &buf)
+{
+  make(buf);
+}
+
+bool CAdPlugDatabase::CKey::operator==(const CKey &key)
+{
+  return ((crc16 == key.crc16) && (crc32 == key.crc32));
+}
+
+void CAdPlugDatabase::CKey::make(binistream &buf)
+// Key is CRC16:CRC32 pair. CRC16 and CRC32 calculation routines (c) Zhengxi
+{
+  static const unsigned short magic16 = 0xa001;
+  static const unsigned long  magic32 = 0xedb88320;
+
+  crc16 = 0; crc32 = ~0;
+
+  while(!buf.eof())
+    {
+      unsigned char byte = buf.readInt(1);
+
+      for (int j=0;j<8;j++)
+	{
+	  if ((crc16 ^ byte) & 1)
+	    crc16 = (crc16 >> 1) ^ magic16;
+	  else
+	    crc16 >>= 1;
+
+	  if ((crc32 ^ byte) & 1)
+	    crc32 = (crc32 >> 1) ^ magic32;
+	  else
+	    crc32 >>= 1;
+
+	  byte >>= 1;
+	}
+    }
+
+  crc16 &= 0xffff;
+  crc32  = ~crc32;
+}
+
+/***** CInfoRecord *****/
+
+CInfoRecord::CInfoRecord()
+{
+  type = SongInfo;
+}
+
+void CInfoRecord::read_own(binistream &in)
+{
+  title = in.readString('\0');
+  author = in.readString('\0');
+}
+
+void CInfoRecord::write_own(binostream &out)
+{
+  out.writeString(title); out.writeInt('\0', 1);
+  out.writeString(author); out.writeInt('\0', 1);
+}
+
+unsigned long CInfoRecord::get_size()
+{
+  return title.length() + author.length() + 2;
+}
+
+bool CInfoRecord::user_read_own(std::istream &in, std::ostream &out)
+{
+  out << "Title: "; in >> title;
+  out << "Author: "; in >> author;
+  return true;
+}
+
+bool CInfoRecord::user_write_own(std::ostream &out)
+{
+  out << "Title: " << title << std::endl;
+  out << "Author: " << author << std::endl;
+  return true;
+}
+
+/***** CClockRecord *****/
+
+CClockRecord::CClockRecord()
+  : clock(0.0f)
+{
+  type = ClockSpeed;
+}
+
+void CClockRecord::read_own(binistream &in)
+{
+  clock = in.readFloat(binio::Single);
+}
+
+void CClockRecord::write_own(binostream &out)
+{
+  out.writeFloat(clock, binio::Single);
+}
+
+unsigned long CClockRecord::get_size()
+{
+  return 4;
+}
+
+bool CClockRecord::user_read_own(std::istream &in, std::ostream &out)
+{
+  out << "Clockspeed: "; in >> clock;
+  return true;
+}
+
+bool CClockRecord::user_write_own(std::ostream &out)
+{
+  out << "Clock speed: " << clock << " Hz" << std::endl;
+  return true;
+}
--- a/Plugins/Input/adplug/core/dfm.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * dfm.cpp - Digital-FM Loader by Simon Peter <dn.tlp@gmx.net>
- */
-
-#include <stdio.h>
-#include <string.h>
-
-#include "dfm.h"
-#include "debug.h"
-
-CPlayer *CdfmLoader::factory(Copl *newopl)
-{
-  return new CdfmLoader(newopl);
-}
-
-bool CdfmLoader::load(const std::string &filename, const CFileProvider &fp)
-{
-  binistream *f = fp.open(filename); if(!f) return false;
-  unsigned char		npats,n,note,fx,c,r,param;
-  unsigned int		i;
-  const unsigned char	convfx[8] = {255,255,17,19,23,24,255,13};
-
-  // file validation
-  f->readString(header.id, 4);
-  header.hiver = f->readInt(1); header.lover = f->readInt(1);
-  if(strncmp(header.id,"DFM\x1a",4) || header.hiver > 1)
-    { fp.close(f); return false; }
-
-  // load
-  restartpos = 0; flags = Standard; bpm = 0;
-  init_trackord();
-  f->readString(songinfo, 33);
-  initspeed = f->readInt(1);
-  for(i = 0; i < 32; i++)
-    f->readString(instname[i], 12);
-  for(i = 0; i < 32; i++) {
-    inst[i].data[1] = f->readInt(1);
-    inst[i].data[2] = f->readInt(1);
-    inst[i].data[9] = f->readInt(1);
-    inst[i].data[10] = f->readInt(1);
-    inst[i].data[3] = f->readInt(1);
-    inst[i].data[4] = f->readInt(1);
-    inst[i].data[5] = f->readInt(1);
-    inst[i].data[6] = f->readInt(1);
-    inst[i].data[7] = f->readInt(1);
-    inst[i].data[8] = f->readInt(1);
-    inst[i].data[0] = f->readInt(1);
-  }
-  for(i = 0; i < 128; i++) order[i] = f->readInt(1);
-  for(i = 0; i < 128 && order[i] != 128; i++) ; length = i;
-  npats = f->readInt(1);
-  for(i = 0; i < npats; i++) {
-    n = f->readInt(1);
-    for(r = 0; r < 64; r++)
-      for(c = 0; c < 9; c++) {
-	note = f->readInt(1);
-	if((note & 15) == 15)
-	  tracks[n*9+c][r].note = 127;	// key off
-	else
-	  tracks[n*9+c][r].note = ((note & 127) >> 4) * 12 + (note & 15);
-	if(note & 128) {	// additional effect byte
-	  fx = f->readInt(1);
-	  if(fx >> 5 == 1)
-	    tracks[n*9+c][r].inst = (fx & 31) + 1;
-	  else {
-	    tracks[n*9+c][r].command = convfx[fx >> 5];
-	    if(tracks[n*9+c][r].command == 17) {	// set volume
-	      param = fx & 31;
-	      param = 63 - param * 2;
-	      tracks[n*9+c][r].param1 = param >> 4;
-	      tracks[n*9+c][r].param2 = param & 15;
-	    } else {
-	      tracks[n*9+c][r].param1 = (fx & 31) >> 4;
-	      tracks[n*9+c][r].param2 = fx & 15;
-	    }
-	  }
-	}
-
-      }
-  }
-
-  fp.close(f);
-  rewind(0);
-  return true;
-}
-
-std::string CdfmLoader::gettype()
-{
-	char tmpstr[20];
-
-	sprintf(tmpstr,"Digital-FM %d.%d",header.hiver,header.lover);
-	return std::string(tmpstr);
-}
-
-float CdfmLoader::getrefresh()
-{
-	return 125.0f;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/dfm.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,115 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * dfm.cpp - Digital-FM Loader by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "dfm.h"
+#include "debug.h"
+
+CPlayer *CdfmLoader::factory(Copl *newopl)
+{
+  return new CdfmLoader(newopl);
+}
+
+bool CdfmLoader::load(const std::string &filename, const CFileProvider &fp)
+{
+  binistream *f = fp.open(filename); if(!f) return false;
+  unsigned char		npats,n,note,fx,c,r,param;
+  unsigned int		i;
+  const unsigned char	convfx[8] = {255,255,17,19,23,24,255,13};
+
+  // file validation
+  f->readString(header.id, 4);
+  header.hiver = f->readInt(1); header.lover = f->readInt(1);
+  if(strncmp(header.id,"DFM\x1a",4) || header.hiver > 1)
+    { fp.close(f); return false; }
+
+  // load
+  restartpos = 0; flags = Standard; bpm = 0;
+  init_trackord();
+  f->readString(songinfo, 33);
+  initspeed = f->readInt(1);
+  for(i = 0; i < 32; i++)
+    f->readString(instname[i], 12);
+  for(i = 0; i < 32; i++) {
+    inst[i].data[1] = f->readInt(1);
+    inst[i].data[2] = f->readInt(1);
+    inst[i].data[9] = f->readInt(1);
+    inst[i].data[10] = f->readInt(1);
+    inst[i].data[3] = f->readInt(1);
+    inst[i].data[4] = f->readInt(1);
+    inst[i].data[5] = f->readInt(1);
+    inst[i].data[6] = f->readInt(1);
+    inst[i].data[7] = f->readInt(1);
+    inst[i].data[8] = f->readInt(1);
+    inst[i].data[0] = f->readInt(1);
+  }
+  for(i = 0; i < 128; i++) order[i] = f->readInt(1);
+  for(i = 0; i < 128 && order[i] != 128; i++) ; length = i;
+  npats = f->readInt(1);
+  for(i = 0; i < npats; i++) {
+    n = f->readInt(1);
+    for(r = 0; r < 64; r++)
+      for(c = 0; c < 9; c++) {
+	note = f->readInt(1);
+	if((note & 15) == 15)
+	  tracks[n*9+c][r].note = 127;	// key off
+	else
+	  tracks[n*9+c][r].note = ((note & 127) >> 4) * 12 + (note & 15);
+	if(note & 128) {	// additional effect byte
+	  fx = f->readInt(1);
+	  if(fx >> 5 == 1)
+	    tracks[n*9+c][r].inst = (fx & 31) + 1;
+	  else {
+	    tracks[n*9+c][r].command = convfx[fx >> 5];
+	    if(tracks[n*9+c][r].command == 17) {	// set volume
+	      param = fx & 31;
+	      param = 63 - param * 2;
+	      tracks[n*9+c][r].param1 = param >> 4;
+	      tracks[n*9+c][r].param2 = param & 15;
+	    } else {
+	      tracks[n*9+c][r].param1 = (fx & 31) >> 4;
+	      tracks[n*9+c][r].param2 = fx & 15;
+	    }
+	  }
+	}
+
+      }
+  }
+
+  fp.close(f);
+  rewind(0);
+  return true;
+}
+
+std::string CdfmLoader::gettype()
+{
+	char tmpstr[20];
+
+	sprintf(tmpstr,"Digital-FM %d.%d",header.hiver,header.lover);
+	return std::string(tmpstr);
+}
+
+float CdfmLoader::getrefresh()
+{
+	return 125.0f;
+}
--- a/Plugins/Input/adplug/core/diskopl.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +0,0 @@
-/*
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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};
-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)
-{
-  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);
-}
-
-void CDiskopl::update(CPlayer *p)
-{
-  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);
-  }
-}
-
-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);
-}
-
-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
-}
-
-void CDiskopl::diskwrite(int reg, int val)
-{
-  fputc(val,f);
-  fputc(reg,f);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/diskopl.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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};
+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)
+{
+  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);
+}
+
+void CDiskopl::update(CPlayer *p)
+{
+  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);
+  }
+}
+
+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);
+}
+
+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
+}
+
+void CDiskopl::diskwrite(int reg, int val)
+{
+  fputc(val,f);
+  fputc(reg,f);
+}
--- a/Plugins/Input/adplug/core/dmo.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,403 +0,0 @@
-/*
-  Adplug - Replayer for many OPL2/OPL3 audio file formats.
-  Copyright (C) 1999 - 2004, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-  dmo.cpp - TwinTeam loader by Riven the Mage <riven@ok.ru>
-*/
-/*
-  NOTES:
-  Panning is ignored.
-
-  A WORD ist 16 bits, a DWORD is 32 bits and a BYTE is 8 bits in this context.
-*/
-
-#include <string.h>
-#include <binstr.h>
-
-#include "dmo.h"
-#include "debug.h"
-
-#define LOWORD(l) ((l) & 0xffff)
-#define HIWORD(l) ((l) >> 16)
-#define LOBYTE(w) ((w) & 0xff)
-#define HIBYTE(w) ((w) >> 8)
-
-#define ARRAY_AS_DWORD(a, i) \
-((a[i + 3] << 24) + (a[i + 2] << 16) + (a[i + 1] << 8) + a[i])
-#define ARRAY_AS_WORD(a, i)	((a[i + 1] << 8) + a[i])
-
-#define CHARP_AS_WORD(p)	(((*(p + 1)) << 8) + (*p))
-
-/* -------- Public Methods -------------------------------- */
-
-CPlayer *CdmoLoader::factory(Copl *newopl)
-{
-  return new CdmoLoader(newopl);
-}
-
-bool CdmoLoader::load(const std::string &filename, const CFileProvider &fp)
-{
-  int i,j;
-  binistream *f;
-
-  // check header
-  dmo_unpacker *unpacker = new dmo_unpacker;
-  unsigned char chkhdr[16];
-
-  if(!fp.extension(filename, ".dmo")) return false;
-  f = fp.open(filename); if(!f) return false;
-
-  f->readString((char *)chkhdr, 16);
-
-  if (!unpacker->decrypt(chkhdr, 16))
-    {
-      delete unpacker;
-      fp.close(f);
-      return false;
-    }
-
-  // get file size
-  long packed_length = fp.filesize(f);
-  f->seek(0);
-
-  unsigned char *packed_module = new unsigned char [packed_length];
-
-  // load file
-  f->readString((char *)packed_module, packed_length);
-  fp.close(f);
-
-  // decrypt
-  unpacker->decrypt(packed_module,packed_length);
-
-  long unpacked_length = 0x2000 * ARRAY_AS_WORD(packed_module, 12);
-  unsigned char *module = new unsigned char [unpacked_length];
-
-  // unpack
-  if (!unpacker->unpack(packed_module+12,module,unpacked_length))
-    {
-      delete unpacker;
-      delete [] packed_module;
-      delete [] module;
-      return false;
-    }
-
-  delete unpacker;
-  delete [] packed_module;
-
-  // "TwinTeam" - signed ?
-  if (memcmp(module,"TwinTeam Module File""\x0D\x0A",22))
-    {
-      delete module;
-      return false;
-    }
-
-  // load header
-  binisstream	uf(module, unpacked_length);
-  uf.setFlag(binio::BigEndian, false); uf.setFlag(binio::FloatIEEE);
-
-  memset(&header,0,sizeof(s3mheader));
-
-  uf.ignore(22);				// ignore DMO header ID string
-  uf.readString(header.name, 28);
-
-  uf.ignore(2);				// _unk_1
-  header.ordnum  = uf.readInt(2);
-  header.insnum  = uf.readInt(2);
-  header.patnum  = uf.readInt(2);
-  uf.ignore(2);				// _unk_2
-  header.is      = uf.readInt(2);
-  header.it      = uf.readInt(2);
-
-  memset(header.chanset,0xFF,32);
-
-  for (i=0;i<9;i++)
-    header.chanset[i] = 0x10 + i;
-
-  uf.ignore(32);				// ignore panning settings for all 32 channels
-
-  // load orders
-  for(i = 0; i < 256; i++) orders[i] = uf.readInt(1);
-
-  orders[header.ordnum] = 0xFF;
-
-  // load pattern lengths
-  unsigned short my_patlen[100];
-  for(i = 0; i < 100; i++) my_patlen[i] = uf.readInt(2);
-
-  // load instruments
-  for (i = 0; i < header.insnum; i++)
-    {
-      memset(&inst[i],0,sizeof(s3minst));
-
-      uf.readString(inst[i].name, 28);
-
-      inst[i].volume = uf.readInt(1);
-      inst[i].dsk    = uf.readInt(1);
-      inst[i].c2spd  = uf.readInt(4);
-      inst[i].type   = uf.readInt(1);
-      inst[i].d00    = uf.readInt(1);
-      inst[i].d01    = uf.readInt(1);
-      inst[i].d02    = uf.readInt(1);
-      inst[i].d03    = uf.readInt(1);
-      inst[i].d04    = uf.readInt(1);
-      inst[i].d05    = uf.readInt(1);
-      inst[i].d06    = uf.readInt(1);
-      inst[i].d07    = uf.readInt(1);
-      inst[i].d08    = uf.readInt(1);
-      inst[i].d09    = uf.readInt(1);
-      inst[i].d0a    = uf.readInt(1);
-      /*
-       * Originally, riven sets d0b = d0a and ignores 1 byte in the
-       * stream, but i guess this was a typo, so i read it here.
-       */
-      inst[i].d0b    = uf.readInt(1);
-    }
-
-  // load patterns
-  for (i = 0; i < header.patnum; i++) {
-    long cur_pos = uf.pos();
-
-    for (j = 0; j < 64; j++) {
-      while (1) {
-	unsigned char token = uf.readInt(1);
-
-	if (!token)
-	  break;
-
-	unsigned char chan = token & 31;
-
-	// note + instrument ?
-	if (token & 32) {
-	  unsigned char bufbyte = uf.readInt(1);
-
-	  pattern[i][j][chan].note = bufbyte & 15;
-	  pattern[i][j][chan].oct = bufbyte >> 4;
-	  pattern[i][j][chan].instrument = uf.readInt(1);
-	}
-
-	// volume ?
-	if (token & 64)
-	  pattern[i][j][chan].volume = uf.readInt(1);
-
-	// command ?
-	if (token & 128) {
-	  pattern[i][j][chan].command = uf.readInt(1);
-	  pattern[i][j][chan].info = uf.readInt(1);
-	}
-      }
-    }
-
-    uf.seek(cur_pos + my_patlen[i]);
-  }
-
-  delete [] module;
-  rewind(0);
-  return true;
-}
-
-std::string CdmoLoader::gettype()
-{
-  return std::string("TwinTeam (packed S3M)");
-}
-
-std::string CdmoLoader::getauthor()
-{
-  /*
-    All available .DMO modules written by one composer. And because all .DMO
-    stuff was lost due to hd crash (TwinTeam guys said this), there are
-    never(?) be another.
-  */
-  return std::string("Benjamin GERARDIN");
-}
-
-/* -------- Private Methods ------------------------------- */
-
-unsigned short CdmoLoader::dmo_unpacker::brand(unsigned short range)
-{
-  unsigned short ax,bx,cx,dx;
-
-  ax = LOWORD(bseed);
-  bx = HIWORD(bseed);
-  cx = ax;
-  ax = LOWORD(cx * 0x8405);
-  dx = HIWORD(cx * 0x8405);
-  cx <<= 3;
-  cx = (((HIBYTE(cx) + LOBYTE(cx)) & 0xFF) << 8) + LOBYTE(cx);
-  dx += cx;
-  dx += bx;
-  bx <<= 2;
-  dx += bx;
-  dx = (((HIBYTE(dx) + LOBYTE(bx)) & 0xFF) << 8) + LOBYTE(dx);
-  bx <<= 5;
-  dx = (((HIBYTE(dx) + LOBYTE(bx)) & 0xFF) << 8) + LOBYTE(dx);
-  ax += 1;
-  if (!ax) dx += 1;
-
-  // leave it that way or amd64 might get it wrong
-  bseed = dx;
-  bseed <<= 16;
-  bseed += ax;
-
-  return HIWORD(HIWORD(LOWORD(bseed) * range) + HIWORD(bseed) * range);
-}
-
-bool CdmoLoader::dmo_unpacker::decrypt(unsigned char *buf, long len)
-{
-  unsigned long seed = 0;
-  int i;
-
-  bseed = ARRAY_AS_DWORD(buf, 0);
-
-  for (i=0; i < ARRAY_AS_WORD(buf, 4) + 1; i++)
-    seed += brand(0xffff);
-
-  bseed = seed ^ ARRAY_AS_DWORD(buf, 6);
-
-  if (ARRAY_AS_WORD(buf, 10) != brand(0xffff))
-    return false;
-
-  for (i=0;i<(len-12);i++)
-    buf[12+i] ^= brand(0x100);
-
-  buf[len - 2] = buf[len - 1] = 0;
-
-  return true;
-}
-
-short CdmoLoader::dmo_unpacker::unpack_block(unsigned char *ibuf, long ilen, unsigned char *obuf)
-{
-  unsigned char code,par1,par2;
-  unsigned short ax,bx,cx;
-
-  unsigned char *ipos = ibuf;
-  unsigned char *opos = obuf;
-
-  // LZ77 child
-  while (ipos - ibuf < ilen)
-    {
-      code = *ipos++;
-
-      // 00xxxxxx: copy (xxxxxx + 1) bytes
-      if ((code >> 6) == 0)
-	{
-	  cx = (code & 0x3F) + 1;
-
-	  if(opos + cx >= oend)
-	    return -1;
-
-	  for (int i=0;i<cx;i++)
-	    *opos++ = *ipos++;
-
-	  continue;
-	}
-
-      // 01xxxxxx xxxyyyyy: copy (Y + 3) bytes from (X + 1)
-      if ((code >> 6) == 1)
-	{
-	  par1 = *ipos++;
-
-	  ax = ((code & 0x3F) << 3) + ((par1 & 0xE0) >> 5) + 1;
-	  cx = (par1 & 0x1F) + 3;
-
-	  if(opos + cx >= oend)
-	    return -1;
-
-	  for(int i=0;i<cx;i++)
-	    *opos++ = *(opos - ax);
-
-	  continue;
-	}
-
-      // 10xxxxxx xyyyzzzz: copy (Y + 3) bytes from (X + 1); copy Z bytes
-      if ((code >> 6) == 2)
-	{
-	  int i;
-
-	  par1 = *ipos++;
-
-	  ax = ((code & 0x3F) << 1) + (par1 >> 7) + 1;
-	  cx = ((par1 & 0x70) >> 4) + 3;
-	  bx = par1 & 0x0F;
-
-	  if(opos + bx + cx >= oend)
-	    return -1;
-
-	  for(i=0;i<cx;i++)
-	    *opos++ = *(opos - ax);
-
-	  for (i=0;i<bx;i++)
-	    *opos++ = *ipos++;
-
-	  continue;
-	}
-
-      // 11xxxxxx xxxxxxxy yyyyzzzz: copy (Y + 4) from X; copy Z bytes
-      if ((code >> 6) == 3)
-	{
-	  int i;
-
-	  par1 = *ipos++;
-	  par2 = *ipos++;
-
-	  bx = ((code & 0x3F) << 7) + (par1 >> 1);
-	  cx = ((par1 & 0x01) << 4) + (par2 >> 4) + 4;
-	  ax = par2 & 0x0F;
-
-	  if(opos + ax + cx >= oend)
-	    return -1;
-
-	  for(i=0;i<cx;i++)
-	    *opos++ = *(opos - bx);
-
-	  for (i=0;i<ax;i++)
-	    *opos++ = *ipos++;
-
-	  continue;
-	}
-    }
-
-  return opos - obuf;
-}
-
-long CdmoLoader::dmo_unpacker::unpack(unsigned char *ibuf, unsigned char *obuf,
-				      unsigned long outputsize)
-{
-  long olen = 0;
-  unsigned short block_count = CHARP_AS_WORD(ibuf);
-
-  ibuf += 2;
-  unsigned char *block_length = ibuf;
-  ibuf += 2 * block_count;
-
-  oend = obuf + outputsize;
-
-  for (int i=0;i<block_count;i++)
-    {
-      unsigned short bul = CHARP_AS_WORD(ibuf);
-
-      if(unpack_block(ibuf + 2,CHARP_AS_WORD(block_length) - 2,obuf) != bul)
-	return 0;
-
-      obuf += bul;
-      olen += bul;
-
-      ibuf += CHARP_AS_WORD(block_length);
-      block_length += 2;
-    }
-
-  return olen;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/dmo.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,403 @@
+/*
+  Adplug - Replayer for many OPL2/OPL3 audio file formats.
+  Copyright (C) 1999 - 2004, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  dmo.cpp - TwinTeam loader by Riven the Mage <riven@ok.ru>
+*/
+/*
+  NOTES:
+  Panning is ignored.
+
+  A WORD ist 16 bits, a DWORD is 32 bits and a BYTE is 8 bits in this context.
+*/
+
+#include <string.h>
+#include <binstr.h>
+
+#include "dmo.h"
+#include "debug.h"
+
+#define LOWORD(l) ((l) & 0xffff)
+#define HIWORD(l) ((l) >> 16)
+#define LOBYTE(w) ((w) & 0xff)
+#define HIBYTE(w) ((w) >> 8)
+
+#define ARRAY_AS_DWORD(a, i) \
+((a[i + 3] << 24) + (a[i + 2] << 16) + (a[i + 1] << 8) + a[i])
+#define ARRAY_AS_WORD(a, i)	((a[i + 1] << 8) + a[i])
+
+#define CHARP_AS_WORD(p)	(((*(p + 1)) << 8) + (*p))
+
+/* -------- Public Methods -------------------------------- */
+
+CPlayer *CdmoLoader::factory(Copl *newopl)
+{
+  return new CdmoLoader(newopl);
+}
+
+bool CdmoLoader::load(const std::string &filename, const CFileProvider &fp)
+{
+  int i,j;
+  binistream *f;
+
+  // check header
+  dmo_unpacker *unpacker = new dmo_unpacker;
+  unsigned char chkhdr[16];
+
+  if(!fp.extension(filename, ".dmo")) return false;
+  f = fp.open(filename); if(!f) return false;
+
+  f->readString((char *)chkhdr, 16);
+
+  if (!unpacker->decrypt(chkhdr, 16))
+    {
+      delete unpacker;
+      fp.close(f);
+      return false;
+    }
+
+  // get file size
+  long packed_length = fp.filesize(f);
+  f->seek(0);
+
+  unsigned char *packed_module = new unsigned char [packed_length];
+
+  // load file
+  f->readString((char *)packed_module, packed_length);
+  fp.close(f);
+
+  // decrypt
+  unpacker->decrypt(packed_module,packed_length);
+
+  long unpacked_length = 0x2000 * ARRAY_AS_WORD(packed_module, 12);
+  unsigned char *module = new unsigned char [unpacked_length];
+
+  // unpack
+  if (!unpacker->unpack(packed_module+12,module,unpacked_length))
+    {
+      delete unpacker;
+      delete [] packed_module;
+      delete [] module;
+      return false;
+    }
+
+  delete unpacker;
+  delete [] packed_module;
+
+  // "TwinTeam" - signed ?
+  if (memcmp(module,"TwinTeam Module File""\x0D\x0A",22))
+    {
+      delete module;
+      return false;
+    }
+
+  // load header
+  binisstream	uf(module, unpacked_length);
+  uf.setFlag(binio::BigEndian, false); uf.setFlag(binio::FloatIEEE);
+
+  memset(&header,0,sizeof(s3mheader));
+
+  uf.ignore(22);				// ignore DMO header ID string
+  uf.readString(header.name, 28);
+
+  uf.ignore(2);				// _unk_1
+  header.ordnum  = uf.readInt(2);
+  header.insnum  = uf.readInt(2);
+  header.patnum  = uf.readInt(2);
+  uf.ignore(2);				// _unk_2
+  header.is      = uf.readInt(2);
+  header.it      = uf.readInt(2);
+
+  memset(header.chanset,0xFF,32);
+
+  for (i=0;i<9;i++)
+    header.chanset[i] = 0x10 + i;
+
+  uf.ignore(32);				// ignore panning settings for all 32 channels
+
+  // load orders
+  for(i = 0; i < 256; i++) orders[i] = uf.readInt(1);
+
+  orders[header.ordnum] = 0xFF;
+
+  // load pattern lengths
+  unsigned short my_patlen[100];
+  for(i = 0; i < 100; i++) my_patlen[i] = uf.readInt(2);
+
+  // load instruments
+  for (i = 0; i < header.insnum; i++)
+    {
+      memset(&inst[i],0,sizeof(s3minst));
+
+      uf.readString(inst[i].name, 28);
+
+      inst[i].volume = uf.readInt(1);
+      inst[i].dsk    = uf.readInt(1);
+      inst[i].c2spd  = uf.readInt(4);
+      inst[i].type   = uf.readInt(1);
+      inst[i].d00    = uf.readInt(1);
+      inst[i].d01    = uf.readInt(1);
+      inst[i].d02    = uf.readInt(1);
+      inst[i].d03    = uf.readInt(1);
+      inst[i].d04    = uf.readInt(1);
+      inst[i].d05    = uf.readInt(1);
+      inst[i].d06    = uf.readInt(1);
+      inst[i].d07    = uf.readInt(1);
+      inst[i].d08    = uf.readInt(1);
+      inst[i].d09    = uf.readInt(1);
+      inst[i].d0a    = uf.readInt(1);
+      /*
+       * Originally, riven sets d0b = d0a and ignores 1 byte in the
+       * stream, but i guess this was a typo, so i read it here.
+       */
+      inst[i].d0b    = uf.readInt(1);
+    }
+
+  // load patterns
+  for (i = 0; i < header.patnum; i++) {
+    long cur_pos = uf.pos();
+
+    for (j = 0; j < 64; j++) {
+      while (1) {
+	unsigned char token = uf.readInt(1);
+
+	if (!token)
+	  break;
+
+	unsigned char chan = token & 31;
+
+	// note + instrument ?
+	if (token & 32) {
+	  unsigned char bufbyte = uf.readInt(1);
+
+	  pattern[i][j][chan].note = bufbyte & 15;
+	  pattern[i][j][chan].oct = bufbyte >> 4;
+	  pattern[i][j][chan].instrument = uf.readInt(1);
+	}
+
+	// volume ?
+	if (token & 64)
+	  pattern[i][j][chan].volume = uf.readInt(1);
+
+	// command ?
+	if (token & 128) {
+	  pattern[i][j][chan].command = uf.readInt(1);
+	  pattern[i][j][chan].info = uf.readInt(1);
+	}
+      }
+    }
+
+    uf.seek(cur_pos + my_patlen[i]);
+  }
+
+  delete [] module;
+  rewind(0);
+  return true;
+}
+
+std::string CdmoLoader::gettype()
+{
+  return std::string("TwinTeam (packed S3M)");
+}
+
+std::string CdmoLoader::getauthor()
+{
+  /*
+    All available .DMO modules written by one composer. And because all .DMO
+    stuff was lost due to hd crash (TwinTeam guys said this), there are
+    never(?) be another.
+  */
+  return std::string("Benjamin GERARDIN");
+}
+
+/* -------- Private Methods ------------------------------- */
+
+unsigned short CdmoLoader::dmo_unpacker::brand(unsigned short range)
+{
+  unsigned short ax,bx,cx,dx;
+
+  ax = LOWORD(bseed);
+  bx = HIWORD(bseed);
+  cx = ax;
+  ax = LOWORD(cx * 0x8405);
+  dx = HIWORD(cx * 0x8405);
+  cx <<= 3;
+  cx = (((HIBYTE(cx) + LOBYTE(cx)) & 0xFF) << 8) + LOBYTE(cx);
+  dx += cx;
+  dx += bx;
+  bx <<= 2;
+  dx += bx;
+  dx = (((HIBYTE(dx) + LOBYTE(bx)) & 0xFF) << 8) + LOBYTE(dx);
+  bx <<= 5;
+  dx = (((HIBYTE(dx) + LOBYTE(bx)) & 0xFF) << 8) + LOBYTE(dx);
+  ax += 1;
+  if (!ax) dx += 1;
+
+  // leave it that way or amd64 might get it wrong
+  bseed = dx;
+  bseed <<= 16;
+  bseed += ax;
+
+  return HIWORD(HIWORD(LOWORD(bseed) * range) + HIWORD(bseed) * range);
+}
+
+bool CdmoLoader::dmo_unpacker::decrypt(unsigned char *buf, long len)
+{
+  unsigned long seed = 0;
+  int i;
+
+  bseed = ARRAY_AS_DWORD(buf, 0);
+
+  for (i=0; i < ARRAY_AS_WORD(buf, 4) + 1; i++)
+    seed += brand(0xffff);
+
+  bseed = seed ^ ARRAY_AS_DWORD(buf, 6);
+
+  if (ARRAY_AS_WORD(buf, 10) != brand(0xffff))
+    return false;
+
+  for (i=0;i<(len-12);i++)
+    buf[12+i] ^= brand(0x100);
+
+  buf[len - 2] = buf[len - 1] = 0;
+
+  return true;
+}
+
+short CdmoLoader::dmo_unpacker::unpack_block(unsigned char *ibuf, long ilen, unsigned char *obuf)
+{
+  unsigned char code,par1,par2;
+  unsigned short ax,bx,cx;
+
+  unsigned char *ipos = ibuf;
+  unsigned char *opos = obuf;
+
+  // LZ77 child
+  while (ipos - ibuf < ilen)
+    {
+      code = *ipos++;
+
+      // 00xxxxxx: copy (xxxxxx + 1) bytes
+      if ((code >> 6) == 0)
+	{
+	  cx = (code & 0x3F) + 1;
+
+	  if(opos + cx >= oend)
+	    return -1;
+
+	  for (int i=0;i<cx;i++)
+	    *opos++ = *ipos++;
+
+	  continue;
+	}
+
+      // 01xxxxxx xxxyyyyy: copy (Y + 3) bytes from (X + 1)
+      if ((code >> 6) == 1)
+	{
+	  par1 = *ipos++;
+
+	  ax = ((code & 0x3F) << 3) + ((par1 & 0xE0) >> 5) + 1;
+	  cx = (par1 & 0x1F) + 3;
+
+	  if(opos + cx >= oend)
+	    return -1;
+
+	  for(int i=0;i<cx;i++)
+	    *opos++ = *(opos - ax);
+
+	  continue;
+	}
+
+      // 10xxxxxx xyyyzzzz: copy (Y + 3) bytes from (X + 1); copy Z bytes
+      if ((code >> 6) == 2)
+	{
+	  int i;
+
+	  par1 = *ipos++;
+
+	  ax = ((code & 0x3F) << 1) + (par1 >> 7) + 1;
+	  cx = ((par1 & 0x70) >> 4) + 3;
+	  bx = par1 & 0x0F;
+
+	  if(opos + bx + cx >= oend)
+	    return -1;
+
+	  for(i=0;i<cx;i++)
+	    *opos++ = *(opos - ax);
+
+	  for (i=0;i<bx;i++)
+	    *opos++ = *ipos++;
+
+	  continue;
+	}
+
+      // 11xxxxxx xxxxxxxy yyyyzzzz: copy (Y + 4) from X; copy Z bytes
+      if ((code >> 6) == 3)
+	{
+	  int i;
+
+	  par1 = *ipos++;
+	  par2 = *ipos++;
+
+	  bx = ((code & 0x3F) << 7) + (par1 >> 1);
+	  cx = ((par1 & 0x01) << 4) + (par2 >> 4) + 4;
+	  ax = par2 & 0x0F;
+
+	  if(opos + ax + cx >= oend)
+	    return -1;
+
+	  for(i=0;i<cx;i++)
+	    *opos++ = *(opos - bx);
+
+	  for (i=0;i<ax;i++)
+	    *opos++ = *ipos++;
+
+	  continue;
+	}
+    }
+
+  return opos - obuf;
+}
+
+long CdmoLoader::dmo_unpacker::unpack(unsigned char *ibuf, unsigned char *obuf,
+				      unsigned long outputsize)
+{
+  long olen = 0;
+  unsigned short block_count = CHARP_AS_WORD(ibuf);
+
+  ibuf += 2;
+  unsigned char *block_length = ibuf;
+  ibuf += 2 * block_count;
+
+  oend = obuf + outputsize;
+
+  for (int i=0;i<block_count;i++)
+    {
+      unsigned short bul = CHARP_AS_WORD(ibuf);
+
+      if(unpack_block(ibuf + 2,CHARP_AS_WORD(block_length) - 2,obuf) != bul)
+	return 0;
+
+      obuf += bul;
+      olen += bul;
+
+      ibuf += CHARP_AS_WORD(block_length);
+      block_length += 2;
+    }
+
+  return olen;
+}
--- a/Plugins/Input/adplug/core/dro.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-/*
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * dro.c - DOSBox Raw OPL Player by Sjoerd van der Berg <harekiet@zophar.net>
- *
- * 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"
-
-/*** public methods *************************************/
-
-CPlayer *CdroPlayer::factory(Copl *newopl)
-{
-  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;
-
-  // 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
-  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;
-      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(); 
-
-  //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;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/dro.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,129 @@
+/*
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * dro.c - DOSBox Raw OPL Player by Sjoerd van der Berg <harekiet@zophar.net>
+ *
+ * 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"
+
+/*** public methods *************************************/
+
+CPlayer *CdroPlayer::factory(Copl *newopl)
+{
+  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;
+
+  // 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
+  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;
+      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(); 
+
+  //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;
+}
--- a/Plugins/Input/adplug/core/dtm.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,317 +0,0 @@
-/*
-  Adplug - Replayer for many OPL2/OPL3 audio file formats.
-  Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-  dtm.cpp - DTM loader by Riven the Mage <riven@ok.ru>
-*/
-/*
-  NOTE: Panning (Ex) effect is ignored.
-*/
-
-#include "dtm.h"
-
-/* -------- Public Methods -------------------------------- */
-
-CPlayer *CdtmLoader::factory(Copl *newopl)
-{
-  return new CdtmLoader(newopl);
-}
-
-bool CdtmLoader::load(const std::string &filename, const CFileProvider &fp)
-{
-        binistream *f = fp.open(filename); if(!f) return false;
-	const unsigned char conv_inst[11] = { 2,1,10,9,4,3,6,5,0,8,7 };
-	const unsigned short conv_note[12] = { 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287, 0x2AE };
-
-	int i,j,k,t=0;
-
-	// read header
-	f->readString(header.id, 12);
-	header.version = f->readInt(1);
-	f->readString(header.title, 20); f->readString(header.author, 20);
-	header.numpat = f->readInt(1); header.numinst = f->readInt(1);
-
-	// signature exists ? good version ?
-	if(memcmp(header.id,"DeFy DTM ",9) || header.version != 0x10)
-	  { fp.close (f); return false; }
-
-	header.numinst++;
-
-	// load description
-	memset(desc,0,80*16);
-
-	char bufstr[80];
-
-	for (i=0;i<16;i++)
-	{
-		// get line length
-		unsigned char bufstr_length = f->readInt(1);
-
-      if(bufstr_length > 80) {
-	fp.close(f);
-	return false;
-      }
-
-		// read line
-		if (bufstr_length)
-		{
-			f->readString(bufstr,bufstr_length);
-
-			for (j=0;j<bufstr_length;j++)
-				if (!bufstr[j])
-					bufstr[j] = 0x20;
-
-			bufstr[bufstr_length] = 0;
-
-			strcat(desc,bufstr);
-		}
-
-		strcat(desc,"\n");
-	}
-
-	// init CmodPlayer
-	realloc_instruments(header.numinst);
-	realloc_order(100);
-	realloc_patterns(header.numpat,64,9);
-	init_notetable(conv_note);
-	init_trackord();
-
-	// load instruments
-	for (i=0;i<header.numinst;i++)
-	{
-		unsigned char name_length = f->readInt(1);
-
-		if (name_length)
-			f->readString(instruments[i].name, name_length);
-
-		instruments[i].name[name_length] = 0;
-
-		for(j = 0; j < 12; j++)
-		  instruments[i].data[j] = f->readInt(1);
-
-		for (j=0;j<11;j++)
-			inst[i].data[conv_inst[j]] = instruments[i].data[j];
-	}
-
-	// load order
-	for(i = 0; i < 100; i++) order[i] = f->readInt(1);
-
-	nop = header.numpat;
-
-	unsigned char *pattern = new unsigned char [0x480];
-
-	// load tracks
-	for (i=0;i<nop;i++)
-	{
-		unsigned short packed_length;
-
-		packed_length = f->readInt(2);
-
-		unsigned char *packed_pattern = new unsigned char [packed_length];
-
-		for(j = 0; j < packed_length; j++)
-		  packed_pattern[j] = f->readInt(1);
-
-		long unpacked_length = unpack_pattern(packed_pattern,packed_length,pattern,0x480);
-
-		delete [] packed_pattern;
-
-		if (!unpacked_length)
-		{
-			delete pattern;
-			fp.close(f);
-			return false;
-		}
-
-		// convert pattern
-		for (j=0;j<9;j++)
-		{
-			for (k=0;k<64;k++)
-			{
-				dtm_event *event = (dtm_event *)&pattern[(k*9+j)*2];
-
-				// instrument
-				if (event->byte0 == 0x80)
-				{
-					if (event->byte1 <= 0x80)
-						tracks[t][k].inst = event->byte1 + 1;
-				}
-
-				// note + effect
-				else
-				{
-					tracks[t][k].note = event->byte0;
-
-					if ((event->byte0 != 0) && (event->byte0 != 127))
-							tracks[t][k].note++;
-
-					// convert effects
-					switch (event->byte1 >> 4)
-					{
-						case 0x0: // pattern break
-							if ((event->byte1 & 15) == 1)
-								tracks[t][k].command = 13;
-							break;
-
-						case 0x1: // freq. slide up
-							tracks[t][k].command = 28;
-							tracks[t][k].param1 = event->byte1 & 15;
-							break;
-
-						case 0x2: // freq. slide down
-							tracks[t][k].command = 28;
-							tracks[t][k].param2 = event->byte1 & 15;
-							break;
-
-						case 0xA: // set carrier volume
-						case 0xC: // set instrument volume
-							tracks[t][k].command = 22;
-							tracks[t][k].param1 = (0x3F - (event->byte1 & 15)) >> 4;
-							tracks[t][k].param2 = (0x3F - (event->byte1 & 15)) & 15;
-							break;
-
-						case 0xB: // set modulator volume
-							tracks[t][k].command = 21;
-							tracks[t][k].param1 = (0x3F - (event->byte1 & 15)) >> 4;
-							tracks[t][k].param2 = (0x3F - (event->byte1 & 15)) & 15;
-							break;
-
-						case 0xE: // set panning
-							break;
-
-						case 0xF: // set speed
-							tracks[t][k].command = 13;
-							tracks[t][k].param2 = event->byte1 & 15;
-							break;
-					}
-				}
-			}
-
-			t++;
-		}
-	}
-
-	delete [] pattern;
-	fp.close(f);
-
-	// order length
-	for (i=0;i<100;i++)
-	{
-		if (order[i] >= 0x80)
-		{
-			length = i;
-
-			if (order[i] == 0xFF)
-				restartpos = 0;
-			else
-				restartpos = order[i] - 0x80;
-
-			break;
-		}
-	}
-
-	// initial speed
-	initspeed = 2;
-
-	rewind(0);
-
-	return true;
-}
-
-void CdtmLoader::rewind(int subsong)
-{
-	CmodPlayer::rewind(subsong);
-
-	// default instruments
-	for (int i=0;i<9;i++)
-	{
-		channel[i].inst = i;
-
-		channel[i].vol1 = 63 - (inst[i].data[10] & 63);
-		channel[i].vol2 = 63 - (inst[i].data[9] & 63);
-	}
-}
-
-float CdtmLoader::getrefresh()
-{
-	return 18.2f;
-}
-
-std::string CdtmLoader::gettype()
-{
-	return std::string("DeFy Adlib Tracker");
-}
-
-std::string CdtmLoader::gettitle()
-{
-	return std::string(header.title);
-}
-
-std::string CdtmLoader::getauthor()
-{
-	return std::string(header.author);
-}
-
-std::string CdtmLoader::getdesc()
-{
-	return std::string(desc);
-}
-
-std::string CdtmLoader::getinstrument(unsigned int n)
-{
-	return std::string(instruments[n].name);
-}
-
-unsigned int CdtmLoader::getinstruments()
-{
-	return header.numinst;
-}
-
-/* -------- Private Methods ------------------------------- */
-
-long CdtmLoader::unpack_pattern(unsigned char *ibuf, long ilen, unsigned char *obuf, long olen)
-{
-	unsigned char *input = ibuf;
-	unsigned char *output = obuf;
-
-	long input_length = 0;
-	long output_length = 0;
-
-	unsigned char repeat_byte, repeat_counter;
-
-	// RLE
-	while (input_length < ilen)
-	{
-		repeat_byte = input[input_length++];
-
-		if ((repeat_byte & 0xF0) == 0xD0)
-		{
-			repeat_counter = repeat_byte & 15;
-			repeat_byte = input[input_length++];
-		}
-		else
-			repeat_counter = 1;
-
-		for (int i=0;i<repeat_counter;i++)
-		{
-			if (output_length < olen)
-				output[output_length++] = repeat_byte;
-		}
-	}
-
-	return output_length;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/dtm.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,317 @@
+/*
+  Adplug - Replayer for many OPL2/OPL3 audio file formats.
+  Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  dtm.cpp - DTM loader by Riven the Mage <riven@ok.ru>
+*/
+/*
+  NOTE: Panning (Ex) effect is ignored.
+*/
+
+#include "dtm.h"
+
+/* -------- Public Methods -------------------------------- */
+
+CPlayer *CdtmLoader::factory(Copl *newopl)
+{
+  return new CdtmLoader(newopl);
+}
+
+bool CdtmLoader::load(const std::string &filename, const CFileProvider &fp)
+{
+        binistream *f = fp.open(filename); if(!f) return false;
+	const unsigned char conv_inst[11] = { 2,1,10,9,4,3,6,5,0,8,7 };
+	const unsigned short conv_note[12] = { 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287, 0x2AE };
+
+	int i,j,k,t=0;
+
+	// read header
+	f->readString(header.id, 12);
+	header.version = f->readInt(1);
+	f->readString(header.title, 20); f->readString(header.author, 20);
+	header.numpat = f->readInt(1); header.numinst = f->readInt(1);
+
+	// signature exists ? good version ?
+	if(memcmp(header.id,"DeFy DTM ",9) || header.version != 0x10)
+	  { fp.close (f); return false; }
+
+	header.numinst++;
+
+	// load description
+	memset(desc,0,80*16);
+
+	char bufstr[80];
+
+	for (i=0;i<16;i++)
+	{
+		// get line length
+		unsigned char bufstr_length = f->readInt(1);
+
+      if(bufstr_length > 80) {
+	fp.close(f);
+	return false;
+      }
+
+		// read line
+		if (bufstr_length)
+		{
+			f->readString(bufstr,bufstr_length);
+
+			for (j=0;j<bufstr_length;j++)
+				if (!bufstr[j])
+					bufstr[j] = 0x20;
+
+			bufstr[bufstr_length] = 0;
+
+			strcat(desc,bufstr);
+		}
+
+		strcat(desc,"\n");
+	}
+
+	// init CmodPlayer
+	realloc_instruments(header.numinst);
+	realloc_order(100);
+	realloc_patterns(header.numpat,64,9);
+	init_notetable(conv_note);
+	init_trackord();
+
+	// load instruments
+	for (i=0;i<header.numinst;i++)
+	{
+		unsigned char name_length = f->readInt(1);
+
+		if (name_length)
+			f->readString(instruments[i].name, name_length);
+
+		instruments[i].name[name_length] = 0;
+
+		for(j = 0; j < 12; j++)
+		  instruments[i].data[j] = f->readInt(1);
+
+		for (j=0;j<11;j++)
+			inst[i].data[conv_inst[j]] = instruments[i].data[j];
+	}
+
+	// load order
+	for(i = 0; i < 100; i++) order[i] = f->readInt(1);
+
+	nop = header.numpat;
+
+	unsigned char *pattern = new unsigned char [0x480];
+
+	// load tracks
+	for (i=0;i<nop;i++)
+	{
+		unsigned short packed_length;
+
+		packed_length = f->readInt(2);
+
+		unsigned char *packed_pattern = new unsigned char [packed_length];
+
+		for(j = 0; j < packed_length; j++)
+		  packed_pattern[j] = f->readInt(1);
+
+		long unpacked_length = unpack_pattern(packed_pattern,packed_length,pattern,0x480);
+
+		delete [] packed_pattern;
+
+		if (!unpacked_length)
+		{
+			delete pattern;
+			fp.close(f);
+			return false;
+		}
+
+		// convert pattern
+		for (j=0;j<9;j++)
+		{
+			for (k=0;k<64;k++)
+			{
+				dtm_event *event = (dtm_event *)&pattern[(k*9+j)*2];
+
+				// instrument
+				if (event->byte0 == 0x80)
+				{
+					if (event->byte1 <= 0x80)
+						tracks[t][k].inst = event->byte1 + 1;
+				}
+
+				// note + effect
+				else
+				{
+					tracks[t][k].note = event->byte0;
+
+					if ((event->byte0 != 0) && (event->byte0 != 127))
+							tracks[t][k].note++;
+
+					// convert effects
+					switch (event->byte1 >> 4)
+					{
+						case 0x0: // pattern break
+							if ((event->byte1 & 15) == 1)
+								tracks[t][k].command = 13;
+							break;
+
+						case 0x1: // freq. slide up
+							tracks[t][k].command = 28;
+							tracks[t][k].param1 = event->byte1 & 15;
+							break;
+
+						case 0x2: // freq. slide down
+							tracks[t][k].command = 28;
+							tracks[t][k].param2 = event->byte1 & 15;
+							break;
+
+						case 0xA: // set carrier volume
+						case 0xC: // set instrument volume
+							tracks[t][k].command = 22;
+							tracks[t][k].param1 = (0x3F - (event->byte1 & 15)) >> 4;
+							tracks[t][k].param2 = (0x3F - (event->byte1 & 15)) & 15;
+							break;
+
+						case 0xB: // set modulator volume
+							tracks[t][k].command = 21;
+							tracks[t][k].param1 = (0x3F - (event->byte1 & 15)) >> 4;
+							tracks[t][k].param2 = (0x3F - (event->byte1 & 15)) & 15;
+							break;
+
+						case 0xE: // set panning
+							break;
+
+						case 0xF: // set speed
+							tracks[t][k].command = 13;
+							tracks[t][k].param2 = event->byte1 & 15;
+							break;
+					}
+				}
+			}
+
+			t++;
+		}
+	}
+
+	delete [] pattern;
+	fp.close(f);
+
+	// order length
+	for (i=0;i<100;i++)
+	{
+		if (order[i] >= 0x80)
+		{
+			length = i;
+
+			if (order[i] == 0xFF)
+				restartpos = 0;
+			else
+				restartpos = order[i] - 0x80;
+
+			break;
+		}
+	}
+
+	// initial speed
+	initspeed = 2;
+
+	rewind(0);
+
+	return true;
+}
+
+void CdtmLoader::rewind(int subsong)
+{
+	CmodPlayer::rewind(subsong);
+
+	// default instruments
+	for (int i=0;i<9;i++)
+	{
+		channel[i].inst = i;
+
+		channel[i].vol1 = 63 - (inst[i].data[10] & 63);
+		channel[i].vol2 = 63 - (inst[i].data[9] & 63);
+	}
+}
+
+float CdtmLoader::getrefresh()
+{
+	return 18.2f;
+}
+
+std::string CdtmLoader::gettype()
+{
+	return std::string("DeFy Adlib Tracker");
+}
+
+std::string CdtmLoader::gettitle()
+{
+	return std::string(header.title);
+}
+
+std::string CdtmLoader::getauthor()
+{
+	return std::string(header.author);
+}
+
+std::string CdtmLoader::getdesc()
+{
+	return std::string(desc);
+}
+
+std::string CdtmLoader::getinstrument(unsigned int n)
+{
+	return std::string(instruments[n].name);
+}
+
+unsigned int CdtmLoader::getinstruments()
+{
+	return header.numinst;
+}
+
+/* -------- Private Methods ------------------------------- */
+
+long CdtmLoader::unpack_pattern(unsigned char *ibuf, long ilen, unsigned char *obuf, long olen)
+{
+	unsigned char *input = ibuf;
+	unsigned char *output = obuf;
+
+	long input_length = 0;
+	long output_length = 0;
+
+	unsigned char repeat_byte, repeat_counter;
+
+	// RLE
+	while (input_length < ilen)
+	{
+		repeat_byte = input[input_length++];
+
+		if ((repeat_byte & 0xF0) == 0xD0)
+		{
+			repeat_counter = repeat_byte & 15;
+			repeat_byte = input[input_length++];
+		}
+		else
+			repeat_counter = 1;
+
+		for (int i=0;i<repeat_counter;i++)
+		{
+			if (output_length < olen)
+				output[output_length++] = repeat_byte;
+		}
+	}
+
+	return output_length;
+}
--- a/Plugins/Input/adplug/core/emuopl.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,147 +0,0 @@
-/*
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * emuopl.cpp - Emulated OPL, by Simon Peter <dn.tlp@gmx.net>
- */
-
-#include "emuopl.h"
-
-CEmuopl::CEmuopl(int rate, bool bit16, bool usestereo)
-  : use16bit(bit16), stereo(usestereo), mixbufSamples(0)
-{
-  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[0]); OPLDestroy(opl[1]);
-
-  if(mixbufSamples) {
-    delete [] mixbuf0;
-    delete [] mixbuf1;
-  }
-}
-
-void CEmuopl::update(short *buf, int samples)
-{
-  int i;
-
-  //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];
-  }
-
-  //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);
-
-    //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);
-
-    //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;
-  }
-
-  //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)
-{
-  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[0]); OPLResetChip(opl[1]);
-  currChip = 0;
-}
-
-void CEmuopl::settype(ChipType type)
-{
-  currType = type;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/emuopl.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,147 @@
+/*
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * emuopl.cpp - Emulated OPL, by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include "emuopl.h"
+
+CEmuopl::CEmuopl(int rate, bool bit16, bool usestereo)
+  : use16bit(bit16), stereo(usestereo), mixbufSamples(0)
+{
+  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[0]); OPLDestroy(opl[1]);
+
+  if(mixbufSamples) {
+    delete [] mixbuf0;
+    delete [] mixbuf1;
+  }
+}
+
+void CEmuopl::update(short *buf, int samples)
+{
+  int i;
+
+  //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];
+  }
+
+  //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);
+
+    //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);
+
+    //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;
+  }
+
+  //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)
+{
+  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[0]); OPLResetChip(opl[1]);
+  currChip = 0;
+}
+
+void CEmuopl::settype(ChipType type)
+{
+  currType = type;
+}
--- a/Plugins/Input/adplug/core/flash.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,230 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * [xad] FLASH player, by Riven the Mage <riven@ok.ru>
- */
-
-/*
-    - discovery -
-
-  file(s) : LA-INTRO.EXE
-     type : Lunatic Asylum BBStro
-     tune : by Rogue [Logic Design]
-   player : by Flash [Logic Design]
-*/
-
-#include "flash.h"
-#include "debug.h"
-
-const unsigned char CxadflashPlayer::flash_adlib_registers[99] =
-{
-  0x23, 0x20, 0x43, 0x40, 0x63, 0x60, 0x83, 0x80, 0xC0, 0xE3, 0xE0,
-  0x24, 0x21, 0x44, 0x41, 0x64, 0x61, 0x84, 0x81, 0xC1, 0xE4, 0xE1,
-  0x25, 0x22, 0x45, 0x42, 0x65, 0x62, 0x85, 0x82, 0xC2, 0xE5, 0xE2,
-  0x2B, 0x28, 0x4B, 0x48, 0x6B, 0x68, 0x8B, 0x88, 0xC3, 0xEB, 0xE8,
-  0x2C, 0x29, 0x4C, 0x49, 0x6C, 0x69, 0x8C, 0x89, 0xC4, 0xEC, 0xE9,
-  0x2D, 0x2A, 0x4D, 0x4A, 0x6D, 0x6A, 0x8D, 0x8A, 0xC5, 0xED, 0xEA,
-  0x33, 0x30, 0x53, 0x50, 0x73, 0x70, 0x93, 0x90, 0xC6, 0xF3, 0xF0,
-  0x34, 0x31, 0x54, 0x51, 0x74, 0x71, 0x94, 0x91, 0xC7, 0xF4, 0xF1,
-  0x35, 0x32, 0x55, 0x52, 0x75, 0x72, 0x95, 0x92, 0xC8, 0xF5, 0xF2
-};
-
-const unsigned short CxadflashPlayer::flash_notes_encoded[268] =
-{
-  0x000,
-  0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700, 0x800, 0x900, 0xA00, 0xB00, 0xC00,
-  0x101, 0x201, 0x301, 0x401, 0x501, 0x601, 0x701, 0x801, 0x901, 0xA01, 0xB01, 0xC01,
-  0x102, 0x202, 0x302, 0x402, 0x502, 0x602, 0x702, 0x802, 0x902, 0xA02, 0xB02, 0xC02,
-  0x103, 0x203, 0x303, 0x403, 0x503, 0x603, 0x703, 0x803, 0x903, 0xA03, 0xB03, 0xC03,
-  0x104, 0x204, 0x304, 0x404, 0x504, 0x604, 0x704, 0x804, 0x904, 0xA04, 0xB04, 0xC04,
-  0x105, 0x205, 0x305, 0x405, 0x505, 0x605, 0x705, 0x805, 0x905, 0xA05, 0xB05, 0xC05,
-  0x106, 0x206, 0x306, 0x406, 0x506, 0x606, 0x706, 0x806, 0x906, 0xA06, 0xB06, 0xC06,
-  0x107, 0x207, 0x307, 0x407, 0x507, 0x607, 0x707, 0x807, 0x907, 0xA07, 0xB07, 0xC07,
-  0x108, 0x208, 0x308, 0x408, 0x508, 0x608, 0x708, 0x808, 0x908, 0xA08, 0xB08, 0xC08,
-  0x109, 0x209, 0x309, 0x409, 0x509, 0x609, 0x709, 0x809, 0x909, 0xA09, 0xB09, 0xC09,
-  0x10A, 0x20A, 0x30A, 0x40A, 0x50A, 0x60A, 0x70A, 0x80A, 0x90A, 0xA0A, 0xB0A, 0xC0A,
-  0x10B, 0x20B, 0x30B, 0x40B, 0x50B, 0x60B, 0x70B, 0x80B, 0x90B, 0xA0B, 0xB0B, 0xC0B,
-  0x10C, 0x20C, 0x30C, 0x40C, 0x50C, 0x60C, 0x70C, 0x80C, 0x90C, 0xA0C, 0xB0C, 0xC0C,
-  0x10D, 0x20D, 0x30D, 0x40D, 0x50D, 0x60D, 0x70D, 0x80D, 0x90D, 0xA0D, 0xB0D, 0xC0D,
-  0x10E, 0x20E, 0x30E, 0x40E, 0x50E, 0x60E, 0x70E, 0x80E, 0x90E, 0xA0E, 0xB0E, 0xC0E,
-  0x10F, 0x20F, 0x30F, 0x40F, 0x50F, 0x60F, 0x70F, 0x80F, 0x90F, 0xA0F, 0xB0F, 0xC0F,
-  0x110, 0x210, 0x310, 0x410, 0x510, 0x610, 0x710, 0x810, 0x910, 0xA10, 0xB10, 0xC10,
-  0x111, 0x211, 0x311, 0x411, 0x511, 0x611, 0x711, 0x811, 0x911, 0xA11, 0xB11, 0xC11,
-  0x112, 0x212, 0x312, 0x412, 0x512, 0x612, 0x712, 0x812, 0x912, 0xA12, 0xB12, 0xC12,
-  0x113, 0x213, 0x313, 0x413, 0x513, 0x613, 0x713, 0x813, 0x913, 0xA13, 0xB13, 0xC13,
-  0x114, 0x214, 0x314, 0x414, 0x514, 0x614, 0x714, 0x814, 0x914, 0xA14, 0xB14, 0xC14,
-  0x115, 0x215, 0x315
-};
-
-const unsigned short CxadflashPlayer::flash_notes[12] =
-{
-  0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287
-};
-
-const unsigned char CxadflashPlayer::flash_default_instrument[8] =
-{
-  0x00, 0x00, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF
-};
-
-CPlayer *CxadflashPlayer::factory(Copl *newopl)
-{
-  return new CxadflashPlayer(newopl);
-}
-
-void CxadflashPlayer::xadplayer_rewind(int subsong)
-{
-  int i;
-
-  plr.speed = xad.speed;
-
-  flash.order_pos = 0;
-  flash.pattern_pos = 0;
-
-  opl_write(0x08, 0x00);
-  opl_write(0xBD, 0x00);
-
-  // assign default instrument
-  for(i=0; i<9; i++)
-  {
-    opl_write(0xA0+i, 0x00);
-    opl_write(0xB0+i, 0x00);
-  }
-
-  // assign instruments
-  for(i=0; i<9; i++)
-    for(int j=0; j<11; j++)
-      opl_write(flash_adlib_registers[i*11+j], tune[i*12+j]);
-}
-
-void CxadflashPlayer::xadplayer_update()
-{
-  unsigned short event_pos = (tune[0x600+flash.order_pos]*1152) + \
-                             (flash.pattern_pos*18) + \
-                              0x633;
-
-  for (int i=0; i<9; i++)
-  {
-    unsigned short flash_channel_freq = (adlib[0xB0+i] << 8) + adlib[0xA0+i];
-
-    unsigned char event_b0 = tune[event_pos++];
-    unsigned char event_b1 = tune[event_pos++];
-#ifdef DEBUG
-  AdPlug_LogWrite("channel %02X, event %02X %02X:\n",i+1,event_b0,event_b1);
-#endif
-
-    if (event_b0 == 0x80)               // 0.0x80: Set Instrument
-    {
-      for(int j=0; j<11; j++)
-        opl_write(flash_adlib_registers[i*11+j], tune[event_b1*12+j]);
-    }
-    else
-    {
-      if (event_b1 == 0x01)
-        flash.pattern_pos = 0x3F;       // 1.0x01: Pattern Break
-
-      unsigned char fx = (event_b1 >> 4);
-      unsigned char fx_p = (event_b1 & 0x0F);
-
-      switch(fx)
-      {
-        case 0x0A:                      // 1.0xAy: Set Carrier volume
-          opl_write(flash_adlib_registers[11*i+2], fx_p << 2);
-          break;
-        case 0x0B:                      // 1.0xBy: Set Modulator volume
-          opl_write(flash_adlib_registers[11*i+3], fx_p << 2);
-          break;
-        case 0x0C:                      // 1.0xCy: Set both operators volume
-          opl_write(flash_adlib_registers[11*i+2], fx_p << 2);
-          opl_write(flash_adlib_registers[11*i+3], fx_p << 2);
-          break;
-//      case 0x0E:                      // 1.0xEy: ? (increase some value)
-        case 0x0F:                      // 1.0xFy: Set Speed
-          plr.speed = (fx_p + 1);
-          break;
-      }
-
-      if (event_b0)
-      {
-        // mute channel
-        opl_write(0xA0+i, adlib[0xA0+i]);
-        opl_write(0xB0+i, adlib[0xB0+i] & 0xDF);
-
-        // is note ?
-        if (event_b0 != 0x7F)
-        {
-          unsigned short note_encoded = flash_notes_encoded[event_b0];
-          unsigned short freq = flash_notes[(note_encoded >> 8) - 1];
-
-          flash_channel_freq = freq | ((note_encoded & 0xFF) << 10) | 0x2000;
-
-          opl_write(0xA0+i, flash_channel_freq & 0xFF);
-          opl_write(0xB0+i, flash_channel_freq >> 8);
-        }
-      }
-
-      if (fx == 0x01)                   // 1.0x1y: Fine Frequency Slide Up
-      {
-        flash_channel_freq += (fx_p << 1);
-
-        opl_write(0xA0+i, flash_channel_freq & 0xFF);
-        opl_write(0xB0+i, flash_channel_freq >> 8);
-      }
-      else if (fx == 0x02)              // 1.0x2y: Fine Frequency Slide Down
-      {
-        flash_channel_freq -= (fx_p << 1);
-
-        opl_write(0xA0+i, flash_channel_freq & 0xFF);
-        opl_write(0xB0+i, flash_channel_freq >> 8);
-      }
-    }
-  }
-
-  // next row
-  flash.pattern_pos++;
-
-  // end of pattern ?
-  if (flash.pattern_pos >= 0x40)
-  {
-    flash.pattern_pos = 0;
-
-    flash.order_pos++;
-
-    // end of module ?
-    if (tune[0x600+flash.order_pos] == 0xFF)
-    {
-      flash.order_pos = 0;
-
-      plr.looping = 1;
-    }
-  }
-}
-
-float CxadflashPlayer::xadplayer_getrefresh()
-{
-  return 17.5f;
-}
-
-std::string CxadflashPlayer::xadplayer_gettype()
-{
-  return std::string("xad: flash player");
-}
-
-unsigned int CxadflashPlayer::xadplayer_getinstruments()
-{
-  return 32;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/flash.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,230 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * [xad] FLASH player, by Riven the Mage <riven@ok.ru>
+ */
+
+/*
+    - discovery -
+
+  file(s) : LA-INTRO.EXE
+     type : Lunatic Asylum BBStro
+     tune : by Rogue [Logic Design]
+   player : by Flash [Logic Design]
+*/
+
+#include "flash.h"
+#include "debug.h"
+
+const unsigned char CxadflashPlayer::flash_adlib_registers[99] =
+{
+  0x23, 0x20, 0x43, 0x40, 0x63, 0x60, 0x83, 0x80, 0xC0, 0xE3, 0xE0,
+  0x24, 0x21, 0x44, 0x41, 0x64, 0x61, 0x84, 0x81, 0xC1, 0xE4, 0xE1,
+  0x25, 0x22, 0x45, 0x42, 0x65, 0x62, 0x85, 0x82, 0xC2, 0xE5, 0xE2,
+  0x2B, 0x28, 0x4B, 0x48, 0x6B, 0x68, 0x8B, 0x88, 0xC3, 0xEB, 0xE8,
+  0x2C, 0x29, 0x4C, 0x49, 0x6C, 0x69, 0x8C, 0x89, 0xC4, 0xEC, 0xE9,
+  0x2D, 0x2A, 0x4D, 0x4A, 0x6D, 0x6A, 0x8D, 0x8A, 0xC5, 0xED, 0xEA,
+  0x33, 0x30, 0x53, 0x50, 0x73, 0x70, 0x93, 0x90, 0xC6, 0xF3, 0xF0,
+  0x34, 0x31, 0x54, 0x51, 0x74, 0x71, 0x94, 0x91, 0xC7, 0xF4, 0xF1,
+  0x35, 0x32, 0x55, 0x52, 0x75, 0x72, 0x95, 0x92, 0xC8, 0xF5, 0xF2
+};
+
+const unsigned short CxadflashPlayer::flash_notes_encoded[268] =
+{
+  0x000,
+  0x100, 0x200, 0x300, 0x400, 0x500, 0x600, 0x700, 0x800, 0x900, 0xA00, 0xB00, 0xC00,
+  0x101, 0x201, 0x301, 0x401, 0x501, 0x601, 0x701, 0x801, 0x901, 0xA01, 0xB01, 0xC01,
+  0x102, 0x202, 0x302, 0x402, 0x502, 0x602, 0x702, 0x802, 0x902, 0xA02, 0xB02, 0xC02,
+  0x103, 0x203, 0x303, 0x403, 0x503, 0x603, 0x703, 0x803, 0x903, 0xA03, 0xB03, 0xC03,
+  0x104, 0x204, 0x304, 0x404, 0x504, 0x604, 0x704, 0x804, 0x904, 0xA04, 0xB04, 0xC04,
+  0x105, 0x205, 0x305, 0x405, 0x505, 0x605, 0x705, 0x805, 0x905, 0xA05, 0xB05, 0xC05,
+  0x106, 0x206, 0x306, 0x406, 0x506, 0x606, 0x706, 0x806, 0x906, 0xA06, 0xB06, 0xC06,
+  0x107, 0x207, 0x307, 0x407, 0x507, 0x607, 0x707, 0x807, 0x907, 0xA07, 0xB07, 0xC07,
+  0x108, 0x208, 0x308, 0x408, 0x508, 0x608, 0x708, 0x808, 0x908, 0xA08, 0xB08, 0xC08,
+  0x109, 0x209, 0x309, 0x409, 0x509, 0x609, 0x709, 0x809, 0x909, 0xA09, 0xB09, 0xC09,
+  0x10A, 0x20A, 0x30A, 0x40A, 0x50A, 0x60A, 0x70A, 0x80A, 0x90A, 0xA0A, 0xB0A, 0xC0A,
+  0x10B, 0x20B, 0x30B, 0x40B, 0x50B, 0x60B, 0x70B, 0x80B, 0x90B, 0xA0B, 0xB0B, 0xC0B,
+  0x10C, 0x20C, 0x30C, 0x40C, 0x50C, 0x60C, 0x70C, 0x80C, 0x90C, 0xA0C, 0xB0C, 0xC0C,
+  0x10D, 0x20D, 0x30D, 0x40D, 0x50D, 0x60D, 0x70D, 0x80D, 0x90D, 0xA0D, 0xB0D, 0xC0D,
+  0x10E, 0x20E, 0x30E, 0x40E, 0x50E, 0x60E, 0x70E, 0x80E, 0x90E, 0xA0E, 0xB0E, 0xC0E,
+  0x10F, 0x20F, 0x30F, 0x40F, 0x50F, 0x60F, 0x70F, 0x80F, 0x90F, 0xA0F, 0xB0F, 0xC0F,
+  0x110, 0x210, 0x310, 0x410, 0x510, 0x610, 0x710, 0x810, 0x910, 0xA10, 0xB10, 0xC10,
+  0x111, 0x211, 0x311, 0x411, 0x511, 0x611, 0x711, 0x811, 0x911, 0xA11, 0xB11, 0xC11,
+  0x112, 0x212, 0x312, 0x412, 0x512, 0x612, 0x712, 0x812, 0x912, 0xA12, 0xB12, 0xC12,
+  0x113, 0x213, 0x313, 0x413, 0x513, 0x613, 0x713, 0x813, 0x913, 0xA13, 0xB13, 0xC13,
+  0x114, 0x214, 0x314, 0x414, 0x514, 0x614, 0x714, 0x814, 0x914, 0xA14, 0xB14, 0xC14,
+  0x115, 0x215, 0x315
+};
+
+const unsigned short CxadflashPlayer::flash_notes[12] =
+{
+  0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287
+};
+
+const unsigned char CxadflashPlayer::flash_default_instrument[8] =
+{
+  0x00, 0x00, 0x3F, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF
+};
+
+CPlayer *CxadflashPlayer::factory(Copl *newopl)
+{
+  return new CxadflashPlayer(newopl);
+}
+
+void CxadflashPlayer::xadplayer_rewind(int subsong)
+{
+  int i;
+
+  plr.speed = xad.speed;
+
+  flash.order_pos = 0;
+  flash.pattern_pos = 0;
+
+  opl_write(0x08, 0x00);
+  opl_write(0xBD, 0x00);
+
+  // assign default instrument
+  for(i=0; i<9; i++)
+  {
+    opl_write(0xA0+i, 0x00);
+    opl_write(0xB0+i, 0x00);
+  }
+
+  // assign instruments
+  for(i=0; i<9; i++)
+    for(int j=0; j<11; j++)
+      opl_write(flash_adlib_registers[i*11+j], tune[i*12+j]);
+}
+
+void CxadflashPlayer::xadplayer_update()
+{
+  unsigned short event_pos = (tune[0x600+flash.order_pos]*1152) + \
+                             (flash.pattern_pos*18) + \
+                              0x633;
+
+  for (int i=0; i<9; i++)
+  {
+    unsigned short flash_channel_freq = (adlib[0xB0+i] << 8) + adlib[0xA0+i];
+
+    unsigned char event_b0 = tune[event_pos++];
+    unsigned char event_b1 = tune[event_pos++];
+#ifdef DEBUG
+  AdPlug_LogWrite("channel %02X, event %02X %02X:\n",i+1,event_b0,event_b1);
+#endif
+
+    if (event_b0 == 0x80)               // 0.0x80: Set Instrument
+    {
+      for(int j=0; j<11; j++)
+        opl_write(flash_adlib_registers[i*11+j], tune[event_b1*12+j]);
+    }
+    else
+    {
+      if (event_b1 == 0x01)
+        flash.pattern_pos = 0x3F;       // 1.0x01: Pattern Break
+
+      unsigned char fx = (event_b1 >> 4);
+      unsigned char fx_p = (event_b1 & 0x0F);
+
+      switch(fx)
+      {
+        case 0x0A:                      // 1.0xAy: Set Carrier volume
+          opl_write(flash_adlib_registers[11*i+2], fx_p << 2);
+          break;
+        case 0x0B:                      // 1.0xBy: Set Modulator volume
+          opl_write(flash_adlib_registers[11*i+3], fx_p << 2);
+          break;
+        case 0x0C:                      // 1.0xCy: Set both operators volume
+          opl_write(flash_adlib_registers[11*i+2], fx_p << 2);
+          opl_write(flash_adlib_registers[11*i+3], fx_p << 2);
+          break;
+//      case 0x0E:                      // 1.0xEy: ? (increase some value)
+        case 0x0F:                      // 1.0xFy: Set Speed
+          plr.speed = (fx_p + 1);
+          break;
+      }
+
+      if (event_b0)
+      {
+        // mute channel
+        opl_write(0xA0+i, adlib[0xA0+i]);
+        opl_write(0xB0+i, adlib[0xB0+i] & 0xDF);
+
+        // is note ?
+        if (event_b0 != 0x7F)
+        {
+          unsigned short note_encoded = flash_notes_encoded[event_b0];
+          unsigned short freq = flash_notes[(note_encoded >> 8) - 1];
+
+          flash_channel_freq = freq | ((note_encoded & 0xFF) << 10) | 0x2000;
+
+          opl_write(0xA0+i, flash_channel_freq & 0xFF);
+          opl_write(0xB0+i, flash_channel_freq >> 8);
+        }
+      }
+
+      if (fx == 0x01)                   // 1.0x1y: Fine Frequency Slide Up
+      {
+        flash_channel_freq += (fx_p << 1);
+
+        opl_write(0xA0+i, flash_channel_freq & 0xFF);
+        opl_write(0xB0+i, flash_channel_freq >> 8);
+      }
+      else if (fx == 0x02)              // 1.0x2y: Fine Frequency Slide Down
+      {
+        flash_channel_freq -= (fx_p << 1);
+
+        opl_write(0xA0+i, flash_channel_freq & 0xFF);
+        opl_write(0xB0+i, flash_channel_freq >> 8);
+      }
+    }
+  }
+
+  // next row
+  flash.pattern_pos++;
+
+  // end of pattern ?
+  if (flash.pattern_pos >= 0x40)
+  {
+    flash.pattern_pos = 0;
+
+    flash.order_pos++;
+
+    // end of module ?
+    if (tune[0x600+flash.order_pos] == 0xFF)
+    {
+      flash.order_pos = 0;
+
+      plr.looping = 1;
+    }
+  }
+}
+
+float CxadflashPlayer::xadplayer_getrefresh()
+{
+  return 17.5f;
+}
+
+std::string CxadflashPlayer::xadplayer_gettype()
+{
+  return std::string("xad: flash player");
+}
+
+unsigned int CxadflashPlayer::xadplayer_getinstruments()
+{
+  return 32;
+}
--- a/Plugins/Input/adplug/core/fmc.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,223 +0,0 @@
-/*
-  Adplug - Replayer for many OPL2/OPL3 audio file formats.
-  Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-  fmc.cpp - FMC Loader by Riven the Mage <riven@ok.ru>
-*/
-
-#include "fmc.h"
-
-/* -------- Public Methods -------------------------------- */
-
-CPlayer *CfmcLoader::factory(Copl *newopl)
-{
-  return new CfmcLoader(newopl);
-}
-
-bool CfmcLoader::load(const std::string &filename, const CFileProvider &fp)
-{
-        binistream *f = fp.open(filename); if(!f) return false;
-	const unsigned char conv_fx[16] = {0,1,2,3,4,8,255,255,255,255,26,11,12,13,14,15};
-
-	int i,j,k,t=0;
-
-	// read header
-	f->readString(header.id, 4);
-	f->readString(header.title, 21);
-	header.numchan = f->readInt(1);
-
-	// 'FMC!' - signed ?
-	if (strncmp(header.id,"FMC!",4)) { fp.close(f); return false; }
-
-	// init CmodPlayer
-	realloc_instruments(32);
-	realloc_order(256);
-	realloc_patterns(64,64,header.numchan);
-	init_trackord();
-
-	// load order
-	for(i = 0; i < 256; i++) order[i] = f->readInt(1);
-
-	f->ignore(2);
-
-	// load instruments
-	for(i = 0; i < 32; i++) {
-	  instruments[i].synthesis = f->readInt(1);
-	  instruments[i].feedback = f->readInt(1);
-
-	  instruments[i].mod_attack = f->readInt(1);
-	  instruments[i].mod_decay = f->readInt(1);
-	  instruments[i].mod_sustain = f->readInt(1);
-	  instruments[i].mod_release = f->readInt(1);
-	  instruments[i].mod_volume = f->readInt(1);
-	  instruments[i].mod_ksl = f->readInt(1);
-	  instruments[i].mod_freq_multi = f->readInt(1);
-	  instruments[i].mod_waveform = f->readInt(1);
-	  instruments[i].mod_sustain_sound = f->readInt(1);
-	  instruments[i].mod_ksr = f->readInt(1);
-	  instruments[i].mod_vibrato = f->readInt(1);
-	  instruments[i].mod_tremolo = f->readInt(1);
-
-	  instruments[i].car_attack = f->readInt(1);
-	  instruments[i].car_decay = f->readInt(1);
-	  instruments[i].car_sustain = f->readInt(1);
-	  instruments[i].car_release = f->readInt(1);
-	  instruments[i].car_volume = f->readInt(1);
-	  instruments[i].car_ksl = f->readInt(1);
-	  instruments[i].car_freq_multi = f->readInt(1);
-	  instruments[i].car_waveform = f->readInt(1);
-	  instruments[i].car_sustain_sound = f->readInt(1);
-	  instruments[i].car_ksr = f->readInt(1);
-	  instruments[i].car_vibrato = f->readInt(1);
-	  instruments[i].car_tremolo = f->readInt(1);
-
-	  instruments[i].pitch_shift = f->readInt(1);
-
-	  f->readString(instruments[i].name, 21);
-	}
-
-	// load tracks
-	for (i=0;i<64;i++)
-	{
-	        if(f->ateof()) break;
-
-		for (j=0;j<header.numchan;j++)
-		{
-			for (k=0;k<64;k++)
-			{
-				fmc_event event;
-
-				// read event
-				event.byte0 = f->readInt(1);
-				event.byte1 = f->readInt(1);
-				event.byte2 = f->readInt(1);
-
-				// convert event
-				tracks[t][k].note = event.byte0 & 0x7F;
-				tracks[t][k].inst = ((event.byte0 & 0x80) >> 3) + (event.byte1 >> 4) + 1;
-				tracks[t][k].command = conv_fx[event.byte1 & 0x0F];
-				tracks[t][k].param1 = event.byte2 >> 4;
-				tracks[t][k].param2 = event.byte2 & 0x0F;
-
-				// fix effects
-				if (tracks[t][k].command == 0x0E) // 0x0E (14): Retrig
-					tracks[t][k].param1 = 3;
-				if (tracks[t][k].command == 0x1A) // 0x1A (26): Volume Slide
-					if (tracks[t][k].param1 > tracks[t][k].param2)
-					{
-						tracks[t][k].param1 -= tracks[t][k].param2;
-						tracks[t][k].param2 = 0;
-					}
-					else
-					{
-						tracks[t][k].param2 -= tracks[t][k].param1;
-						tracks[t][k].param1 = 0;
-					}
-			}
-
-			t++;
-		}
-	}
-	fp.close(f);
-
-	// convert instruments
-	for (i=0;i<31;i++)
-		buildinst(i);
-
-	// order length
-	for (i=0;i<256;i++)
-	{
-		if (order[i] >= 0xFE)
-		{
-			length = i;
-			break;
-		}
-	}
-
-	// data for Protracker
-	activechan = (0xffff >> (16 - header.numchan)) << (16 - header.numchan);
-	nop = t / header.numchan;
-	restartpos = 0;
-
-	// flags
-	flags = Faust;
-
-	rewind(0);
-
-	return true;
-}
-
-float CfmcLoader::getrefresh()
-{
-	return 50.0f;
-}
-
-std::string CfmcLoader::gettype()
-{
-	return std::string("Faust Music Creator");
-}
-
-std::string CfmcLoader::gettitle()
-{
-	return std::string(header.title);
-}
-
-std::string CfmcLoader::getinstrument(unsigned int n)
-{
-	return std::string(instruments[n].name);
-}
-
-unsigned int CfmcLoader::getinstruments()
-{
-	return 32;
-}
-
-/* -------- Private Methods ------------------------------- */
-
-void CfmcLoader::buildinst(unsigned char i)
-{
-	inst[i].data[0]   = ((instruments[i].synthesis & 1) ^ 1);
-	inst[i].data[0]  |= ((instruments[i].feedback & 7) << 1);
-
-	inst[i].data[3]   = ((instruments[i].mod_attack & 15) << 4);
-	inst[i].data[3]  |=  (instruments[i].mod_decay & 15);
-	inst[i].data[5]   = ((15 - (instruments[i].mod_sustain & 15)) << 4);
-	inst[i].data[5]  |=  (instruments[i].mod_release & 15);
-	inst[i].data[9]   =  (63 - (instruments[i].mod_volume & 63));
-	inst[i].data[9]  |= ((instruments[i].mod_ksl & 3) << 6);
-	inst[i].data[1]   =  (instruments[i].mod_freq_multi & 15);
-	inst[i].data[7]   =  (instruments[i].mod_waveform & 3);
-	inst[i].data[1]  |= ((instruments[i].mod_sustain_sound & 1) << 5);
-	inst[i].data[1]  |= ((instruments[i].mod_ksr & 1) << 4);
-	inst[i].data[1]  |= ((instruments[i].mod_vibrato & 1) << 6);
-	inst[i].data[1]  |= ((instruments[i].mod_tremolo & 1) << 7);
-
-	inst[i].data[4]   = ((instruments[i].car_attack & 15) << 4);
-	inst[i].data[4]  |=  (instruments[i].car_decay & 15);
-	inst[i].data[6]   = ((15 - (instruments[i].car_sustain & 15)) << 4);
-	inst[i].data[6]  |=  (instruments[i].car_release & 15);
-	inst[i].data[10]  =  (63 - (instruments[i].car_volume & 63));
-	inst[i].data[10] |= ((instruments[i].car_ksl & 3) << 6);
-	inst[i].data[2]   =  (instruments[i].car_freq_multi & 15);
-	inst[i].data[8]   =  (instruments[i].car_waveform & 3);
-	inst[i].data[2]  |= ((instruments[i].car_sustain_sound & 1) << 5);
-	inst[i].data[2]  |= ((instruments[i].car_ksr & 1) << 4);
-	inst[i].data[2]  |= ((instruments[i].car_vibrato & 1) << 6);
-	inst[i].data[2]  |= ((instruments[i].car_tremolo & 1) << 7);
-
-	inst[i].slide     =   instruments[i].pitch_shift;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/fmc.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,223 @@
+/*
+  Adplug - Replayer for many OPL2/OPL3 audio file formats.
+  Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  fmc.cpp - FMC Loader by Riven the Mage <riven@ok.ru>
+*/
+
+#include "fmc.h"
+
+/* -------- Public Methods -------------------------------- */
+
+CPlayer *CfmcLoader::factory(Copl *newopl)
+{
+  return new CfmcLoader(newopl);
+}
+
+bool CfmcLoader::load(const std::string &filename, const CFileProvider &fp)
+{
+        binistream *f = fp.open(filename); if(!f) return false;
+	const unsigned char conv_fx[16] = {0,1,2,3,4,8,255,255,255,255,26,11,12,13,14,15};
+
+	int i,j,k,t=0;
+
+	// read header
+	f->readString(header.id, 4);
+	f->readString(header.title, 21);
+	header.numchan = f->readInt(1);
+
+	// 'FMC!' - signed ?
+	if (strncmp(header.id,"FMC!",4)) { fp.close(f); return false; }
+
+	// init CmodPlayer
+	realloc_instruments(32);
+	realloc_order(256);
+	realloc_patterns(64,64,header.numchan);
+	init_trackord();
+
+	// load order
+	for(i = 0; i < 256; i++) order[i] = f->readInt(1);
+
+	f->ignore(2);
+
+	// load instruments
+	for(i = 0; i < 32; i++) {
+	  instruments[i].synthesis = f->readInt(1);
+	  instruments[i].feedback = f->readInt(1);
+
+	  instruments[i].mod_attack = f->readInt(1);
+	  instruments[i].mod_decay = f->readInt(1);
+	  instruments[i].mod_sustain = f->readInt(1);
+	  instruments[i].mod_release = f->readInt(1);
+	  instruments[i].mod_volume = f->readInt(1);
+	  instruments[i].mod_ksl = f->readInt(1);
+	  instruments[i].mod_freq_multi = f->readInt(1);
+	  instruments[i].mod_waveform = f->readInt(1);
+	  instruments[i].mod_sustain_sound = f->readInt(1);
+	  instruments[i].mod_ksr = f->readInt(1);
+	  instruments[i].mod_vibrato = f->readInt(1);
+	  instruments[i].mod_tremolo = f->readInt(1);
+
+	  instruments[i].car_attack = f->readInt(1);
+	  instruments[i].car_decay = f->readInt(1);
+	  instruments[i].car_sustain = f->readInt(1);
+	  instruments[i].car_release = f->readInt(1);
+	  instruments[i].car_volume = f->readInt(1);
+	  instruments[i].car_ksl = f->readInt(1);
+	  instruments[i].car_freq_multi = f->readInt(1);
+	  instruments[i].car_waveform = f->readInt(1);
+	  instruments[i].car_sustain_sound = f->readInt(1);
+	  instruments[i].car_ksr = f->readInt(1);
+	  instruments[i].car_vibrato = f->readInt(1);
+	  instruments[i].car_tremolo = f->readInt(1);
+
+	  instruments[i].pitch_shift = f->readInt(1);
+
+	  f->readString(instruments[i].name, 21);
+	}
+
+	// load tracks
+	for (i=0;i<64;i++)
+	{
+	        if(f->ateof()) break;
+
+		for (j=0;j<header.numchan;j++)
+		{
+			for (k=0;k<64;k++)
+			{
+				fmc_event event;
+
+				// read event
+				event.byte0 = f->readInt(1);
+				event.byte1 = f->readInt(1);
+				event.byte2 = f->readInt(1);
+
+				// convert event
+				tracks[t][k].note = event.byte0 & 0x7F;
+				tracks[t][k].inst = ((event.byte0 & 0x80) >> 3) + (event.byte1 >> 4) + 1;
+				tracks[t][k].command = conv_fx[event.byte1 & 0x0F];
+				tracks[t][k].param1 = event.byte2 >> 4;
+				tracks[t][k].param2 = event.byte2 & 0x0F;
+
+				// fix effects
+				if (tracks[t][k].command == 0x0E) // 0x0E (14): Retrig
+					tracks[t][k].param1 = 3;
+				if (tracks[t][k].command == 0x1A) // 0x1A (26): Volume Slide
+					if (tracks[t][k].param1 > tracks[t][k].param2)
+					{
+						tracks[t][k].param1 -= tracks[t][k].param2;
+						tracks[t][k].param2 = 0;
+					}
+					else
+					{
+						tracks[t][k].param2 -= tracks[t][k].param1;
+						tracks[t][k].param1 = 0;
+					}
+			}
+
+			t++;
+		}
+	}
+	fp.close(f);
+
+	// convert instruments
+	for (i=0;i<31;i++)
+		buildinst(i);
+
+	// order length
+	for (i=0;i<256;i++)
+	{
+		if (order[i] >= 0xFE)
+		{
+			length = i;
+			break;
+		}
+	}
+
+	// data for Protracker
+	activechan = (0xffff >> (16 - header.numchan)) << (16 - header.numchan);
+	nop = t / header.numchan;
+	restartpos = 0;
+
+	// flags
+	flags = Faust;
+
+	rewind(0);
+
+	return true;
+}
+
+float CfmcLoader::getrefresh()
+{
+	return 50.0f;
+}
+
+std::string CfmcLoader::gettype()
+{
+	return std::string("Faust Music Creator");
+}
+
+std::string CfmcLoader::gettitle()
+{
+	return std::string(header.title);
+}
+
+std::string CfmcLoader::getinstrument(unsigned int n)
+{
+	return std::string(instruments[n].name);
+}
+
+unsigned int CfmcLoader::getinstruments()
+{
+	return 32;
+}
+
+/* -------- Private Methods ------------------------------- */
+
+void CfmcLoader::buildinst(unsigned char i)
+{
+	inst[i].data[0]   = ((instruments[i].synthesis & 1) ^ 1);
+	inst[i].data[0]  |= ((instruments[i].feedback & 7) << 1);
+
+	inst[i].data[3]   = ((instruments[i].mod_attack & 15) << 4);
+	inst[i].data[3]  |=  (instruments[i].mod_decay & 15);
+	inst[i].data[5]   = ((15 - (instruments[i].mod_sustain & 15)) << 4);
+	inst[i].data[5]  |=  (instruments[i].mod_release & 15);
+	inst[i].data[9]   =  (63 - (instruments[i].mod_volume & 63));
+	inst[i].data[9]  |= ((instruments[i].mod_ksl & 3) << 6);
+	inst[i].data[1]   =  (instruments[i].mod_freq_multi & 15);
+	inst[i].data[7]   =  (instruments[i].mod_waveform & 3);
+	inst[i].data[1]  |= ((instruments[i].mod_sustain_sound & 1) << 5);
+	inst[i].data[1]  |= ((instruments[i].mod_ksr & 1) << 4);
+	inst[i].data[1]  |= ((instruments[i].mod_vibrato & 1) << 6);
+	inst[i].data[1]  |= ((instruments[i].mod_tremolo & 1) << 7);
+
+	inst[i].data[4]   = ((instruments[i].car_attack & 15) << 4);
+	inst[i].data[4]  |=  (instruments[i].car_decay & 15);
+	inst[i].data[6]   = ((15 - (instruments[i].car_sustain & 15)) << 4);
+	inst[i].data[6]  |=  (instruments[i].car_release & 15);
+	inst[i].data[10]  =  (63 - (instruments[i].car_volume & 63));
+	inst[i].data[10] |= ((instruments[i].car_ksl & 3) << 6);
+	inst[i].data[2]   =  (instruments[i].car_freq_multi & 15);
+	inst[i].data[8]   =  (instruments[i].car_waveform & 3);
+	inst[i].data[2]  |= ((instruments[i].car_sustain_sound & 1) << 5);
+	inst[i].data[2]  |= ((instruments[i].car_ksr & 1) << 4);
+	inst[i].data[2]  |= ((instruments[i].car_vibrato & 1) << 6);
+	inst[i].data[2]  |= ((instruments[i].car_tremolo & 1) << 7);
+
+	inst[i].slide     =   instruments[i].pitch_shift;
+}
--- a/Plugins/Input/adplug/core/fprovide.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * fprovide.cpp - File provider class framework, by Simon Peter <dn.tlp@gmx.net>
- */
-
-#include <string.h>
-#include <binio.h>
-#include <binfile.h>
-
-#include "fprovide.h"
-
-/***** CFileProvider *****/
-
-bool CFileProvider::extension(const std::string &filename,
-			      const std::string &extension)
-{
-  const char *fname = filename.c_str(), *ext = extension.c_str();
-
-  if(strlen(fname) < strlen(ext) ||
-     stricmp(fname + strlen(fname) - strlen(ext), ext))
-    return false;
-  else
-    return true;
-}
-
-unsigned long CFileProvider::filesize(binistream *f)
-{
-  unsigned long oldpos = f->pos(), size;
-
-  f->seek(0, binio::End);
-  size = f->pos();
-  f->seek(oldpos, binio::Set);
-
-  return size;
-}
-
-/***** CProvider_Filesystem *****/
-
-binistream *CProvider_Filesystem::open(std::string filename) const
-{
-  binifstream *f = new binifstream(filename);
-
-  if(!f) return 0;
-  if(f->error()) { delete f; return 0; }
-
-  // Open all files as little endian with IEEE floats by default
-  f->setFlag(binio::BigEndian, false); f->setFlag(binio::FloatIEEE);
-
-  return f;
-}
-
-void CProvider_Filesystem::close(binistream *f) const
-{
-  binifstream *ff = (binifstream *)f;
-
-  if(f) {
-    ff->close();
-    delete ff;
-  }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/fprovide.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,76 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * fprovide.cpp - File provider class framework, by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include <string.h>
+#include <binio.h>
+#include <binfile.h>
+
+#include "fprovide.h"
+
+/***** CFileProvider *****/
+
+bool CFileProvider::extension(const std::string &filename,
+			      const std::string &extension)
+{
+  const char *fname = filename.c_str(), *ext = extension.c_str();
+
+  if(strlen(fname) < strlen(ext) ||
+     stricmp(fname + strlen(fname) - strlen(ext), ext))
+    return false;
+  else
+    return true;
+}
+
+unsigned long CFileProvider::filesize(binistream *f)
+{
+  unsigned long oldpos = f->pos(), size;
+
+  f->seek(0, binio::End);
+  size = f->pos();
+  f->seek(oldpos, binio::Set);
+
+  return size;
+}
+
+/***** CProvider_Filesystem *****/
+
+binistream *CProvider_Filesystem::open(std::string filename) const
+{
+  binifstream *f = new binifstream(filename);
+
+  if(!f) return 0;
+  if(f->error()) { delete f; return 0; }
+
+  // Open all files as little endian with IEEE floats by default
+  f->setFlag(binio::BigEndian, false); f->setFlag(binio::FloatIEEE);
+
+  return f;
+}
+
+void CProvider_Filesystem::close(binistream *f) const
+{
+  binifstream *ff = (binifstream *)f;
+
+  if(f) {
+    ff->close();
+    delete ff;
+  }
+}
--- a/Plugins/Input/adplug/core/hsc.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,317 +0,0 @@
-/*
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * hsc.cpp - HSC Player by Simon Peter <dn.tlp@gmx.net>
- */
-
-#include <string.h>
-
-#include "hsc.h"
-#include "debug.h"
-
-/*** public methods **************************************/
-
-CPlayer *ChscPlayer::factory(Copl *newopl)
-{
-  return new ChscPlayer(newopl);
-}
-
-bool ChscPlayer::load(const std::string &filename, const CFileProvider &fp)
-{
-  binistream	*f = fp.open(filename);
-  int		i;
-
-  // file validation section
-  if(!f || !fp.extension(filename, ".hsc") || fp.filesize(f) > 59187) {
-    AdPlug_LogWrite("ChscPlayer::load(\"%s\"): Not a HSC file!\n", filename.c_str());
-    fp.close(f);
-    return false;
-  }
-
-  // load section
-  for(i=0;i<128*12;i++)		// load instruments
-    *((unsigned char *)instr + i) = f->readInt(1);
-  for (i=0;i<128;i++) {			// correct instruments
-    instr[i][2] ^= (instr[i][2] & 0x40) << 1;
-    instr[i][3] ^= (instr[i][3] & 0x40) << 1;
-    instr[i][11] >>= 4;			// slide
-  }
-  for(i=0;i<51;i++) song[i] = f->readInt(1);	// load tracklist
-  for(i=0;i<50*64*9;i++)			// load patterns
-    *((char *)patterns + i) = f->readInt(1);
-
-  fp.close(f);
-  rewind(0);					// rewind module
-  return true;
-}
-
-bool ChscPlayer::update()
-{
-  // general vars
-  unsigned char		chan,pattnr,note,effect,eff_op,inst,vol,Okt,db;
-  unsigned short	Fnr;
-  unsigned long		pattoff;
-
-  del--;                      // player speed handling
-  if(del)
-    return !songend;		// nothing done
-
-  if(fadein)					// fade-in handling
-    fadein--;
-
-  pattnr = song[songpos];
-  if(pattnr == 0xff) {			// arrangement handling
-    songend = 1;				// set end-flag
-    songpos = 0;
-    pattnr = song[songpos];
-  } else
-    if ((pattnr & 128) && (pattnr <= 0xb1)) { // goto pattern "nr"
-      songpos = song[songpos] & 127;
-      pattpos = 0;
-      pattnr = song[songpos];
-      songend = 1;
-    }
-
-  pattoff = pattpos*9;
-  for (chan=0;chan<9;chan++) {			// handle all channels
-    note = patterns[pattnr][pattoff].note;
-    effect = patterns[pattnr][pattoff].effect;
-    pattoff++;
-
-    if(note & 128) {                    // set instrument
-      setinstr(chan,effect);
-      continue;
-    }
-    eff_op = effect & 0x0f;
-    inst = channel[chan].inst;
-    if(note)
-      channel[chan].slide = 0;
-
-    switch (effect & 0xf0) {			// effect handling
-    case 0:								// global effect
-      /* The following fx are unimplemented on purpose:
-       * 02 - Slide Mainvolume up
-       * 03 - Slide Mainvolume down (here: fade in)
-       * 04 - Set Mainvolume to 0
-       *
-       * This is because i've never seen any HSC modules using the fx this way.
-       * All modules use the fx the way, i've implemented it.
-       */
-      switch(eff_op) {
-      case 1: pattbreak++; break;	// jump to next pattern
-      case 3: fadein = 31; break;	// fade in (divided by 2)
-      case 5: mode6 = 1; break;	// 6 voice mode on
-      case 6: mode6 = 0; break;	// 6 voice mode off
-      }
-      break;
-    case 0x20:
-    case 0x10:		                    // manual slides
-      if (effect & 0x10) {
-	channel[chan].freq += eff_op;
-	channel[chan].slide += eff_op;
-      } else {
-	channel[chan].freq -= eff_op;
-	channel[chan].slide -= eff_op;
-      }
-      if(!note)
-	setfreq(chan,channel[chan].freq);
-      break;
-    case 0x50:							// set percussion instrument (unimplemented)
-      break;
-    case 0x60:							// set feedback
-      opl->write(0xc0 + chan, (instr[channel[chan].inst][8] & 1) + (eff_op << 1));
-      break;
-    case 0xa0:		                    // set carrier volume
-      vol = eff_op << 2;
-      opl->write(0x43 + op_table[chan], vol | (instr[channel[chan].inst][2] & ~63));
-      break;
-    case 0xb0:		                    // set modulator volume
-      vol = eff_op << 2;
-      if (instr[inst][8] & 1)
-	opl->write(0x40 + op_table[chan], vol | (instr[channel[chan].inst][3] & ~63));
-      else
-	opl->write(0x40 + op_table[chan],vol | (instr[inst][3] & ~63));
-      break;
-    case 0xc0:		                    // set instrument volume
-      db = eff_op << 2;
-      opl->write(0x43 + op_table[chan], db | (instr[channel[chan].inst][2] & ~63));
-      if (instr[inst][8] & 1)
-	opl->write(0x40 + op_table[chan], db | (instr[channel[chan].inst][3] & ~63));
-      break;
-    case 0xd0: pattbreak++; songpos = eff_op; songend = 1; break;	// position jump
-    case 0xf0:							// set speed
-      speed = eff_op;
-      del = ++speed;
-      break;
-    }
-
-    if(fadein)						// fade-in volume setting
-      setvolume(chan,fadein*2,fadein*2);
-
-    if(!note)						// note handling
-      continue;
-    note--;
-
-    if ((note == 0x7f-1) || ((note/12) & ~7)) {    // pause (7fh)
-      adl_freq[chan] &= ~32;
-      opl->write(0xb0 + chan,adl_freq[chan]);
-      continue;
-    }
-
-    // play the note
-    if(mtkmode)		// imitate MPU-401 Trakker bug
-      note--;
-    Okt = ((note/12) & 7) << 2;
-    Fnr = note_table[(note % 12)] + instr[inst][11] + channel[chan].slide;
-    channel[chan].freq = Fnr;
-    if(!mode6 || chan < 6)
-      adl_freq[chan] = Okt | 32;
-    else
-      adl_freq[chan] = Okt;		// never set key for drums
-    opl->write(0xb0 + chan, 0);
-    setfreq(chan,Fnr);
-    if(mode6) {
-      switch(chan) {		// play drums
-      case 6: opl->write(0xbd,bd & ~16); bd |= 48; break;	// bass drum
-      case 7: opl->write(0xbd,bd & ~1); bd |= 33; break;	// hihat
-      case 8: opl->write(0xbd,bd & ~2); bd |= 34; break;	// cymbal
-      }
-      opl->write(0xbd,bd);
-    }
-  }
-
-  del = speed;		// player speed-timing
-  if(pattbreak) {		// do post-effect handling
-    pattpos=0;			// pattern break!
-    pattbreak=0;
-    songpos++;
-    songpos %= 50;
-    if(!songpos)
-      songend = 1;
-  } else {
-    pattpos++;
-    pattpos &= 63;		// advance in pattern data
-    if (!pattpos) {
-      songpos++;
-      songpos %= 50;
-      if(!songpos)
-	songend = 1;
-    }
-  }
-  return !songend;		// still playing
-}
-
-void ChscPlayer::rewind(int subsong)
-{
-  int i;								// counter
-
-  // rewind HSC player
-  pattpos = 0; songpos = 0; pattbreak = 0; speed = 2;
-  del = 1; songend = 0; mode6 = 0; bd = 0; fadein = 0;
-
-  opl->init();						// reset OPL chip
-  opl->write(1,32); opl->write(8,128); opl->write(0xbd,0);
-
-  for(i=0;i<9;i++)
-    setinstr((char) i,(char) i);	// init channels
-}
-
-unsigned int ChscPlayer::getpatterns()
-{
-  unsigned char	poscnt,pattcnt=0;
-
-  // count patterns
-  for(poscnt=0;poscnt<51 && song[poscnt] != 0xff;poscnt++)
-    if(song[poscnt] > pattcnt)
-      pattcnt = song[poscnt];
-
-  return (pattcnt+1);
-}
-
-unsigned int ChscPlayer::getorders()
-{
-  unsigned char poscnt;
-
-  // count positions
-  for(poscnt=0;poscnt<51;poscnt++)
-    if(song[poscnt] == 0xff)
-      break;
-
-  return poscnt;
-}
-
-unsigned int ChscPlayer::getinstruments()
-{
-  unsigned char	instcnt,instnum=0,i;
-  bool		isinst;
-
-  // count instruments
-  for(instcnt=0;instcnt<128;instcnt++) {
-    isinst = false;
-    for(i=0;i<12;i++)
-      if(instr[instcnt][i])
-	isinst = true;
-    if(isinst)
-      instnum++;
-  }
-
-  return instnum;
-}
-
-/*** private methods *************************************/
-
-void ChscPlayer::setfreq(unsigned char chan, unsigned short freq)
-{
-  adl_freq[chan] = (adl_freq[chan] & ~3) | (freq >> 8);
-
-  opl->write(0xa0 + chan, freq & 0xff);
-  opl->write(0xb0 + chan, adl_freq[chan]);
-}
-
-void ChscPlayer::setvolume(unsigned char chan, int volc, int volm)
-{
-  unsigned char	*ins = instr[channel[chan].inst];
-  char		op = op_table[chan];
-
-  opl->write(0x43 + op,volc | (ins[2] & ~63));
-  if (ins[8] & 1)							// carrier
-    opl->write(0x40 + op,volm | (ins[3] & ~63));
-  else
-    opl->write(0x40 + op, ins[3]);		// modulator
-}
-
-void ChscPlayer::setinstr(unsigned char chan, unsigned char insnr)
-{
-  unsigned char	*ins = instr[insnr];
-  char		op = op_table[chan];
-
-  channel[chan].inst = insnr;		// set internal instrument
-  opl->write(0xb0 + chan,0);			// stop old note
-
-  // set instrument
-  opl->write(0xc0 + chan, ins[8]);
-  opl->write(0x23 + op, ins[0]);        // carrier
-  opl->write(0x20 + op, ins[1]);        // modulator
-  opl->write(0x63 + op, ins[4]);        // bits 0..3 = decay; 4..7 = attack
-  opl->write(0x60 + op, ins[5]);
-  opl->write(0x83 + op, ins[6]);        // 0..3 = release; 4..7 = sustain
-  opl->write(0x80 + op, ins[7]);
-  opl->write(0xe3 + op, ins[9]);        // bits 0..1 = Wellenform
-  opl->write(0xe0 + op, ins[10]);
-  setvolume(chan, ins[2] & 63, ins[3] & 63);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/hsc.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,317 @@
+/*
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * hsc.cpp - HSC Player by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include <string.h>
+
+#include "hsc.h"
+#include "debug.h"
+
+/*** public methods **************************************/
+
+CPlayer *ChscPlayer::factory(Copl *newopl)
+{
+  return new ChscPlayer(newopl);
+}
+
+bool ChscPlayer::load(const std::string &filename, const CFileProvider &fp)
+{
+  binistream	*f = fp.open(filename);
+  int		i;
+
+  // file validation section
+  if(!f || !fp.extension(filename, ".hsc") || fp.filesize(f) > 59187) {
+    AdPlug_LogWrite("ChscPlayer::load(\"%s\"): Not a HSC file!\n", filename.c_str());
+    fp.close(f);
+    return false;
+  }
+
+  // load section
+  for(i=0;i<128*12;i++)		// load instruments
+    *((unsigned char *)instr + i) = f->readInt(1);
+  for (i=0;i<128;i++) {			// correct instruments
+    instr[i][2] ^= (instr[i][2] & 0x40) << 1;
+    instr[i][3] ^= (instr[i][3] & 0x40) << 1;
+    instr[i][11] >>= 4;			// slide
+  }
+  for(i=0;i<51;i++) song[i] = f->readInt(1);	// load tracklist
+  for(i=0;i<50*64*9;i++)			// load patterns
+    *((char *)patterns + i) = f->readInt(1);
+
+  fp.close(f);
+  rewind(0);					// rewind module
+  return true;
+}
+
+bool ChscPlayer::update()
+{
+  // general vars
+  unsigned char		chan,pattnr,note,effect,eff_op,inst,vol,Okt,db;
+  unsigned short	Fnr;
+  unsigned long		pattoff;
+
+  del--;                      // player speed handling
+  if(del)
+    return !songend;		// nothing done
+
+  if(fadein)					// fade-in handling
+    fadein--;
+
+  pattnr = song[songpos];
+  if(pattnr == 0xff) {			// arrangement handling
+    songend = 1;				// set end-flag
+    songpos = 0;
+    pattnr = song[songpos];
+  } else
+    if ((pattnr & 128) && (pattnr <= 0xb1)) { // goto pattern "nr"
+      songpos = song[songpos] & 127;
+      pattpos = 0;
+      pattnr = song[songpos];
+      songend = 1;
+    }
+
+  pattoff = pattpos*9;
+  for (chan=0;chan<9;chan++) {			// handle all channels
+    note = patterns[pattnr][pattoff].note;
+    effect = patterns[pattnr][pattoff].effect;
+    pattoff++;
+
+    if(note & 128) {                    // set instrument
+      setinstr(chan,effect);
+      continue;
+    }
+    eff_op = effect & 0x0f;
+    inst = channel[chan].inst;
+    if(note)
+      channel[chan].slide = 0;
+
+    switch (effect & 0xf0) {			// effect handling
+    case 0:								// global effect
+      /* The following fx are unimplemented on purpose:
+       * 02 - Slide Mainvolume up
+       * 03 - Slide Mainvolume down (here: fade in)
+       * 04 - Set Mainvolume to 0
+       *
+       * This is because i've never seen any HSC modules using the fx this way.
+       * All modules use the fx the way, i've implemented it.
+       */
+      switch(eff_op) {
+      case 1: pattbreak++; break;	// jump to next pattern
+      case 3: fadein = 31; break;	// fade in (divided by 2)
+      case 5: mode6 = 1; break;	// 6 voice mode on
+      case 6: mode6 = 0; break;	// 6 voice mode off
+      }
+      break;
+    case 0x20:
+    case 0x10:		                    // manual slides
+      if (effect & 0x10) {
+	channel[chan].freq += eff_op;
+	channel[chan].slide += eff_op;
+      } else {
+	channel[chan].freq -= eff_op;
+	channel[chan].slide -= eff_op;
+      }
+      if(!note)
+	setfreq(chan,channel[chan].freq);
+      break;
+    case 0x50:							// set percussion instrument (unimplemented)
+      break;
+    case 0x60:							// set feedback
+      opl->write(0xc0 + chan, (instr[channel[chan].inst][8] & 1) + (eff_op << 1));
+      break;
+    case 0xa0:		                    // set carrier volume
+      vol = eff_op << 2;
+      opl->write(0x43 + op_table[chan], vol | (instr[channel[chan].inst][2] & ~63));
+      break;
+    case 0xb0:		                    // set modulator volume
+      vol = eff_op << 2;
+      if (instr[inst][8] & 1)
+	opl->write(0x40 + op_table[chan], vol | (instr[channel[chan].inst][3] & ~63));
+      else
+	opl->write(0x40 + op_table[chan],vol | (instr[inst][3] & ~63));
+      break;
+    case 0xc0:		                    // set instrument volume
+      db = eff_op << 2;
+      opl->write(0x43 + op_table[chan], db | (instr[channel[chan].inst][2] & ~63));
+      if (instr[inst][8] & 1)
+	opl->write(0x40 + op_table[chan], db | (instr[channel[chan].inst][3] & ~63));
+      break;
+    case 0xd0: pattbreak++; songpos = eff_op; songend = 1; break;	// position jump
+    case 0xf0:							// set speed
+      speed = eff_op;
+      del = ++speed;
+      break;
+    }
+
+    if(fadein)						// fade-in volume setting
+      setvolume(chan,fadein*2,fadein*2);
+
+    if(!note)						// note handling
+      continue;
+    note--;
+
+    if ((note == 0x7f-1) || ((note/12) & ~7)) {    // pause (7fh)
+      adl_freq[chan] &= ~32;
+      opl->write(0xb0 + chan,adl_freq[chan]);
+      continue;
+    }
+
+    // play the note
+    if(mtkmode)		// imitate MPU-401 Trakker bug
+      note--;
+    Okt = ((note/12) & 7) << 2;
+    Fnr = note_table[(note % 12)] + instr[inst][11] + channel[chan].slide;
+    channel[chan].freq = Fnr;
+    if(!mode6 || chan < 6)
+      adl_freq[chan] = Okt | 32;
+    else
+      adl_freq[chan] = Okt;		// never set key for drums
+    opl->write(0xb0 + chan, 0);
+    setfreq(chan,Fnr);
+    if(mode6) {
+      switch(chan) {		// play drums
+      case 6: opl->write(0xbd,bd & ~16); bd |= 48; break;	// bass drum
+      case 7: opl->write(0xbd,bd & ~1); bd |= 33; break;	// hihat
+      case 8: opl->write(0xbd,bd & ~2); bd |= 34; break;	// cymbal
+      }
+      opl->write(0xbd,bd);
+    }
+  }
+
+  del = speed;		// player speed-timing
+  if(pattbreak) {		// do post-effect handling
+    pattpos=0;			// pattern break!
+    pattbreak=0;
+    songpos++;
+    songpos %= 50;
+    if(!songpos)
+      songend = 1;
+  } else {
+    pattpos++;
+    pattpos &= 63;		// advance in pattern data
+    if (!pattpos) {
+      songpos++;
+      songpos %= 50;
+      if(!songpos)
+	songend = 1;
+    }
+  }
+  return !songend;		// still playing
+}
+
+void ChscPlayer::rewind(int subsong)
+{
+  int i;								// counter
+
+  // rewind HSC player
+  pattpos = 0; songpos = 0; pattbreak = 0; speed = 2;
+  del = 1; songend = 0; mode6 = 0; bd = 0; fadein = 0;
+
+  opl->init();						// reset OPL chip
+  opl->write(1,32); opl->write(8,128); opl->write(0xbd,0);
+
+  for(i=0;i<9;i++)
+    setinstr((char) i,(char) i);	// init channels
+}
+
+unsigned int ChscPlayer::getpatterns()
+{
+  unsigned char	poscnt,pattcnt=0;
+
+  // count patterns
+  for(poscnt=0;poscnt<51 && song[poscnt] != 0xff;poscnt++)
+    if(song[poscnt] > pattcnt)
+      pattcnt = song[poscnt];
+
+  return (pattcnt+1);
+}
+
+unsigned int ChscPlayer::getorders()
+{
+  unsigned char poscnt;
+
+  // count positions
+  for(poscnt=0;poscnt<51;poscnt++)
+    if(song[poscnt] == 0xff)
+      break;
+
+  return poscnt;
+}
+
+unsigned int ChscPlayer::getinstruments()
+{
+  unsigned char	instcnt,instnum=0,i;
+  bool		isinst;
+
+  // count instruments
+  for(instcnt=0;instcnt<128;instcnt++) {
+    isinst = false;
+    for(i=0;i<12;i++)
+      if(instr[instcnt][i])
+	isinst = true;
+    if(isinst)
+      instnum++;
+  }
+
+  return instnum;
+}
+
+/*** private methods *************************************/
+
+void ChscPlayer::setfreq(unsigned char chan, unsigned short freq)
+{
+  adl_freq[chan] = (adl_freq[chan] & ~3) | (freq >> 8);
+
+  opl->write(0xa0 + chan, freq & 0xff);
+  opl->write(0xb0 + chan, adl_freq[chan]);
+}
+
+void ChscPlayer::setvolume(unsigned char chan, int volc, int volm)
+{
+  unsigned char	*ins = instr[channel[chan].inst];
+  char		op = op_table[chan];
+
+  opl->write(0x43 + op,volc | (ins[2] & ~63));
+  if (ins[8] & 1)							// carrier
+    opl->write(0x40 + op,volm | (ins[3] & ~63));
+  else
+    opl->write(0x40 + op, ins[3]);		// modulator
+}
+
+void ChscPlayer::setinstr(unsigned char chan, unsigned char insnr)
+{
+  unsigned char	*ins = instr[insnr];
+  char		op = op_table[chan];
+
+  channel[chan].inst = insnr;		// set internal instrument
+  opl->write(0xb0 + chan,0);			// stop old note
+
+  // set instrument
+  opl->write(0xc0 + chan, ins[8]);
+  opl->write(0x23 + op, ins[0]);        // carrier
+  opl->write(0x20 + op, ins[1]);        // modulator
+  opl->write(0x63 + op, ins[4]);        // bits 0..3 = decay; 4..7 = attack
+  opl->write(0x60 + op, ins[5]);
+  opl->write(0x83 + op, ins[6]);        // 0..3 = release; 4..7 = sustain
+  opl->write(0x80 + op, ins[7]);
+  opl->write(0xe3 + op, ins[9]);        // bits 0..1 = Wellenform
+  opl->write(0xe0 + op, ins[10]);
+  setvolume(chan, ins[2] & 63, ins[3] & 63);
+}
--- a/Plugins/Input/adplug/core/hsp.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * hsp.cpp - HSP Loader by Simon Peter <dn.tlp@gmx.net>
- */
-
-#include <string.h>
-
-#include "hsp.h"
-
-CPlayer *ChspLoader::factory(Copl *newopl)
-{
-  return new ChspLoader(newopl);
-}
-
-bool ChspLoader::load(const std::string &filename, const CFileProvider &fp)
-{
-  binistream	*f = fp.open(filename); if(!f) return false;
-  unsigned long	i, j, orgsize, filesize;
-  unsigned char	*cmp, *org;
-
-  // file validation section
-  if(!fp.extension(filename, ".hsp")) { fp.close(f); return false; }
-
-  filesize = fp.filesize(f);
-  orgsize = f->readInt(2);
-  if(orgsize > 59187) { fp.close(f); return false; }
-
-  // load section
-  cmp = new unsigned char[filesize];
-  for(i = 0; i < filesize; i++) cmp[i] = f->readInt(1);
-  fp.close(f);
-
-  org = new unsigned char[orgsize];
-  for(i = 0, j = 0; i < filesize; j += cmp[i], i += 2) {	// RLE decompress
-    if(j >= orgsize) break;	// memory boundary check
-    memset(org + j, cmp[i + 1], j + cmp[i] < orgsize ? cmp[i] : orgsize - j - 1);
-  }
-  delete [] cmp;
-
-  memcpy(instr, org, 128 * 12);		// instruments
-  for(i = 0; i < 128; i++) {		// correct instruments
-    instr[i][2] ^= (instr[i][2] & 0x40) << 1;
-    instr[i][3] ^= (instr[i][3] & 0x40) << 1;
-    instr[i][11] >>= 4;		// slide
-  }
-  memcpy(song, org + 128 * 12, 51);	// tracklist
-  memcpy(patterns, org + 128 * 12 + 51, orgsize - 128 * 12 - 51);	// patterns
-  delete [] org;
-
-  rewind(0);
-  return true;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/hsp.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,68 @@
+/*
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * hsp.cpp - HSP Loader by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include <string.h>
+
+#include "hsp.h"
+
+CPlayer *ChspLoader::factory(Copl *newopl)
+{
+  return new ChspLoader(newopl);
+}
+
+bool ChspLoader::load(const std::string &filename, const CFileProvider &fp)
+{
+  binistream	*f = fp.open(filename); if(!f) return false;
+  unsigned long	i, j, orgsize, filesize;
+  unsigned char	*cmp, *org;
+
+  // file validation section
+  if(!fp.extension(filename, ".hsp")) { fp.close(f); return false; }
+
+  filesize = fp.filesize(f);
+  orgsize = f->readInt(2);
+  if(orgsize > 59187) { fp.close(f); return false; }
+
+  // load section
+  cmp = new unsigned char[filesize];
+  for(i = 0; i < filesize; i++) cmp[i] = f->readInt(1);
+  fp.close(f);
+
+  org = new unsigned char[orgsize];
+  for(i = 0, j = 0; i < filesize; j += cmp[i], i += 2) {	// RLE decompress
+    if(j >= orgsize) break;	// memory boundary check
+    memset(org + j, cmp[i + 1], j + cmp[i] < orgsize ? cmp[i] : orgsize - j - 1);
+  }
+  delete [] cmp;
+
+  memcpy(instr, org, 128 * 12);		// instruments
+  for(i = 0; i < 128; i++) {		// correct instruments
+    instr[i][2] ^= (instr[i][2] & 0x40) << 1;
+    instr[i][3] ^= (instr[i][3] & 0x40) << 1;
+    instr[i][11] >>= 4;		// slide
+  }
+  memcpy(song, org + 128 * 12, 51);	// tracklist
+  memcpy(patterns, org + 128 * 12 + 51, orgsize - 128 * 12 - 51);	// patterns
+  delete [] org;
+
+  rewind(0);
+  return true;
+}
--- a/Plugins/Input/adplug/core/hybrid.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,248 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * [xad] HYBRID player, by Riven the Mage <riven@ok.ru>
- */
-
-/*
-    - discovery -
-
-  file(s) : HYBRID.EXE
-     type : Hybrid cracktro for Apache Longbow CD-RIP
-     tune : from 'Mig-29 Super Fulcrum' game by Domark
-   player : from 'Mig-29 Super Fulcrum' game by Domark
-*/
-
-#include "hybrid.h"
-#include "debug.h"
-
-const unsigned char CxadhybridPlayer::hyb_adlib_registers[99] = 
-{
-  0xE0, 0x60, 0x80, 0x20, 0x40, 0xE3, 0x63, 0x83, 0x23, 0x43, 0xC0,
-  0xE1, 0x61, 0x81, 0x21, 0x41, 0xE4, 0x64, 0x84, 0x24, 0x44, 0xC1,
-  0xE2, 0x62, 0x82, 0x22, 0x42, 0xE5, 0x65, 0x85, 0x25, 0x45, 0xC2,
-  0xE8, 0x68, 0x88, 0x28, 0x48, 0xEB, 0x6B, 0x8B, 0x2B, 0x4B, 0xC3,
-  0xE9, 0x69, 0x89, 0x29, 0x49, 0xEC, 0x6C, 0x8C, 0x2C, 0x4C, 0xC4,
-  0xEA, 0x6A, 0x8A, 0x2A, 0x4A, 0xED, 0x6D, 0x8D, 0x2D, 0x4D, 0xC5,
-  0xF0, 0x70, 0x90, 0x30, 0x50, 0xF3, 0x73, 0x93, 0x33, 0x53, 0xC6,
-  0xF1, 0x71, 0x91, 0x31, 0x51, 0xF4, 0x74, 0x94, 0x34, 0x54, 0xC7,
-  0xF2, 0x72, 0x92, 0x32, 0x52, 0xF5, 0x75, 0x95, 0x35, 0x55, 0xC8
-};
-
-const unsigned short CxadhybridPlayer::hyb_notes[98] =
-{
-  0x0000, 0x0000,
-  0x016B, 0x0181, 0x0198, 0x01B0, 0x01CA, 0x01E5, 0x0202, 0x0220, 0x0241, 0x0263, 0x0287, 0x02AE,
-  0x056B, 0x0581, 0x0598, 0x05B0, 0x05CA, 0x05E5, 0x0602, 0x0620, 0x0641, 0x0663, 0x0687, 0x06AE,
-  0x096B, 0x0981, 0x0998, 0x09B0, 0x09CA, 0x09E5, 0x0A02, 0x0A20, 0x0A41, 0x0A63, 0x0A87, 0x0AAE,
-  0x0D6B, 0x0D81, 0x0D98, 0x0DB0, 0x0DCA, 0x0DE5, 0x0E02, 0x0E20, 0x0E41, 0x0E63, 0x0E87, 0x0EAE,
-  0x116B, 0x1181, 0x1198, 0x11B0, 0x11CA, 0x11E5, 0x1202, 0x1220, 0x1241, 0x1263, 0x1287, 0x12AE,
-  0x156B, 0x1581, 0x1598, 0x15B0, 0x15CA, 0x15E5, 0x1602, 0x1620, 0x1641, 0x1663, 0x1687, 0x16AE,
-  0x196B, 0x1981, 0x1998, 0x19B0, 0x19CA, 0x19E5, 0x1A02, 0x1A20, 0x1A41, 0x1A63, 0x1A87, 0x1AAE,
-  0x1D6B, 0x1D81, 0x1D98, 0x1DB0, 0x1DCA, 0x1DE5, 0x1E02, 0x1E20, 0x1E41, 0x1E63, 0x1E87, 0x1EAE
-};
-
-const unsigned char CxadhybridPlayer::hyb_default_instrument[11] = 
-{
-  0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00
-};
-
-CPlayer *CxadhybridPlayer::factory(Copl *newopl)
-{
-  return new CxadhybridPlayer(newopl);
-}
-
-bool CxadhybridPlayer::xadplayer_load()
-{
-  if(xad.fmt != HYBRID)
-    return false;
-
-  // load instruments
-  hyb.inst = (hyb_instrument *)&tune[0];
-
-  // load order
-  hyb.order = &tune[0x1D4];
-
-  return true;
-}
-
-void CxadhybridPlayer::xadplayer_rewind(int subsong)
-{
-  int i;
-
-  hyb.order_pos = 0;
-  hyb.pattern_pos = 0;
-
-  hyb.speed = 6;
-  hyb.speed_counter = 1;
-
-  plr.speed = 1;
-
-  // init channel data
-  for(i=0;i<9;i++)
-  {
-    hyb.channel[i].freq       = 0x2000;
-    hyb.channel[i].freq_slide = 0x0000;
-  }
-
-  // basic OPL init
-  opl_write(0x01, 0x20);
-  opl_write(0xBD, 0x40);
-  opl_write(0x08, 0x00);
-
-  // init OPL channels
-  for(i=0;i<9;i++)
-  {
-    for(int j=0;j<11;j++)
-      opl_write(hyb_adlib_registers[i*11+j], 0x00 /* hyb_default_instrument[j] */ );
-
-	opl_write(0xA0+i, 0x00);
-	opl_write(0xB0+i, 0x20);
-  }
-}
-
-void CxadhybridPlayer::xadplayer_update()
-{
-  int i,j;
-  unsigned char patpos,ordpos;
-
-  if (--hyb.speed_counter)
-    goto update_slides;
-
-  hyb.speed_counter = hyb.speed;
-
-  patpos = hyb.pattern_pos;
-  ordpos = hyb.order_pos;
-
-  // 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 = (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 );
-#endif
-
-    // calculate variables
-	unsigned char  note  =   event >> 9;
-	unsigned char  ins   = ((event & 0x01F0) >> 4);
-    unsigned char  slide =   event & 0x000F;
-
-    // play event
-    switch(note)
-    {
-      case 0x7D: // 0x7D: Set Speed
-        hyb.speed = event & 0xFF;
-        break;
-      case 0x7E: // 0x7E: Jump Position
-        hyb.order_pos = event & 0xFF;
-        hyb.pattern_pos = 0x3F;
-
-        // jumpback ?
-        if (hyb.order_pos <= ordpos)
-          plr.looping = 1;
-
-        break;
-      case 0x7F: // 0x7F: Pattern Break
-        hyb.pattern_pos = 0x3F;
-        break;
-      default:
-
-        // is instrument ?
-        if (ins)
-          for(j=0;j<11;j++)
-            opl_write(hyb_adlib_registers[i*11+j], *((unsigned char *)&hyb.inst[ins-1] + 7 + j)); // +7 = skip name...
-
-        // is note ?
-        if (note)
-        {
-          hyb.channel[i].freq = hyb_notes[note];
-          hyb.channel[i].freq_slide = 0;
-        }
-
-        // is slide ?
-        if (slide)
-        {
-          hyb.channel[i].freq_slide = (((slide >> 3) * -1) * (slide & 7)) << 1;
-    
-          if (slide & 0x80)
-            slide = -(slide & 7);
-        }
-
-        // set frequency
-        if (!(hyb.channel[i].freq & 0x2000))
-        {
-          opl_write(0xA0+i, hyb.channel[i].freq & 0xFF);
-          opl_write(0xB0+i, hyb.channel[i].freq >> 8);
-
-          hyb.channel[i].freq |= 0x2000;
-
-          opl_write(0xA0+i, hyb.channel[i].freq & 0xFF);
-          opl_write(0xB0+i, hyb.channel[i].freq >> 8);
-        }
-
-        break;
-    }
-  }
-
-  hyb.pattern_pos++;
-
-  // end of pattern ?
-  if (hyb.pattern_pos >= 0x40)
-  {
-    hyb.pattern_pos = 0;
-
-    hyb.order_pos++;
-  }
-
-update_slides:
-#ifdef DEBUG
-   AdPlug_LogWrite("slides:\n");
-#endif
-  // update fine frequency slides
-  for(i=0;i<9;i++)
-    if (hyb.channel[i].freq_slide)
-    {
-      hyb.channel[i].freq = (((hyb.channel[i].freq & 0x1FFF) + hyb.channel[i].freq_slide) & 0x1FFF) | 0x2000;
-
-      opl_write(0xA0+i, hyb.channel[i].freq & 0xFF);
-      opl_write(0xB0+i, hyb.channel[i].freq >> 8);
-    }
-}
-
-float CxadhybridPlayer::xadplayer_getrefresh()
-{
-  return 50.0f;
-}
-
-std::string CxadhybridPlayer::xadplayer_gettype()
-{
-  return (std::string("xad: hybrid player"));
-}
-
-std::string CxadhybridPlayer::xadplayer_getinstrument(unsigned int i)
-{
-  return (std::string(hyb.inst[i].name,7));
-}
-
-unsigned int CxadhybridPlayer::xadplayer_getinstruments()
-{
-  return 26;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/hybrid.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,248 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * [xad] HYBRID player, by Riven the Mage <riven@ok.ru>
+ */
+
+/*
+    - discovery -
+
+  file(s) : HYBRID.EXE
+     type : Hybrid cracktro for Apache Longbow CD-RIP
+     tune : from 'Mig-29 Super Fulcrum' game by Domark
+   player : from 'Mig-29 Super Fulcrum' game by Domark
+*/
+
+#include "hybrid.h"
+#include "debug.h"
+
+const unsigned char CxadhybridPlayer::hyb_adlib_registers[99] = 
+{
+  0xE0, 0x60, 0x80, 0x20, 0x40, 0xE3, 0x63, 0x83, 0x23, 0x43, 0xC0,
+  0xE1, 0x61, 0x81, 0x21, 0x41, 0xE4, 0x64, 0x84, 0x24, 0x44, 0xC1,
+  0xE2, 0x62, 0x82, 0x22, 0x42, 0xE5, 0x65, 0x85, 0x25, 0x45, 0xC2,
+  0xE8, 0x68, 0x88, 0x28, 0x48, 0xEB, 0x6B, 0x8B, 0x2B, 0x4B, 0xC3,
+  0xE9, 0x69, 0x89, 0x29, 0x49, 0xEC, 0x6C, 0x8C, 0x2C, 0x4C, 0xC4,
+  0xEA, 0x6A, 0x8A, 0x2A, 0x4A, 0xED, 0x6D, 0x8D, 0x2D, 0x4D, 0xC5,
+  0xF0, 0x70, 0x90, 0x30, 0x50, 0xF3, 0x73, 0x93, 0x33, 0x53, 0xC6,
+  0xF1, 0x71, 0x91, 0x31, 0x51, 0xF4, 0x74, 0x94, 0x34, 0x54, 0xC7,
+  0xF2, 0x72, 0x92, 0x32, 0x52, 0xF5, 0x75, 0x95, 0x35, 0x55, 0xC8
+};
+
+const unsigned short CxadhybridPlayer::hyb_notes[98] =
+{
+  0x0000, 0x0000,
+  0x016B, 0x0181, 0x0198, 0x01B0, 0x01CA, 0x01E5, 0x0202, 0x0220, 0x0241, 0x0263, 0x0287, 0x02AE,
+  0x056B, 0x0581, 0x0598, 0x05B0, 0x05CA, 0x05E5, 0x0602, 0x0620, 0x0641, 0x0663, 0x0687, 0x06AE,
+  0x096B, 0x0981, 0x0998, 0x09B0, 0x09CA, 0x09E5, 0x0A02, 0x0A20, 0x0A41, 0x0A63, 0x0A87, 0x0AAE,
+  0x0D6B, 0x0D81, 0x0D98, 0x0DB0, 0x0DCA, 0x0DE5, 0x0E02, 0x0E20, 0x0E41, 0x0E63, 0x0E87, 0x0EAE,
+  0x116B, 0x1181, 0x1198, 0x11B0, 0x11CA, 0x11E5, 0x1202, 0x1220, 0x1241, 0x1263, 0x1287, 0x12AE,
+  0x156B, 0x1581, 0x1598, 0x15B0, 0x15CA, 0x15E5, 0x1602, 0x1620, 0x1641, 0x1663, 0x1687, 0x16AE,
+  0x196B, 0x1981, 0x1998, 0x19B0, 0x19CA, 0x19E5, 0x1A02, 0x1A20, 0x1A41, 0x1A63, 0x1A87, 0x1AAE,
+  0x1D6B, 0x1D81, 0x1D98, 0x1DB0, 0x1DCA, 0x1DE5, 0x1E02, 0x1E20, 0x1E41, 0x1E63, 0x1E87, 0x1EAE
+};
+
+const unsigned char CxadhybridPlayer::hyb_default_instrument[11] = 
+{
+  0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xFF, 0x00, 0xFF, 0x00
+};
+
+CPlayer *CxadhybridPlayer::factory(Copl *newopl)
+{
+  return new CxadhybridPlayer(newopl);
+}
+
+bool CxadhybridPlayer::xadplayer_load()
+{
+  if(xad.fmt != HYBRID)
+    return false;
+
+  // load instruments
+  hyb.inst = (hyb_instrument *)&tune[0];
+
+  // load order
+  hyb.order = &tune[0x1D4];
+
+  return true;
+}
+
+void CxadhybridPlayer::xadplayer_rewind(int subsong)
+{
+  int i;
+
+  hyb.order_pos = 0;
+  hyb.pattern_pos = 0;
+
+  hyb.speed = 6;
+  hyb.speed_counter = 1;
+
+  plr.speed = 1;
+
+  // init channel data
+  for(i=0;i<9;i++)
+  {
+    hyb.channel[i].freq       = 0x2000;
+    hyb.channel[i].freq_slide = 0x0000;
+  }
+
+  // basic OPL init
+  opl_write(0x01, 0x20);
+  opl_write(0xBD, 0x40);
+  opl_write(0x08, 0x00);
+
+  // init OPL channels
+  for(i=0;i<9;i++)
+  {
+    for(int j=0;j<11;j++)
+      opl_write(hyb_adlib_registers[i*11+j], 0x00 /* hyb_default_instrument[j] */ );
+
+	opl_write(0xA0+i, 0x00);
+	opl_write(0xB0+i, 0x20);
+  }
+}
+
+void CxadhybridPlayer::xadplayer_update()
+{
+  int i,j;
+  unsigned char patpos,ordpos;
+
+  if (--hyb.speed_counter)
+    goto update_slides;
+
+  hyb.speed_counter = hyb.speed;
+
+  patpos = hyb.pattern_pos;
+  ordpos = hyb.order_pos;
+
+  // 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 = (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 );
+#endif
+
+    // calculate variables
+	unsigned char  note  =   event >> 9;
+	unsigned char  ins   = ((event & 0x01F0) >> 4);
+    unsigned char  slide =   event & 0x000F;
+
+    // play event
+    switch(note)
+    {
+      case 0x7D: // 0x7D: Set Speed
+        hyb.speed = event & 0xFF;
+        break;
+      case 0x7E: // 0x7E: Jump Position
+        hyb.order_pos = event & 0xFF;
+        hyb.pattern_pos = 0x3F;
+
+        // jumpback ?
+        if (hyb.order_pos <= ordpos)
+          plr.looping = 1;
+
+        break;
+      case 0x7F: // 0x7F: Pattern Break
+        hyb.pattern_pos = 0x3F;
+        break;
+      default:
+
+        // is instrument ?
+        if (ins)
+          for(j=0;j<11;j++)
+            opl_write(hyb_adlib_registers[i*11+j], *((unsigned char *)&hyb.inst[ins-1] + 7 + j)); // +7 = skip name...
+
+        // is note ?
+        if (note)
+        {
+          hyb.channel[i].freq = hyb_notes[note];
+          hyb.channel[i].freq_slide = 0;
+        }
+
+        // is slide ?
+        if (slide)
+        {
+          hyb.channel[i].freq_slide = (((slide >> 3) * -1) * (slide & 7)) << 1;
+    
+          if (slide & 0x80)
+            slide = -(slide & 7);
+        }
+
+        // set frequency
+        if (!(hyb.channel[i].freq & 0x2000))
+        {
+          opl_write(0xA0+i, hyb.channel[i].freq & 0xFF);
+          opl_write(0xB0+i, hyb.channel[i].freq >> 8);
+
+          hyb.channel[i].freq |= 0x2000;
+
+          opl_write(0xA0+i, hyb.channel[i].freq & 0xFF);
+          opl_write(0xB0+i, hyb.channel[i].freq >> 8);
+        }
+
+        break;
+    }
+  }
+
+  hyb.pattern_pos++;
+
+  // end of pattern ?
+  if (hyb.pattern_pos >= 0x40)
+  {
+    hyb.pattern_pos = 0;
+
+    hyb.order_pos++;
+  }
+
+update_slides:
+#ifdef DEBUG
+   AdPlug_LogWrite("slides:\n");
+#endif
+  // update fine frequency slides
+  for(i=0;i<9;i++)
+    if (hyb.channel[i].freq_slide)
+    {
+      hyb.channel[i].freq = (((hyb.channel[i].freq & 0x1FFF) + hyb.channel[i].freq_slide) & 0x1FFF) | 0x2000;
+
+      opl_write(0xA0+i, hyb.channel[i].freq & 0xFF);
+      opl_write(0xB0+i, hyb.channel[i].freq >> 8);
+    }
+}
+
+float CxadhybridPlayer::xadplayer_getrefresh()
+{
+  return 50.0f;
+}
+
+std::string CxadhybridPlayer::xadplayer_gettype()
+{
+  return (std::string("xad: hybrid player"));
+}
+
+std::string CxadhybridPlayer::xadplayer_getinstrument(unsigned int i)
+{
+  return (std::string(hyb.inst[i].name,7));
+}
+
+unsigned int CxadhybridPlayer::xadplayer_getinstruments()
+{
+  return 26;
+}
--- a/Plugins/Input/adplug/core/hyp.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * [xad] HYP player, by Riven the Mage <riven@ok.ru>
- */
-
-/*
-    - discovery -
-
-  file(s) : HT-EF2.COM, HT-EF3.COM
-     type : Eiserne Front BBStro
-     tune : by Shadowdancer [Hypnosis]
-   player : by (?)Hetero [LKCC/SAC]
-*/
-
-#include "hyp.h"
-#include "debug.h"
-
-const unsigned char CxadhypPlayer::hyp_adlib_registers[99] =
-{
-  0x20, 0x23, 0x40, 0x43, 0x60, 0x63, 0x80, 0x83, 0xA0, 0xB0, 0xC0,
-  0x21, 0x24, 0x41, 0x44, 0x61, 0x64, 0x81, 0x84, 0xA1, 0xB1, 0xC1,
-  0x22, 0x25, 0x42, 0x45, 0x62, 0x65, 0x82, 0x85, 0xA2, 0xB2, 0xC2,
-  0x28, 0x2B, 0x48, 0x4B, 0x68, 0x6B, 0x88, 0x8B, 0xA3, 0xB3, 0xC3,
-  0x29, 0x2C, 0x49, 0x4C, 0x69, 0x6C, 0x89, 0x8C, 0xA4, 0xB4, 0xC4,
-  0x2A, 0x2D, 0x4A, 0x4D, 0x6A, 0x6D, 0x8A, 0x8D, 0xA5, 0xB5, 0xC5,
-  0x30, 0x33, 0x50, 0x53, 0x70, 0x73, 0x90, 0x93, 0xA6, 0xB6, 0xC6,
-  0x31, 0x34, 0x51, 0x54, 0x71, 0x74, 0x91, 0x94, 0xA7, 0xB7, 0xC7,
-  0x32, 0x35, 0x52, 0x55, 0x72, 0x75, 0x92, 0x95, 0xA8, 0xB8, 0xC8
-};
-
-const unsigned short CxadhypPlayer::hyp_notes[73] =
-{
-  0x0000, // by riven
-  0x0956, 0x096B, 0x0980, 0x0998, 0x09B1, 0x09C9, 0x09E5, 0x0A03, 0x0A21,
-  0x0A41, 0x0A63, 0x0A86, 0x0D56, 0x0D6B, 0x0D80, 0x0D98, 0x0DB1, 0x0DC9,
-  0x0DE5, 0x0E03, 0x0E21, 0x0E41, 0x0E63, 0x0E86, 0x1156, 0x116B, 0x1180,
-  0x1198, 0x11B1, 0x11C9, 0x11E5, 0x1203, 0x1221, 0x1241, 0x1263, 0x1286,
-  0x1556, 0x156B, 0x1580, 0x1598, 0x15B1, 0x15C9, 0x15E5, 0x1603, 0x1621,
-  0x1641, 0x1663, 0x1686, 0x1956, 0x196B, 0x1980, 0x1998, 0x19B1, 0x19C9,
-  0x19E5, 0x1A03, 0x1A21, 0x1A41, 0x1A63, 0x1A86, 0x1D56, 0x1D6B, 0x1D80,
-  0x1D98, 0x1DB1, 0x1DC9, 0x1DE5, 0x1E03, 0x1E21, 0x1E41, 0x1E63, 0x1E86
-};
-
-CPlayer *CxadhypPlayer::factory(Copl *newopl)
-{
-  return new CxadhypPlayer(newopl);
-}
-
-void CxadhypPlayer::xadplayer_rewind(int subsong)
-{
-  int i;
-
-  plr.speed = tune[5];
-
-  opl_write(0xBD,0xC0);
-
-  for(i=0; i<9; i++)
-    adlib[0xB0+i] = 0;
-
-  // define instruments
-  for(i=0; i<99; i++)
-    opl_write(hyp_adlib_registers[i], tune[6+i]);
-
-  hyp.pointer = 0x69;
-}
-
-void CxadhypPlayer::xadplayer_update()
-{
-  for(int i=0; i<9; i++)
-  {
-    unsigned char event = tune[hyp.pointer++];
-
-    if (event)
-    {
-      unsigned short freq = hyp_notes[event & 0x3F];
-
-      unsigned char lofreq = (freq & 0xFF);
-      unsigned char hifreq = (freq >> 8);
-
-      opl_write(0xB0+i, adlib[0xB0+i]);
-
-      if (!(event & 0x40))
-      {
-        opl_write(0xA0+i, lofreq);
-        opl_write(0xB0+i, hifreq | 0x20);
-      }
-
-      adlib[0xB0+i] &= 0xDF;
-    }
-  }
-
-  hyp.pointer += 3;
-
-  if (hyp.pointer >= tune_size)
-  {
-    hyp.pointer = 0x69;
-    plr.looping = 1;
-  }
-}
-
-float CxadhypPlayer::xadplayer_getrefresh()
-{
-  return 60.0f;
-}
-
-std::string CxadhypPlayer::xadplayer_gettype()
-{
-  return std::string("xad: hypnosis player");
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/hyp.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,125 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * [xad] HYP player, by Riven the Mage <riven@ok.ru>
+ */
+
+/*
+    - discovery -
+
+  file(s) : HT-EF2.COM, HT-EF3.COM
+     type : Eiserne Front BBStro
+     tune : by Shadowdancer [Hypnosis]
+   player : by (?)Hetero [LKCC/SAC]
+*/
+
+#include "hyp.h"
+#include "debug.h"
+
+const unsigned char CxadhypPlayer::hyp_adlib_registers[99] =
+{
+  0x20, 0x23, 0x40, 0x43, 0x60, 0x63, 0x80, 0x83, 0xA0, 0xB0, 0xC0,
+  0x21, 0x24, 0x41, 0x44, 0x61, 0x64, 0x81, 0x84, 0xA1, 0xB1, 0xC1,
+  0x22, 0x25, 0x42, 0x45, 0x62, 0x65, 0x82, 0x85, 0xA2, 0xB2, 0xC2,
+  0x28, 0x2B, 0x48, 0x4B, 0x68, 0x6B, 0x88, 0x8B, 0xA3, 0xB3, 0xC3,
+  0x29, 0x2C, 0x49, 0x4C, 0x69, 0x6C, 0x89, 0x8C, 0xA4, 0xB4, 0xC4,
+  0x2A, 0x2D, 0x4A, 0x4D, 0x6A, 0x6D, 0x8A, 0x8D, 0xA5, 0xB5, 0xC5,
+  0x30, 0x33, 0x50, 0x53, 0x70, 0x73, 0x90, 0x93, 0xA6, 0xB6, 0xC6,
+  0x31, 0x34, 0x51, 0x54, 0x71, 0x74, 0x91, 0x94, 0xA7, 0xB7, 0xC7,
+  0x32, 0x35, 0x52, 0x55, 0x72, 0x75, 0x92, 0x95, 0xA8, 0xB8, 0xC8
+};
+
+const unsigned short CxadhypPlayer::hyp_notes[73] =
+{
+  0x0000, // by riven
+  0x0956, 0x096B, 0x0980, 0x0998, 0x09B1, 0x09C9, 0x09E5, 0x0A03, 0x0A21,
+  0x0A41, 0x0A63, 0x0A86, 0x0D56, 0x0D6B, 0x0D80, 0x0D98, 0x0DB1, 0x0DC9,
+  0x0DE5, 0x0E03, 0x0E21, 0x0E41, 0x0E63, 0x0E86, 0x1156, 0x116B, 0x1180,
+  0x1198, 0x11B1, 0x11C9, 0x11E5, 0x1203, 0x1221, 0x1241, 0x1263, 0x1286,
+  0x1556, 0x156B, 0x1580, 0x1598, 0x15B1, 0x15C9, 0x15E5, 0x1603, 0x1621,
+  0x1641, 0x1663, 0x1686, 0x1956, 0x196B, 0x1980, 0x1998, 0x19B1, 0x19C9,
+  0x19E5, 0x1A03, 0x1A21, 0x1A41, 0x1A63, 0x1A86, 0x1D56, 0x1D6B, 0x1D80,
+  0x1D98, 0x1DB1, 0x1DC9, 0x1DE5, 0x1E03, 0x1E21, 0x1E41, 0x1E63, 0x1E86
+};
+
+CPlayer *CxadhypPlayer::factory(Copl *newopl)
+{
+  return new CxadhypPlayer(newopl);
+}
+
+void CxadhypPlayer::xadplayer_rewind(int subsong)
+{
+  int i;
+
+  plr.speed = tune[5];
+
+  opl_write(0xBD,0xC0);
+
+  for(i=0; i<9; i++)
+    adlib[0xB0+i] = 0;
+
+  // define instruments
+  for(i=0; i<99; i++)
+    opl_write(hyp_adlib_registers[i], tune[6+i]);
+
+  hyp.pointer = 0x69;
+}
+
+void CxadhypPlayer::xadplayer_update()
+{
+  for(int i=0; i<9; i++)
+  {
+    unsigned char event = tune[hyp.pointer++];
+
+    if (event)
+    {
+      unsigned short freq = hyp_notes[event & 0x3F];
+
+      unsigned char lofreq = (freq & 0xFF);
+      unsigned char hifreq = (freq >> 8);
+
+      opl_write(0xB0+i, adlib[0xB0+i]);
+
+      if (!(event & 0x40))
+      {
+        opl_write(0xA0+i, lofreq);
+        opl_write(0xB0+i, hifreq | 0x20);
+      }
+
+      adlib[0xB0+i] &= 0xDF;
+    }
+  }
+
+  hyp.pointer += 3;
+
+  if (hyp.pointer >= tune_size)
+  {
+    hyp.pointer = 0x69;
+    plr.looping = 1;
+  }
+}
+
+float CxadhypPlayer::xadplayer_getrefresh()
+{
+  return 60.0f;
+}
+
+std::string CxadhypPlayer::xadplayer_gettype()
+{
+  return std::string("xad: hypnosis player");
+}
--- a/Plugins/Input/adplug/core/imf.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,196 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * imf.cpp - IMF Player by Simon Peter <dn.tlp@gmx.net>
- *
- * FILE FORMAT:
- * There seem to be 2 different flavors of IMF formats out there. One version
- * contains just the raw IMF music data. In this case, the first word of the
- * file is always 0 (because the music data starts this way). This is already
- * the music data! So read in the entire file and play it.
- *
- * If this word is greater than 0, it specifies the size of the following
- * song data in bytes. In this case, the file has a footer that contains
- * arbitrary infos about it. Mostly, this is plain ASCII text with some words
- * of the author. Read and play the specified amount of song data and display
- * the remaining data as ASCII text.
- *
- * NOTES:
- * This player handles the two above mentioned formats, as well as a third
- * type, invented by Martin Fernandez <mfernan@cnba.uba.ar>, that's got a
- * proper header to add title/game name information. After the header starts
- * the normal IMF file in one of the two above mentioned formats.
- *
- * This player also handles a special footer format by Adam Nielsen,
- * which has defined fields of information about the song, the author
- * and more.
- */
-
-#include <string.h>
-
-#include "imf.h"
-#include "database.h"
-
-/*** public methods *************************************/
-
-CPlayer *CimfPlayer::factory(Copl *newopl)
-{
-  return new CimfPlayer(newopl);
-}
-
-bool CimfPlayer::load(const std::string &filename, const CFileProvider &fp)
-{
-  binistream *f = fp.open(filename); if(!f) return false;
-  unsigned long fsize, flsize, mfsize = 0;
-  unsigned int i;
-
-  // file validation section
-  {
-    char	header[5];
-    int		version;
-
-    f->readString(header, 5);
-    version = f->readInt(1);
-
-    if(strncmp(header, "ADLIB", 5) || version != 1) {
-      if(!fp.extension(filename, ".imf") && !fp.extension(filename, ".wlf")) {
-	// It's no IMF file at all
-	fp.close(f);
-	return false;
-      } else
-	f->seek(0);	// It's a normal IMF file
-    } else {
-      // It's a IMF file with header
-      track_name = f->readString('\0');
-      game_name = f->readString('\0');
-      f->ignore(1);
-      mfsize = f->pos() + 2;
-    }
-  }
-
-  // load section
-  if(mfsize)
-    fsize = f->readInt(4);
-  else
-    fsize = f->readInt(2);
-  flsize = fp.filesize(f);
-  if(!fsize) {		// footerless file (raw music data)
-    if(mfsize)
-      f->seek(-4, binio::Add);
-    else
-      f->seek(-2, binio::Add);
-    size = (flsize - mfsize) / 4;
-  } else		// file has got a footer
-    size = fsize / 4;
-
-  data = new Sdata[size];
-  for(i = 0; i < size; i++) {
-    data[i].reg = f->readInt(1); data[i].val = f->readInt(1);
-    data[i].time = f->readInt(2);
-  }
-
-  // read footer, if any
-  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
-    }
-
-  rate = getrate(filename, fp, f);
-  fp.close(f);
-  rewind(0);
-  return true;
-}
-
-bool CimfPlayer::update()
-{
-	do {
-		opl->write(data[pos].reg,data[pos].val);
-		del = data[pos].time;
-		pos++;
-	} while(!del && pos < size);
-
-	if(pos >= size) {
-		pos = 0;
-		songend = true;
-	}
-	else timer = rate / (float)del;
-
-	return !songend;
-}
-
-void CimfPlayer::rewind(int subsong)
-{
-	pos = 0; del = 0; timer = rate; songend = false;
-	opl->init(); opl->write(1,32);	// go to OPL2 mode
-}
-
-std::string CimfPlayer::gettitle()
-{
-  std::string	title;
-
-  title = track_name;
-
-  if(!track_name.empty() && !game_name.empty())
-    title += " - ";
-
-  title += game_name;
-
-  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(const std::string &filename, const CFileProvider &fp, binistream *f)
-{
-  if(db) {	// Database available
-    f->seek(0, binio::Set);
-    CClockRecord *record = (CClockRecord *)db->search(CAdPlugDatabase::CKey(*f));
-    if (record && record->type == CAdPlugDatabase::CRecord::ClockSpeed)
-      return record->clock;
-  }
-
-  // Otherwise the database is either unavailable, or there's no entry for this file
-  if (fp.extension(filename, ".imf")) return 560.0f;
-  if (fp.extension(filename, ".wlf")) return 700.0f;
-  return 700.0f; // default speed for unknown files that aren't .IMF or .WLF
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/imf.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,196 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * imf.cpp - IMF Player by Simon Peter <dn.tlp@gmx.net>
+ *
+ * FILE FORMAT:
+ * There seem to be 2 different flavors of IMF formats out there. One version
+ * contains just the raw IMF music data. In this case, the first word of the
+ * file is always 0 (because the music data starts this way). This is already
+ * the music data! So read in the entire file and play it.
+ *
+ * If this word is greater than 0, it specifies the size of the following
+ * song data in bytes. In this case, the file has a footer that contains
+ * arbitrary infos about it. Mostly, this is plain ASCII text with some words
+ * of the author. Read and play the specified amount of song data and display
+ * the remaining data as ASCII text.
+ *
+ * NOTES:
+ * This player handles the two above mentioned formats, as well as a third
+ * type, invented by Martin Fernandez <mfernan@cnba.uba.ar>, that's got a
+ * proper header to add title/game name information. After the header starts
+ * the normal IMF file in one of the two above mentioned formats.
+ *
+ * This player also handles a special footer format by Adam Nielsen,
+ * which has defined fields of information about the song, the author
+ * and more.
+ */
+
+#include <string.h>
+
+#include "imf.h"
+#include "database.h"
+
+/*** public methods *************************************/
+
+CPlayer *CimfPlayer::factory(Copl *newopl)
+{
+  return new CimfPlayer(newopl);
+}
+
+bool CimfPlayer::load(const std::string &filename, const CFileProvider &fp)
+{
+  binistream *f = fp.open(filename); if(!f) return false;
+  unsigned long fsize, flsize, mfsize = 0;
+  unsigned int i;
+
+  // file validation section
+  {
+    char	header[5];
+    int		version;
+
+    f->readString(header, 5);
+    version = f->readInt(1);
+
+    if(strncmp(header, "ADLIB", 5) || version != 1) {
+      if(!fp.extension(filename, ".imf") && !fp.extension(filename, ".wlf")) {
+	// It's no IMF file at all
+	fp.close(f);
+	return false;
+      } else
+	f->seek(0);	// It's a normal IMF file
+    } else {
+      // It's a IMF file with header
+      track_name = f->readString('\0');
+      game_name = f->readString('\0');
+      f->ignore(1);
+      mfsize = f->pos() + 2;
+    }
+  }
+
+  // load section
+  if(mfsize)
+    fsize = f->readInt(4);
+  else
+    fsize = f->readInt(2);
+  flsize = fp.filesize(f);
+  if(!fsize) {		// footerless file (raw music data)
+    if(mfsize)
+      f->seek(-4, binio::Add);
+    else
+      f->seek(-2, binio::Add);
+    size = (flsize - mfsize) / 4;
+  } else		// file has got a footer
+    size = fsize / 4;
+
+  data = new Sdata[size];
+  for(i = 0; i < size; i++) {
+    data[i].reg = f->readInt(1); data[i].val = f->readInt(1);
+    data[i].time = f->readInt(2);
+  }
+
+  // read footer, if any
+  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
+    }
+
+  rate = getrate(filename, fp, f);
+  fp.close(f);
+  rewind(0);
+  return true;
+}
+
+bool CimfPlayer::update()
+{
+	do {
+		opl->write(data[pos].reg,data[pos].val);
+		del = data[pos].time;
+		pos++;
+	} while(!del && pos < size);
+
+	if(pos >= size) {
+		pos = 0;
+		songend = true;
+	}
+	else timer = rate / (float)del;
+
+	return !songend;
+}
+
+void CimfPlayer::rewind(int subsong)
+{
+	pos = 0; del = 0; timer = rate; songend = false;
+	opl->init(); opl->write(1,32);	// go to OPL2 mode
+}
+
+std::string CimfPlayer::gettitle()
+{
+  std::string	title;
+
+  title = track_name;
+
+  if(!track_name.empty() && !game_name.empty())
+    title += " - ";
+
+  title += game_name;
+
+  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(const std::string &filename, const CFileProvider &fp, binistream *f)
+{
+  if(db) {	// Database available
+    f->seek(0, binio::Set);
+    CClockRecord *record = (CClockRecord *)db->search(CAdPlugDatabase::CKey(*f));
+    if (record && record->type == CAdPlugDatabase::CRecord::ClockSpeed)
+      return record->clock;
+  }
+
+  // Otherwise the database is either unavailable, or there's no entry for this file
+  if (fp.extension(filename, ".imf")) return 560.0f;
+  if (fp.extension(filename, ".wlf")) return 700.0f;
+  return 700.0f; // default speed for unknown files that aren't .IMF or .WLF
+}
--- a/Plugins/Input/adplug/core/ksm.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,336 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * ksm.cpp - KSM Player for AdPlug by Simon Peter <dn.tlp@gmx.net>
- */
-
-#include <string.h>
-
-#include "ksm.h"
-#include "debug.h"
-
-const unsigned int CksmPlayer::adlibfreq[63] = {
-	0,
-	2390,2411,2434,2456,2480,2506,2533,2562,2592,2625,2659,2695,
-	3414,3435,3458,3480,3504,3530,3557,3586,3616,3649,3683,3719,
-	4438,4459,4482,4504,4528,4554,4581,4610,4640,4673,4707,4743,
-	5462,5483,5506,5528,5552,5578,5605,5634,5664,5697,5731,5767,
-	6486,6507,6530,6552,6576,6602,6629,6658,6688,6721,6755,6791,
-	7510};
-
-/*** public methods **************************************/
-
-CPlayer *CksmPlayer::factory(Copl *newopl)
-{
-  return new CksmPlayer(newopl);
-}
-
-bool CksmPlayer::load(const std::string &filename, const CFileProvider &fp)
-{
-  binistream	*f;
-  int		i;
-  char		*fn = new char[filename.length() + 9];
-
-  // file validation section
-  if(!fp.extension(filename, ".ksm")) {
-    AdPlug_LogWrite("CksmPlayer::load(,\"%s\"): File doesn't have '.ksm' "
-		    "extension! Rejected!\n", filename.c_str());
-    return false;
-  }
-  AdPlug_LogWrite("*** CksmPlayer::load(,\"%s\") ***\n", filename.c_str());
-
-  // Load instruments from 'insts.dat'
-  strcpy(fn, filename.c_str());
-  for(i = strlen(fn) - 1; i >= 0; i--)
-    if(fn[i] == '/' || fn[i] == '\\')
-      break;
-  strcpy(fn + i + 1, "insts.dat");
-  AdPlug_LogWrite("Instruments file: \"%s\"\n", fn);
-  f = fp.open(fn);
-  delete [] fn;
-  if(!f) {
-    AdPlug_LogWrite("Couldn't open instruments file! Aborting!\n");
-    AdPlug_LogWrite("--- CksmPlayer::load ---\n");
-    return false;
-  }
-  loadinsts(f);
-  fp.close(f);
-
-  f = fp.open(filename); if(!f) return false;
-  for(i = 0; i < 16; i++) trinst[i] = f->readInt(1);
-  for(i = 0; i < 16; i++) trquant[i] = f->readInt(1);
-  for(i = 0; i < 16; i++) trchan[i] = f->readInt(1);
-  f->ignore(16);
-  for(i = 0; i < 16; i++) trvol[i] = f->readInt(1);
-  numnotes = f->readInt(2);
-  note = new unsigned long [numnotes];
-  for(i = 0; i < numnotes; i++) note[i] = f->readInt(4);
-  fp.close(f);
-
-  if(!trchan[11]) {
-    drumstat = 0;
-    numchans = 9;
-  } else {
-    drumstat = 32;
-    numchans = 6;
-  }
-
-  rewind(0);
-  AdPlug_LogWrite("--- CksmPlayer::load ---\n");
-  return true;
-}
-
-bool CksmPlayer::update()
-{
-  int quanter,chan,drumnum,freq,track,volevel,volval;
-	unsigned int i,j,bufnum;
-	unsigned long temp,templong;
-
-	count++;
-	if (count >= countstop)
-	{
-		bufnum = 0;
-		while (count >= countstop)
-		{
-			templong = note[nownote];
-			track = (int)((templong>>8)&15);
-			if ((templong&192) == 0)
-			{
-				i = 0;
-
-	      while ((i < numchans) &&
-		     ((chanfreq[i] != (templong&63)) ||
-		      (chantrack[i] != ((templong>>8)&15))))
-					i++;
-				if (i < numchans)
-				{
-					databuf[bufnum] = (char)0; bufnum++;
-					databuf[bufnum] = (unsigned char)(0xb0+i); bufnum++;
-					databuf[bufnum] = (unsigned char)((adlibfreq[templong&63]>>8)&223); bufnum++;
-					chanfreq[i] = 0;
-					chanage[i] = 0;
-				}
-			}
-			else
-			{
-				volevel = trvol[track];
-				if ((templong&192) == 128)
-				{
-					volevel -= 4;
-					if (volevel < 0)
-						volevel = 0;
-				}
-				if ((templong&192) == 192)
-				{
-					volevel += 4;
-					if (volevel > 63)
-						volevel = 63;
-				}
-				if (track < 11)
-				{
-					temp = 0;
-					i = numchans;
-					for(j=0;j<numchans;j++)
-						if ((countstop - chanage[j] >= temp) && (chantrack[j] == track))
-						{
-							temp = countstop - chanage[j];
-							i = j;
-						}
-					if (i < numchans)
-					{
-						databuf[bufnum] = (char)0, bufnum++;
-						databuf[bufnum] = (unsigned char)(0xb0+i); bufnum++;
-						databuf[bufnum] = (unsigned char)0; bufnum++;
-						volval = (inst[trinst[track]][1]&192)+(volevel^63);
-						databuf[bufnum] = (char)0, bufnum++;
-						databuf[bufnum] = (unsigned char)(0x40+op_table[i]+3); bufnum++;
-						databuf[bufnum] = (unsigned char)volval; bufnum++;
-						databuf[bufnum] = (char)0, bufnum++;
-						databuf[bufnum] = (unsigned char)(0xa0+i); bufnum++;
-						databuf[bufnum] = (unsigned char)(adlibfreq[templong&63]&255); bufnum++;
-						databuf[bufnum] = (char)0, bufnum++;
-						databuf[bufnum] = (unsigned char)(0xb0+i); bufnum++;
-						databuf[bufnum] = (unsigned char)((adlibfreq[templong&63]>>8)|32); bufnum++;
-						chanfreq[i] = templong&63;
-						chanage[i] = countstop;
-					}
-				}
-				else if ((drumstat&32) > 0)
-				{
-					freq = adlibfreq[templong&63];
-					switch(track)
-					{
-						case 11: drumnum = 16; chan = 6; freq -= 2048; break;
-						case 12: drumnum = 8; chan = 7; freq -= 2048; break;
-						case 13: drumnum = 4; chan = 8; break;
-						case 14: drumnum = 2; chan = 8; break;
-						case 15: drumnum = 1; chan = 7; freq -= 2048; break;
-					}
-					databuf[bufnum] = (char)0, bufnum++;
-					databuf[bufnum] = (unsigned char)(0xa0+chan); bufnum++;
-					databuf[bufnum] = (unsigned char)(freq&255); bufnum++;
-					databuf[bufnum] = (char)0, bufnum++;
-					databuf[bufnum] = (unsigned char)(0xb0+chan); bufnum++;
-					databuf[bufnum] = (unsigned char)((freq>>8)&223); bufnum++;
-					databuf[bufnum] = (char)0, bufnum++;
-					databuf[bufnum] = (unsigned char)(0xbd); bufnum++;
-					databuf[bufnum] = (unsigned char)(drumstat&(255-drumnum)); bufnum++;
-					drumstat |= drumnum;
-					if ((track == 11) || (track == 12) || (track == 14))
-					{
-						volval = (inst[trinst[track]][1]&192)+(volevel^63);
-						databuf[bufnum] = (char)0, bufnum++;
-						databuf[bufnum] = (unsigned char)(0x40+op_table[chan]+3); bufnum++;
-						databuf[bufnum] = (unsigned char)(volval); bufnum++;
-					}
-					else
-					{
-						volval = (inst[trinst[track]][6]&192)+(volevel^63);
-						databuf[bufnum] = (char)0, bufnum++;
-						databuf[bufnum] = (unsigned char)(0x40+op_table[chan]); bufnum++;
-						databuf[bufnum] = (unsigned char)(volval); bufnum++;
-					}
-					databuf[bufnum] = (char)0, bufnum++;
-					databuf[bufnum] = (unsigned char)(0xbd); bufnum++;
-					databuf[bufnum] = (unsigned char)(drumstat); bufnum++;
-				}
-			}
-			nownote++;
-			if (nownote >= numnotes) {
-				nownote = 0;
-				songend = true;
-			}
-			templong = note[nownote];
-			if (nownote == 0)
-				count = (templong>>12)-1;
-			quanter = (240/trquant[(templong>>8)&15]);
-			countstop = (((templong>>12)+(quanter>>1)) / quanter) * quanter;
-		}
-		for(i=0;i<bufnum;i+=3)
-			opl->write(databuf[i+1],databuf[i+2]);
-	}
-	return !songend;
-}
-
-void CksmPlayer::rewind(int subsong)
-{
-	unsigned int i,j,k;
-	unsigned char instbuf[11];
-	unsigned long templong;
-
-	songend = false;
-	opl->init(); opl->write(1,32); opl->write(4,0); opl->write(8,0); opl->write(0xbd,drumstat);
-
-	if (trchan[11] == 1) {
-	  for(i=0;i<11;i++)
-	    instbuf[i] = inst[trinst[11]][i];
-	  instbuf[1] = ((instbuf[1]&192)|(trvol[11])^63);
-	  setinst(6,instbuf[0],instbuf[1],instbuf[2],instbuf[3],instbuf[4],instbuf[5],instbuf[6],instbuf[7],instbuf[8],instbuf[9],instbuf[10]);
-	  for(i=0;i<5;i++)
-	    instbuf[i] = inst[trinst[12]][i];
-	  for(i=5;i<11;i++)
-	    instbuf[i] = inst[trinst[15]][i];
-	  instbuf[1] = ((instbuf[1]&192)|(trvol[12])^63);
-	  instbuf[6] = ((instbuf[6]&192)|(trvol[15])^63);
-	  setinst(7,instbuf[0],instbuf[1],instbuf[2],instbuf[3],instbuf[4],instbuf[5],instbuf[6],instbuf[7],instbuf[8],instbuf[9],instbuf[10]);
-	  for(i=0;i<5;i++)
-	    instbuf[i] = inst[trinst[14]][i];
-	  for(i=5;i<11;i++)
-	    instbuf[i] = inst[trinst[13]][i];
-	  instbuf[1] = ((instbuf[1]&192)|(trvol[14])^63);
-	  instbuf[6] = ((instbuf[6]&192)|(trvol[13])^63);
-	  setinst(8,instbuf[0],instbuf[1],instbuf[2],instbuf[3],instbuf[4],instbuf[5],instbuf[6],instbuf[7],instbuf[8],instbuf[9],instbuf[10]);
-	}
-
-	for(i=0;i<numchans;i++)
-	{
-		chantrack[i] = 0;
-		chanage[i] = 0;
-	}
-	j = 0;
-	for(i=0;i<16;i++)
-		if ((trchan[i] > 0) && (j < numchans))
-		{
-			k = trchan[i];
-			while ((j < numchans) && (k > 0))
-			{
-				chantrack[j] = i;
-				k--;
-				j++;
-			}
-		}
-	for(i=0;i<numchans;i++)
-	{
-		for(j=0;j<11;j++)
-			instbuf[j] = inst[trinst[chantrack[i]]][j];
-		instbuf[1] = ((instbuf[1]&192)|(63-trvol[chantrack[i]]));
-		setinst(i,instbuf[0],instbuf[1],instbuf[2],instbuf[3],instbuf[4],instbuf[5],instbuf[6],instbuf[7],instbuf[8],instbuf[9],instbuf[10]);
-		chanfreq[i] = 0;
-	}
-	k = 0;
-	templong = *note;
-	count = (templong>>12)-1;
-	countstop = (templong>>12)-1;
-	nownote = 0;
-}
-
-std::string CksmPlayer::getinstrument(unsigned int n)
-{
-	if(trchan[n])
-		return std::string(instname[trinst[n]]);
-	else
-		return std::string();
-}
-
-/*** private methods *************************************/
-
-void CksmPlayer::loadinsts(binistream *f)
-{
-  int i, j;
-
-  for(i = 0; i < 256; i++) {
-    f->readString(instname[i], 20);
-    for(j = 0; j < 11; j++) inst[i][j] = f->readInt(1);
-    f->ignore(2);
-  }
-}
-
-void CksmPlayer::setinst(int chan,
-			 unsigned char v0,unsigned char v1,unsigned char v2,
-			 unsigned char v3,unsigned char v4,unsigned char v5,
-			 unsigned char v6,unsigned char v7,unsigned char v8,
-			 unsigned char v9,unsigned char v10)
-{
-	int offs;
-
-	opl->write(0xa0+chan,0);
-	opl->write(0xb0+chan,0);
-	opl->write(0xc0+chan,v10);
-	offs = op_table[chan];
-	opl->write(0x20+offs,v5);
-	opl->write(0x40+offs,v6);
-	opl->write(0x60+offs,v7);
-	opl->write(0x80+offs,v8);
-	opl->write(0xe0+offs,v9);
-	offs+=3;
-	opl->write(0x20+offs,v0);
-	opl->write(0x40+offs,v1);
-	opl->write(0x60+offs,v2);
-	opl->write(0x80+offs,v3);
-	opl->write(0xe0+offs,v4);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/ksm.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,336 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * ksm.cpp - KSM Player for AdPlug by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include <string.h>
+
+#include "ksm.h"
+#include "debug.h"
+
+const unsigned int CksmPlayer::adlibfreq[63] = {
+	0,
+	2390,2411,2434,2456,2480,2506,2533,2562,2592,2625,2659,2695,
+	3414,3435,3458,3480,3504,3530,3557,3586,3616,3649,3683,3719,
+	4438,4459,4482,4504,4528,4554,4581,4610,4640,4673,4707,4743,
+	5462,5483,5506,5528,5552,5578,5605,5634,5664,5697,5731,5767,
+	6486,6507,6530,6552,6576,6602,6629,6658,6688,6721,6755,6791,
+	7510};
+
+/*** public methods **************************************/
+
+CPlayer *CksmPlayer::factory(Copl *newopl)
+{
+  return new CksmPlayer(newopl);
+}
+
+bool CksmPlayer::load(const std::string &filename, const CFileProvider &fp)
+{
+  binistream	*f;
+  int		i;
+  char		*fn = new char[filename.length() + 9];
+
+  // file validation section
+  if(!fp.extension(filename, ".ksm")) {
+    AdPlug_LogWrite("CksmPlayer::load(,\"%s\"): File doesn't have '.ksm' "
+		    "extension! Rejected!\n", filename.c_str());
+    return false;
+  }
+  AdPlug_LogWrite("*** CksmPlayer::load(,\"%s\") ***\n", filename.c_str());
+
+  // Load instruments from 'insts.dat'
+  strcpy(fn, filename.c_str());
+  for(i = strlen(fn) - 1; i >= 0; i--)
+    if(fn[i] == '/' || fn[i] == '\\')
+      break;
+  strcpy(fn + i + 1, "insts.dat");
+  AdPlug_LogWrite("Instruments file: \"%s\"\n", fn);
+  f = fp.open(fn);
+  delete [] fn;
+  if(!f) {
+    AdPlug_LogWrite("Couldn't open instruments file! Aborting!\n");
+    AdPlug_LogWrite("--- CksmPlayer::load ---\n");
+    return false;
+  }
+  loadinsts(f);
+  fp.close(f);
+
+  f = fp.open(filename); if(!f) return false;
+  for(i = 0; i < 16; i++) trinst[i] = f->readInt(1);
+  for(i = 0; i < 16; i++) trquant[i] = f->readInt(1);
+  for(i = 0; i < 16; i++) trchan[i] = f->readInt(1);
+  f->ignore(16);
+  for(i = 0; i < 16; i++) trvol[i] = f->readInt(1);
+  numnotes = f->readInt(2);
+  note = new unsigned long [numnotes];
+  for(i = 0; i < numnotes; i++) note[i] = f->readInt(4);
+  fp.close(f);
+
+  if(!trchan[11]) {
+    drumstat = 0;
+    numchans = 9;
+  } else {
+    drumstat = 32;
+    numchans = 6;
+  }
+
+  rewind(0);
+  AdPlug_LogWrite("--- CksmPlayer::load ---\n");
+  return true;
+}
+
+bool CksmPlayer::update()
+{
+  int quanter,chan,drumnum,freq,track,volevel,volval;
+	unsigned int i,j,bufnum;
+	unsigned long temp,templong;
+
+	count++;
+	if (count >= countstop)
+	{
+		bufnum = 0;
+		while (count >= countstop)
+		{
+			templong = note[nownote];
+			track = (int)((templong>>8)&15);
+			if ((templong&192) == 0)
+			{
+				i = 0;
+
+	      while ((i < numchans) &&
+		     ((chanfreq[i] != (templong&63)) ||
+		      (chantrack[i] != ((templong>>8)&15))))
+					i++;
+				if (i < numchans)
+				{
+					databuf[bufnum] = (char)0; bufnum++;
+					databuf[bufnum] = (unsigned char)(0xb0+i); bufnum++;
+					databuf[bufnum] = (unsigned char)((adlibfreq[templong&63]>>8)&223); bufnum++;
+					chanfreq[i] = 0;
+					chanage[i] = 0;
+				}
+			}
+			else
+			{
+				volevel = trvol[track];
+				if ((templong&192) == 128)
+				{
+					volevel -= 4;
+					if (volevel < 0)
+						volevel = 0;
+				}
+				if ((templong&192) == 192)
+				{
+					volevel += 4;
+					if (volevel > 63)
+						volevel = 63;
+				}
+				if (track < 11)
+				{
+					temp = 0;
+					i = numchans;
+					for(j=0;j<numchans;j++)
+						if ((countstop - chanage[j] >= temp) && (chantrack[j] == track))
+						{
+							temp = countstop - chanage[j];
+							i = j;
+						}
+					if (i < numchans)
+					{
+						databuf[bufnum] = (char)0, bufnum++;
+						databuf[bufnum] = (unsigned char)(0xb0+i); bufnum++;
+						databuf[bufnum] = (unsigned char)0; bufnum++;
+						volval = (inst[trinst[track]][1]&192)+(volevel^63);
+						databuf[bufnum] = (char)0, bufnum++;
+						databuf[bufnum] = (unsigned char)(0x40+op_table[i]+3); bufnum++;
+						databuf[bufnum] = (unsigned char)volval; bufnum++;
+						databuf[bufnum] = (char)0, bufnum++;
+						databuf[bufnum] = (unsigned char)(0xa0+i); bufnum++;
+						databuf[bufnum] = (unsigned char)(adlibfreq[templong&63]&255); bufnum++;
+						databuf[bufnum] = (char)0, bufnum++;
+						databuf[bufnum] = (unsigned char)(0xb0+i); bufnum++;
+						databuf[bufnum] = (unsigned char)((adlibfreq[templong&63]>>8)|32); bufnum++;
+						chanfreq[i] = templong&63;
+						chanage[i] = countstop;
+					}
+				}
+				else if ((drumstat&32) > 0)
+				{
+					freq = adlibfreq[templong&63];
+					switch(track)
+					{
+						case 11: drumnum = 16; chan = 6; freq -= 2048; break;
+						case 12: drumnum = 8; chan = 7; freq -= 2048; break;
+						case 13: drumnum = 4; chan = 8; break;
+						case 14: drumnum = 2; chan = 8; break;
+						case 15: drumnum = 1; chan = 7; freq -= 2048; break;
+					}
+					databuf[bufnum] = (char)0, bufnum++;
+					databuf[bufnum] = (unsigned char)(0xa0+chan); bufnum++;
+					databuf[bufnum] = (unsigned char)(freq&255); bufnum++;
+					databuf[bufnum] = (char)0, bufnum++;
+					databuf[bufnum] = (unsigned char)(0xb0+chan); bufnum++;
+					databuf[bufnum] = (unsigned char)((freq>>8)&223); bufnum++;
+					databuf[bufnum] = (char)0, bufnum++;
+					databuf[bufnum] = (unsigned char)(0xbd); bufnum++;
+					databuf[bufnum] = (unsigned char)(drumstat&(255-drumnum)); bufnum++;
+					drumstat |= drumnum;
+					if ((track == 11) || (track == 12) || (track == 14))
+					{
+						volval = (inst[trinst[track]][1]&192)+(volevel^63);
+						databuf[bufnum] = (char)0, bufnum++;
+						databuf[bufnum] = (unsigned char)(0x40+op_table[chan]+3); bufnum++;
+						databuf[bufnum] = (unsigned char)(volval); bufnum++;
+					}
+					else
+					{
+						volval = (inst[trinst[track]][6]&192)+(volevel^63);
+						databuf[bufnum] = (char)0, bufnum++;
+						databuf[bufnum] = (unsigned char)(0x40+op_table[chan]); bufnum++;
+						databuf[bufnum] = (unsigned char)(volval); bufnum++;
+					}
+					databuf[bufnum] = (char)0, bufnum++;
+					databuf[bufnum] = (unsigned char)(0xbd); bufnum++;
+					databuf[bufnum] = (unsigned char)(drumstat); bufnum++;
+				}
+			}
+			nownote++;
+			if (nownote >= numnotes) {
+				nownote = 0;
+				songend = true;
+			}
+			templong = note[nownote];
+			if (nownote == 0)
+				count = (templong>>12)-1;
+			quanter = (240/trquant[(templong>>8)&15]);
+			countstop = (((templong>>12)+(quanter>>1)) / quanter) * quanter;
+		}
+		for(i=0;i<bufnum;i+=3)
+			opl->write(databuf[i+1],databuf[i+2]);
+	}
+	return !songend;
+}
+
+void CksmPlayer::rewind(int subsong)
+{
+	unsigned int i,j,k;
+	unsigned char instbuf[11];
+	unsigned long templong;
+
+	songend = false;
+	opl->init(); opl->write(1,32); opl->write(4,0); opl->write(8,0); opl->write(0xbd,drumstat);
+
+	if (trchan[11] == 1) {
+	  for(i=0;i<11;i++)
+	    instbuf[i] = inst[trinst[11]][i];
+	  instbuf[1] = ((instbuf[1]&192)|(trvol[11])^63);
+	  setinst(6,instbuf[0],instbuf[1],instbuf[2],instbuf[3],instbuf[4],instbuf[5],instbuf[6],instbuf[7],instbuf[8],instbuf[9],instbuf[10]);
+	  for(i=0;i<5;i++)
+	    instbuf[i] = inst[trinst[12]][i];
+	  for(i=5;i<11;i++)
+	    instbuf[i] = inst[trinst[15]][i];
+	  instbuf[1] = ((instbuf[1]&192)|(trvol[12])^63);
+	  instbuf[6] = ((instbuf[6]&192)|(trvol[15])^63);
+	  setinst(7,instbuf[0],instbuf[1],instbuf[2],instbuf[3],instbuf[4],instbuf[5],instbuf[6],instbuf[7],instbuf[8],instbuf[9],instbuf[10]);
+	  for(i=0;i<5;i++)
+	    instbuf[i] = inst[trinst[14]][i];
+	  for(i=5;i<11;i++)
+	    instbuf[i] = inst[trinst[13]][i];
+	  instbuf[1] = ((instbuf[1]&192)|(trvol[14])^63);
+	  instbuf[6] = ((instbuf[6]&192)|(trvol[13])^63);
+	  setinst(8,instbuf[0],instbuf[1],instbuf[2],instbuf[3],instbuf[4],instbuf[5],instbuf[6],instbuf[7],instbuf[8],instbuf[9],instbuf[10]);
+	}
+
+	for(i=0;i<numchans;i++)
+	{
+		chantrack[i] = 0;
+		chanage[i] = 0;
+	}
+	j = 0;
+	for(i=0;i<16;i++)
+		if ((trchan[i] > 0) && (j < numchans))
+		{
+			k = trchan[i];
+			while ((j < numchans) && (k > 0))
+			{
+				chantrack[j] = i;
+				k--;
+				j++;
+			}
+		}
+	for(i=0;i<numchans;i++)
+	{
+		for(j=0;j<11;j++)
+			instbuf[j] = inst[trinst[chantrack[i]]][j];
+		instbuf[1] = ((instbuf[1]&192)|(63-trvol[chantrack[i]]));
+		setinst(i,instbuf[0],instbuf[1],instbuf[2],instbuf[3],instbuf[4],instbuf[5],instbuf[6],instbuf[7],instbuf[8],instbuf[9],instbuf[10]);
+		chanfreq[i] = 0;
+	}
+	k = 0;
+	templong = *note;
+	count = (templong>>12)-1;
+	countstop = (templong>>12)-1;
+	nownote = 0;
+}
+
+std::string CksmPlayer::getinstrument(unsigned int n)
+{
+	if(trchan[n])
+		return std::string(instname[trinst[n]]);
+	else
+		return std::string();
+}
+
+/*** private methods *************************************/
+
+void CksmPlayer::loadinsts(binistream *f)
+{
+  int i, j;
+
+  for(i = 0; i < 256; i++) {
+    f->readString(instname[i], 20);
+    for(j = 0; j < 11; j++) inst[i][j] = f->readInt(1);
+    f->ignore(2);
+  }
+}
+
+void CksmPlayer::setinst(int chan,
+			 unsigned char v0,unsigned char v1,unsigned char v2,
+			 unsigned char v3,unsigned char v4,unsigned char v5,
+			 unsigned char v6,unsigned char v7,unsigned char v8,
+			 unsigned char v9,unsigned char v10)
+{
+	int offs;
+
+	opl->write(0xa0+chan,0);
+	opl->write(0xb0+chan,0);
+	opl->write(0xc0+chan,v10);
+	offs = op_table[chan];
+	opl->write(0x20+offs,v5);
+	opl->write(0x40+offs,v6);
+	opl->write(0x60+offs,v7);
+	opl->write(0x80+offs,v8);
+	opl->write(0xe0+offs,v9);
+	offs+=3;
+	opl->write(0x20+offs,v0);
+	opl->write(0x40+offs,v1);
+	opl->write(0x60+offs,v2);
+	opl->write(0x80+offs,v3);
+	opl->write(0xe0+offs,v4);
+}
--- a/Plugins/Input/adplug/core/lds.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,676 +0,0 @@
-/*
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * lds.cpp - LOUDNESS Player by Simon Peter <dn.tlp@gmx.net>
- */
-
-#include <string.h>
-
-#include "lds.h"
-#include "debug.h"
-
-// Note frequency table (16 notes / octave)
-const unsigned short CldsPlayer::frequency[] = {
-  343, 344, 345, 347, 348, 349, 350, 352, 353, 354, 356, 357, 358,
-  359, 361, 362, 363, 365, 366, 367, 369, 370, 371, 373, 374, 375,
-  377, 378, 379, 381, 382, 384, 385, 386, 388, 389, 391, 392, 393,
-  395, 396, 398, 399, 401, 402, 403, 405, 406, 408, 409, 411, 412,
-  414, 415, 417, 418, 420, 421, 423, 424, 426, 427, 429, 430, 432,
-  434, 435, 437, 438, 440, 442, 443, 445, 446, 448, 450, 451, 453,
-  454, 456, 458, 459, 461, 463, 464, 466, 468, 469, 471, 473, 475,
-  476, 478, 480, 481, 483, 485, 487, 488, 490, 492, 494, 496, 497,
-  499, 501, 503, 505, 506, 508, 510, 512, 514, 516, 518, 519, 521,
-  523, 525, 527, 529, 531, 533, 535, 537, 538, 540, 542, 544, 546,
-  548, 550, 552, 554, 556, 558, 560, 562, 564, 566, 568, 571, 573,
-  575, 577, 579, 581, 583, 585, 587, 589, 591, 594, 596, 598, 600,
-  602, 604, 607, 609, 611, 613, 615, 618, 620, 622, 624, 627, 629,
-  631, 633, 636, 638, 640, 643, 645, 647, 650, 652, 654, 657, 659,
-  662, 664, 666, 669, 671, 674, 676, 678, 681, 683
-};
-
-// Vibrato (sine) table
-const unsigned char CldsPlayer::vibtab[] = {
-  0, 13, 25, 37, 50, 62, 74, 86, 98, 109, 120, 131, 142, 152, 162,
-  171, 180, 189, 197, 205, 212, 219, 225, 231, 236, 240, 244, 247,
-  250, 252, 254, 255, 255, 255, 254, 252, 250, 247, 244, 240, 236,
-  231, 225, 219, 212, 205, 197, 189, 180, 171, 162, 152, 142, 131,
-  120, 109, 98, 86, 74, 62, 50, 37, 25, 13
-};
-
-// Tremolo (sine * sine) table
-const unsigned char CldsPlayer::tremtab[] = {
-  0, 0, 1, 1, 2, 4, 5, 7, 10, 12, 15, 18, 21, 25, 29, 33, 37, 42, 47,
-  52, 57, 62, 67, 73, 79, 85, 90, 97, 103, 109, 115, 121, 128, 134,
-  140, 146, 152, 158, 165, 170, 176, 182, 188, 193, 198, 203, 208,
-  213, 218, 222, 226, 230, 234, 237, 240, 243, 245, 248, 250, 251,
-  253, 254, 254, 255, 255, 255, 254, 254, 253, 251, 250, 248, 245,
-  243, 240, 237, 234, 230, 226, 222, 218, 213, 208, 203, 198, 193,
-  188, 182, 176, 170, 165, 158, 152, 146, 140, 134, 127, 121, 115,
-  109, 103, 97, 90, 85, 79, 73, 67, 62, 57, 52, 47, 42, 37, 33, 29,
-  25, 21, 18, 15, 12, 10, 7, 5, 4, 2, 1, 1, 0
-};
-
-// 'maxsound' is maximum number of patches (instruments)
-// 'maxpos' is maximum number of entries in position list (orderlist)
-const unsigned short CldsPlayer::maxsound = 0x3f, CldsPlayer::maxpos = 0xff;
-
-/*** public methods *************************************/
-
-CldsPlayer::CldsPlayer(Copl *newopl)
-  : CPlayer(newopl), soundbank(0), positions(0), patterns(0)
-{
-}
-
-CldsPlayer::~CldsPlayer()
-{
-  if(soundbank) delete [] soundbank;
-  if(positions) delete [] positions;
-  if(patterns) delete [] patterns;
-}
-
-bool CldsPlayer::load(const std::string &filename, const CFileProvider &fp)
-{
-  binistream	*f;
-  unsigned int	i, j;
-  SoundBank	*sb;
-
-  // file validation section (actually just an extension check)
-  if(!fp.extension(filename, ".lds")) return false;
-  f = fp.open(filename); if(!f) return false;
-
-  // file load section (header)
-  mode = f->readInt(1);
-  if(mode > 2) { fp.close(f); return false; }
-  speed = f->readInt(2);
-  tempo = f->readInt(1);
-  pattlen = f->readInt(1);
-  for(i = 0; i < 9; i++) chandelay[i] = f->readInt(1);
-  regbd = f->readInt(1);
-
-  // load patches
-  numpatch = f->readInt(2);
-  soundbank = new SoundBank[numpatch];
-  for(i = 0; i < numpatch; i++) {
-    sb = &soundbank[i];
-    sb->mod_misc = f->readInt(1); sb->mod_vol = f->readInt(1);
-    sb->mod_ad = f->readInt(1); sb->mod_sr = f->readInt(1);
-    sb->mod_wave = f->readInt(1); sb->car_misc = f->readInt(1);
-    sb->car_vol = f->readInt(1); sb->car_ad = f->readInt(1);
-    sb->car_sr = f->readInt(1); sb->car_wave = f->readInt(1);
-    sb->feedback = f->readInt(1); sb->keyoff = f->readInt(1);
-    sb->portamento = f->readInt(1); sb->glide = f->readInt(1);
-    sb->finetune = f->readInt(1); sb->vibrato = f->readInt(1);
-    sb->vibdelay = f->readInt(1); sb->mod_trem = f->readInt(1);
-    sb->car_trem = f->readInt(1); sb->tremwait = f->readInt(1);
-    sb->arpeggio = f->readInt(1);
-    for(j = 0; j < 12; j++) sb->arp_tab[j] = f->readInt(1);
-    sb->start = f->readInt(2); sb->size = f->readInt(2);
-    sb->fms = f->readInt(1); sb->transp = f->readInt(2);
-    sb->midinst = f->readInt(1); sb->midvelo = f->readInt(1);
-    sb->midkey = f->readInt(1); sb->midtrans = f->readInt(1);
-    sb->middum1 = f->readInt(1); sb->middum2 = f->readInt(1);
-  }
-
-  // load positions
-  numposi = f->readInt(2);
-  positions = new Position[9 * numposi];
-  for(i = 0; i < numposi; i++)
-    for(j = 0; j < 9; j++) {
-      /*
-       * patnum is a pointer inside the pattern space, but patterns are 16bit
-       * word fields anyway, so it ought to be an even number (hopefully) and
-       * we can just divide it by 2 to get our array index of 16bit words.
-       */
-      positions[i * 9 + j].patnum = f->readInt(2) / 2;
-      positions[i * 9 + j].transpose = f->readInt(1);
-    }
-
-  AdPlug_LogWrite("CldsPlayer::load(\"%s\",fp): loading LOUDNESS file: mode = "
-		  "%d, pattlen = %d, numpatch = %d, numposi = %d\n",
-		  filename.c_str(), mode, pattlen, numpatch, numposi);
-
-  // load patterns
-  f->ignore(2);		// ignore # of digital sounds (not played by this player)
-  patterns = new unsigned short[(fp.filesize(f) - f->pos()) / 2 + 1];
-  for(i = 0; !f->eof(); i++)
-    patterns[i] = f->readInt(2);
-
-  fp.close(f);
-  rewind(0);
-  return true;
-}
-
-bool CldsPlayer::update()
-{
-  unsigned short	comword, freq, octave, chan, tune, wibc, tremc, arpreg;
-  bool			vbreak;
-  unsigned char		level, regnum, comhi, comlo;
-  int			i;
-  Channel		*c;
-
-  if(!playing) return false;
-
-  // handle fading
-  if(fadeonoff)
-    if(fadeonoff <= 128) {
-      if(allvolume > fadeonoff || allvolume == 0)
-	allvolume -= fadeonoff;
-      else {
-	allvolume = 1;
-	fadeonoff = 0;
-	if(hardfade != 0) {
-	  playing = false;
-	  hardfade = 0;
-	  for(i = 0; i < 9; i++)
-	    channel[i].keycount = 1;
-	}
-      }
-    } else
-      if((unsigned int)((allvolume + (0x100 - fadeonoff)) & 0xff) <= mainvolume)
-	allvolume += 0x100 - fadeonoff;
-      else {
-	allvolume = mainvolume;
-	fadeonoff = 0;
-      }
-
-  // handle channel delay
-  for(chan = 0; chan < 9; chan++) {
-    c = &channel[chan];
-    if(c->chancheat.chandelay)
-      if(!(--c->chancheat.chandelay))
-	playsound(c->chancheat.sound, chan, c->chancheat.high);
-  }
-
-  // handle notes
-  if(!tempo_now) {
-    vbreak = false;
-    for(chan = 0; chan < 9; chan++) {
-      c = &channel[chan];
-      if(!c->packwait) {
-	unsigned short	patnum = positions[posplay * 9 + chan].patnum;
-	unsigned char	transpose = positions[posplay * 9 + chan].transpose;
-
-	comword = patterns[patnum + c->packpos];
-	comhi = comword >> 8; comlo = comword & 0xff;
-	if(comword)
-	  if(comhi == 0x80)
-	    c->packwait = comlo;
-	  else
-	    if(comhi >= 0x80) {
-	      switch(comhi) {
-	      case 0xff:
-		c->volcar = (((c->volcar & 0x3f) * comlo) >> 6) & 0x3f;
-		if(fmchip[0xc0 + chan] & 1)
-		  c->volmod = (((c->volmod & 0x3f) * comlo) >> 6) & 0x3f;
-		break;
-	      case 0xfe:
-		tempo = comword & 0x3f;
-		break;
-	      case 0xfd:
-		c->nextvol = comlo;
-		break;
-	      case 0xfc:
-		playing = false;
-		// in real player there's also full keyoff here, but we don't need it
-		break;
-	      case 0xfb:
-		c->keycount = 1;
-		break;
-	      case 0xfa:
-		vbreak = true;
-		jumppos = (posplay + 1) & maxpos;
-		break;
-	      case 0xf9:
-		vbreak = true;
-		jumppos = comlo & maxpos;
-		jumping = 1;
-		if(jumppos < posplay) songlooped = true;
-		break;
-	      case 0xf8:
-		c->lasttune = 0;
-		break;
-	      case 0xf7:
-		c->vibwait = 0;
-		// PASCAL: c->vibspeed = ((comlo >> 4) & 15) + 2;
-		c->vibspeed = (comlo >> 4) + 2;
-		c->vibrate = (comlo & 15) + 1;
-		break;
-	      case 0xf6:
-		c->glideto = comlo;
-		break;
-	      case 0xf5:
-		c->finetune = comlo;
-		break;
-	      case 0xf4:
-		if(!hardfade) {
-		  allvolume = mainvolume = comlo;
-		  fadeonoff = 0;
-		}
-		break;
-	      case 0xf3:
-		if(!hardfade) fadeonoff = comlo;
-		break;
-	      case 0xf2:
-		c->trmstay = comlo;
-		break;
-	      case 0xf1:	// panorama
-	      case 0xf0:	// progch
-		// MIDI commands (unhandled)
-		AdPlug_LogWrite("CldsPlayer(): not handling MIDI command 0x%x, "
-				"value = 0x%x\n", comhi);
-		break;
-	      default:
-		if(comhi < 0xa0)
-		  c->glideto = comhi & 0x1f;
-		else
-		  AdPlug_LogWrite("CldsPlayer(): unknown command 0x%x encountered!"
-				  " value = 0x%x\n", comhi, comlo);
-		break;
-	      }
-	    } else {
-	      unsigned char	sound;
-	      unsigned short	high;
-	      signed char	transp = transpose & 127;
-
-	      /*
-	       * Originally, in assembler code, the player first shifted
-	       * logically left the transpose byte by 1 and then shifted
-	       * arithmetically right the same byte to achieve the final,
-	       * signed transpose value. Since we can't do arithmetic shifts
-	       * in C, we just duplicate the 7th bit into the 8th one and
-	       * discard the 8th one completely.
-	       */
-
-	      if(transpose & 64) transp |= 128;
-
-	      if(transpose & 128) {
-		sound = (comlo + transp) & maxsound;
-		high = comhi << 4;
-	      } else {
-		sound = comlo & maxsound;
-		high = (comhi + transp) << 4;
-	      }
-
-	      /*
-		PASCAL:
-	      sound = comlo & maxsound;
-	      high = (comhi + (((transpose + 0x24) & 0xff) - 0x24)) << 4;
-	      */
-
-	      if(!chandelay[chan])
-		playsound(sound, chan, high);
-	      else {
-		c->chancheat.chandelay = chandelay[chan];
-		c->chancheat.sound = sound;
-		c->chancheat.high = high;
-	      }
-	    }
-
-	c->packpos++;
-      } else
-	c->packwait--;
-    }
-
-    tempo_now = tempo;
-    /*
-      The continue table is updated here, but this is only used in the
-      original player, which can be paused in the middle of a song and then
-      unpaused. Since AdPlug does all this for us automatically, we don't
-      have a continue table here. The continue table update code is noted
-      here for reference only.
-
-      if(!pattplay) {
-        conttab[speed & maxcont].position = posplay & 0xff;
-        conttab[speed & maxcont].tempo = tempo;
-      }
-    */
-    pattplay++;
-    if(vbreak) {
-      pattplay = 0;
-      for(i = 0; i < 9; i++) channel[i].packpos = channel[i].packwait = 0;
-      posplay = jumppos;
-    } else
-      if(pattplay >= pattlen) {
-	pattplay = 0;
-	for(i = 0; i < 9; i++) channel[i].packpos = channel[i].packwait = 0;
-	posplay = (posplay + 1) & maxpos;
-      }
-  } else
-    tempo_now--;
-
-  // make effects
-  for(chan = 0; chan < 9; chan++) {
-    c = &channel[chan];
-    regnum = op_table[chan];
-    if(c->keycount > 0) {
-      if(c->keycount == 1)
-	setregs_adv(0xb0 + chan, 0xdf, 0);
-      c->keycount--;
-    }
-
-    // arpeggio
-    if(c->arp_size == 0)
-      arpreg = 0;
-    else {
-      arpreg = c->arp_tab[c->arp_pos] << 4;
-      if(arpreg == 0x800) {
-	if(c->arp_pos > 0) c->arp_tab[0] = c->arp_tab[c->arp_pos - 1];
-	c->arp_size = 1; c->arp_pos = 0;
-	arpreg = c->arp_tab[0] << 4;
-      }
-
-      if(c->arp_count == c->arp_speed) {
-	c->arp_pos++;
-	if(c->arp_pos >= c->arp_size) c->arp_pos = 0;
-	c->arp_count = 0;
-      } else
-	c->arp_count++;
-    }
-
-    // glide & portamento
-    if(c->lasttune && (c->lasttune != c->gototune)) {
-      if(c->lasttune > c->gototune) {
-	if(c->lasttune - c->gototune < c->portspeed)
-	  c->lasttune = c->gototune;
-	else
-	  c->lasttune -= c->portspeed;
-      } else {
-	if(c->gototune - c->lasttune < c->portspeed)
-	  c->lasttune = c->gototune;
-	else
-	  c->lasttune += c->portspeed;
-      }
-
-      if(arpreg >= 0x800)
-	arpreg = c->lasttune - (arpreg ^ 0xff0) - 16;
-      else
-	arpreg += c->lasttune;
-
-      freq = frequency[arpreg % (12 * 16)];
-      octave = arpreg / (12 * 16) - 1;
-      setregs(0xa0 + chan, freq & 0xff);
-      setregs_adv(0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf);
-    } else {
-      // vibrato
-      if(!c->vibwait) {
-	if(c->vibrate) {
-	  wibc = vibtab[c->vibcount & 0x3f] * c->vibrate;
-
-	  if((c->vibcount & 0x40) == 0)
-	    tune = c->lasttune + (wibc >> 8);
-	  else
-	    tune = c->lasttune - (wibc >> 8);
-
-	  if(arpreg >= 0x800)
-	    tune = tune - (arpreg ^ 0xff0) - 16;
-	  else
-	    tune += arpreg;
-
-	  freq = frequency[tune % (12 * 16)];
-	  octave = tune / (12 * 16) - 1;
-	  setregs(0xa0 + chan, freq & 0xff);
-	  setregs_adv(0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf);
-	  c->vibcount += c->vibspeed;
-	} else
-	  if(c->arp_size != 0) {	// no vibrato, just arpeggio
-	    if(arpreg >= 0x800)
-	      tune = c->lasttune - (arpreg ^ 0xff0) - 16;
-	    else
-	      tune = c->lasttune + arpreg;
-
-	    freq = frequency[tune % (12 * 16)];
-	    octave = tune / (12 * 16) - 1;
-	    setregs(0xa0 + chan, freq & 0xff);
-	    setregs_adv(0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf);
-	  }
-      } else {	// no vibrato, just arpeggio
-	c->vibwait--;
-
-	if(c->arp_size != 0) {
-	  if(arpreg >= 0x800)
-	    tune = c->lasttune - (arpreg ^ 0xff0) - 16;
-	  else
-	    tune = c->lasttune + arpreg;
-
-	  freq = frequency[tune % (12 * 16)];
-	  octave = tune / (12 * 16) - 1;
-	  setregs(0xa0 + chan, freq & 0xff);
-	  setregs_adv(0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf);
-	}
-      }
-    }
-
-    // tremolo (modulator)
-    if(!c->trmwait) {
-      if(c->trmrate) {
-	tremc = tremtab[c->trmcount & 0x7f] * c->trmrate;
-	if((tremc >> 8) <= (c->volmod & 0x3f))
-	  level = (c->volmod & 0x3f) - (tremc >> 8);
-	else
-	  level = 0;
-
-	if(allvolume != 0 && (fmchip[0xc0 + chan] & 1))
-	  setregs_adv(0x40 + regnum, 0xc0, ((level * allvolume) >> 8) ^ 0x3f);
-	else
-	  setregs_adv(0x40 + regnum, 0xc0, level ^ 0x3f);
-
-	c->trmcount += c->trmspeed;
-      } else
-	if(allvolume != 0 && (fmchip[0xc0 + chan] & 1))
-	  setregs_adv(0x40 + regnum, 0xc0, ((((c->volmod & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
-	else
-	  setregs_adv(0x40 + regnum, 0xc0, (c->volmod ^ 0x3f) & 0x3f);
-    } else {
-      c->trmwait--;
-      if(allvolume != 0 && (fmchip[0xc0 + chan] & 1))
-	setregs_adv(0x40 + regnum, 0xc0, ((((c->volmod & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
-    }
-
-    // tremolo (carrier)
-    if(!c->trcwait) {
-      if(c->trcrate) {
-	tremc = tremtab[c->trccount & 0x7f] * c->trcrate;
-	if((tremc >> 8) <= (c->volcar & 0x3f))
-	  level = (c->volcar & 0x3f) - (tremc >> 8);
-	else
-	  level = 0;
-
-	if(allvolume != 0)
-	  setregs_adv(0x43 + regnum, 0xc0, ((level * allvolume) >> 8) ^ 0x3f);
-	else
-	  setregs_adv(0x43 + regnum, 0xc0, level ^ 0x3f);
-	c->trccount += c->trcspeed;
-      } else
-	if(allvolume != 0)
-	  setregs_adv(0x43 + regnum, 0xc0, ((((c->volcar & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
-	else
-	  setregs_adv(0x43 + regnum, 0xc0, (c->volcar ^ 0x3f) & 0x3f);
-    } else {
-      c->trcwait--;
-      if(allvolume != 0)
-	setregs_adv(0x43 + regnum, 0xc0, ((((c->volcar & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
-    }
-  }
-
-  return (!playing || songlooped) ? false : true;
-}
-
-void CldsPlayer::rewind(int subsong)
-{
-  int i;
-
-  // init all with 0
-  tempo_now = 3; playing = true; songlooped = false;
-  jumping = fadeonoff = allvolume = hardfade = pattplay = posplay = jumppos =
-    mainvolume = 0;
-  memset(channel, 0, sizeof(channel));
-  memset(fmchip, 0, sizeof(fmchip));
-
-  // OPL2 init
-  opl->init();				// Reset OPL chip
-  opl->write(1, 0x20);
-  opl->write(8, 0);
-  opl->write(0xbd, regbd);
-
-  for(i = 0; i < 9; i++) {
-    opl->write(0x20 + op_table[i], 0);
-    opl->write(0x23 + op_table[i], 0);
-    opl->write(0x40 + op_table[i], 0x3f);
-    opl->write(0x43 + op_table[i], 0x3f);
-    opl->write(0x60 + op_table[i], 0xff);
-    opl->write(0x63 + op_table[i], 0xff);
-    opl->write(0x80 + op_table[i], 0xff);
-    opl->write(0x83 + op_table[i], 0xff);
-    opl->write(0xe0 + op_table[i], 0);
-    opl->write(0xe3 + op_table[i], 0);
-    opl->write(0xa0 + i, 0);
-    opl->write(0xb0 + i, 0);
-    opl->write(0xc0 + i, 0);
-  }
-}
-
-/*** private methods *************************************/
-
-void CldsPlayer::playsound(int inst_number, int channel_number, int tunehigh)
-{
-  Channel		*c = &channel[channel_number];		// current channel
-  SoundBank		*i = &soundbank[inst_number];		// current instrument
-  unsigned int		regnum = op_table[channel_number];	// channel's OPL2 register
-  unsigned char		volcalc, octave;
-  unsigned short	freq;
-
-  // set fine tune
-  tunehigh += ((i->finetune + c->finetune + 0x80) & 0xff) - 0x80;
-
-  // arpeggio handling
-  if(!i->arpeggio) {
-    unsigned short	arpcalc = i->arp_tab[0] << 4;
-
-    if(arpcalc > 0x800)
-      tunehigh = tunehigh - (arpcalc ^ 0xff0) - 16;
-    else
-      tunehigh += arpcalc;
-  }
-
-  // glide handling
-  if(c->glideto != 0) {
-    c->gototune = tunehigh;
-    c->portspeed = c->glideto;
-    c->glideto = c->finetune = 0;
-    return;
-  }
-
-  // set modulator registers
-  setregs(0x20 + regnum, i->mod_misc);
-  volcalc = i->mod_vol;
-  if(!c->nextvol || !(i->feedback & 1))
-    c->volmod = volcalc;
-  else
-    c->volmod = (volcalc & 0xc0) | ((((volcalc & 0x3f) * c->nextvol) >> 6));
-
-  if((i->feedback & 1) == 1 && allvolume != 0)
-    setregs(0x40 + regnum, ((c->volmod & 0xc0) | (((c->volmod & 0x3f) * allvolume) >> 8)) ^ 0x3f);
-  else
-    setregs(0x40 + regnum, c->volmod ^ 0x3f);
-  setregs(0x60 + regnum, i->mod_ad);
-  setregs(0x80 + regnum, i->mod_sr);
-  setregs(0xe0 + regnum, i->mod_wave);
-
-  // Set carrier registers
-  setregs(0x23 + regnum, i->car_misc);
-  volcalc = i->car_vol;
-  if(!c->nextvol)
-    c->volcar = volcalc;
-  else
-    c->volcar = (volcalc & 0xc0) | ((((volcalc & 0x3f) * c->nextvol) >> 6));
-
-  if(allvolume)
-    setregs(0x43 + regnum, ((c->volcar & 0xc0) | (((c->volcar & 0x3f) * allvolume) >> 8)) ^ 0x3f);
-  else
-    setregs(0x43 + regnum, c->volcar ^ 0x3f);
-  setregs(0x63 + regnum, i->car_ad);
-  setregs(0x83 + regnum, i->car_sr);
-  setregs(0xe3 + regnum, i->car_wave);
-  setregs(0xc0 + channel_number, i->feedback);
-  setregs_adv(0xb0 + channel_number, 0xdf, 0);		// key off
-
-  freq = frequency[tunehigh % (12 * 16)];
-  octave = tunehigh / (12 * 16) - 1;
-  if(!i->glide) {
-    if(!i->portamento || !c->lasttune) {
-      setregs(0xa0 + channel_number, freq & 0xff);
-      setregs(0xb0 + channel_number, (octave << 2) + 0x20 + (freq >> 8));
-      c->lasttune = c->gototune = tunehigh;
-    } else {
-      c->gototune = tunehigh;
-      c->portspeed = i->portamento;
-      setregs_adv(0xb0 + channel_number, 0xdf, 0x20);	// key on
-    }
-  } else {
-    setregs(0xa0 + channel_number, freq & 0xff);
-    setregs(0xb0 + channel_number, (octave << 2) + 0x20 + (freq >> 8));
-    c->lasttune = tunehigh;
-    c->gototune = tunehigh + ((i->glide + 0x80) & 0xff) - 0x80;	// set destination
-    c->portspeed = i->portamento;
-  }
-
-  if(!i->vibrato)
-    c->vibwait = c->vibspeed = c->vibrate = 0;
-  else {
-    c->vibwait = i->vibdelay;
-    // PASCAL:    c->vibspeed = ((i->vibrato >> 4) & 15) + 1;
-    c->vibspeed = (i->vibrato >> 4) + 2;
-    c->vibrate = (i->vibrato & 15) + 1;
-  }
-
-  if(!(c->trmstay & 0xf0)) {
-    c->trmwait = (i->tremwait & 0xf0) >> 3;
-    // PASCAL:    c->trmspeed = (i->mod_trem >> 4) & 15;
-    c->trmspeed = i->mod_trem >> 4;
-    c->trmrate = i->mod_trem & 15;
-    c->trmcount = 0;
-  }
-
-  if(!(c->trmstay & 0x0f)) {
-    c->trcwait = (i->tremwait & 15) << 1;
-    // PASCAL:    c->trcspeed = (i->car_trem >> 4) & 15;
-    c->trcspeed = i->car_trem >> 4;
-    c->trcrate = i->car_trem & 15;
-    c->trccount = 0;
-  }
-
-  c->arp_size = i->arpeggio & 15;
-  c->arp_speed = i->arpeggio >> 4;
-  memcpy(c->arp_tab, i->arp_tab, 12);
-  c->keycount = i->keyoff;
-  c->nextvol = c->glideto = c->finetune = c->vibcount = c->arp_pos = c->arp_count = 0;
-}
-
-inline void CldsPlayer::setregs(unsigned char reg, unsigned char val)
-{
-  if(fmchip[reg] == val) return;
-
-  fmchip[reg] = val;
-  opl->write(reg, val);
-}
-
-inline void CldsPlayer::setregs_adv(unsigned char reg, unsigned char mask,
-				    unsigned char val)
-{
-  setregs(reg, (fmchip[reg] & mask) | val);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/lds.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,676 @@
+/*
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * lds.cpp - LOUDNESS Player by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include <string.h>
+
+#include "lds.h"
+#include "debug.h"
+
+// Note frequency table (16 notes / octave)
+const unsigned short CldsPlayer::frequency[] = {
+  343, 344, 345, 347, 348, 349, 350, 352, 353, 354, 356, 357, 358,
+  359, 361, 362, 363, 365, 366, 367, 369, 370, 371, 373, 374, 375,
+  377, 378, 379, 381, 382, 384, 385, 386, 388, 389, 391, 392, 393,
+  395, 396, 398, 399, 401, 402, 403, 405, 406, 408, 409, 411, 412,
+  414, 415, 417, 418, 420, 421, 423, 424, 426, 427, 429, 430, 432,
+  434, 435, 437, 438, 440, 442, 443, 445, 446, 448, 450, 451, 453,
+  454, 456, 458, 459, 461, 463, 464, 466, 468, 469, 471, 473, 475,
+  476, 478, 480, 481, 483, 485, 487, 488, 490, 492, 494, 496, 497,
+  499, 501, 503, 505, 506, 508, 510, 512, 514, 516, 518, 519, 521,
+  523, 525, 527, 529, 531, 533, 535, 537, 538, 540, 542, 544, 546,
+  548, 550, 552, 554, 556, 558, 560, 562, 564, 566, 568, 571, 573,
+  575, 577, 579, 581, 583, 585, 587, 589, 591, 594, 596, 598, 600,
+  602, 604, 607, 609, 611, 613, 615, 618, 620, 622, 624, 627, 629,
+  631, 633, 636, 638, 640, 643, 645, 647, 650, 652, 654, 657, 659,
+  662, 664, 666, 669, 671, 674, 676, 678, 681, 683
+};
+
+// Vibrato (sine) table
+const unsigned char CldsPlayer::vibtab[] = {
+  0, 13, 25, 37, 50, 62, 74, 86, 98, 109, 120, 131, 142, 152, 162,
+  171, 180, 189, 197, 205, 212, 219, 225, 231, 236, 240, 244, 247,
+  250, 252, 254, 255, 255, 255, 254, 252, 250, 247, 244, 240, 236,
+  231, 225, 219, 212, 205, 197, 189, 180, 171, 162, 152, 142, 131,
+  120, 109, 98, 86, 74, 62, 50, 37, 25, 13
+};
+
+// Tremolo (sine * sine) table
+const unsigned char CldsPlayer::tremtab[] = {
+  0, 0, 1, 1, 2, 4, 5, 7, 10, 12, 15, 18, 21, 25, 29, 33, 37, 42, 47,
+  52, 57, 62, 67, 73, 79, 85, 90, 97, 103, 109, 115, 121, 128, 134,
+  140, 146, 152, 158, 165, 170, 176, 182, 188, 193, 198, 203, 208,
+  213, 218, 222, 226, 230, 234, 237, 240, 243, 245, 248, 250, 251,
+  253, 254, 254, 255, 255, 255, 254, 254, 253, 251, 250, 248, 245,
+  243, 240, 237, 234, 230, 226, 222, 218, 213, 208, 203, 198, 193,
+  188, 182, 176, 170, 165, 158, 152, 146, 140, 134, 127, 121, 115,
+  109, 103, 97, 90, 85, 79, 73, 67, 62, 57, 52, 47, 42, 37, 33, 29,
+  25, 21, 18, 15, 12, 10, 7, 5, 4, 2, 1, 1, 0
+};
+
+// 'maxsound' is maximum number of patches (instruments)
+// 'maxpos' is maximum number of entries in position list (orderlist)
+const unsigned short CldsPlayer::maxsound = 0x3f, CldsPlayer::maxpos = 0xff;
+
+/*** public methods *************************************/
+
+CldsPlayer::CldsPlayer(Copl *newopl)
+  : CPlayer(newopl), soundbank(0), positions(0), patterns(0)
+{
+}
+
+CldsPlayer::~CldsPlayer()
+{
+  if(soundbank) delete [] soundbank;
+  if(positions) delete [] positions;
+  if(patterns) delete [] patterns;
+}
+
+bool CldsPlayer::load(const std::string &filename, const CFileProvider &fp)
+{
+  binistream	*f;
+  unsigned int	i, j;
+  SoundBank	*sb;
+
+  // file validation section (actually just an extension check)
+  if(!fp.extension(filename, ".lds")) return false;
+  f = fp.open(filename); if(!f) return false;
+
+  // file load section (header)
+  mode = f->readInt(1);
+  if(mode > 2) { fp.close(f); return false; }
+  speed = f->readInt(2);
+  tempo = f->readInt(1);
+  pattlen = f->readInt(1);
+  for(i = 0; i < 9; i++) chandelay[i] = f->readInt(1);
+  regbd = f->readInt(1);
+
+  // load patches
+  numpatch = f->readInt(2);
+  soundbank = new SoundBank[numpatch];
+  for(i = 0; i < numpatch; i++) {
+    sb = &soundbank[i];
+    sb->mod_misc = f->readInt(1); sb->mod_vol = f->readInt(1);
+    sb->mod_ad = f->readInt(1); sb->mod_sr = f->readInt(1);
+    sb->mod_wave = f->readInt(1); sb->car_misc = f->readInt(1);
+    sb->car_vol = f->readInt(1); sb->car_ad = f->readInt(1);
+    sb->car_sr = f->readInt(1); sb->car_wave = f->readInt(1);
+    sb->feedback = f->readInt(1); sb->keyoff = f->readInt(1);
+    sb->portamento = f->readInt(1); sb->glide = f->readInt(1);
+    sb->finetune = f->readInt(1); sb->vibrato = f->readInt(1);
+    sb->vibdelay = f->readInt(1); sb->mod_trem = f->readInt(1);
+    sb->car_trem = f->readInt(1); sb->tremwait = f->readInt(1);
+    sb->arpeggio = f->readInt(1);
+    for(j = 0; j < 12; j++) sb->arp_tab[j] = f->readInt(1);
+    sb->start = f->readInt(2); sb->size = f->readInt(2);
+    sb->fms = f->readInt(1); sb->transp = f->readInt(2);
+    sb->midinst = f->readInt(1); sb->midvelo = f->readInt(1);
+    sb->midkey = f->readInt(1); sb->midtrans = f->readInt(1);
+    sb->middum1 = f->readInt(1); sb->middum2 = f->readInt(1);
+  }
+
+  // load positions
+  numposi = f->readInt(2);
+  positions = new Position[9 * numposi];
+  for(i = 0; i < numposi; i++)
+    for(j = 0; j < 9; j++) {
+      /*
+       * patnum is a pointer inside the pattern space, but patterns are 16bit
+       * word fields anyway, so it ought to be an even number (hopefully) and
+       * we can just divide it by 2 to get our array index of 16bit words.
+       */
+      positions[i * 9 + j].patnum = f->readInt(2) / 2;
+      positions[i * 9 + j].transpose = f->readInt(1);
+    }
+
+  AdPlug_LogWrite("CldsPlayer::load(\"%s\",fp): loading LOUDNESS file: mode = "
+		  "%d, pattlen = %d, numpatch = %d, numposi = %d\n",
+		  filename.c_str(), mode, pattlen, numpatch, numposi);
+
+  // load patterns
+  f->ignore(2);		// ignore # of digital sounds (not played by this player)
+  patterns = new unsigned short[(fp.filesize(f) - f->pos()) / 2 + 1];
+  for(i = 0; !f->eof(); i++)
+    patterns[i] = f->readInt(2);
+
+  fp.close(f);
+  rewind(0);
+  return true;
+}
+
+bool CldsPlayer::update()
+{
+  unsigned short	comword, freq, octave, chan, tune, wibc, tremc, arpreg;
+  bool			vbreak;
+  unsigned char		level, regnum, comhi, comlo;
+  int			i;
+  Channel		*c;
+
+  if(!playing) return false;
+
+  // handle fading
+  if(fadeonoff)
+    if(fadeonoff <= 128) {
+      if(allvolume > fadeonoff || allvolume == 0)
+	allvolume -= fadeonoff;
+      else {
+	allvolume = 1;
+	fadeonoff = 0;
+	if(hardfade != 0) {
+	  playing = false;
+	  hardfade = 0;
+	  for(i = 0; i < 9; i++)
+	    channel[i].keycount = 1;
+	}
+      }
+    } else
+      if((unsigned int)((allvolume + (0x100 - fadeonoff)) & 0xff) <= mainvolume)
+	allvolume += 0x100 - fadeonoff;
+      else {
+	allvolume = mainvolume;
+	fadeonoff = 0;
+      }
+
+  // handle channel delay
+  for(chan = 0; chan < 9; chan++) {
+    c = &channel[chan];
+    if(c->chancheat.chandelay)
+      if(!(--c->chancheat.chandelay))
+	playsound(c->chancheat.sound, chan, c->chancheat.high);
+  }
+
+  // handle notes
+  if(!tempo_now) {
+    vbreak = false;
+    for(chan = 0; chan < 9; chan++) {
+      c = &channel[chan];
+      if(!c->packwait) {
+	unsigned short	patnum = positions[posplay * 9 + chan].patnum;
+	unsigned char	transpose = positions[posplay * 9 + chan].transpose;
+
+	comword = patterns[patnum + c->packpos];
+	comhi = comword >> 8; comlo = comword & 0xff;
+	if(comword)
+	  if(comhi == 0x80)
+	    c->packwait = comlo;
+	  else
+	    if(comhi >= 0x80) {
+	      switch(comhi) {
+	      case 0xff:
+		c->volcar = (((c->volcar & 0x3f) * comlo) >> 6) & 0x3f;
+		if(fmchip[0xc0 + chan] & 1)
+		  c->volmod = (((c->volmod & 0x3f) * comlo) >> 6) & 0x3f;
+		break;
+	      case 0xfe:
+		tempo = comword & 0x3f;
+		break;
+	      case 0xfd:
+		c->nextvol = comlo;
+		break;
+	      case 0xfc:
+		playing = false;
+		// in real player there's also full keyoff here, but we don't need it
+		break;
+	      case 0xfb:
+		c->keycount = 1;
+		break;
+	      case 0xfa:
+		vbreak = true;
+		jumppos = (posplay + 1) & maxpos;
+		break;
+	      case 0xf9:
+		vbreak = true;
+		jumppos = comlo & maxpos;
+		jumping = 1;
+		if(jumppos < posplay) songlooped = true;
+		break;
+	      case 0xf8:
+		c->lasttune = 0;
+		break;
+	      case 0xf7:
+		c->vibwait = 0;
+		// PASCAL: c->vibspeed = ((comlo >> 4) & 15) + 2;
+		c->vibspeed = (comlo >> 4) + 2;
+		c->vibrate = (comlo & 15) + 1;
+		break;
+	      case 0xf6:
+		c->glideto = comlo;
+		break;
+	      case 0xf5:
+		c->finetune = comlo;
+		break;
+	      case 0xf4:
+		if(!hardfade) {
+		  allvolume = mainvolume = comlo;
+		  fadeonoff = 0;
+		}
+		break;
+	      case 0xf3:
+		if(!hardfade) fadeonoff = comlo;
+		break;
+	      case 0xf2:
+		c->trmstay = comlo;
+		break;
+	      case 0xf1:	// panorama
+	      case 0xf0:	// progch
+		// MIDI commands (unhandled)
+		AdPlug_LogWrite("CldsPlayer(): not handling MIDI command 0x%x, "
+				"value = 0x%x\n", comhi);
+		break;
+	      default:
+		if(comhi < 0xa0)
+		  c->glideto = comhi & 0x1f;
+		else
+		  AdPlug_LogWrite("CldsPlayer(): unknown command 0x%x encountered!"
+				  " value = 0x%x\n", comhi, comlo);
+		break;
+	      }
+	    } else {
+	      unsigned char	sound;
+	      unsigned short	high;
+	      signed char	transp = transpose & 127;
+
+	      /*
+	       * Originally, in assembler code, the player first shifted
+	       * logically left the transpose byte by 1 and then shifted
+	       * arithmetically right the same byte to achieve the final,
+	       * signed transpose value. Since we can't do arithmetic shifts
+	       * in C, we just duplicate the 7th bit into the 8th one and
+	       * discard the 8th one completely.
+	       */
+
+	      if(transpose & 64) transp |= 128;
+
+	      if(transpose & 128) {
+		sound = (comlo + transp) & maxsound;
+		high = comhi << 4;
+	      } else {
+		sound = comlo & maxsound;
+		high = (comhi + transp) << 4;
+	      }
+
+	      /*
+		PASCAL:
+	      sound = comlo & maxsound;
+	      high = (comhi + (((transpose + 0x24) & 0xff) - 0x24)) << 4;
+	      */
+
+	      if(!chandelay[chan])
+		playsound(sound, chan, high);
+	      else {
+		c->chancheat.chandelay = chandelay[chan];
+		c->chancheat.sound = sound;
+		c->chancheat.high = high;
+	      }
+	    }
+
+	c->packpos++;
+      } else
+	c->packwait--;
+    }
+
+    tempo_now = tempo;
+    /*
+      The continue table is updated here, but this is only used in the
+      original player, which can be paused in the middle of a song and then
+      unpaused. Since AdPlug does all this for us automatically, we don't
+      have a continue table here. The continue table update code is noted
+      here for reference only.
+
+      if(!pattplay) {
+        conttab[speed & maxcont].position = posplay & 0xff;
+        conttab[speed & maxcont].tempo = tempo;
+      }
+    */
+    pattplay++;
+    if(vbreak) {
+      pattplay = 0;
+      for(i = 0; i < 9; i++) channel[i].packpos = channel[i].packwait = 0;
+      posplay = jumppos;
+    } else
+      if(pattplay >= pattlen) {
+	pattplay = 0;
+	for(i = 0; i < 9; i++) channel[i].packpos = channel[i].packwait = 0;
+	posplay = (posplay + 1) & maxpos;
+      }
+  } else
+    tempo_now--;
+
+  // make effects
+  for(chan = 0; chan < 9; chan++) {
+    c = &channel[chan];
+    regnum = op_table[chan];
+    if(c->keycount > 0) {
+      if(c->keycount == 1)
+	setregs_adv(0xb0 + chan, 0xdf, 0);
+      c->keycount--;
+    }
+
+    // arpeggio
+    if(c->arp_size == 0)
+      arpreg = 0;
+    else {
+      arpreg = c->arp_tab[c->arp_pos] << 4;
+      if(arpreg == 0x800) {
+	if(c->arp_pos > 0) c->arp_tab[0] = c->arp_tab[c->arp_pos - 1];
+	c->arp_size = 1; c->arp_pos = 0;
+	arpreg = c->arp_tab[0] << 4;
+      }
+
+      if(c->arp_count == c->arp_speed) {
+	c->arp_pos++;
+	if(c->arp_pos >= c->arp_size) c->arp_pos = 0;
+	c->arp_count = 0;
+      } else
+	c->arp_count++;
+    }
+
+    // glide & portamento
+    if(c->lasttune && (c->lasttune != c->gototune)) {
+      if(c->lasttune > c->gototune) {
+	if(c->lasttune - c->gototune < c->portspeed)
+	  c->lasttune = c->gototune;
+	else
+	  c->lasttune -= c->portspeed;
+      } else {
+	if(c->gototune - c->lasttune < c->portspeed)
+	  c->lasttune = c->gototune;
+	else
+	  c->lasttune += c->portspeed;
+      }
+
+      if(arpreg >= 0x800)
+	arpreg = c->lasttune - (arpreg ^ 0xff0) - 16;
+      else
+	arpreg += c->lasttune;
+
+      freq = frequency[arpreg % (12 * 16)];
+      octave = arpreg / (12 * 16) - 1;
+      setregs(0xa0 + chan, freq & 0xff);
+      setregs_adv(0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf);
+    } else {
+      // vibrato
+      if(!c->vibwait) {
+	if(c->vibrate) {
+	  wibc = vibtab[c->vibcount & 0x3f] * c->vibrate;
+
+	  if((c->vibcount & 0x40) == 0)
+	    tune = c->lasttune + (wibc >> 8);
+	  else
+	    tune = c->lasttune - (wibc >> 8);
+
+	  if(arpreg >= 0x800)
+	    tune = tune - (arpreg ^ 0xff0) - 16;
+	  else
+	    tune += arpreg;
+
+	  freq = frequency[tune % (12 * 16)];
+	  octave = tune / (12 * 16) - 1;
+	  setregs(0xa0 + chan, freq & 0xff);
+	  setregs_adv(0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf);
+	  c->vibcount += c->vibspeed;
+	} else
+	  if(c->arp_size != 0) {	// no vibrato, just arpeggio
+	    if(arpreg >= 0x800)
+	      tune = c->lasttune - (arpreg ^ 0xff0) - 16;
+	    else
+	      tune = c->lasttune + arpreg;
+
+	    freq = frequency[tune % (12 * 16)];
+	    octave = tune / (12 * 16) - 1;
+	    setregs(0xa0 + chan, freq & 0xff);
+	    setregs_adv(0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf);
+	  }
+      } else {	// no vibrato, just arpeggio
+	c->vibwait--;
+
+	if(c->arp_size != 0) {
+	  if(arpreg >= 0x800)
+	    tune = c->lasttune - (arpreg ^ 0xff0) - 16;
+	  else
+	    tune = c->lasttune + arpreg;
+
+	  freq = frequency[tune % (12 * 16)];
+	  octave = tune / (12 * 16) - 1;
+	  setregs(0xa0 + chan, freq & 0xff);
+	  setregs_adv(0xb0 + chan, 0x20, ((octave << 2) + (freq >> 8)) & 0xdf);
+	}
+      }
+    }
+
+    // tremolo (modulator)
+    if(!c->trmwait) {
+      if(c->trmrate) {
+	tremc = tremtab[c->trmcount & 0x7f] * c->trmrate;
+	if((tremc >> 8) <= (c->volmod & 0x3f))
+	  level = (c->volmod & 0x3f) - (tremc >> 8);
+	else
+	  level = 0;
+
+	if(allvolume != 0 && (fmchip[0xc0 + chan] & 1))
+	  setregs_adv(0x40 + regnum, 0xc0, ((level * allvolume) >> 8) ^ 0x3f);
+	else
+	  setregs_adv(0x40 + regnum, 0xc0, level ^ 0x3f);
+
+	c->trmcount += c->trmspeed;
+      } else
+	if(allvolume != 0 && (fmchip[0xc0 + chan] & 1))
+	  setregs_adv(0x40 + regnum, 0xc0, ((((c->volmod & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
+	else
+	  setregs_adv(0x40 + regnum, 0xc0, (c->volmod ^ 0x3f) & 0x3f);
+    } else {
+      c->trmwait--;
+      if(allvolume != 0 && (fmchip[0xc0 + chan] & 1))
+	setregs_adv(0x40 + regnum, 0xc0, ((((c->volmod & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
+    }
+
+    // tremolo (carrier)
+    if(!c->trcwait) {
+      if(c->trcrate) {
+	tremc = tremtab[c->trccount & 0x7f] * c->trcrate;
+	if((tremc >> 8) <= (c->volcar & 0x3f))
+	  level = (c->volcar & 0x3f) - (tremc >> 8);
+	else
+	  level = 0;
+
+	if(allvolume != 0)
+	  setregs_adv(0x43 + regnum, 0xc0, ((level * allvolume) >> 8) ^ 0x3f);
+	else
+	  setregs_adv(0x43 + regnum, 0xc0, level ^ 0x3f);
+	c->trccount += c->trcspeed;
+      } else
+	if(allvolume != 0)
+	  setregs_adv(0x43 + regnum, 0xc0, ((((c->volcar & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
+	else
+	  setregs_adv(0x43 + regnum, 0xc0, (c->volcar ^ 0x3f) & 0x3f);
+    } else {
+      c->trcwait--;
+      if(allvolume != 0)
+	setregs_adv(0x43 + regnum, 0xc0, ((((c->volcar & 0x3f) * allvolume) >> 8) ^ 0x3f) & 0x3f);
+    }
+  }
+
+  return (!playing || songlooped) ? false : true;
+}
+
+void CldsPlayer::rewind(int subsong)
+{
+  int i;
+
+  // init all with 0
+  tempo_now = 3; playing = true; songlooped = false;
+  jumping = fadeonoff = allvolume = hardfade = pattplay = posplay = jumppos =
+    mainvolume = 0;
+  memset(channel, 0, sizeof(channel));
+  memset(fmchip, 0, sizeof(fmchip));
+
+  // OPL2 init
+  opl->init();				// Reset OPL chip
+  opl->write(1, 0x20);
+  opl->write(8, 0);
+  opl->write(0xbd, regbd);
+
+  for(i = 0; i < 9; i++) {
+    opl->write(0x20 + op_table[i], 0);
+    opl->write(0x23 + op_table[i], 0);
+    opl->write(0x40 + op_table[i], 0x3f);
+    opl->write(0x43 + op_table[i], 0x3f);
+    opl->write(0x60 + op_table[i], 0xff);
+    opl->write(0x63 + op_table[i], 0xff);
+    opl->write(0x80 + op_table[i], 0xff);
+    opl->write(0x83 + op_table[i], 0xff);
+    opl->write(0xe0 + op_table[i], 0);
+    opl->write(0xe3 + op_table[i], 0);
+    opl->write(0xa0 + i, 0);
+    opl->write(0xb0 + i, 0);
+    opl->write(0xc0 + i, 0);
+  }
+}
+
+/*** private methods *************************************/
+
+void CldsPlayer::playsound(int inst_number, int channel_number, int tunehigh)
+{
+  Channel		*c = &channel[channel_number];		// current channel
+  SoundBank		*i = &soundbank[inst_number];		// current instrument
+  unsigned int		regnum = op_table[channel_number];	// channel's OPL2 register
+  unsigned char		volcalc, octave;
+  unsigned short	freq;
+
+  // set fine tune
+  tunehigh += ((i->finetune + c->finetune + 0x80) & 0xff) - 0x80;
+
+  // arpeggio handling
+  if(!i->arpeggio) {
+    unsigned short	arpcalc = i->arp_tab[0] << 4;
+
+    if(arpcalc > 0x800)
+      tunehigh = tunehigh - (arpcalc ^ 0xff0) - 16;
+    else
+      tunehigh += arpcalc;
+  }
+
+  // glide handling
+  if(c->glideto != 0) {
+    c->gototune = tunehigh;
+    c->portspeed = c->glideto;
+    c->glideto = c->finetune = 0;
+    return;
+  }
+
+  // set modulator registers
+  setregs(0x20 + regnum, i->mod_misc);
+  volcalc = i->mod_vol;
+  if(!c->nextvol || !(i->feedback & 1))
+    c->volmod = volcalc;
+  else
+    c->volmod = (volcalc & 0xc0) | ((((volcalc & 0x3f) * c->nextvol) >> 6));
+
+  if((i->feedback & 1) == 1 && allvolume != 0)
+    setregs(0x40 + regnum, ((c->volmod & 0xc0) | (((c->volmod & 0x3f) * allvolume) >> 8)) ^ 0x3f);
+  else
+    setregs(0x40 + regnum, c->volmod ^ 0x3f);
+  setregs(0x60 + regnum, i->mod_ad);
+  setregs(0x80 + regnum, i->mod_sr);
+  setregs(0xe0 + regnum, i->mod_wave);
+
+  // Set carrier registers
+  setregs(0x23 + regnum, i->car_misc);
+  volcalc = i->car_vol;
+  if(!c->nextvol)
+    c->volcar = volcalc;
+  else
+    c->volcar = (volcalc & 0xc0) | ((((volcalc & 0x3f) * c->nextvol) >> 6));
+
+  if(allvolume)
+    setregs(0x43 + regnum, ((c->volcar & 0xc0) | (((c->volcar & 0x3f) * allvolume) >> 8)) ^ 0x3f);
+  else
+    setregs(0x43 + regnum, c->volcar ^ 0x3f);
+  setregs(0x63 + regnum, i->car_ad);
+  setregs(0x83 + regnum, i->car_sr);
+  setregs(0xe3 + regnum, i->car_wave);
+  setregs(0xc0 + channel_number, i->feedback);
+  setregs_adv(0xb0 + channel_number, 0xdf, 0);		// key off
+
+  freq = frequency[tunehigh % (12 * 16)];
+  octave = tunehigh / (12 * 16) - 1;
+  if(!i->glide) {
+    if(!i->portamento || !c->lasttune) {
+      setregs(0xa0 + channel_number, freq & 0xff);
+      setregs(0xb0 + channel_number, (octave << 2) + 0x20 + (freq >> 8));
+      c->lasttune = c->gototune = tunehigh;
+    } else {
+      c->gototune = tunehigh;
+      c->portspeed = i->portamento;
+      setregs_adv(0xb0 + channel_number, 0xdf, 0x20);	// key on
+    }
+  } else {
+    setregs(0xa0 + channel_number, freq & 0xff);
+    setregs(0xb0 + channel_number, (octave << 2) + 0x20 + (freq >> 8));
+    c->lasttune = tunehigh;
+    c->gototune = tunehigh + ((i->glide + 0x80) & 0xff) - 0x80;	// set destination
+    c->portspeed = i->portamento;
+  }
+
+  if(!i->vibrato)
+    c->vibwait = c->vibspeed = c->vibrate = 0;
+  else {
+    c->vibwait = i->vibdelay;
+    // PASCAL:    c->vibspeed = ((i->vibrato >> 4) & 15) + 1;
+    c->vibspeed = (i->vibrato >> 4) + 2;
+    c->vibrate = (i->vibrato & 15) + 1;
+  }
+
+  if(!(c->trmstay & 0xf0)) {
+    c->trmwait = (i->tremwait & 0xf0) >> 3;
+    // PASCAL:    c->trmspeed = (i->mod_trem >> 4) & 15;
+    c->trmspeed = i->mod_trem >> 4;
+    c->trmrate = i->mod_trem & 15;
+    c->trmcount = 0;
+  }
+
+  if(!(c->trmstay & 0x0f)) {
+    c->trcwait = (i->tremwait & 15) << 1;
+    // PASCAL:    c->trcspeed = (i->car_trem >> 4) & 15;
+    c->trcspeed = i->car_trem >> 4;
+    c->trcrate = i->car_trem & 15;
+    c->trccount = 0;
+  }
+
+  c->arp_size = i->arpeggio & 15;
+  c->arp_speed = i->arpeggio >> 4;
+  memcpy(c->arp_tab, i->arp_tab, 12);
+  c->keycount = i->keyoff;
+  c->nextvol = c->glideto = c->finetune = c->vibcount = c->arp_pos = c->arp_count = 0;
+}
+
+inline void CldsPlayer::setregs(unsigned char reg, unsigned char val)
+{
+  if(fmchip[reg] == val) return;
+
+  fmchip[reg] = val;
+  opl->write(reg, val);
+}
+
+inline void CldsPlayer::setregs_adv(unsigned char reg, unsigned char mask,
+				    unsigned char val)
+{
+  setregs(reg, (fmchip[reg] & mask) | val);
+}
--- a/Plugins/Input/adplug/core/mad.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,126 +0,0 @@
-/*
-  Adplug - Replayer for many OPL2/OPL3 audio file formats.
-  Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-  mad.cpp - MAD loader by Riven the Mage <riven@ok.ru>
-*/
-
-#include "mad.h"
-
-/* -------- Public Methods -------------------------------- */
-
-CPlayer *CmadLoader::factory(Copl *newopl)
-{
-  return new CmadLoader(newopl);
-}
-
-bool CmadLoader::load(const std::string &filename, const CFileProvider &fp)
-{
-  binistream *f = fp.open(filename); if(!f) return false;
-  const unsigned char conv_inst[10] = { 2,1,10,9,4,3,6,5,8,7 };
-  unsigned int i, j, k, t = 0;
-
-  // 'MAD+' - signed ?
-  char id[4]; f->readString(id, 4);
-  if (strncmp(id,"MAD+",4)) { fp.close(f); return false; }
-
-  // load instruments
-  for(i = 0; i < 9; i++) {
-    f->readString(instruments[i].name, 8);
-    for(j = 0; j < 12; j++) instruments[i].data[j] = f->readInt(1);
-  }
-
-  f->ignore(1);
-
-  // data for Protracker
-  length = f->readInt(1); nop = f->readInt(1); timer = f->readInt(1);
-
-  // init CmodPlayer
-  realloc_instruments(9);
-  realloc_order(length);
-  realloc_patterns(nop,32,9);
-  init_trackord();
-
-  // load tracks
-  for(i = 0; i < nop; i++)
-    for(k = 0; k < 32; k++)
-      for(j = 0; j < 9; j++) {
-	t = i * 9 + j;
-
-	// read event
-	unsigned char event = f->readInt(1);
-
-	// convert event
-	if (event < 0x61)
-	  tracks[t][k].note = event;
-	if (event == 0xFF) // 0xFF: Release note
-	  tracks[t][k].command = 8;
-	if (event == 0xFE) // 0xFE: Pattern Break
-	  tracks[t][k].command = 13;
-      }
-
-  // load order
-  for(i = 0; i < length; i++) order[i] = f->readInt(1) - 1;
-
-  fp.close(f);
-
-  // convert instruments
-  for(i = 0; i < 9; i++)
-    for(j = 0; j < 10; j++)
-      inst[i].data[conv_inst[j]] = instruments[i].data[j];
-
-  // data for Protracker
-  restartpos = 0;
-  initspeed = 1;
-
-  rewind(0);
-  return true;
-}
-
-void CmadLoader::rewind(int subsong)
-{
-	CmodPlayer::rewind(subsong);
-
-	// default instruments
-	for (int i=0;i<9;i++)
-	{
-		channel[i].inst = i;
-
-		channel[i].vol1 = 63 - (inst[i].data[10] & 63);
-		channel[i].vol2 = 63 - (inst[i].data[9] & 63);
-	}
-}
-
-float CmadLoader::getrefresh()
-{
-	return (float)timer;
-}
-
-std::string CmadLoader::gettype()
-{
-	return std::string("Mlat Adlib Tracker");
-}
-
-std::string CmadLoader::getinstrument(unsigned int n)
-{
-	return std::string(instruments[n].name,8);
-}
-
-unsigned int CmadLoader::getinstruments()
-{
-	return 9;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/mad.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,126 @@
+/*
+  Adplug - Replayer for many OPL2/OPL3 audio file formats.
+  Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  mad.cpp - MAD loader by Riven the Mage <riven@ok.ru>
+*/
+
+#include "mad.h"
+
+/* -------- Public Methods -------------------------------- */
+
+CPlayer *CmadLoader::factory(Copl *newopl)
+{
+  return new CmadLoader(newopl);
+}
+
+bool CmadLoader::load(const std::string &filename, const CFileProvider &fp)
+{
+  binistream *f = fp.open(filename); if(!f) return false;
+  const unsigned char conv_inst[10] = { 2,1,10,9,4,3,6,5,8,7 };
+  unsigned int i, j, k, t = 0;
+
+  // 'MAD+' - signed ?
+  char id[4]; f->readString(id, 4);
+  if (strncmp(id,"MAD+",4)) { fp.close(f); return false; }
+
+  // load instruments
+  for(i = 0; i < 9; i++) {
+    f->readString(instruments[i].name, 8);
+    for(j = 0; j < 12; j++) instruments[i].data[j] = f->readInt(1);
+  }
+
+  f->ignore(1);
+
+  // data for Protracker
+  length = f->readInt(1); nop = f->readInt(1); timer = f->readInt(1);
+
+  // init CmodPlayer
+  realloc_instruments(9);
+  realloc_order(length);
+  realloc_patterns(nop,32,9);
+  init_trackord();
+
+  // load tracks
+  for(i = 0; i < nop; i++)
+    for(k = 0; k < 32; k++)
+      for(j = 0; j < 9; j++) {
+	t = i * 9 + j;
+
+	// read event
+	unsigned char event = f->readInt(1);
+
+	// convert event
+	if (event < 0x61)
+	  tracks[t][k].note = event;
+	if (event == 0xFF) // 0xFF: Release note
+	  tracks[t][k].command = 8;
+	if (event == 0xFE) // 0xFE: Pattern Break
+	  tracks[t][k].command = 13;
+      }
+
+  // load order
+  for(i = 0; i < length; i++) order[i] = f->readInt(1) - 1;
+
+  fp.close(f);
+
+  // convert instruments
+  for(i = 0; i < 9; i++)
+    for(j = 0; j < 10; j++)
+      inst[i].data[conv_inst[j]] = instruments[i].data[j];
+
+  // data for Protracker
+  restartpos = 0;
+  initspeed = 1;
+
+  rewind(0);
+  return true;
+}
+
+void CmadLoader::rewind(int subsong)
+{
+	CmodPlayer::rewind(subsong);
+
+	// default instruments
+	for (int i=0;i<9;i++)
+	{
+		channel[i].inst = i;
+
+		channel[i].vol1 = 63 - (inst[i].data[10] & 63);
+		channel[i].vol2 = 63 - (inst[i].data[9] & 63);
+	}
+}
+
+float CmadLoader::getrefresh()
+{
+	return (float)timer;
+}
+
+std::string CmadLoader::gettype()
+{
+	return std::string("Mlat Adlib Tracker");
+}
+
+std::string CmadLoader::getinstrument(unsigned int n)
+{
+	return std::string(instruments[n].name,8);
+}
+
+unsigned int CmadLoader::getinstruments()
+{
+	return 9;
+}
--- a/Plugins/Input/adplug/core/mid.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1088 +0,0 @@
-/*
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *
- * MIDI & MIDI-like file player - Last Update: 10/15/2005
- *                  by Phil Hassey - www.imitationpickles.org
- *                                   philhassey@hotmail.com
- *
- * Can play the following
- *      .LAA - a raw save of a Lucas Arts Adlib music
- *             or
- *             a raw save of a LucasFilm Adlib music
- *      .CMF - Creative Music Format
- *      .SCI - the sierra "midi" format.
- *             Files must be in the form
- *             xxxNAME.sci
- *             So that the loader can load the right patch file:
- *             xxxPATCH.003  (patch.003 must be saved from the
- *                            sierra resource from each game.)
- *
- * 1/9/2006: audacious libadplug
- *      Status:  MID not as fine as originally thought. Removing general MIDI detector so timidity handles these files instead.
- *      
- * 6/2/2000:  v1.0 relased by phil hassey
- *      Status:  LAA is almost perfect
- *                      - some volumes are a bit off (intrument too quiet)
- *               MID is fine (who wants to listen to MIDI vid adlib anyway)
- *               CMF is okay (still needs the adlib rythm mode implemented
- *                            for real)
- * 6/6/2000:
- *      Status:  SCI:  there are two SCI formats, orginal and advanced.
- *                    original:  (Found in SCI/EGA Sierra Adventures)
- *                               played almost perfectly, I believe
- *                               there is one mistake in the instrument
- *                               loader that causes some sounds to
- *                               not be quite right.  Most sounds are fine.
- *                    advanced:  (Found in SCI/VGA Sierra Adventures)
- *                               These are multi-track files.  (Thus the
- *                               player had to be modified to work with
- *                               them.)  This works fine.
- *                               There are also multiple tunes in each file.
- *                               I think some of them are supposed to be
- *                               played at the same time, but I'm not sure
- *                               when.
- * 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
- *                    LucasArts files.
- *  FreeSCI - for some information on the sci music files
- *  SD - the SCI Decoder (to get all .sci out of the Sierra files)
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <math.h>
-#include <string.h>
-#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);
-    return(data[pos]);
-}
-
-unsigned long CmidPlayer::getnexti(unsigned long num)
-{
-	unsigned long v=0;
-	unsigned long i;
-
-    for (i=0; i<num; i++)
-        {
-        v+=(datalook(pos)<<(8*i)); pos++;
-        }
-    return(v);
-}
-
-unsigned long CmidPlayer::getnext(unsigned long num)
-{
-	unsigned long v=0;
-	unsigned long i;
-
-    for (i=0; i<num; i++)
-        {
-        v<<=8;
-        v+=datalook(pos); pos++;
-        }
-    return(v);
-}
-
-unsigned long CmidPlayer::getval()
-{
-    int v=0;
-	unsigned char b;
-
-    b=(unsigned char)getnext(1);
-	v=b&0x7f;
-	while ((b&0x80) !=0)
-		{
-        b=(unsigned char)getnext(1);
-        v = (v << 7) + (b & 0x7F);
-		}
-	return(v);
-}
-
-bool CmidPlayer::load_sierra_ins(const std::string &fname, const CFileProvider &fp)
-{
-    long i,j,k,l;
-    unsigned char ins[28];
-    char *pfilename;
-    binistream *f;
-
-    pfilename = (char *)malloc(fname.length()+9);
-    strcpy(pfilename,fname.c_str());
-    j=0;
-    for(i=strlen(pfilename)-1; i >= 0; i--)
-      if(pfilename[i] == '/' || pfilename[i] == '\\') {
-	j = i+1;
-	break;
-      }
-    sprintf(pfilename+j+3,"patch.003");
-
-    f = fp.open(pfilename);
-    free(pfilename);
-    if(!f) return false;
-
-    f->ignore(2);
-    stins = 0;
-    for (i=0; i<2; i++)
-        {
-        for (k=0; k<48; k++)
-            {
-            l=i*48+k;
-            midiprintf ("\n%2d: ",l);
-            for (j=0; j<28; j++)
-                ins[j] = f->readInt(1);
-
-            myinsbank[l][0]=
-                (ins[9]*0x80) + (ins[10]*0x40) +
-                (ins[5]*0x20) + (ins[11]*0x10) +
-                ins[1];   //1=ins5
-            myinsbank[l][1]=
-                (ins[22]*0x80) + (ins[23]*0x40) +
-                (ins[18]*0x20) + (ins[24]*0x10) +
-                ins[14];  //1=ins18
-
-            myinsbank[l][2]=(ins[0]<<6)+ins[8];
-            myinsbank[l][3]=(ins[13]<<6)+ins[21];
-
-            myinsbank[l][4]=(ins[3]<<4)+ins[6];
-            myinsbank[l][5]=(ins[16]<<4)+ins[19];
-            myinsbank[l][6]=(ins[4]<<4)+ins[7];
-            myinsbank[l][7]=(ins[17]<<4)+ins[20];
-
-            myinsbank[l][8]=ins[26];
-            myinsbank[l][9]=ins[27];
-
-            myinsbank[l][10]=((ins[2]<<1))+(1-(ins[12]&1));
-            //(ins[12] ? 0:1)+((ins[2]<<1));
-
-            for (j=0; j<11; j++)
-                midiprintf ("%02X ",myinsbank[l][j]);
-			stins++;
-            }
-		f->ignore(2);
-        }
-
-    fp.close(f);
-    memcpy(smyinsbank, myinsbank, 128 * 16);
-    return true;
-}
-
-void CmidPlayer::sierra_next_section()
-{
-    int i,j;
-
-    for (i=0; i<16; i++)
-        track[i].on=0;
-
-    midiprintf("\n\nnext adv sierra section:\n");
-
-    pos=sierra_pos;
-    i=0;j=0;
-    while (i!=0xff)
-       {
-       getnext(1);
-       curtrack=j; j++;
-       track[curtrack].on=1;
-	   track[curtrack].spos = getnext(1);
-	   track[curtrack].spos += (getnext(1) << 8) + 4;	//4 best usually +3? not 0,1,2 or 5
-//       track[curtrack].spos=getnext(1)+(getnext(1)<<8)+4;		// dynamite!: doesn't optimize correctly!!
-       track[curtrack].tend=flen; //0xFC will kill it
-       track[curtrack].iwait=0;
-       track[curtrack].pv=0;
-       midiprintf ("track %d starts at %lx\n",curtrack,track[curtrack].spos);
-
-       getnext(2);
-       i=getnext(1);
-       }
-    getnext(2);
-    deltas=0x20;
-    sierra_pos=pos;
-    //getch();
-
-    fwait=0;
-    doing=1;
-}
-
-bool CmidPlayer::load(const std::string &filename, const CFileProvider &fp)
-{
-    binistream *f = fp.open(filename); if(!f) return false;
-    int good;
-    unsigned char s[6];
-
-    f->readString((char *)s, 6);
-    good=0;
-    subsongs=0;
-    switch(s[0])
-        {
-        case 'A':
-            if (s[1]=='D' && s[2]=='L') good=FILE_LUCAS;
-            break;
-        case 'C':
-            if (s[1]=='T' && s[2]=='M' && s[3]=='F') good=FILE_CMF;
-            break;
-        case 0x84:
-            if (s[1]==0x00 && load_sierra_ins(filename, fp))
-                if (s[2]==0xf0)
-                    good=FILE_ADVSIERRA;
-                    else
-                    good=FILE_SIERRA;
-            break;
-        default:
-            if (s[4]=='A' && s[5]=='D') good=FILE_OLDLUCAS;
-            break;
-        }
-
-    if (good!=0)
-		subsongs=1;
-    else {
-      fp.close(f);
-      return false;
-    }
-
-    type=good;
-    f->seek(0);
-    flen = fp.filesize(f);
-    data = new unsigned char [flen];
-    f->readString((char *)data, flen);
-
-    fp.close(f);
-    rewind(0);
-    return true;
-}
-
-void CmidPlayer::midi_write_adlib(unsigned int r, unsigned char v)
-{
-  opl->write(r,v);
-  adlib_data[r]=v;
-}
-
-void CmidPlayer::midi_fm_instrument(int voice, unsigned char *inst)
-{
-    if ((adlib_style&SIERRA_STYLE)!=0)
-        midi_write_adlib(0xbd,0);  //just gotta make sure this happens..
-                                      //'cause who knows when it'll be
-                                      //reset otherwise.
-
-
-    midi_write_adlib(0x20+adlib_opadd[voice],inst[0]);
-    midi_write_adlib(0x23+adlib_opadd[voice],inst[1]);
-
-    if ((adlib_style&LUCAS_STYLE)!=0)
-        {
-        midi_write_adlib(0x43+adlib_opadd[voice],0x3f);
-        if ((inst[10] & 1)==0)
-            midi_write_adlib(0x40+adlib_opadd[voice],inst[2]);
-            else
-            midi_write_adlib(0x40+adlib_opadd[voice],0x3f);
-        }
-        else
-        {
-        if ((adlib_style&SIERRA_STYLE)!=0)
-            {
-            midi_write_adlib(0x40+adlib_opadd[voice],inst[2]);
-            midi_write_adlib(0x43+adlib_opadd[voice],inst[3]);
-            }
-            else
-            {
-            midi_write_adlib(0x40+adlib_opadd[voice],inst[2]);
-            if ((inst[10] & 1)==0)
-                midi_write_adlib(0x43+adlib_opadd[voice],inst[3]);
-                else
-                midi_write_adlib(0x43+adlib_opadd[voice],0);
-            }
-        }
-
-    midi_write_adlib(0x60+adlib_opadd[voice],inst[4]);
-    midi_write_adlib(0x63+adlib_opadd[voice],inst[5]);
-    midi_write_adlib(0x80+adlib_opadd[voice],inst[6]);
-    midi_write_adlib(0x83+adlib_opadd[voice],inst[7]);
-    midi_write_adlib(0xe0+adlib_opadd[voice],inst[8]);
-    midi_write_adlib(0xe3+adlib_opadd[voice],inst[9]);
-
-    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;
-
-    if ((adlib_style&SIERRA_STYLE)==0)  //sierra likes it loud!
-    {
-    vol=volume>>2;
-
-    if ((adlib_style&LUCAS_STYLE)!=0)
-        {
-        if ((adlib_data[0xc0+voice]&1)==1)
-            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)));
-        }
-        else
-        {
-        if ((adlib_data[0xc0+voice]&1)==1)
-            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)));
-        }
-    }
-}
-
-void CmidPlayer::midi_fm_playnote(int voice, int note, int volume)
-{
-    int freq=fnums[note%12];
-    int oct=note/12;
-	int c;
-
-    midi_fm_volume(voice,volume);
-    midi_write_adlib(0xa0+voice,(unsigned char)(freq&0xff));
-
-	c=((freq&0x300) >> 8)+(oct<<2) + (adlib_mode == ADLIB_MELODIC || voice < 6 ? (1<<5) : 0);
-    midi_write_adlib(0xb0+voice,(unsigned char)c);
-}
-
-void CmidPlayer::midi_fm_endnote(int voice)
-{
-    //midi_fm_volume(voice,0);
-    //midi_write_adlib(0xb0+voice,0);
-
-    midi_write_adlib(0xb0+voice,(unsigned char)(adlib_data[0xb0+voice]&(255-32)));
-}
-
-void CmidPlayer::midi_fm_reset()
-{
-    int i;
-
-    opl->init();
-
-    for (i=0; i<256; i++)
-        midi_write_adlib(i,0);
-
-    midi_write_adlib(0x01, 0x20);
-    midi_write_adlib(0xBD,0xc0);
-}
-
-bool CmidPlayer::update()
-{
-    long w,v,note,vel,ctrl,nv,x,l,lnum;
-    int i=0,j,c;
-    int on,onl,numchan;
-    int ret;
-
-    if (doing == 1)
-        {
-        // just get the first wait and ignore it :>
-        for (curtrack=0; curtrack<16; curtrack++)
-            if (track[curtrack].on)
-                {
-                pos=track[curtrack].pos;
-                if (type != FILE_SIERRA && type !=FILE_ADVSIERRA)
-                    track[curtrack].iwait+=getval();
-                    else
-                    track[curtrack].iwait+=getnext(1);
-                track[curtrack].pos=pos;
-                }
-        doing=0;
-        }
-
-    iwait=0;
-    ret=1;
-
-    while (iwait==0 && ret==1)
-        {
-        for (curtrack=0; curtrack<16; curtrack++)
-        if (track[curtrack].on && track[curtrack].iwait==0 &&
-            track[curtrack].pos < track[curtrack].tend)
-        {
-        pos=track[curtrack].pos;
-
-		v=getnext(1);
-
-        //  This is to do implied MIDI events.
-        if (v<0x80) {v=track[curtrack].pv; pos--;}
-        track[curtrack].pv=(unsigned char)v;
-
-		c=v&0x0f;
-        midiprintf ("[%2X]",v);
-        switch(v&0xf0)
-            {
-			case 0x80: /*note off*/
-				note=getnext(1); vel=getnext(1);
-                for (i=0; i<9; i++)
-                    if (chp[i][0]==c && chp[i][1]==note)
-                        {
-                        midi_fm_endnote(i);
-                        chp[i][0]=-1;
-                        }
-                break;
-            case 0x90: /*note on*/
-              //  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<18; i++)
-                    chp[i][2]++;
-
-		  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<numchan; i++)
-			  if (chp[i][2]>onl)
-			    { onl=chp[i][2]; on=i; }
-		      }
-
-		    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
- 		      midi_fm_percussion(c, ch[c].ins);
-
-                    if ((adlib_style&MIDI_STYLE)!=0)
-                        {
-                        nv=((ch[c].vol*vel)/128);
-                        if ((adlib_style&LUCAS_STYLE)!=0)
-                            nv*=2;
-                        if (nv>127) nv=127;
-                        nv=my_midi_fm_vol_table[nv];
-                        if ((adlib_style&LUCAS_STYLE)!=0)
-                            nv=(int)((float)sqrt((float)nv)*11);
-                        }
-                        else
-                        {
-                        nv=vel;
-                        }
-
-		    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
-                    {
-                    if (vel==0)  //same code as end note
-                        {
-                        for (i=0; i<9; i++)
-                            if (chp[i][0]==c && chp[i][1]==note)
-                                {
-                               // midi_fm_volume(i,0);  // really end the note
-                                midi_fm_endnote(i);
-                                chp[i][0]=-1;
-                                }
-                        }
-                        else
-                        {        // i forget what this is for.
-                        chp[on][0]=-1;
-                        chp[on][2]=0;
-                        }
-                    }
-                midiprintf(" [%d:%d:%d:%d]\n",c,ch[c].inum,note,vel);
-                }
-                else
-                midiprintf ("off");
-                break;
-            case 0xa0: /*key after touch */
-                note=getnext(1); vel=getnext(1);
-                /*  //this might all be good
-                for (i=0; i<9; i++)
-                    if (chp[i][0]==c & chp[i][1]==note)
-                        
-midi_fm_playnote(i,note+cnote[c],my_midi_fm_vol_table[(cvols[c]*vel)/128]*2);
-                */
-                break;
-            case 0xb0: /*control change .. pitch bend? */
-                ctrl=getnext(1); vel=getnext(1);
-
-                switch(ctrl)
-                    {
-                    case 0x07:
-                        midiprintf ("(pb:%d: %d %d)",c,ctrl,vel);
-                        ch[c].vol=vel;
-                        midiprintf("vol");
-                        break;
-                    case 0x67:
-                        midiprintf ("\n\nhere:%d\n\n",vel);
-                        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;
-            case 0xd0: /*chanel touch*/
-                x=getnext(1);
-                break;
-            case 0xe0: /*pitch wheel*/
-                x=getnext(1);
-                x=getnext(1);
-                break;
-            case 0xf0:
-                switch(v)
-                    {
-                    case 0xf0:
-                    case 0xf7: /*sysex*/
-		      l=getval();
-		      if (datalook(pos+l)==0xf7)
-			i=1;
-		      midiprintf("{%d}",l);
-		      midiprintf("\n");
-
-                        if (datalook(pos)==0x7d &&
-                            datalook(pos+1)==0x10 &&
-                            datalook(pos+2)<16)
-							{
-                            adlib_style=LUCAS_STYLE|MIDI_STYLE;
-							for (i=0; i<l; i++)
-								{
-                                midiprintf ("%x ",datalook(pos+i));
-                                if ((i-3)%10 == 0) midiprintf("\n");
-								}
-                            midiprintf ("\n");
-                            getnext(1);
-                            getnext(1);
-							c=getnext(1);
-							getnext(1);
-
-                          //  getnext(22); //temp
-                            ch[c].ins[0]=(unsigned char)((getnext(1)<<4)+getnext(1));
-                            ch[c].ins[2]=(unsigned char)(0xff-(((getnext(1)<<4)+getnext(1))&0x3f));
-                            ch[c].ins[4]=(unsigned char)(0xff-((getnext(1)<<4)+getnext(1)));
-                            ch[c].ins[6]=(unsigned char)(0xff-((getnext(1)<<4)+getnext(1)));
-                            ch[c].ins[8]=(unsigned char)((getnext(1)<<4)+getnext(1));
-
-                            ch[c].ins[1]=(unsigned char)((getnext(1)<<4)+getnext(1));
-                            ch[c].ins[3]=(unsigned char)(0xff-(((getnext(1)<<4)+getnext(1))&0x3f));
-                            ch[c].ins[5]=(unsigned char)(0xff-((getnext(1)<<4)+getnext(1)));
-                            ch[c].ins[7]=(unsigned char)(0xff-((getnext(1)<<4)+getnext(1)));
-                            ch[c].ins[9]=(unsigned char)((getnext(1)<<4)+getnext(1));
-
-                            i=(getnext(1)<<4)+getnext(1);
-                            ch[c].ins[10]=i;
-
-                            //if ((i&1)==1) ch[c].ins[10]=1;
-
-                            midiprintf ("\n%d: ",c);
-							for (i=0; i<11; i++)
-                                midiprintf ("%2X ",ch[c].ins[i]);
-                            getnext(l-26);
-							}
-                            else
-                            {
-                            midiprintf("\n");
-                            for (j=0; j<l; j++)
-                                midiprintf ("%2X ",getnext(1));
-                            }
-
-                        midiprintf("\n");
-						if(i==1)
-							getnext(1);
-                        break;
-                    case 0xf1:
-                        break;
-                    case 0xf2:
-                        getnext(2);
-                        break;
-                    case 0xf3:
-                        getnext(1);
-                        break;
-                    case 0xf4:
-                        break;
-                    case 0xf5:
-                        break;
-                    case 0xf6: /*something*/
-                    case 0xf8:
-                    case 0xfa:
-                    case 0xfb:
-                    case 0xfc:
-                        //this ends the track for sierra.
-                        if (type == FILE_SIERRA ||
-                            type == FILE_ADVSIERRA)
-                            {
-                            track[curtrack].tend=pos;
-                            midiprintf ("endmark: %ld -- %lx\n",pos,pos);
-                            }
-                        break;
-                    case 0xfe:
-                        break;
-                    case 0xfd:
-                        break;
-                    case 0xff:
-                        v=getnext(1);
-                        l=getval();
-                        midiprintf ("\n");
-                        midiprintf("{%X_%X}",v,l);
-                        if (v==0x51)
-                            {
-                            lnum=getnext(l);
-                            msqtr=lnum; /*set tempo*/
-                            midiprintf ("(qtr=%ld)",msqtr);
-                            }
-                            else
-                            {
-                            for (i=0; i<l; i++)
-                                midiprintf ("%2X ",getnext(1));
-                            }
-                        break;
-					}
-                break;
-            default: midiprintf("!",v); /* if we get down here, a error occurred */
-			break;
-            }
-
-        if (pos < track[curtrack].tend)
-            {
-            if (type != FILE_SIERRA && type !=FILE_ADVSIERRA)
-                w=getval();
-                else
-                w=getnext(1);
-            track[curtrack].iwait=w;
-            /*
-            if (w!=0)
-                {
-                midiprintf("\n<%d>",w);
-                f = 
-((float)w/(float)deltas)*((float)msqtr/(float)1000000);
-                if (doing==1) f=0; //not playing yet. don't wait yet
-                }
-                */
-            }
-            else
-            track[curtrack].iwait=0;
-
-        track[curtrack].pos=pos;
-        }
-
-
-        ret=0; //end of song.
-        iwait=0;
-        for (curtrack=0; curtrack<16; curtrack++)
-            if (track[curtrack].on == 1 &&
-                track[curtrack].pos < track[curtrack].tend)
-                ret=1;  //not yet..
-
-        if (ret==1)
-            {
-            iwait=0xffffff;  // bigger than any wait can be!
-            for (curtrack=0; curtrack<16; curtrack++)
-               if (track[curtrack].on == 1 &&
-                   track[curtrack].pos < track[curtrack].tend &&
-                   track[curtrack].iwait < iwait)
-                   iwait=track[curtrack].iwait;
-            }
-        }
-
-
-    if (iwait !=0 && ret==1)
-        {
-        for (curtrack=0; curtrack<16; curtrack++)
-            if (track[curtrack].on)
-                track[curtrack].iwait-=iwait;
-
-        
-fwait=1.0f/(((float)iwait/(float)deltas)*((float)msqtr/(float)1000000));
-        }
-        else
-        fwait=50;  // 1/50th of a second
-
-    midiprintf ("\n");
-    for (i=0; i<16; i++)
-        if (track[i].on)
-            if (track[i].pos < track[i].tend)
-                midiprintf ("<%d>",track[i].iwait);
-                else
-                midiprintf("stop");
-
-    /*
-    if (ret==0 && type==FILE_ADVSIERRA)
-        if (datalook(sierra_pos-2)!=0xff)
-            {
-            midiprintf ("next sectoin!");
-            sierra_next_section(p);
-            fwait=50;
-            ret=1;
-            }
-    */
-
-	if(ret)
-		return true;
-	else
-		return false;
-}
-
-float CmidPlayer::getrefresh()
-{
-    return (fwait > 0.01f ? fwait : 0.01f);
-}
-
-void CmidPlayer::rewind(int subsong)
-{
-    long i,j,n,m,l;
-    long o_sierra_pos;
-    unsigned char ins[16];
-
-    pos=0; tins=0;
-    adlib_style=MIDI_STYLE|CMF_STYLE;
-    adlib_mode=ADLIB_MELODIC;
-    for (i=0; i<128; i++)
-        for (j=0; j<16; j++)
-            myinsbank[i][j]=midi_fm_instruments[i][j];
-	for (i=0; i<16; i++)
-        {
-        ch[i].inum=0;
-        for (j=0; j<11; j++)
-            ch[i].ins[j]=myinsbank[ch[i].inum][j];
-        ch[i].vol=127;
-        ch[i].nshift=-25;
-        ch[i].on=1;
-        }
-
-    /* General init */
-    for (i=0; i<9; i++)
-        {
-        chp[i][0]=-1;
-        chp[i][2]=0;
-        }
-
-    deltas=250;  // just a number,  not a standard
-    msqtr=500000;
-    fwait=123; // gotta be a small thing.. sorta like nothing
-    iwait=0;
-
-    subsongs=1;
-
-    for (i=0; i<16; i++)
-        {
-        track[i].tend=0;
-        track[i].spos=0;
-        track[i].pos=0;
-        track[i].iwait=0;
-        track[i].on=0;
-        track[i].pv=0;
-        }
-    curtrack=0;
-
-    /* specific to file-type init */
-
-        pos=0;
-        i=getnext(1);
-        switch(type)
-            {
-            case FILE_LUCAS:
-                getnext(24);  //skip junk and get to the midi.
-                adlib_style=LUCAS_STYLE|MIDI_STYLE;
-                //note: no break, we go right into midi headers...
-            case FILE_MIDI:
-                if (type != FILE_LUCAS)
-                    tins=128;
-                getnext(11);  /*skip header*/
-                deltas=getnext(2);
-                midiprintf ("deltas:%ld\n",deltas);
-                getnext(4);
-
-                curtrack=0;
-                track[curtrack].on=1;
-                track[curtrack].tend=getnext(4);
-                track[curtrack].spos=pos;
-                midiprintf ("tracklen:%ld\n",track[curtrack].tend);
-                break;
-            case FILE_CMF:
-                getnext(3);  // ctmf
-                getnexti(2); //version
-                n=getnexti(2); // instrument offset
-                m=getnexti(2); // music offset
-                deltas=getnexti(2); //ticks/qtr note
-                msqtr=1000000/getnexti(2)*deltas;
-                   //the stuff in the cmf is click ticks per second..
-
-                i=getnexti(2);
-				if(i) title = (char *)data+i;
-                i=getnexti(2);
-				if(i) author = (char *)data+i;
-                i=getnexti(2);
-				if(i) remarks = (char *)data+i;
-
-                getnext(16); // channel in use table ..
-                i=getnexti(2); // num instr
-                if (i>128) i=128; // to ward of bad numbers...
-                getnexti(2); //basic tempo
-
-                midiprintf("\nioff:%d\nmoff%d\ndeltas:%ld\nmsqtr:%ld\nnumi:%d\n",
-                    n,m,deltas,msqtr,i);
-                pos=n;  // jump to instruments
-                tins=i;
-                for (j=0; j<i; j++)
-                    {
-                    midiprintf ("\n%d: ",j);
-                    for (l=0; l<16; l++)
-                        {
-                        myinsbank[j][l]=(unsigned char)getnext(1);
-                        midiprintf ("%2X ",myinsbank[j][l]);
-                        }
-                    }
-
-                for (i=0; i<16; i++)
-                    ch[i].nshift=-13;
-
-                adlib_style=CMF_STYLE;
-
-                curtrack=0;
-                track[curtrack].on=1;
-                track[curtrack].tend=flen;  // music until the end of the file
-                track[curtrack].spos=m;  //jump to midi music
-                break;
-            case FILE_OLDLUCAS:
-                msqtr=250000;
-                pos=9;
-                deltas=getnext(1);
-
-                i=8;
-                pos=0x19;  // jump to instruments
-                tins=i;
-                for (j=0; j<i; j++)
-                    {
-                    midiprintf ("\n%d: ",j);
-                    for (l=0; l<16; l++)
-                        ins[l]=(unsigned char)getnext(1);
-
-                    myinsbank[j][10]=ins[2];
-                    myinsbank[j][0]=ins[3];
-                    myinsbank[j][2]=ins[4];
-                    myinsbank[j][4]=ins[5];
-                    myinsbank[j][6]=ins[6];
-                    myinsbank[j][8]=ins[7];
-                    myinsbank[j][1]=ins[8];
-                    myinsbank[j][3]=ins[9];
-                    myinsbank[j][5]=ins[10];
-                    myinsbank[j][7]=ins[11];
-                    myinsbank[j][9]=ins[12];
-
-                    for (l=0; l<11; l++)
-                        midiprintf ("%2X ",myinsbank[j][l]);
-                    }
-
-                for (i=0; i<16; i++)
-                    {
-                    if (i<tins)
-                        {
-                        ch[i].inum=i;
-                        for (j=0; j<11; j++)
-                            ch[i].ins[j]=myinsbank[ch[i].inum][j];
-                        }
-                    }
-
-                adlib_style=LUCAS_STYLE|MIDI_STYLE;
-
-                curtrack=0;
-                track[curtrack].on=1;
-                track[curtrack].tend=flen;  // music until the end of the file
-                track[curtrack].spos=0x98;  //jump to midi music
-                break;
-            case FILE_ADVSIERRA:
-	      memcpy(myinsbank, smyinsbank, 128 * 16);
-	      tins = stins;
-                deltas=0x20;
-                getnext(11); //worthless empty space and "stuff" :)
-
-                o_sierra_pos=sierra_pos=pos;
-                sierra_next_section();
-                while (datalook(sierra_pos-2)!=0xff)
-                    {
-                    sierra_next_section();
-                    subsongs++;
-                    }
-
-                if (subsong < 0 || subsong >= subsongs) subsong=0;
-
-                sierra_pos=o_sierra_pos;
-                sierra_next_section();
-                i=0;
-                while (i != subsong)
-                    {
-                    sierra_next_section();
-                    i++;
-                    }
-
-                adlib_style=SIERRA_STYLE|MIDI_STYLE;  //advanced sierra tunes use volume
-                break;
-            case FILE_SIERRA:
-	      memcpy(myinsbank, smyinsbank, 128 * 16);
-	      tins = stins;
-                getnext(2);
-                deltas=0x20;
-
-                curtrack=0;
-                track[curtrack].on=1;
-                track[curtrack].tend=flen;  // music until the end of the file
-
-                for (i=0; i<16; i++)
-                    {
-                    ch[i].nshift=-13;
-                    ch[i].on=getnext(1);
-                    ch[i].inum=getnext(1);
-                    for (j=0; j<11; j++)
-                        ch[i].ins[j]=myinsbank[ch[i].inum][j];
-                    }
-
-                track[curtrack].spos=pos;
-                adlib_style=SIERRA_STYLE|MIDI_STYLE;
-                break;
-            }
-
-
-/*        sprintf(info,"%s\r\nTicks/Quarter Note: %ld\r\n",info,deltas);
-        sprintf(info,"%sms/Quarter Note: %ld",info,msqtr); */
-
-        for (i=0; i<16; i++)
-            if (track[i].on)
-                {
-                track[i].pos=track[i].spos;
-                track[i].pv=0;
-                track[i].iwait=0;
-                }
-
-    doing=1;
-    midi_fm_reset();
-}
-
-std::string CmidPlayer::gettype()
-{
-	switch(type) {
-	case FILE_LUCAS:
-		return std::string("LucasArts AdLib MIDI");
-	case FILE_MIDI:
-		return std::string("General MIDI");
-	case FILE_CMF:
-		return std::string("Creative Music Format (CMF MIDI)");
-	case FILE_OLDLUCAS:
-		return std::string("Lucasfilm Adlib MIDI");
-	case FILE_ADVSIERRA:
-		return std::string("Sierra On-Line VGA MIDI");
-	case FILE_SIERRA:
-		return std::string("Sierra On-Line EGA MIDI");
-	default:
-		return std::string("MIDI unknown");
-	}
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/mid.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,1088 @@
+/*
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ *
+ * MIDI & MIDI-like file player - Last Update: 10/15/2005
+ *                  by Phil Hassey - www.imitationpickles.org
+ *                                   philhassey@hotmail.com
+ *
+ * Can play the following
+ *      .LAA - a raw save of a Lucas Arts Adlib music
+ *             or
+ *             a raw save of a LucasFilm Adlib music
+ *      .CMF - Creative Music Format
+ *      .SCI - the sierra "midi" format.
+ *             Files must be in the form
+ *             xxxNAME.sci
+ *             So that the loader can load the right patch file:
+ *             xxxPATCH.003  (patch.003 must be saved from the
+ *                            sierra resource from each game.)
+ *
+ * 1/9/2006: audacious libadplug
+ *      Status:  MID not as fine as originally thought. Removing general MIDI detector so timidity handles these files instead.
+ *      
+ * 6/2/2000:  v1.0 relased by phil hassey
+ *      Status:  LAA is almost perfect
+ *                      - some volumes are a bit off (intrument too quiet)
+ *               MID is fine (who wants to listen to MIDI vid adlib anyway)
+ *               CMF is okay (still needs the adlib rythm mode implemented
+ *                            for real)
+ * 6/6/2000:
+ *      Status:  SCI:  there are two SCI formats, orginal and advanced.
+ *                    original:  (Found in SCI/EGA Sierra Adventures)
+ *                               played almost perfectly, I believe
+ *                               there is one mistake in the instrument
+ *                               loader that causes some sounds to
+ *                               not be quite right.  Most sounds are fine.
+ *                    advanced:  (Found in SCI/VGA Sierra Adventures)
+ *                               These are multi-track files.  (Thus the
+ *                               player had to be modified to work with
+ *                               them.)  This works fine.
+ *                               There are also multiple tunes in each file.
+ *                               I think some of them are supposed to be
+ *                               played at the same time, but I'm not sure
+ *                               when.
+ * 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
+ *                    LucasArts files.
+ *  FreeSCI - for some information on the sci music files
+ *  SD - the SCI Decoder (to get all .sci out of the Sierra files)
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+#include <string.h>
+#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);
+    return(data[pos]);
+}
+
+unsigned long CmidPlayer::getnexti(unsigned long num)
+{
+	unsigned long v=0;
+	unsigned long i;
+
+    for (i=0; i<num; i++)
+        {
+        v+=(datalook(pos)<<(8*i)); pos++;
+        }
+    return(v);
+}
+
+unsigned long CmidPlayer::getnext(unsigned long num)
+{
+	unsigned long v=0;
+	unsigned long i;
+
+    for (i=0; i<num; i++)
+        {
+        v<<=8;
+        v+=datalook(pos); pos++;
+        }
+    return(v);
+}
+
+unsigned long CmidPlayer::getval()
+{
+    int v=0;
+	unsigned char b;
+
+    b=(unsigned char)getnext(1);
+	v=b&0x7f;
+	while ((b&0x80) !=0)
+		{
+        b=(unsigned char)getnext(1);
+        v = (v << 7) + (b & 0x7F);
+		}
+	return(v);
+}
+
+bool CmidPlayer::load_sierra_ins(const std::string &fname, const CFileProvider &fp)
+{
+    long i,j,k,l;
+    unsigned char ins[28];
+    char *pfilename;
+    binistream *f;
+
+    pfilename = (char *)malloc(fname.length()+9);
+    strcpy(pfilename,fname.c_str());
+    j=0;
+    for(i=strlen(pfilename)-1; i >= 0; i--)
+      if(pfilename[i] == '/' || pfilename[i] == '\\') {
+	j = i+1;
+	break;
+      }
+    sprintf(pfilename+j+3,"patch.003");
+
+    f = fp.open(pfilename);
+    free(pfilename);
+    if(!f) return false;
+
+    f->ignore(2);
+    stins = 0;
+    for (i=0; i<2; i++)
+        {
+        for (k=0; k<48; k++)
+            {
+            l=i*48+k;
+            midiprintf ("\n%2d: ",l);
+            for (j=0; j<28; j++)
+                ins[j] = f->readInt(1);
+
+            myinsbank[l][0]=
+                (ins[9]*0x80) + (ins[10]*0x40) +
+                (ins[5]*0x20) + (ins[11]*0x10) +
+                ins[1];   //1=ins5
+            myinsbank[l][1]=
+                (ins[22]*0x80) + (ins[23]*0x40) +
+                (ins[18]*0x20) + (ins[24]*0x10) +
+                ins[14];  //1=ins18
+
+            myinsbank[l][2]=(ins[0]<<6)+ins[8];
+            myinsbank[l][3]=(ins[13]<<6)+ins[21];
+
+            myinsbank[l][4]=(ins[3]<<4)+ins[6];
+            myinsbank[l][5]=(ins[16]<<4)+ins[19];
+            myinsbank[l][6]=(ins[4]<<4)+ins[7];
+            myinsbank[l][7]=(ins[17]<<4)+ins[20];
+
+            myinsbank[l][8]=ins[26];
+            myinsbank[l][9]=ins[27];
+
+            myinsbank[l][10]=((ins[2]<<1))+(1-(ins[12]&1));
+            //(ins[12] ? 0:1)+((ins[2]<<1));
+
+            for (j=0; j<11; j++)
+                midiprintf ("%02X ",myinsbank[l][j]);
+			stins++;
+            }
+		f->ignore(2);
+        }
+
+    fp.close(f);
+    memcpy(smyinsbank, myinsbank, 128 * 16);
+    return true;
+}
+
+void CmidPlayer::sierra_next_section()
+{
+    int i,j;
+
+    for (i=0; i<16; i++)
+        track[i].on=0;
+
+    midiprintf("\n\nnext adv sierra section:\n");
+
+    pos=sierra_pos;
+    i=0;j=0;
+    while (i!=0xff)
+       {
+       getnext(1);
+       curtrack=j; j++;
+       track[curtrack].on=1;
+	   track[curtrack].spos = getnext(1);
+	   track[curtrack].spos += (getnext(1) << 8) + 4;	//4 best usually +3? not 0,1,2 or 5
+//       track[curtrack].spos=getnext(1)+(getnext(1)<<8)+4;		// dynamite!: doesn't optimize correctly!!
+       track[curtrack].tend=flen; //0xFC will kill it
+       track[curtrack].iwait=0;
+       track[curtrack].pv=0;
+       midiprintf ("track %d starts at %lx\n",curtrack,track[curtrack].spos);
+
+       getnext(2);
+       i=getnext(1);
+       }
+    getnext(2);
+    deltas=0x20;
+    sierra_pos=pos;
+    //getch();
+
+    fwait=0;
+    doing=1;
+}
+
+bool CmidPlayer::load(const std::string &filename, const CFileProvider &fp)
+{
+    binistream *f = fp.open(filename); if(!f) return false;
+    int good;
+    unsigned char s[6];
+
+    f->readString((char *)s, 6);
+    good=0;
+    subsongs=0;
+    switch(s[0])
+        {
+        case 'A':
+            if (s[1]=='D' && s[2]=='L') good=FILE_LUCAS;
+            break;
+        case 'C':
+            if (s[1]=='T' && s[2]=='M' && s[3]=='F') good=FILE_CMF;
+            break;
+        case 0x84:
+            if (s[1]==0x00 && load_sierra_ins(filename, fp))
+                if (s[2]==0xf0)
+                    good=FILE_ADVSIERRA;
+                    else
+                    good=FILE_SIERRA;
+            break;
+        default:
+            if (s[4]=='A' && s[5]=='D') good=FILE_OLDLUCAS;
+            break;
+        }
+
+    if (good!=0)
+		subsongs=1;
+    else {
+      fp.close(f);
+      return false;
+    }
+
+    type=good;
+    f->seek(0);
+    flen = fp.filesize(f);
+    data = new unsigned char [flen];
+    f->readString((char *)data, flen);
+
+    fp.close(f);
+    rewind(0);
+    return true;
+}
+
+void CmidPlayer::midi_write_adlib(unsigned int r, unsigned char v)
+{
+  opl->write(r,v);
+  adlib_data[r]=v;
+}
+
+void CmidPlayer::midi_fm_instrument(int voice, unsigned char *inst)
+{
+    if ((adlib_style&SIERRA_STYLE)!=0)
+        midi_write_adlib(0xbd,0);  //just gotta make sure this happens..
+                                      //'cause who knows when it'll be
+                                      //reset otherwise.
+
+
+    midi_write_adlib(0x20+adlib_opadd[voice],inst[0]);
+    midi_write_adlib(0x23+adlib_opadd[voice],inst[1]);
+
+    if ((adlib_style&LUCAS_STYLE)!=0)
+        {
+        midi_write_adlib(0x43+adlib_opadd[voice],0x3f);
+        if ((inst[10] & 1)==0)
+            midi_write_adlib(0x40+adlib_opadd[voice],inst[2]);
+            else
+            midi_write_adlib(0x40+adlib_opadd[voice],0x3f);
+        }
+        else
+        {
+        if ((adlib_style&SIERRA_STYLE)!=0)
+            {
+            midi_write_adlib(0x40+adlib_opadd[voice],inst[2]);
+            midi_write_adlib(0x43+adlib_opadd[voice],inst[3]);
+            }
+            else
+            {
+            midi_write_adlib(0x40+adlib_opadd[voice],inst[2]);
+            if ((inst[10] & 1)==0)
+                midi_write_adlib(0x43+adlib_opadd[voice],inst[3]);
+                else
+                midi_write_adlib(0x43+adlib_opadd[voice],0);
+            }
+        }
+
+    midi_write_adlib(0x60+adlib_opadd[voice],inst[4]);
+    midi_write_adlib(0x63+adlib_opadd[voice],inst[5]);
+    midi_write_adlib(0x80+adlib_opadd[voice],inst[6]);
+    midi_write_adlib(0x83+adlib_opadd[voice],inst[7]);
+    midi_write_adlib(0xe0+adlib_opadd[voice],inst[8]);
+    midi_write_adlib(0xe3+adlib_opadd[voice],inst[9]);
+
+    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;
+
+    if ((adlib_style&SIERRA_STYLE)==0)  //sierra likes it loud!
+    {
+    vol=volume>>2;
+
+    if ((adlib_style&LUCAS_STYLE)!=0)
+        {
+        if ((adlib_data[0xc0+voice]&1)==1)
+            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)));
+        }
+        else
+        {
+        if ((adlib_data[0xc0+voice]&1)==1)
+            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)));
+        }
+    }
+}
+
+void CmidPlayer::midi_fm_playnote(int voice, int note, int volume)
+{
+    int freq=fnums[note%12];
+    int oct=note/12;
+	int c;
+
+    midi_fm_volume(voice,volume);
+    midi_write_adlib(0xa0+voice,(unsigned char)(freq&0xff));
+
+	c=((freq&0x300) >> 8)+(oct<<2) + (adlib_mode == ADLIB_MELODIC || voice < 6 ? (1<<5) : 0);
+    midi_write_adlib(0xb0+voice,(unsigned char)c);
+}
+
+void CmidPlayer::midi_fm_endnote(int voice)
+{
+    //midi_fm_volume(voice,0);
+    //midi_write_adlib(0xb0+voice,0);
+
+    midi_write_adlib(0xb0+voice,(unsigned char)(adlib_data[0xb0+voice]&(255-32)));
+}
+
+void CmidPlayer::midi_fm_reset()
+{
+    int i;
+
+    opl->init();
+
+    for (i=0; i<256; i++)
+        midi_write_adlib(i,0);
+
+    midi_write_adlib(0x01, 0x20);
+    midi_write_adlib(0xBD,0xc0);
+}
+
+bool CmidPlayer::update()
+{
+    long w,v,note,vel,ctrl,nv,x,l,lnum;
+    int i=0,j,c;
+    int on,onl,numchan;
+    int ret;
+
+    if (doing == 1)
+        {
+        // just get the first wait and ignore it :>
+        for (curtrack=0; curtrack<16; curtrack++)
+            if (track[curtrack].on)
+                {
+                pos=track[curtrack].pos;
+                if (type != FILE_SIERRA && type !=FILE_ADVSIERRA)
+                    track[curtrack].iwait+=getval();
+                    else
+                    track[curtrack].iwait+=getnext(1);
+                track[curtrack].pos=pos;
+                }
+        doing=0;
+        }
+
+    iwait=0;
+    ret=1;
+
+    while (iwait==0 && ret==1)
+        {
+        for (curtrack=0; curtrack<16; curtrack++)
+        if (track[curtrack].on && track[curtrack].iwait==0 &&
+            track[curtrack].pos < track[curtrack].tend)
+        {
+        pos=track[curtrack].pos;
+
+		v=getnext(1);
+
+        //  This is to do implied MIDI events.
+        if (v<0x80) {v=track[curtrack].pv; pos--;}
+        track[curtrack].pv=(unsigned char)v;
+
+		c=v&0x0f;
+        midiprintf ("[%2X]",v);
+        switch(v&0xf0)
+            {
+			case 0x80: /*note off*/
+				note=getnext(1); vel=getnext(1);
+                for (i=0; i<9; i++)
+                    if (chp[i][0]==c && chp[i][1]==note)
+                        {
+                        midi_fm_endnote(i);
+                        chp[i][0]=-1;
+                        }
+                break;
+            case 0x90: /*note on*/
+              //  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<18; i++)
+                    chp[i][2]++;
+
+		  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<numchan; i++)
+			  if (chp[i][2]>onl)
+			    { onl=chp[i][2]; on=i; }
+		      }
+
+		    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
+ 		      midi_fm_percussion(c, ch[c].ins);
+
+                    if ((adlib_style&MIDI_STYLE)!=0)
+                        {
+                        nv=((ch[c].vol*vel)/128);
+                        if ((adlib_style&LUCAS_STYLE)!=0)
+                            nv*=2;
+                        if (nv>127) nv=127;
+                        nv=my_midi_fm_vol_table[nv];
+                        if ((adlib_style&LUCAS_STYLE)!=0)
+                            nv=(int)((float)sqrt((float)nv)*11);
+                        }
+                        else
+                        {
+                        nv=vel;
+                        }
+
+		    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
+                    {
+                    if (vel==0)  //same code as end note
+                        {
+                        for (i=0; i<9; i++)
+                            if (chp[i][0]==c && chp[i][1]==note)
+                                {
+                               // midi_fm_volume(i,0);  // really end the note
+                                midi_fm_endnote(i);
+                                chp[i][0]=-1;
+                                }
+                        }
+                        else
+                        {        // i forget what this is for.
+                        chp[on][0]=-1;
+                        chp[on][2]=0;
+                        }
+                    }
+                midiprintf(" [%d:%d:%d:%d]\n",c,ch[c].inum,note,vel);
+                }
+                else
+                midiprintf ("off");
+                break;
+            case 0xa0: /*key after touch */
+                note=getnext(1); vel=getnext(1);
+                /*  //this might all be good
+                for (i=0; i<9; i++)
+                    if (chp[i][0]==c & chp[i][1]==note)
+                        
+midi_fm_playnote(i,note+cnote[c],my_midi_fm_vol_table[(cvols[c]*vel)/128]*2);
+                */
+                break;
+            case 0xb0: /*control change .. pitch bend? */
+                ctrl=getnext(1); vel=getnext(1);
+
+                switch(ctrl)
+                    {
+                    case 0x07:
+                        midiprintf ("(pb:%d: %d %d)",c,ctrl,vel);
+                        ch[c].vol=vel;
+                        midiprintf("vol");
+                        break;
+                    case 0x67:
+                        midiprintf ("\n\nhere:%d\n\n",vel);
+                        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;
+            case 0xd0: /*chanel touch*/
+                x=getnext(1);
+                break;
+            case 0xe0: /*pitch wheel*/
+                x=getnext(1);
+                x=getnext(1);
+                break;
+            case 0xf0:
+                switch(v)
+                    {
+                    case 0xf0:
+                    case 0xf7: /*sysex*/
+		      l=getval();
+		      if (datalook(pos+l)==0xf7)
+			i=1;
+		      midiprintf("{%d}",l);
+		      midiprintf("\n");
+
+                        if (datalook(pos)==0x7d &&
+                            datalook(pos+1)==0x10 &&
+                            datalook(pos+2)<16)
+							{
+                            adlib_style=LUCAS_STYLE|MIDI_STYLE;
+							for (i=0; i<l; i++)
+								{
+                                midiprintf ("%x ",datalook(pos+i));
+                                if ((i-3)%10 == 0) midiprintf("\n");
+								}
+                            midiprintf ("\n");
+                            getnext(1);
+                            getnext(1);
+							c=getnext(1);
+							getnext(1);
+
+                          //  getnext(22); //temp
+                            ch[c].ins[0]=(unsigned char)((getnext(1)<<4)+getnext(1));
+                            ch[c].ins[2]=(unsigned char)(0xff-(((getnext(1)<<4)+getnext(1))&0x3f));
+                            ch[c].ins[4]=(unsigned char)(0xff-((getnext(1)<<4)+getnext(1)));
+                            ch[c].ins[6]=(unsigned char)(0xff-((getnext(1)<<4)+getnext(1)));
+                            ch[c].ins[8]=(unsigned char)((getnext(1)<<4)+getnext(1));
+
+                            ch[c].ins[1]=(unsigned char)((getnext(1)<<4)+getnext(1));
+                            ch[c].ins[3]=(unsigned char)(0xff-(((getnext(1)<<4)+getnext(1))&0x3f));
+                            ch[c].ins[5]=(unsigned char)(0xff-((getnext(1)<<4)+getnext(1)));
+                            ch[c].ins[7]=(unsigned char)(0xff-((getnext(1)<<4)+getnext(1)));
+                            ch[c].ins[9]=(unsigned char)((getnext(1)<<4)+getnext(1));
+
+                            i=(getnext(1)<<4)+getnext(1);
+                            ch[c].ins[10]=i;
+
+                            //if ((i&1)==1) ch[c].ins[10]=1;
+
+                            midiprintf ("\n%d: ",c);
+							for (i=0; i<11; i++)
+                                midiprintf ("%2X ",ch[c].ins[i]);
+                            getnext(l-26);
+							}
+                            else
+                            {
+                            midiprintf("\n");
+                            for (j=0; j<l; j++)
+                                midiprintf ("%2X ",getnext(1));
+                            }
+
+                        midiprintf("\n");
+						if(i==1)
+							getnext(1);
+                        break;
+                    case 0xf1:
+                        break;
+                    case 0xf2:
+                        getnext(2);
+                        break;
+                    case 0xf3:
+                        getnext(1);
+                        break;
+                    case 0xf4:
+                        break;
+                    case 0xf5:
+                        break;
+                    case 0xf6: /*something*/
+                    case 0xf8:
+                    case 0xfa:
+                    case 0xfb:
+                    case 0xfc:
+                        //this ends the track for sierra.
+                        if (type == FILE_SIERRA ||
+                            type == FILE_ADVSIERRA)
+                            {
+                            track[curtrack].tend=pos;
+                            midiprintf ("endmark: %ld -- %lx\n",pos,pos);
+                            }
+                        break;
+                    case 0xfe:
+                        break;
+                    case 0xfd:
+                        break;
+                    case 0xff:
+                        v=getnext(1);
+                        l=getval();
+                        midiprintf ("\n");
+                        midiprintf("{%X_%X}",v,l);
+                        if (v==0x51)
+                            {
+                            lnum=getnext(l);
+                            msqtr=lnum; /*set tempo*/
+                            midiprintf ("(qtr=%ld)",msqtr);
+                            }
+                            else
+                            {
+                            for (i=0; i<l; i++)
+                                midiprintf ("%2X ",getnext(1));
+                            }
+                        break;
+					}
+                break;
+            default: midiprintf("!",v); /* if we get down here, a error occurred */
+			break;
+            }
+
+        if (pos < track[curtrack].tend)
+            {
+            if (type != FILE_SIERRA && type !=FILE_ADVSIERRA)
+                w=getval();
+                else
+                w=getnext(1);
+            track[curtrack].iwait=w;
+            /*
+            if (w!=0)
+                {
+                midiprintf("\n<%d>",w);
+                f = 
+((float)w/(float)deltas)*((float)msqtr/(float)1000000);
+                if (doing==1) f=0; //not playing yet. don't wait yet
+                }
+                */
+            }
+            else
+            track[curtrack].iwait=0;
+
+        track[curtrack].pos=pos;
+        }
+
+
+        ret=0; //end of song.
+        iwait=0;
+        for (curtrack=0; curtrack<16; curtrack++)
+            if (track[curtrack].on == 1 &&
+                track[curtrack].pos < track[curtrack].tend)
+                ret=1;  //not yet..
+
+        if (ret==1)
+            {
+            iwait=0xffffff;  // bigger than any wait can be!
+            for (curtrack=0; curtrack<16; curtrack++)
+               if (track[curtrack].on == 1 &&
+                   track[curtrack].pos < track[curtrack].tend &&
+                   track[curtrack].iwait < iwait)
+                   iwait=track[curtrack].iwait;
+            }
+        }
+
+
+    if (iwait !=0 && ret==1)
+        {
+        for (curtrack=0; curtrack<16; curtrack++)
+            if (track[curtrack].on)
+                track[curtrack].iwait-=iwait;
+
+        
+fwait=1.0f/(((float)iwait/(float)deltas)*((float)msqtr/(float)1000000));
+        }
+        else
+        fwait=50;  // 1/50th of a second
+
+    midiprintf ("\n");
+    for (i=0; i<16; i++)
+        if (track[i].on)
+            if (track[i].pos < track[i].tend)
+                midiprintf ("<%d>",track[i].iwait);
+                else
+                midiprintf("stop");
+
+    /*
+    if (ret==0 && type==FILE_ADVSIERRA)
+        if (datalook(sierra_pos-2)!=0xff)
+            {
+            midiprintf ("next sectoin!");
+            sierra_next_section(p);
+            fwait=50;
+            ret=1;
+            }
+    */
+
+	if(ret)
+		return true;
+	else
+		return false;
+}
+
+float CmidPlayer::getrefresh()
+{
+    return (fwait > 0.01f ? fwait : 0.01f);
+}
+
+void CmidPlayer::rewind(int subsong)
+{
+    long i,j,n,m,l;
+    long o_sierra_pos;
+    unsigned char ins[16];
+
+    pos=0; tins=0;
+    adlib_style=MIDI_STYLE|CMF_STYLE;
+    adlib_mode=ADLIB_MELODIC;
+    for (i=0; i<128; i++)
+        for (j=0; j<16; j++)
+            myinsbank[i][j]=midi_fm_instruments[i][j];
+	for (i=0; i<16; i++)
+        {
+        ch[i].inum=0;
+        for (j=0; j<11; j++)
+            ch[i].ins[j]=myinsbank[ch[i].inum][j];
+        ch[i].vol=127;
+        ch[i].nshift=-25;
+        ch[i].on=1;
+        }
+
+    /* General init */
+    for (i=0; i<9; i++)
+        {
+        chp[i][0]=-1;
+        chp[i][2]=0;
+        }
+
+    deltas=250;  // just a number,  not a standard
+    msqtr=500000;
+    fwait=123; // gotta be a small thing.. sorta like nothing
+    iwait=0;
+
+    subsongs=1;
+
+    for (i=0; i<16; i++)
+        {
+        track[i].tend=0;
+        track[i].spos=0;
+        track[i].pos=0;
+        track[i].iwait=0;
+        track[i].on=0;
+        track[i].pv=0;
+        }
+    curtrack=0;
+
+    /* specific to file-type init */
+
+        pos=0;
+        i=getnext(1);
+        switch(type)
+            {
+            case FILE_LUCAS:
+                getnext(24);  //skip junk and get to the midi.
+                adlib_style=LUCAS_STYLE|MIDI_STYLE;
+                //note: no break, we go right into midi headers...
+            case FILE_MIDI:
+                if (type != FILE_LUCAS)
+                    tins=128;
+                getnext(11);  /*skip header*/
+                deltas=getnext(2);
+                midiprintf ("deltas:%ld\n",deltas);
+                getnext(4);
+
+                curtrack=0;
+                track[curtrack].on=1;
+                track[curtrack].tend=getnext(4);
+                track[curtrack].spos=pos;
+                midiprintf ("tracklen:%ld\n",track[curtrack].tend);
+                break;
+            case FILE_CMF:
+                getnext(3);  // ctmf
+                getnexti(2); //version
+                n=getnexti(2); // instrument offset
+                m=getnexti(2); // music offset
+                deltas=getnexti(2); //ticks/qtr note
+                msqtr=1000000/getnexti(2)*deltas;
+                   //the stuff in the cmf is click ticks per second..
+
+                i=getnexti(2);
+				if(i) title = (char *)data+i;
+                i=getnexti(2);
+				if(i) author = (char *)data+i;
+                i=getnexti(2);
+				if(i) remarks = (char *)data+i;
+
+                getnext(16); // channel in use table ..
+                i=getnexti(2); // num instr
+                if (i>128) i=128; // to ward of bad numbers...
+                getnexti(2); //basic tempo
+
+                midiprintf("\nioff:%d\nmoff%d\ndeltas:%ld\nmsqtr:%ld\nnumi:%d\n",
+                    n,m,deltas,msqtr,i);
+                pos=n;  // jump to instruments
+                tins=i;
+                for (j=0; j<i; j++)
+                    {
+                    midiprintf ("\n%d: ",j);
+                    for (l=0; l<16; l++)
+                        {
+                        myinsbank[j][l]=(unsigned char)getnext(1);
+                        midiprintf ("%2X ",myinsbank[j][l]);
+                        }
+                    }
+
+                for (i=0; i<16; i++)
+                    ch[i].nshift=-13;
+
+                adlib_style=CMF_STYLE;
+
+                curtrack=0;
+                track[curtrack].on=1;
+                track[curtrack].tend=flen;  // music until the end of the file
+                track[curtrack].spos=m;  //jump to midi music
+                break;
+            case FILE_OLDLUCAS:
+                msqtr=250000;
+                pos=9;
+                deltas=getnext(1);
+
+                i=8;
+                pos=0x19;  // jump to instruments
+                tins=i;
+                for (j=0; j<i; j++)
+                    {
+                    midiprintf ("\n%d: ",j);
+                    for (l=0; l<16; l++)
+                        ins[l]=(unsigned char)getnext(1);
+
+                    myinsbank[j][10]=ins[2];
+                    myinsbank[j][0]=ins[3];
+                    myinsbank[j][2]=ins[4];
+                    myinsbank[j][4]=ins[5];
+                    myinsbank[j][6]=ins[6];
+                    myinsbank[j][8]=ins[7];
+                    myinsbank[j][1]=ins[8];
+                    myinsbank[j][3]=ins[9];
+                    myinsbank[j][5]=ins[10];
+                    myinsbank[j][7]=ins[11];
+                    myinsbank[j][9]=ins[12];
+
+                    for (l=0; l<11; l++)
+                        midiprintf ("%2X ",myinsbank[j][l]);
+                    }
+
+                for (i=0; i<16; i++)
+                    {
+                    if (i<tins)
+                        {
+                        ch[i].inum=i;
+                        for (j=0; j<11; j++)
+                            ch[i].ins[j]=myinsbank[ch[i].inum][j];
+                        }
+                    }
+
+                adlib_style=LUCAS_STYLE|MIDI_STYLE;
+
+                curtrack=0;
+                track[curtrack].on=1;
+                track[curtrack].tend=flen;  // music until the end of the file
+                track[curtrack].spos=0x98;  //jump to midi music
+                break;
+            case FILE_ADVSIERRA:
+	      memcpy(myinsbank, smyinsbank, 128 * 16);
+	      tins = stins;
+                deltas=0x20;
+                getnext(11); //worthless empty space and "stuff" :)
+
+                o_sierra_pos=sierra_pos=pos;
+                sierra_next_section();
+                while (datalook(sierra_pos-2)!=0xff)
+                    {
+                    sierra_next_section();
+                    subsongs++;
+                    }
+
+                if (subsong < 0 || subsong >= subsongs) subsong=0;
+
+                sierra_pos=o_sierra_pos;
+                sierra_next_section();
+                i=0;
+                while (i != subsong)
+                    {
+                    sierra_next_section();
+                    i++;
+                    }
+
+                adlib_style=SIERRA_STYLE|MIDI_STYLE;  //advanced sierra tunes use volume
+                break;
+            case FILE_SIERRA:
+	      memcpy(myinsbank, smyinsbank, 128 * 16);
+	      tins = stins;
+                getnext(2);
+                deltas=0x20;
+
+                curtrack=0;
+                track[curtrack].on=1;
+                track[curtrack].tend=flen;  // music until the end of the file
+
+                for (i=0; i<16; i++)
+                    {
+                    ch[i].nshift=-13;
+                    ch[i].on=getnext(1);
+                    ch[i].inum=getnext(1);
+                    for (j=0; j<11; j++)
+                        ch[i].ins[j]=myinsbank[ch[i].inum][j];
+                    }
+
+                track[curtrack].spos=pos;
+                adlib_style=SIERRA_STYLE|MIDI_STYLE;
+                break;
+            }
+
+
+/*        sprintf(info,"%s\r\nTicks/Quarter Note: %ld\r\n",info,deltas);
+        sprintf(info,"%sms/Quarter Note: %ld",info,msqtr); */
+
+        for (i=0; i<16; i++)
+            if (track[i].on)
+                {
+                track[i].pos=track[i].spos;
+                track[i].pv=0;
+                track[i].iwait=0;
+                }
+
+    doing=1;
+    midi_fm_reset();
+}
+
+std::string CmidPlayer::gettype()
+{
+	switch(type) {
+	case FILE_LUCAS:
+		return std::string("LucasArts AdLib MIDI");
+	case FILE_MIDI:
+		return std::string("General MIDI");
+	case FILE_CMF:
+		return std::string("Creative Music Format (CMF MIDI)");
+	case FILE_OLDLUCAS:
+		return std::string("Lucasfilm Adlib MIDI");
+	case FILE_ADVSIERRA:
+		return std::string("Sierra On-Line VGA MIDI");
+	case FILE_SIERRA:
+		return std::string("Sierra On-Line EGA MIDI");
+	default:
+		return std::string("MIDI unknown");
+	}
+}
--- a/Plugins/Input/adplug/core/mkj.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-/*
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * mkj.cpp - MKJamz Player, by Simon Peter <dn.tlp@gmx.net>
- */
-
-#include <assert.h>
-
-#include "mkj.h"
-#include "debug.h"
-
-CPlayer *CmkjPlayer::factory(Copl *newopl)
-{
-  return new CmkjPlayer(newopl);
-}
-
-bool CmkjPlayer::load(const std::string &filename, const CFileProvider &fp)
-{
-  binistream *f = fp.open(filename); if(!f) return false;
-  char	id[6];
-  float	ver;
-  int	i, j;
-  short	inst[8];
-
-  // file validation
-  f->readString(id, 6);
-  if(strncmp(id,"MKJamz",6)) { fp.close(f); return false; }
-  ver = f->readFloat(binio::Single);
-  if(ver > 1.12) { fp.close(f); return false; }
-
-  // load
-  maxchannel = f->readInt(2);
-  opl->init(); opl->write(1, 32);
-  for(i = 0; i < maxchannel; i++) {
-    for(j = 0; j < 8; j++) inst[j] = f->readInt(2);
-    opl->write(0x20+op_table[i],inst[4]);
-    opl->write(0x23+op_table[i],inst[0]);
-    opl->write(0x40+op_table[i],inst[5]);
-    opl->write(0x43+op_table[i],inst[1]);
-    opl->write(0x60+op_table[i],inst[6]);
-    opl->write(0x63+op_table[i],inst[2]);
-    opl->write(0x80+op_table[i],inst[7]);
-    opl->write(0x83+op_table[i],inst[3]);
-  }
-  maxnotes = f->readInt(2);
-  songbuf = new short [(maxchannel+1)*maxnotes];
-  for(i = 0; i < maxchannel; i++) channel[i].defined = f->readInt(2);
-  for(i = 0; i < (maxchannel + 1) * maxnotes; i++)
-    songbuf[i] = f->readInt(2);
-
-  AdPlug_LogWrite("CmkjPlayer::load(\"%s\"): loaded file ver %.2f, %d channels,"
-		  " %d notes/channel.\n", filename.c_str(), ver, maxchannel,
-		  maxnotes);
-  fp.close(f);
-  rewind(0);
-  return true;
-}
-
-bool CmkjPlayer::update()
-{
-  int c, i;
-  short note;
-
-  for(c = 0; c < maxchannel; c++) {
-    if(!channel[c].defined)	// skip if channel is disabled
-      continue;
-
-    if(channel[c].pstat) {
-      channel[c].pstat--;
-      continue;
-    }
-
-    opl->write(0xb0 + c, 0);	// key off
-    do {
-      assert(channel[c].songptr < (maxchannel + 1) * maxnotes);
-      note = songbuf[channel[c].songptr];
-      if(channel[c].songptr - c > maxchannel)
-	if(note && note < 250)
-	  channel[c].pstat = channel[c].speed;
-      switch(note) {
-	// normal notes
-      case 68: opl->write(0xa0 + c,0x81); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
-      case 69: opl->write(0xa0 + c,0xb0); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
-      case 70: opl->write(0xa0 + c,0xca); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
-      case 71: opl->write(0xa0 + c,0x2); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
-      case 65: opl->write(0xa0 + c,0x41); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
-      case 66: opl->write(0xa0 + c,0x87); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
-      case 67: opl->write(0xa0 + c,0xae); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
-      case 17: opl->write(0xa0 + c,0x6b); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
-      case 18: opl->write(0xa0 + c,0x98); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
-      case 20: opl->write(0xa0 + c,0xe5); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
-      case 21: opl->write(0xa0 + c,0x20); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
-      case 15: opl->write(0xa0 + c,0x63); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
-      case 255:	// delay
-	channel[c].songptr += maxchannel;
-	channel[c].pstat = songbuf[channel[c].songptr];
-	break;
-      case 254:	// set octave
-	channel[c].songptr += maxchannel;
-	channel[c].octave = songbuf[channel[c].songptr];
-	break;
-      case 253:	// set speed
-	channel[c].songptr += maxchannel;
-	channel[c].speed = songbuf[channel[c].songptr];
-	break;
-      case 252:	// set waveform
-	channel[c].songptr += maxchannel;
-	channel[c].waveform = songbuf[channel[c].songptr] - 300;
-	if(c > 2)
-	  opl->write(0xe0 + c + (c+6),channel[c].waveform);
-	else
-	  opl->write(0xe0 + c,channel[c].waveform);
-	break;
-      case 251:	// song end
-	for(i = 0; i < maxchannel; i++) channel[i].songptr = i;
-	songend = true;
-	return false;
-      }
-
-      if(channel[c].songptr - c < maxnotes)
-	channel[c].songptr += maxchannel;
-      else
-	channel[c].songptr = c;
-    } while(!channel[c].pstat);
-  }
-
-  return !songend;
-}
-
-void CmkjPlayer::rewind(int subsong)
-{
-  int i;
-
-  for(i = 0; i < maxchannel; i++) {
-    channel[i].pstat = 0;
-    channel[i].speed = 0;
-    channel[i].waveform = 0;
-    channel[i].songptr = i;
-    channel[i].octave = 4;
-  }
-
-  songend = false;
-}
-
-float CmkjPlayer::getrefresh()
-{
-  return 100.0f;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/mkj.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,163 @@
+/*
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * mkj.cpp - MKJamz Player, by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include <assert.h>
+
+#include "mkj.h"
+#include "debug.h"
+
+CPlayer *CmkjPlayer::factory(Copl *newopl)
+{
+  return new CmkjPlayer(newopl);
+}
+
+bool CmkjPlayer::load(const std::string &filename, const CFileProvider &fp)
+{
+  binistream *f = fp.open(filename); if(!f) return false;
+  char	id[6];
+  float	ver;
+  int	i, j;
+  short	inst[8];
+
+  // file validation
+  f->readString(id, 6);
+  if(strncmp(id,"MKJamz",6)) { fp.close(f); return false; }
+  ver = f->readFloat(binio::Single);
+  if(ver > 1.12) { fp.close(f); return false; }
+
+  // load
+  maxchannel = f->readInt(2);
+  opl->init(); opl->write(1, 32);
+  for(i = 0; i < maxchannel; i++) {
+    for(j = 0; j < 8; j++) inst[j] = f->readInt(2);
+    opl->write(0x20+op_table[i],inst[4]);
+    opl->write(0x23+op_table[i],inst[0]);
+    opl->write(0x40+op_table[i],inst[5]);
+    opl->write(0x43+op_table[i],inst[1]);
+    opl->write(0x60+op_table[i],inst[6]);
+    opl->write(0x63+op_table[i],inst[2]);
+    opl->write(0x80+op_table[i],inst[7]);
+    opl->write(0x83+op_table[i],inst[3]);
+  }
+  maxnotes = f->readInt(2);
+  songbuf = new short [(maxchannel+1)*maxnotes];
+  for(i = 0; i < maxchannel; i++) channel[i].defined = f->readInt(2);
+  for(i = 0; i < (maxchannel + 1) * maxnotes; i++)
+    songbuf[i] = f->readInt(2);
+
+  AdPlug_LogWrite("CmkjPlayer::load(\"%s\"): loaded file ver %.2f, %d channels,"
+		  " %d notes/channel.\n", filename.c_str(), ver, maxchannel,
+		  maxnotes);
+  fp.close(f);
+  rewind(0);
+  return true;
+}
+
+bool CmkjPlayer::update()
+{
+  int c, i;
+  short note;
+
+  for(c = 0; c < maxchannel; c++) {
+    if(!channel[c].defined)	// skip if channel is disabled
+      continue;
+
+    if(channel[c].pstat) {
+      channel[c].pstat--;
+      continue;
+    }
+
+    opl->write(0xb0 + c, 0);	// key off
+    do {
+      assert(channel[c].songptr < (maxchannel + 1) * maxnotes);
+      note = songbuf[channel[c].songptr];
+      if(channel[c].songptr - c > maxchannel)
+	if(note && note < 250)
+	  channel[c].pstat = channel[c].speed;
+      switch(note) {
+	// normal notes
+      case 68: opl->write(0xa0 + c,0x81); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
+      case 69: opl->write(0xa0 + c,0xb0); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
+      case 70: opl->write(0xa0 + c,0xca); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
+      case 71: opl->write(0xa0 + c,0x2); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
+      case 65: opl->write(0xa0 + c,0x41); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
+      case 66: opl->write(0xa0 + c,0x87); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
+      case 67: opl->write(0xa0 + c,0xae); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
+      case 17: opl->write(0xa0 + c,0x6b); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
+      case 18: opl->write(0xa0 + c,0x98); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
+      case 20: opl->write(0xa0 + c,0xe5); opl->write(0xb0 + c,0x21 + 4 * channel[c].octave); break;
+      case 21: opl->write(0xa0 + c,0x20); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
+      case 15: opl->write(0xa0 + c,0x63); opl->write(0xb0 + c,0x22 + 4 * channel[c].octave); break;
+      case 255:	// delay
+	channel[c].songptr += maxchannel;
+	channel[c].pstat = songbuf[channel[c].songptr];
+	break;
+      case 254:	// set octave
+	channel[c].songptr += maxchannel;
+	channel[c].octave = songbuf[channel[c].songptr];
+	break;
+      case 253:	// set speed
+	channel[c].songptr += maxchannel;
+	channel[c].speed = songbuf[channel[c].songptr];
+	break;
+      case 252:	// set waveform
+	channel[c].songptr += maxchannel;
+	channel[c].waveform = songbuf[channel[c].songptr] - 300;
+	if(c > 2)
+	  opl->write(0xe0 + c + (c+6),channel[c].waveform);
+	else
+	  opl->write(0xe0 + c,channel[c].waveform);
+	break;
+      case 251:	// song end
+	for(i = 0; i < maxchannel; i++) channel[i].songptr = i;
+	songend = true;
+	return false;
+      }
+
+      if(channel[c].songptr - c < maxnotes)
+	channel[c].songptr += maxchannel;
+      else
+	channel[c].songptr = c;
+    } while(!channel[c].pstat);
+  }
+
+  return !songend;
+}
+
+void CmkjPlayer::rewind(int subsong)
+{
+  int i;
+
+  for(i = 0; i < maxchannel; i++) {
+    channel[i].pstat = 0;
+    channel[i].speed = 0;
+    channel[i].waveform = 0;
+    channel[i].songptr = i;
+    channel[i].octave = 4;
+  }
+
+  songend = false;
+}
+
+float CmkjPlayer::getrefresh()
+{
+  return 100.0f;
+}
--- a/Plugins/Input/adplug/core/msc.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,312 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * msc.c - MSC Player by Lubomir Bulej (pallas@kadan.cz)
- */
-
-#include <stdio.h>
-
-#include "msc.h"
-#include "debug.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];
-	
-  sprintf(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:
-      if((int)raw_pos >= dec_dist)
-			octet = raw_data [raw_pos - dec_dist];
-      else {
-	AdPlug_LogWrite("error! read before raw_data buffer.\n");
-	octet = 0;
-      }
-			
-			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.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,312 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * msc.c - MSC Player by Lubomir Bulej (pallas@kadan.cz)
+ */
+
+#include <stdio.h>
+
+#include "msc.h"
+#include "debug.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];
+	
+  sprintf(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:
+      if((int)raw_pos >= dec_dist)
+			octet = raw_data [raw_pos - dec_dist];
+      else {
+	AdPlug_LogWrite("error! read before raw_data buffer.\n");
+	octet = 0;
+      }
+			
+			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;
+}	
--- a/Plugins/Input/adplug/core/mtk.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * mtk.cpp - MPU-401 Trakker Loader by Simon Peter (dn.tlp@gmx.net)
- */
-
-#include "mtk.h"
-
-/*** public methods **************************************/
-
-CPlayer *CmtkLoader::factory(Copl *newopl)
-{
-  return new CmtkLoader(newopl);
-}
-
-bool CmtkLoader::load(const std::string &filename, const CFileProvider &fp)
-{
-        binistream *f = fp.open(filename); if(!f) return false;
-	struct {
-		char id[18];
-		unsigned short crc,size;
-	} header;
-	struct mtkdata {
-		char songname[34],composername[34],instname[0x80][34];
-		unsigned char insts[0x80][12],order[0x80],dummy,patterns[0x32][0x40][9];
-	} *data;
-	unsigned char *cmp,*org;
-	unsigned int i;
-	unsigned long cmpsize,cmpptr=0,orgptr=0;
-	unsigned short ctrlbits=0,ctrlmask=0,cmd,cnt,offs;
-
-	// read header
-	f->readString(header.id, 18);
-	header.crc = f->readInt(2);
-	header.size = f->readInt(2);
-
-	// file validation section
-	if(strncmp(header.id,"mpu401tr\x92kk\xeer@data",18))
-	  { fp.close(f); return false; }
-
-	// load section
-	cmpsize = fp.filesize(f) - 22;
-	cmp = new unsigned char[cmpsize];
-	org = new unsigned char[header.size];
-	for(i = 0; i < cmpsize; i++) cmp[i] = f->readInt(1);
-	fp.close(f);
-
-	while(cmpptr < cmpsize) {	// decompress
-		ctrlmask >>= 1;
-		if(!ctrlmask) {
-		        ctrlbits = cmp[cmpptr] + (cmp[cmpptr + 1] << 8);
-			cmpptr += 2;
-			ctrlmask = 0x8000;
-		}
-		if(!(ctrlbits & ctrlmask)) {	// uncompressed data
-      if(orgptr >= header.size)
-	goto err;
-
-			org[orgptr] = cmp[cmpptr];
-			orgptr++; cmpptr++;
-			continue;
-		}
-
-		// compressed data
-		cmd = (cmp[cmpptr] >> 4) & 0x0f;
-		cnt = cmp[cmpptr] & 0x0f;
-		cmpptr++;
-		switch(cmd) {
-    case 0:
-      if(orgptr + cnt > header.size) goto err;
-      cnt += 3;
-      memset(&org[orgptr],cmp[cmpptr],cnt);
-      cmpptr++; orgptr += cnt;
-      break;
-
-    case 1:
-      if(orgptr + cnt > header.size) goto err;
-      cnt += (cmp[cmpptr] << 4) + 19;
-      memset(&org[orgptr],cmp[++cmpptr],cnt);
-      cmpptr++; orgptr += cnt;
-      break;
-
-    case 2:
-      if(orgptr + cnt > header.size) goto err;
-      offs = (cnt+3) + (cmp[cmpptr] << 4);
-      cnt = cmp[++cmpptr] + 16; cmpptr++;
-      memcpy(&org[orgptr],&org[orgptr - offs],cnt);
-      orgptr += cnt;
-      break;
-
-    default:
-      if(orgptr + cmd > header.size) goto err;
-      offs = (cnt+3) + (cmp[cmpptr++] << 4);
-      memcpy(&org[orgptr],&org[orgptr-offs],cmd);
-      orgptr += cmd;
-      break;
-		}
-	}
-	delete [] cmp;
-	data = (struct mtkdata *) org;
-
-	// convert to HSC replay data
-	memset(title,0,34); strncpy(title,data->songname+1,33);
-	memset(composer,0,34); strncpy(composer,data->composername+1,33);
-	memset(instname,0,0x80*34);
-	for(i=0;i<0x80;i++)
-		strncpy(instname[i],data->instname[i]+1,33);
-	memcpy(instr,data->insts,0x80 * 12);
-	memcpy(song,data->order,0x80);
-	memcpy(patterns,data->patterns,header.size-6084);
-	for (i=0;i<128;i++) {				// correct instruments
-		instr[i][2] ^= (instr[i][2] & 0x40) << 1;
-		instr[i][3] ^= (instr[i][3] & 0x40) << 1;
-		instr[i][11] >>= 4;		// make unsigned
-	}
-
-	delete [] org;
-	rewind(0);
-	return true;
-
- err:
-  delete [] cmp;
-  delete [] org;
-  return false;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/mtk.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,140 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * mtk.cpp - MPU-401 Trakker Loader by Simon Peter (dn.tlp@gmx.net)
+ */
+
+#include "mtk.h"
+
+/*** public methods **************************************/
+
+CPlayer *CmtkLoader::factory(Copl *newopl)
+{
+  return new CmtkLoader(newopl);
+}
+
+bool CmtkLoader::load(const std::string &filename, const CFileProvider &fp)
+{
+        binistream *f = fp.open(filename); if(!f) return false;
+	struct {
+		char id[18];
+		unsigned short crc,size;
+	} header;
+	struct mtkdata {
+		char songname[34],composername[34],instname[0x80][34];
+		unsigned char insts[0x80][12],order[0x80],dummy,patterns[0x32][0x40][9];
+	} *data;
+	unsigned char *cmp,*org;
+	unsigned int i;
+	unsigned long cmpsize,cmpptr=0,orgptr=0;
+	unsigned short ctrlbits=0,ctrlmask=0,cmd,cnt,offs;
+
+	// read header
+	f->readString(header.id, 18);
+	header.crc = f->readInt(2);
+	header.size = f->readInt(2);
+
+	// file validation section
+	if(strncmp(header.id,"mpu401tr\x92kk\xeer@data",18))
+	  { fp.close(f); return false; }
+
+	// load section
+	cmpsize = fp.filesize(f) - 22;
+	cmp = new unsigned char[cmpsize];
+	org = new unsigned char[header.size];
+	for(i = 0; i < cmpsize; i++) cmp[i] = f->readInt(1);
+	fp.close(f);
+
+	while(cmpptr < cmpsize) {	// decompress
+		ctrlmask >>= 1;
+		if(!ctrlmask) {
+		        ctrlbits = cmp[cmpptr] + (cmp[cmpptr + 1] << 8);
+			cmpptr += 2;
+			ctrlmask = 0x8000;
+		}
+		if(!(ctrlbits & ctrlmask)) {	// uncompressed data
+      if(orgptr >= header.size)
+	goto err;
+
+			org[orgptr] = cmp[cmpptr];
+			orgptr++; cmpptr++;
+			continue;
+		}
+
+		// compressed data
+		cmd = (cmp[cmpptr] >> 4) & 0x0f;
+		cnt = cmp[cmpptr] & 0x0f;
+		cmpptr++;
+		switch(cmd) {
+    case 0:
+      if(orgptr + cnt > header.size) goto err;
+      cnt += 3;
+      memset(&org[orgptr],cmp[cmpptr],cnt);
+      cmpptr++; orgptr += cnt;
+      break;
+
+    case 1:
+      if(orgptr + cnt > header.size) goto err;
+      cnt += (cmp[cmpptr] << 4) + 19;
+      memset(&org[orgptr],cmp[++cmpptr],cnt);
+      cmpptr++; orgptr += cnt;
+      break;
+
+    case 2:
+      if(orgptr + cnt > header.size) goto err;
+      offs = (cnt+3) + (cmp[cmpptr] << 4);
+      cnt = cmp[++cmpptr] + 16; cmpptr++;
+      memcpy(&org[orgptr],&org[orgptr - offs],cnt);
+      orgptr += cnt;
+      break;
+
+    default:
+      if(orgptr + cmd > header.size) goto err;
+      offs = (cnt+3) + (cmp[cmpptr++] << 4);
+      memcpy(&org[orgptr],&org[orgptr-offs],cmd);
+      orgptr += cmd;
+      break;
+		}
+	}
+	delete [] cmp;
+	data = (struct mtkdata *) org;
+
+	// convert to HSC replay data
+	memset(title,0,34); strncpy(title,data->songname+1,33);
+	memset(composer,0,34); strncpy(composer,data->composername+1,33);
+	memset(instname,0,0x80*34);
+	for(i=0;i<0x80;i++)
+		strncpy(instname[i],data->instname[i]+1,33);
+	memcpy(instr,data->insts,0x80 * 12);
+	memcpy(song,data->order,0x80);
+	memcpy(patterns,data->patterns,header.size-6084);
+	for (i=0;i<128;i++) {				// correct instruments
+		instr[i][2] ^= (instr[i][2] & 0x40) << 1;
+		instr[i][3] ^= (instr[i][3] & 0x40) << 1;
+		instr[i][11] >>= 4;		// make unsigned
+	}
+
+	delete [] org;
+	rewind(0);
+	return true;
+
+ err:
+  delete [] cmp;
+  delete [] org;
+  return false;
+}
--- a/Plugins/Input/adplug/core/player.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * player.cpp - Replayer base class, by Simon Peter <dn.tlp@gmx.net>
- */
-
-#include "player.h"
-#include "adplug.h"
-#include "silentopl.h"
-
-/***** CPlayer *****/
-
-const unsigned short CPlayer::note_table[12] =
-  {363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647, 686};
-
-const unsigned char CPlayer::op_table[9] =
-  {0x00, 0x01, 0x02, 0x08, 0x09, 0x0a, 0x10, 0x11, 0x12};
-
-CPlayer::CPlayer(Copl *newopl)
-  : opl(newopl), db(CAdPlug::database)
-{
-}
-
-CPlayer::~CPlayer()
-{
-}
-
-unsigned long CPlayer::songlength(int subsong)
-{
-  CSilentopl	tempopl;
-  Copl		*saveopl = opl;
-  float		slength = 0.0f;
-
-  // save original OPL from being overwritten
-  opl = &tempopl;
-
-  // get song length
-  rewind(subsong);
-  while(update() && slength < 600000)	// song length limit: 10 minutes
-    slength += 1000.0f / getrefresh();
-  rewind(subsong);
-
-  // restore original OPL and return
-  opl = saveopl;
-  return (unsigned long)slength;
-}
-
-void CPlayer::seek(unsigned long ms)
-{
-  float pos = 0.0f;
-
-  rewind();
-  while(pos < ms && update())		// seek to new position
-    pos += 1000/getrefresh();
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/player.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,70 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * player.cpp - Replayer base class, by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include "player.h"
+#include "adplug.h"
+#include "silentopl.h"
+
+/***** CPlayer *****/
+
+const unsigned short CPlayer::note_table[12] =
+  {363, 385, 408, 432, 458, 485, 514, 544, 577, 611, 647, 686};
+
+const unsigned char CPlayer::op_table[9] =
+  {0x00, 0x01, 0x02, 0x08, 0x09, 0x0a, 0x10, 0x11, 0x12};
+
+CPlayer::CPlayer(Copl *newopl)
+  : opl(newopl), db(CAdPlug::database)
+{
+}
+
+CPlayer::~CPlayer()
+{
+}
+
+unsigned long CPlayer::songlength(int subsong)
+{
+  CSilentopl	tempopl;
+  Copl		*saveopl = opl;
+  float		slength = 0.0f;
+
+  // save original OPL from being overwritten
+  opl = &tempopl;
+
+  // get song length
+  rewind(subsong);
+  while(update() && slength < 600000)	// song length limit: 10 minutes
+    slength += 1000.0f / getrefresh();
+  rewind(subsong);
+
+  // restore original OPL and return
+  opl = saveopl;
+  return (unsigned long)slength;
+}
+
+void CPlayer::seek(unsigned long ms)
+{
+  float pos = 0.0f;
+
+  rewind();
+  while(pos < ms && update())		// seek to new position
+    pos += 1000/getrefresh();
+}
--- a/Plugins/Input/adplug/core/players.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-/*
- * AdPlug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * players.h - Players enumeration, by Simon Peter <dn.tlp@gmx.net>
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "players.h"
-
-/***** CPlayerDesc *****/
-
-CPlayerDesc::CPlayerDesc()
-  : factory(0), extensions(0), extlength(0)
-{
-}
-
-CPlayerDesc::CPlayerDesc(const CPlayerDesc &pd)
-  : factory(pd.factory), filetype(pd.filetype), extlength(pd.extlength)
-{
-  if(pd.extensions) {
-    extensions = (char *)malloc(extlength);
-    memcpy(extensions, pd.extensions, extlength);
-  } else
-    extensions = 0;
-}
-
-CPlayerDesc::CPlayerDesc(Factory f, const std::string &type, const char *ext)
-  : factory(f), filetype(type), extensions(0)
-{
-  const char *i = ext;
-
-  // Determine length of passed extensions list
-  while(*i) i += strlen(i) + 1;
-  extlength = i - ext + 1;	// length = difference between last and first char + 1
-
-  extensions = (char *)malloc(extlength);
-  memcpy(extensions, ext, extlength);
-}
-
-CPlayerDesc::~CPlayerDesc()
-{
-  if(extensions) free(extensions);
-}
-
-void CPlayerDesc::add_extension(const char *ext)
-{
-  unsigned long newlength = extlength + strlen(ext) + 1;
-
-  extensions = (char *)realloc(extensions, newlength);
-  strcpy(extensions + extlength - 1, ext);
-  extensions[newlength - 1] = '\0';
-  extlength = newlength;
-}
-
-const char *CPlayerDesc::get_extension(unsigned int n) const
-{
-  const char	*i = extensions;
-  unsigned int	j;
-
-  for(j = 0; j < n && (*i); j++, i += strlen(i) + 1) ;
-  return (*i != '\0' ? i : 0);
-}
-
-/***** CPlayers *****/
-
-const CPlayerDesc *CPlayers::lookup_filetype(const std::string &ftype) const
-{
-  const_iterator	i;
-
-  for(i = begin(); i != end(); i++)
-    if((*i)->filetype == ftype)
-      return *i;
-
-  return 0;
-}
-
-const CPlayerDesc *CPlayers::lookup_extension(const std::string &extension) const
-{
-  const_iterator	i;
-  unsigned int		j;
-
-  for(i = begin(); i != end(); i++)
-    for(j = 0; (*i)->get_extension(j); j++)
-      if(!stricmp(extension.c_str(), (*i)->get_extension(j)))
-	return *i;
-
-  return 0;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/players.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,105 @@
+/*
+ * AdPlug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * players.h - Players enumeration, by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "players.h"
+
+/***** CPlayerDesc *****/
+
+CPlayerDesc::CPlayerDesc()
+  : factory(0), extensions(0), extlength(0)
+{
+}
+
+CPlayerDesc::CPlayerDesc(const CPlayerDesc &pd)
+  : factory(pd.factory), filetype(pd.filetype), extlength(pd.extlength)
+{
+  if(pd.extensions) {
+    extensions = (char *)malloc(extlength);
+    memcpy(extensions, pd.extensions, extlength);
+  } else
+    extensions = 0;
+}
+
+CPlayerDesc::CPlayerDesc(Factory f, const std::string &type, const char *ext)
+  : factory(f), filetype(type), extensions(0)
+{
+  const char *i = ext;
+
+  // Determine length of passed extensions list
+  while(*i) i += strlen(i) + 1;
+  extlength = i - ext + 1;	// length = difference between last and first char + 1
+
+  extensions = (char *)malloc(extlength);
+  memcpy(extensions, ext, extlength);
+}
+
+CPlayerDesc::~CPlayerDesc()
+{
+  if(extensions) free(extensions);
+}
+
+void CPlayerDesc::add_extension(const char *ext)
+{
+  unsigned long newlength = extlength + strlen(ext) + 1;
+
+  extensions = (char *)realloc(extensions, newlength);
+  strcpy(extensions + extlength - 1, ext);
+  extensions[newlength - 1] = '\0';
+  extlength = newlength;
+}
+
+const char *CPlayerDesc::get_extension(unsigned int n) const
+{
+  const char	*i = extensions;
+  unsigned int	j;
+
+  for(j = 0; j < n && (*i); j++, i += strlen(i) + 1) ;
+  return (*i != '\0' ? i : 0);
+}
+
+/***** CPlayers *****/
+
+const CPlayerDesc *CPlayers::lookup_filetype(const std::string &ftype) const
+{
+  const_iterator	i;
+
+  for(i = begin(); i != end(); i++)
+    if((*i)->filetype == ftype)
+      return *i;
+
+  return 0;
+}
+
+const CPlayerDesc *CPlayers::lookup_extension(const std::string &extension) const
+{
+  const_iterator	i;
+  unsigned int		j;
+
+  for(i = begin(); i != end(); i++)
+    for(j = 0; (*i)->get_extension(j); j++)
+      if(!stricmp(extension.c_str(), (*i)->get_extension(j)))
+	return *i;
+
+  return 0;
+}
--- a/Plugins/Input/adplug/core/protrack.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,719 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * protrack.cpp - Generic Protracker Player
- *
- * NOTES:
- * This is a generic Protracker-based formats player. It offers all Protracker
- * features, plus a good set of extensions to be compatible to other Protracker
- * derivatives. It is derived from the original SA2 player by me. If you got a
- * Protracker-like format, this is most certainly the player you want to use.
- */
-
-#include "protrack.h"
-#include "debug.h"
-
-#define SPECIALARPLEN	256	// Standard length of special arpeggio lists
-#define JUMPMARKER	0x80	// Orderlist jump marker
-
-// SA2 compatible adlib note table
-const unsigned short CmodPlayer::sa2_notetable[12] =
-  {340,363,385,408,432,458,485,514,544,577,611,647};
-
-// SA2 compatible vibrato rate table
-const unsigned char CmodPlayer::vibratotab[32] =
-  {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1};
-
-/*** public methods *************************************/
-
-CmodPlayer::CmodPlayer(Copl *newopl)
-  : CPlayer(newopl), inst(0), order(0), arplist(0), arpcmd(0), initspeed(6),
-    activechan(0xffff), flags(Standard), nop(0), nrows(0), npats(0), nchans(0)
-{
-  realloc_order(128);
-  realloc_patterns(64, 64, 9);
-  realloc_instruments(250);
-  init_notetable(sa2_notetable);
-}
-
-CmodPlayer::~CmodPlayer()
-{
-  dealloc();
-}
-
-bool CmodPlayer::update()
-{
-	unsigned char pattbreak=0,donote;		// remember vars
-	unsigned char pattnr,chan,info1,info2,info;	// cache vars
-	unsigned short track;
-	unsigned long row;
-
-	if(!speed)		// song full stop
-		return !songend;
-
-	// effect handling (timer dependant)
-	for(chan=0;chan<nchans;chan++) {
-		if(arplist && arpcmd && inst[channel[chan].inst].arpstart)	// special arpeggio
-			if(channel[chan].arpspdcnt)
-				channel[chan].arpspdcnt--;
-			else
-				if(arpcmd[channel[chan].arppos] != 255) {
-					switch(arpcmd[channel[chan].arppos]) {
-					case 252: channel[chan].vol1 = arplist[channel[chan].arppos];	// set volume
-							if(channel[chan].vol1 > 63)	// ?????
-								channel[chan].vol1 = 63;
-							channel[chan].vol2 = channel[chan].vol1;
-							setvolume(chan);
-							break;
-					case 253: channel[chan].key = 0; setfreq(chan); break;	// release sustaining note
-					case 254: channel[chan].arppos = arplist[channel[chan].arppos]; break; // arpeggio loop
-					default: if(arpcmd[channel[chan].arppos]) {
-								if(arpcmd[channel[chan].arppos] / 10)
-									opl->write(0xe3 + op_table[chan], arpcmd[channel[chan].arppos] / 10 - 1);
-								if(arpcmd[channel[chan].arppos] % 10)
-									opl->write(0xe0 + op_table[chan], (arpcmd[channel[chan].arppos] % 10) - 1);
-								if(arpcmd[channel[chan].arppos] < 10)	// ?????
-									opl->write(0xe0 + op_table[chan], arpcmd[channel[chan].arppos] - 1);
-							 }
-					}
-					if(arpcmd[channel[chan].arppos] != 252) {
-						if(arplist[channel[chan].arppos] <= 96)
-							setnote(chan,channel[chan].note + arplist[channel[chan].arppos]);
-						if(arplist[channel[chan].arppos] >= 100)
-							setnote(chan,arplist[channel[chan].arppos] - 100);
-					} else
-						setnote(chan,channel[chan].note);
-					setfreq(chan);
-					if(arpcmd[channel[chan].arppos] != 255)
-						channel[chan].arppos++;
-					channel[chan].arpspdcnt = inst[channel[chan].inst].arpspeed - 1;
-				}
-
-		info1 = channel[chan].info1;
-		info2 = channel[chan].info2;
-		if(flags & Decimal)
-			info = channel[chan].info1 * 10 + channel[chan].info2;
-		else
-			info = (channel[chan].info1 << 4) + channel[chan].info2;
-		switch(channel[chan].fx) {
-		case 0:	if(info) {									// arpeggio
-					if(channel[chan].trigger < 2)
-						channel[chan].trigger++;
-					else
-						channel[chan].trigger = 0;
-					switch(channel[chan].trigger) {
-					case 0: setnote(chan,channel[chan].note); break;
-					case 1: setnote(chan,channel[chan].note + info1); break;
-					case 2: setnote(chan,channel[chan].note + info2);
-					}
-					setfreq(chan);
-				}
-				break;
-		case 1: slide_up(chan,info); setfreq(chan); break;	// slide up
-		case 2: slide_down(chan,info); setfreq(chan); break;	// slide down
-		case 3: tone_portamento(chan,channel[chan].portainfo); break;	// tone portamento
-		case 4: vibrato(chan,channel[chan].vibinfo1,channel[chan].vibinfo2); break;	// vibrato
-		case 5:												// tone portamento & volume slide
-		case 6: if(channel[chan].fx == 5)				// vibrato & volume slide
-					tone_portamento(chan,channel[chan].portainfo);
-				else
-					vibrato(chan,channel[chan].vibinfo1,channel[chan].vibinfo2);
-		case 10: if(del % 4)	// SA2 volume slide
-					break;
-				 if(info1)
-					 vol_up(chan,info1);
-				 else
-					 vol_down(chan,info2);
-				 setvolume(chan);
-				 break;
-		case 14: if(info1 == 3)							// retrig note
-					if(!(del % (info2+1)))
-						playnote(chan);
-				 break;
-		case 16: if(del % 4)	// AMD volume slide
-					break;
-				 if(info1)
-					 vol_up_alt(chan,info1);
-				 else
-					 vol_down_alt(chan,info2);
-				 setvolume(chan);
-				 break;
-		case 20:				// RAD volume slide
-			if(info < 50)
-				vol_down_alt(chan,info);
-			else
-				vol_up_alt(chan,info - 50);
-			setvolume(chan);
-			break;
-		case 26: // volume slide
-			if(info1)
-				vol_up(chan,info1);
-			else
-				vol_down(chan,info2);
-			setvolume(chan);
-			break;
-		case 28:
-			if (info1) {
-				slide_up(chan,1); channel[chan].info1--;
-			}
-			if (info2) {
-				slide_down(chan,1); channel[chan].info2--;
-			}
-			setfreq(chan);
-			break;
-		}
-	}
-
-	if(del) {		// speed compensation
-		del--;
-		return !songend;
-	}
-
-	// arrangement handling
-	if(ord >= length) {
-		songend = 1;				// set end-flag
-		ord = restartpos;
-	}
-	pattnr = order[ord];
-
-        if(!rw) AdPlug_LogWrite("\nCmodPlayer::update(): Pattern: %d, Order: %d\n", pattnr, ord);
-        AdPlug_LogWrite("CmodPlayer::update():%3d|", rw);
-
-	// play row
-	row = rw;
-	for(chan=0;chan<nchans;chan++) {
-		if(!(activechan >> (15 - chan)) & 1) {	// channel active?
-                  AdPlug_LogWrite("N/A|");
-		  continue;
-		}
-		if(!(track = trackord[pattnr][chan])) {	// resolve track
-                  AdPlug_LogWrite("------------|");
-		  continue;
-		} else
-			track--;
-
-                AdPlug_LogWrite("%3d%3d%2X%2X%2X|", tracks[track][row].note,
-			 tracks[track][row].inst, tracks[track][row].command,
-			 tracks[track][row].param1, tracks[track][row].param2);
-
-		donote = 0;
-		if(tracks[track][row].inst) {
-		  channel[chan].inst = tracks[track][row].inst - 1;
-		  if (!(flags & Faust)) {
-		    channel[chan].vol1 = 63 - (inst[channel[chan].inst].data[10] & 63);
-		    channel[chan].vol2 = 63 - (inst[channel[chan].inst].data[9] & 63);
-		    setvolume(chan);
-		  }
-		}
-
-		if(tracks[track][row].note && tracks[track][row].command != 3) {	// no tone portamento
-			channel[chan].note = tracks[track][row].note;
-			setnote(chan,tracks[track][row].note);
-			channel[chan].nextfreq = channel[chan].freq;
-			channel[chan].nextoct = channel[chan].oct;
-			channel[chan].arppos = inst[channel[chan].inst].arpstart;
-			channel[chan].arpspdcnt = 0;
-			if(tracks[track][row].note != 127)	// handle key off
-				donote = 1;
-		}
-		channel[chan].fx = tracks[track][row].command;
-		channel[chan].info1 = tracks[track][row].param1;
-		channel[chan].info2 = tracks[track][row].param2;
-
-		if(donote)
-			playnote(chan);
-
-		// command handling (row dependant)
-		info1 = channel[chan].info1;
-		info2 = channel[chan].info2;
-		if(flags & Decimal)
-			info = channel[chan].info1 * 10 + channel[chan].info2;
-		else
-			info = (channel[chan].info1 << 4) + channel[chan].info2;
-		switch(channel[chan].fx) {
-		case 3:	if(tracks[track][row].note) {					// tone portamento
-					if(tracks[track][row].note < 13)
-						channel[chan].nextfreq = notetable[tracks[track][row].note - 1];
-					else
-						if(tracks[track][row].note % 12 > 0)
-							channel[chan].nextfreq = notetable[(tracks[track][row].note % 12) - 1];
-						else
-							channel[chan].nextfreq = notetable[11];
-					channel[chan].nextoct = (tracks[track][row].note - 1) / 12;
-					if(tracks[track][row].note == 127) {	// handle key off
-						channel[chan].nextfreq = channel[chan].freq;
-						channel[chan].nextoct = channel[chan].oct;
-					}
-				}
-				if(info)		// remember vars
-					channel[chan].portainfo = info;
-				break;
-		case 4: if(info) {										// vibrato (remember vars)
-					channel[chan].vibinfo1 = info1;
-					channel[chan].vibinfo2 = info2;
-				}
-				break;
-		case 7: tempo = info; break;							// set tempo
-		case 8: channel[chan].key = 0; setfreq(chan); break;	// release sustaining note
-		case 9: // set carrier/modulator volume
-				if(info1)
-					channel[chan].vol1 = info1 * 7;
-				else
-					channel[chan].vol2 = info2 * 7;
-				setvolume(chan);
-				break;
-		case 11: pattbreak = 1; rw = 0; if(info < ord) songend = 1; ord = info; break; // position jump
-		case 12: // set volume
-				channel[chan].vol1 = info;
-				channel[chan].vol2 = info;
-				if(channel[chan].vol1 > 63)
-					channel[chan].vol1 = 63;
-				if(channel[chan].vol2 > 63)
-					channel[chan].vol2 = 63;
-				setvolume(chan);
-				break;
-		case 13: if(!pattbreak) { pattbreak = 1; rw = info; ord++; } break;	// pattern break
-		case 14: // extended command
-				switch(info1) {
-				case 0: if(info2)								// define cell-tremolo
-							regbd |= 128;
-						else
-							regbd &= 127;
-						opl->write(0xbd,regbd);
-						break;
-				case 1: if(info2)								// define cell-vibrato
-							regbd |= 64;
-						else
-							regbd &= 191;
-						opl->write(0xbd,regbd);
-						break;
-				case 4: vol_up_alt(chan,info2);					// increase volume fine
-						setvolume(chan);
-						break;
-				case 5: vol_down_alt(chan,info2);				// decrease volume fine
-						setvolume(chan);
-						break;
-				case 6: slide_up(chan,info2);					// manual slide up
-						setfreq(chan);
-						break;
-				case 7: slide_down(chan,info2);					// manual slide down
-						setfreq(chan);
-						break;
-				}
-				break;
-		case 15: // SA2 set speed
-			if(info <= 0x1f)
-				speed = info;
-			if(info >= 0x32)
-				tempo = info;
-			if(!info)
-				songend = 1;
-			break;
-		case 17: // alternate set volume
-			channel[chan].vol1 = info;
-			if(channel[chan].vol1 > 63)
-				channel[chan].vol1 = 63;
-			if(inst[channel[chan].inst].data[0] & 1) {
-				channel[chan].vol2 = info;
-	 			if(channel[chan].vol2 > 63)
-					channel[chan].vol2 = 63;
-			}
-
-			setvolume(chan);
-			break;
-		case 18: // AMD set speed
-			if(info <= 31 && info > 0)
-				speed = info;
-			if(info > 31 || !info)
-				tempo = info;
-			break;
-		case 19: // RAD/A2M set speed
-			speed = (info ? info : info + 1);
-			break;
-		case 21: // set modulator volume
-			if(info <= 63)
-				channel[chan].vol2 = info;
-			else
-				channel[chan].vol2 = 63;
-			setvolume(chan);
-			break;
-		case 22: // set carrier volume
-			if(info <= 63)
-				channel[chan].vol1 = info;
-			else
-				channel[chan].vol1 = 63;
-			setvolume(chan);
-			break;
-		case 23: // fine frequency slide up
-			slide_up(chan,info);
-			setfreq(chan);
-			break;
-		case 24: // fine frequency slide down
-			slide_down(chan,info);
-			setfreq(chan);
-			break;
-		case 25: // set carrier/modulator waveform
-			if(info1 != 0x0f)
-				opl->write(0xe3 + op_table[chan],info1);
-			if(info2 != 0x0f)
-				opl->write(0xe0 + op_table[chan],info2);
-			break;
-		case 27: // set chip tremolo/vibrato
-			if (info1)
-				regbd |= 128;
-			else
-				regbd &= 127;
-			if (info2)
-				regbd |= 64;
-			else
-				regbd &= 191;
-			opl->write(0xbd,regbd);
-			break;
-		}
-	}
-
-	del = speed - 1;	// speed compensation
-	if(!pattbreak) {	// next row (only if no manual advance)
-		rw++;
-		if(rw >= nrows) {
-			rw = 0;
-			ord++;
-		}
-	}
-	if(ord < length) {
-	  if(order[ord] >= JUMPMARKER) {	// jump to order
-	    ord = order[ord] - JUMPMARKER;
-	    songend = 1;
-	  }
-	} else
-	  songend = 1;
-
-        AdPlug_LogWrite("\n");
-	return !songend;
-}
-
-void CmodPlayer::rewind(int subsong)
-{
-  unsigned long i;
-
-  // Reset playing variables
-  songend = del = ord = rw = regbd = 0;
-  tempo = bpm; speed = initspeed;
-
-  // Reset channel data
-  memset(channel,0,sizeof(Channel)*nchans);
-
-  // Compute number of patterns, if needed
-  if(!nop)
-    for(i=0;i<length;i++)
-      nop = (order[i] > nop ? order[i] : nop);
-
-  opl->init();				// Reset OPL chip
-  opl->write(1,32);			// Go to ym3812 mode
-}
-
-float CmodPlayer::getrefresh()
-{
-	return (float) (tempo / 2.5);
-}
-
-void CmodPlayer::init_trackord()
-{
-  unsigned long i;
-
-  for(i=0;i<npats*nchans;i++)
-    trackord[i / nchans][i % nchans] = i + 1;
-}
-
-bool CmodPlayer::init_specialarp()
-{
-  arplist = new unsigned char[SPECIALARPLEN];
-  arpcmd = new unsigned char[SPECIALARPLEN];
-
-  return true;
-}
-
-void CmodPlayer::init_notetable(const unsigned short *newnotetable)
-{
-  memcpy(notetable, newnotetable, 12 * 2);
-}
-
-bool CmodPlayer::realloc_order(unsigned long len)
-{
-  if(order) delete [] order;
-  order = new unsigned char[len];
-  return true;
-}
-
-bool CmodPlayer::realloc_patterns(unsigned long pats, unsigned long rows, unsigned long chans)
-{
-  unsigned long i;
-
-  dealloc_patterns();
-
-  // set new number of tracks, rows and channels
-  npats = pats; nrows = rows; nchans = chans;
-
-  // alloc new patterns
-  tracks = new Tracks *[pats * chans];
-  for(i=0;i<pats*chans;i++) tracks[i] = new Tracks[rows];
-  trackord = new unsigned short *[pats];
-  for(i=0;i<pats;i++) trackord[i] = new unsigned short[chans];
-  channel = new Channel[chans];
-
-  // initialize new patterns
-  for(i=0;i<pats*chans;i++) memset(tracks[i],0,sizeof(Tracks)*rows);
-  for(i=0;i<pats;i++) memset(trackord[i],0,chans*2);
-
-  return true;
-}
-
-void CmodPlayer::dealloc_patterns()
-{
-  unsigned long i;
-
-  // dealloc everything previously allocated
-  if(npats && nrows && nchans) {
-    for(i=0;i<npats*nchans;i++) delete [] tracks[i];
-    delete [] tracks;
-    for(i=0;i<npats;i++) delete [] trackord[i];
-    delete [] trackord;
-    delete [] channel;
-  }
-}
-
-bool CmodPlayer::realloc_instruments(unsigned long len)
-{
-  // dealloc previous instance, if any
-  if(inst) delete [] inst;
-
-  inst = new Instrument[len];
-  memset(inst,0,sizeof(Instrument)*len);	// reset instruments
-  return true;
-}
-
-void CmodPlayer::dealloc()
-{
-  if(inst) delete [] inst;
-  if(order) delete [] order;
-  if(arplist) delete [] arplist;
-  if(arpcmd) delete [] arpcmd;
-  dealloc_patterns();
-}
-
-/*** private methods *************************************/
-
-void CmodPlayer::setvolume(unsigned char chan)
-{
-	if (flags & Faust)
-        	setvolume_alt(chan);
-	else {
-		opl->write(0x40 + op_table[chan], 63-channel[chan].vol2 + (inst[channel[chan].inst].data[9] & 192));
-		opl->write(0x43 + op_table[chan], 63-channel[chan].vol1 + (inst[channel[chan].inst].data[10] & 192));
-	}
-}
-
-void CmodPlayer::setvolume_alt(unsigned char chan)
-{
-    unsigned char ivol2 = inst[channel[chan].inst].data[9] & 63;
-    unsigned char ivol1 = inst[channel[chan].inst].data[10] & 63;
-
-    opl->write(0x40 + op_table[chan], (((63 - channel[chan].vol2 & 63) + ivol2) >> 1) + (inst[channel[chan].inst].data[9] & 192));
-    opl->write(0x43 + op_table[chan], (((63 - channel[chan].vol1 & 63) + ivol1) >> 1) + (inst[channel[chan].inst].data[10] & 192));
-}
-
-void CmodPlayer::setfreq(unsigned char chan)
-{
-	opl->write(0xa0 + chan, channel[chan].freq & 255);
-	if(channel[chan].key)
-		opl->write(0xb0 + chan, ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2) | 32);
-	else
-		opl->write(0xb0 + chan, ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2));
-}
-
-void CmodPlayer::playnote(unsigned char chan)
-{
-	unsigned char op = op_table[chan], insnr = channel[chan].inst;
-
-	if(!(flags & NoKeyOn))
-	  opl->write(0xb0 + chan, 0);	// stop old note
-
-	// set instrument data
-	opl->write(0x20 + op, inst[insnr].data[1]);
-	opl->write(0x23 + op, inst[insnr].data[2]);
-	opl->write(0x60 + op, inst[insnr].data[3]);
-	opl->write(0x63 + op, inst[insnr].data[4]);
-	opl->write(0x80 + op, inst[insnr].data[5]);
-	opl->write(0x83 + op, inst[insnr].data[6]);
-	opl->write(0xe0 + op, inst[insnr].data[7]);
-	opl->write(0xe3 + op, inst[insnr].data[8]);
-	opl->write(0xc0 + chan, inst[insnr].data[0]);
-	opl->write(0xbd, inst[insnr].misc);	// set misc. register
-
-	// set frequency, volume & play
-	channel[chan].key = 1;
-	setfreq(chan);
-
-	if (flags & Faust) {
-		channel[chan].vol2 = 63;
-		channel[chan].vol1 = 63;
-	}
-	setvolume(chan);
-}
-
-void CmodPlayer::setnote(unsigned char chan, int note)
-{
-	if(note > 96)
-		if(note == 127) {	// key off
-			channel[chan].key = 0;
-			setfreq(chan);
-			return;
-		} else
-			note = 96;
-
-	if(note < 13)
-		channel[chan].freq = notetable[note - 1];
-	else
-		if(note % 12 > 0)
-			channel[chan].freq = notetable[(note % 12) - 1];
-		else
-			channel[chan].freq = notetable[11];
-	channel[chan].oct = (note - 1) / 12;
-	channel[chan].freq += inst[channel[chan].inst].slide;	// apply pre-slide
-}
-
-void CmodPlayer::slide_down(unsigned char chan, int amount)
-{
-	channel[chan].freq -= amount;
-	if(channel[chan].freq <= 342)
-		if(channel[chan].oct) {
-			channel[chan].oct--;
-			channel[chan].freq <<= 1;
-		} else
-			channel[chan].freq = 342;
-}
-
-void CmodPlayer::slide_up(unsigned char chan, int amount)
-{
-	channel[chan].freq += amount;
-	if(channel[chan].freq >= 686)
-		if(channel[chan].oct < 7) {
-			channel[chan].oct++;
-			channel[chan].freq >>= 1;
-		} else
-			channel[chan].freq = 686;
-}
-
-void CmodPlayer::tone_portamento(unsigned char chan, unsigned char info)
-{
-	if(channel[chan].freq + (channel[chan].oct << 10) < channel[chan].nextfreq +
-		(channel[chan].nextoct << 10)) {
-		slide_up(chan,info);
-		if(channel[chan].freq + (channel[chan].oct << 10) > channel[chan].nextfreq +
-		(channel[chan].nextoct << 10)) {
-			channel[chan].freq = channel[chan].nextfreq;
-			channel[chan].oct = channel[chan].nextoct;
-		}
-	}
-	if(channel[chan].freq + (channel[chan].oct << 10) > channel[chan].nextfreq +
-		(channel[chan].nextoct << 10)) {
-		slide_down(chan,info);
-		if(channel[chan].freq + (channel[chan].oct << 10) < channel[chan].nextfreq +
-		(channel[chan].nextoct << 10)) {
-			channel[chan].freq = channel[chan].nextfreq;
-			channel[chan].oct = channel[chan].nextoct;
-		}
-	}
-	setfreq(chan);
-}
-
-void CmodPlayer::vibrato(unsigned char chan, unsigned char speed, unsigned char depth)
-{
-	int i;
-
-	if(!speed || !depth)
-		return;
-
-	if(depth > 14)
-		depth = 14;
-
-	for(i=0;i<speed;i++) {
-		channel[chan].trigger++;
-		while(channel[chan].trigger >= 64)
-			channel[chan].trigger -= 64;
-		if(channel[chan].trigger >= 16 && channel[chan].trigger < 48)
-			slide_down(chan,vibratotab[channel[chan].trigger - 16] / (16-depth));
-		if(channel[chan].trigger < 16)
-			slide_up(chan,vibratotab[channel[chan].trigger + 16] / (16-depth));
-		if(channel[chan].trigger >= 48)
-			slide_up(chan,vibratotab[channel[chan].trigger - 48] / (16-depth));
-	}
-	setfreq(chan);
-}
-
-void CmodPlayer::vol_up(unsigned char chan, int amount)
-{
-	if(channel[chan].vol1 + amount < 63)
-		channel[chan].vol1 += amount;
-	else
-		channel[chan].vol1 = 63;
-
-	if(channel[chan].vol2 + amount < 63)
-		channel[chan].vol2 += amount;
-	else
-		channel[chan].vol2 = 63;
-}
-
-void CmodPlayer::vol_down(unsigned char chan, int amount)
-{
-	if(channel[chan].vol1 - amount > 0)
-		channel[chan].vol1 -= amount;
-	else
-		channel[chan].vol1 = 0;
-
-	if(channel[chan].vol2 - amount > 0)
-		channel[chan].vol2 -= amount;
-	else
-		channel[chan].vol2 = 0;
-}
-
-void CmodPlayer::vol_up_alt(unsigned char chan, int amount)
-{
-	if(channel[chan].vol1 + amount < 63)
-		channel[chan].vol1 += amount;
-	else
-		channel[chan].vol1 = 63;
-	if(inst[channel[chan].inst].data[0] & 1)
-		if(channel[chan].vol2 + amount < 63)
-			channel[chan].vol2 += amount;
-		else
-			channel[chan].vol2 = 63;
-}
-
-void CmodPlayer::vol_down_alt(unsigned char chan, int amount)
-{
-	if(channel[chan].vol1 - amount > 0)
-		channel[chan].vol1 -= amount;
-	else
-		channel[chan].vol1 = 0;
-	if(inst[channel[chan].inst].data[0] & 1)
-		if(channel[chan].vol2 - amount > 0)
-			channel[chan].vol2 -= amount;
-		else
-			channel[chan].vol2 = 0;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/protrack.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,719 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * protrack.cpp - Generic Protracker Player
+ *
+ * NOTES:
+ * This is a generic Protracker-based formats player. It offers all Protracker
+ * features, plus a good set of extensions to be compatible to other Protracker
+ * derivatives. It is derived from the original SA2 player by me. If you got a
+ * Protracker-like format, this is most certainly the player you want to use.
+ */
+
+#include "protrack.h"
+#include "debug.h"
+
+#define SPECIALARPLEN	256	// Standard length of special arpeggio lists
+#define JUMPMARKER	0x80	// Orderlist jump marker
+
+// SA2 compatible adlib note table
+const unsigned short CmodPlayer::sa2_notetable[12] =
+  {340,363,385,408,432,458,485,514,544,577,611,647};
+
+// SA2 compatible vibrato rate table
+const unsigned char CmodPlayer::vibratotab[32] =
+  {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1};
+
+/*** public methods *************************************/
+
+CmodPlayer::CmodPlayer(Copl *newopl)
+  : CPlayer(newopl), inst(0), order(0), arplist(0), arpcmd(0), initspeed(6),
+    activechan(0xffff), flags(Standard), nop(0), nrows(0), npats(0), nchans(0)
+{
+  realloc_order(128);
+  realloc_patterns(64, 64, 9);
+  realloc_instruments(250);
+  init_notetable(sa2_notetable);
+}
+
+CmodPlayer::~CmodPlayer()
+{
+  dealloc();
+}
+
+bool CmodPlayer::update()
+{
+	unsigned char pattbreak=0,donote;		// remember vars
+	unsigned char pattnr,chan,info1,info2,info;	// cache vars
+	unsigned short track;
+	unsigned long row;
+
+	if(!speed)		// song full stop
+		return !songend;
+
+	// effect handling (timer dependant)
+	for(chan=0;chan<nchans;chan++) {
+		if(arplist && arpcmd && inst[channel[chan].inst].arpstart)	// special arpeggio
+			if(channel[chan].arpspdcnt)
+				channel[chan].arpspdcnt--;
+			else
+				if(arpcmd[channel[chan].arppos] != 255) {
+					switch(arpcmd[channel[chan].arppos]) {
+					case 252: channel[chan].vol1 = arplist[channel[chan].arppos];	// set volume
+							if(channel[chan].vol1 > 63)	// ?????
+								channel[chan].vol1 = 63;
+							channel[chan].vol2 = channel[chan].vol1;
+							setvolume(chan);
+							break;
+					case 253: channel[chan].key = 0; setfreq(chan); break;	// release sustaining note
+					case 254: channel[chan].arppos = arplist[channel[chan].arppos]; break; // arpeggio loop
+					default: if(arpcmd[channel[chan].arppos]) {
+								if(arpcmd[channel[chan].arppos] / 10)
+									opl->write(0xe3 + op_table[chan], arpcmd[channel[chan].arppos] / 10 - 1);
+								if(arpcmd[channel[chan].arppos] % 10)
+									opl->write(0xe0 + op_table[chan], (arpcmd[channel[chan].arppos] % 10) - 1);
+								if(arpcmd[channel[chan].arppos] < 10)	// ?????
+									opl->write(0xe0 + op_table[chan], arpcmd[channel[chan].arppos] - 1);
+							 }
+					}
+					if(arpcmd[channel[chan].arppos] != 252) {
+						if(arplist[channel[chan].arppos] <= 96)
+							setnote(chan,channel[chan].note + arplist[channel[chan].arppos]);
+						if(arplist[channel[chan].arppos] >= 100)
+							setnote(chan,arplist[channel[chan].arppos] - 100);
+					} else
+						setnote(chan,channel[chan].note);
+					setfreq(chan);
+					if(arpcmd[channel[chan].arppos] != 255)
+						channel[chan].arppos++;
+					channel[chan].arpspdcnt = inst[channel[chan].inst].arpspeed - 1;
+				}
+
+		info1 = channel[chan].info1;
+		info2 = channel[chan].info2;
+		if(flags & Decimal)
+			info = channel[chan].info1 * 10 + channel[chan].info2;
+		else
+			info = (channel[chan].info1 << 4) + channel[chan].info2;
+		switch(channel[chan].fx) {
+		case 0:	if(info) {									// arpeggio
+					if(channel[chan].trigger < 2)
+						channel[chan].trigger++;
+					else
+						channel[chan].trigger = 0;
+					switch(channel[chan].trigger) {
+					case 0: setnote(chan,channel[chan].note); break;
+					case 1: setnote(chan,channel[chan].note + info1); break;
+					case 2: setnote(chan,channel[chan].note + info2);
+					}
+					setfreq(chan);
+				}
+				break;
+		case 1: slide_up(chan,info); setfreq(chan); break;	// slide up
+		case 2: slide_down(chan,info); setfreq(chan); break;	// slide down
+		case 3: tone_portamento(chan,channel[chan].portainfo); break;	// tone portamento
+		case 4: vibrato(chan,channel[chan].vibinfo1,channel[chan].vibinfo2); break;	// vibrato
+		case 5:												// tone portamento & volume slide
+		case 6: if(channel[chan].fx == 5)				// vibrato & volume slide
+					tone_portamento(chan,channel[chan].portainfo);
+				else
+					vibrato(chan,channel[chan].vibinfo1,channel[chan].vibinfo2);
+		case 10: if(del % 4)	// SA2 volume slide
+					break;
+				 if(info1)
+					 vol_up(chan,info1);
+				 else
+					 vol_down(chan,info2);
+				 setvolume(chan);
+				 break;
+		case 14: if(info1 == 3)							// retrig note
+					if(!(del % (info2+1)))
+						playnote(chan);
+				 break;
+		case 16: if(del % 4)	// AMD volume slide
+					break;
+				 if(info1)
+					 vol_up_alt(chan,info1);
+				 else
+					 vol_down_alt(chan,info2);
+				 setvolume(chan);
+				 break;
+		case 20:				// RAD volume slide
+			if(info < 50)
+				vol_down_alt(chan,info);
+			else
+				vol_up_alt(chan,info - 50);
+			setvolume(chan);
+			break;
+		case 26: // volume slide
+			if(info1)
+				vol_up(chan,info1);
+			else
+				vol_down(chan,info2);
+			setvolume(chan);
+			break;
+		case 28:
+			if (info1) {
+				slide_up(chan,1); channel[chan].info1--;
+			}
+			if (info2) {
+				slide_down(chan,1); channel[chan].info2--;
+			}
+			setfreq(chan);
+			break;
+		}
+	}
+
+	if(del) {		// speed compensation
+		del--;
+		return !songend;
+	}
+
+	// arrangement handling
+	if(ord >= length) {
+		songend = 1;				// set end-flag
+		ord = restartpos;
+	}
+	pattnr = order[ord];
+
+        if(!rw) AdPlug_LogWrite("\nCmodPlayer::update(): Pattern: %d, Order: %d\n", pattnr, ord);
+        AdPlug_LogWrite("CmodPlayer::update():%3d|", rw);
+
+	// play row
+	row = rw;
+	for(chan=0;chan<nchans;chan++) {
+		if(!(activechan >> (15 - chan)) & 1) {	// channel active?
+                  AdPlug_LogWrite("N/A|");
+		  continue;
+		}
+		if(!(track = trackord[pattnr][chan])) {	// resolve track
+                  AdPlug_LogWrite("------------|");
+		  continue;
+		} else
+			track--;
+
+                AdPlug_LogWrite("%3d%3d%2X%2X%2X|", tracks[track][row].note,
+			 tracks[track][row].inst, tracks[track][row].command,
+			 tracks[track][row].param1, tracks[track][row].param2);
+
+		donote = 0;
+		if(tracks[track][row].inst) {
+		  channel[chan].inst = tracks[track][row].inst - 1;
+		  if (!(flags & Faust)) {
+		    channel[chan].vol1 = 63 - (inst[channel[chan].inst].data[10] & 63);
+		    channel[chan].vol2 = 63 - (inst[channel[chan].inst].data[9] & 63);
+		    setvolume(chan);
+		  }
+		}
+
+		if(tracks[track][row].note && tracks[track][row].command != 3) {	// no tone portamento
+			channel[chan].note = tracks[track][row].note;
+			setnote(chan,tracks[track][row].note);
+			channel[chan].nextfreq = channel[chan].freq;
+			channel[chan].nextoct = channel[chan].oct;
+			channel[chan].arppos = inst[channel[chan].inst].arpstart;
+			channel[chan].arpspdcnt = 0;
+			if(tracks[track][row].note != 127)	// handle key off
+				donote = 1;
+		}
+		channel[chan].fx = tracks[track][row].command;
+		channel[chan].info1 = tracks[track][row].param1;
+		channel[chan].info2 = tracks[track][row].param2;
+
+		if(donote)
+			playnote(chan);
+
+		// command handling (row dependant)
+		info1 = channel[chan].info1;
+		info2 = channel[chan].info2;
+		if(flags & Decimal)
+			info = channel[chan].info1 * 10 + channel[chan].info2;
+		else
+			info = (channel[chan].info1 << 4) + channel[chan].info2;
+		switch(channel[chan].fx) {
+		case 3:	if(tracks[track][row].note) {					// tone portamento
+					if(tracks[track][row].note < 13)
+						channel[chan].nextfreq = notetable[tracks[track][row].note - 1];
+					else
+						if(tracks[track][row].note % 12 > 0)
+							channel[chan].nextfreq = notetable[(tracks[track][row].note % 12) - 1];
+						else
+							channel[chan].nextfreq = notetable[11];
+					channel[chan].nextoct = (tracks[track][row].note - 1) / 12;
+					if(tracks[track][row].note == 127) {	// handle key off
+						channel[chan].nextfreq = channel[chan].freq;
+						channel[chan].nextoct = channel[chan].oct;
+					}
+				}
+				if(info)		// remember vars
+					channel[chan].portainfo = info;
+				break;
+		case 4: if(info) {										// vibrato (remember vars)
+					channel[chan].vibinfo1 = info1;
+					channel[chan].vibinfo2 = info2;
+				}
+				break;
+		case 7: tempo = info; break;							// set tempo
+		case 8: channel[chan].key = 0; setfreq(chan); break;	// release sustaining note
+		case 9: // set carrier/modulator volume
+				if(info1)
+					channel[chan].vol1 = info1 * 7;
+				else
+					channel[chan].vol2 = info2 * 7;
+				setvolume(chan);
+				break;
+		case 11: pattbreak = 1; rw = 0; if(info < ord) songend = 1; ord = info; break; // position jump
+		case 12: // set volume
+				channel[chan].vol1 = info;
+				channel[chan].vol2 = info;
+				if(channel[chan].vol1 > 63)
+					channel[chan].vol1 = 63;
+				if(channel[chan].vol2 > 63)
+					channel[chan].vol2 = 63;
+				setvolume(chan);
+				break;
+		case 13: if(!pattbreak) { pattbreak = 1; rw = info; ord++; } break;	// pattern break
+		case 14: // extended command
+				switch(info1) {
+				case 0: if(info2)								// define cell-tremolo
+							regbd |= 128;
+						else
+							regbd &= 127;
+						opl->write(0xbd,regbd);
+						break;
+				case 1: if(info2)								// define cell-vibrato
+							regbd |= 64;
+						else
+							regbd &= 191;
+						opl->write(0xbd,regbd);
+						break;
+				case 4: vol_up_alt(chan,info2);					// increase volume fine
+						setvolume(chan);
+						break;
+				case 5: vol_down_alt(chan,info2);				// decrease volume fine
+						setvolume(chan);
+						break;
+				case 6: slide_up(chan,info2);					// manual slide up
+						setfreq(chan);
+						break;
+				case 7: slide_down(chan,info2);					// manual slide down
+						setfreq(chan);
+						break;
+				}
+				break;
+		case 15: // SA2 set speed
+			if(info <= 0x1f)
+				speed = info;
+			if(info >= 0x32)
+				tempo = info;
+			if(!info)
+				songend = 1;
+			break;
+		case 17: // alternate set volume
+			channel[chan].vol1 = info;
+			if(channel[chan].vol1 > 63)
+				channel[chan].vol1 = 63;
+			if(inst[channel[chan].inst].data[0] & 1) {
+				channel[chan].vol2 = info;
+	 			if(channel[chan].vol2 > 63)
+					channel[chan].vol2 = 63;
+			}
+
+			setvolume(chan);
+			break;
+		case 18: // AMD set speed
+			if(info <= 31 && info > 0)
+				speed = info;
+			if(info > 31 || !info)
+				tempo = info;
+			break;
+		case 19: // RAD/A2M set speed
+			speed = (info ? info : info + 1);
+			break;
+		case 21: // set modulator volume
+			if(info <= 63)
+				channel[chan].vol2 = info;
+			else
+				channel[chan].vol2 = 63;
+			setvolume(chan);
+			break;
+		case 22: // set carrier volume
+			if(info <= 63)
+				channel[chan].vol1 = info;
+			else
+				channel[chan].vol1 = 63;
+			setvolume(chan);
+			break;
+		case 23: // fine frequency slide up
+			slide_up(chan,info);
+			setfreq(chan);
+			break;
+		case 24: // fine frequency slide down
+			slide_down(chan,info);
+			setfreq(chan);
+			break;
+		case 25: // set carrier/modulator waveform
+			if(info1 != 0x0f)
+				opl->write(0xe3 + op_table[chan],info1);
+			if(info2 != 0x0f)
+				opl->write(0xe0 + op_table[chan],info2);
+			break;
+		case 27: // set chip tremolo/vibrato
+			if (info1)
+				regbd |= 128;
+			else
+				regbd &= 127;
+			if (info2)
+				regbd |= 64;
+			else
+				regbd &= 191;
+			opl->write(0xbd,regbd);
+			break;
+		}
+	}
+
+	del = speed - 1;	// speed compensation
+	if(!pattbreak) {	// next row (only if no manual advance)
+		rw++;
+		if(rw >= nrows) {
+			rw = 0;
+			ord++;
+		}
+	}
+	if(ord < length) {
+	  if(order[ord] >= JUMPMARKER) {	// jump to order
+	    ord = order[ord] - JUMPMARKER;
+	    songend = 1;
+	  }
+	} else
+	  songend = 1;
+
+        AdPlug_LogWrite("\n");
+	return !songend;
+}
+
+void CmodPlayer::rewind(int subsong)
+{
+  unsigned long i;
+
+  // Reset playing variables
+  songend = del = ord = rw = regbd = 0;
+  tempo = bpm; speed = initspeed;
+
+  // Reset channel data
+  memset(channel,0,sizeof(Channel)*nchans);
+
+  // Compute number of patterns, if needed
+  if(!nop)
+    for(i=0;i<length;i++)
+      nop = (order[i] > nop ? order[i] : nop);
+
+  opl->init();				// Reset OPL chip
+  opl->write(1,32);			// Go to ym3812 mode
+}
+
+float CmodPlayer::getrefresh()
+{
+	return (float) (tempo / 2.5);
+}
+
+void CmodPlayer::init_trackord()
+{
+  unsigned long i;
+
+  for(i=0;i<npats*nchans;i++)
+    trackord[i / nchans][i % nchans] = i + 1;
+}
+
+bool CmodPlayer::init_specialarp()
+{
+  arplist = new unsigned char[SPECIALARPLEN];
+  arpcmd = new unsigned char[SPECIALARPLEN];
+
+  return true;
+}
+
+void CmodPlayer::init_notetable(const unsigned short *newnotetable)
+{
+  memcpy(notetable, newnotetable, 12 * 2);
+}
+
+bool CmodPlayer::realloc_order(unsigned long len)
+{
+  if(order) delete [] order;
+  order = new unsigned char[len];
+  return true;
+}
+
+bool CmodPlayer::realloc_patterns(unsigned long pats, unsigned long rows, unsigned long chans)
+{
+  unsigned long i;
+
+  dealloc_patterns();
+
+  // set new number of tracks, rows and channels
+  npats = pats; nrows = rows; nchans = chans;
+
+  // alloc new patterns
+  tracks = new Tracks *[pats * chans];
+  for(i=0;i<pats*chans;i++) tracks[i] = new Tracks[rows];
+  trackord = new unsigned short *[pats];
+  for(i=0;i<pats;i++) trackord[i] = new unsigned short[chans];
+  channel = new Channel[chans];
+
+  // initialize new patterns
+  for(i=0;i<pats*chans;i++) memset(tracks[i],0,sizeof(Tracks)*rows);
+  for(i=0;i<pats;i++) memset(trackord[i],0,chans*2);
+
+  return true;
+}
+
+void CmodPlayer::dealloc_patterns()
+{
+  unsigned long i;
+
+  // dealloc everything previously allocated
+  if(npats && nrows && nchans) {
+    for(i=0;i<npats*nchans;i++) delete [] tracks[i];
+    delete [] tracks;
+    for(i=0;i<npats;i++) delete [] trackord[i];
+    delete [] trackord;
+    delete [] channel;
+  }
+}
+
+bool CmodPlayer::realloc_instruments(unsigned long len)
+{
+  // dealloc previous instance, if any
+  if(inst) delete [] inst;
+
+  inst = new Instrument[len];
+  memset(inst,0,sizeof(Instrument)*len);	// reset instruments
+  return true;
+}
+
+void CmodPlayer::dealloc()
+{
+  if(inst) delete [] inst;
+  if(order) delete [] order;
+  if(arplist) delete [] arplist;
+  if(arpcmd) delete [] arpcmd;
+  dealloc_patterns();
+}
+
+/*** private methods *************************************/
+
+void CmodPlayer::setvolume(unsigned char chan)
+{
+	if (flags & Faust)
+        	setvolume_alt(chan);
+	else {
+		opl->write(0x40 + op_table[chan], 63-channel[chan].vol2 + (inst[channel[chan].inst].data[9] & 192));
+		opl->write(0x43 + op_table[chan], 63-channel[chan].vol1 + (inst[channel[chan].inst].data[10] & 192));
+	}
+}
+
+void CmodPlayer::setvolume_alt(unsigned char chan)
+{
+    unsigned char ivol2 = inst[channel[chan].inst].data[9] & 63;
+    unsigned char ivol1 = inst[channel[chan].inst].data[10] & 63;
+
+    opl->write(0x40 + op_table[chan], (((63 - channel[chan].vol2 & 63) + ivol2) >> 1) + (inst[channel[chan].inst].data[9] & 192));
+    opl->write(0x43 + op_table[chan], (((63 - channel[chan].vol1 & 63) + ivol1) >> 1) + (inst[channel[chan].inst].data[10] & 192));
+}
+
+void CmodPlayer::setfreq(unsigned char chan)
+{
+	opl->write(0xa0 + chan, channel[chan].freq & 255);
+	if(channel[chan].key)
+		opl->write(0xb0 + chan, ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2) | 32);
+	else
+		opl->write(0xb0 + chan, ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2));
+}
+
+void CmodPlayer::playnote(unsigned char chan)
+{
+	unsigned char op = op_table[chan], insnr = channel[chan].inst;
+
+	if(!(flags & NoKeyOn))
+	  opl->write(0xb0 + chan, 0);	// stop old note
+
+	// set instrument data
+	opl->write(0x20 + op, inst[insnr].data[1]);
+	opl->write(0x23 + op, inst[insnr].data[2]);
+	opl->write(0x60 + op, inst[insnr].data[3]);
+	opl->write(0x63 + op, inst[insnr].data[4]);
+	opl->write(0x80 + op, inst[insnr].data[5]);
+	opl->write(0x83 + op, inst[insnr].data[6]);
+	opl->write(0xe0 + op, inst[insnr].data[7]);
+	opl->write(0xe3 + op, inst[insnr].data[8]);
+	opl->write(0xc0 + chan, inst[insnr].data[0]);
+	opl->write(0xbd, inst[insnr].misc);	// set misc. register
+
+	// set frequency, volume & play
+	channel[chan].key = 1;
+	setfreq(chan);
+
+	if (flags & Faust) {
+		channel[chan].vol2 = 63;
+		channel[chan].vol1 = 63;
+	}
+	setvolume(chan);
+}
+
+void CmodPlayer::setnote(unsigned char chan, int note)
+{
+	if(note > 96)
+		if(note == 127) {	// key off
+			channel[chan].key = 0;
+			setfreq(chan);
+			return;
+		} else
+			note = 96;
+
+	if(note < 13)
+		channel[chan].freq = notetable[note - 1];
+	else
+		if(note % 12 > 0)
+			channel[chan].freq = notetable[(note % 12) - 1];
+		else
+			channel[chan].freq = notetable[11];
+	channel[chan].oct = (note - 1) / 12;
+	channel[chan].freq += inst[channel[chan].inst].slide;	// apply pre-slide
+}
+
+void CmodPlayer::slide_down(unsigned char chan, int amount)
+{
+	channel[chan].freq -= amount;
+	if(channel[chan].freq <= 342)
+		if(channel[chan].oct) {
+			channel[chan].oct--;
+			channel[chan].freq <<= 1;
+		} else
+			channel[chan].freq = 342;
+}
+
+void CmodPlayer::slide_up(unsigned char chan, int amount)
+{
+	channel[chan].freq += amount;
+	if(channel[chan].freq >= 686)
+		if(channel[chan].oct < 7) {
+			channel[chan].oct++;
+			channel[chan].freq >>= 1;
+		} else
+			channel[chan].freq = 686;
+}
+
+void CmodPlayer::tone_portamento(unsigned char chan, unsigned char info)
+{
+	if(channel[chan].freq + (channel[chan].oct << 10) < channel[chan].nextfreq +
+		(channel[chan].nextoct << 10)) {
+		slide_up(chan,info);
+		if(channel[chan].freq + (channel[chan].oct << 10) > channel[chan].nextfreq +
+		(channel[chan].nextoct << 10)) {
+			channel[chan].freq = channel[chan].nextfreq;
+			channel[chan].oct = channel[chan].nextoct;
+		}
+	}
+	if(channel[chan].freq + (channel[chan].oct << 10) > channel[chan].nextfreq +
+		(channel[chan].nextoct << 10)) {
+		slide_down(chan,info);
+		if(channel[chan].freq + (channel[chan].oct << 10) < channel[chan].nextfreq +
+		(channel[chan].nextoct << 10)) {
+			channel[chan].freq = channel[chan].nextfreq;
+			channel[chan].oct = channel[chan].nextoct;
+		}
+	}
+	setfreq(chan);
+}
+
+void CmodPlayer::vibrato(unsigned char chan, unsigned char speed, unsigned char depth)
+{
+	int i;
+
+	if(!speed || !depth)
+		return;
+
+	if(depth > 14)
+		depth = 14;
+
+	for(i=0;i<speed;i++) {
+		channel[chan].trigger++;
+		while(channel[chan].trigger >= 64)
+			channel[chan].trigger -= 64;
+		if(channel[chan].trigger >= 16 && channel[chan].trigger < 48)
+			slide_down(chan,vibratotab[channel[chan].trigger - 16] / (16-depth));
+		if(channel[chan].trigger < 16)
+			slide_up(chan,vibratotab[channel[chan].trigger + 16] / (16-depth));
+		if(channel[chan].trigger >= 48)
+			slide_up(chan,vibratotab[channel[chan].trigger - 48] / (16-depth));
+	}
+	setfreq(chan);
+}
+
+void CmodPlayer::vol_up(unsigned char chan, int amount)
+{
+	if(channel[chan].vol1 + amount < 63)
+		channel[chan].vol1 += amount;
+	else
+		channel[chan].vol1 = 63;
+
+	if(channel[chan].vol2 + amount < 63)
+		channel[chan].vol2 += amount;
+	else
+		channel[chan].vol2 = 63;
+}
+
+void CmodPlayer::vol_down(unsigned char chan, int amount)
+{
+	if(channel[chan].vol1 - amount > 0)
+		channel[chan].vol1 -= amount;
+	else
+		channel[chan].vol1 = 0;
+
+	if(channel[chan].vol2 - amount > 0)
+		channel[chan].vol2 -= amount;
+	else
+		channel[chan].vol2 = 0;
+}
+
+void CmodPlayer::vol_up_alt(unsigned char chan, int amount)
+{
+	if(channel[chan].vol1 + amount < 63)
+		channel[chan].vol1 += amount;
+	else
+		channel[chan].vol1 = 63;
+	if(inst[channel[chan].inst].data[0] & 1)
+		if(channel[chan].vol2 + amount < 63)
+			channel[chan].vol2 += amount;
+		else
+			channel[chan].vol2 = 63;
+}
+
+void CmodPlayer::vol_down_alt(unsigned char chan, int amount)
+{
+	if(channel[chan].vol1 - amount > 0)
+		channel[chan].vol1 -= amount;
+	else
+		channel[chan].vol1 = 0;
+	if(inst[channel[chan].inst].data[0] & 1)
+		if(channel[chan].vol2 - amount > 0)
+			channel[chan].vol2 -= amount;
+		else
+			channel[chan].vol2 = 0;
+}
--- a/Plugins/Input/adplug/core/psi.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,177 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * [xad] PSI player, by Riven the Mage <riven@ok.ru>
- */
-
-/*
-    - discovery -
-
-  file(s) : 4BIDDEN.COM, PGRID.EXE
-     type : Forbidden Dreams BBStro
-            Power Grid BBStro
-     tune : by Friar Tuck [Shadow Faction/ICE]
-   player : by Psi [Future Crew]
-  comment : seems to me what 4bidden tune & player was ripped from pgrid
-
-  file(s) : MYSTRUNE.COM
-     type : Mystical Runes BBStro
-     tune : by ?
-   player : by Psi [Future Crew]
-*/
-
-#include "psi.h"
-#include "debug.h"
-
-const unsigned char CxadpsiPlayer::psi_adlib_registers[99] =
-{
-  0x20, 0x23, 0x40, 0x43, 0x60, 0x63, 0x80, 0x83, 0xE0, 0xE3, 0xC0,
-  0x21, 0x24, 0x41, 0x44, 0x61, 0x64, 0x81, 0x84, 0xE1, 0xE4, 0xC1,
-  0x22, 0x25, 0x42, 0x45, 0x62, 0x65, 0x82, 0x85, 0xE2, 0xE5, 0xC2,
-  0x28, 0x2B, 0x48, 0x4B, 0x68, 0x6B, 0x88, 0x8B, 0xE8, 0xEB, 0xC3,
-  0x29, 0x2C, 0x49, 0x4C, 0x69, 0x6C, 0x89, 0x8C, 0xE9, 0xEC, 0xC4,
-  0x2A, 0x2D, 0x4A, 0x4D, 0x6A, 0x6D, 0x8A, 0x8D, 0xEA, 0xED, 0xC5,
-  0x30, 0x33, 0x50, 0x53, 0x70, 0x73, 0x90, 0x93, 0xF0, 0xF3, 0xC6,
-  0x31, 0x34, 0x51, 0x54, 0x71, 0x74, 0x91, 0x94, 0xF1, 0xF4, 0xC7,
-  0x32, 0x35, 0x52, 0x55, 0x72, 0x75, 0x92, 0x95, 0xF2, 0xF5, 0xC8
-};
-
-const unsigned short CxadpsiPlayer::psi_notes[16] =
-{
-  0x216B, 0x2181, 0x2198, 0x21B0, 0x21CA, 0x21E5, 0x2202, 0x2220,
-  0x2241, 0x2263, 0x2287, 0x2364,
-  0x0000, 0x0000, 0x0000, 0x0000 // by riven
-};
-
-CPlayer *CxadpsiPlayer::factory(Copl *newopl)
-{
-  return new CxadpsiPlayer(newopl);
-}
-
-void CxadpsiPlayer::xadplayer_rewind(int subsong)
-{
-  opl_write(0x01, 0x20);
-  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 = &tune[header.instr_ptr];
-
-  for(int i=0; i<8; i++)
-  {
-    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);
-
-    psi.note_delay[i] = 1;
-    psi.note_curdelay[i] = 1;
-    psi.looping[i] = 0;
-  }
-
-  // calculate sequence pointer
-  psi.seq_table = &tune[header.seq_ptr];
-}
-
-void CxadpsiPlayer::xadplayer_update()
-{
-  unsigned short ptr;
-
-  for(int i=0; i<8; i++)
-  {
-    ptr = (psi.seq_table[(i<<1) * 2 + 1] << 8) + psi.seq_table[(i<<1) * 2];
-
-    psi.note_curdelay[i]--;
-
-    if (!psi.note_curdelay[i])
-    {
-      opl_write(0xA0+i, 0x00);
-      opl_write(0xB0+i, 0x00);
-
-      unsigned char event = tune[ptr++];
-#ifdef DEBUG
-  AdPlug_LogWrite("channel %02X, event %02X:\n",i+1,event);
-#endif
-
-      // end of sequence ?
-      if (!event)
-      {
-	ptr = (psi.seq_table[(i<<1) * 2 + 3] << 8) + psi.seq_table[(i<<1) * 2 + 2];
-
-        event = tune[ptr++];
-#ifdef DEBUG
-  AdPlug_LogWrite(" channel %02X, event %02X:\n",i+1,event);
-#endif
-
-        // set sequence loop flag
-        psi.looping[i] = 1;
-
-        // module loop ?
-        plr.looping = 1;
-        for(int j=0; j<8; j++)
-          plr.looping &= psi.looping[j];
-      }
-
-      // new note delay ?
-      if (event & 0x80)
-      {
-        psi.note_delay[i] = (event & 0x7F);
-
-        event = tune[ptr++];
-#ifdef DEBUG
-  AdPlug_LogWrite("  channel %02X, event %02X:\n",i+1,event);
-#endif
-      }
-
-      psi.note_curdelay[i] = psi.note_delay[i];
-
-      // play note
-      unsigned short note = psi_notes[event & 0x0F];
-
-      opl_write(0xA0+i, note & 0xFF);
-      opl_write(0xB0+i, (note >> 8) + ((event >> 2) & 0xFC));
-
-      // save position
-      psi.seq_table[(i<<1) * 2] = ptr & 0xff;
-      psi.seq_table[(i<<1) * 2 + 1] = ptr >> 8;
-    }
-  }
-}
-
-float CxadpsiPlayer::xadplayer_getrefresh()
-{
-  return 70.0f;
-}
-
-std::string CxadpsiPlayer::xadplayer_gettype()
-{
-  return std::string("xad: psi player");
-}
-
-unsigned int CxadpsiPlayer::xadplayer_getinstruments()
-{
-  return 8;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/psi.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,177 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * [xad] PSI player, by Riven the Mage <riven@ok.ru>
+ */
+
+/*
+    - discovery -
+
+  file(s) : 4BIDDEN.COM, PGRID.EXE
+     type : Forbidden Dreams BBStro
+            Power Grid BBStro
+     tune : by Friar Tuck [Shadow Faction/ICE]
+   player : by Psi [Future Crew]
+  comment : seems to me what 4bidden tune & player was ripped from pgrid
+
+  file(s) : MYSTRUNE.COM
+     type : Mystical Runes BBStro
+     tune : by ?
+   player : by Psi [Future Crew]
+*/
+
+#include "psi.h"
+#include "debug.h"
+
+const unsigned char CxadpsiPlayer::psi_adlib_registers[99] =
+{
+  0x20, 0x23, 0x40, 0x43, 0x60, 0x63, 0x80, 0x83, 0xE0, 0xE3, 0xC0,
+  0x21, 0x24, 0x41, 0x44, 0x61, 0x64, 0x81, 0x84, 0xE1, 0xE4, 0xC1,
+  0x22, 0x25, 0x42, 0x45, 0x62, 0x65, 0x82, 0x85, 0xE2, 0xE5, 0xC2,
+  0x28, 0x2B, 0x48, 0x4B, 0x68, 0x6B, 0x88, 0x8B, 0xE8, 0xEB, 0xC3,
+  0x29, 0x2C, 0x49, 0x4C, 0x69, 0x6C, 0x89, 0x8C, 0xE9, 0xEC, 0xC4,
+  0x2A, 0x2D, 0x4A, 0x4D, 0x6A, 0x6D, 0x8A, 0x8D, 0xEA, 0xED, 0xC5,
+  0x30, 0x33, 0x50, 0x53, 0x70, 0x73, 0x90, 0x93, 0xF0, 0xF3, 0xC6,
+  0x31, 0x34, 0x51, 0x54, 0x71, 0x74, 0x91, 0x94, 0xF1, 0xF4, 0xC7,
+  0x32, 0x35, 0x52, 0x55, 0x72, 0x75, 0x92, 0x95, 0xF2, 0xF5, 0xC8
+};
+
+const unsigned short CxadpsiPlayer::psi_notes[16] =
+{
+  0x216B, 0x2181, 0x2198, 0x21B0, 0x21CA, 0x21E5, 0x2202, 0x2220,
+  0x2241, 0x2263, 0x2287, 0x2364,
+  0x0000, 0x0000, 0x0000, 0x0000 // by riven
+};
+
+CPlayer *CxadpsiPlayer::factory(Copl *newopl)
+{
+  return new CxadpsiPlayer(newopl);
+}
+
+void CxadpsiPlayer::xadplayer_rewind(int subsong)
+{
+  opl_write(0x01, 0x20);
+  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 = &tune[header.instr_ptr];
+
+  for(int i=0; i<8; i++)
+  {
+    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);
+
+    psi.note_delay[i] = 1;
+    psi.note_curdelay[i] = 1;
+    psi.looping[i] = 0;
+  }
+
+  // calculate sequence pointer
+  psi.seq_table = &tune[header.seq_ptr];
+}
+
+void CxadpsiPlayer::xadplayer_update()
+{
+  unsigned short ptr;
+
+  for(int i=0; i<8; i++)
+  {
+    ptr = (psi.seq_table[(i<<1) * 2 + 1] << 8) + psi.seq_table[(i<<1) * 2];
+
+    psi.note_curdelay[i]--;
+
+    if (!psi.note_curdelay[i])
+    {
+      opl_write(0xA0+i, 0x00);
+      opl_write(0xB0+i, 0x00);
+
+      unsigned char event = tune[ptr++];
+#ifdef DEBUG
+  AdPlug_LogWrite("channel %02X, event %02X:\n",i+1,event);
+#endif
+
+      // end of sequence ?
+      if (!event)
+      {
+	ptr = (psi.seq_table[(i<<1) * 2 + 3] << 8) + psi.seq_table[(i<<1) * 2 + 2];
+
+        event = tune[ptr++];
+#ifdef DEBUG
+  AdPlug_LogWrite(" channel %02X, event %02X:\n",i+1,event);
+#endif
+
+        // set sequence loop flag
+        psi.looping[i] = 1;
+
+        // module loop ?
+        plr.looping = 1;
+        for(int j=0; j<8; j++)
+          plr.looping &= psi.looping[j];
+      }
+
+      // new note delay ?
+      if (event & 0x80)
+      {
+        psi.note_delay[i] = (event & 0x7F);
+
+        event = tune[ptr++];
+#ifdef DEBUG
+  AdPlug_LogWrite("  channel %02X, event %02X:\n",i+1,event);
+#endif
+      }
+
+      psi.note_curdelay[i] = psi.note_delay[i];
+
+      // play note
+      unsigned short note = psi_notes[event & 0x0F];
+
+      opl_write(0xA0+i, note & 0xFF);
+      opl_write(0xB0+i, (note >> 8) + ((event >> 2) & 0xFC));
+
+      // save position
+      psi.seq_table[(i<<1) * 2] = ptr & 0xff;
+      psi.seq_table[(i<<1) * 2 + 1] = ptr >> 8;
+    }
+  }
+}
+
+float CxadpsiPlayer::xadplayer_getrefresh()
+{
+  return 70.0f;
+}
+
+std::string CxadpsiPlayer::xadplayer_gettype()
+{
+  return std::string("xad: psi player");
+}
+
+unsigned int CxadpsiPlayer::xadplayer_getinstruments()
+{
+  return 8;
+}
--- a/Plugins/Input/adplug/core/rad.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,124 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * rad.cpp - RAD Loader by Simon Peter <dn.tlp@gmx.net>
- *
- * BUGS:
- * some volumes are dropped out
- */
-
-#include "rad.h"
-
-CPlayer *CradLoader::factory(Copl *newopl)
-{
-  return new CradLoader(newopl);
-}
-
-bool CradLoader::load(const std::string &filename, const CFileProvider &fp)
-{
-        binistream *f = fp.open(filename); if(!f) return false;
-	char id[16];
-	unsigned char buf,ch,c,b,inp;
-	char bufstr[2] = "\0";
-	unsigned int i,j;
-	unsigned short patofs[32];
-	const unsigned char convfx[16] = {255,1,2,3,255,5,255,255,255,255,20,255,17,0xd,255,19};
-
-	// file validation section
-	f->readString(id, 16); version = f->readInt(1);
-	if(strncmp(id,"RAD by REALiTY!!",16) || version != 0x10)
-	  { fp.close(f); return false; }
-
-	// load section
-	radflags = f->readInt(1);
-	if(radflags & 128) {	// description
-		memset(desc,0,80*22);
-		while((buf = f->readInt(1)))
-			if(buf == 1)
-				strcat(desc,"\n");
-			else
-				if(buf >= 2 && buf <= 0x1f)
-					for(i=0;i<buf;i++)
-						strcat(desc," ");
-				else {
-					*bufstr = buf;
-					strcat(desc,bufstr);
-				}
-	}
-	while((buf = f->readInt(1))) {	// instruments
-		buf--;
-		inst[buf].data[2] = f->readInt(1); inst[buf].data[1] = f->readInt(1);
-		inst[buf].data[10] = f->readInt(1); inst[buf].data[9] = f->readInt(1);
-		inst[buf].data[4] = f->readInt(1); inst[buf].data[3] = f->readInt(1);
-		inst[buf].data[6] = f->readInt(1); inst[buf].data[5] = f->readInt(1);
-		inst[buf].data[0] = f->readInt(1);
-		inst[buf].data[8] = f->readInt(1); inst[buf].data[7] = f->readInt(1);
-	}
-	length = f->readInt(1);
-	for(i = 0; i < length; i++) order[i] = f->readInt(1);	// orderlist
-	for(i = 0; i < 32; i++) patofs[i] = f->readInt(2);	// pattern offset table
-	init_trackord();		// patterns
-	for(i=0;i<32;i++)
-		if(patofs[i]) {
-			f->seek(patofs[i]);
-			do {
-				buf = f->readInt(1); b = buf & 127;
-				do {
-					ch = f->readInt(1); c = ch & 127;
-					inp = f->readInt(1);
-					tracks[i*9+c][b].note = inp & 127;
-					tracks[i*9+c][b].inst = (inp & 128) >> 3;
-					inp = f->readInt(1);
-					tracks[i*9+c][b].inst += inp >> 4;
-					tracks[i*9+c][b].command = inp & 15;
-					if(inp & 15) {
-						inp = f->readInt(1);
-						tracks[i*9+c][b].param1 = inp / 10;
-						tracks[i*9+c][b].param2 = inp % 10;
-					}
-				} while(!(ch & 128));
-			} while(!(buf & 128));
-		} else
-			memset(trackord[i],0,9*2);
-	fp.close(f);
-
-	// convert replay data
-	for(i=0;i<32*9;i++)	// convert patterns
-		for(j=0;j<64;j++) {
-			if(tracks[i][j].note == 15)
-				tracks[i][j].note = 127;
-			if(tracks[i][j].note > 16 && tracks[i][j].note < 127)
-				tracks[i][j].note -= 4 * (tracks[i][j].note >> 4);
-			if(tracks[i][j].note && tracks[i][j].note < 126)
-				tracks[i][j].note++;
-			tracks[i][j].command = convfx[tracks[i][j].command];
-		}
-	restartpos = 0; activechan = 0xffff; initspeed = radflags & 31;
-	bpm = radflags & 64 ? 0 : 50; flags = Decimal;
-
-	rewind(0);
-	return true;
-}
-
-float CradLoader::getrefresh()
-{
-	if(tempo)
-		return (float) (tempo);
-	else
-		return 18.2f;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/rad.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,124 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * rad.cpp - RAD Loader by Simon Peter <dn.tlp@gmx.net>
+ *
+ * BUGS:
+ * some volumes are dropped out
+ */
+
+#include "rad.h"
+
+CPlayer *CradLoader::factory(Copl *newopl)
+{
+  return new CradLoader(newopl);
+}
+
+bool CradLoader::load(const std::string &filename, const CFileProvider &fp)
+{
+        binistream *f = fp.open(filename); if(!f) return false;
+	char id[16];
+	unsigned char buf,ch,c,b,inp;
+	char bufstr[2] = "\0";
+	unsigned int i,j;
+	unsigned short patofs[32];
+	const unsigned char convfx[16] = {255,1,2,3,255,5,255,255,255,255,20,255,17,0xd,255,19};
+
+	// file validation section
+	f->readString(id, 16); version = f->readInt(1);
+	if(strncmp(id,"RAD by REALiTY!!",16) || version != 0x10)
+	  { fp.close(f); return false; }
+
+	// load section
+	radflags = f->readInt(1);
+	if(radflags & 128) {	// description
+		memset(desc,0,80*22);
+		while((buf = f->readInt(1)))
+			if(buf == 1)
+				strcat(desc,"\n");
+			else
+				if(buf >= 2 && buf <= 0x1f)
+					for(i=0;i<buf;i++)
+						strcat(desc," ");
+				else {
+					*bufstr = buf;
+					strcat(desc,bufstr);
+				}
+	}
+	while((buf = f->readInt(1))) {	// instruments
+		buf--;
+		inst[buf].data[2] = f->readInt(1); inst[buf].data[1] = f->readInt(1);
+		inst[buf].data[10] = f->readInt(1); inst[buf].data[9] = f->readInt(1);
+		inst[buf].data[4] = f->readInt(1); inst[buf].data[3] = f->readInt(1);
+		inst[buf].data[6] = f->readInt(1); inst[buf].data[5] = f->readInt(1);
+		inst[buf].data[0] = f->readInt(1);
+		inst[buf].data[8] = f->readInt(1); inst[buf].data[7] = f->readInt(1);
+	}
+	length = f->readInt(1);
+	for(i = 0; i < length; i++) order[i] = f->readInt(1);	// orderlist
+	for(i = 0; i < 32; i++) patofs[i] = f->readInt(2);	// pattern offset table
+	init_trackord();		// patterns
+	for(i=0;i<32;i++)
+		if(patofs[i]) {
+			f->seek(patofs[i]);
+			do {
+				buf = f->readInt(1); b = buf & 127;
+				do {
+					ch = f->readInt(1); c = ch & 127;
+					inp = f->readInt(1);
+					tracks[i*9+c][b].note = inp & 127;
+					tracks[i*9+c][b].inst = (inp & 128) >> 3;
+					inp = f->readInt(1);
+					tracks[i*9+c][b].inst += inp >> 4;
+					tracks[i*9+c][b].command = inp & 15;
+					if(inp & 15) {
+						inp = f->readInt(1);
+						tracks[i*9+c][b].param1 = inp / 10;
+						tracks[i*9+c][b].param2 = inp % 10;
+					}
+				} while(!(ch & 128));
+			} while(!(buf & 128));
+		} else
+			memset(trackord[i],0,9*2);
+	fp.close(f);
+
+	// convert replay data
+	for(i=0;i<32*9;i++)	// convert patterns
+		for(j=0;j<64;j++) {
+			if(tracks[i][j].note == 15)
+				tracks[i][j].note = 127;
+			if(tracks[i][j].note > 16 && tracks[i][j].note < 127)
+				tracks[i][j].note -= 4 * (tracks[i][j].note >> 4);
+			if(tracks[i][j].note && tracks[i][j].note < 126)
+				tracks[i][j].note++;
+			tracks[i][j].command = convfx[tracks[i][j].command];
+		}
+	restartpos = 0; activechan = 0xffff; initspeed = radflags & 31;
+	bpm = radflags & 64 ? 0 : 50; flags = Decimal;
+
+	rewind(0);
+	return true;
+}
+
+float CradLoader::getrefresh()
+{
+	if(tempo)
+		return (float) (tempo);
+	else
+		return 18.2f;
+}
--- a/Plugins/Input/adplug/core/rat.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,292 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * [xad] RAT player, by Riven the Mage <riven@ok.ru>
- */
-
-/*
-    - discovery -
-
-  file(s) : PINA.EXE
-     type : Experimental Connection BBStro tune
-     tune : by (?)Ratt/GRIF
-   player : by (?)Ratt/GRIF
-  comment : there are bug in original replayer's adlib_init(): wrong frequency registers.
-*/
-
-#include "rat.h"
-#include "debug.h"
-
-const unsigned char CxadratPlayer::rat_adlib_bases[18] =
-{
-  0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12,
-  0x03, 0x04, 0x05, 0x0B, 0x0C, 0x0D, 0x13, 0x14, 0x15
-};
-
-const unsigned short CxadratPlayer::rat_notes[16] =
-{
-  0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287,
-  0x000, 0x000, 0x000, 0x000 // by riven
-};
-
-CPlayer *CxadratPlayer::factory(Copl *newopl)
-{
-  return new CxadratPlayer(newopl);
-}
-
-bool CxadratPlayer::xadplayer_load()
-{
-  if(xad.fmt != RAT)
-    return false;
-
-  // load header
-  memcpy(&rat.hdr, &tune[0], sizeof(rat_header));
-
-  // is 'RAT'-signed ?
-  if (strncmp(rat.hdr.id,"RAT",3))
-    return false;
-
-  // is version 1.0 ?
-  if (rat.hdr.version != 0x10)
-    return false;
-
-  // load order
-  rat.order = &tune[0x40];
-
-  // load instruments
-  rat.inst = (rat_instrument *)&tune[0x140];
-
-  // load pattern data
-  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++)
-      for(int k=0;k<rat.hdr.numchan;k++)
-      {
-        memcpy(&rat.tracks[i][j][k], event_ptr, sizeof(rat_event));
-
-        event_ptr += sizeof(rat_event);
-      }
-
-  return true;
-}
-
-void CxadratPlayer::xadplayer_rewind(int subsong)
-{
-  int i;
-
-  rat.order_pos = rat.hdr.order_start;
-  rat.pattern_pos = 0;
-  rat.volume = rat.hdr.volume;
-
-  plr.speed = rat.hdr.speed;
-
-  // clear channel data
-  memset(&rat.channel, 0, sizeof(rat.channel[0])*9);
-
-  // init OPL
-  opl_write(0x01, 0x20);
-  opl_write(0x08, 0x00);
-  opl_write(0xBD, 0x00);
-
-  // set default frequencies
-  for(i=0;i<9;i++)
-  {
-    opl_write(0xA0+i, 0x00);
-    opl_write(0xA3+i, 0x00);
-    opl_write(0xB0+i, 0x00);
-    opl_write(0xB3+i, 0x00);
-  }
-
-  // set default volumes
-  for(i=0;i<0x1F;i++)
-    opl_write(0x40+i, 0x3F);
-}
-
-void CxadratPlayer::xadplayer_update()
-{
-  int i;
-
-  rat_event event;
-
-  // process events
-  for(i=0;i<rat.hdr.numchan;i++)
-  {
-    memcpy(&event,&rat.tracks[rat.order[rat.order_pos]][rat.pattern_pos][i],sizeof(rat_event));
-#ifdef DEBUG
-   AdPlug_LogWrite("order %02X, pattern %02X, row %02X, channel %02X, event %02X %02X %02X %02X %02X:\n",
-	         rat.order_pos, rat.order[rat.order_pos], rat.pattern_pos, i, event.note, event.instrument, event.volume, event.fx, event.fxp
-           );
-#endif
-
-    // is instrument ?
-    if (event.instrument != 0xFF)
-    {
-      rat.channel[i].instrument = event.instrument - 1;
-      rat.channel[i].volume = rat.inst[event.instrument - 1].volume;
-    }
-
-    // is volume ?
-    if (event.volume != 0xFF)
-      rat.channel[i].volume = event.volume;
-
-    // is note ?
-    if (event.note != 0xFF)
-    {
-      // mute channel
-      opl_write(0xB0+i, 0x00);
-      opl_write(0xA0+i, 0x00);
-
-      // if note != 0xFE then play
-      if (event.note != 0xFE)
-      {
-        unsigned char ins = rat.channel[i].instrument;
-
-        // synthesis/feedback
-        opl_write(0xC0+i, rat.inst[ins].connect);
-
-        // controls
-		opl_write(0x20+rat_adlib_bases[i], rat.inst[ins].mod_ctrl);
-        opl_write(0x20+rat_adlib_bases[i+9], rat.inst[ins].car_ctrl);
-
-        // volumes
-		opl_write(0x40+rat_adlib_bases[i], __rat_calc_volume(rat.inst[ins].mod_volume,rat.channel[i].volume,rat.volume));
-        opl_write(0x40+rat_adlib_bases[i+9], __rat_calc_volume(rat.inst[ins].car_volume,rat.channel[i].volume,rat.volume));
-
-        // attack/decay
-		opl_write(0x60+rat_adlib_bases[i], rat.inst[ins].mod_AD);
-        opl_write(0x60+rat_adlib_bases[i+9], rat.inst[ins].car_AD);
-
-        // sustain/release
-		opl_write(0x80+rat_adlib_bases[i], rat.inst[ins].mod_SR);
-        opl_write(0x80+rat_adlib_bases[i+9], rat.inst[ins].car_SR);
-
-        // waveforms
-		opl_write(0xE0+rat_adlib_bases[i], rat.inst[ins].mod_wave);
-        opl_write(0xE0+rat_adlib_bases[i+9], rat.inst[ins].car_wave);
-
-        // octave/frequency
-	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);
-      }
-    }
-
-    // is effect ?
-    if (event.fx != 0xFF)
-    {
-      rat.channel[i].fx = event.fx;
-      rat.channel[i].fxp = event.fxp;
-    }
-  }
-
-  // next row
-  rat.pattern_pos++;
-
-  // process effects
-  for(i=0;i<rat.hdr.numchan;i++)
-  {
-    unsigned char old_order_pos = rat.order_pos;
-
-    switch (rat.channel[i].fx)
-    {
-      case 0x01: // 0x01: Set Speed
-        plr.speed = rat.channel[i].fxp;
-        break;
-      case 0x02: // 0x02: Position Jump
-        if (rat.channel[i].fxp < rat.hdr.order_end)
-          rat.order_pos = rat.channel[i].fxp;
-        else
-          rat.order_pos = 0;
-
-        // jumpback ?
-        if (rat.order_pos <= old_order_pos)
-          plr.looping = 1;
-
-        rat.pattern_pos = 0;
-        break;
-      case 0x03: // 0x03: Pattern Break (?)
-        rat.pattern_pos = 0x40;
-        break;
-    }
-
-    rat.channel[i].fx = 0;
-  }
-
-  // end of pattern ?
-  if (rat.pattern_pos >= 0x40)
-  {
-    rat.pattern_pos = 0;
-
-    rat.order_pos++;
-
-    // end of module ?
-    if (rat.order_pos == rat.hdr.order_end)
-    {
-      rat.order_pos = rat.hdr.order_loop;
-
-      plr.looping = 1;
-    }
-  }
-}
-
-float CxadratPlayer::xadplayer_getrefresh()
-{
-  return 60.0f;
-}
-
-std::string CxadratPlayer::xadplayer_gettype()
-{
-  return (std::string("xad: rat player"));
-}
-
-std::string CxadratPlayer::xadplayer_gettitle()
-{
-  return (std::string(rat.hdr.title,32));
-}
-
-unsigned int CxadratPlayer::xadplayer_getinstruments()
-{
-  return rat.hdr.numinst;
-}
-
-/* -------- Internal Functions ---------------------------- */
-
-unsigned char CxadratPlayer::__rat_calc_volume(unsigned char ivol, unsigned char cvol, unsigned char gvol)
-{
-#ifdef DEBUG
-   AdPlug_LogWrite("volumes: instrument %02X, channel %02X, global %02X:\n", ivol, cvol, gvol);
-#endif
-  unsigned short vol;
-
-  vol   =  ivol;
-  vol  &=  0x3F;
-  vol  ^=  0x3F;
-  vol  *=  cvol;
-  vol >>=  6;
-  vol  *=  gvol;
-  vol >>=  6;
-  vol  ^=  0x3F;
-
-  vol  |=  ivol & 0xC0;
-
-  return vol;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/rat.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,292 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * [xad] RAT player, by Riven the Mage <riven@ok.ru>
+ */
+
+/*
+    - discovery -
+
+  file(s) : PINA.EXE
+     type : Experimental Connection BBStro tune
+     tune : by (?)Ratt/GRIF
+   player : by (?)Ratt/GRIF
+  comment : there are bug in original replayer's adlib_init(): wrong frequency registers.
+*/
+
+#include "rat.h"
+#include "debug.h"
+
+const unsigned char CxadratPlayer::rat_adlib_bases[18] =
+{
+  0x00, 0x01, 0x02, 0x08, 0x09, 0x0A, 0x10, 0x11, 0x12,
+  0x03, 0x04, 0x05, 0x0B, 0x0C, 0x0D, 0x13, 0x14, 0x15
+};
+
+const unsigned short CxadratPlayer::rat_notes[16] =
+{
+  0x157, 0x16B, 0x181, 0x198, 0x1B0, 0x1CA, 0x1E5, 0x202, 0x220, 0x241, 0x263, 0x287,
+  0x000, 0x000, 0x000, 0x000 // by riven
+};
+
+CPlayer *CxadratPlayer::factory(Copl *newopl)
+{
+  return new CxadratPlayer(newopl);
+}
+
+bool CxadratPlayer::xadplayer_load()
+{
+  if(xad.fmt != RAT)
+    return false;
+
+  // load header
+  memcpy(&rat.hdr, &tune[0], sizeof(rat_header));
+
+  // is 'RAT'-signed ?
+  if (strncmp(rat.hdr.id,"RAT",3))
+    return false;
+
+  // is version 1.0 ?
+  if (rat.hdr.version != 0x10)
+    return false;
+
+  // load order
+  rat.order = &tune[0x40];
+
+  // load instruments
+  rat.inst = (rat_instrument *)&tune[0x140];
+
+  // load pattern data
+  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++)
+      for(int k=0;k<rat.hdr.numchan;k++)
+      {
+        memcpy(&rat.tracks[i][j][k], event_ptr, sizeof(rat_event));
+
+        event_ptr += sizeof(rat_event);
+      }
+
+  return true;
+}
+
+void CxadratPlayer::xadplayer_rewind(int subsong)
+{
+  int i;
+
+  rat.order_pos = rat.hdr.order_start;
+  rat.pattern_pos = 0;
+  rat.volume = rat.hdr.volume;
+
+  plr.speed = rat.hdr.speed;
+
+  // clear channel data
+  memset(&rat.channel, 0, sizeof(rat.channel[0])*9);
+
+  // init OPL
+  opl_write(0x01, 0x20);
+  opl_write(0x08, 0x00);
+  opl_write(0xBD, 0x00);
+
+  // set default frequencies
+  for(i=0;i<9;i++)
+  {
+    opl_write(0xA0+i, 0x00);
+    opl_write(0xA3+i, 0x00);
+    opl_write(0xB0+i, 0x00);
+    opl_write(0xB3+i, 0x00);
+  }
+
+  // set default volumes
+  for(i=0;i<0x1F;i++)
+    opl_write(0x40+i, 0x3F);
+}
+
+void CxadratPlayer::xadplayer_update()
+{
+  int i;
+
+  rat_event event;
+
+  // process events
+  for(i=0;i<rat.hdr.numchan;i++)
+  {
+    memcpy(&event,&rat.tracks[rat.order[rat.order_pos]][rat.pattern_pos][i],sizeof(rat_event));
+#ifdef DEBUG
+   AdPlug_LogWrite("order %02X, pattern %02X, row %02X, channel %02X, event %02X %02X %02X %02X %02X:\n",
+	         rat.order_pos, rat.order[rat.order_pos], rat.pattern_pos, i, event.note, event.instrument, event.volume, event.fx, event.fxp
+           );
+#endif
+
+    // is instrument ?
+    if (event.instrument != 0xFF)
+    {
+      rat.channel[i].instrument = event.instrument - 1;
+      rat.channel[i].volume = rat.inst[event.instrument - 1].volume;
+    }
+
+    // is volume ?
+    if (event.volume != 0xFF)
+      rat.channel[i].volume = event.volume;
+
+    // is note ?
+    if (event.note != 0xFF)
+    {
+      // mute channel
+      opl_write(0xB0+i, 0x00);
+      opl_write(0xA0+i, 0x00);
+
+      // if note != 0xFE then play
+      if (event.note != 0xFE)
+      {
+        unsigned char ins = rat.channel[i].instrument;
+
+        // synthesis/feedback
+        opl_write(0xC0+i, rat.inst[ins].connect);
+
+        // controls
+		opl_write(0x20+rat_adlib_bases[i], rat.inst[ins].mod_ctrl);
+        opl_write(0x20+rat_adlib_bases[i+9], rat.inst[ins].car_ctrl);
+
+        // volumes
+		opl_write(0x40+rat_adlib_bases[i], __rat_calc_volume(rat.inst[ins].mod_volume,rat.channel[i].volume,rat.volume));
+        opl_write(0x40+rat_adlib_bases[i+9], __rat_calc_volume(rat.inst[ins].car_volume,rat.channel[i].volume,rat.volume));
+
+        // attack/decay
+		opl_write(0x60+rat_adlib_bases[i], rat.inst[ins].mod_AD);
+        opl_write(0x60+rat_adlib_bases[i+9], rat.inst[ins].car_AD);
+
+        // sustain/release
+		opl_write(0x80+rat_adlib_bases[i], rat.inst[ins].mod_SR);
+        opl_write(0x80+rat_adlib_bases[i+9], rat.inst[ins].car_SR);
+
+        // waveforms
+		opl_write(0xE0+rat_adlib_bases[i], rat.inst[ins].mod_wave);
+        opl_write(0xE0+rat_adlib_bases[i+9], rat.inst[ins].car_wave);
+
+        // octave/frequency
+	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);
+      }
+    }
+
+    // is effect ?
+    if (event.fx != 0xFF)
+    {
+      rat.channel[i].fx = event.fx;
+      rat.channel[i].fxp = event.fxp;
+    }
+  }
+
+  // next row
+  rat.pattern_pos++;
+
+  // process effects
+  for(i=0;i<rat.hdr.numchan;i++)
+  {
+    unsigned char old_order_pos = rat.order_pos;
+
+    switch (rat.channel[i].fx)
+    {
+      case 0x01: // 0x01: Set Speed
+        plr.speed = rat.channel[i].fxp;
+        break;
+      case 0x02: // 0x02: Position Jump
+        if (rat.channel[i].fxp < rat.hdr.order_end)
+          rat.order_pos = rat.channel[i].fxp;
+        else
+          rat.order_pos = 0;
+
+        // jumpback ?
+        if (rat.order_pos <= old_order_pos)
+          plr.looping = 1;
+
+        rat.pattern_pos = 0;
+        break;
+      case 0x03: // 0x03: Pattern Break (?)
+        rat.pattern_pos = 0x40;
+        break;
+    }
+
+    rat.channel[i].fx = 0;
+  }
+
+  // end of pattern ?
+  if (rat.pattern_pos >= 0x40)
+  {
+    rat.pattern_pos = 0;
+
+    rat.order_pos++;
+
+    // end of module ?
+    if (rat.order_pos == rat.hdr.order_end)
+    {
+      rat.order_pos = rat.hdr.order_loop;
+
+      plr.looping = 1;
+    }
+  }
+}
+
+float CxadratPlayer::xadplayer_getrefresh()
+{
+  return 60.0f;
+}
+
+std::string CxadratPlayer::xadplayer_gettype()
+{
+  return (std::string("xad: rat player"));
+}
+
+std::string CxadratPlayer::xadplayer_gettitle()
+{
+  return (std::string(rat.hdr.title,32));
+}
+
+unsigned int CxadratPlayer::xadplayer_getinstruments()
+{
+  return rat.hdr.numinst;
+}
+
+/* -------- Internal Functions ---------------------------- */
+
+unsigned char CxadratPlayer::__rat_calc_volume(unsigned char ivol, unsigned char cvol, unsigned char gvol)
+{
+#ifdef DEBUG
+   AdPlug_LogWrite("volumes: instrument %02X, channel %02X, global %02X:\n", ivol, cvol, gvol);
+#endif
+  unsigned short vol;
+
+  vol   =  ivol;
+  vol  &=  0x3F;
+  vol  ^=  0x3F;
+  vol  *=  cvol;
+  vol >>=  6;
+  vol  *=  gvol;
+  vol >>=  6;
+  vol  ^=  0x3F;
+
+  vol  |=  ivol & 0xC0;
+
+  return vol;
+}
--- a/Plugins/Input/adplug/core/raw.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-/*
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * raw.c - RAW Player by Simon Peter <dn.tlp@gmx.net>
- */
-
-#include "raw.h"
-
-/*** public methods *************************************/
-
-CPlayer *CrawPlayer::factory(Copl *newopl)
-{
-  return new CrawPlayer(newopl);
-}
-
-bool CrawPlayer::load(const std::string &filename, const CFileProvider &fp)
-{
-  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,"RAWADATA",8)) { fp.close (f); return false; }
-
-  // load section
-  clock = f->readInt(2);	// clock speed
-  length = (fp.filesize(f) - 10) / 2;
-  data = new Tdata [length];
-  for(i = 0; i < length; i++) {
-    data[i].param = f->readInt(1);
-    data[i].command = f->readInt(1);
-  }
-
-  fp.close(f);
-  rewind(0);
-  return true;
-}
-
-bool CrawPlayer::update()
-{
-  bool	setspeed;
-
-  if(pos >= length) return false;
-
-  if(del) {
-    del--;
-    return !songend;
-  }
-
-  do {
-    setspeed = false;
-    switch(data[pos].command) {
-    case 0: del = data[pos].param - 1; break;
-    case 2:
-      if(!data[pos].param) {
-	pos++;
-	speed = data[pos].param + (data[pos].command << 8);
-	setspeed = true;
-      } else
-	opl->setchip(data[pos].param - 1);
-      break;
-    case 0xff:
-      if(data[pos].param == 0xff) {
-	rewind(0);		// auto-rewind song
-	songend = true;
-	return !songend;
-      }
-      break;
-    default:
-      opl->write(data[pos].command,data[pos].param);
-      break;
-    }
-  } while(data[pos++].command || setspeed);
-
-  return !songend;
-}
-
-void CrawPlayer::rewind(int subsong)
-{
-  pos = del = 0; speed = clock; songend = false;
-  opl->init(); opl->write(1, 32);	// go to 9 channel mode
-}
-
-float CrawPlayer::getrefresh()
-{
-  return 1193180.0 / (speed ? speed : 0xffff);	// timer oscillator speed / wait register = clock frequency
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/raw.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,103 @@
+/*
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * raw.c - RAW Player by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include "raw.h"
+
+/*** public methods *************************************/
+
+CPlayer *CrawPlayer::factory(Copl *newopl)
+{
+  return new CrawPlayer(newopl);
+}
+
+bool CrawPlayer::load(const std::string &filename, const CFileProvider &fp)
+{
+  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,"RAWADATA",8)) { fp.close (f); return false; }
+
+  // load section
+  clock = f->readInt(2);	// clock speed
+  length = (fp.filesize(f) - 10) / 2;
+  data = new Tdata [length];
+  for(i = 0; i < length; i++) {
+    data[i].param = f->readInt(1);
+    data[i].command = f->readInt(1);
+  }
+
+  fp.close(f);
+  rewind(0);
+  return true;
+}
+
+bool CrawPlayer::update()
+{
+  bool	setspeed;
+
+  if(pos >= length) return false;
+
+  if(del) {
+    del--;
+    return !songend;
+  }
+
+  do {
+    setspeed = false;
+    switch(data[pos].command) {
+    case 0: del = data[pos].param - 1; break;
+    case 2:
+      if(!data[pos].param) {
+	pos++;
+	speed = data[pos].param + (data[pos].command << 8);
+	setspeed = true;
+      } else
+	opl->setchip(data[pos].param - 1);
+      break;
+    case 0xff:
+      if(data[pos].param == 0xff) {
+	rewind(0);		// auto-rewind song
+	songend = true;
+	return !songend;
+      }
+      break;
+    default:
+      opl->write(data[pos].command,data[pos].param);
+      break;
+    }
+  } while(data[pos++].command || setspeed);
+
+  return !songend;
+}
+
+void CrawPlayer::rewind(int subsong)
+{
+  pos = del = 0; speed = clock; songend = false;
+  opl->init(); opl->write(1, 32);	// go to 9 channel mode
+}
+
+float CrawPlayer::getrefresh()
+{
+  return 1193180.0 / (speed ? speed : 0xffff);	// timer oscillator speed / wait register = clock frequency
+}
--- a/Plugins/Input/adplug/core/rix.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,492 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * rix.cpp - Softstar RIX OPL Format Player by palxex <palxex.ys168.com>
- *                                             BSPAL <BSPAL.ys168.com>
- */
-
-#include "rix.h"
-#include "debug.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);
-}
-
-CrixPlayer::CrixPlayer(Copl *newopl)
-  : CPlayer(newopl), flag_mkf(0), file_buffer(0), buf_addr(0)
-{
-}
-
-CrixPlayer::~CrixPlayer()
-{
-  if(file_buffer)
-    delete [] file_buffer;
-}
-
-bool CrixPlayer::load(const std::string &filename, const CFileProvider &fp)
-{
-  binistream *f = fp.open(filename); if(!f) return false;
-  unsigned long i=0;
-
-  if(stricmp(filename.substr(filename.length()-4,4).c_str(),".mkf")==0)
-  {
-	  flag_mkf=1;
-	  f->seek(0);
-	  int offset=f->readInt(4);
-	  f->seek(offset);
-  }
-  if(f->readInt(2)!=0x55aa){ fp.close(f);return false; }
-  file_buffer = new unsigned char [fp.filesize(f) + 1];
-  f->seek(0);
-  while(!f->eof())
-	file_buffer[i++]=f->readInt(1);
-  length=i;
-  fp.close(f);
-  if(!flag_mkf)
-	  buf_addr=file_buffer;
-  rewind(0);
-  return true;
-}
-
-bool CrixPlayer::update()
-{
-	int_08h_entry();
-	return !play_end;
-}
-
-void CrixPlayer::rewind(int subsong)
-{
-  I = 0; T = 0;
-  mus_block = 0;
-  ins_block = 0;
-  rhythm = 0;
-  music_on = 0;
-  pause_flag = 0;
-  band = 0;
-  band_low = 0;
-  e0_reg_flag = 0;
-  bd_modify = 0;
-  sustain = 0;
-  play_end = 0;
-  pos = index = 0; 
-
-  memset(f_buffer, 0, sizeof(unsigned short) * 300);
-  memset(a0b0_data2, 0, sizeof(unsigned short) * 11);
-  memset(a0b0_data3, 0, 18);
-  memset(a0b0_data4, 0, 18);
-  memset(a0b0_data5, 0, 96);
-  memset(addrs_head, 0, 96);
-  memset(insbuf, 0, 28 * sizeof(unsigned short));
-  memset(displace, 0, 11 * sizeof(unsigned short));
-  memset(reg_bufs, 0, 18 * sizeof(ADDT));
-
-  if(flag_mkf)
-  {
-	  unsigned int *buf_index=(unsigned int *)file_buffer;
-	  int offset1=buf_index[subsong],offset2;
-	  while((offset2=buf_index[++subsong])==offset1);
-	  length=offset2-offset1+1;
-	  buf_addr=file_buffer+offset1;
-  }
-  opl->init(); 
-  opl->write(1,32);	// go to OPL2 mode
-  set_new_int();
-  data_initial();
-}
-unsigned int CrixPlayer::getsubsongs()
-{
-	if(flag_mkf)
-	{
-		unsigned int *buf_index=(unsigned int *)file_buffer;
-		int songs=buf_index[0]/4,i=0;
-		for(i=0;i<songs;i++)
-			if(buf_index[i+1]==buf_index[i])
-				songs--;
-		return songs;
-	}
-	else
-		return 1;
-}
-
-float CrixPlayer::getrefresh()
-{
-	return 70.0f;
-}
-
-/*------------------Implemention----------------------------*/
-inline void CrixPlayer::set_new_int()
-{
-  if(!ad_initial()) exit(1);
-}
-/*----------------------------------------------------------*/
-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++) 
-  {
-  	f_buffer[i*12]=(unsigned int)((i*24+10000)*0.27461678223+4)>>3;
-  	for(int t=1;t<12;t++)
-  		f_buffer[i*12+t]=(unsigned int)((double)f_buffer[i*12+t-1]*1.06);
-  }
-  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::ad_bop(unsigned short reg,unsigned short value)
-{
-  if(reg == 2 || reg == 3)
-    AdPlug_LogWrite("switch OPL2/3 mode!\n");
-  opl->write(reg & 0xff, value & 0xff);
-}
-/*--------------------------------------------------------------*/
-inline void CrixPlayer::int_08h_entry()
-  {   
-  unsigned short band_sus = 1;
-  while(band_sus)
-    {
-        if(sustain <= 0)   
-	{
-	  band_sus = rix_proc();
-	  if(band_sus) sustain += band_sus;
-            else
-	    {
-                play_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()
-{
-  int		i;
-  unsigned char	*baddr = (&buf_addr[ins_block])+(band_low<<6);
-
-  for(i = 0; i < 28; i++)
-    insbuf[i] = (baddr[i * 2 + 1] << 8) + baddr[i * 2];
-}
-/*--------------------------------------------------------------*/
-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;
-  int res1 = (v-0x2000)*0x19;
-  if(res1 == (int)0xff) return;
-  low = res1/0x2000;
-  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 = f_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;
-  for(i=0;i<11;i++)
-    switch_ad_bd(i);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/rix.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,492 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * rix.cpp - Softstar RIX OPL Format Player by palxex <palxex.ys168.com>
+ *                                             BSPAL <BSPAL.ys168.com>
+ */
+
+#include "rix.h"
+#include "debug.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);
+}
+
+CrixPlayer::CrixPlayer(Copl *newopl)
+  : CPlayer(newopl), flag_mkf(0), file_buffer(0), buf_addr(0)
+{
+}
+
+CrixPlayer::~CrixPlayer()
+{
+  if(file_buffer)
+    delete [] file_buffer;
+}
+
+bool CrixPlayer::load(const std::string &filename, const CFileProvider &fp)
+{
+  binistream *f = fp.open(filename); if(!f) return false;
+  unsigned long i=0;
+
+  if(stricmp(filename.substr(filename.length()-4,4).c_str(),".mkf")==0)
+  {
+	  flag_mkf=1;
+	  f->seek(0);
+	  int offset=f->readInt(4);
+	  f->seek(offset);
+  }
+  if(f->readInt(2)!=0x55aa){ fp.close(f);return false; }
+  file_buffer = new unsigned char [fp.filesize(f) + 1];
+  f->seek(0);
+  while(!f->eof())
+	file_buffer[i++]=f->readInt(1);
+  length=i;
+  fp.close(f);
+  if(!flag_mkf)
+	  buf_addr=file_buffer;
+  rewind(0);
+  return true;
+}
+
+bool CrixPlayer::update()
+{
+	int_08h_entry();
+	return !play_end;
+}
+
+void CrixPlayer::rewind(int subsong)
+{
+  I = 0; T = 0;
+  mus_block = 0;
+  ins_block = 0;
+  rhythm = 0;
+  music_on = 0;
+  pause_flag = 0;
+  band = 0;
+  band_low = 0;
+  e0_reg_flag = 0;
+  bd_modify = 0;
+  sustain = 0;
+  play_end = 0;
+  pos = index = 0; 
+
+  memset(f_buffer, 0, sizeof(unsigned short) * 300);
+  memset(a0b0_data2, 0, sizeof(unsigned short) * 11);
+  memset(a0b0_data3, 0, 18);
+  memset(a0b0_data4, 0, 18);
+  memset(a0b0_data5, 0, 96);
+  memset(addrs_head, 0, 96);
+  memset(insbuf, 0, 28 * sizeof(unsigned short));
+  memset(displace, 0, 11 * sizeof(unsigned short));
+  memset(reg_bufs, 0, 18 * sizeof(ADDT));
+
+  if(flag_mkf)
+  {
+	  unsigned int *buf_index=(unsigned int *)file_buffer;
+	  int offset1=buf_index[subsong],offset2;
+	  while((offset2=buf_index[++subsong])==offset1);
+	  length=offset2-offset1+1;
+	  buf_addr=file_buffer+offset1;
+  }
+  opl->init(); 
+  opl->write(1,32);	// go to OPL2 mode
+  set_new_int();
+  data_initial();
+}
+unsigned int CrixPlayer::getsubsongs()
+{
+	if(flag_mkf)
+	{
+		unsigned int *buf_index=(unsigned int *)file_buffer;
+		int songs=buf_index[0]/4,i=0;
+		for(i=0;i<songs;i++)
+			if(buf_index[i+1]==buf_index[i])
+				songs--;
+		return songs;
+	}
+	else
+		return 1;
+}
+
+float CrixPlayer::getrefresh()
+{
+	return 70.0f;
+}
+
+/*------------------Implemention----------------------------*/
+inline void CrixPlayer::set_new_int()
+{
+  if(!ad_initial()) exit(1);
+}
+/*----------------------------------------------------------*/
+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++) 
+  {
+  	f_buffer[i*12]=(unsigned int)((i*24+10000)*0.27461678223+4)>>3;
+  	for(int t=1;t<12;t++)
+  		f_buffer[i*12+t]=(unsigned int)((double)f_buffer[i*12+t-1]*1.06);
+  }
+  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::ad_bop(unsigned short reg,unsigned short value)
+{
+  if(reg == 2 || reg == 3)
+    AdPlug_LogWrite("switch OPL2/3 mode!\n");
+  opl->write(reg & 0xff, value & 0xff);
+}
+/*--------------------------------------------------------------*/
+inline void CrixPlayer::int_08h_entry()
+  {   
+  unsigned short band_sus = 1;
+  while(band_sus)
+    {
+        if(sustain <= 0)   
+	{
+	  band_sus = rix_proc();
+	  if(band_sus) sustain += band_sus;
+            else
+	    {
+                play_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()
+{
+  int		i;
+  unsigned char	*baddr = (&buf_addr[ins_block])+(band_low<<6);
+
+  for(i = 0; i < 28; i++)
+    insbuf[i] = (baddr[i * 2 + 1] << 8) + baddr[i * 2];
+}
+/*--------------------------------------------------------------*/
+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;
+  int res1 = (v-0x2000)*0x19;
+  if(res1 == (int)0xff) return;
+  low = res1/0x2000;
+  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 = f_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;
+  for(i=0;i<11;i++)
+    switch_ad_bd(i);
+}
--- a/Plugins/Input/adplug/core/rol.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,723 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * rol.h - ROL Player by OPLx <oplx@yahoo.com>
- *
- * Visit:  http://tenacity.hispeed.com/aomit/oplx/
- */
-#include <algorithm>
-
-#include "rol.h"
-#include "debug.h"
-
-int   const CrolPlayer::kSizeofDataRecord    =  30;
-int   const CrolPlayer::kMaxTickBeat         =  60;
-int   const CrolPlayer::kSilenceNote         = -12;
-int   const CrolPlayer::kNumMelodicVoices    =  9;
-int   const CrolPlayer::kNumPercussiveVoices = 11;
-int   const CrolPlayer::kBassDrumChannel     =  6;
-int   const CrolPlayer::kSnareDrumChannel    =  7;
-int   const CrolPlayer::kTomtomChannel       =  8;
-int   const CrolPlayer::kTomtomFreq          =  2;//4;
-int   const CrolPlayer::kSnareDrumFreq       =  2;//kTomtomFreq + 7;
-float const CrolPlayer::kDefaultUpdateTme    = 18.2f;
-float const CrolPlayer::kPitchFactor         = 400.0f;
-
-static const unsigned char drum_table[4] = {0x14, 0x12, 0x15, 0x11};
-
-CrolPlayer::uint16 const CrolPlayer::kNoteTable[12] = 
-{ 
-    340, // C
-    363, // C#
-    385, // D
-    408, // D#
-    432, // E
-    458, // F
-    485, // F#
-    514, // G
-    544, // G#
-    577, // A
-    611, // A#
-    647  // B
-};
-
-/*** public methods **************************************/
-
-CPlayer *CrolPlayer::factory(Copl *newopl)
-{
-  return new CrolPlayer(newopl);
-}
-//---------------------------------------------------------
-CrolPlayer::CrolPlayer(Copl *newopl)
-:  CPlayer         ( newopl )
-  ,rol_header      ( NULL )
-  ,mNextTempoEvent ( 0 )
-  ,mCurrTick       ( 0 )
-  ,mTimeOfLastNote ( 0 )
-  ,mRefresh        ( kDefaultUpdateTme )
-  ,bdRegister      ( 0 )
-{
-    int n;
-
-    memset(bxRegister,  0, sizeof(bxRegister) );
-    memset(volumeCache, 0, sizeof(volumeCache) );
-    memset(freqCache,   0, sizeof(freqCache) );
-
-    for(n=0; n<11; n++)
-      pitchCache[n]=1.0f;    
-}
-//---------------------------------------------------------
-CrolPlayer::~CrolPlayer()
-{
-    if( rol_header != NULL )
-    {
-        delete rol_header;
-        rol_header=NULL;
-    }
-}
-//---------------------------------------------------------
-bool CrolPlayer::load(const std::string &filename, const CFileProvider &fp)
-{
-    binistream *f = fp.open(filename); if(!f) return false;
-
-    char *fn = new char[filename.length()+9];
-    int i;
-    std::string bnk_filename;
-
-    AdPlug_LogWrite("*** CrolPlayer::load(f, \"%s\") ***\n", filename.c_str());
-    strcpy(fn,filename.data());
-    for (i=strlen(fn)-1; i>=0; i--)
-      if (fn[i] == '/' || fn[i] == '\\')
-	break;
-    strcpy(fn+i+1,"standard.bnk");
-    bnk_filename = fn;
-    delete [] fn;
-    AdPlug_LogWrite("bnk_filename = \"%s\"\n",bnk_filename.c_str());
-
-    rol_header = new SRolHeader;
-    memset( rol_header, 0, sizeof(SRolHeader) );
-
-    rol_header->version_major = f->readInt( 2 );
-    rol_header->version_minor = f->readInt( 2 );
-
-    // Version check
-    if(rol_header->version_major != 0 || rol_header->version_minor != 4) {
-      AdPlug_LogWrite("Unsupported file version %d.%d or not a ROL file!\n",
-	       rol_header->version_major, rol_header->version_minor);
-      AdPlug_LogWrite("--- CrolPlayer::load ---\n");
-      fp.close(f);
-      return false;
-    }
-
-    f->seek( 40, binio::Add );
-
-    rol_header->ticks_per_beat    = f->readInt( 2 );
-    rol_header->beats_per_measure = f->readInt( 2 );
-    rol_header->edit_scale_y      = f->readInt( 2 );
-    rol_header->edit_scale_x      = f->readInt( 2 );
-
-    f->seek( 1, binio::Add );
-
-    rol_header->mode = f->readInt(1);
-
-    f->seek( 90+38+15, binio::Add );
-
-    rol_header->basic_tempo = f->readFloat( binio::Single );
-
-    load_tempo_events( f );
-
-    mTimeOfLastNote = 0;
-
-    if( load_voice_data( f, bnk_filename, fp ) != true )
-    {
-      AdPlug_LogWrite("CrolPlayer::load_voice_data(f) failed!\n");
-      AdPlug_LogWrite("--- CrolPlayer::load ---\n");
-
-      fp.close( f );
-      return false;
-    }
-
-    fp.close( f );
-
-    rewind( 0 );
-    AdPlug_LogWrite("--- CrolPlayer::load ---\n");
-    return true;
-}
-//---------------------------------------------------------
-bool CrolPlayer::update()
-{
-    if( mNextTempoEvent < mTempoEvents.size() &&
-        mTempoEvents[mNextTempoEvent].time == mCurrTick )
-    {
-        SetRefresh( mTempoEvents[mNextTempoEvent].multiplier );
-        ++mNextTempoEvent;
-    }
-
-    TVoiceData::iterator curr = voice_data.begin();
-    TVoiceData::iterator end  = voice_data.end();
-    int voice                 = 0;
-
-    while( curr != end )
-    {
-        UpdateVoice( voice, *curr );
-        ++curr;
-        ++voice;
-    }
-
-    ++mCurrTick;
-
-    if( mCurrTick > mTimeOfLastNote )
-    {
-        return false;
-    }
-
-    return true;
-    //return ( mCurrTick > mTimeOfLastNote ) ? false : true;
-}
-//---------------------------------------------------------
-void CrolPlayer::rewind( int subsong )
-{
-    TVoiceData::iterator curr = voice_data.begin();
-    TVoiceData::iterator end  = voice_data.end();
-
-    while( curr != end )
-    {
-        CVoiceData &voice = *curr;
-
-        voice.Reset();
-        ++curr;
-    }
-
-    memset(bxRegister,  0, sizeof(bxRegister) );
-    memset(volumeCache, 0, sizeof(volumeCache) );
-
-    bdRegister = 0;
-
-    opl->init();        // initialize to melodic by default
-    opl->write(1,0x20); // Enable waveform select (bit 5)
-
-    if( rol_header->mode == 0 )
-    {
-        opl->write( 0xbd, 0x20 ); // select rhythm mode (bit 5)
-        bdRegister = 0x20;
-
-        SetFreq( kTomtomChannel,    24 );
-        SetFreq( kSnareDrumChannel, 31 );
-    }
-
-    mNextTempoEvent = 0;
-    mCurrTick       = 0;
-
-    SetRefresh(1.0f);
-}
-//---------------------------------------------------------
-inline float fmin( int const a, int const b )
-{
-    return static_cast<float>( a < b ? a : b );
-}
-//---------------------------------------------------------
-void CrolPlayer::SetRefresh( float const multiplier )
-{
-    float const tickBeat = fmin(kMaxTickBeat, rol_header->ticks_per_beat);
-
-    mRefresh =  (tickBeat*rol_header->basic_tempo*multiplier) / 60.0f;
-}
-//---------------------------------------------------------
-float CrolPlayer::getrefresh()
-{
-    return mRefresh;
-}
-//---------------------------------------------------------
-void CrolPlayer::UpdateVoice( int const voice, CVoiceData &voiceData )
-{
-    TNoteEvents const &nEvents = voiceData.note_events;
-
-    if( nEvents.empty() || voiceData.mEventStatus & CVoiceData::kES_NoteEnd )
-    {
-        return; // no note data to process, don't bother doing anything.
-    }
-
-    TInstrumentEvents  &iEvents = voiceData.instrument_events;
-    TVolumeEvents      &vEvents = voiceData.volume_events;
-    TPitchEvents       &pEvents = voiceData.pitch_events;
-
-    if( !(voiceData.mEventStatus & CVoiceData::kES_InstrEnd ) &&
-        iEvents[voiceData.next_instrument_event].time == mCurrTick )
-    {
-        if( voiceData.next_instrument_event < iEvents.size() )
-        {
-            send_ins_data_to_chip( voice, iEvents[voiceData.next_instrument_event].ins_index );
-            ++voiceData.next_instrument_event;
-        }
-        else
-        {
-            voiceData.mEventStatus |= CVoiceData::kES_InstrEnd;
-        }
-    }
-
-    if( !(voiceData.mEventStatus & CVoiceData::kES_VolumeEnd ) &&
-        vEvents[voiceData.next_volume_event].time == mCurrTick )
-    {
-      SVolumeEvent const &volumeEvent = vEvents[voiceData.next_volume_event];
-
-        if(  voiceData.next_volume_event < vEvents.size() )
-        {
-            int const volume = (int)(63.0f*(1.0f - volumeEvent.multiplier));
-
-            SetVolume( voice, volume );
-
-            ++voiceData.next_volume_event; // move to next volume event
-        }
-        else
-        {
-            voiceData.mEventStatus |= CVoiceData::kES_VolumeEnd;
-        }        
-    }
-
-    if( voiceData.mForceNote || voiceData.current_note_duration > voiceData.mNoteDuration-1 )
-    {
-        if( mCurrTick != 0 )
-        {
-            ++voiceData.current_note;
-        }
-
-        if( voiceData.current_note < nEvents.size() )
-        {
-            SNoteEvent const &noteEvent = nEvents[voiceData.current_note];
-
-            SetNote( voice, noteEvent.number );
-            voiceData.current_note_duration = 0;
-            voiceData.mNoteDuration         = noteEvent.duration;
-            voiceData.mForceNote            = false;
-        }
-        else
-        {
-            SetNote( voice, kSilenceNote );
-            voiceData.mEventStatus |= CVoiceData::kES_NoteEnd;
-            return;
-        }
-    }
-
-    if( !(voiceData.mEventStatus & CVoiceData::kES_PitchEnd ) &&
-        pEvents[voiceData.next_pitch_event].time == mCurrTick )
-    {
-        if( voiceData.next_pitch_event < pEvents.size() )
-        {
-            SetPitch(voice,pEvents[voiceData.next_pitch_event].variation);
-            ++voiceData.next_pitch_event;
-        }
-        else
-        {
-            voiceData.mEventStatus |= CVoiceData::kES_PitchEnd;
-        }
-    }
-
-    ++voiceData.current_note_duration;
-}
-//---------------------------------------------------------
-void CrolPlayer::SetNote( int const voice, int const note )
-{
-    if( voice < kBassDrumChannel || rol_header->mode )
-    {
-        SetNoteMelodic( voice, note );
-    }
-    else
-    {
-        SetNotePercussive( voice, note );
-    }
-}
-//---------------------------------------------------------
-void CrolPlayer::SetNotePercussive( int const voice, int const note )
-{
-    int const bit_pos = 4-voice+kBassDrumChannel;
-
-    bdRegister &= ~( 1<<bit_pos );
-    opl->write( 0xbd, bdRegister );
-
-    if( note != kSilenceNote )
-    {
-        switch( voice )
-        {
-            case kTomtomChannel:
-                SetFreq( kSnareDrumChannel, note+7 );
-            case kBassDrumChannel:
-                SetFreq( voice, note );
-                break;
-        }
-
-        bdRegister |= 1<<bit_pos;
-        opl->write( 0xbd, bdRegister );
-    }
-}
-//---------------------------------------------------------
-void CrolPlayer::SetNoteMelodic( int const voice, int const note )
-{
-    opl->write( 0xb0+voice, bxRegister[voice] & ~0x20 );
-
-    if( note != kSilenceNote )
-    {
-        SetFreq( voice, note, true );
-    }
-}
-//---------------------------------------------------------
-void CrolPlayer::SetPitch(int const voice, real32 const variation)
-{
-  pitchCache[voice] = variation;
-  freqCache[voice] += (uint16)((((float)freqCache[voice])*(variation-1.0f)) / kPitchFactor);
-
-  opl->write(0xa0+voice,freqCache[voice] & 0xff);
-}
-//---------------------------------------------------------
-void CrolPlayer::SetFreq( int const voice, int const note, bool const keyOn )
-{
-    uint16 freq = kNoteTable[note%12] + ((note/12) << 10);
-    freq += (uint16)((((float)freq)*(pitchCache[voice]-1.0f))/kPitchFactor);
-
-    freqCache[voice] = freq;
-    bxRegister[voice] = ((freq >> 8) & 0x1f);
-
-    opl->write( 0xa0+voice, freq & 0xff );
-    opl->write( 0xb0+voice, bxRegister[voice] | (keyOn ? 0x20 : 0x0) );
-}
-//---------------------------------------------------------
-void CrolPlayer::SetVolume( int const voice, int const volume )
-{
-    volumeCache[voice] = (volumeCache[voice] &0xc0) | volume;
-
-    int const op_offset = ( voice < kSnareDrumChannel || rol_header->mode ) ? 
-                          op_table[voice]+3 : drum_table[voice-kSnareDrumChannel];
-
-    opl->write( 0x40+op_offset, volumeCache[voice] );
-}
-//---------------------------------------------------------
-void CrolPlayer::send_ins_data_to_chip( int const voice, int const ins_index )
-{
-    SRolInstrument &instrument = ins_list[ins_index].instrument;
-
-    send_operator( voice, instrument.modulator, instrument.carrier );
-}
-//---------------------------------------------------------
-void CrolPlayer::send_operator( int const voice, SOPL2Op const &modulator,  SOPL2Op const &carrier )
-{
-    if( voice < kSnareDrumChannel || rol_header->mode )
-    {
-        int const op_offset = op_table[voice];
-
-        opl->write( 0x20+op_offset, modulator.ammulti  );
-        opl->write( 0x40+op_offset, modulator.ksltl    );
-        opl->write( 0x60+op_offset, modulator.ardr     );
-        opl->write( 0x80+op_offset, modulator.slrr     );
-        opl->write( 0xc0+voice    , modulator.fbc      );
-        opl->write( 0xe0+op_offset, modulator.waveform );
-
-        volumeCache[voice] = (carrier.ksltl & 0xc0) | volumeCache[voice] & 0x3f;
-
-        opl->write( 0x23+op_offset, carrier.ammulti  );
-        opl->write( 0x43+op_offset, volumeCache[voice]    );
-        opl->write( 0x63+op_offset, carrier.ardr     );
-        opl->write( 0x83+op_offset, carrier.slrr     );
-//        opl->write( 0xc3+voice    , carrier.fbc      ); <- don't bother writing this.
-        opl->write( 0xe3+op_offset, carrier.waveform );
-    }
-    else
-    {
-        int const op_offset = drum_table[voice-kSnareDrumChannel];
-
-        volumeCache[voice] = (modulator.ksltl & 0xc0) | volumeCache[voice] & 0x3f;
-
-        opl->write( 0x20+op_offset, modulator.ammulti  );
-        opl->write( 0x40+op_offset, volumeCache[voice]      );
-        opl->write( 0x60+op_offset, modulator.ardr     );
-        opl->write( 0x80+op_offset, modulator.slrr     );
-        opl->write( 0xc0+voice    , modulator.fbc      );
-        opl->write( 0xe0+op_offset, modulator.waveform );
-    }
-}
-//---------------------------------------------------------
-void CrolPlayer::load_tempo_events( binistream *f )
-{
-    int16 const num_tempo_events = f->readInt( 2 );
-
-    mTempoEvents.reserve( num_tempo_events );
-
-    for(int i=0; i<num_tempo_events; ++i)
-    {
-        STempoEvent event;
-
-        event.time       = f->readInt( 2 );
-        event.multiplier = f->readFloat( binio::Single );
-        mTempoEvents.push_back( event );
-    }
-}
-//---------------------------------------------------------
-bool CrolPlayer::load_voice_data( binistream *f, std::string const &bnk_filename, const CFileProvider &fp )
-{
-    SBnkHeader bnk_header;
-    binistream *bnk_file = fp.open( bnk_filename.c_str() );
-
-    if( bnk_file )
-    {
-        load_bnk_info( bnk_file, bnk_header );
-
-        int const numVoices = rol_header->mode ? kNumMelodicVoices : kNumPercussiveVoices;
-
-        voice_data.reserve( numVoices );
-        for(int i=0; i<numVoices; ++i)
-        {
-            CVoiceData voice;
-
-            load_note_events( f, voice );
-            load_instrument_events( f, voice, bnk_file, bnk_header );
-            load_volume_events( f, voice );
-            load_pitch_events( f, voice );
-
-            voice_data.push_back( voice );
-        }
-
-        fp.close(bnk_file);
-
-        return true;
-    }
-
-    return false;
-}
-//---------------------------------------------------------
-void CrolPlayer::load_note_events( binistream *f, CVoiceData &voice )
-{
-    f->seek( 15, binio::Add );
-
-    int16 const time_of_last_note = f->readInt( 2 );
-
-    if( time_of_last_note != 0 )
-    {
-        TNoteEvents &note_events = voice.note_events;
-        int16 total_duration     = 0;
-
-        do
-        {
-            SNoteEvent event;
-
-            event.number   = f->readInt( 2 );
-            event.duration = f->readInt( 2 );
-
-            event.number += kSilenceNote; // adding -12
-
-            note_events.push_back( event );
-
-            total_duration += event.duration;
-        } while( total_duration < time_of_last_note );
-
-        if( time_of_last_note > mTimeOfLastNote )
-        {
-            mTimeOfLastNote = time_of_last_note;
-        }
-    }
-
-    f->seek( 15, binio::Add );
-}
-//---------------------------------------------------------
-void CrolPlayer::load_instrument_events( binistream *f, CVoiceData &voice,
-                                         binistream *bnk_file, SBnkHeader const &bnk_header )
-{
-    int16 const number_of_instrument_events = f->readInt( 2 );
-
-    TInstrumentEvents &instrument_events = voice.instrument_events;
-
-    instrument_events.reserve( number_of_instrument_events );
-
-    for(int i=0; i<number_of_instrument_events; ++i)
-    {
-        SInstrumentEvent event;
-        event.time = f->readInt( 2 );
-        f->readString( event.name, 9 );
-
-	    std::string event_name = event.name;
-        event.ins_index = load_rol_instrument( bnk_file, bnk_header, event_name );
-
-        instrument_events.push_back( event );
-
-        f->seek( 1+2, binio::Add );
-    }
-
-    f->seek( 15, binio::Add );
-}
-//---------------------------------------------------------
-void CrolPlayer::load_volume_events( binistream *f, CVoiceData &voice )
-{
-    int16 const number_of_volume_events = f->readInt( 2 );
-
-    TVolumeEvents &volume_events = voice.volume_events;
-
-    volume_events.reserve( number_of_volume_events );
-
-    for(int i=0; i<number_of_volume_events; ++i)
-    {
-        SVolumeEvent event;
-        event.time       = f->readInt( 2 );
-        event.multiplier = f->readFloat( binio::Single );
-
-        volume_events.push_back( event );
-    }
-
-    f->seek( 15, binio::Add );
-}
-//---------------------------------------------------------
-void CrolPlayer::load_pitch_events( binistream *f, CVoiceData &voice )
-{
-    int16 const number_of_pitch_events = f->readInt( 2 );
-
-    TPitchEvents &pitch_events = voice.pitch_events;
-
-    pitch_events.reserve( number_of_pitch_events );
-
-    for(int i=0; i<number_of_pitch_events; ++i)
-    {
-        SPitchEvent event;
-        event.time      = f->readInt( 2 );
-        event.variation = f->readFloat( binio::Single );
-
-        pitch_events.push_back( event );
-    }
-}
-//---------------------------------------------------------
-bool CrolPlayer::load_bnk_info( binistream *f, SBnkHeader &header )
-{
-  header.version_major = f->readInt(1);
-  header.version_minor = f->readInt(1);
-  f->readString( header.signature, 6 );
-
-  header.number_of_list_entries_used  = f->readInt( 2 );
-  header.total_number_of_list_entries = f->readInt( 2 );
-
-  header.abs_offset_of_name_list = f->readInt( 4 );
-  header.abs_offset_of_data      = f->readInt( 4 );
-
-  f->seek( header.abs_offset_of_name_list, binio::Set );
-
-  TInstrumentNames &ins_name_list = header.ins_name_list;
-  ins_name_list.reserve( header.number_of_list_entries_used );
-
-  for(int i=0; i<header.number_of_list_entries_used; ++i)
-    {
-      SInstrumentName instrument;
-
-      instrument.index = f->readInt( 2 );
-      instrument.record_used = f->readInt(1);
-      f->readString( instrument.name, 9 );
-
-      // printf("%s = #%d\n", instrument.name, i );
-
-      ins_name_list.push_back( instrument );
-    }
-
-  //std::sort( ins_name_list.begin(), ins_name_list.end(), StringCompare() );
-
-  return true;
-}
-//---------------------------------------------------------
-int CrolPlayer::load_rol_instrument( binistream *f, SBnkHeader const &header, std::string &name )
-{
-    TInstrumentNames const &ins_name_list = header.ins_name_list;
-
-    int const ins_index = get_ins_index( name );
-
-    if( ins_index != -1 )
-    {
-        return ins_index;
-    }
-
-    typedef TInstrumentNames::const_iterator TInsIter;
-    typedef std::pair<TInsIter, TInsIter>    TInsIterPair;
-
-    TInsIterPair range = std::equal_range( ins_name_list.begin(), 
-                                           ins_name_list.end(), 
-                                           name, 
-                                           StringCompare() );
-
-    if( range.first != range.second )
-    {
-        int const seekOffs = header.abs_offset_of_data + (range.first->index*kSizeofDataRecord);
-        f->seek( seekOffs, binio::Set );
-    }
-
-    SUsedList usedIns;
-    usedIns.name = name;
-
-    if( range.first != range.second )
-    {
-        read_rol_instrument( f, usedIns.instrument );
-    }
-    else
-    {
-        // set up default instrument data here
-        memset( &usedIns.instrument, 0, kSizeofDataRecord );
-    }
-    ins_list.push_back( usedIns );
-
-    return ins_list.size()-1;
-}
-//---------------------------------------------------------
-int CrolPlayer::get_ins_index( std::string const &name ) const
-{
-    for(unsigned int i=0; i<ins_list.size(); ++i)
-    {
-        if( stricmp(ins_list[i].name.c_str(), name.c_str()) == 0 )
-        {
-            return i;
-        }
-    }
-
-    return -1;
-}
-//---------------------------------------------------------
-void CrolPlayer::read_rol_instrument( binistream *f, SRolInstrument &ins )
-{
-  ins.mode = f->readInt(1);
-  ins.voice_number = f->readInt(1);
-
-  read_fm_operator( f, ins.modulator );
-  read_fm_operator( f, ins.carrier );
-
-  ins.modulator.waveform = f->readInt(1);
-  ins.carrier.waveform = f->readInt(1);
-}
-//---------------------------------------------------------
-void CrolPlayer::read_fm_operator( binistream *f, SOPL2Op &opl2_op )
-{
-  SFMOperator fm_op;
-
-  fm_op.key_scale_level = f->readInt(1);
-  fm_op.freq_multiplier = f->readInt(1);
-  fm_op.feed_back = f->readInt(1);
-  fm_op.attack_rate = f->readInt(1);
-  fm_op.sustain_level = f->readInt(1);
-  fm_op.sustaining_sound = f->readInt(1);
-  fm_op.decay_rate = f->readInt(1);
-  fm_op.release_rate = f->readInt(1);
-  fm_op.output_level = f->readInt(1);
-  fm_op.amplitude_vibrato = f->readInt(1);
-  fm_op.frequency_vibrato = f->readInt(1);
-  fm_op.envelope_scaling = f->readInt(1);
-  fm_op.fm_type = f->readInt(1);
-
-  opl2_op.ammulti = fm_op.amplitude_vibrato << 7 | fm_op.frequency_vibrato << 6 | fm_op.sustaining_sound << 5 | fm_op.envelope_scaling << 4 | fm_op.freq_multiplier;
-  opl2_op.ksltl   = fm_op.key_scale_level   << 6 | fm_op.output_level;
-  opl2_op.ardr    = fm_op.attack_rate       << 4 | fm_op.decay_rate;
-  opl2_op.slrr    = fm_op.sustain_level     << 4 | fm_op.release_rate;
-  opl2_op.fbc     = fm_op.feed_back         << 1 | (fm_op.fm_type ^ 1);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/rol.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,723 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * rol.h - ROL Player by OPLx <oplx@yahoo.com>
+ *
+ * Visit:  http://tenacity.hispeed.com/aomit/oplx/
+ */
+#include <algorithm>
+
+#include "rol.h"
+#include "debug.h"
+
+int   const CrolPlayer::kSizeofDataRecord    =  30;
+int   const CrolPlayer::kMaxTickBeat         =  60;
+int   const CrolPlayer::kSilenceNote         = -12;
+int   const CrolPlayer::kNumMelodicVoices    =  9;
+int   const CrolPlayer::kNumPercussiveVoices = 11;
+int   const CrolPlayer::kBassDrumChannel     =  6;
+int   const CrolPlayer::kSnareDrumChannel    =  7;
+int   const CrolPlayer::kTomtomChannel       =  8;
+int   const CrolPlayer::kTomtomFreq          =  2;//4;
+int   const CrolPlayer::kSnareDrumFreq       =  2;//kTomtomFreq + 7;
+float const CrolPlayer::kDefaultUpdateTme    = 18.2f;
+float const CrolPlayer::kPitchFactor         = 400.0f;
+
+static const unsigned char drum_table[4] = {0x14, 0x12, 0x15, 0x11};
+
+CrolPlayer::uint16 const CrolPlayer::kNoteTable[12] = 
+{ 
+    340, // C
+    363, // C#
+    385, // D
+    408, // D#
+    432, // E
+    458, // F
+    485, // F#
+    514, // G
+    544, // G#
+    577, // A
+    611, // A#
+    647  // B
+};
+
+/*** public methods **************************************/
+
+CPlayer *CrolPlayer::factory(Copl *newopl)
+{
+  return new CrolPlayer(newopl);
+}
+//---------------------------------------------------------
+CrolPlayer::CrolPlayer(Copl *newopl)
+:  CPlayer         ( newopl )
+  ,rol_header      ( NULL )
+  ,mNextTempoEvent ( 0 )
+  ,mCurrTick       ( 0 )
+  ,mTimeOfLastNote ( 0 )
+  ,mRefresh        ( kDefaultUpdateTme )
+  ,bdRegister      ( 0 )
+{
+    int n;
+
+    memset(bxRegister,  0, sizeof(bxRegister) );
+    memset(volumeCache, 0, sizeof(volumeCache) );
+    memset(freqCache,   0, sizeof(freqCache) );
+
+    for(n=0; n<11; n++)
+      pitchCache[n]=1.0f;    
+}
+//---------------------------------------------------------
+CrolPlayer::~CrolPlayer()
+{
+    if( rol_header != NULL )
+    {
+        delete rol_header;
+        rol_header=NULL;
+    }
+}
+//---------------------------------------------------------
+bool CrolPlayer::load(const std::string &filename, const CFileProvider &fp)
+{
+    binistream *f = fp.open(filename); if(!f) return false;
+
+    char *fn = new char[filename.length()+9];
+    int i;
+    std::string bnk_filename;
+
+    AdPlug_LogWrite("*** CrolPlayer::load(f, \"%s\") ***\n", filename.c_str());
+    strcpy(fn,filename.data());
+    for (i=strlen(fn)-1; i>=0; i--)
+      if (fn[i] == '/' || fn[i] == '\\')
+	break;
+    strcpy(fn+i+1,"standard.bnk");
+    bnk_filename = fn;
+    delete [] fn;
+    AdPlug_LogWrite("bnk_filename = \"%s\"\n",bnk_filename.c_str());
+
+    rol_header = new SRolHeader;
+    memset( rol_header, 0, sizeof(SRolHeader) );
+
+    rol_header->version_major = f->readInt( 2 );
+    rol_header->version_minor = f->readInt( 2 );
+
+    // Version check
+    if(rol_header->version_major != 0 || rol_header->version_minor != 4) {
+      AdPlug_LogWrite("Unsupported file version %d.%d or not a ROL file!\n",
+	       rol_header->version_major, rol_header->version_minor);
+      AdPlug_LogWrite("--- CrolPlayer::load ---\n");
+      fp.close(f);
+      return false;
+    }
+
+    f->seek( 40, binio::Add );
+
+    rol_header->ticks_per_beat    = f->readInt( 2 );
+    rol_header->beats_per_measure = f->readInt( 2 );
+    rol_header->edit_scale_y      = f->readInt( 2 );
+    rol_header->edit_scale_x      = f->readInt( 2 );
+
+    f->seek( 1, binio::Add );
+
+    rol_header->mode = f->readInt(1);
+
+    f->seek( 90+38+15, binio::Add );
+
+    rol_header->basic_tempo = f->readFloat( binio::Single );
+
+    load_tempo_events( f );
+
+    mTimeOfLastNote = 0;
+
+    if( load_voice_data( f, bnk_filename, fp ) != true )
+    {
+      AdPlug_LogWrite("CrolPlayer::load_voice_data(f) failed!\n");
+      AdPlug_LogWrite("--- CrolPlayer::load ---\n");
+
+      fp.close( f );
+      return false;
+    }
+
+    fp.close( f );
+
+    rewind( 0 );
+    AdPlug_LogWrite("--- CrolPlayer::load ---\n");
+    return true;
+}
+//---------------------------------------------------------
+bool CrolPlayer::update()
+{
+    if( mNextTempoEvent < mTempoEvents.size() &&
+        mTempoEvents[mNextTempoEvent].time == mCurrTick )
+    {
+        SetRefresh( mTempoEvents[mNextTempoEvent].multiplier );
+        ++mNextTempoEvent;
+    }
+
+    TVoiceData::iterator curr = voice_data.begin();
+    TVoiceData::iterator end  = voice_data.end();
+    int voice                 = 0;
+
+    while( curr != end )
+    {
+        UpdateVoice( voice, *curr );
+        ++curr;
+        ++voice;
+    }
+
+    ++mCurrTick;
+
+    if( mCurrTick > mTimeOfLastNote )
+    {
+        return false;
+    }
+
+    return true;
+    //return ( mCurrTick > mTimeOfLastNote ) ? false : true;
+}
+//---------------------------------------------------------
+void CrolPlayer::rewind( int subsong )
+{
+    TVoiceData::iterator curr = voice_data.begin();
+    TVoiceData::iterator end  = voice_data.end();
+
+    while( curr != end )
+    {
+        CVoiceData &voice = *curr;
+
+        voice.Reset();
+        ++curr;
+    }
+
+    memset(bxRegister,  0, sizeof(bxRegister) );
+    memset(volumeCache, 0, sizeof(volumeCache) );
+
+    bdRegister = 0;
+
+    opl->init();        // initialize to melodic by default
+    opl->write(1,0x20); // Enable waveform select (bit 5)
+
+    if( rol_header->mode == 0 )
+    {
+        opl->write( 0xbd, 0x20 ); // select rhythm mode (bit 5)
+        bdRegister = 0x20;
+
+        SetFreq( kTomtomChannel,    24 );
+        SetFreq( kSnareDrumChannel, 31 );
+    }
+
+    mNextTempoEvent = 0;
+    mCurrTick       = 0;
+
+    SetRefresh(1.0f);
+}
+//---------------------------------------------------------
+inline float fmin( int const a, int const b )
+{
+    return static_cast<float>( a < b ? a : b );
+}
+//---------------------------------------------------------
+void CrolPlayer::SetRefresh( float const multiplier )
+{
+    float const tickBeat = fmin(kMaxTickBeat, rol_header->ticks_per_beat);
+
+    mRefresh =  (tickBeat*rol_header->basic_tempo*multiplier) / 60.0f;
+}
+//---------------------------------------------------------
+float CrolPlayer::getrefresh()
+{
+    return mRefresh;
+}
+//---------------------------------------------------------
+void CrolPlayer::UpdateVoice( int const voice, CVoiceData &voiceData )
+{
+    TNoteEvents const &nEvents = voiceData.note_events;
+
+    if( nEvents.empty() || voiceData.mEventStatus & CVoiceData::kES_NoteEnd )
+    {
+        return; // no note data to process, don't bother doing anything.
+    }
+
+    TInstrumentEvents  &iEvents = voiceData.instrument_events;
+    TVolumeEvents      &vEvents = voiceData.volume_events;
+    TPitchEvents       &pEvents = voiceData.pitch_events;
+
+    if( !(voiceData.mEventStatus & CVoiceData::kES_InstrEnd ) &&
+        iEvents[voiceData.next_instrument_event].time == mCurrTick )
+    {
+        if( voiceData.next_instrument_event < iEvents.size() )
+        {
+            send_ins_data_to_chip( voice, iEvents[voiceData.next_instrument_event].ins_index );
+            ++voiceData.next_instrument_event;
+        }
+        else
+        {
+            voiceData.mEventStatus |= CVoiceData::kES_InstrEnd;
+        }
+    }
+
+    if( !(voiceData.mEventStatus & CVoiceData::kES_VolumeEnd ) &&
+        vEvents[voiceData.next_volume_event].time == mCurrTick )
+    {
+      SVolumeEvent const &volumeEvent = vEvents[voiceData.next_volume_event];
+
+        if(  voiceData.next_volume_event < vEvents.size() )
+        {
+            int const volume = (int)(63.0f*(1.0f - volumeEvent.multiplier));
+
+            SetVolume( voice, volume );
+
+            ++voiceData.next_volume_event; // move to next volume event
+        }
+        else
+        {
+            voiceData.mEventStatus |= CVoiceData::kES_VolumeEnd;
+        }        
+    }
+
+    if( voiceData.mForceNote || voiceData.current_note_duration > voiceData.mNoteDuration-1 )
+    {
+        if( mCurrTick != 0 )
+        {
+            ++voiceData.current_note;
+        }
+
+        if( voiceData.current_note < nEvents.size() )
+        {
+            SNoteEvent const &noteEvent = nEvents[voiceData.current_note];
+
+            SetNote( voice, noteEvent.number );
+            voiceData.current_note_duration = 0;
+            voiceData.mNoteDuration         = noteEvent.duration;
+            voiceData.mForceNote            = false;
+        }
+        else
+        {
+            SetNote( voice, kSilenceNote );
+            voiceData.mEventStatus |= CVoiceData::kES_NoteEnd;
+            return;
+        }
+    }
+
+    if( !(voiceData.mEventStatus & CVoiceData::kES_PitchEnd ) &&
+        pEvents[voiceData.next_pitch_event].time == mCurrTick )
+    {
+        if( voiceData.next_pitch_event < pEvents.size() )
+        {
+            SetPitch(voice,pEvents[voiceData.next_pitch_event].variation);
+            ++voiceData.next_pitch_event;
+        }
+        else
+        {
+            voiceData.mEventStatus |= CVoiceData::kES_PitchEnd;
+        }
+    }
+
+    ++voiceData.current_note_duration;
+}
+//---------------------------------------------------------
+void CrolPlayer::SetNote( int const voice, int const note )
+{
+    if( voice < kBassDrumChannel || rol_header->mode )
+    {
+        SetNoteMelodic( voice, note );
+    }
+    else
+    {
+        SetNotePercussive( voice, note );
+    }
+}
+//---------------------------------------------------------
+void CrolPlayer::SetNotePercussive( int const voice, int const note )
+{
+    int const bit_pos = 4-voice+kBassDrumChannel;
+
+    bdRegister &= ~( 1<<bit_pos );
+    opl->write( 0xbd, bdRegister );
+
+    if( note != kSilenceNote )
+    {
+        switch( voice )
+        {
+            case kTomtomChannel:
+                SetFreq( kSnareDrumChannel, note+7 );
+            case kBassDrumChannel:
+                SetFreq( voice, note );
+                break;
+        }
+
+        bdRegister |= 1<<bit_pos;
+        opl->write( 0xbd, bdRegister );
+    }
+}
+//---------------------------------------------------------
+void CrolPlayer::SetNoteMelodic( int const voice, int const note )
+{
+    opl->write( 0xb0+voice, bxRegister[voice] & ~0x20 );
+
+    if( note != kSilenceNote )
+    {
+        SetFreq( voice, note, true );
+    }
+}
+//---------------------------------------------------------
+void CrolPlayer::SetPitch(int const voice, real32 const variation)
+{
+  pitchCache[voice] = variation;
+  freqCache[voice] += (uint16)((((float)freqCache[voice])*(variation-1.0f)) / kPitchFactor);
+
+  opl->write(0xa0+voice,freqCache[voice] & 0xff);
+}
+//---------------------------------------------------------
+void CrolPlayer::SetFreq( int const voice, int const note, bool const keyOn )
+{
+    uint16 freq = kNoteTable[note%12] + ((note/12) << 10);
+    freq += (uint16)((((float)freq)*(pitchCache[voice]-1.0f))/kPitchFactor);
+
+    freqCache[voice] = freq;
+    bxRegister[voice] = ((freq >> 8) & 0x1f);
+
+    opl->write( 0xa0+voice, freq & 0xff );
+    opl->write( 0xb0+voice, bxRegister[voice] | (keyOn ? 0x20 : 0x0) );
+}
+//---------------------------------------------------------
+void CrolPlayer::SetVolume( int const voice, int const volume )
+{
+    volumeCache[voice] = (volumeCache[voice] &0xc0) | volume;
+
+    int const op_offset = ( voice < kSnareDrumChannel || rol_header->mode ) ? 
+                          op_table[voice]+3 : drum_table[voice-kSnareDrumChannel];
+
+    opl->write( 0x40+op_offset, volumeCache[voice] );
+}
+//---------------------------------------------------------
+void CrolPlayer::send_ins_data_to_chip( int const voice, int const ins_index )
+{
+    SRolInstrument &instrument = ins_list[ins_index].instrument;
+
+    send_operator( voice, instrument.modulator, instrument.carrier );
+}
+//---------------------------------------------------------
+void CrolPlayer::send_operator( int const voice, SOPL2Op const &modulator,  SOPL2Op const &carrier )
+{
+    if( voice < kSnareDrumChannel || rol_header->mode )
+    {
+        int const op_offset = op_table[voice];
+
+        opl->write( 0x20+op_offset, modulator.ammulti  );
+        opl->write( 0x40+op_offset, modulator.ksltl    );
+        opl->write( 0x60+op_offset, modulator.ardr     );
+        opl->write( 0x80+op_offset, modulator.slrr     );
+        opl->write( 0xc0+voice    , modulator.fbc      );
+        opl->write( 0xe0+op_offset, modulator.waveform );
+
+        volumeCache[voice] = (carrier.ksltl & 0xc0) | volumeCache[voice] & 0x3f;
+
+        opl->write( 0x23+op_offset, carrier.ammulti  );
+        opl->write( 0x43+op_offset, volumeCache[voice]    );
+        opl->write( 0x63+op_offset, carrier.ardr     );
+        opl->write( 0x83+op_offset, carrier.slrr     );
+//        opl->write( 0xc3+voice    , carrier.fbc      ); <- don't bother writing this.
+        opl->write( 0xe3+op_offset, carrier.waveform );
+    }
+    else
+    {
+        int const op_offset = drum_table[voice-kSnareDrumChannel];
+
+        volumeCache[voice] = (modulator.ksltl & 0xc0) | volumeCache[voice] & 0x3f;
+
+        opl->write( 0x20+op_offset, modulator.ammulti  );
+        opl->write( 0x40+op_offset, volumeCache[voice]      );
+        opl->write( 0x60+op_offset, modulator.ardr     );
+        opl->write( 0x80+op_offset, modulator.slrr     );
+        opl->write( 0xc0+voice    , modulator.fbc      );
+        opl->write( 0xe0+op_offset, modulator.waveform );
+    }
+}
+//---------------------------------------------------------
+void CrolPlayer::load_tempo_events( binistream *f )
+{
+    int16 const num_tempo_events = f->readInt( 2 );
+
+    mTempoEvents.reserve( num_tempo_events );
+
+    for(int i=0; i<num_tempo_events; ++i)
+    {
+        STempoEvent event;
+
+        event.time       = f->readInt( 2 );
+        event.multiplier = f->readFloat( binio::Single );
+        mTempoEvents.push_back( event );
+    }
+}
+//---------------------------------------------------------
+bool CrolPlayer::load_voice_data( binistream *f, std::string const &bnk_filename, const CFileProvider &fp )
+{
+    SBnkHeader bnk_header;
+    binistream *bnk_file = fp.open( bnk_filename.c_str() );
+
+    if( bnk_file )
+    {
+        load_bnk_info( bnk_file, bnk_header );
+
+        int const numVoices = rol_header->mode ? kNumMelodicVoices : kNumPercussiveVoices;
+
+        voice_data.reserve( numVoices );
+        for(int i=0; i<numVoices; ++i)
+        {
+            CVoiceData voice;
+
+            load_note_events( f, voice );
+            load_instrument_events( f, voice, bnk_file, bnk_header );
+            load_volume_events( f, voice );
+            load_pitch_events( f, voice );
+
+            voice_data.push_back( voice );
+        }
+
+        fp.close(bnk_file);
+
+        return true;
+    }
+
+    return false;
+}
+//---------------------------------------------------------
+void CrolPlayer::load_note_events( binistream *f, CVoiceData &voice )
+{
+    f->seek( 15, binio::Add );
+
+    int16 const time_of_last_note = f->readInt( 2 );
+
+    if( time_of_last_note != 0 )
+    {
+        TNoteEvents &note_events = voice.note_events;
+        int16 total_duration     = 0;
+
+        do
+        {
+            SNoteEvent event;
+
+            event.number   = f->readInt( 2 );
+            event.duration = f->readInt( 2 );
+
+            event.number += kSilenceNote; // adding -12
+
+            note_events.push_back( event );
+
+            total_duration += event.duration;
+        } while( total_duration < time_of_last_note );
+
+        if( time_of_last_note > mTimeOfLastNote )
+        {
+            mTimeOfLastNote = time_of_last_note;
+        }
+    }
+
+    f->seek( 15, binio::Add );
+}
+//---------------------------------------------------------
+void CrolPlayer::load_instrument_events( binistream *f, CVoiceData &voice,
+                                         binistream *bnk_file, SBnkHeader const &bnk_header )
+{
+    int16 const number_of_instrument_events = f->readInt( 2 );
+
+    TInstrumentEvents &instrument_events = voice.instrument_events;
+
+    instrument_events.reserve( number_of_instrument_events );
+
+    for(int i=0; i<number_of_instrument_events; ++i)
+    {
+        SInstrumentEvent event;
+        event.time = f->readInt( 2 );
+        f->readString( event.name, 9 );
+
+	    std::string event_name = event.name;
+        event.ins_index = load_rol_instrument( bnk_file, bnk_header, event_name );
+
+        instrument_events.push_back( event );
+
+        f->seek( 1+2, binio::Add );
+    }
+
+    f->seek( 15, binio::Add );
+}
+//---------------------------------------------------------
+void CrolPlayer::load_volume_events( binistream *f, CVoiceData &voice )
+{
+    int16 const number_of_volume_events = f->readInt( 2 );
+
+    TVolumeEvents &volume_events = voice.volume_events;
+
+    volume_events.reserve( number_of_volume_events );
+
+    for(int i=0; i<number_of_volume_events; ++i)
+    {
+        SVolumeEvent event;
+        event.time       = f->readInt( 2 );
+        event.multiplier = f->readFloat( binio::Single );
+
+        volume_events.push_back( event );
+    }
+
+    f->seek( 15, binio::Add );
+}
+//---------------------------------------------------------
+void CrolPlayer::load_pitch_events( binistream *f, CVoiceData &voice )
+{
+    int16 const number_of_pitch_events = f->readInt( 2 );
+
+    TPitchEvents &pitch_events = voice.pitch_events;
+
+    pitch_events.reserve( number_of_pitch_events );
+
+    for(int i=0; i<number_of_pitch_events; ++i)
+    {
+        SPitchEvent event;
+        event.time      = f->readInt( 2 );
+        event.variation = f->readFloat( binio::Single );
+
+        pitch_events.push_back( event );
+    }
+}
+//---------------------------------------------------------
+bool CrolPlayer::load_bnk_info( binistream *f, SBnkHeader &header )
+{
+  header.version_major = f->readInt(1);
+  header.version_minor = f->readInt(1);
+  f->readString( header.signature, 6 );
+
+  header.number_of_list_entries_used  = f->readInt( 2 );
+  header.total_number_of_list_entries = f->readInt( 2 );
+
+  header.abs_offset_of_name_list = f->readInt( 4 );
+  header.abs_offset_of_data      = f->readInt( 4 );
+
+  f->seek( header.abs_offset_of_name_list, binio::Set );
+
+  TInstrumentNames &ins_name_list = header.ins_name_list;
+  ins_name_list.reserve( header.number_of_list_entries_used );
+
+  for(int i=0; i<header.number_of_list_entries_used; ++i)
+    {
+      SInstrumentName instrument;
+
+      instrument.index = f->readInt( 2 );
+      instrument.record_used = f->readInt(1);
+      f->readString( instrument.name, 9 );
+
+      // printf("%s = #%d\n", instrument.name, i );
+
+      ins_name_list.push_back( instrument );
+    }
+
+  //std::sort( ins_name_list.begin(), ins_name_list.end(), StringCompare() );
+
+  return true;
+}
+//---------------------------------------------------------
+int CrolPlayer::load_rol_instrument( binistream *f, SBnkHeader const &header, std::string &name )
+{
+    TInstrumentNames const &ins_name_list = header.ins_name_list;
+
+    int const ins_index = get_ins_index( name );
+
+    if( ins_index != -1 )
+    {
+        return ins_index;
+    }
+
+    typedef TInstrumentNames::const_iterator TInsIter;
+    typedef std::pair<TInsIter, TInsIter>    TInsIterPair;
+
+    TInsIterPair range = std::equal_range( ins_name_list.begin(), 
+                                           ins_name_list.end(), 
+                                           name, 
+                                           StringCompare() );
+
+    if( range.first != range.second )
+    {
+        int const seekOffs = header.abs_offset_of_data + (range.first->index*kSizeofDataRecord);
+        f->seek( seekOffs, binio::Set );
+    }
+
+    SUsedList usedIns;
+    usedIns.name = name;
+
+    if( range.first != range.second )
+    {
+        read_rol_instrument( f, usedIns.instrument );
+    }
+    else
+    {
+        // set up default instrument data here
+        memset( &usedIns.instrument, 0, kSizeofDataRecord );
+    }
+    ins_list.push_back( usedIns );
+
+    return ins_list.size()-1;
+}
+//---------------------------------------------------------
+int CrolPlayer::get_ins_index( std::string const &name ) const
+{
+    for(unsigned int i=0; i<ins_list.size(); ++i)
+    {
+        if( stricmp(ins_list[i].name.c_str(), name.c_str()) == 0 )
+        {
+            return i;
+        }
+    }
+
+    return -1;
+}
+//---------------------------------------------------------
+void CrolPlayer::read_rol_instrument( binistream *f, SRolInstrument &ins )
+{
+  ins.mode = f->readInt(1);
+  ins.voice_number = f->readInt(1);
+
+  read_fm_operator( f, ins.modulator );
+  read_fm_operator( f, ins.carrier );
+
+  ins.modulator.waveform = f->readInt(1);
+  ins.carrier.waveform = f->readInt(1);
+}
+//---------------------------------------------------------
+void CrolPlayer::read_fm_operator( binistream *f, SOPL2Op &opl2_op )
+{
+  SFMOperator fm_op;
+
+  fm_op.key_scale_level = f->readInt(1);
+  fm_op.freq_multiplier = f->readInt(1);
+  fm_op.feed_back = f->readInt(1);
+  fm_op.attack_rate = f->readInt(1);
+  fm_op.sustain_level = f->readInt(1);
+  fm_op.sustaining_sound = f->readInt(1);
+  fm_op.decay_rate = f->readInt(1);
+  fm_op.release_rate = f->readInt(1);
+  fm_op.output_level = f->readInt(1);
+  fm_op.amplitude_vibrato = f->readInt(1);
+  fm_op.frequency_vibrato = f->readInt(1);
+  fm_op.envelope_scaling = f->readInt(1);
+  fm_op.fm_type = f->readInt(1);
+
+  opl2_op.ammulti = fm_op.amplitude_vibrato << 7 | fm_op.frequency_vibrato << 6 | fm_op.sustaining_sound << 5 | fm_op.envelope_scaling << 4 | fm_op.freq_multiplier;
+  opl2_op.ksltl   = fm_op.key_scale_level   << 6 | fm_op.output_level;
+  opl2_op.ardr    = fm_op.attack_rate       << 4 | fm_op.decay_rate;
+  opl2_op.slrr    = fm_op.sustain_level     << 4 | fm_op.release_rate;
+  opl2_op.fbc     = fm_op.feed_back         << 1 | (fm_op.fm_type ^ 1);
+}
--- a/Plugins/Input/adplug/core/s3m.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,535 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * s3m.c - S3M Player by Simon Peter <dn.tlp@gmx.net>
- *
- * BUGS:
- * Extra Fine Slides (EEx, FEx) & Fine Vibrato (Uxy) are inaccurate
- */
-
-#include "s3m.h"
-
-const char Cs3mPlayer::chnresolv[] =	// S3M -> adlib channel conversion
-	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,-1,-1,-1,-1,-1,-1,-1};
-
-const unsigned short Cs3mPlayer::notetable[12] =		// S3M adlib note table
-			{340,363,385,408,432,458,485,514,544,577,611,647};
-
-const unsigned char Cs3mPlayer::vibratotab[32] =		// vibrato rate table
-			{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1};
-
-/*** public methods *************************************/
-
-CPlayer *Cs3mPlayer::factory(Copl *newopl)
-{
-  return new Cs3mPlayer(newopl);
-}
-
-Cs3mPlayer::Cs3mPlayer(Copl *newopl): CPlayer(newopl)
-{
-	int			i,j,k;
-
-	memset(pattern,255,sizeof(pattern));
-	memset(orders,255,sizeof(orders));
-
-	for(i=0;i<99;i++)		// setup pattern
-		for(j=0;j<64;j++)
-			for(k=0;k<32;k++) {
-				pattern[i][j][k].instrument = 0;
-				pattern[i][j][k].info = 0;
-			}
-}
-
-bool Cs3mPlayer::load(const std::string &filename, const CFileProvider &fp)
-{
-        binistream *f = fp.open(filename); if(!f) return false;
-	unsigned short	insptr[99],pattptr[99];
-	int		i,row;
-	unsigned char	bufval,bufval2;
-	unsigned short	ppatlen;
-	s3mheader	*checkhead;
-	bool		adlibins=false;
-
-	// file validation section
-	checkhead = new s3mheader;
-	load_header(f, checkhead);
-  if(checkhead->kennung != 0x1a || checkhead->typ != 16
-     || checkhead->insnum > 99) {
-		delete checkhead; fp.close(f); return false;
-	} else
-		if(strncmp(checkhead->scrm,"SCRM",4)) {
-			delete checkhead; fp.close(f); return false;
-		} else {	// is an adlib module?
-             	        f->seek(checkhead->ordnum, binio::Add);
-			for(i = 0; i < checkhead->insnum; i++)
-			  insptr[i] = f->readInt(2);
-			for(i=0;i<checkhead->insnum;i++) {
-				f->seek(insptr[i]*16);
-				if(f->readInt(1) >= 2) {
-					adlibins = true;
-					break;
-				}
-			}
-			delete checkhead;
-			if(!adlibins) { fp.close(f); return false; }
-		}
-
-	// load section
-	f->seek(0);	// rewind for load
-	load_header(f, &header);			// read header
-
-  // security check
-  if(header.ordnum > 256 || header.insnum > 99 || header.patnum > 99) {
-    fp.close(f);
-    return false;
-  }
-
-	for(i = 0; i < header.ordnum; i++) orders[i] = f->readInt(1);	// read orders
-	for(i = 0; i < header.insnum; i++) insptr[i] = f->readInt(2);	// instrument parapointers
-	for(i = 0; i < header.patnum; i++) pattptr[i] = f->readInt(2);	// pattern parapointers
-
-	for(i=0;i<header.insnum;i++) {	// load instruments
-		f->seek(insptr[i]*16);
-		inst[i].type = f->readInt(1);
-		f->readString(inst[i].filename, 15);
-		inst[i].d00 = f->readInt(1); inst[i].d01 = f->readInt(1);
-		inst[i].d02 = f->readInt(1); inst[i].d03 = f->readInt(1);
-		inst[i].d04 = f->readInt(1); inst[i].d05 = f->readInt(1);
-		inst[i].d06 = f->readInt(1); inst[i].d07 = f->readInt(1);
-		inst[i].d08 = f->readInt(1); inst[i].d09 = f->readInt(1);
-		inst[i].d0a = f->readInt(1); inst[i].d0b = f->readInt(1);
-		inst[i].volume = f->readInt(1); inst[i].dsk = f->readInt(1);
-		f->ignore(2);
-		inst[i].c2spd = f->readInt(4);
-		f->ignore(12);
-		f->readString(inst[i].name, 28);
-		f->readString(inst[i].scri, 4);
-	}
-
-	for(i=0;i<header.patnum;i++) {	// depack patterns
-		f->seek(pattptr[i]*16);
-		ppatlen = f->readInt(2);
-		unsigned long pattpos = f->pos();
-		for(row=0;(row<64) && (pattpos-pattptr[i]*16<=ppatlen);row++)
-			do {
-            		        bufval = f->readInt(1);
-				if(bufval & 32) {
-				        bufval2 = f->readInt(1);
-					pattern[i][row][bufval & 31].note = bufval2 & 15;
-					pattern[i][row][bufval & 31].oct = (bufval2 & 240) >> 4;
-					pattern[i][row][bufval & 31].instrument = f->readInt(1);
-				}
-				if(bufval & 64)
-				        pattern[i][row][bufval & 31].volume = f->readInt(1);
-				if(bufval & 128) {
-				        pattern[i][row][bufval & 31].command = f->readInt(1);
-					pattern[i][row][bufval & 31].info = f->readInt(1);
-				}
-			} while(bufval);
-	}
-
-	fp.close(f);
-	rewind(0);
-	return true;		// done
-}
-
-bool Cs3mPlayer::update()
-{
-	unsigned char	pattbreak=0,donote;		// remember vars
-	unsigned char	pattnr,chan,row,info;	// cache vars
-	signed char		realchan;
-
-	// effect handling (timer dependant)
-	for(realchan=0; realchan<9; realchan++) {
-		info = channel[realchan].info;	// fill infobyte cache
-		switch(channel[realchan].fx) {
-		case 11:
-		case 12: if(channel[realchan].fx == 11)								// dual command: H00 and Dxy
-					 vibrato(realchan,channel[realchan].dualinfo);
-				 else															// dual command: G00 and Dxy
-					 tone_portamento(realchan,channel[realchan].dualinfo);
-		case 4: if(info <= 0x0f)												// volume slide down
-					if(channel[realchan].vol - info >= 0)
-						channel[realchan].vol -= info;
-					else
-						channel[realchan].vol = 0;
-				if((info & 0x0f) == 0)											// volume slide up
-					if(channel[realchan].vol + (info >> 4) <= 63)
-						channel[realchan].vol += info >> 4;
-					else
-						channel[realchan].vol = 63;
-				setvolume(realchan);
-				break;
-		case 5: if(info == 0xf0 || info <= 0xe0) {								// slide down
-					slide_down(realchan,info);
-					setfreq(realchan);
-				}
-				break;
-		case 6: if(info == 0xf0 || info <= 0xe0) {								// slide up
-					slide_up(realchan,info);
-					setfreq(realchan);
-				}
-				break;
-		case 7: tone_portamento(realchan,channel[realchan].dualinfo); break;	// tone portamento
-		case 8: vibrato(realchan,channel[realchan].dualinfo); break;		// vibrato
-		case 10: channel[realchan].nextfreq = channel[realchan].freq;	// arpeggio
-				 channel[realchan].nextoct = channel[realchan].oct;
-				 switch(channel[realchan].trigger) {
-				 case 0: channel[realchan].freq = notetable[channel[realchan].note]; break;
-				 case 1: if(channel[realchan].note + ((info & 0xf0) >> 4) < 12)
-							 channel[realchan].freq = notetable[channel[realchan].note + ((info & 0xf0) >> 4)];
-						 else {
-							 channel[realchan].freq = notetable[channel[realchan].note + ((info & 0xf0) >> 4) - 12];
-							 channel[realchan].oct++;
-						 }
-						 break;
-				 case 2: if(channel[realchan].note + (info & 0x0f) < 12)
-							 channel[realchan].freq = notetable[channel[realchan].note + (info & 0x0f)];
-						 else {
-							 channel[realchan].freq = notetable[channel[realchan].note + (info & 0x0f) - 12];
-							 channel[realchan].oct++;
-						 }
-						 break;
-				 }
-				 if(channel[realchan].trigger < 2)
-					 channel[realchan].trigger++;
-				 else
-					 channel[realchan].trigger = 0;
-				 setfreq(realchan);
-				 channel[realchan].freq = channel[realchan].nextfreq;
-				 channel[realchan].oct = channel[realchan].nextoct;
-				 break;
-		case 21: vibrato(realchan,(unsigned char) (info / 4)); break;		// fine vibrato
-		}
-	}
-
-	if(del) {		// speed compensation
-		del--;
-		return !songend;
-	}
-
-	// arrangement handling
-	pattnr = orders[ord];
-	if(pattnr == 0xff || ord > header.ordnum) {	// "--" end of song
-		songend = 1;				// set end-flag
-		ord = 0;
-		pattnr = orders[ord];
-		if(pattnr == 0xff)
-			return !songend;
-	}
-	if(pattnr == 0xfe) {		// "++" skip marker
-		ord++; pattnr = orders[ord];
-	}
-
-	// play row
-	row = crow;	// fill row cache
-	for(chan=0;chan<32;chan++) {
-		if(!(header.chanset[chan] & 128))		// resolve S3M -> AdLib channels
-			realchan = chnresolv[header.chanset[chan] & 127];
-		else
-			realchan = -1;		// channel disabled
-		if(realchan != -1) {	// channel playable?
-			// set channel values
-			donote = 0;
-			if(pattern[pattnr][row][chan].note < 14)
-				// tone portamento
-				if(pattern[pattnr][row][chan].command == 7 || pattern[pattnr][row][chan].command == 12) {
-					channel[realchan].nextfreq = notetable[pattern[pattnr][row][chan].note];
-					channel[realchan].nextoct = pattern[pattnr][row][chan].oct;
-				} else {											// normal note
-					channel[realchan].note = pattern[pattnr][row][chan].note;
-					channel[realchan].freq = notetable[pattern[pattnr][row][chan].note];
-					channel[realchan].oct = pattern[pattnr][row][chan].oct;
-					channel[realchan].key = 1;
-					donote = 1;
-				}
-			if(pattern[pattnr][row][chan].note == 14) {	// key off (is 14 here, cause note is only first 4 bits)
-				channel[realchan].key = 0;
-				setfreq(realchan);
-			}
-			if((channel[realchan].fx != 8 && channel[realchan].fx != 11) &&		// vibrato begins
-				(pattern[pattnr][row][chan].command == 8 || pattern[pattnr][row][chan].command == 11)) {
-				channel[realchan].nextfreq = channel[realchan].freq;
-				channel[realchan].nextoct = channel[realchan].oct;
-			}
-			if(pattern[pattnr][row][chan].note >= 14)
-				if((channel[realchan].fx == 8 || channel[realchan].fx == 11) &&	// vibrato ends
-					(pattern[pattnr][row][chan].command != 8 && pattern[pattnr][row][chan].command != 11)) {
-					channel[realchan].freq = channel[realchan].nextfreq;
-					channel[realchan].oct = channel[realchan].nextoct;
-					setfreq(realchan);
-				}
-			if(pattern[pattnr][row][chan].instrument) {	// set instrument
-				channel[realchan].inst = pattern[pattnr][row][chan].instrument - 1;
-				if(inst[channel[realchan].inst].volume < 64)
-					channel[realchan].vol = inst[channel[realchan].inst].volume;
-				else
-					channel[realchan].vol = 63;
-				if(pattern[pattnr][row][chan].command != 7)
-					donote = 1;
-			}
-			if(pattern[pattnr][row][chan].volume != 255)
-				if(pattern[pattnr][row][chan].volume < 64)	// set volume
-					channel[realchan].vol = pattern[pattnr][row][chan].volume;
-				else
-					channel[realchan].vol = 63;
-			channel[realchan].fx = pattern[pattnr][row][chan].command;	// set command
-			if(pattern[pattnr][row][chan].info)			// set infobyte
-				channel[realchan].info = pattern[pattnr][row][chan].info;
-
-      // some commands reset the infobyte memory
-      switch(channel[realchan].fx) {
-      case 1:
-      case 2:
-      case 3:
-      case 20:
-	channel[realchan].info = pattern[pattnr][row][chan].info;
-	break;
-      }
-
-			// play note
-			if(donote)
-				playnote(realchan);
-			if(pattern[pattnr][row][chan].volume != 255)	// set volume
-				setvolume(realchan);
-
-			// command handling (row dependant)
-			info = channel[realchan].info;	// fill infobyte cache
-			switch(channel[realchan].fx) {
-			case 1: speed = info; break;							// set speed
-			case 2: if(info <= ord) songend = 1; ord = info; crow = 0; pattbreak = 1; break;	// jump to order
-			case 3: if(!pattbreak) { crow = info; ord++; pattbreak = 1; } break;	// pattern break
-			case 4: if(info > 0xf0)										// fine volume down
-						if(channel[realchan].vol - (info & 0x0f) >= 0)
-							channel[realchan].vol -= info & 0x0f;
-						else
-							channel[realchan].vol = 0;
-					if((info & 0x0f) == 0x0f && info >= 0x1f)			// fine volume up
-						if(channel[realchan].vol + ((info & 0xf0) >> 4) <= 63)
-							channel[realchan].vol += (info & 0xf0) >> 4;
-						else
-							channel[realchan].vol = 63;
-					setvolume(realchan);
-					break;
-			case 5: if(info > 0xf0)	{									// fine slide down
-						slide_down(realchan,(unsigned char) (info & 0x0f));
-						setfreq(realchan);
-					}
-					if(info > 0xe0 && info < 0xf0) {					// extra fine slide down
-						slide_down(realchan,(unsigned char) ((info & 0x0f) / 4));
-						setfreq(realchan);
-					}
-					break;
-			case 6: if(info > 0xf0) {									// fine slide up
-						slide_up(realchan,(unsigned char) (info & 0x0f));
-						setfreq(realchan);
-					}
-					if(info > 0xe0 && info < 0xf0) {					// extra fine slide up
-						slide_up(realchan,(unsigned char) ((info & 0x0f) / 4));
-						setfreq(realchan);
-					}
-					break;
-			case 7:														// tone portamento
-			case 8:	if((channel[realchan].fx == 7 ||				// vibrato (remember info for dual commands)
-					 channel[realchan].fx == 8) && pattern[pattnr][row][chan].info)
-						channel[realchan].dualinfo = info;
-					break;
-			case 10: channel[realchan].trigger = 0; break;			// arpeggio (set trigger)
-			case 19: if(info == 0xb0)									// set loop start
-						loopstart = row;
-					 if(info > 0xb0 && info <= 0xbf)					// pattern loop
-						if(!loopcnt) {
-							loopcnt = info & 0x0f;
-							crow = loopstart;
-							pattbreak = 1;
-						} else
-							if(--loopcnt > 0) {
-								crow = loopstart;
-								pattbreak = 1;
-							}
-					 if((info & 0xf0) == 0xe0)							// patterndelay
-						 del = speed * (info & 0x0f) - 1;
-					 break;
-			case 20: tempo = info; break;							// set tempo
-			}
-		}
-	}
-
-	if(!del)
-    del = speed - 1;		// speed compensation
-	if(!pattbreak) {			// next row (only if no manual advance)
-		crow++;
-		if(crow > 63) {
-			crow = 0;
-			ord++;
-			loopstart = 0;
-		}
-	}
-
-	return !songend;		// still playing
-}
-
-void Cs3mPlayer::rewind(int subsong)
-{
-	// set basic variables
-	songend = 0; ord = 0; crow = 0; tempo = header.it;
-	speed = header.is; del = 0; loopstart = 0; loopcnt = 0;
-
-	memset(channel,0,sizeof(channel));
-
-	opl->init();				// reset OPL chip
-	opl->write(1,32);			// Go to ym3812 mode
-}
-
-std::string Cs3mPlayer::gettype()
-{
-	char filever[5];
-
-	switch(header.cwtv) {		// determine version number
-	case 0x1300: strcpy(filever,"3.00"); break;
-	case 0x1301: strcpy(filever,"3.01"); break;
-	case 0x1303: strcpy(filever,"3.03"); break;
-	case 0x1320: strcpy(filever,"3.20"); break;
-	default: strcpy(filever,"3.??");
-	}
-
-	return (std::string("Scream Tracker ") + filever);
-}
-
-float Cs3mPlayer::getrefresh()
-{
-	return (float) (tempo / 2.5);
-}
-
-/*** private methods *************************************/
-
-void Cs3mPlayer::load_header(binistream *f, s3mheader *h)
-{
-  int i;
-
-  f->readString(h->name, 28);
-  h->kennung = f->readInt(1); h->typ = f->readInt(1);
-  f->ignore(2);
-  h->ordnum = f->readInt(2); h->insnum = f->readInt(2);
-  h->patnum = f->readInt(2); h->flags = f->readInt(2);
-  h->cwtv = f->readInt(2); h->ffi = f->readInt(2);
-  f->readString(h->scrm, 4);
-  h->gv = f->readInt(1); h->is = f->readInt(1); h->it = f->readInt(1);
-  h->mv = f->readInt(1); h->uc = f->readInt(1); h->dp = f->readInt(1);
-  f->ignore(8);
-  h->special = f->readInt(2);
-  for(i = 0; i < 32; i++) h->chanset[i] = f->readInt(1);
-}
-
-void Cs3mPlayer::setvolume(unsigned char chan)
-{
-	unsigned char op = op_table[chan], insnr = channel[chan].inst;
-
-	opl->write(0x43 + op,(int)(63-((63-(inst[insnr].d03 & 63))/63.0)*channel[chan].vol) + (inst[insnr].d03 & 192));
-	if(inst[insnr].d0a & 1)
-		opl->write(0x40 + op,(int)(63-((63-(inst[insnr].d02 & 63))/63.0)*channel[chan].vol) + (inst[insnr].d02 & 192));
-}
-
-void Cs3mPlayer::setfreq(unsigned char chan)
-{
-	opl->write(0xa0 + chan, channel[chan].freq & 255);
-	if(channel[chan].key)
-		opl->write(0xb0 + chan, ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2) | 32);
-	else
-		opl->write(0xb0 + chan, ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2));
-}
-
-void Cs3mPlayer::playnote(unsigned char chan)
-{
-	unsigned char op = op_table[chan], insnr = channel[chan].inst;
-
-	opl->write(0xb0 + chan, 0);	// stop old note
-
-	// set instrument data
-	opl->write(0x20 + op, inst[insnr].d00);
-	opl->write(0x23 + op, inst[insnr].d01);
-	opl->write(0x40 + op, inst[insnr].d02);
-	opl->write(0x43 + op, inst[insnr].d03);
-	opl->write(0x60 + op, inst[insnr].d04);
-	opl->write(0x63 + op, inst[insnr].d05);
-	opl->write(0x80 + op, inst[insnr].d06);
-	opl->write(0x83 + op, inst[insnr].d07);
-	opl->write(0xe0 + op, inst[insnr].d08);
-	opl->write(0xe3 + op, inst[insnr].d09);
-	opl->write(0xc0 + chan, inst[insnr].d0a);
-
-	// set frequency & play
-	channel[chan].key = 1;
-	setfreq(chan);
-}
-
-void Cs3mPlayer::slide_down(unsigned char chan, unsigned char amount)
-{
-	if(channel[chan].freq - amount > 340)
-		channel[chan].freq -= amount;
-	else
-		if(channel[chan].oct > 0) {
-			channel[chan].oct--;
-			channel[chan].freq = 684;
-		} else
-			channel[chan].freq = 340;
-}
-
-void Cs3mPlayer::slide_up(unsigned char chan, unsigned char amount)
-{
-	if(channel[chan].freq + amount < 686)
-		channel[chan].freq += amount;
-	else
-		if(channel[chan].oct < 7) {
-			channel[chan].oct++;
-			channel[chan].freq = 341;
-		} else
-			channel[chan].freq = 686;
-}
-
-void Cs3mPlayer::vibrato(unsigned char chan, unsigned char info)
-{
-	unsigned char i,speed,depth;
-
-	speed = info >> 4;
-	depth = (info & 0x0f) / 2;
-
-	for(i=0;i<speed;i++) {
-		channel[chan].trigger++;
-		while(channel[chan].trigger >= 64)
-			channel[chan].trigger -= 64;
-		if(channel[chan].trigger >= 16 && channel[chan].trigger < 48)
-			slide_down(chan,(unsigned char) (vibratotab[channel[chan].trigger - 16] / (16-depth)));
-		if(channel[chan].trigger < 16)
-			slide_up(chan,(unsigned char) (vibratotab[channel[chan].trigger + 16] / (16-depth)));
-		if(channel[chan].trigger >= 48)
-			slide_up(chan,(unsigned char) (vibratotab[channel[chan].trigger - 48] / (16-depth)));
-	}
-	setfreq(chan);
-}
-
-void Cs3mPlayer::tone_portamento(unsigned char chan, unsigned char info)
-{
-	if(channel[chan].freq + (channel[chan].oct << 10) < channel[chan].nextfreq +
-		(channel[chan].nextoct << 10))
-		slide_up(chan,info);
-	if(channel[chan].freq + (channel[chan].oct << 10) > channel[chan].nextfreq +
-		(channel[chan].nextoct << 10))
-		slide_down(chan,info);
-	setfreq(chan);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/s3m.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,535 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * s3m.c - S3M Player by Simon Peter <dn.tlp@gmx.net>
+ *
+ * BUGS:
+ * Extra Fine Slides (EEx, FEx) & Fine Vibrato (Uxy) are inaccurate
+ */
+
+#include "s3m.h"
+
+const char Cs3mPlayer::chnresolv[] =	// S3M -> adlib channel conversion
+	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,-1,-1,-1,-1,-1,-1,-1};
+
+const unsigned short Cs3mPlayer::notetable[12] =		// S3M adlib note table
+			{340,363,385,408,432,458,485,514,544,577,611,647};
+
+const unsigned char Cs3mPlayer::vibratotab[32] =		// vibrato rate table
+			{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1};
+
+/*** public methods *************************************/
+
+CPlayer *Cs3mPlayer::factory(Copl *newopl)
+{
+  return new Cs3mPlayer(newopl);
+}
+
+Cs3mPlayer::Cs3mPlayer(Copl *newopl): CPlayer(newopl)
+{
+	int			i,j,k;
+
+	memset(pattern,255,sizeof(pattern));
+	memset(orders,255,sizeof(orders));
+
+	for(i=0;i<99;i++)		// setup pattern
+		for(j=0;j<64;j++)
+			for(k=0;k<32;k++) {
+				pattern[i][j][k].instrument = 0;
+				pattern[i][j][k].info = 0;
+			}
+}
+
+bool Cs3mPlayer::load(const std::string &filename, const CFileProvider &fp)
+{
+        binistream *f = fp.open(filename); if(!f) return false;
+	unsigned short	insptr[99],pattptr[99];
+	int		i,row;
+	unsigned char	bufval,bufval2;
+	unsigned short	ppatlen;
+	s3mheader	*checkhead;
+	bool		adlibins=false;
+
+	// file validation section
+	checkhead = new s3mheader;
+	load_header(f, checkhead);
+  if(checkhead->kennung != 0x1a || checkhead->typ != 16
+     || checkhead->insnum > 99) {
+		delete checkhead; fp.close(f); return false;
+	} else
+		if(strncmp(checkhead->scrm,"SCRM",4)) {
+			delete checkhead; fp.close(f); return false;
+		} else {	// is an adlib module?
+             	        f->seek(checkhead->ordnum, binio::Add);
+			for(i = 0; i < checkhead->insnum; i++)
+			  insptr[i] = f->readInt(2);
+			for(i=0;i<checkhead->insnum;i++) {
+				f->seek(insptr[i]*16);
+				if(f->readInt(1) >= 2) {
+					adlibins = true;
+					break;
+				}
+			}
+			delete checkhead;
+			if(!adlibins) { fp.close(f); return false; }
+		}
+
+	// load section
+	f->seek(0);	// rewind for load
+	load_header(f, &header);			// read header
+
+  // security check
+  if(header.ordnum > 256 || header.insnum > 99 || header.patnum > 99) {
+    fp.close(f);
+    return false;
+  }
+
+	for(i = 0; i < header.ordnum; i++) orders[i] = f->readInt(1);	// read orders
+	for(i = 0; i < header.insnum; i++) insptr[i] = f->readInt(2);	// instrument parapointers
+	for(i = 0; i < header.patnum; i++) pattptr[i] = f->readInt(2);	// pattern parapointers
+
+	for(i=0;i<header.insnum;i++) {	// load instruments
+		f->seek(insptr[i]*16);
+		inst[i].type = f->readInt(1);
+		f->readString(inst[i].filename, 15);
+		inst[i].d00 = f->readInt(1); inst[i].d01 = f->readInt(1);
+		inst[i].d02 = f->readInt(1); inst[i].d03 = f->readInt(1);
+		inst[i].d04 = f->readInt(1); inst[i].d05 = f->readInt(1);
+		inst[i].d06 = f->readInt(1); inst[i].d07 = f->readInt(1);
+		inst[i].d08 = f->readInt(1); inst[i].d09 = f->readInt(1);
+		inst[i].d0a = f->readInt(1); inst[i].d0b = f->readInt(1);
+		inst[i].volume = f->readInt(1); inst[i].dsk = f->readInt(1);
+		f->ignore(2);
+		inst[i].c2spd = f->readInt(4);
+		f->ignore(12);
+		f->readString(inst[i].name, 28);
+		f->readString(inst[i].scri, 4);
+	}
+
+	for(i=0;i<header.patnum;i++) {	// depack patterns
+		f->seek(pattptr[i]*16);
+		ppatlen = f->readInt(2);
+		unsigned long pattpos = f->pos();
+		for(row=0;(row<64) && (pattpos-pattptr[i]*16<=ppatlen);row++)
+			do {
+            		        bufval = f->readInt(1);
+				if(bufval & 32) {
+				        bufval2 = f->readInt(1);
+					pattern[i][row][bufval & 31].note = bufval2 & 15;
+					pattern[i][row][bufval & 31].oct = (bufval2 & 240) >> 4;
+					pattern[i][row][bufval & 31].instrument = f->readInt(1);
+				}
+				if(bufval & 64)
+				        pattern[i][row][bufval & 31].volume = f->readInt(1);
+				if(bufval & 128) {
+				        pattern[i][row][bufval & 31].command = f->readInt(1);
+					pattern[i][row][bufval & 31].info = f->readInt(1);
+				}
+			} while(bufval);
+	}
+
+	fp.close(f);
+	rewind(0);
+	return true;		// done
+}
+
+bool Cs3mPlayer::update()
+{
+	unsigned char	pattbreak=0,donote;		// remember vars
+	unsigned char	pattnr,chan,row,info;	// cache vars
+	signed char		realchan;
+
+	// effect handling (timer dependant)
+	for(realchan=0; realchan<9; realchan++) {
+		info = channel[realchan].info;	// fill infobyte cache
+		switch(channel[realchan].fx) {
+		case 11:
+		case 12: if(channel[realchan].fx == 11)								// dual command: H00 and Dxy
+					 vibrato(realchan,channel[realchan].dualinfo);
+				 else															// dual command: G00 and Dxy
+					 tone_portamento(realchan,channel[realchan].dualinfo);
+		case 4: if(info <= 0x0f)												// volume slide down
+					if(channel[realchan].vol - info >= 0)
+						channel[realchan].vol -= info;
+					else
+						channel[realchan].vol = 0;
+				if((info & 0x0f) == 0)											// volume slide up
+					if(channel[realchan].vol + (info >> 4) <= 63)
+						channel[realchan].vol += info >> 4;
+					else
+						channel[realchan].vol = 63;
+				setvolume(realchan);
+				break;
+		case 5: if(info == 0xf0 || info <= 0xe0) {								// slide down
+					slide_down(realchan,info);
+					setfreq(realchan);
+				}
+				break;
+		case 6: if(info == 0xf0 || info <= 0xe0) {								// slide up
+					slide_up(realchan,info);
+					setfreq(realchan);
+				}
+				break;
+		case 7: tone_portamento(realchan,channel[realchan].dualinfo); break;	// tone portamento
+		case 8: vibrato(realchan,channel[realchan].dualinfo); break;		// vibrato
+		case 10: channel[realchan].nextfreq = channel[realchan].freq;	// arpeggio
+				 channel[realchan].nextoct = channel[realchan].oct;
+				 switch(channel[realchan].trigger) {
+				 case 0: channel[realchan].freq = notetable[channel[realchan].note]; break;
+				 case 1: if(channel[realchan].note + ((info & 0xf0) >> 4) < 12)
+							 channel[realchan].freq = notetable[channel[realchan].note + ((info & 0xf0) >> 4)];
+						 else {
+							 channel[realchan].freq = notetable[channel[realchan].note + ((info & 0xf0) >> 4) - 12];
+							 channel[realchan].oct++;
+						 }
+						 break;
+				 case 2: if(channel[realchan].note + (info & 0x0f) < 12)
+							 channel[realchan].freq = notetable[channel[realchan].note + (info & 0x0f)];
+						 else {
+							 channel[realchan].freq = notetable[channel[realchan].note + (info & 0x0f) - 12];
+							 channel[realchan].oct++;
+						 }
+						 break;
+				 }
+				 if(channel[realchan].trigger < 2)
+					 channel[realchan].trigger++;
+				 else
+					 channel[realchan].trigger = 0;
+				 setfreq(realchan);
+				 channel[realchan].freq = channel[realchan].nextfreq;
+				 channel[realchan].oct = channel[realchan].nextoct;
+				 break;
+		case 21: vibrato(realchan,(unsigned char) (info / 4)); break;		// fine vibrato
+		}
+	}
+
+	if(del) {		// speed compensation
+		del--;
+		return !songend;
+	}
+
+	// arrangement handling
+	pattnr = orders[ord];
+	if(pattnr == 0xff || ord > header.ordnum) {	// "--" end of song
+		songend = 1;				// set end-flag
+		ord = 0;
+		pattnr = orders[ord];
+		if(pattnr == 0xff)
+			return !songend;
+	}
+	if(pattnr == 0xfe) {		// "++" skip marker
+		ord++; pattnr = orders[ord];
+	}
+
+	// play row
+	row = crow;	// fill row cache
+	for(chan=0;chan<32;chan++) {
+		if(!(header.chanset[chan] & 128))		// resolve S3M -> AdLib channels
+			realchan = chnresolv[header.chanset[chan] & 127];
+		else
+			realchan = -1;		// channel disabled
+		if(realchan != -1) {	// channel playable?
+			// set channel values
+			donote = 0;
+			if(pattern[pattnr][row][chan].note < 14)
+				// tone portamento
+				if(pattern[pattnr][row][chan].command == 7 || pattern[pattnr][row][chan].command == 12) {
+					channel[realchan].nextfreq = notetable[pattern[pattnr][row][chan].note];
+					channel[realchan].nextoct = pattern[pattnr][row][chan].oct;
+				} else {											// normal note
+					channel[realchan].note = pattern[pattnr][row][chan].note;
+					channel[realchan].freq = notetable[pattern[pattnr][row][chan].note];
+					channel[realchan].oct = pattern[pattnr][row][chan].oct;
+					channel[realchan].key = 1;
+					donote = 1;
+				}
+			if(pattern[pattnr][row][chan].note == 14) {	// key off (is 14 here, cause note is only first 4 bits)
+				channel[realchan].key = 0;
+				setfreq(realchan);
+			}
+			if((channel[realchan].fx != 8 && channel[realchan].fx != 11) &&		// vibrato begins
+				(pattern[pattnr][row][chan].command == 8 || pattern[pattnr][row][chan].command == 11)) {
+				channel[realchan].nextfreq = channel[realchan].freq;
+				channel[realchan].nextoct = channel[realchan].oct;
+			}
+			if(pattern[pattnr][row][chan].note >= 14)
+				if((channel[realchan].fx == 8 || channel[realchan].fx == 11) &&	// vibrato ends
+					(pattern[pattnr][row][chan].command != 8 && pattern[pattnr][row][chan].command != 11)) {
+					channel[realchan].freq = channel[realchan].nextfreq;
+					channel[realchan].oct = channel[realchan].nextoct;
+					setfreq(realchan);
+				}
+			if(pattern[pattnr][row][chan].instrument) {	// set instrument
+				channel[realchan].inst = pattern[pattnr][row][chan].instrument - 1;
+				if(inst[channel[realchan].inst].volume < 64)
+					channel[realchan].vol = inst[channel[realchan].inst].volume;
+				else
+					channel[realchan].vol = 63;
+				if(pattern[pattnr][row][chan].command != 7)
+					donote = 1;
+			}
+			if(pattern[pattnr][row][chan].volume != 255)
+				if(pattern[pattnr][row][chan].volume < 64)	// set volume
+					channel[realchan].vol = pattern[pattnr][row][chan].volume;
+				else
+					channel[realchan].vol = 63;
+			channel[realchan].fx = pattern[pattnr][row][chan].command;	// set command
+			if(pattern[pattnr][row][chan].info)			// set infobyte
+				channel[realchan].info = pattern[pattnr][row][chan].info;
+
+      // some commands reset the infobyte memory
+      switch(channel[realchan].fx) {
+      case 1:
+      case 2:
+      case 3:
+      case 20:
+	channel[realchan].info = pattern[pattnr][row][chan].info;
+	break;
+      }
+
+			// play note
+			if(donote)
+				playnote(realchan);
+			if(pattern[pattnr][row][chan].volume != 255)	// set volume
+				setvolume(realchan);
+
+			// command handling (row dependant)
+			info = channel[realchan].info;	// fill infobyte cache
+			switch(channel[realchan].fx) {
+			case 1: speed = info; break;							// set speed
+			case 2: if(info <= ord) songend = 1; ord = info; crow = 0; pattbreak = 1; break;	// jump to order
+			case 3: if(!pattbreak) { crow = info; ord++; pattbreak = 1; } break;	// pattern break
+			case 4: if(info > 0xf0)										// fine volume down
+						if(channel[realchan].vol - (info & 0x0f) >= 0)
+							channel[realchan].vol -= info & 0x0f;
+						else
+							channel[realchan].vol = 0;
+					if((info & 0x0f) == 0x0f && info >= 0x1f)			// fine volume up
+						if(channel[realchan].vol + ((info & 0xf0) >> 4) <= 63)
+							channel[realchan].vol += (info & 0xf0) >> 4;
+						else
+							channel[realchan].vol = 63;
+					setvolume(realchan);
+					break;
+			case 5: if(info > 0xf0)	{									// fine slide down
+						slide_down(realchan,(unsigned char) (info & 0x0f));
+						setfreq(realchan);
+					}
+					if(info > 0xe0 && info < 0xf0) {					// extra fine slide down
+						slide_down(realchan,(unsigned char) ((info & 0x0f) / 4));
+						setfreq(realchan);
+					}
+					break;
+			case 6: if(info > 0xf0) {									// fine slide up
+						slide_up(realchan,(unsigned char) (info & 0x0f));
+						setfreq(realchan);
+					}
+					if(info > 0xe0 && info < 0xf0) {					// extra fine slide up
+						slide_up(realchan,(unsigned char) ((info & 0x0f) / 4));
+						setfreq(realchan);
+					}
+					break;
+			case 7:														// tone portamento
+			case 8:	if((channel[realchan].fx == 7 ||				// vibrato (remember info for dual commands)
+					 channel[realchan].fx == 8) && pattern[pattnr][row][chan].info)
+						channel[realchan].dualinfo = info;
+					break;
+			case 10: channel[realchan].trigger = 0; break;			// arpeggio (set trigger)
+			case 19: if(info == 0xb0)									// set loop start
+						loopstart = row;
+					 if(info > 0xb0 && info <= 0xbf)					// pattern loop
+						if(!loopcnt) {
+							loopcnt = info & 0x0f;
+							crow = loopstart;
+							pattbreak = 1;
+						} else
+							if(--loopcnt > 0) {
+								crow = loopstart;
+								pattbreak = 1;
+							}
+					 if((info & 0xf0) == 0xe0)							// patterndelay
+						 del = speed * (info & 0x0f) - 1;
+					 break;
+			case 20: tempo = info; break;							// set tempo
+			}
+		}
+	}
+
+	if(!del)
+    del = speed - 1;		// speed compensation
+	if(!pattbreak) {			// next row (only if no manual advance)
+		crow++;
+		if(crow > 63) {
+			crow = 0;
+			ord++;
+			loopstart = 0;
+		}
+	}
+
+	return !songend;		// still playing
+}
+
+void Cs3mPlayer::rewind(int subsong)
+{
+	// set basic variables
+	songend = 0; ord = 0; crow = 0; tempo = header.it;
+	speed = header.is; del = 0; loopstart = 0; loopcnt = 0;
+
+	memset(channel,0,sizeof(channel));
+
+	opl->init();				// reset OPL chip
+	opl->write(1,32);			// Go to ym3812 mode
+}
+
+std::string Cs3mPlayer::gettype()
+{
+	char filever[5];
+
+	switch(header.cwtv) {		// determine version number
+	case 0x1300: strcpy(filever,"3.00"); break;
+	case 0x1301: strcpy(filever,"3.01"); break;
+	case 0x1303: strcpy(filever,"3.03"); break;
+	case 0x1320: strcpy(filever,"3.20"); break;
+	default: strcpy(filever,"3.??");
+	}
+
+	return (std::string("Scream Tracker ") + filever);
+}
+
+float Cs3mPlayer::getrefresh()
+{
+	return (float) (tempo / 2.5);
+}
+
+/*** private methods *************************************/
+
+void Cs3mPlayer::load_header(binistream *f, s3mheader *h)
+{
+  int i;
+
+  f->readString(h->name, 28);
+  h->kennung = f->readInt(1); h->typ = f->readInt(1);
+  f->ignore(2);
+  h->ordnum = f->readInt(2); h->insnum = f->readInt(2);
+  h->patnum = f->readInt(2); h->flags = f->readInt(2);
+  h->cwtv = f->readInt(2); h->ffi = f->readInt(2);
+  f->readString(h->scrm, 4);
+  h->gv = f->readInt(1); h->is = f->readInt(1); h->it = f->readInt(1);
+  h->mv = f->readInt(1); h->uc = f->readInt(1); h->dp = f->readInt(1);
+  f->ignore(8);
+  h->special = f->readInt(2);
+  for(i = 0; i < 32; i++) h->chanset[i] = f->readInt(1);
+}
+
+void Cs3mPlayer::setvolume(unsigned char chan)
+{
+	unsigned char op = op_table[chan], insnr = channel[chan].inst;
+
+	opl->write(0x43 + op,(int)(63-((63-(inst[insnr].d03 & 63))/63.0)*channel[chan].vol) + (inst[insnr].d03 & 192));
+	if(inst[insnr].d0a & 1)
+		opl->write(0x40 + op,(int)(63-((63-(inst[insnr].d02 & 63))/63.0)*channel[chan].vol) + (inst[insnr].d02 & 192));
+}
+
+void Cs3mPlayer::setfreq(unsigned char chan)
+{
+	opl->write(0xa0 + chan, channel[chan].freq & 255);
+	if(channel[chan].key)
+		opl->write(0xb0 + chan, ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2) | 32);
+	else
+		opl->write(0xb0 + chan, ((channel[chan].freq & 768) >> 8) + (channel[chan].oct << 2));
+}
+
+void Cs3mPlayer::playnote(unsigned char chan)
+{
+	unsigned char op = op_table[chan], insnr = channel[chan].inst;
+
+	opl->write(0xb0 + chan, 0);	// stop old note
+
+	// set instrument data
+	opl->write(0x20 + op, inst[insnr].d00);
+	opl->write(0x23 + op, inst[insnr].d01);
+	opl->write(0x40 + op, inst[insnr].d02);
+	opl->write(0x43 + op, inst[insnr].d03);
+	opl->write(0x60 + op, inst[insnr].d04);
+	opl->write(0x63 + op, inst[insnr].d05);
+	opl->write(0x80 + op, inst[insnr].d06);
+	opl->write(0x83 + op, inst[insnr].d07);
+	opl->write(0xe0 + op, inst[insnr].d08);
+	opl->write(0xe3 + op, inst[insnr].d09);
+	opl->write(0xc0 + chan, inst[insnr].d0a);
+
+	// set frequency & play
+	channel[chan].key = 1;
+	setfreq(chan);
+}
+
+void Cs3mPlayer::slide_down(unsigned char chan, unsigned char amount)
+{
+	if(channel[chan].freq - amount > 340)
+		channel[chan].freq -= amount;
+	else
+		if(channel[chan].oct > 0) {
+			channel[chan].oct--;
+			channel[chan].freq = 684;
+		} else
+			channel[chan].freq = 340;
+}
+
+void Cs3mPlayer::slide_up(unsigned char chan, unsigned char amount)
+{
+	if(channel[chan].freq + amount < 686)
+		channel[chan].freq += amount;
+	else
+		if(channel[chan].oct < 7) {
+			channel[chan].oct++;
+			channel[chan].freq = 341;
+		} else
+			channel[chan].freq = 686;
+}
+
+void Cs3mPlayer::vibrato(unsigned char chan, unsigned char info)
+{
+	unsigned char i,speed,depth;
+
+	speed = info >> 4;
+	depth = (info & 0x0f) / 2;
+
+	for(i=0;i<speed;i++) {
+		channel[chan].trigger++;
+		while(channel[chan].trigger >= 64)
+			channel[chan].trigger -= 64;
+		if(channel[chan].trigger >= 16 && channel[chan].trigger < 48)
+			slide_down(chan,(unsigned char) (vibratotab[channel[chan].trigger - 16] / (16-depth)));
+		if(channel[chan].trigger < 16)
+			slide_up(chan,(unsigned char) (vibratotab[channel[chan].trigger + 16] / (16-depth)));
+		if(channel[chan].trigger >= 48)
+			slide_up(chan,(unsigned char) (vibratotab[channel[chan].trigger - 48] / (16-depth)));
+	}
+	setfreq(chan);
+}
+
+void Cs3mPlayer::tone_portamento(unsigned char chan, unsigned char info)
+{
+	if(channel[chan].freq + (channel[chan].oct << 10) < channel[chan].nextfreq +
+		(channel[chan].nextoct << 10))
+		slide_up(chan,info);
+	if(channel[chan].freq + (channel[chan].oct << 10) > channel[chan].nextfreq +
+		(channel[chan].nextoct << 10))
+		slide_down(chan,info);
+	setfreq(chan);
+}
--- a/Plugins/Input/adplug/core/sa2.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,263 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * sa2.cpp - SAdT2 Loader by Simon Peter <dn.tlp@gmx.net>
- *           SAdT Loader by Mamiya <mamiya@users.sourceforge.net>
- */
-
-#include <stdio.h>
-
-#include "sa2.h"
-#include "debug.h"
-
-CPlayer *Csa2Loader::factory(Copl *newopl)
-{
-  return new Csa2Loader(newopl);
-}
-
-bool Csa2Loader::load(const std::string &filename, const CFileProvider &fp)
-{
-        binistream *f = fp.open(filename); if(!f) return false;
-	struct {
-		unsigned char data[11],arpstart,arpspeed,arppos,arpspdcnt;
-	} insts;
-	unsigned char buf;
-	int i,j, k, notedis = 0;
-	const unsigned char convfx[16] = {0,1,2,3,4,5,6,255,8,255,10,11,12,13,255,15};
-	unsigned char sat_type;
-	enum SAT_TYPE {
-		HAS_ARPEGIOLIST = (1 << 7),
-		HAS_V7PATTERNS = (1 << 6),
-		HAS_ACTIVECHANNELS = (1 << 5),
-		HAS_TRACKORDER = (1 << 4),
-		HAS_ARPEGIO = (1 << 3),
-		HAS_OLDBPM = (1 << 2),
-		HAS_OLDPATTERNS = (1 << 1),
-		HAS_UNKNOWN127 = (1 << 0)
-	};
-
-	// read header
-	f->readString(header.sadt, 4);
-	header.version = f->readInt(1);
-
-	// file validation section
-	if(strncmp(header.sadt,"SAdT",4)) { fp.close(f); return false; }
-	switch(header.version) {
-	case 1:
-		notedis = +0x18;
-		sat_type = HAS_UNKNOWN127 | HAS_OLDPATTERNS | HAS_OLDBPM;
-		break;
-	case 2:
-		notedis = +0x18;
-		sat_type = HAS_OLDPATTERNS | HAS_OLDBPM;
-		break;
-	case 3:
-		notedis = +0x0c;
-		sat_type = HAS_OLDPATTERNS | HAS_OLDBPM;
-		break;
-	case 4:
-		notedis = +0x0c;
-		sat_type = HAS_ARPEGIO | HAS_OLDPATTERNS | HAS_OLDBPM;
-		break;
-	case 5:
-		notedis = +0x0c;
-		sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_OLDPATTERNS | HAS_OLDBPM;
-		break;
-	case 6:
-		sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_OLDPATTERNS | HAS_OLDBPM;
-		break;
-	case 7:
-		sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_V7PATTERNS;
-		break;
-	case 8:
-		sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_TRACKORDER;
-		break;
-	case 9:
-		sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_TRACKORDER | HAS_ACTIVECHANNELS;
-		break;
-	default:	/* unknown */
-	        fp.close(f);
-		return false;
-	}
-
-	// load section
-	// instruments
-	for(i = 0; i < 31; i++) {
-		if(sat_type & HAS_ARPEGIO) {
-		        for(j = 0; j < 11; j++) insts.data[j] = f->readInt(1);
-			insts.arpstart = f->readInt(1);
-			insts.arpspeed = f->readInt(1);
-			insts.arppos = f->readInt(1);
-			insts.arpspdcnt = f->readInt(1);
-			inst[i].arpstart = insts.arpstart;
-			inst[i].arpspeed = insts.arpspeed;
-			inst[i].arppos = insts.arppos;
-			inst[i].arpspdcnt = insts.arpspdcnt;
-		} else {
-		        for(j = 0; j < 11; j++) insts.data[j] = f->readInt(1);
-			inst[i].arpstart = 0;
-			inst[i].arpspeed = 0;
-			inst[i].arppos = 0;
-			inst[i].arpspdcnt = 0;
-		}
-		for(j=0;j<11;j++)
-			inst[i].data[j] = insts.data[j];
-		inst[i].misc = 0;
-		inst[i].slide = 0;
-	}
-
-	// instrument names
-	for(i = 0; i < 29; i++) f->readString(instname[i], 17);
-
-	f->ignore(3);		// dummy bytes
-	for(i = 0; i < 128; i++) order[i] = f->readInt(1);	// pattern orders
-	if(sat_type & HAS_UNKNOWN127) f->ignore(127);
-
-	// infos
-	nop = f->readInt(2); length = f->readInt(1); restartpos = f->readInt(1);
-
-	// bpm
-	bpm = f->readInt(2);
-	if(sat_type & HAS_OLDBPM) {
-		bpm = bpm * 125 / 50;		// cps -> bpm
-	}
-
-	if(sat_type & HAS_ARPEGIOLIST) {
-	  init_specialarp();
-	  for(i = 0; i < 256; i++) arplist[i] = f->readInt(1);	// arpeggio list
-	  for(i = 0; i < 256; i++) arpcmd[i] = f->readInt(1);	// arpeggio commands
-	}
-
-	for(i=0;i<64;i++) {				// track orders
-	  for(j=0;j<9;j++) {
-	    if(sat_type & HAS_TRACKORDER)
-	      trackord[i][j] = f->readInt(1);
-	    else
-	      {
-		trackord[i][j] = i * 9 + j;
-	      }
-	  }
-	}
-
-	if(sat_type & HAS_ACTIVECHANNELS)
-	        activechan = f->readInt(2);		// active channels
-	else
-		activechan = 0xffff;
-
-        AdPlug_LogWrite("Csa2Loader::load(\"%s\"): sat_type = %x, nop = %d, "
-		 "length = %d, restartpos = %d, activechan = %x, bpm = %d\n",
-		 filename.c_str(), sat_type, nop, length, restartpos, activechan, bpm);
-
-	// track data
-	if(sat_type & HAS_OLDPATTERNS) {
-		i = 0;
-		while(!f->ateof()) {
-			for(j=0;j<64;j++) {
-				for(k=0;k<9;k++) {
-					buf = f->readInt(1);
-					tracks[i+k][j].note = buf ? (buf + notedis) : 0;
-					tracks[i+k][j].inst = f->readInt(1);
-					tracks[i+k][j].command = convfx[f->readInt(1) & 0xf];
-					tracks[i+k][j].param1 = f->readInt(1);
-					tracks[i+k][j].param2 = f->readInt(1);
-				}
-			}
-			i+=9;
-		}
-	} else
-	  if(sat_type & HAS_V7PATTERNS) {
-		i = 0;
-		while(!f->ateof()) {
-			for(j=0;j<64;j++) {
-				for(k=0;k<9;k++) {
-					buf = f->readInt(1);
-					tracks[i+k][j].note = buf >> 1;
-					tracks[i+k][j].inst = (buf & 1) << 4;
-					buf = f->readInt(1);
-					tracks[i+k][j].inst += buf >> 4;
-					tracks[i+k][j].command = convfx[buf & 0x0f];
-					buf = f->readInt(1);
-					tracks[i+k][j].param1 = buf >> 4;
-					tracks[i+k][j].param2 = buf & 0x0f;
-				}
-			}
-			i+=9;
-		}
-	  } else {
-		i = 0;
-		while(!f->ateof()) {
-			for(j=0;j<64;j++) {
-				buf = f->readInt(1);
-				tracks[i][j].note = buf >> 1;
-				tracks[i][j].inst = (buf & 1) << 4;
-				buf = f->readInt(1);
-				tracks[i][j].inst += buf >> 4;
-				tracks[i][j].command = convfx[buf & 0x0f];
-				buf = f->readInt(1);
-				tracks[i][j].param1 = buf >> 4;
-				tracks[i][j].param2 = buf & 0x0f;
-			}
-			i++;
-		}
-	  }
-	fp.close(f);
-
-	// fix instrument names
-	for(i=0;i<29;i++)
-		for(j=0;j<17;j++)
-			if(!instname[i][j])
-				instname[i][j] = ' ';
-
-	rewind(0);		// rewind module
-	return true;
-}
-
-std::string Csa2Loader::gettype()
-{
-	char tmpstr[40];
-
-	sprintf(tmpstr,"Surprise! Adlib Tracker 2 (version %d)",header.version);
-	return std::string(tmpstr);
-}
-
-std::string Csa2Loader::gettitle()
-{
-	char bufinst[29*17],buf[18];
-	int i,ptr;
-
-	// parse instrument names for song name
-	memset(bufinst,'\0',29*17);
-	for(i=0;i<29;i++) {
-		buf[16] = ' '; buf[17] = '\0';
-		memcpy(buf,instname[i]+1,16);
-		for(ptr=16;ptr>0;ptr--)
-			if(buf[ptr] == ' ')
-				buf[ptr] = '\0';
-			else {
-				if(ptr<16)
-					buf[ptr+1] = ' ';
-				break;
-			}
-		strcat(bufinst,buf);
-	}
-
-	if(strchr(bufinst,'"'))
-		return std::string(bufinst,strchr(bufinst,'"')-bufinst+1,strrchr(bufinst,'"')-strchr(bufinst,'"')-1);
-	else
-		return std::string();
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/sa2.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,263 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * sa2.cpp - SAdT2 Loader by Simon Peter <dn.tlp@gmx.net>
+ *           SAdT Loader by Mamiya <mamiya@users.sourceforge.net>
+ */
+
+#include <stdio.h>
+
+#include "sa2.h"
+#include "debug.h"
+
+CPlayer *Csa2Loader::factory(Copl *newopl)
+{
+  return new Csa2Loader(newopl);
+}
+
+bool Csa2Loader::load(const std::string &filename, const CFileProvider &fp)
+{
+        binistream *f = fp.open(filename); if(!f) return false;
+	struct {
+		unsigned char data[11],arpstart,arpspeed,arppos,arpspdcnt;
+	} insts;
+	unsigned char buf;
+	int i,j, k, notedis = 0;
+	const unsigned char convfx[16] = {0,1,2,3,4,5,6,255,8,255,10,11,12,13,255,15};
+	unsigned char sat_type;
+	enum SAT_TYPE {
+		HAS_ARPEGIOLIST = (1 << 7),
+		HAS_V7PATTERNS = (1 << 6),
+		HAS_ACTIVECHANNELS = (1 << 5),
+		HAS_TRACKORDER = (1 << 4),
+		HAS_ARPEGIO = (1 << 3),
+		HAS_OLDBPM = (1 << 2),
+		HAS_OLDPATTERNS = (1 << 1),
+		HAS_UNKNOWN127 = (1 << 0)
+	};
+
+	// read header
+	f->readString(header.sadt, 4);
+	header.version = f->readInt(1);
+
+	// file validation section
+	if(strncmp(header.sadt,"SAdT",4)) { fp.close(f); return false; }
+	switch(header.version) {
+	case 1:
+		notedis = +0x18;
+		sat_type = HAS_UNKNOWN127 | HAS_OLDPATTERNS | HAS_OLDBPM;
+		break;
+	case 2:
+		notedis = +0x18;
+		sat_type = HAS_OLDPATTERNS | HAS_OLDBPM;
+		break;
+	case 3:
+		notedis = +0x0c;
+		sat_type = HAS_OLDPATTERNS | HAS_OLDBPM;
+		break;
+	case 4:
+		notedis = +0x0c;
+		sat_type = HAS_ARPEGIO | HAS_OLDPATTERNS | HAS_OLDBPM;
+		break;
+	case 5:
+		notedis = +0x0c;
+		sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_OLDPATTERNS | HAS_OLDBPM;
+		break;
+	case 6:
+		sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_OLDPATTERNS | HAS_OLDBPM;
+		break;
+	case 7:
+		sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_V7PATTERNS;
+		break;
+	case 8:
+		sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_TRACKORDER;
+		break;
+	case 9:
+		sat_type = HAS_ARPEGIO | HAS_ARPEGIOLIST | HAS_TRACKORDER | HAS_ACTIVECHANNELS;
+		break;
+	default:	/* unknown */
+	        fp.close(f);
+		return false;
+	}
+
+	// load section
+	// instruments
+	for(i = 0; i < 31; i++) {
+		if(sat_type & HAS_ARPEGIO) {
+		        for(j = 0; j < 11; j++) insts.data[j] = f->readInt(1);
+			insts.arpstart = f->readInt(1);
+			insts.arpspeed = f->readInt(1);
+			insts.arppos = f->readInt(1);
+			insts.arpspdcnt = f->readInt(1);
+			inst[i].arpstart = insts.arpstart;
+			inst[i].arpspeed = insts.arpspeed;
+			inst[i].arppos = insts.arppos;
+			inst[i].arpspdcnt = insts.arpspdcnt;
+		} else {
+		        for(j = 0; j < 11; j++) insts.data[j] = f->readInt(1);
+			inst[i].arpstart = 0;
+			inst[i].arpspeed = 0;
+			inst[i].arppos = 0;
+			inst[i].arpspdcnt = 0;
+		}
+		for(j=0;j<11;j++)
+			inst[i].data[j] = insts.data[j];
+		inst[i].misc = 0;
+		inst[i].slide = 0;
+	}
+
+	// instrument names
+	for(i = 0; i < 29; i++) f->readString(instname[i], 17);
+
+	f->ignore(3);		// dummy bytes
+	for(i = 0; i < 128; i++) order[i] = f->readInt(1);	// pattern orders
+	if(sat_type & HAS_UNKNOWN127) f->ignore(127);
+
+	// infos
+	nop = f->readInt(2); length = f->readInt(1); restartpos = f->readInt(1);
+
+	// bpm
+	bpm = f->readInt(2);
+	if(sat_type & HAS_OLDBPM) {
+		bpm = bpm * 125 / 50;		// cps -> bpm
+	}
+
+	if(sat_type & HAS_ARPEGIOLIST) {
+	  init_specialarp();
+	  for(i = 0; i < 256; i++) arplist[i] = f->readInt(1);	// arpeggio list
+	  for(i = 0; i < 256; i++) arpcmd[i] = f->readInt(1);	// arpeggio commands
+	}
+
+	for(i=0;i<64;i++) {				// track orders
+	  for(j=0;j<9;j++) {
+	    if(sat_type & HAS_TRACKORDER)
+	      trackord[i][j] = f->readInt(1);
+	    else
+	      {
+		trackord[i][j] = i * 9 + j;
+	      }
+	  }
+	}
+
+	if(sat_type & HAS_ACTIVECHANNELS)
+	        activechan = f->readInt(2);		// active channels
+	else
+		activechan = 0xffff;
+
+        AdPlug_LogWrite("Csa2Loader::load(\"%s\"): sat_type = %x, nop = %d, "
+		 "length = %d, restartpos = %d, activechan = %x, bpm = %d\n",
+		 filename.c_str(), sat_type, nop, length, restartpos, activechan, bpm);
+
+	// track data
+	if(sat_type & HAS_OLDPATTERNS) {
+		i = 0;
+		while(!f->ateof()) {
+			for(j=0;j<64;j++) {
+				for(k=0;k<9;k++) {
+					buf = f->readInt(1);
+					tracks[i+k][j].note = buf ? (buf + notedis) : 0;
+					tracks[i+k][j].inst = f->readInt(1);
+					tracks[i+k][j].command = convfx[f->readInt(1) & 0xf];
+					tracks[i+k][j].param1 = f->readInt(1);
+					tracks[i+k][j].param2 = f->readInt(1);
+				}
+			}
+			i+=9;
+		}
+	} else
+	  if(sat_type & HAS_V7PATTERNS) {
+		i = 0;
+		while(!f->ateof()) {
+			for(j=0;j<64;j++) {
+				for(k=0;k<9;k++) {
+					buf = f->readInt(1);
+					tracks[i+k][j].note = buf >> 1;
+					tracks[i+k][j].inst = (buf & 1) << 4;
+					buf = f->readInt(1);
+					tracks[i+k][j].inst += buf >> 4;
+					tracks[i+k][j].command = convfx[buf & 0x0f];
+					buf = f->readInt(1);
+					tracks[i+k][j].param1 = buf >> 4;
+					tracks[i+k][j].param2 = buf & 0x0f;
+				}
+			}
+			i+=9;
+		}
+	  } else {
+		i = 0;
+		while(!f->ateof()) {
+			for(j=0;j<64;j++) {
+				buf = f->readInt(1);
+				tracks[i][j].note = buf >> 1;
+				tracks[i][j].inst = (buf & 1) << 4;
+				buf = f->readInt(1);
+				tracks[i][j].inst += buf >> 4;
+				tracks[i][j].command = convfx[buf & 0x0f];
+				buf = f->readInt(1);
+				tracks[i][j].param1 = buf >> 4;
+				tracks[i][j].param2 = buf & 0x0f;
+			}
+			i++;
+		}
+	  }
+	fp.close(f);
+
+	// fix instrument names
+	for(i=0;i<29;i++)
+		for(j=0;j<17;j++)
+			if(!instname[i][j])
+				instname[i][j] = ' ';
+
+	rewind(0);		// rewind module
+	return true;
+}
+
+std::string Csa2Loader::gettype()
+{
+	char tmpstr[40];
+
+	sprintf(tmpstr,"Surprise! Adlib Tracker 2 (version %d)",header.version);
+	return std::string(tmpstr);
+}
+
+std::string Csa2Loader::gettitle()
+{
+	char bufinst[29*17],buf[18];
+	int i,ptr;
+
+	// parse instrument names for song name
+	memset(bufinst,'\0',29*17);
+	for(i=0;i<29;i++) {
+		buf[16] = ' '; buf[17] = '\0';
+		memcpy(buf,instname[i]+1,16);
+		for(ptr=16;ptr>0;ptr--)
+			if(buf[ptr] == ' ')
+				buf[ptr] = '\0';
+			else {
+				if(ptr<16)
+					buf[ptr+1] = ' ';
+				break;
+			}
+		strcat(bufinst,buf);
+	}
+
+	if(strchr(bufinst,'"'))
+		return std::string(bufinst,strchr(bufinst,'"')-bufinst+1,strrchr(bufinst,'"')-strchr(bufinst,'"')-1);
+	else
+		return std::string();
+}
--- a/Plugins/Input/adplug/core/sng.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * sng.cpp - SNG Player by Simon Peter <dn.tlp@gmx.net>
- */
-
-#include "sng.h"
-
-CPlayer *CsngPlayer::factory(Copl *newopl)
-{
-  return new CsngPlayer(newopl);
-}
-
-bool CsngPlayer::load(const std::string &filename, const CFileProvider &fp)
-{
-  binistream *f = fp.open(filename); if(!f) return false;
-  int i;
-
-  // load header
-  f->readString(header.id, 4);
-  header.length = f->readInt(2); header.start = f->readInt(2);
-  header.loop = f->readInt(2); header.delay = f->readInt(1);
-  header.compressed = f->readInt(1) ? true : false;
-
-  // file validation section
-  if(strncmp(header.id,"ObsM",4)) { fp.close(f); return false; }
-
-  // load section
-  header.length /= 2; header.start /= 2; header.loop /= 2;
-  data = new Sdata [header.length];
-  for(i = 0; i < header.length; i++) {
-    data[i].val = f->readInt(1);
-    data[i].reg = f->readInt(1);
-  }
-
-  rewind(0);
-  fp.close(f);
-  return true;
-}
-
-bool CsngPlayer::update()
-{
-  if(header.compressed && del) {
-    del--;
-    return !songend;
-  }
-
-  while(data[pos].reg) {
-    opl->write(data[pos].reg, data[pos].val);
-    pos++;
-    if(pos >= header.length) {
-      songend = true;
-      pos = header.loop;
-    }
-  }
-
-  if(!header.compressed)
-    opl->write(data[pos].reg, data[pos].val);
-
-  if(data[pos].val) del = data[pos].val - 1; pos++;
-  if(pos >= header.length) { songend = true; pos = header.loop; }
-  return !songend;
-}
-
-void CsngPlayer::rewind(int subsong)
-{
-  pos = header.start; del = header.delay; songend = false;
-  opl->init(); opl->write(1,32);	// go to OPL2 mode
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/sng.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,84 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2002 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * sng.cpp - SNG Player by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include "sng.h"
+
+CPlayer *CsngPlayer::factory(Copl *newopl)
+{
+  return new CsngPlayer(newopl);
+}
+
+bool CsngPlayer::load(const std::string &filename, const CFileProvider &fp)
+{
+  binistream *f = fp.open(filename); if(!f) return false;
+  int i;
+
+  // load header
+  f->readString(header.id, 4);
+  header.length = f->readInt(2); header.start = f->readInt(2);
+  header.loop = f->readInt(2); header.delay = f->readInt(1);
+  header.compressed = f->readInt(1) ? true : false;
+
+  // file validation section
+  if(strncmp(header.id,"ObsM",4)) { fp.close(f); return false; }
+
+  // load section
+  header.length /= 2; header.start /= 2; header.loop /= 2;
+  data = new Sdata [header.length];
+  for(i = 0; i < header.length; i++) {
+    data[i].val = f->readInt(1);
+    data[i].reg = f->readInt(1);
+  }
+
+  rewind(0);
+  fp.close(f);
+  return true;
+}
+
+bool CsngPlayer::update()
+{
+  if(header.compressed && del) {
+    del--;
+    return !songend;
+  }
+
+  while(data[pos].reg) {
+    opl->write(data[pos].reg, data[pos].val);
+    pos++;
+    if(pos >= header.length) {
+      songend = true;
+      pos = header.loop;
+    }
+  }
+
+  if(!header.compressed)
+    opl->write(data[pos].reg, data[pos].val);
+
+  if(data[pos].val) del = data[pos].val - 1; pos++;
+  if(pos >= header.length) { songend = true; pos = header.loop; }
+  return !songend;
+}
+
+void CsngPlayer::rewind(int subsong)
+{
+  pos = header.start; del = header.delay; songend = false;
+  opl->init(); opl->write(1,32);	// go to OPL2 mode
+}
--- a/Plugins/Input/adplug/core/temuopl.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-/*
- * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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);
+}
--- a/Plugins/Input/adplug/core/u6m.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,935 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * u6m.cpp - Ultima 6 Music Player by Marc Winterrowd.
- * This code extends the Adlib Winamp plug-in by Simon Peter <dn.tlp@gmx.net>
- */
-
-#include "u6m.h"
-
-// Makes security checks on output buffer before writing
-#define SAVE_OUTPUT_ROOT(c, d, p) \
-if(p < d.size) \
-  output_root(c, d.data, p); \
-else \
-  return false;
-
-CPlayer *Cu6mPlayer::factory(Copl *newopl)
-{
-  return new Cu6mPlayer(newopl);
-}
-
-bool Cu6mPlayer::load(const std::string &filename, const CFileProvider &fp)
-{
-    // file validation section
-    // this section only checks a few *necessary* conditions
-    unsigned long filesize, decompressed_filesize;
-    binistream *f;
-
-    f = fp.open(filename); if(!f) return false;
-    filesize = fp.filesize(f);
-
-    if (filesize >= 6)
-    {
-        // check if the file has a valid pseudo-header
-        unsigned char pseudo_header[6];
-        f->readString((char *)pseudo_header, 6);
-        decompressed_filesize = pseudo_header[0] + (pseudo_header[1] << 8);
-
-        if (!( (pseudo_header[2]==0) && (pseudo_header[3]==0) &&
-               (pseudo_header[4] + ((pseudo_header[5] & 0x1)<<8) == 0x100) &&
-               (decompressed_filesize > (filesize-4)) ))
-        {
-	    fp.close(f);
-            return(false);
-        }
-    }
-    else
-    {
-        fp.close(f);
-        return(false);
-    }
-
-    // load section
-    song_data = new unsigned char[decompressed_filesize];
-    unsigned char* compressed_song_data = new unsigned char[filesize-3];
-
-    f->seek(4);
-    f->readString((char *)compressed_song_data, filesize - 4);
-    fp.close(f);
-
-    // attempt to decompress the song data
-    // if unsuccessful, deallocate song_data[] on the spot, and return(false)
-    data_block source, destination;
-    source.size = filesize-4;
-    source.data = compressed_song_data;
-    destination.size = decompressed_filesize;
-    destination.data = song_data;
-	
-    if (!lzw_decompress(source,destination))
-    {
-        delete[] compressed_song_data;
-        delete[] song_data;
-        return(false);
-    }
-
-    // deallocation section
-    delete[] compressed_song_data;
-
-    rewind(0);
-    return (true);
-}
-
-
-bool Cu6mPlayer::update()
-{
-    if (!driver_active)
-    {
-        driver_active = true;
-        dec_clip(read_delay);
-        if (read_delay == 0)
-        {
-            command_loop();
-        }
-
-        // on all Adlib channels: freq slide/vibrato, mute factor slide
-        for (int i = 0; i < 9; i++)
-        {
-            if (channel_freq_signed_delta[i]!=0)
-            // frequency slide + mute factor slide
-            {
-                // freq slide
-                freq_slide(i);
-
-                // mute factor slide
-                if (carrier_mf_signed_delta[i]!=0)
-                {
-                    mf_slide(i);
-                }
-            }
-            else
-            // vibrato + mute factor slide
-            {
-                // vibrato
-                if ((vb_multiplier[i]!=0) && ((channel_freq[i].hi & 0x20)==0x20))
-                {
-                    vibrato(i);
-                }
-
-                // mute factor slide
-                if (carrier_mf_signed_delta[i]!=0)
-                {
-                    mf_slide(i);
-                }
-            }
-        }
-
-        driver_active = false;
-    }
-
-    return !songend;
-}
-
-
-void Cu6mPlayer::rewind(int subsong)
-{
-	played_ticks = 0;
-	songend = false;
-
-    // set the driver's internal variables
-    byte_pair freq_word = {0,0};
-
-    driver_active = false;
-    song_pos = 0;
-    loop_position = 0;   // position of the loop point
-    read_delay = 0;      // delay (in timer ticks) before further song data is read
- 
-    for (int i = 0; i < 9; i++)
-    {
-        // frequency
-        channel_freq_signed_delta[i] = 0;
-        channel_freq[i] = freq_word;  // Adlib freq settings for each channel
-
-        // vibrato ("vb")
-        vb_current_value[i] = 0;
-        vb_double_amplitude[i] = 0;
-        vb_multiplier[i] = 0;
-        vb_direction_flag[i] = 0;
-
-        // mute factor ("mf") == ~(volume)
-        carrier_mf[i] = 0;
-        carrier_mf_signed_delta[i] = 0;
-        carrier_mf_mod_delay_backup[i] = 0;
-        carrier_mf_mod_delay[i] = 0;
-    }
-
-	while (!subsong_stack.empty())		// empty subsong stack
-		subsong_stack.pop();
-
-    opl->init();
-	out_adlib(1,32);	// go to OPL2 mode
-}
-
-
-float Cu6mPlayer::getrefresh()
-{
-    return ((float)60);   // the Ultima 6 music driver expects to be called at 60 Hz
-}
-
-
-// ============================================================================================
-//
-//
-//    Functions called by load()
-//
-//
-// ============================================================================================
-
-
-// decompress from memory to memory
-bool Cu6mPlayer::lzw_decompress(Cu6mPlayer::data_block source, Cu6mPlayer::data_block dest)
-{
-    bool end_marker_reached = false;
-    int codeword_size = 9;
-    long bits_read = 0;
-    int next_free_codeword = 0x102;
-    int dictionary_size = 0x200;
-    MyDict dictionary = MyDict();
-	std::stack<unsigned char> root_stack;
-
-    long bytes_written = 0;
-
-    int cW;
-  int pW;
-    unsigned char C;
-
-    while (!end_marker_reached)
-    {
-        cW = get_next_codeword(bits_read, source.data, codeword_size);
-        switch (cW)
-        {
-            // re-init the dictionary
-            case 0x100:
-                codeword_size = 9;
-                next_free_codeword = 0x102;
-                dictionary_size = 0x200;
-                dictionary.reset();
-                cW = get_next_codeword(bits_read, source.data, codeword_size);
-	  SAVE_OUTPUT_ROOT((unsigned char)cW, dest, bytes_written);
-                break;
-            // end of compressed file has been reached
-            case 0x101:
-                end_marker_reached = true;
-                break;
-            // (cW <> 0x100) && (cW <> 0x101)
-            default:
-                if (cW < next_free_codeword)  // codeword is already in the dictionary
-                {
-                    // create the string associated with cW (on the stack)
-                    get_string(cW,dictionary,root_stack);
-                    C = root_stack.top();
-                    // output the string represented by cW
-                    while (!root_stack.empty())
-                    {
-		  SAVE_OUTPUT_ROOT(root_stack.top(), dest, bytes_written);
-                        root_stack.pop();
-                    }
-                    // add pW+C to the dictionary
-                    dictionary.add(C,pW);
-
-                    next_free_codeword++;
-                    if (next_free_codeword >= dictionary_size)
-                    {
-                        if (codeword_size < max_codeword_length)
-                        {
-                            codeword_size += 1;
-                            dictionary_size *= 2;
-                        }
-                    }
-                }
-                else  // codeword is not yet defined
-                {
-                    // create the string associated with pW (on the stack)
-                    get_string(pW,dictionary,root_stack);
-                    C = root_stack.top();
-                    // output the string represented by pW
-                    while (!root_stack.empty())
-                    {
-		  SAVE_OUTPUT_ROOT(root_stack.top(), dest, bytes_written);
-                        root_stack.pop();
-                    }
-                    // output the char C
-	      SAVE_OUTPUT_ROOT(C, dest, bytes_written);
-
-                    // the new dictionary entry must correspond to cW
-                    // if it doesn't, something is wrong with the lzw-compressed data.
-                    if (cW != next_free_codeword)
-                    {
-		  /*                        printf("cW != next_free_codeword!\n");
-                        exit(-1); */
-						return false;
-                    }
-                    // add pW+C to the dictionary
-                    dictionary.add(C,pW);
- 
-                    next_free_codeword++;
-                    if (next_free_codeword >= dictionary_size)
-                    {
-                        if (codeword_size < max_codeword_length)
-                        {
-                            codeword_size += 1;
-                            dictionary_size *= 2;
-                        }
-                    }
-                };
-                break;
-        }
-        // shift roles - the current cW becomes the new pW
-        pW = cW;
-    }
-
-	return(true);   // indicate successful decompression
-}
-
-
-// --------------------
-// Additional functions
-// --------------------
-
-
-// Read the next code word from the source buffer
-int Cu6mPlayer::get_next_codeword (long& bits_read, unsigned char *source, int codeword_size)
-{
-    unsigned char b0,b1,b2;
-    int codeword;
- 
-    b0 = source[bits_read/8];
-    b1 = source[bits_read/8+1];
-    b2 = source[bits_read/8+2];
-
-    codeword = ((b2 << 16) + (b1 << 8) + b0);
-    codeword = codeword >> (bits_read % 8);
-    switch (codeword_size)
-    {
-        case 0x9:
-           codeword = codeword & 0x1ff;
-            break;
-        case 0xa:
-            codeword = codeword & 0x3ff;
-            break;
-        case 0xb:
-            codeword = codeword & 0x7ff;
-            break;
-        case 0xc:
-            codeword = codeword & 0xfff;
-            break;
-        default:
-            codeword = -1;   // indicates that an error has occurred
-            break;
-    }
-
-    bits_read += codeword_size;
-    return (codeword);
-}
-
-
-// output a root to memory
-void Cu6mPlayer::output_root(unsigned char root, unsigned char *destination, long& position)
-{
-    destination[position] = root;
-    position++;
-}
-
-
-// output the string represented by a codeword
-void Cu6mPlayer::get_string(int codeword, Cu6mPlayer::MyDict& dictionary, std::stack<unsigned char>& root_stack)
-{
-   unsigned char root;
-   int current_codeword;
-
-   current_codeword = codeword;
-
-   while (current_codeword > 0xff)
-   {
-      root = dictionary.get_root(current_codeword);
-      current_codeword = dictionary.get_codeword(current_codeword);
-      root_stack.push(root);
-   }
-
-   // push the root at the leaf
-   root_stack.push((unsigned char)current_codeword);
-}
-
-
-// ============================================================================================
-//
-//
-//    Functions called by update()
-//
-//
-// ============================================================================================
-
-
-// This function reads the song data and executes the embedded commands.
-void Cu6mPlayer::command_loop()
-{
-    unsigned char command_byte;   // current command byte
-    int command_nibble_hi;        // command byte, bits 4-7
-    int command_nibble_lo;        // command byte, bite 0-3
-    bool repeat_loop = true;      //
-
-    do
-    {
-        // extract low and high command nibbles
-        command_byte = read_song_byte();   // implicitly increments song_pos
-        command_nibble_hi = command_byte >> 4;
-        command_nibble_lo = command_byte & 0xf;
- 
-        switch (command_nibble_hi)
-        {
-            case 0x0: command_0(command_nibble_lo); break;
-            case 0x1: command_1(command_nibble_lo); break;
-            case 0x2: command_2(command_nibble_lo); break;
-            case 0x3: command_3(command_nibble_lo); break;
-            case 0x4: command_4(command_nibble_lo); break;
-            case 0x5: command_5(command_nibble_lo); break;
-            case 0x6: command_6(command_nibble_lo); break;
-            case 0x7: command_7(command_nibble_lo); break;
-            case 0x8:
-                switch (command_nibble_lo)
-                {
-                    case 1: command_81(); break;
-                    case 2: command_82(); repeat_loop = false; break;
-                    case 3: command_83(); break;
-                    case 5: command_85(); break;
-                    case 6: command_86(); break;
-                    default: break; // maybe generate an error?
-                }
-                break;
-            case 0xE: command_E(); break;
-            case 0xF: command_F(); break;
-            default: break; // maybe generate an error?
-        }
-
-    } while (repeat_loop);
-}
-
-
-// --------------------------------------------------------
-//    The commands supported by the U6 music file format
-// --------------------------------------------------------
-
-// ----------------------------------------
-// Set octave and frequency, note off
-// Format: 0c nn
-// c = channel, nn = packed Adlib frequency
-// ----------------------------------------
-void Cu6mPlayer::command_0(int channel)
-{
-    unsigned char freq_byte;
-    byte_pair freq_word;
-
-    freq_byte = read_song_byte();
-    freq_word = expand_freq_byte(freq_byte);
-    set_adlib_freq(channel,freq_word);
-}
-
-
-// ---------------------------------------------------
-// Set octave and frequency, old note off, new note on
-// Format: 1c nn
-// c = channel, nn = packed Adlib frequency
-// ---------------------------------------------------
-void Cu6mPlayer::command_1(int channel)
-{
-    unsigned char freq_byte;
-    byte_pair freq_word;
-
-    vb_direction_flag[channel] = 0;
-    vb_current_value[channel] = 0;
- 
-    freq_byte = read_song_byte();
-    freq_word = expand_freq_byte(freq_byte);
-    set_adlib_freq(channel,freq_word);
-
-    freq_word.hi = freq_word.hi | 0x20; // note on
-    set_adlib_freq(channel,freq_word);
-}
-
-
-// ----------------------------------------
-// Set octave and frequency, note on
-// Format: 2c nn
-// c = channel, nn = packed Adlib frequency
-// ----------------------------------------
-void Cu6mPlayer::command_2(int channel)
-{
-    unsigned char freq_byte;
-    byte_pair freq_word;
- 
-    freq_byte = read_song_byte();
-    freq_word = expand_freq_byte(freq_byte);
-    freq_word.hi = freq_word.hi | 0x20; // note on
-    set_adlib_freq(channel,freq_word);
-}
-
-
-// --------------------------------------
-// Set "carrier mute factor"==not(volume)
-// Format: 3c nn
-// c = channel, nn = mute factor
-// --------------------------------------
-void Cu6mPlayer::command_3(int channel)
-{
-    unsigned char mf_byte;
-
-    carrier_mf_signed_delta[channel] = 0;
-    mf_byte = read_song_byte();
-    set_carrier_mf(channel,mf_byte);
-}
-
-
-// ----------------------------------------
-// set "modulator mute factor"==not(volume)
-// Format: 4c nn
-// c = channel, nn = mute factor
-// ----------------------------------------
-void Cu6mPlayer::command_4(int channel)
-{
-    unsigned char mf_byte;
-
-    mf_byte = read_song_byte();
-    set_modulator_mf(channel,mf_byte);
-}
-
-
-// --------------------------------------------
-// Set portamento (pitch slide)
-// Format: 5c nn
-// c = channel, nn = signed channel pitch delta
-// --------------------------------------------
-void Cu6mPlayer::command_5(int channel)
-{
-    channel_freq_signed_delta[channel] = read_signed_song_byte();
-}
-
-
-// --------------------------------------------
-// Set vibrato paramters
-// Format: 6c mn
-// c = channel
-// m = vibrato double amplitude
-// n = vibrato multiplier
-// --------------------------------------------
-void Cu6mPlayer::command_6(int channel)
-{
-    unsigned char vb_parameters;
-
-    vb_parameters = read_song_byte();
-    vb_double_amplitude[channel] = vb_parameters >> 4; // high nibble
-    vb_multiplier[channel] = vb_parameters & 0xF; // low nibble
-}
-
-
-// ----------------------------------------
-// Assign Adlib instrument to Adlib channel
-// Format: 7c nn
-// c = channel, nn = instrument number
-// ----------------------------------------
-void Cu6mPlayer::command_7(int channel)
-{
-    int instrument_offset = instrument_offsets[read_song_byte()];
-    out_adlib_opcell(channel, false, 0x20, *(song_data + instrument_offset+0));
-    out_adlib_opcell(channel, false, 0x40, *(song_data + instrument_offset+1));
-    out_adlib_opcell(channel, false, 0x60, *(song_data + instrument_offset+2));
-    out_adlib_opcell(channel, false, 0x80, *(song_data + instrument_offset+3));
-    out_adlib_opcell(channel, false, 0xE0, *(song_data + instrument_offset+4));
-    out_adlib_opcell(channel, true, 0x20, *(song_data + instrument_offset+5));
-    out_adlib_opcell(channel, true, 0x40, *(song_data + instrument_offset+6));
-    out_adlib_opcell(channel, true, 0x60, *(song_data + instrument_offset+7));
-    out_adlib_opcell(channel, true, 0x80, *(song_data + instrument_offset+8));
-    out_adlib_opcell(channel, true, 0xE0, *(song_data + instrument_offset+9));
-    out_adlib(0xC0+channel, *(song_data + instrument_offset+10));
-}
-
-
-// -------------------------------------------
-// Branch to a new subsong
-// Format: 81 nn aa bb
-// nn == number of times to repeat the subsong
-// aa == subsong offset (low byte)
-// bb == subsong offset (high byte)
-// -------------------------------------------
-void Cu6mPlayer::command_81()
-{
-    subsong_info new_ss_info;
- 
-    new_ss_info.subsong_repetitions = read_song_byte();
-    new_ss_info.subsong_start = read_song_byte(); new_ss_info.subsong_start += read_song_byte() << 8;
-    new_ss_info.continue_pos = song_pos;
-
-    subsong_stack.push(new_ss_info);
-    song_pos = new_ss_info.subsong_start;
-}
-
-
-// ------------------------------------------------------------
-// Stop interpreting commands for this timer tick
-// Format: 82 nn
-// nn == delay (in timer ticks) until further data will be read
-// ------------------------------------------------------------
-void Cu6mPlayer::command_82()
-{
-    read_delay = read_song_byte();
-}
-
-
-// -----------------------------
-// Adlib instrument data follows
-// Format: 83 nn <11 bytes>
-// nn == instrument number
-// -----------------------------
-void Cu6mPlayer::command_83()
-{
-    unsigned char instrument_number = read_song_byte();
-    instrument_offsets[instrument_number] = song_pos;
-    song_pos += 11;
-}
-
-
-// ----------------------------------------------
-// Set -1 mute factor slide (upward volume slide)
-// Format: 85 cn
-// c == channel
-// n == slide delay
-// ----------------------------------------------
-void Cu6mPlayer::command_85()
-{
-    unsigned char data_byte = read_song_byte();
-    int channel = data_byte >> 4; // high nibble
-    unsigned char slide_delay = data_byte & 0xF; // low nibble
-    carrier_mf_signed_delta[channel] = +1;
-    carrier_mf_mod_delay[channel] = slide_delay + 1;
-    carrier_mf_mod_delay_backup[channel] = slide_delay + 1;
-}
-
-
-// ------------------------------------------------
-// Set +1 mute factor slide (downward volume slide)
-// Format: 86 cn
-// c == channel
-// n == slide speed
-// ------------------------------------------------
-void Cu6mPlayer::command_86()
-{
-    unsigned char data_byte = read_song_byte();
-    int channel = data_byte >> 4; // high nibble
-    unsigned char slide_delay = data_byte & 0xF; // low nibble
-    carrier_mf_signed_delta[channel] = -1;
-    carrier_mf_mod_delay[channel] = slide_delay + 1;
-    carrier_mf_mod_delay_backup[channel] = slide_delay + 1;
-}
-
-
-// --------------
-// Set loop point
-// Format: E?
-// --------------
-void Cu6mPlayer::command_E()
-{
-    loop_position = song_pos;
-}
-
-
-// ---------------------------
-// Return from current subsong
-// Format: F?
-// ---------------------------
-void Cu6mPlayer::command_F()
-{
-    if (!subsong_stack.empty())
-    {
-        subsong_info temp = subsong_stack.top();
-        subsong_stack.pop();
-        temp.subsong_repetitions--;
-        if (temp.subsong_repetitions==0)
-        {
-            song_pos = temp.continue_pos;
-        }
-        else
-        {
-            song_pos = temp.subsong_start;
-            subsong_stack.push(temp);
-        }
-    }
-    else
-    {
-        song_pos = loop_position;
-		songend = true;
-    }
-}
-
-
-// --------------------
-// Additional functions
-// --------------------
-
-// This function decrements its argument, without allowing it to become negative.
-void Cu6mPlayer::dec_clip(int& param)
-{
-    param--;
-    if (param < 0) { param = 0; }
-}
-
-
-// Returns the byte at the current song position.
-// Side effect: increments song_pos.
-unsigned char Cu6mPlayer::read_song_byte()
-{
-    unsigned char song_byte;
-    song_byte = song_data[song_pos];
-    song_pos++;
-    return(song_byte);
-}
-
-
-// Same as read_song_byte(), except that it returns a signed byte
-signed char Cu6mPlayer::read_signed_song_byte()
-{
-    unsigned char song_byte;
-    int signed_value;
-    song_byte = *(song_data + song_pos);
-    song_pos++;
-    if (song_byte <= 127)
-    {
-        signed_value = song_byte;
-    }
-    else
-    {
-        signed_value = (int)song_byte - 0x100;
-    }
-    return((signed char)signed_value);
-}
-
-
-Cu6mPlayer::byte_pair Cu6mPlayer::expand_freq_byte(unsigned char freq_byte)
-{
-    const byte_pair freq_table[24] =
-        {
-          {0x00,0x00}, {0x58,0x01}, {0x82,0x01}, {0xB0,0x01},
-          {0xCC,0x01}, {0x03,0x02}, {0x41,0x02}, {0x86,0x02},
-          {0x00,0x00}, {0x6A,0x01}, {0x96,0x01}, {0xC7,0x01},
-          {0xE4,0x01}, {0x1E,0x02}, {0x5F,0x02}, {0xA8,0x02},
-          {0x00,0x00}, {0x47,0x01}, {0x6E,0x01}, {0x9A,0x01},
-          {0xB5,0x01}, {0xE9,0x01}, {0x24,0x02}, {0x66,0x02}
-        };
-
-    int packed_freq;
-    int octave;
-    byte_pair freq_word;
-
-    packed_freq = freq_byte & 0x1F;
-    octave = freq_byte >> 5;
-
-    // range check (not present in the original U6 music driver)
-    if (packed_freq >= 24) { packed_freq = 0; }
-
-    freq_word.hi = freq_table[packed_freq].hi + (octave << 2);
-    freq_word.lo = freq_table[packed_freq].lo;
-
-    return(freq_word);
-}
-
-
-void Cu6mPlayer::set_adlib_freq(int channel,Cu6mPlayer::byte_pair freq_word)
-{
-    out_adlib(0xA0+channel,freq_word.lo);
-    out_adlib(0xB0+channel,freq_word.hi);
-    // update the Adlib register backups
-    channel_freq[channel] = freq_word;
-}
-
-
-// this function sets the Adlib frequency, but does not update the register backups
-void Cu6mPlayer::set_adlib_freq_no_update(int channel,Cu6mPlayer::byte_pair freq_word)
-{
-    out_adlib(0xA0+channel,freq_word.lo);
-    out_adlib(0xB0+channel,freq_word.hi);
-}
-
-
-void Cu6mPlayer::set_carrier_mf(int channel,unsigned char mute_factor)
-{
-    out_adlib_opcell(channel,true,0x40,mute_factor);
-    carrier_mf[channel] = mute_factor;
-}
-
-
-void Cu6mPlayer::set_modulator_mf(int channel,unsigned char mute_factor)
-{
-    out_adlib_opcell(channel,false,0x40,mute_factor);
-}
-
-
-void Cu6mPlayer::freq_slide(int channel)
-{
-    byte_pair freq = channel_freq[channel];
-
-    long freq_word = freq.lo + (freq.hi << 8) + channel_freq_signed_delta[channel];
-    if (freq_word < 0) { freq_word += 0x10000; }
-    if (freq_word > 0xFFFF) { freq_word -= 0x10000; }
-
-    freq.lo = freq_word & 0xFF;
-    freq.hi = (freq_word >> 8) & 0xFF;
-    set_adlib_freq(channel,freq);
-}
-
-
-void Cu6mPlayer::vibrato(int channel)
-{
-    byte_pair freq;
-
-    if (vb_current_value[channel] >= vb_double_amplitude[channel])
-    { vb_direction_flag[channel] = 1; }
-    else if (vb_current_value[channel] <= 0)
-    { vb_direction_flag[channel] = 0; }
-
-    if (vb_direction_flag[channel]==0)
-    { vb_current_value[channel]++; }
-    else
-    { vb_current_value[channel]--; }
-
-    long freq_word = channel_freq[channel].lo + (channel_freq[channel].hi << 8);
-    freq_word += (vb_current_value[channel] - (vb_double_amplitude[channel] >> 1))
-                 * vb_multiplier[channel];
-    if (freq_word < 0) { freq_word += 0x10000; }
-    if (freq_word > 0xFFFF) { freq_word -= 0x10000; }
-
-    freq.lo = freq_word & 0xFF;
-    freq.hi = (freq_word >> 8) & 0xFF;
-    set_adlib_freq_no_update(channel,freq);
-}
-
-
-void Cu6mPlayer::mf_slide(int channel)
-{
-    carrier_mf_mod_delay[channel]--;
-    if (carrier_mf_mod_delay[channel]==0)
-    {
-        carrier_mf_mod_delay[channel] = carrier_mf_mod_delay_backup[channel];
-        int current_mf = carrier_mf[channel] + carrier_mf_signed_delta[channel];
-        if (current_mf > 0x3F)
-        {
-            current_mf = 0x3F;
-            carrier_mf_signed_delta[channel] = 0;
-        }
-        else if (current_mf < 0)
-            {
-                current_mf = 0;
-                carrier_mf_signed_delta[channel] = 0;
-            }
-
-        set_carrier_mf(channel,(unsigned char)current_mf);
-    }
-}
-
-
-void Cu6mPlayer::out_adlib(unsigned char adlib_register, unsigned char adlib_data)
-{
-    opl->write(adlib_register,adlib_data);
-}
-
-
-void Cu6mPlayer::out_adlib_opcell(int channel, bool carrier, unsigned char adlib_register, unsigned char out_byte)
-{
-    const unsigned char adlib_channel_to_carrier_offset[9] =
-        {0x03,0x04,0x05,0x0B,0x0C,0x0D,0x13,0x14,0x15};
-    const unsigned char adlib_channel_to_modulator_offset[9] =
-        {0x00,0x01,0x02,0x08,0x09,0x0A,0x10,0x11,0x12};
-
-    if (carrier)
-    {
-        out_adlib(adlib_register+adlib_channel_to_carrier_offset[channel],out_byte);
-    }
-    else
-    {
-        out_adlib(adlib_register+adlib_channel_to_modulator_offset[channel],out_byte);
-    }
-}
-
-
-// ============================================================================================
-//
-//
-//    The Dictionary
-//
-//
-// ============================================================================================
-
-
-Cu6mPlayer::MyDict::MyDict()
-{
-    dict_size = default_dict_size;
-    dictionary = new dict_entry[dict_size-0x100]; // don't allocate space for the roots
-    contains = 0x102;
-}
-
-
-Cu6mPlayer::MyDict::MyDict(int max_size)
-{
-    dict_size = max_size;
-    dictionary = new dict_entry[dict_size-0x100]; // don't allocate space for the roots
-    contains = 0x102;
-}
-
-
-Cu6mPlayer::MyDict::~MyDict()
-{
-  delete [] dictionary;
-}
-
-// re-initializes the dictionary
-void Cu6mPlayer::MyDict::reset()
-{
-    contains = 0x102;
-}
-
-
-// Note: If the dictionary is already full, this function does nothing.
-void Cu6mPlayer::MyDict::add(unsigned char root, int codeword)
-{
-    if (contains < dict_size)
-    {
-        dictionary[contains-0x100].root = root;
-        dictionary[contains-0x100].codeword = codeword;
-        contains++;
-    }
-}
-
-
-unsigned char Cu6mPlayer::MyDict::get_root(int codeword)
-{
-    return (dictionary[codeword-0x100].root);
-}
-
-
-int Cu6mPlayer::MyDict::get_codeword(int codeword)
-{
-    return (dictionary[codeword-0x100].codeword);
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/u6m.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,935 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * u6m.cpp - Ultima 6 Music Player by Marc Winterrowd.
+ * This code extends the Adlib Winamp plug-in by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include "u6m.h"
+
+// Makes security checks on output buffer before writing
+#define SAVE_OUTPUT_ROOT(c, d, p) \
+if(p < d.size) \
+  output_root(c, d.data, p); \
+else \
+  return false;
+
+CPlayer *Cu6mPlayer::factory(Copl *newopl)
+{
+  return new Cu6mPlayer(newopl);
+}
+
+bool Cu6mPlayer::load(const std::string &filename, const CFileProvider &fp)
+{
+    // file validation section
+    // this section only checks a few *necessary* conditions
+    unsigned long filesize, decompressed_filesize;
+    binistream *f;
+
+    f = fp.open(filename); if(!f) return false;
+    filesize = fp.filesize(f);
+
+    if (filesize >= 6)
+    {
+        // check if the file has a valid pseudo-header
+        unsigned char pseudo_header[6];
+        f->readString((char *)pseudo_header, 6);
+        decompressed_filesize = pseudo_header[0] + (pseudo_header[1] << 8);
+
+        if (!( (pseudo_header[2]==0) && (pseudo_header[3]==0) &&
+               (pseudo_header[4] + ((pseudo_header[5] & 0x1)<<8) == 0x100) &&
+               (decompressed_filesize > (filesize-4)) ))
+        {
+	    fp.close(f);
+            return(false);
+        }
+    }
+    else
+    {
+        fp.close(f);
+        return(false);
+    }
+
+    // load section
+    song_data = new unsigned char[decompressed_filesize];
+    unsigned char* compressed_song_data = new unsigned char[filesize-3];
+
+    f->seek(4);
+    f->readString((char *)compressed_song_data, filesize - 4);
+    fp.close(f);
+
+    // attempt to decompress the song data
+    // if unsuccessful, deallocate song_data[] on the spot, and return(false)
+    data_block source, destination;
+    source.size = filesize-4;
+    source.data = compressed_song_data;
+    destination.size = decompressed_filesize;
+    destination.data = song_data;
+	
+    if (!lzw_decompress(source,destination))
+    {
+        delete[] compressed_song_data;
+        delete[] song_data;
+        return(false);
+    }
+
+    // deallocation section
+    delete[] compressed_song_data;
+
+    rewind(0);
+    return (true);
+}
+
+
+bool Cu6mPlayer::update()
+{
+    if (!driver_active)
+    {
+        driver_active = true;
+        dec_clip(read_delay);
+        if (read_delay == 0)
+        {
+            command_loop();
+        }
+
+        // on all Adlib channels: freq slide/vibrato, mute factor slide
+        for (int i = 0; i < 9; i++)
+        {
+            if (channel_freq_signed_delta[i]!=0)
+            // frequency slide + mute factor slide
+            {
+                // freq slide
+                freq_slide(i);
+
+                // mute factor slide
+                if (carrier_mf_signed_delta[i]!=0)
+                {
+                    mf_slide(i);
+                }
+            }
+            else
+            // vibrato + mute factor slide
+            {
+                // vibrato
+                if ((vb_multiplier[i]!=0) && ((channel_freq[i].hi & 0x20)==0x20))
+                {
+                    vibrato(i);
+                }
+
+                // mute factor slide
+                if (carrier_mf_signed_delta[i]!=0)
+                {
+                    mf_slide(i);
+                }
+            }
+        }
+
+        driver_active = false;
+    }
+
+    return !songend;
+}
+
+
+void Cu6mPlayer::rewind(int subsong)
+{
+	played_ticks = 0;
+	songend = false;
+
+    // set the driver's internal variables
+    byte_pair freq_word = {0,0};
+
+    driver_active = false;
+    song_pos = 0;
+    loop_position = 0;   // position of the loop point
+    read_delay = 0;      // delay (in timer ticks) before further song data is read
+ 
+    for (int i = 0; i < 9; i++)
+    {
+        // frequency
+        channel_freq_signed_delta[i] = 0;
+        channel_freq[i] = freq_word;  // Adlib freq settings for each channel
+
+        // vibrato ("vb")
+        vb_current_value[i] = 0;
+        vb_double_amplitude[i] = 0;
+        vb_multiplier[i] = 0;
+        vb_direction_flag[i] = 0;
+
+        // mute factor ("mf") == ~(volume)
+        carrier_mf[i] = 0;
+        carrier_mf_signed_delta[i] = 0;
+        carrier_mf_mod_delay_backup[i] = 0;
+        carrier_mf_mod_delay[i] = 0;
+    }
+
+	while (!subsong_stack.empty())		// empty subsong stack
+		subsong_stack.pop();
+
+    opl->init();
+	out_adlib(1,32);	// go to OPL2 mode
+}
+
+
+float Cu6mPlayer::getrefresh()
+{
+    return ((float)60);   // the Ultima 6 music driver expects to be called at 60 Hz
+}
+
+
+// ============================================================================================
+//
+//
+//    Functions called by load()
+//
+//
+// ============================================================================================
+
+
+// decompress from memory to memory
+bool Cu6mPlayer::lzw_decompress(Cu6mPlayer::data_block source, Cu6mPlayer::data_block dest)
+{
+    bool end_marker_reached = false;
+    int codeword_size = 9;
+    long bits_read = 0;
+    int next_free_codeword = 0x102;
+    int dictionary_size = 0x200;
+    MyDict dictionary = MyDict();
+	std::stack<unsigned char> root_stack;
+
+    long bytes_written = 0;
+
+    int cW;
+  int pW;
+    unsigned char C;
+
+    while (!end_marker_reached)
+    {
+        cW = get_next_codeword(bits_read, source.data, codeword_size);
+        switch (cW)
+        {
+            // re-init the dictionary
+            case 0x100:
+                codeword_size = 9;
+                next_free_codeword = 0x102;
+                dictionary_size = 0x200;
+                dictionary.reset();
+                cW = get_next_codeword(bits_read, source.data, codeword_size);
+	  SAVE_OUTPUT_ROOT((unsigned char)cW, dest, bytes_written);
+                break;
+            // end of compressed file has been reached
+            case 0x101:
+                end_marker_reached = true;
+                break;
+            // (cW <> 0x100) && (cW <> 0x101)
+            default:
+                if (cW < next_free_codeword)  // codeword is already in the dictionary
+                {
+                    // create the string associated with cW (on the stack)
+                    get_string(cW,dictionary,root_stack);
+                    C = root_stack.top();
+                    // output the string represented by cW
+                    while (!root_stack.empty())
+                    {
+		  SAVE_OUTPUT_ROOT(root_stack.top(), dest, bytes_written);
+                        root_stack.pop();
+                    }
+                    // add pW+C to the dictionary
+                    dictionary.add(C,pW);
+
+                    next_free_codeword++;
+                    if (next_free_codeword >= dictionary_size)
+                    {
+                        if (codeword_size < max_codeword_length)
+                        {
+                            codeword_size += 1;
+                            dictionary_size *= 2;
+                        }
+                    }
+                }
+                else  // codeword is not yet defined
+                {
+                    // create the string associated with pW (on the stack)
+                    get_string(pW,dictionary,root_stack);
+                    C = root_stack.top();
+                    // output the string represented by pW
+                    while (!root_stack.empty())
+                    {
+		  SAVE_OUTPUT_ROOT(root_stack.top(), dest, bytes_written);
+                        root_stack.pop();
+                    }
+                    // output the char C
+	      SAVE_OUTPUT_ROOT(C, dest, bytes_written);
+
+                    // the new dictionary entry must correspond to cW
+                    // if it doesn't, something is wrong with the lzw-compressed data.
+                    if (cW != next_free_codeword)
+                    {
+		  /*                        printf("cW != next_free_codeword!\n");
+                        exit(-1); */
+						return false;
+                    }
+                    // add pW+C to the dictionary
+                    dictionary.add(C,pW);
+ 
+                    next_free_codeword++;
+                    if (next_free_codeword >= dictionary_size)
+                    {
+                        if (codeword_size < max_codeword_length)
+                        {
+                            codeword_size += 1;
+                            dictionary_size *= 2;
+                        }
+                    }
+                };
+                break;
+        }
+        // shift roles - the current cW becomes the new pW
+        pW = cW;
+    }
+
+	return(true);   // indicate successful decompression
+}
+
+
+// --------------------
+// Additional functions
+// --------------------
+
+
+// Read the next code word from the source buffer
+int Cu6mPlayer::get_next_codeword (long& bits_read, unsigned char *source, int codeword_size)
+{
+    unsigned char b0,b1,b2;
+    int codeword;
+ 
+    b0 = source[bits_read/8];
+    b1 = source[bits_read/8+1];
+    b2 = source[bits_read/8+2];
+
+    codeword = ((b2 << 16) + (b1 << 8) + b0);
+    codeword = codeword >> (bits_read % 8);
+    switch (codeword_size)
+    {
+        case 0x9:
+           codeword = codeword & 0x1ff;
+            break;
+        case 0xa:
+            codeword = codeword & 0x3ff;
+            break;
+        case 0xb:
+            codeword = codeword & 0x7ff;
+            break;
+        case 0xc:
+            codeword = codeword & 0xfff;
+            break;
+        default:
+            codeword = -1;   // indicates that an error has occurred
+            break;
+    }
+
+    bits_read += codeword_size;
+    return (codeword);
+}
+
+
+// output a root to memory
+void Cu6mPlayer::output_root(unsigned char root, unsigned char *destination, long& position)
+{
+    destination[position] = root;
+    position++;
+}
+
+
+// output the string represented by a codeword
+void Cu6mPlayer::get_string(int codeword, Cu6mPlayer::MyDict& dictionary, std::stack<unsigned char>& root_stack)
+{
+   unsigned char root;
+   int current_codeword;
+
+   current_codeword = codeword;
+
+   while (current_codeword > 0xff)
+   {
+      root = dictionary.get_root(current_codeword);
+      current_codeword = dictionary.get_codeword(current_codeword);
+      root_stack.push(root);
+   }
+
+   // push the root at the leaf
+   root_stack.push((unsigned char)current_codeword);
+}
+
+
+// ============================================================================================
+//
+//
+//    Functions called by update()
+//
+//
+// ============================================================================================
+
+
+// This function reads the song data and executes the embedded commands.
+void Cu6mPlayer::command_loop()
+{
+    unsigned char command_byte;   // current command byte
+    int command_nibble_hi;        // command byte, bits 4-7
+    int command_nibble_lo;        // command byte, bite 0-3
+    bool repeat_loop = true;      //
+
+    do
+    {
+        // extract low and high command nibbles
+        command_byte = read_song_byte();   // implicitly increments song_pos
+        command_nibble_hi = command_byte >> 4;
+        command_nibble_lo = command_byte & 0xf;
+ 
+        switch (command_nibble_hi)
+        {
+            case 0x0: command_0(command_nibble_lo); break;
+            case 0x1: command_1(command_nibble_lo); break;
+            case 0x2: command_2(command_nibble_lo); break;
+            case 0x3: command_3(command_nibble_lo); break;
+            case 0x4: command_4(command_nibble_lo); break;
+            case 0x5: command_5(command_nibble_lo); break;
+            case 0x6: command_6(command_nibble_lo); break;
+            case 0x7: command_7(command_nibble_lo); break;
+            case 0x8:
+                switch (command_nibble_lo)
+                {
+                    case 1: command_81(); break;
+                    case 2: command_82(); repeat_loop = false; break;
+                    case 3: command_83(); break;
+                    case 5: command_85(); break;
+                    case 6: command_86(); break;
+                    default: break; // maybe generate an error?
+                }
+                break;
+            case 0xE: command_E(); break;
+            case 0xF: command_F(); break;
+            default: break; // maybe generate an error?
+        }
+
+    } while (repeat_loop);
+}
+
+
+// --------------------------------------------------------
+//    The commands supported by the U6 music file format
+// --------------------------------------------------------
+
+// ----------------------------------------
+// Set octave and frequency, note off
+// Format: 0c nn
+// c = channel, nn = packed Adlib frequency
+// ----------------------------------------
+void Cu6mPlayer::command_0(int channel)
+{
+    unsigned char freq_byte;
+    byte_pair freq_word;
+
+    freq_byte = read_song_byte();
+    freq_word = expand_freq_byte(freq_byte);
+    set_adlib_freq(channel,freq_word);
+}
+
+
+// ---------------------------------------------------
+// Set octave and frequency, old note off, new note on
+// Format: 1c nn
+// c = channel, nn = packed Adlib frequency
+// ---------------------------------------------------
+void Cu6mPlayer::command_1(int channel)
+{
+    unsigned char freq_byte;
+    byte_pair freq_word;
+
+    vb_direction_flag[channel] = 0;
+    vb_current_value[channel] = 0;
+ 
+    freq_byte = read_song_byte();
+    freq_word = expand_freq_byte(freq_byte);
+    set_adlib_freq(channel,freq_word);
+
+    freq_word.hi = freq_word.hi | 0x20; // note on
+    set_adlib_freq(channel,freq_word);
+}
+
+
+// ----------------------------------------
+// Set octave and frequency, note on
+// Format: 2c nn
+// c = channel, nn = packed Adlib frequency
+// ----------------------------------------
+void Cu6mPlayer::command_2(int channel)
+{
+    unsigned char freq_byte;
+    byte_pair freq_word;
+ 
+    freq_byte = read_song_byte();
+    freq_word = expand_freq_byte(freq_byte);
+    freq_word.hi = freq_word.hi | 0x20; // note on
+    set_adlib_freq(channel,freq_word);
+}
+
+
+// --------------------------------------
+// Set "carrier mute factor"==not(volume)
+// Format: 3c nn
+// c = channel, nn = mute factor
+// --------------------------------------
+void Cu6mPlayer::command_3(int channel)
+{
+    unsigned char mf_byte;
+
+    carrier_mf_signed_delta[channel] = 0;
+    mf_byte = read_song_byte();
+    set_carrier_mf(channel,mf_byte);
+}
+
+
+// ----------------------------------------
+// set "modulator mute factor"==not(volume)
+// Format: 4c nn
+// c = channel, nn = mute factor
+// ----------------------------------------
+void Cu6mPlayer::command_4(int channel)
+{
+    unsigned char mf_byte;
+
+    mf_byte = read_song_byte();
+    set_modulator_mf(channel,mf_byte);
+}
+
+
+// --------------------------------------------
+// Set portamento (pitch slide)
+// Format: 5c nn
+// c = channel, nn = signed channel pitch delta
+// --------------------------------------------
+void Cu6mPlayer::command_5(int channel)
+{
+    channel_freq_signed_delta[channel] = read_signed_song_byte();
+}
+
+
+// --------------------------------------------
+// Set vibrato paramters
+// Format: 6c mn
+// c = channel
+// m = vibrato double amplitude
+// n = vibrato multiplier
+// --------------------------------------------
+void Cu6mPlayer::command_6(int channel)
+{
+    unsigned char vb_parameters;
+
+    vb_parameters = read_song_byte();
+    vb_double_amplitude[channel] = vb_parameters >> 4; // high nibble
+    vb_multiplier[channel] = vb_parameters & 0xF; // low nibble
+}
+
+
+// ----------------------------------------
+// Assign Adlib instrument to Adlib channel
+// Format: 7c nn
+// c = channel, nn = instrument number
+// ----------------------------------------
+void Cu6mPlayer::command_7(int channel)
+{
+    int instrument_offset = instrument_offsets[read_song_byte()];
+    out_adlib_opcell(channel, false, 0x20, *(song_data + instrument_offset+0));
+    out_adlib_opcell(channel, false, 0x40, *(song_data + instrument_offset+1));
+    out_adlib_opcell(channel, false, 0x60, *(song_data + instrument_offset+2));
+    out_adlib_opcell(channel, false, 0x80, *(song_data + instrument_offset+3));
+    out_adlib_opcell(channel, false, 0xE0, *(song_data + instrument_offset+4));
+    out_adlib_opcell(channel, true, 0x20, *(song_data + instrument_offset+5));
+    out_adlib_opcell(channel, true, 0x40, *(song_data + instrument_offset+6));
+    out_adlib_opcell(channel, true, 0x60, *(song_data + instrument_offset+7));
+    out_adlib_opcell(channel, true, 0x80, *(song_data + instrument_offset+8));
+    out_adlib_opcell(channel, true, 0xE0, *(song_data + instrument_offset+9));
+    out_adlib(0xC0+channel, *(song_data + instrument_offset+10));
+}
+
+
+// -------------------------------------------
+// Branch to a new subsong
+// Format: 81 nn aa bb
+// nn == number of times to repeat the subsong
+// aa == subsong offset (low byte)
+// bb == subsong offset (high byte)
+// -------------------------------------------
+void Cu6mPlayer::command_81()
+{
+    subsong_info new_ss_info;
+ 
+    new_ss_info.subsong_repetitions = read_song_byte();
+    new_ss_info.subsong_start = read_song_byte(); new_ss_info.subsong_start += read_song_byte() << 8;
+    new_ss_info.continue_pos = song_pos;
+
+    subsong_stack.push(new_ss_info);
+    song_pos = new_ss_info.subsong_start;
+}
+
+
+// ------------------------------------------------------------
+// Stop interpreting commands for this timer tick
+// Format: 82 nn
+// nn == delay (in timer ticks) until further data will be read
+// ------------------------------------------------------------
+void Cu6mPlayer::command_82()
+{
+    read_delay = read_song_byte();
+}
+
+
+// -----------------------------
+// Adlib instrument data follows
+// Format: 83 nn <11 bytes>
+// nn == instrument number
+// -----------------------------
+void Cu6mPlayer::command_83()
+{
+    unsigned char instrument_number = read_song_byte();
+    instrument_offsets[instrument_number] = song_pos;
+    song_pos += 11;
+}
+
+
+// ----------------------------------------------
+// Set -1 mute factor slide (upward volume slide)
+// Format: 85 cn
+// c == channel
+// n == slide delay
+// ----------------------------------------------
+void Cu6mPlayer::command_85()
+{
+    unsigned char data_byte = read_song_byte();
+    int channel = data_byte >> 4; // high nibble
+    unsigned char slide_delay = data_byte & 0xF; // low nibble
+    carrier_mf_signed_delta[channel] = +1;
+    carrier_mf_mod_delay[channel] = slide_delay + 1;
+    carrier_mf_mod_delay_backup[channel] = slide_delay + 1;
+}
+
+
+// ------------------------------------------------
+// Set +1 mute factor slide (downward volume slide)
+// Format: 86 cn
+// c == channel
+// n == slide speed
+// ------------------------------------------------
+void Cu6mPlayer::command_86()
+{
+    unsigned char data_byte = read_song_byte();
+    int channel = data_byte >> 4; // high nibble
+    unsigned char slide_delay = data_byte & 0xF; // low nibble
+    carrier_mf_signed_delta[channel] = -1;
+    carrier_mf_mod_delay[channel] = slide_delay + 1;
+    carrier_mf_mod_delay_backup[channel] = slide_delay + 1;
+}
+
+
+// --------------
+// Set loop point
+// Format: E?
+// --------------
+void Cu6mPlayer::command_E()
+{
+    loop_position = song_pos;
+}
+
+
+// ---------------------------
+// Return from current subsong
+// Format: F?
+// ---------------------------
+void Cu6mPlayer::command_F()
+{
+    if (!subsong_stack.empty())
+    {
+        subsong_info temp = subsong_stack.top();
+        subsong_stack.pop();
+        temp.subsong_repetitions--;
+        if (temp.subsong_repetitions==0)
+        {
+            song_pos = temp.continue_pos;
+        }
+        else
+        {
+            song_pos = temp.subsong_start;
+            subsong_stack.push(temp);
+        }
+    }
+    else
+    {
+        song_pos = loop_position;
+		songend = true;
+    }
+}
+
+
+// --------------------
+// Additional functions
+// --------------------
+
+// This function decrements its argument, without allowing it to become negative.
+void Cu6mPlayer::dec_clip(int& param)
+{
+    param--;
+    if (param < 0) { param = 0; }
+}
+
+
+// Returns the byte at the current song position.
+// Side effect: increments song_pos.
+unsigned char Cu6mPlayer::read_song_byte()
+{
+    unsigned char song_byte;
+    song_byte = song_data[song_pos];
+    song_pos++;
+    return(song_byte);
+}
+
+
+// Same as read_song_byte(), except that it returns a signed byte
+signed char Cu6mPlayer::read_signed_song_byte()
+{
+    unsigned char song_byte;
+    int signed_value;
+    song_byte = *(song_data + song_pos);
+    song_pos++;
+    if (song_byte <= 127)
+    {
+        signed_value = song_byte;
+    }
+    else
+    {
+        signed_value = (int)song_byte - 0x100;
+    }
+    return((signed char)signed_value);
+}
+
+
+Cu6mPlayer::byte_pair Cu6mPlayer::expand_freq_byte(unsigned char freq_byte)
+{
+    const byte_pair freq_table[24] =
+        {
+          {0x00,0x00}, {0x58,0x01}, {0x82,0x01}, {0xB0,0x01},
+          {0xCC,0x01}, {0x03,0x02}, {0x41,0x02}, {0x86,0x02},
+          {0x00,0x00}, {0x6A,0x01}, {0x96,0x01}, {0xC7,0x01},
+          {0xE4,0x01}, {0x1E,0x02}, {0x5F,0x02}, {0xA8,0x02},
+          {0x00,0x00}, {0x47,0x01}, {0x6E,0x01}, {0x9A,0x01},
+          {0xB5,0x01}, {0xE9,0x01}, {0x24,0x02}, {0x66,0x02}
+        };
+
+    int packed_freq;
+    int octave;
+    byte_pair freq_word;
+
+    packed_freq = freq_byte & 0x1F;
+    octave = freq_byte >> 5;
+
+    // range check (not present in the original U6 music driver)
+    if (packed_freq >= 24) { packed_freq = 0; }
+
+    freq_word.hi = freq_table[packed_freq].hi + (octave << 2);
+    freq_word.lo = freq_table[packed_freq].lo;
+
+    return(freq_word);
+}
+
+
+void Cu6mPlayer::set_adlib_freq(int channel,Cu6mPlayer::byte_pair freq_word)
+{
+    out_adlib(0xA0+channel,freq_word.lo);
+    out_adlib(0xB0+channel,freq_word.hi);
+    // update the Adlib register backups
+    channel_freq[channel] = freq_word;
+}
+
+
+// this function sets the Adlib frequency, but does not update the register backups
+void Cu6mPlayer::set_adlib_freq_no_update(int channel,Cu6mPlayer::byte_pair freq_word)
+{
+    out_adlib(0xA0+channel,freq_word.lo);
+    out_adlib(0xB0+channel,freq_word.hi);
+}
+
+
+void Cu6mPlayer::set_carrier_mf(int channel,unsigned char mute_factor)
+{
+    out_adlib_opcell(channel,true,0x40,mute_factor);
+    carrier_mf[channel] = mute_factor;
+}
+
+
+void Cu6mPlayer::set_modulator_mf(int channel,unsigned char mute_factor)
+{
+    out_adlib_opcell(channel,false,0x40,mute_factor);
+}
+
+
+void Cu6mPlayer::freq_slide(int channel)
+{
+    byte_pair freq = channel_freq[channel];
+
+    long freq_word = freq.lo + (freq.hi << 8) + channel_freq_signed_delta[channel];
+    if (freq_word < 0) { freq_word += 0x10000; }
+    if (freq_word > 0xFFFF) { freq_word -= 0x10000; }
+
+    freq.lo = freq_word & 0xFF;
+    freq.hi = (freq_word >> 8) & 0xFF;
+    set_adlib_freq(channel,freq);
+}
+
+
+void Cu6mPlayer::vibrato(int channel)
+{
+    byte_pair freq;
+
+    if (vb_current_value[channel] >= vb_double_amplitude[channel])
+    { vb_direction_flag[channel] = 1; }
+    else if (vb_current_value[channel] <= 0)
+    { vb_direction_flag[channel] = 0; }
+
+    if (vb_direction_flag[channel]==0)
+    { vb_current_value[channel]++; }
+    else
+    { vb_current_value[channel]--; }
+
+    long freq_word = channel_freq[channel].lo + (channel_freq[channel].hi << 8);
+    freq_word += (vb_current_value[channel] - (vb_double_amplitude[channel] >> 1))
+                 * vb_multiplier[channel];
+    if (freq_word < 0) { freq_word += 0x10000; }
+    if (freq_word > 0xFFFF) { freq_word -= 0x10000; }
+
+    freq.lo = freq_word & 0xFF;
+    freq.hi = (freq_word >> 8) & 0xFF;
+    set_adlib_freq_no_update(channel,freq);
+}
+
+
+void Cu6mPlayer::mf_slide(int channel)
+{
+    carrier_mf_mod_delay[channel]--;
+    if (carrier_mf_mod_delay[channel]==0)
+    {
+        carrier_mf_mod_delay[channel] = carrier_mf_mod_delay_backup[channel];
+        int current_mf = carrier_mf[channel] + carrier_mf_signed_delta[channel];
+        if (current_mf > 0x3F)
+        {
+            current_mf = 0x3F;
+            carrier_mf_signed_delta[channel] = 0;
+        }
+        else if (current_mf < 0)
+            {
+                current_mf = 0;
+                carrier_mf_signed_delta[channel] = 0;
+            }
+
+        set_carrier_mf(channel,(unsigned char)current_mf);
+    }
+}
+
+
+void Cu6mPlayer::out_adlib(unsigned char adlib_register, unsigned char adlib_data)
+{
+    opl->write(adlib_register,adlib_data);
+}
+
+
+void Cu6mPlayer::out_adlib_opcell(int channel, bool carrier, unsigned char adlib_register, unsigned char out_byte)
+{
+    const unsigned char adlib_channel_to_carrier_offset[9] =
+        {0x03,0x04,0x05,0x0B,0x0C,0x0D,0x13,0x14,0x15};
+    const unsigned char adlib_channel_to_modulator_offset[9] =
+        {0x00,0x01,0x02,0x08,0x09,0x0A,0x10,0x11,0x12};
+
+    if (carrier)
+    {
+        out_adlib(adlib_register+adlib_channel_to_carrier_offset[channel],out_byte);
+    }
+    else
+    {
+        out_adlib(adlib_register+adlib_channel_to_modulator_offset[channel],out_byte);
+    }
+}
+
+
+// ============================================================================================
+//
+//
+//    The Dictionary
+//
+//
+// ============================================================================================
+
+
+Cu6mPlayer::MyDict::MyDict()
+{
+    dict_size = default_dict_size;
+    dictionary = new dict_entry[dict_size-0x100]; // don't allocate space for the roots
+    contains = 0x102;
+}
+
+
+Cu6mPlayer::MyDict::MyDict(int max_size)
+{
+    dict_size = max_size;
+    dictionary = new dict_entry[dict_size-0x100]; // don't allocate space for the roots
+    contains = 0x102;
+}
+
+
+Cu6mPlayer::MyDict::~MyDict()
+{
+  delete [] dictionary;
+}
+
+// re-initializes the dictionary
+void Cu6mPlayer::MyDict::reset()
+{
+    contains = 0x102;
+}
+
+
+// Note: If the dictionary is already full, this function does nothing.
+void Cu6mPlayer::MyDict::add(unsigned char root, int codeword)
+{
+    if (contains < dict_size)
+    {
+        dictionary[contains-0x100].root = root;
+        dictionary[contains-0x100].codeword = codeword;
+        contains++;
+    }
+}
+
+
+unsigned char Cu6mPlayer::MyDict::get_root(int codeword)
+{
+    return (dictionary[codeword-0x100].root);
+}
+
+
+int Cu6mPlayer::MyDict::get_codeword(int codeword)
+{
+    return (dictionary[codeword-0x100].codeword);
+}
+
--- a/Plugins/Input/adplug/core/xad.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/*
-  Adplug - Replayer for many OPL2/OPL3 audio file formats.
-  Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-  xad.cpp - XAD shell player by Riven the Mage <riven@ok.ru>
-*/
-
-#include "xad.h"
-#include "debug.h"
-
-/* -------- Public Methods -------------------------------- */
-
-CxadPlayer::CxadPlayer(Copl * newopl) : CPlayer(newopl)
-{
-  tune = 0;
-}
-
-CxadPlayer::~CxadPlayer()
-{
-  if (tune)
-    delete [] tune;
-}
-
-bool CxadPlayer::load(const std::string &filename, const CFileProvider &fp)
-{
-  binistream *f = fp.open(filename); if(!f) return false;
-  bool ret = false;
-
-  // load header
-  xad.id = f->readInt(4);
-  f->readString(xad.title, 36);
-  f->readString(xad.author, 36);
-  xad.fmt = f->readInt(2);
-  xad.speed = f->readInt(1);
-  xad.reserved_a = f->readInt(1);
-
-  // 'XAD!' - signed ?
-  if(xad.id != 0x21444158) { fp.close(f); return false; }
-
-  // get file size
-  tune_size = fp.filesize(f) - 80;
-
-  // load()
-  tune = new unsigned char [tune_size];
-  f->readString((char *)tune, tune_size);
-  fp.close(f);
-
-  ret = xadplayer_load();
-
-  if (ret)
-    rewind(0);
-
-  return ret;
-}
-
-void CxadPlayer::rewind(int subsong)
-{
-  opl->init();
-
-  plr.speed = xad.speed;
-  plr.speed_counter = 1;
-  plr.playing = 1;
-  plr.looping = 0;
-
-  // rewind()
-  xadplayer_rewind(subsong);
-
-#ifdef DEBUG
-  AdPlug_LogWrite("-----------\n");
-#endif
-}
-
-bool CxadPlayer::update()
-{
-  if (--plr.speed_counter)
-    goto update_end;
-
-  plr.speed_counter = plr.speed;
-
-  // update()
-  xadplayer_update();
-
-update_end:
-  return (plr.playing && (!plr.looping));
-}
-
-float CxadPlayer::getrefresh()
-{
-  return xadplayer_getrefresh();
-}
-
-std::string CxadPlayer::gettype()
-{
-  return xadplayer_gettype();
-}
-
-std::string CxadPlayer::gettitle()
-{
-  return xadplayer_gettitle();
-}
-
-std::string CxadPlayer::getauthor()
-{
-  return xadplayer_getauthor();
-}
-
-std::string CxadPlayer::getinstrument(unsigned int i)
-{
-  return xadplayer_getinstrument(i);
-}
-
-unsigned int CxadPlayer::getinstruments()
-{
-  return xadplayer_getinstruments();
-}
-
-/* -------- Protected Methods ------------------------------- */
-
-void CxadPlayer::opl_write(int reg, int val)
-{
-  adlib[reg] = val;
-#ifdef DEBUG
-  AdPlug_LogWrite("[ %02X ] = %02X\n",reg,val);
-#endif
-  opl->write(reg,val);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/xad.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,140 @@
+/*
+  Adplug - Replayer for many OPL2/OPL3 audio file formats.
+  Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+  xad.cpp - XAD shell player by Riven the Mage <riven@ok.ru>
+*/
+
+#include "xad.h"
+#include "debug.h"
+
+/* -------- Public Methods -------------------------------- */
+
+CxadPlayer::CxadPlayer(Copl * newopl) : CPlayer(newopl)
+{
+  tune = 0;
+}
+
+CxadPlayer::~CxadPlayer()
+{
+  if (tune)
+    delete [] tune;
+}
+
+bool CxadPlayer::load(const std::string &filename, const CFileProvider &fp)
+{
+  binistream *f = fp.open(filename); if(!f) return false;
+  bool ret = false;
+
+  // load header
+  xad.id = f->readInt(4);
+  f->readString(xad.title, 36);
+  f->readString(xad.author, 36);
+  xad.fmt = f->readInt(2);
+  xad.speed = f->readInt(1);
+  xad.reserved_a = f->readInt(1);
+
+  // 'XAD!' - signed ?
+  if(xad.id != 0x21444158) { fp.close(f); return false; }
+
+  // get file size
+  tune_size = fp.filesize(f) - 80;
+
+  // load()
+  tune = new unsigned char [tune_size];
+  f->readString((char *)tune, tune_size);
+  fp.close(f);
+
+  ret = xadplayer_load();
+
+  if (ret)
+    rewind(0);
+
+  return ret;
+}
+
+void CxadPlayer::rewind(int subsong)
+{
+  opl->init();
+
+  plr.speed = xad.speed;
+  plr.speed_counter = 1;
+  plr.playing = 1;
+  plr.looping = 0;
+
+  // rewind()
+  xadplayer_rewind(subsong);
+
+#ifdef DEBUG
+  AdPlug_LogWrite("-----------\n");
+#endif
+}
+
+bool CxadPlayer::update()
+{
+  if (--plr.speed_counter)
+    goto update_end;
+
+  plr.speed_counter = plr.speed;
+
+  // update()
+  xadplayer_update();
+
+update_end:
+  return (plr.playing && (!plr.looping));
+}
+
+float CxadPlayer::getrefresh()
+{
+  return xadplayer_getrefresh();
+}
+
+std::string CxadPlayer::gettype()
+{
+  return xadplayer_gettype();
+}
+
+std::string CxadPlayer::gettitle()
+{
+  return xadplayer_gettitle();
+}
+
+std::string CxadPlayer::getauthor()
+{
+  return xadplayer_getauthor();
+}
+
+std::string CxadPlayer::getinstrument(unsigned int i)
+{
+  return xadplayer_getinstrument(i);
+}
+
+unsigned int CxadPlayer::getinstruments()
+{
+  return xadplayer_getinstruments();
+}
+
+/* -------- Protected Methods ------------------------------- */
+
+void CxadPlayer::opl_write(int reg, int val)
+{
+  adlib[reg] = val;
+#ifdef DEBUG
+  AdPlug_LogWrite("[ %02X ] = %02X\n",reg,val);
+#endif
+  opl->write(reg,val);
+}
--- a/Plugins/Input/adplug/core/xsm.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-/*
- * Adplug - Replayer for many OPL2/OPL3 audio file formats.
- * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
- * xsm.cpp - eXtra Simple Music Player, by Simon Peter <dn.tlp@gmx.net>
- */
-
-#include <string.h>
-
-#include "xsm.h"
-
-CxsmPlayer::CxsmPlayer(Copl *newopl)
-  : CPlayer(newopl), music(0)
-{
-}
-
-CxsmPlayer::~CxsmPlayer()
-{
-  if(music) delete [] music;
-}
-
-bool CxsmPlayer::load(const std::string &filename, const CFileProvider &fp)
-{
-  binistream *f = fp.open(filename); if(!f) return false;
-  char			id[6];
-  int			i, j;
-
-  // check if header matches
-  f->readString(id, 6); songlen = f->readInt(2);
-  if(strncmp(id, "ofTAZ!", 6) || songlen > 3200) { fp.close(f); return false; }
-
-  // read and set instruments
-  for(i = 0; i < 9; i++) {
-    opl->write(0x20 + op_table[i], f->readInt(1));
-    opl->write(0x23 + op_table[i], f->readInt(1));
-    opl->write(0x40 + op_table[i], f->readInt(1));
-    opl->write(0x43 + op_table[i], f->readInt(1));
-    opl->write(0x60 + op_table[i], f->readInt(1));
-    opl->write(0x63 + op_table[i], f->readInt(1));
-    opl->write(0x80 + op_table[i], f->readInt(1));
-    opl->write(0x83 + op_table[i], f->readInt(1));
-    opl->write(0xe0 + op_table[i], f->readInt(1));
-    opl->write(0xe3 + op_table[i], f->readInt(1));
-    opl->write(0xc0 + op_table[i], f->readInt(1));
-    f->ignore(5);
-  }
-
-  // read song data
-  music = new char [songlen * 9];
-  for(i = 0; i < 9; i++)
-    for(j = 0; j < songlen; j++)
-      music[j * 9 + i] = f->readInt(1);
-
-  // success
-  fp.close(f);
-  rewind(0);
-  return true;
-}
-
-bool CxsmPlayer::update()
-{
-  int c;
-
-  if(notenum >= songlen) {
-    songend = true;
-    notenum = last = 0;
-  }
-
-  for(c = 0; c < 9; c++)
-    if(music[notenum * 9 + c] != music[last * 9 + c])
-      opl->write(0xb0 + c, 0);
-
-  for(c = 0; c < 9; c++) {
-    if(music[notenum * 9 + c])
-      play_note(c, music[notenum * 9 + c] % 12, music[notenum * 9 + c] / 12);
-    else
-      play_note(c, 0, 0);
-  }
-
-  last = notenum;
-  notenum++;
-  return !songend;
-}
-
-void CxsmPlayer::rewind(int subsong)
-{
-  notenum = last = 0;
-  songend = false;
-}
-
-float CxsmPlayer::getrefresh()
-{
-  return 5.0f;
-}
-
-void CxsmPlayer::play_note(int c, int note, int octv)
-{
-  int freq = note_table[note];
-
-  if(!note && !octv) freq = 0;
-  opl->write(0xa0 + c, freq & 0xff);
-  opl->write(0xb0 + c, (freq / 0xff) | 32 | (octv * 4));
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/adplug/core/xsm.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,117 @@
+/*
+ * Adplug - Replayer for many OPL2/OPL3 audio file formats.
+ * Copyright (C) 1999 - 2003 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * xsm.cpp - eXtra Simple Music Player, by Simon Peter <dn.tlp@gmx.net>
+ */
+
+#include <string.h>
+
+#include "xsm.h"
+
+CxsmPlayer::CxsmPlayer(Copl *newopl)
+  : CPlayer(newopl), music(0)
+{
+}
+
+CxsmPlayer::~CxsmPlayer()
+{
+  if(music) delete [] music;
+}
+
+bool CxsmPlayer::load(const std::string &filename, const CFileProvider &fp)
+{
+  binistream *f = fp.open(filename); if(!f) return false;
+  char			id[6];
+  int			i, j;
+
+  // check if header matches
+  f->readString(id, 6); songlen = f->readInt(2);
+  if(strncmp(id, "ofTAZ!", 6) || songlen > 3200) { fp.close(f); return false; }
+
+  // read and set instruments
+  for(i = 0; i < 9; i++) {
+    opl->write(0x20 + op_table[i], f->readInt(1));
+    opl->write(0x23 + op_table[i], f->readInt(1));
+    opl->write(0x40 + op_table[i], f->readInt(1));
+    opl->write(0x43 + op_table[i], f->readInt(1));
+    opl->write(0x60 + op_table[i], f->readInt(1));
+    opl->write(0x63 + op_table[i], f->readInt(1));
+    opl->write(0x80 + op_table[i], f->readInt(1));
+    opl->write(0x83 + op_table[i], f->readInt(1));
+    opl->write(0xe0 + op_table[i], f->readInt(1));
+    opl->write(0xe3 + op_table[i], f->readInt(1));
+    opl->write(0xc0 + op_table[i], f->readInt(1));
+    f->ignore(5);
+  }
+
+  // read song data
+  music = new char [songlen * 9];
+  for(i = 0; i < 9; i++)
+    for(j = 0; j < songlen; j++)
+      music[j * 9 + i] = f->readInt(1);
+
+  // success
+  fp.close(f);
+  rewind(0);
+  return true;
+}
+
+bool CxsmPlayer::update()
+{
+  int c;
+
+  if(notenum >= songlen) {
+    songend = true;
+    notenum = last = 0;
+  }
+
+  for(c = 0; c < 9; c++)
+    if(music[notenum * 9 + c] != music[last * 9 + c])
+      opl->write(0xb0 + c, 0);
+
+  for(c = 0; c < 9; c++) {
+    if(music[notenum * 9 + c])
+      play_note(c, music[notenum * 9 + c] % 12, music[notenum * 9 + c] / 12);
+    else
+      play_note(c, 0, 0);
+  }
+
+  last = notenum;
+  notenum++;
+  return !songend;
+}
+
+void CxsmPlayer::rewind(int subsong)
+{
+  notenum = last = 0;
+  songend = false;
+}
+
+float CxsmPlayer::getrefresh()
+{
+  return 5.0f;
+}
+
+void CxsmPlayer::play_note(int c, int note, int octv)
+{
+  int freq = note_table[note];
+
+  if(!note && !octv) freq = 0;
+  opl->write(0xa0 + c, freq & 0xff);
+  opl->write(0xb0 + c, (freq / 0xff) | 32 | (octv * 4));
+}
--- a/Plugins/Input/modplug/Makefile.in	Sat Sep 16 07:18:18 2006 -0700
+++ b/Plugins/Input/modplug/Makefile.in	Sat Sep 16 07:33:28 2006 -0700
@@ -8,8 +8,8 @@
 
 CXXFLAGS += $(PICFLAGS) $(GTK_CFLAGS) -I.. -I../../.. -I../../../intl
 LIBADD  = $(GTK_LIBS) -lstdc++ -lmodplug ./archive/libarchive.a ./gui/libgui.a
-SOURCES  = plugin.cpp modplugbmp.cpp
+SOURCES  = plugin.cxx modplugbmp.cxx
 
-OBJECTS = ${SOURCES:.cpp=.o}
+OBJECTS = ${SOURCES:.cxx=.o}
 
 include ../../../mk/objective.mk
--- a/Plugins/Input/modplug/archive/Makefile.in	Sat Sep 16 07:18:18 2006 -0700
+++ b/Plugins/Input/modplug/archive/Makefile.in	Sat Sep 16 07:33:28 2006 -0700
@@ -5,14 +5,14 @@
 
 OBJECTIVE_LIBS_NOINST = libarchive.a
 
-SOURCES = archive.cpp     \
-          open.cpp        \
-          arch_raw.cpp    \
-          arch_gzip.cpp   \
-          arch_zip.cpp    \
-          arch_rar.cpp    \
-          arch_bz2.cpp
+SOURCES = archive.cxx     \
+          open.cxx        \
+          arch_raw.cxx    \
+          arch_gzip.cxx   \
+          arch_zip.cxx    \
+          arch_rar.cxx    \
+          arch_bz2.cxx
 
-OBJECTS = ${SOURCES:.cpp=.o}
+OBJECTS = ${SOURCES:.cxx=.o}
 
 include ../../../../mk/objective.mk
--- a/Plugins/Input/modplug/archive/arch_bz2.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/* Modplug XMMS Plugin
- * Authors: Kenton Varda <temporal@gauge3d.org>
- *          Colin DeVilbiss <crdevilb@mtu.edu>
- *
- * This source code is public domain.
- */
-
-// BZ2 support added by Colin DeVilbiss <crdevilb@mtu.edu>
-
-//open()
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#include "arch_bz2.h"
-#include <iostream>
- 	
-arch_Bzip2::arch_Bzip2(const string& aFileName)
-{
-	//check if file exists
-	int lFileDesc = open(aFileName.c_str(), O_RDONLY);
-	
-	if(lFileDesc == -1)
-	{
-		mSize = 0;
-		return;
-	}
-	
-	close(lFileDesc);
-	
-	//ok, continue
-	string lCommand = "bzcat \'" + aFileName + "\' | wc -c";   //get info
-	FILE *f = popen(lCommand.c_str(), "r");
-
-	if (f <= 0)
-	{
-		mSize = 0;
-		return;
-	}
-	
-	fscanf(f, "%u", &mSize); // this is the size.
-	
-	pclose(f);
-	
-	mMap = new char[mSize];
-	if(mMap == NULL)
-	{
-		mSize = 0;
-		return;
-	}
-	
-	lCommand = "bzcat \'" + aFileName + '\'';  //decompress to stdout
-	popen(lCommand.c_str(), "r");
-
-	if (f <= 0)
-	{
-		mSize = 0;
-		return;
-	}
-
-	fread((char *)mMap, sizeof(char), mSize, f);
-
-	pclose(f);
-}
-
-arch_Bzip2::~arch_Bzip2()
-{
-	if(mSize != 0)
-		delete [] (char*)mMap;
-}
-
-bool arch_Bzip2::ContainsMod(const string& aFileName)
-{
-	string lName;
-	int lFileDesc = open(aFileName.c_str(), O_RDONLY);
- 	if(lFileDesc == -1)
-		return false;
-	
-	close(lFileDesc);
-	
-	lName = aFileName.substr(0, aFileName.find_last_of('.'));
-	return IsOurFile(lName);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/modplug/archive/arch_bz2.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,85 @@
+/* Modplug XMMS Plugin
+ * Authors: Kenton Varda <temporal@gauge3d.org>
+ *          Colin DeVilbiss <crdevilb@mtu.edu>
+ *
+ * This source code is public domain.
+ */
+
+// BZ2 support added by Colin DeVilbiss <crdevilb@mtu.edu>
+
+//open()
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include "arch_bz2.h"
+#include <iostream>
+ 	
+arch_Bzip2::arch_Bzip2(const string& aFileName)
+{
+	//check if file exists
+	int lFileDesc = open(aFileName.c_str(), O_RDONLY);
+	
+	if(lFileDesc == -1)
+	{
+		mSize = 0;
+		return;
+	}
+	
+	close(lFileDesc);
+	
+	//ok, continue
+	string lCommand = "bzcat \'" + aFileName + "\' | wc -c";   //get info
+	FILE *f = popen(lCommand.c_str(), "r");
+
+	if (f <= 0)
+	{
+		mSize = 0;
+		return;
+	}
+	
+	fscanf(f, "%u", &mSize); // this is the size.
+	
+	pclose(f);
+	
+	mMap = new char[mSize];
+	if(mMap == NULL)
+	{
+		mSize = 0;
+		return;
+	}
+	
+	lCommand = "bzcat \'" + aFileName + '\'';  //decompress to stdout
+	popen(lCommand.c_str(), "r");
+
+	if (f <= 0)
+	{
+		mSize = 0;
+		return;
+	}
+
+	fread((char *)mMap, sizeof(char), mSize, f);
+
+	pclose(f);
+}
+
+arch_Bzip2::~arch_Bzip2()
+{
+	if(mSize != 0)
+		delete [] (char*)mMap;
+}
+
+bool arch_Bzip2::ContainsMod(const string& aFileName)
+{
+	string lName;
+	int lFileDesc = open(aFileName.c_str(), O_RDONLY);
+ 	if(lFileDesc == -1)
+		return false;
+	
+	close(lFileDesc);
+	
+	lName = aFileName.substr(0, aFileName.find_last_of('.'));
+	return IsOurFile(lName);
+}
--- a/Plugins/Input/modplug/archive/arch_gzip.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-/* Modplug XMMS Plugin
- * Authors: Kenton Varda <temporal@gauge3d.org>
- *
- * This source code is public domain.
- */
-
-//open()
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#include "arch_gzip.h"
-
-	
-arch_Gzip::arch_Gzip(const string& aFileName)
-{
-	//check if file exists
-	int lFileDesc = open(aFileName.c_str(), O_RDONLY);
-	
-	if(lFileDesc == -1)
-	{
-		mSize = 0;
-		return;
-	}       
-	close(lFileDesc);
-
-	// file exists.       
-	string lCommand = "gunzip -l \"" + aFileName + '\"';   //get info
-	FILE *f = popen(lCommand.c_str(), "r");
-	
-	if (f <= 0)
-	{
-		mSize = 0;
-		return;
-	}
-	
-	char line[81];
-	fgets(line, 80, f);   // ignore a line.
-	fscanf(f, "%u", &mSize); // ignore first number.
-	fscanf(f, "%u", &mSize); // keep second number.
-	
-	pclose(f);
-	
-	mMap = new char[mSize];
-	if(mMap == NULL)
-	{
-		mSize = 0;
-		return;
-	}
-	
-	lCommand = "gunzip -c \"" + aFileName + '\"';  //decompress to stdout
-        f = popen(lCommand.c_str(), "r");
-	
-	if (f <= 0)
-	{
-		mSize = 0;
-		return;
-	}
-
-	fread((char *)mMap, sizeof(char), mSize, f);
-
-	pclose(f);
-	
-}
-
-arch_Gzip::~arch_Gzip()
-{
-	if(mSize != 0)
-		delete [] (char*)mMap;
-}
-
-bool arch_Gzip::ContainsMod(const string& aFileName)
-{
-	string lName;
-	int lFileDesc = open(aFileName.c_str(), O_RDONLY);
-	uint32 num;
-	float fnum;
-
-	if(lFileDesc == -1)
-		return false;
-	
-	close(lFileDesc);
-
-	// file exists.       
-	string lCommand = "gunzip -l \"" + aFileName + '\"';   //get info
-	FILE *f = popen(lCommand.c_str(),"r");
-	
-	if (f <= 0) {
-		pclose(f);
-		return false;
-	}
-	
-	char line[300];
-	fgets(line, 80, f);   // ignore a line.
-	fscanf(f, "%i", &num); // ignore first number
-	fscanf(f, "%i", &num); // ignore second number
-	fscanf(f, "%f%%", &fnum); // ignore ratio
-	fgets(line, 300, f);   // read in correct line safely.
-	if (strlen(line) > 1)
-		line[strlen(line)-1] = 0;
-	lName = line;
-	
-	pclose(f);
-	
-	return IsOurFile(lName);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/modplug/archive/arch_gzip.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,108 @@
+/* Modplug XMMS Plugin
+ * Authors: Kenton Varda <temporal@gauge3d.org>
+ *
+ * This source code is public domain.
+ */
+
+//open()
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include "arch_gzip.h"
+
+	
+arch_Gzip::arch_Gzip(const string& aFileName)
+{
+	//check if file exists
+	int lFileDesc = open(aFileName.c_str(), O_RDONLY);
+	
+	if(lFileDesc == -1)
+	{
+		mSize = 0;
+		return;
+	}       
+	close(lFileDesc);
+
+	// file exists.       
+	string lCommand = "gunzip -l \"" + aFileName + '\"';   //get info
+	FILE *f = popen(lCommand.c_str(), "r");
+	
+	if (f <= 0)
+	{
+		mSize = 0;
+		return;
+	}
+	
+	char line[81];
+	fgets(line, 80, f);   // ignore a line.
+	fscanf(f, "%u", &mSize); // ignore first number.
+	fscanf(f, "%u", &mSize); // keep second number.
+	
+	pclose(f);
+	
+	mMap = new char[mSize];
+	if(mMap == NULL)
+	{
+		mSize = 0;
+		return;
+	}
+	
+	lCommand = "gunzip -c \"" + aFileName + '\"';  //decompress to stdout
+        f = popen(lCommand.c_str(), "r");
+	
+	if (f <= 0)
+	{
+		mSize = 0;
+		return;
+	}
+
+	fread((char *)mMap, sizeof(char), mSize, f);
+
+	pclose(f);
+	
+}
+
+arch_Gzip::~arch_Gzip()
+{
+	if(mSize != 0)
+		delete [] (char*)mMap;
+}
+
+bool arch_Gzip::ContainsMod(const string& aFileName)
+{
+	string lName;
+	int lFileDesc = open(aFileName.c_str(), O_RDONLY);
+	uint32 num;
+	float fnum;
+
+	if(lFileDesc == -1)
+		return false;
+	
+	close(lFileDesc);
+
+	// file exists.       
+	string lCommand = "gunzip -l \"" + aFileName + '\"';   //get info
+	FILE *f = popen(lCommand.c_str(),"r");
+	
+	if (f <= 0) {
+		pclose(f);
+		return false;
+	}
+	
+	char line[300];
+	fgets(line, 80, f);   // ignore a line.
+	fscanf(f, "%i", &num); // ignore first number
+	fscanf(f, "%i", &num); // ignore second number
+	fscanf(f, "%f%%", &fnum); // ignore ratio
+	fgets(line, 300, f);   // read in correct line safely.
+	if (strlen(line) > 1)
+		line[strlen(line)-1] = 0;
+	lName = line;
+	
+	pclose(f);
+	
+	return IsOurFile(lName);
+}
--- a/Plugins/Input/modplug/archive/arch_rar.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,185 +0,0 @@
-/* Modplug XMMS Plugin
- * Authors: Kenton Varda <temporal@gauge3d.org>
- *
- * This source code is public domain.
- */
-
-//open()
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdio.h>
-
-#include "arch_rar.h"
-#include <iostream>
-#include <vector>
-	
-arch_Rar::arch_Rar(const string& aFileName)
-{
-	//check if file exists
-	int lFileDesc = open(aFileName.c_str(), O_RDONLY);
-	char lBuffer[350];
-	uint32 lLength;
-	uint32 lCount;
-	uint32 lPos = 0;
-	bool lFound = false;
-	string lName, lGoodName;
-
-	if(lFileDesc == -1)
-	{
-		mSize = 0;
-		return;
-	}
-	
-	close(lFileDesc);
-
-	string lCommand = "unrar l \"" + aFileName + '\"';   //get info
-	FILE *f = popen(lCommand.c_str(), "r");
-	
-	if(f <= 0)
-	{
-		mSize = 0;
-		return;
-	}
-
-	int num = 7;
-	while (num--) // ignore 7 lines.
-		fgets(lBuffer, 90, f);
-	
-	bool eof = false;
-	while(!eof)
-	{
-		if(fgets(lBuffer, 350, f) <= 0 || f <= 0)
-			break;
-		if (strlen(lBuffer) > 1)
-			lBuffer[strlen(lBuffer)-1] = 0;
-		
-		lLength = strlen(lBuffer);
-		lCount = 0;
-		for(uint32 i = lLength - 1; i > 0; i--)
-		{
-			if(lBuffer[i] == ' ')
-			{
-				lBuffer[i] = 0;
-				if(lBuffer[i - 1] != ' ')
-				{
-					lCount++;
-					if(lCount == 9)
-					{
-						lPos = i;
-						break;
-					}
-				}
-			}
-		}
-		
-		while(lBuffer[lPos] == '\0')
-			lPos++;
-		lName = &lBuffer[1]; // get rid of the space.
-
-		mSize = strtol(lBuffer + lPos, NULL, 10);
-		
-		if(IsOurFile(lName))
-		{
-			lFound = true;
-			break;
-		}		
-	}
-	
-	if(!lFound)
-	{
-		mSize = 0;
-		return;
-	}
-
-	pclose(f);
-	
-	mMap = new char[mSize];
-	if(mMap == NULL)
-	{
-		mSize = 0;
-		return;
-	}
-	
-	lCommand = "unrar p -inul \"" + aFileName + "\" \"" + lName + '\"';  
-        //decompress to stdout
-	f = popen(lCommand.c_str(), "r");
-	
-	if (f <= 0)
-	{
-		mSize = 0;
-		return;
-	}
-
-	fread((char *)mMap, sizeof(char), mSize, f);
-	
-	pclose(f);
-}
-
-arch_Rar::~arch_Rar()
-{
-	if(mSize != 0)
-		delete [] (char*)mMap;
-}
-
-bool arch_Rar::ContainsMod(const string& aFileName)
-{
-	//check if file exists
-	string lName;
-	int lFileDesc = open(aFileName.c_str(), O_RDONLY);
-	char lBuffer[350];
-	uint32 lLength;
-	uint32 lCount;
-
-	if(lFileDesc == -1)
-		return false;
-	
-	close(lFileDesc);
-
-	string lCommand = "unrar l \"" + aFileName + '\"';   //get info
-	FILE *f = popen(lCommand.c_str(), "r");
-	
-	if(f <= 0)
-		return false;
-
-	int num = 7;
-	while (num--)
-		fgets(lBuffer, 90, f); //ignore a line.
-
-	bool eof = false;
-	while(!eof)
-	{
-		if(fgets(lBuffer, 350, f) || f <= 0)
-			if(f <= 0)
-			break;
-		if (strlen(lBuffer) > 1)
-			lBuffer[strlen(lBuffer)-1] = 0;
-		
-		lLength = strlen(lBuffer);
-		lCount = 0;
-		for(uint32 i = lLength - 1; i > 0; i--)
-		{
-			if(lBuffer[i] == ' ')
-			{
-				lBuffer[i] = 0;
-				if(lBuffer[i - 1] != ' ')
-				{
-					lCount++;
-					if(lCount == 9)
-						break;
-				}
-			}
-		}
-		
-		lName = lBuffer;
-		
-		if(IsOurFile(lName)) {
-			pclose(f);
-			return true;
-		}
-	}
-
-	pclose(f);	
-	return false;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/modplug/archive/arch_rar.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,185 @@
+/* Modplug XMMS Plugin
+ * Authors: Kenton Varda <temporal@gauge3d.org>
+ *
+ * This source code is public domain.
+ */
+
+//open()
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdio.h>
+
+#include "arch_rar.h"
+#include <iostream>
+#include <vector>
+	
+arch_Rar::arch_Rar(const string& aFileName)
+{
+	//check if file exists
+	int lFileDesc = open(aFileName.c_str(), O_RDONLY);
+	char lBuffer[350];
+	uint32 lLength;
+	uint32 lCount;
+	uint32 lPos = 0;
+	bool lFound = false;
+	string lName, lGoodName;
+
+	if(lFileDesc == -1)
+	{
+		mSize = 0;
+		return;
+	}
+	
+	close(lFileDesc);
+
+	string lCommand = "unrar l \"" + aFileName + '\"';   //get info
+	FILE *f = popen(lCommand.c_str(), "r");
+	
+	if(f <= 0)
+	{
+		mSize = 0;
+		return;
+	}
+
+	int num = 7;
+	while (num--) // ignore 7 lines.
+		fgets(lBuffer, 90, f);
+	
+	bool eof = false;
+	while(!eof)
+	{
+		if(fgets(lBuffer, 350, f) <= 0 || f <= 0)
+			break;
+		if (strlen(lBuffer) > 1)
+			lBuffer[strlen(lBuffer)-1] = 0;
+		
+		lLength = strlen(lBuffer);
+		lCount = 0;
+		for(uint32 i = lLength - 1; i > 0; i--)
+		{
+			if(lBuffer[i] == ' ')
+			{
+				lBuffer[i] = 0;
+				if(lBuffer[i - 1] != ' ')
+				{
+					lCount++;
+					if(lCount == 9)
+					{
+						lPos = i;
+						break;
+					}
+				}
+			}
+		}
+		
+		while(lBuffer[lPos] == '\0')
+			lPos++;
+		lName = &lBuffer[1]; // get rid of the space.
+
+		mSize = strtol(lBuffer + lPos, NULL, 10);
+		
+		if(IsOurFile(lName))
+		{
+			lFound = true;
+			break;
+		}		
+	}
+	
+	if(!lFound)
+	{
+		mSize = 0;
+		return;
+	}
+
+	pclose(f);
+	
+	mMap = new char[mSize];
+	if(mMap == NULL)
+	{
+		mSize = 0;
+		return;
+	}
+	
+	lCommand = "unrar p -inul \"" + aFileName + "\" \"" + lName + '\"';  
+        //decompress to stdout
+	f = popen(lCommand.c_str(), "r");
+	
+	if (f <= 0)
+	{
+		mSize = 0;
+		return;
+	}
+
+	fread((char *)mMap, sizeof(char), mSize, f);
+	
+	pclose(f);
+}
+
+arch_Rar::~arch_Rar()
+{
+	if(mSize != 0)
+		delete [] (char*)mMap;
+}
+
+bool arch_Rar::ContainsMod(const string& aFileName)
+{
+	//check if file exists
+	string lName;
+	int lFileDesc = open(aFileName.c_str(), O_RDONLY);
+	char lBuffer[350];
+	uint32 lLength;
+	uint32 lCount;
+
+	if(lFileDesc == -1)
+		return false;
+	
+	close(lFileDesc);
+
+	string lCommand = "unrar l \"" + aFileName + '\"';   //get info
+	FILE *f = popen(lCommand.c_str(), "r");
+	
+	if(f <= 0)
+		return false;
+
+	int num = 7;
+	while (num--)
+		fgets(lBuffer, 90, f); //ignore a line.
+
+	bool eof = false;
+	while(!eof)
+	{
+		if(fgets(lBuffer, 350, f) || f <= 0)
+			if(f <= 0)
+			break;
+		if (strlen(lBuffer) > 1)
+			lBuffer[strlen(lBuffer)-1] = 0;
+		
+		lLength = strlen(lBuffer);
+		lCount = 0;
+		for(uint32 i = lLength - 1; i > 0; i--)
+		{
+			if(lBuffer[i] == ' ')
+			{
+				lBuffer[i] = 0;
+				if(lBuffer[i - 1] != ' ')
+				{
+					lCount++;
+					if(lCount == 9)
+						break;
+				}
+			}
+		}
+		
+		lName = lBuffer;
+		
+		if(IsOurFile(lName)) {
+			pclose(f);
+			return true;
+		}
+	}
+
+	pclose(f);	
+	return false;
+}
--- a/Plugins/Input/modplug/archive/arch_raw.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/* Modplug XMMS Plugin
- * Authors: Kenton Varda <temporal@gauge3d.org>
- *
- * This source code is public domain.
- */
-
-//open()
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-//mmap()
-#include <unistd.h>
-#include <sys/mman.h>
-
-#include "arch_raw.h"
-
-arch_Raw::arch_Raw(const string& aFileName)
-{
-	mFileDesc = open(aFileName.c_str(), O_RDONLY);
-
-	struct stat lStat;
-
-	//open and mmap the file
-	if(mFileDesc == -1)
-	{
-		mSize = 0;
-		return;
-	}
-	fstat(mFileDesc, &lStat);
-	mSize = lStat.st_size;
-
-	mMap =
-		(uchar*)mmap(0, mSize, PROT_READ,
-		MAP_PRIVATE, mFileDesc, 0);
-	if(!mMap)
-	{
-		close(mFileDesc);
-		mSize = 0;
-		return;
-	}
-}
-
-arch_Raw::~arch_Raw()
-{
-	if(mSize != 0)
-	{
-		munmap(mMap, mSize);
-		close(mFileDesc);
-	}
-}
-
-bool arch_Raw::ContainsMod(const string& aFileName)
-{
-	return IsOurFile(aFileName);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/modplug/archive/arch_raw.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,55 @@
+/* Modplug XMMS Plugin
+ * Authors: Kenton Varda <temporal@gauge3d.org>
+ *
+ * This source code is public domain.
+ */
+
+//open()
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+//mmap()
+#include <unistd.h>
+#include <sys/mman.h>
+
+#include "arch_raw.h"
+
+arch_Raw::arch_Raw(const string& aFileName)
+{
+	mFileDesc = open(aFileName.c_str(), O_RDONLY);
+
+	struct stat lStat;
+
+	//open and mmap the file
+	if(mFileDesc == -1)
+	{
+		mSize = 0;
+		return;
+	}
+	fstat(mFileDesc, &lStat);
+	mSize = lStat.st_size;
+
+	mMap =
+		(uchar*)mmap(0, mSize, PROT_READ,
+		MAP_PRIVATE, mFileDesc, 0);
+	if(!mMap)
+	{
+		close(mFileDesc);
+		mSize = 0;
+		return;
+	}
+}
+
+arch_Raw::~arch_Raw()
+{
+	if(mSize != 0)
+	{
+		munmap(mMap, mSize);
+		close(mFileDesc);
+	}
+}
+
+bool arch_Raw::ContainsMod(const string& aFileName)
+{
+	return IsOurFile(aFileName);
+}
--- a/Plugins/Input/modplug/archive/arch_zip.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,143 +0,0 @@
-/* Modplug XMMS Plugin
- * Authors: Kenton Varda <temporal@gauge3d.org>
- *
- * This source code is public domain.
- */
-
-//open()
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "arch_zip.h"
-#include <iostream>
-#include <vector>
-	
-arch_Zip::arch_Zip(const string& aFileName)
-{
-	//check if file exists
-	int lFileDesc = open(aFileName.c_str(), O_RDONLY);
-	string lGoodName;
-	bool bFound = false;
-
-	if(lFileDesc == -1)
-	{
-		mSize = 0;
-		return;
-	}
-	
-	close(lFileDesc);
-	
-	// file exists.
-	string lCommand = "unzip -l -qq \"" + aFileName + '\"';   //get info
-	FILE *f = popen(lCommand.c_str(), "r");
-
-	if(f <= 0)
-	{
-		mSize = 0;
-		return;
-	}
-	
-
-	bool eof = false;
-	while(!eof)
-	{
-		char line[301];
-		char lUncompName[300];
-		if (fgets(line, 300, f) <= 0) 
-		{
-			eof = true;
-			break;
-		}
-		
-		if (processLine(line, &mSize, lUncompName))
-		{
-			lGoodName = lUncompName;
-			bFound = true;
-			break;
-		}
-		
-	}
-	if(!bFound)
-	{
-		mSize = 0;
-		return;
-	}
-
-	pclose(f);
-	
-	mMap = new char[mSize];
-	
-	lCommand = "unzip -p \"" + aFileName + "\" \"" + lGoodName + '\"';
-	//decompress to stdout
-	f = popen(lCommand.c_str(), "r");
-	
-	if (f <= 0)
-	{
-		mSize = 0;
-		return;
-	}
-
-	fread((char *)mMap, sizeof(char), mSize, f);
-	
-	pclose(f);
-	
-}
-
-bool arch_Zip::processLine(char *buffer, uint32 *mSize, char *filename)
-{
-	uint32 mlSize;
-	mlSize = 0;
-
-	if (sscanf(buffer, "%u %*s %*s %s\n", &mlSize, &filename[0]) <= 0)
-		return false;
-		
-	*mSize = mlSize;
-	string lName = filename;
-
-	// size date time name
-	return IsOurFile(lName);	
-}
-
-arch_Zip::~arch_Zip()
-{
-	if(mSize != 0)
-		delete [] (char*)mMap;
-}
-	
-bool arch_Zip::ContainsMod(const string& aFileName)
-{
-	int lFileDesc = open(aFileName.c_str(), O_RDONLY);
-
-	if(lFileDesc == -1)
-		return false;
-	
-	close(lFileDesc);
-	
-	// file exists.
-	string lCommand = "unzip -l -qq \"" + aFileName + '\"';   //get info
-	FILE *f = popen(lCommand.c_str(), "r");
-
-	if(f <= 0)
-		return false;
-	
-	bool eof = false;
-	while(!eof)
-	{
-		char line[301], lName[300];
-		if (fgets(line, 300, f) <= 0) 
-			return false;
-		
-		uint32 tempSize;
-		// Simplification of previous if statement
-		pclose(f);
-		return (processLine(line, &tempSize, lName));
-		
-	}
-
-	pclose(f);	
-	return false;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/modplug/archive/arch_zip.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,143 @@
+/* Modplug XMMS Plugin
+ * Authors: Kenton Varda <temporal@gauge3d.org>
+ *
+ * This source code is public domain.
+ */
+
+//open()
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "arch_zip.h"
+#include <iostream>
+#include <vector>
+	
+arch_Zip::arch_Zip(const string& aFileName)
+{
+	//check if file exists
+	int lFileDesc = open(aFileName.c_str(), O_RDONLY);
+	string lGoodName;
+	bool bFound = false;
+
+	if(lFileDesc == -1)
+	{
+		mSize = 0;
+		return;
+	}
+	
+	close(lFileDesc);
+	
+	// file exists.
+	string lCommand = "unzip -l -qq \"" + aFileName + '\"';   //get info
+	FILE *f = popen(lCommand.c_str(), "r");
+
+	if(f <= 0)
+	{
+		mSize = 0;
+		return;
+	}
+	
+
+	bool eof = false;
+	while(!eof)
+	{
+		char line[301];
+		char lUncompName[300];
+		if (fgets(line, 300, f) <= 0) 
+		{
+			eof = true;
+			break;
+		}
+		
+		if (processLine(line, &mSize, lUncompName))
+		{
+			lGoodName = lUncompName;
+			bFound = true;
+			break;
+		}
+		
+	}
+	if(!bFound)
+	{
+		mSize = 0;
+		return;
+	}
+
+	pclose(f);
+	
+	mMap = new char[mSize];
+	
+	lCommand = "unzip -p \"" + aFileName + "\" \"" + lGoodName + '\"';
+	//decompress to stdout
+	f = popen(lCommand.c_str(), "r");
+	
+	if (f <= 0)
+	{
+		mSize = 0;
+		return;
+	}
+
+	fread((char *)mMap, sizeof(char), mSize, f);
+	
+	pclose(f);
+	
+}
+
+bool arch_Zip::processLine(char *buffer, uint32 *mSize, char *filename)
+{
+	uint32 mlSize;
+	mlSize = 0;
+
+	if (sscanf(buffer, "%u %*s %*s %s\n", &mlSize, &filename[0]) <= 0)
+		return false;
+		
+	*mSize = mlSize;
+	string lName = filename;
+
+	// size date time name
+	return IsOurFile(lName);	
+}
+
+arch_Zip::~arch_Zip()
+{
+	if(mSize != 0)
+		delete [] (char*)mMap;
+}
+	
+bool arch_Zip::ContainsMod(const string& aFileName)
+{
+	int lFileDesc = open(aFileName.c_str(), O_RDONLY);
+
+	if(lFileDesc == -1)
+		return false;
+	
+	close(lFileDesc);
+	
+	// file exists.
+	string lCommand = "unzip -l -qq \"" + aFileName + '\"';   //get info
+	FILE *f = popen(lCommand.c_str(), "r");
+
+	if(f <= 0)
+		return false;
+	
+	bool eof = false;
+	while(!eof)
+	{
+		char line[301], lName[300];
+		if (fgets(line, 300, f) <= 0) 
+			return false;
+		
+		uint32 tempSize;
+		// Simplification of previous if statement
+		pclose(f);
+		return (processLine(line, &tempSize, lName));
+		
+	}
+
+	pclose(f);	
+	return false;
+}
--- a/Plugins/Input/modplug/archive/archive.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/* Modplug XMMS Plugin
- * Authors: Kenton Varda <temporal@gauge3d.org>
- *
- * This source code is public domain.
- */
-
-#include "archive.h"
-
-
-
-///* Open a read pipe */ File f;
-//f=popen("gzip -d compressed.file.name","r");
-///* Read some data in the usual manner, for example */
-//fscanf(f,"%d %f %f",name,&age,$id);
-///* Close the pipe */
-//pclose(f); 
-
-Archive::~Archive()
-{
-}
-
-bool Archive::IsOurFile(const string& aFileName)
-{
-	string lExt;
-	uint32 lPos;
-
-	lPos = aFileName.find_last_of('.');
-	if((int)lPos == -1)
-		return false;
-	lExt = aFileName.substr(lPos);
-	for(uint32 i = 0; i < lExt.length(); i++)
-		lExt[i] = tolower(lExt[i]);
-
-	if (lExt == ".669")
-		return true;
-	if (lExt == ".amf")
-		return true;
-	if (lExt == ".ams")
-		return true;
-	if (lExt == ".dbm")
-		return true;
-	if (lExt == ".dbf")
-		return true;
-	if (lExt == ".dsm")
-		return true;
-	if (lExt == ".far")
-		return true;
-	if (lExt == ".it")
-		return true;
-	if (lExt == ".mdl")
-		return true;
-	if (lExt == ".med")
-		return true;
-	if (lExt == ".mod")
-		return true;
-	if (lExt == ".mtm")
-		return true;
-	if (lExt == ".okt")
-		return true;
-	if (lExt == ".ptm")
-		return true;
-	if (lExt == ".s3m")
-		return true;
-	if (lExt == ".stm")
-		return true;
-	if (lExt == ".ult")
-		return true;
-	if (lExt == ".umx")      //Unreal rocks!
-		return true;
-	if (lExt == ".xm")
-		return true;
-	if (lExt == ".j2b")
-		return true;
-	if (lExt == ".mt2")
-		return true;
-	if (lExt == ".psm")
-		return true;
-	
-	return false;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/modplug/archive/archive.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,80 @@
+/* Modplug XMMS Plugin
+ * Authors: Kenton Varda <temporal@gauge3d.org>
+ *
+ * This source code is public domain.
+ */
+
+#include "archive.h"
+
+
+
+///* Open a read pipe */ File f;
+//f=popen("gzip -d compressed.file.name","r");
+///* Read some data in the usual manner, for example */
+//fscanf(f,"%d %f %f",name,&age,$id);
+///* Close the pipe */
+//pclose(f); 
+
+Archive::~Archive()
+{
+}
+
+bool Archive::IsOurFile(const string& aFileName)
+{
+	string lExt;
+	uint32 lPos;
+
+	lPos = aFileName.find_last_of('.');
+	if((int)lPos == -1)
+		return false;
+	lExt = aFileName.substr(lPos);
+	for(uint32 i = 0; i < lExt.length(); i++)
+		lExt[i] = tolower(lExt[i]);
+
+	if (lExt == ".669")
+		return true;
+	if (lExt == ".amf")
+		return true;
+	if (lExt == ".ams")
+		return true;
+	if (lExt == ".dbm")
+		return true;
+	if (lExt == ".dbf")
+		return true;
+	if (lExt == ".dsm")
+		return true;
+	if (lExt == ".far")
+		return true;
+	if (lExt == ".it")
+		return true;
+	if (lExt == ".mdl")
+		return true;
+	if (lExt == ".med")
+		return true;
+	if (lExt == ".mod")
+		return true;
+	if (lExt == ".mtm")
+		return true;
+	if (lExt == ".okt")
+		return true;
+	if (lExt == ".ptm")
+		return true;
+	if (lExt == ".s3m")
+		return true;
+	if (lExt == ".stm")
+		return true;
+	if (lExt == ".ult")
+		return true;
+	if (lExt == ".umx")      //Unreal rocks!
+		return true;
+	if (lExt == ".xm")
+		return true;
+	if (lExt == ".j2b")
+		return true;
+	if (lExt == ".mt2")
+		return true;
+	if (lExt == ".psm")
+		return true;
+	
+	return false;
+}
--- a/Plugins/Input/modplug/archive/open.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/* Modplug XMMS Plugin
- * Authors: Kenton Varda <temporal@gauge3d.org>
- *
- * This source code is public domain.
- */
-
-#include "open.h"
-#include "arch_raw.h"
-#include "arch_gzip.h"
-#include "arch_zip.h"
-#include "arch_rar.h"
-#include "arch_bz2.h"
-
-Archive* OpenArchive(const string& aFileName)
-{
-	string lExt;
-	uint32 lPos;
-
-	lPos = aFileName.find_last_of('.');
-	if(lPos > aFileName.length())
-		return NULL;
-	lExt = aFileName.substr(lPos);
-	for(uint32 i = 0; i < lExt.length(); i++)
-		lExt[i] = tolower(lExt[i]);
-
-	if (lExt == ".mdz")
-		return new arch_Zip(aFileName);
-	if (lExt == ".mdr")
-		return new arch_Rar(aFileName);
-	if (lExt == ".mdgz")
-		return new arch_Gzip(aFileName);
-	if (lExt == ".mdbz")
-		return new arch_Bzip2(aFileName);
-	if (lExt == ".s3z")
-		return new arch_Zip(aFileName);
-	if (lExt == ".s3r")
-		return new arch_Rar(aFileName);
-	if (lExt == ".s3gz")
-		return new arch_Gzip(aFileName);
-	if (lExt == ".xmz")
-		return new arch_Zip(aFileName);
-	if (lExt == ".xmr")
-		return new arch_Rar(aFileName);
-	if (lExt == ".xmgz")
-		return new arch_Gzip(aFileName);
-	if (lExt == ".itz")
-		return new arch_Zip(aFileName);
-	if (lExt == ".itr")
-		return new arch_Rar(aFileName);
-	if (lExt == ".itgz")
-		return new arch_Gzip(aFileName);
-	if (lExt == ".zip")
-		return new arch_Zip(aFileName);
-	if (lExt == ".rar")
-		return new arch_Rar(aFileName);
-	if (lExt == ".gz")
-		return new arch_Gzip(aFileName);
-	if (lExt == ".bz2")
-		return new arch_Bzip2(aFileName);
-
-	return new arch_Raw(aFileName);
-}
-
-bool ContainsMod(const string& aFileName)
-{
-	string lExt;
-	uint32 lPos;
-
-	lPos = aFileName.find_last_of('.');
-	if(lPos > aFileName.length())
-		return false;
-	lExt = aFileName.substr(lPos);
-	for(uint32 i = 0; i < lExt.length(); i++)
-		lExt[i] = tolower(lExt[i]);
-
-	if (lExt == ".mdz")
-		return arch_Zip::ContainsMod(aFileName);
-	if (lExt == ".mdr")
-		return arch_Rar::ContainsMod(aFileName);
-	if (lExt == ".mdgz")
-		return arch_Gzip::ContainsMod(aFileName);
-	if (lExt == ".mdbz")
-		return arch_Bzip2::ContainsMod(aFileName);
-	if (lExt == ".s3z")
-		return arch_Zip::ContainsMod(aFileName);
-	if (lExt == ".s3r")
-		return arch_Rar::ContainsMod(aFileName);
-	if (lExt == ".s3gz")
-		return arch_Gzip::ContainsMod(aFileName);
-	if (lExt == ".xmz")
-		return arch_Zip::ContainsMod(aFileName);
-	if (lExt == ".xmr")
-		return arch_Rar::ContainsMod(aFileName);
-	if (lExt == ".xmgz")
-		return arch_Gzip::ContainsMod(aFileName);
-	if (lExt == ".itz")
-		return arch_Zip::ContainsMod(aFileName);
-	if (lExt == ".itr")
-		return arch_Rar::ContainsMod(aFileName);
-	if (lExt == ".itgz")
-		return arch_Gzip::ContainsMod(aFileName);
-	if (lExt == ".zip")
-		return arch_Zip::ContainsMod(aFileName);
-	if (lExt == ".rar")
-		return arch_Rar::ContainsMod(aFileName);
-	if (lExt == ".gz")
-		return arch_Gzip::ContainsMod(aFileName);
-	if (lExt == ".bz2")
-		return arch_Bzip2::ContainsMod(aFileName);
-
-	return arch_Raw::ContainsMod(aFileName);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/modplug/archive/open.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,112 @@
+/* Modplug XMMS Plugin
+ * Authors: Kenton Varda <temporal@gauge3d.org>
+ *
+ * This source code is public domain.
+ */
+
+#include "open.h"
+#include "arch_raw.h"
+#include "arch_gzip.h"
+#include "arch_zip.h"
+#include "arch_rar.h"
+#include "arch_bz2.h"
+
+Archive* OpenArchive(const string& aFileName)
+{
+	string lExt;
+	uint32 lPos;
+
+	lPos = aFileName.find_last_of('.');
+	if(lPos > aFileName.length())
+		return NULL;
+	lExt = aFileName.substr(lPos);
+	for(uint32 i = 0; i < lExt.length(); i++)
+		lExt[i] = tolower(lExt[i]);
+
+	if (lExt == ".mdz")
+		return new arch_Zip(aFileName);
+	if (lExt == ".mdr")
+		return new arch_Rar(aFileName);
+	if (lExt == ".mdgz")
+		return new arch_Gzip(aFileName);
+	if (lExt == ".mdbz")
+		return new arch_Bzip2(aFileName);
+	if (lExt == ".s3z")
+		return new arch_Zip(aFileName);
+	if (lExt == ".s3r")
+		return new arch_Rar(aFileName);
+	if (lExt == ".s3gz")
+		return new arch_Gzip(aFileName);
+	if (lExt == ".xmz")
+		return new arch_Zip(aFileName);
+	if (lExt == ".xmr")
+		return new arch_Rar(aFileName);
+	if (lExt == ".xmgz")
+		return new arch_Gzip(aFileName);
+	if (lExt == ".itz")
+		return new arch_Zip(aFileName);
+	if (lExt == ".itr")
+		return new arch_Rar(aFileName);
+	if (lExt == ".itgz")
+		return new arch_Gzip(aFileName);
+	if (lExt == ".zip")
+		return new arch_Zip(aFileName);
+	if (lExt == ".rar")
+		return new arch_Rar(aFileName);
+	if (lExt == ".gz")
+		return new arch_Gzip(aFileName);
+	if (lExt == ".bz2")
+		return new arch_Bzip2(aFileName);
+
+	return new arch_Raw(aFileName);
+}
+
+bool ContainsMod(const string& aFileName)
+{
+	string lExt;
+	uint32 lPos;
+
+	lPos = aFileName.find_last_of('.');
+	if(lPos > aFileName.length())
+		return false;
+	lExt = aFileName.substr(lPos);
+	for(uint32 i = 0; i < lExt.length(); i++)
+		lExt[i] = tolower(lExt[i]);
+
+	if (lExt == ".mdz")
+		return arch_Zip::ContainsMod(aFileName);
+	if (lExt == ".mdr")
+		return arch_Rar::ContainsMod(aFileName);
+	if (lExt == ".mdgz")
+		return arch_Gzip::ContainsMod(aFileName);
+	if (lExt == ".mdbz")
+		return arch_Bzip2::ContainsMod(aFileName);
+	if (lExt == ".s3z")
+		return arch_Zip::ContainsMod(aFileName);
+	if (lExt == ".s3r")
+		return arch_Rar::ContainsMod(aFileName);
+	if (lExt == ".s3gz")
+		return arch_Gzip::ContainsMod(aFileName);
+	if (lExt == ".xmz")
+		return arch_Zip::ContainsMod(aFileName);
+	if (lExt == ".xmr")
+		return arch_Rar::ContainsMod(aFileName);
+	if (lExt == ".xmgz")
+		return arch_Gzip::ContainsMod(aFileName);
+	if (lExt == ".itz")
+		return arch_Zip::ContainsMod(aFileName);
+	if (lExt == ".itr")
+		return arch_Rar::ContainsMod(aFileName);
+	if (lExt == ".itgz")
+		return arch_Gzip::ContainsMod(aFileName);
+	if (lExt == ".zip")
+		return arch_Zip::ContainsMod(aFileName);
+	if (lExt == ".rar")
+		return arch_Rar::ContainsMod(aFileName);
+	if (lExt == ".gz")
+		return arch_Gzip::ContainsMod(aFileName);
+	if (lExt == ".bz2")
+		return arch_Bzip2::ContainsMod(aFileName);
+
+	return arch_Raw::ContainsMod(aFileName);
+}
--- a/Plugins/Input/modplug/gui/Makefile.in	Sat Sep 16 07:18:18 2006 -0700
+++ b/Plugins/Input/modplug/gui/Makefile.in	Sat Sep 16 07:33:28 2006 -0700
@@ -5,8 +5,8 @@
 CXXFLAGS += $(PICFLAGS) $(GTK_CFLAGS) -I../../../../intl -I../../../..
 
 OBJECTIVE_LIBS_NOINST = libgui.a
-SOURCES = main.cpp support.cpp interface.cpp callbacks.cpp
+SOURCES = main.cxx support.cxx interface.cxx callbacks.cxx
 
-OBJECTS = ${SOURCES:.cpp=.o}
+OBJECTS = ${SOURCES:.cxx=.o}
 
 include ../../../../mk/objective.mk
--- a/Plugins/Input/modplug/gui/callbacks.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include <gtk/gtk.h>
-#include <iostream>
-
-#include "callbacks.h"
-#include "interface.h"
-#include "support.h"
-
-#include "../modplugbmp.h"
-
-
-gboolean
-hide_window                            (GtkWidget       *widget,
-                                        GdkEvent        *event,
-                                        gpointer         user_data)
-{
-	gtk_widget_hide(widget);
-	return TRUE;
-}
-
-
-void
-on_config_apply_clicked                (GtkButton       *button,
-                                        gpointer         user_data)
-{
-	ModplugXMMS::Settings lProps;
-	
-	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "bit8")))
-		lProps.mBits = 8;
-	else
-		lProps.mBits = 16;
-	
-	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "samp11")))
-		lProps.mFrequency = 11025;
-	else if (gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "samp22")))
-		lProps.mFrequency = 22050;
-	else if (gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "samp48")))
-		lProps.mFrequency = 48000;
-	else
-		lProps.mFrequency = 44100;
-	
-	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "resampNearest")))
-		lProps.mResamplingMode = 0;
-	else if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "resampLinear")))
-		lProps.mResamplingMode = 1;
-	else if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "resampSpline")))
-		lProps.mResamplingMode = 2;
-	else
-		lProps.mResamplingMode = 3;
-	
-	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "mono")))
-		lProps.mChannels = 1;
-	else
-		lProps.mChannels = 2;
-	
-	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxNR")))
-		lProps.mNoiseReduction = true;
-	else
-		lProps.mNoiseReduction = false;
-	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxAmigaMOD")))
-		lProps.mGrabAmigaMOD = true;
-	else
-		lProps.mGrabAmigaMOD = false;
-	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxFastInfo")))
-		lProps.mFastinfo       = true;
-	else
-		lProps.mFastinfo       = false;
-	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxUseFilename")))
-		lProps.mUseFilename    = true;
-	else
-		lProps.mUseFilename    = false;
-	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxReverb")))
-		lProps.mReverb         = true;
-	else
-		lProps.mReverb         = false;
-	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxBassBoost")))
-		lProps.mMegabass       = true;
-	else
-		lProps.mMegabass       = false;
-	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxSurround")))
-		lProps.mSurround       = true;
-	else
-		lProps.mSurround       = false;
-	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxPreamp")))
-		lProps.mPreamp         = true;
-	else
-		lProps.mPreamp         = false;
-	
-	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxLoopForever")))
-		lProps.mLoopCount = -1;
-	else if (gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxLoopFinite")))
-	{
-		lProps.mLoopCount =
-			(uint32)gtk_spin_button_get_adjustment(
-			(GtkSpinButton*)lookup_widget((GtkWidget*)button, "fxLoopCount"))->value;
-	}
-	else
-		lProps.mLoopCount = 0;
-	
-	//hmm...  GTK objects have un-protected data members?  That's not good...
-	lProps.mReverbDepth =
-		(uint32)gtk_range_get_adjustment((GtkRange*)lookup_widget((GtkWidget*)button, "fxReverbDepth"))->value;
-	lProps.mReverbDelay =
-		(uint32)gtk_range_get_adjustment((GtkRange*)lookup_widget((GtkWidget*)button, "fxReverbDelay"))->value;
-	lProps.mBassAmount =
-		(uint32)gtk_range_get_adjustment((GtkRange*)lookup_widget((GtkWidget*)button, "fxBassAmount"))->value;
-	lProps.mBassRange =
-		(uint32)gtk_range_get_adjustment((GtkRange*)lookup_widget((GtkWidget*)button, "fxBassRange"))->value;
-	lProps.mSurroundDepth =
-		(uint32)gtk_range_get_adjustment((GtkRange*)lookup_widget((GtkWidget*)button, "fxSurroundDepth"))->value;
-	lProps.mSurroundDelay =
-		(uint32)gtk_range_get_adjustment((GtkRange*)lookup_widget((GtkWidget*)button, "fxSurroundDelay"))->value;
-	lProps.mPreampLevel =
-		(float)gtk_range_get_adjustment((GtkRange*)lookup_widget((GtkWidget*)button, "fxPreampLevel"))->value;
-	
-	gModplugXMMS.SetModProps(lProps);
-}
-
-
-void
-on_config_ok_clicked                   (GtkButton       *button,
-                                        gpointer         user_data)
-{
-	GtkWidget* lConfigWindow;
-	
-	on_config_apply_clicked(button, user_data);
-	
-	lConfigWindow = lookup_widget((GtkWidget*)button, "Config");
-	if(!lConfigWindow)
-		cerr << "ModPlug: on_config_ok_clicked: Could not find config window!" << endl;
-	else
-		gtk_widget_hide(lConfigWindow);
-}
-
-
-void
-on_config_cancel_clicked               (GtkButton       *button,
-                                        gpointer         user_data)
-{
-	GtkWidget* lConfigWindow;
-	
-	lConfigWindow = lookup_widget((GtkWidget*)button, "Config");
-	if(!lConfigWindow)
-		cerr << "ModPlug: on_config_ok_clicked: Could not find config window!" << endl;
-	else
-		gtk_widget_hide(lConfigWindow);
-}
-
-
-void
-on_info_close_clicked                  (GtkButton       *button,
-                                        gpointer         user_data)
-{
-	GtkWidget* lInfoWindow;
-	
-	lInfoWindow = lookup_widget((GtkWidget*)button, "Info");
-	if(!lInfoWindow)
-		cerr << "ModPlug: on_info_close_clicked: Could not find info window!" << endl;
-	else
-		gtk_widget_hide(lInfoWindow);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/modplug/gui/callbacks.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,164 @@
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <iostream>
+
+#include "callbacks.h"
+#include "interface.h"
+#include "support.h"
+
+#include "../modplugbmp.h"
+
+
+gboolean
+hide_window                            (GtkWidget       *widget,
+                                        GdkEvent        *event,
+                                        gpointer         user_data)
+{
+	gtk_widget_hide(widget);
+	return TRUE;
+}
+
+
+void
+on_config_apply_clicked                (GtkButton       *button,
+                                        gpointer         user_data)
+{
+	ModplugXMMS::Settings lProps;
+	
+	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "bit8")))
+		lProps.mBits = 8;
+	else
+		lProps.mBits = 16;
+	
+	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "samp11")))
+		lProps.mFrequency = 11025;
+	else if (gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "samp22")))
+		lProps.mFrequency = 22050;
+	else if (gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "samp48")))
+		lProps.mFrequency = 48000;
+	else
+		lProps.mFrequency = 44100;
+	
+	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "resampNearest")))
+		lProps.mResamplingMode = 0;
+	else if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "resampLinear")))
+		lProps.mResamplingMode = 1;
+	else if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "resampSpline")))
+		lProps.mResamplingMode = 2;
+	else
+		lProps.mResamplingMode = 3;
+	
+	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "mono")))
+		lProps.mChannels = 1;
+	else
+		lProps.mChannels = 2;
+	
+	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxNR")))
+		lProps.mNoiseReduction = true;
+	else
+		lProps.mNoiseReduction = false;
+	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxAmigaMOD")))
+		lProps.mGrabAmigaMOD = true;
+	else
+		lProps.mGrabAmigaMOD = false;
+	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxFastInfo")))
+		lProps.mFastinfo       = true;
+	else
+		lProps.mFastinfo       = false;
+	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxUseFilename")))
+		lProps.mUseFilename    = true;
+	else
+		lProps.mUseFilename    = false;
+	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxReverb")))
+		lProps.mReverb         = true;
+	else
+		lProps.mReverb         = false;
+	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxBassBoost")))
+		lProps.mMegabass       = true;
+	else
+		lProps.mMegabass       = false;
+	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxSurround")))
+		lProps.mSurround       = true;
+	else
+		lProps.mSurround       = false;
+	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxPreamp")))
+		lProps.mPreamp         = true;
+	else
+		lProps.mPreamp         = false;
+	
+	if(gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxLoopForever")))
+		lProps.mLoopCount = -1;
+	else if (gtk_toggle_button_get_active((GtkToggleButton*)lookup_widget((GtkWidget*)button, "fxLoopFinite")))
+	{
+		lProps.mLoopCount =
+			(uint32)gtk_spin_button_get_adjustment(
+			(GtkSpinButton*)lookup_widget((GtkWidget*)button, "fxLoopCount"))->value;
+	}
+	else
+		lProps.mLoopCount = 0;
+	
+	//hmm...  GTK objects have un-protected data members?  That's not good...
+	lProps.mReverbDepth =
+		(uint32)gtk_range_get_adjustment((GtkRange*)lookup_widget((GtkWidget*)button, "fxReverbDepth"))->value;
+	lProps.mReverbDelay =
+		(uint32)gtk_range_get_adjustment((GtkRange*)lookup_widget((GtkWidget*)button, "fxReverbDelay"))->value;
+	lProps.mBassAmount =
+		(uint32)gtk_range_get_adjustment((GtkRange*)lookup_widget((GtkWidget*)button, "fxBassAmount"))->value;
+	lProps.mBassRange =
+		(uint32)gtk_range_get_adjustment((GtkRange*)lookup_widget((GtkWidget*)button, "fxBassRange"))->value;
+	lProps.mSurroundDepth =
+		(uint32)gtk_range_get_adjustment((GtkRange*)lookup_widget((GtkWidget*)button, "fxSurroundDepth"))->value;
+	lProps.mSurroundDelay =
+		(uint32)gtk_range_get_adjustment((GtkRange*)lookup_widget((GtkWidget*)button, "fxSurroundDelay"))->value;
+	lProps.mPreampLevel =
+		(float)gtk_range_get_adjustment((GtkRange*)lookup_widget((GtkWidget*)button, "fxPreampLevel"))->value;
+	
+	gModplugXMMS.SetModProps(lProps);
+}
+
+
+void
+on_config_ok_clicked                   (GtkButton       *button,
+                                        gpointer         user_data)
+{
+	GtkWidget* lConfigWindow;
+	
+	on_config_apply_clicked(button, user_data);
+	
+	lConfigWindow = lookup_widget((GtkWidget*)button, "Config");
+	if(!lConfigWindow)
+		cerr << "ModPlug: on_config_ok_clicked: Could not find config window!" << endl;
+	else
+		gtk_widget_hide(lConfigWindow);
+}
+
+
+void
+on_config_cancel_clicked               (GtkButton       *button,
+                                        gpointer         user_data)
+{
+	GtkWidget* lConfigWindow;
+	
+	lConfigWindow = lookup_widget((GtkWidget*)button, "Config");
+	if(!lConfigWindow)
+		cerr << "ModPlug: on_config_ok_clicked: Could not find config window!" << endl;
+	else
+		gtk_widget_hide(lConfigWindow);
+}
+
+
+void
+on_info_close_clicked                  (GtkButton       *button,
+                                        gpointer         user_data)
+{
+	GtkWidget* lInfoWindow;
+	
+	lInfoWindow = lookup_widget((GtkWidget*)button, "Info");
+	if(!lInfoWindow)
+		cerr << "ModPlug: on_info_close_clicked: Could not find info window!" << endl;
+	else
+		gtk_widget_hide(lInfoWindow);
+}
--- a/Plugins/Input/modplug/gui/interface.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,963 +0,0 @@
-/*
- * DO NOT EDIT THIS FILE - it is generated by Glade.
- */
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-
-#include "callbacks.h"
-#include "interface.h"
-#include "support.h"
-
-GtkWidget*
-create_Config (void)
-{
-  GtkWidget *Config;
-  GtkWidget *vbox2;
-  GtkWidget *notebook1;
-  GtkWidget *vbox3;
-  GtkWidget *hbox2;
-  GtkWidget *frame1;
-  GtkWidget *vbox4;
-  GSList *vbox4_group = NULL;
-  GtkWidget *bit16;
-  GtkWidget *bit8;
-  GtkWidget *frame2;
-  GtkWidget *vbox5;
-  GSList *vbox5_group = NULL;
-  GtkWidget *stereo;
-  GtkWidget *mono;
-  GtkWidget *hbox10;
-  GtkWidget *frame3;
-  GtkWidget *vbox6;
-  GSList *vbox6_group = NULL;
-  GtkWidget *samp48;
-  GtkWidget *samp44;
-  GtkWidget *samp22;
-  GtkWidget *samp11;
-  GtkWidget *frame9;
-  GtkWidget *vbox15;
-  GSList *vbox15_group = NULL;
-  GtkWidget *resampNearest;
-  GtkWidget *resampLinear;
-  GtkWidget *resampSpline;
-  GtkWidget *resampPolyphase;
-  GtkWidget *label2;
-  GtkWidget *vbox7;
-  GtkWidget *frame4;
-  GtkWidget *hbox3;
-  GtkWidget *vbox8;
-  GtkWidget *fxUseFilename;
-  GtkWidget *fxFastInfo;
-  GtkWidget *vbox9;
-  GtkWidget *fxNR;
-  GtkWidget *fxAmigaMOD;
-  GtkWidget *frame5;
-  GtkWidget *hbox4;
-  GtkWidget *fxReverb;
-  GtkWidget *vbox10;
-  GtkWidget *table1;
-  GtkWidget *fxReverbDepth;
-  GtkWidget *fxReverbDelay;
-  GtkWidget *label3;
-  GtkWidget *label4;
-  GtkWidget *frame6;
-  GtkWidget *hbox5;
-  GtkWidget *fxBassBoost;
-  GtkWidget *vbox11;
-  GtkWidget *table2;
-  GtkWidget *fxBassAmount;
-  GtkWidget *fxBassRange;
-  GtkWidget *label5;
-  GtkWidget *label6;
-  GtkWidget *frame7;
-  GtkWidget *hbox6;
-  GtkWidget *fxSurround;
-  GtkWidget *vbox12;
-  GtkWidget *table3;
-  GtkWidget *fxSurroundDepth;
-  GtkWidget *fxSurroundDelay;
-  GtkWidget *label7;
-  GtkWidget *label8;
-  GtkWidget *frame10;
-  GtkWidget *vbox16;
-  GtkWidget *label20;
-  GtkWidget *hbox11;
-  GtkWidget *fxPreamp;
-  GtkWidget *label19;
-  GtkWidget *fxPreampLevel;
-  GtkWidget *frame11;
-  GtkWidget *vbox17;
-  GSList *loopGroup_group = NULL;
-  GtkWidget *fxNoLoop;
-  GtkWidget *hbox13;
-  GtkWidget *fxLoopFinite;
-  GtkObject *fxLoopCount_adj;
-  GtkWidget *fxLoopCount;
-  GtkWidget *label21;
-  GtkWidget *fxLoopForever;
-  GtkWidget *label10;
-  GtkWidget *hbuttonbox2;
-  GtkWidget *config_ok;
-  GtkWidget *config_apply;
-  GtkWidget *config_cancel;
-
-  Config = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  gtk_object_set_data (GTK_OBJECT (Config), "Config", Config);
-  gtk_widget_set_usize (Config, 350, -2);
-  gtk_window_set_title (GTK_WINDOW (Config), _("ModPlug Configuration"));
-  gtk_window_set_policy (GTK_WINDOW (Config), FALSE, FALSE, FALSE);
-
-  vbox2 = gtk_vbox_new (FALSE, 0);
-  gtk_container_set_border_width(GTK_CONTAINER(vbox2),5);
-  gtk_widget_ref (vbox2);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox2", vbox2,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (vbox2);
-  gtk_container_add (GTK_CONTAINER (Config), vbox2);
-
-  notebook1 = gtk_notebook_new ();
-  gtk_widget_ref (notebook1);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "notebook1", notebook1,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (notebook1);
-  gtk_box_pack_start (GTK_BOX (vbox2), notebook1, TRUE, TRUE, 5);
-  gtk_container_set_border_width (GTK_CONTAINER (notebook1), 0);
-
-  vbox3 = gtk_vbox_new (FALSE, 0);
-  gtk_widget_ref (vbox3);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox3", vbox3,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (vbox3);
-  gtk_container_add (GTK_CONTAINER (notebook1), vbox3);
-  gtk_container_set_border_width (GTK_CONTAINER (vbox3), 6);
-
-  hbox2 = gtk_hbox_new (FALSE, 0);
-  gtk_widget_ref (hbox2);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "hbox2", hbox2,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (hbox2);
-  gtk_box_pack_start (GTK_BOX (vbox3), hbox2, TRUE, TRUE, 0);
-
-  frame1 = gtk_frame_new (_("Resolution"));
-  gtk_widget_ref (frame1);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "frame1", frame1,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (frame1);
-  gtk_box_pack_start (GTK_BOX (hbox2), frame1, TRUE, TRUE, 0);
-
-  vbox4 = gtk_vbox_new (FALSE, 0);
-  gtk_widget_ref (vbox4);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox4", vbox4,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (vbox4);
-  gtk_container_add (GTK_CONTAINER (frame1), vbox4);
-
-  bit16 = gtk_radio_button_new_with_label (vbox4_group, _("16 bit"));
-  vbox4_group = gtk_radio_button_group (GTK_RADIO_BUTTON (bit16));
-  gtk_widget_ref (bit16);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "bit16", bit16,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (bit16);
-  gtk_box_pack_start (GTK_BOX (vbox4), bit16, FALSE, FALSE, 0);
-
-  bit8 = gtk_radio_button_new_with_label (vbox4_group, _("8 bit"));
-  vbox4_group = gtk_radio_button_group (GTK_RADIO_BUTTON (bit8));
-  gtk_widget_ref (bit8);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "bit8", bit8,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (bit8);
-  gtk_box_pack_start (GTK_BOX (vbox4), bit8, FALSE, FALSE, 0);
-
-  frame2 = gtk_frame_new (_("Channels"));
-  gtk_widget_ref (frame2);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "frame2", frame2,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (frame2);
-  gtk_box_pack_start (GTK_BOX (hbox2), frame2, TRUE, TRUE, 0);
-
-  vbox5 = gtk_vbox_new (FALSE, 0);
-  gtk_widget_ref (vbox5);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox5", vbox5,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (vbox5);
-  gtk_container_add (GTK_CONTAINER (frame2), vbox5);
-
-  stereo = gtk_radio_button_new_with_label (vbox5_group, _("Stereo"));
-  vbox5_group = gtk_radio_button_group (GTK_RADIO_BUTTON (stereo));
-  gtk_widget_ref (stereo);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "stereo", stereo,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (stereo);
-  gtk_box_pack_start (GTK_BOX (vbox5), stereo, FALSE, FALSE, 0);
-
-  mono = gtk_radio_button_new_with_label (vbox5_group, _("Mono (downmix)"));
-  vbox5_group = gtk_radio_button_group (GTK_RADIO_BUTTON (mono));
-  gtk_widget_ref (mono);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "mono", mono,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (mono);
-  gtk_box_pack_start (GTK_BOX (vbox5), mono, FALSE, FALSE, 0);
-
-  hbox10 = gtk_hbox_new (FALSE, 0);
-  gtk_widget_ref (hbox10);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "hbox10", hbox10,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (hbox10);
-  gtk_box_pack_start (GTK_BOX (vbox3), hbox10, TRUE, TRUE, 0);
-
-  frame3 = gtk_frame_new (_("Sampling Rate"));
-  gtk_widget_ref (frame3);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "frame3", frame3,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (frame3);
-  gtk_box_pack_start (GTK_BOX (hbox10), frame3, TRUE, TRUE, 0);
-
-  vbox6 = gtk_vbox_new (FALSE, 0);
-  gtk_widget_ref (vbox6);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox6", vbox6,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (vbox6);
-  gtk_container_add (GTK_CONTAINER (frame3), vbox6);
-
-  samp48 = gtk_radio_button_new_with_label (vbox6_group, _("48 kHz"));
-  vbox6_group = gtk_radio_button_group (GTK_RADIO_BUTTON (samp48));
-  gtk_widget_ref (samp48);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "samp48", samp48,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (samp48);
-  gtk_box_pack_start (GTK_BOX (vbox6), samp48, FALSE, FALSE, 0);
-
-  samp44 = gtk_radio_button_new_with_label (vbox6_group, _("44 kHz"));
-  vbox6_group = gtk_radio_button_group (GTK_RADIO_BUTTON (samp44));
-  gtk_widget_ref (samp44);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "samp44", samp44,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (samp44);
-  gtk_box_pack_start (GTK_BOX (vbox6), samp44, FALSE, FALSE, 0);
-
-  samp22 = gtk_radio_button_new_with_label (vbox6_group, _("22 kHz"));
-  vbox6_group = gtk_radio_button_group (GTK_RADIO_BUTTON (samp22));
-  gtk_widget_ref (samp22);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "samp22", samp22,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (samp22);
-  gtk_box_pack_start (GTK_BOX (vbox6), samp22, FALSE, FALSE, 0);
-
-  samp11 = gtk_radio_button_new_with_label (vbox6_group, _("11 kHz"));
-  vbox6_group = gtk_radio_button_group (GTK_RADIO_BUTTON (samp11));
-  gtk_widget_ref (samp11);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "samp11", samp11,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (samp11);
-  gtk_box_pack_start (GTK_BOX (vbox6), samp11, FALSE, FALSE, 0);
-
-  frame9 = gtk_frame_new (_("Resampling"));
-  gtk_widget_ref (frame9);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "frame9", frame9,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (frame9);
-  gtk_box_pack_start (GTK_BOX (hbox10), frame9, TRUE, TRUE, 0);
-
-  vbox15 = gtk_vbox_new (FALSE, 0);
-  gtk_widget_ref (vbox15);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox15", vbox15,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (vbox15);
-  gtk_container_add (GTK_CONTAINER (frame9), vbox15);
-
-  resampNearest = gtk_radio_button_new_with_label (vbox15_group, _("Nearest (fastest)"));
-  vbox15_group = gtk_radio_button_group (GTK_RADIO_BUTTON (resampNearest));
-  gtk_widget_ref (resampNearest);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "resampNearest", resampNearest,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (resampNearest);
-  gtk_box_pack_start (GTK_BOX (vbox15), resampNearest, FALSE, FALSE, 0);
-
-  resampLinear = gtk_radio_button_new_with_label (vbox15_group, _("Linear (fast)"));
-  vbox15_group = gtk_radio_button_group (GTK_RADIO_BUTTON (resampLinear));
-  gtk_widget_ref (resampLinear);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "resampLinear", resampLinear,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (resampLinear);
-  gtk_box_pack_start (GTK_BOX (vbox15), resampLinear, FALSE, FALSE, 0);
-
-  resampSpline = gtk_radio_button_new_with_label (vbox15_group, _("Spline (good quality)"));
-  vbox15_group = gtk_radio_button_group (GTK_RADIO_BUTTON (resampSpline));
-  gtk_widget_ref (resampSpline);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "resampSpline", resampSpline,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (resampSpline);
-  gtk_box_pack_start (GTK_BOX (vbox15), resampSpline, FALSE, FALSE, 0);
-
-  resampPolyphase = gtk_radio_button_new_with_label (vbox15_group, _("8-tap Fir (extremely high quality)"));
-  vbox15_group = gtk_radio_button_group (GTK_RADIO_BUTTON (resampPolyphase));
-  gtk_widget_ref (resampPolyphase);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "resampPolyphase", resampPolyphase,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (resampPolyphase);
-  gtk_box_pack_start (GTK_BOX (vbox15), resampPolyphase, FALSE, FALSE, 0);
-
-  label2 = gtk_label_new (_("Quality"));
-  gtk_widget_ref (label2);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "label2", label2,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (label2);
-  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 0), label2);
-
-  vbox7 = gtk_vbox_new (FALSE, 0);
-  gtk_widget_ref (vbox7);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox7", vbox7,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (vbox7);
-  gtk_container_add (GTK_CONTAINER (notebook1), vbox7);
-  gtk_container_set_border_width (GTK_CONTAINER (vbox7), 6);
-
-  frame4 = gtk_frame_new (_("General"));
-  gtk_widget_ref (frame4);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "frame4", frame4,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (frame4);
-  gtk_box_pack_start (GTK_BOX (vbox7), frame4, TRUE, TRUE, 0);
-
-  hbox3 = gtk_hbox_new (FALSE, 0);
-  gtk_widget_ref (hbox3);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "hbox3", hbox3,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (hbox3);
-  gtk_container_add (GTK_CONTAINER (frame4), hbox3);
-
-  vbox8 = gtk_vbox_new (FALSE, 0);
-  gtk_widget_ref (vbox8);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox8", vbox8,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (vbox8);
-  gtk_box_pack_start (GTK_BOX (hbox3), vbox8, TRUE, TRUE, 0);
-
-  fxUseFilename = gtk_check_button_new_with_label (_("Use Filename as Song Title"));
-  gtk_widget_ref (fxUseFilename);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxUseFilename", fxUseFilename,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxUseFilename);
-  gtk_box_pack_start (GTK_BOX (vbox8), fxUseFilename, FALSE, FALSE, 0);
-
-  fxFastInfo = gtk_check_button_new_with_label (_("Fast Playlist Info"));
-  gtk_widget_ref (fxFastInfo);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxFastInfo", fxFastInfo,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxFastInfo);
-  gtk_box_pack_start (GTK_BOX (vbox8), fxFastInfo, FALSE, FALSE, 0);
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fxFastInfo), TRUE);
-
-  vbox9 = gtk_vbox_new (FALSE, 0);
-  gtk_widget_ref (vbox9);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox9", vbox9,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (vbox9);
-  gtk_box_pack_start (GTK_BOX (hbox3), vbox9, TRUE, TRUE, 0);
-
-  fxNR = gtk_check_button_new_with_label (_("Noise Reduction"));
-  gtk_widget_ref (fxNR);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxNR", fxNR,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxNR);
-  gtk_box_pack_start (GTK_BOX (vbox9), fxNR, FALSE, FALSE, 0);
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fxNR), TRUE);
-
-  fxAmigaMOD = gtk_check_button_new_with_label (_("Play Amiga MOD"));
-  gtk_widget_ref (fxAmigaMOD);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxAmigaMOD", fxAmigaMOD,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxAmigaMOD);
-  gtk_box_pack_start (GTK_BOX (vbox9), fxAmigaMOD, FALSE, FALSE, 0);
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fxAmigaMOD), TRUE);
-
-  frame5 = gtk_frame_new (_("Reverb"));
-  gtk_widget_ref (frame5);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "frame5", frame5,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (frame5);
-  gtk_box_pack_start (GTK_BOX (vbox7), frame5, TRUE, TRUE, 0);
-
-  hbox4 = gtk_hbox_new (FALSE, 0);
-  gtk_widget_ref (hbox4);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "hbox4", hbox4,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (hbox4);
-  gtk_container_add (GTK_CONTAINER (frame5), hbox4);
-
-  fxReverb = gtk_check_button_new_with_label (_("Enable"));
-  gtk_widget_ref (fxReverb);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxReverb", fxReverb,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxReverb);
-  gtk_box_pack_start (GTK_BOX (hbox4), fxReverb, FALSE, FALSE, 0);
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fxReverb), TRUE);
-
-  vbox10 = gtk_vbox_new (FALSE, 0);
-  gtk_widget_ref (vbox10);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox10", vbox10,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (vbox10);
-  gtk_box_pack_start (GTK_BOX (hbox4), vbox10, TRUE, TRUE, 0);
-
-  table1 = gtk_table_new (2, 2, FALSE);
-  gtk_widget_ref (table1);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "table1", table1,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (table1);
-  gtk_box_pack_start (GTK_BOX (vbox10), table1, TRUE, TRUE, 0);
-
-  fxReverbDepth = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (30, 0, 100, 0, 0, 0)));
-  gtk_widget_ref (fxReverbDepth);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxReverbDepth", fxReverbDepth,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxReverbDepth);
-  gtk_table_attach (GTK_TABLE (table1), fxReverbDepth, 1, 2, 0, 1,
-                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
-                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
-
-  fxReverbDelay = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (90, 40, 200, 0, 0, 0)));
-  gtk_widget_ref (fxReverbDelay);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxReverbDelay", fxReverbDelay,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxReverbDelay);
-  gtk_table_attach (GTK_TABLE (table1), fxReverbDelay, 1, 2, 1, 2,
-                    (GtkAttachOptions) (GTK_FILL),
-                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
-
-  label3 = gtk_label_new (_("Depth"));
-  gtk_widget_ref (label3);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "label3", label3,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (label3);
-  gtk_table_attach (GTK_TABLE (table1), label3, 0, 1, 0, 1,
-                    (GtkAttachOptions) (0),
-                    (GtkAttachOptions) (0), 0, 0);
-
-  label4 = gtk_label_new (_("Delay"));
-  gtk_widget_ref (label4);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "label4", label4,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (label4);
-  gtk_table_attach (GTK_TABLE (table1), label4, 0, 1, 1, 2,
-                    (GtkAttachOptions) (0),
-                    (GtkAttachOptions) (0), 0, 0);
-
-  frame6 = gtk_frame_new (_("Bass Boost"));
-  gtk_widget_ref (frame6);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "frame6", frame6,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (frame6);
-  gtk_box_pack_start (GTK_BOX (vbox7), frame6, TRUE, TRUE, 0);
-
-  hbox5 = gtk_hbox_new (FALSE, 0);
-  gtk_widget_ref (hbox5);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "hbox5", hbox5,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (hbox5);
-  gtk_container_add (GTK_CONTAINER (frame6), hbox5);
-
-  fxBassBoost = gtk_check_button_new_with_label (_("Enable"));
-  gtk_widget_ref (fxBassBoost);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxBassBoost", fxBassBoost,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxBassBoost);
-  gtk_box_pack_start (GTK_BOX (hbox5), fxBassBoost, FALSE, FALSE, 0);
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fxBassBoost), TRUE);
-
-  vbox11 = gtk_vbox_new (FALSE, 0);
-  gtk_widget_ref (vbox11);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox11", vbox11,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (vbox11);
-  gtk_box_pack_start (GTK_BOX (hbox5), vbox11, TRUE, TRUE, 0);
-
-  table2 = gtk_table_new (2, 2, FALSE);
-  gtk_widget_ref (table2);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "table2", table2,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (table2);
-  gtk_box_pack_start (GTK_BOX (vbox11), table2, TRUE, TRUE, 0);
-
-  fxBassAmount = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (30, 0, 100, 0, 0, 0)));
-  gtk_widget_ref (fxBassAmount);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxBassAmount", fxBassAmount,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxBassAmount);
-  gtk_table_attach (GTK_TABLE (table2), fxBassAmount, 1, 2, 0, 1,
-                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
-                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
-
-  fxBassRange = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (30, 10, 100, 0, 0, 0)));
-  gtk_widget_ref (fxBassRange);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxBassRange", fxBassRange,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxBassRange);
-  gtk_table_attach (GTK_TABLE (table2), fxBassRange, 1, 2, 1, 2,
-                    (GtkAttachOptions) (GTK_FILL),
-                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
-
-  label5 = gtk_label_new (_("Amount"));
-  gtk_widget_ref (label5);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "label5", label5,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (label5);
-  gtk_table_attach (GTK_TABLE (table2), label5, 0, 1, 0, 1,
-                    (GtkAttachOptions) (0),
-                    (GtkAttachOptions) (0), 0, 0);
-
-  label6 = gtk_label_new (_("Range"));
-  gtk_widget_ref (label6);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "label6", label6,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (label6);
-  gtk_table_attach (GTK_TABLE (table2), label6, 0, 1, 1, 2,
-                    (GtkAttachOptions) (0),
-                    (GtkAttachOptions) (0), 0, 0);
-
-  frame7 = gtk_frame_new (_("Surround"));
-  gtk_widget_ref (frame7);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "frame7", frame7,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (frame7);
-  gtk_box_pack_start (GTK_BOX (vbox7), frame7, TRUE, TRUE, 0);
-
-  hbox6 = gtk_hbox_new (FALSE, 0);
-  gtk_widget_ref (hbox6);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "hbox6", hbox6,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (hbox6);
-  gtk_container_add (GTK_CONTAINER (frame7), hbox6);
-
-  fxSurround = gtk_check_button_new_with_label (_("Enable"));
-  gtk_widget_ref (fxSurround);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxSurround", fxSurround,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxSurround);
-  gtk_box_pack_start (GTK_BOX (hbox6), fxSurround, FALSE, FALSE, 0);
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fxSurround), TRUE);
-
-  vbox12 = gtk_vbox_new (FALSE, 0);
-  gtk_widget_ref (vbox12);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox12", vbox12,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (vbox12);
-  gtk_box_pack_start (GTK_BOX (hbox6), vbox12, TRUE, TRUE, 0);
-
-  table3 = gtk_table_new (2, 2, FALSE);
-  gtk_widget_ref (table3);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "table3", table3,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (table3);
-  gtk_box_pack_start (GTK_BOX (vbox12), table3, TRUE, TRUE, 0);
-
-  fxSurroundDepth = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (20, 0, 100, 0, 0, 0)));
-  gtk_widget_ref (fxSurroundDepth);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxSurroundDepth", fxSurroundDepth,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxSurroundDepth);
-  gtk_table_attach (GTK_TABLE (table3), fxSurroundDepth, 1, 2, 0, 1,
-                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
-                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
-
-  fxSurroundDelay = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (20, 5, 40, 0, 0, 0)));
-  gtk_widget_ref (fxSurroundDelay);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxSurroundDelay", fxSurroundDelay,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxSurroundDelay);
-  gtk_table_attach (GTK_TABLE (table3), fxSurroundDelay, 1, 2, 1, 2,
-                    (GtkAttachOptions) (GTK_FILL),
-                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
-
-  label7 = gtk_label_new (_("Depth"));
-  gtk_widget_ref (label7);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "label7", label7,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (label7);
-  gtk_table_attach (GTK_TABLE (table3), label7, 0, 1, 0, 1,
-                    (GtkAttachOptions) (0),
-                    (GtkAttachOptions) (0), 0, 0);
-
-  label8 = gtk_label_new (_("Delay"));
-  gtk_widget_ref (label8);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "label8", label8,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (label8);
-  gtk_table_attach (GTK_TABLE (table3), label8, 0, 1, 1, 2,
-                    (GtkAttachOptions) (0),
-                    (GtkAttachOptions) (0), 0, 0);
-
-  frame10 = gtk_frame_new (_("Preamp"));
-  gtk_widget_ref (frame10);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "frame10", frame10,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (frame10);
-  gtk_box_pack_start (GTK_BOX (vbox7), frame10, TRUE, TRUE, 0);
-
-  vbox16 = gtk_vbox_new (FALSE, 0);
-  gtk_widget_ref (vbox16);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox16", vbox16,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (vbox16);
-  gtk_container_add (GTK_CONTAINER (frame10), vbox16);
-
-  label20 = gtk_label_new (_("Note:  Setting the preamp too high may cause\nclipping / distortion!"));
-  gtk_widget_ref (label20);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "label20", label20,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (label20);
-  gtk_box_pack_start (GTK_BOX (vbox16), label20, FALSE, FALSE, 0);
-
-  hbox11 = gtk_hbox_new (FALSE, 0);
-  gtk_widget_ref (hbox11);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "hbox11", hbox11,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (hbox11);
-  gtk_box_pack_start (GTK_BOX (vbox16), hbox11, TRUE, TRUE, 0);
-
-  fxPreamp = gtk_check_button_new_with_label (_("Enable"));
-  gtk_widget_ref (fxPreamp);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxPreamp", fxPreamp,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxPreamp);
-  gtk_box_pack_start (GTK_BOX (hbox11), fxPreamp, FALSE, FALSE, 0);
-
-  label19 = gtk_label_new (_("Volume"));
-  gtk_widget_ref (label19);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "label19", label19,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (label19);
-  gtk_box_pack_start (GTK_BOX (hbox11), label19, FALSE, FALSE, 0);
-
-  fxPreampLevel = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -3, 3, 1, 0, 0)));
-  gtk_widget_ref (fxPreampLevel);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxPreampLevel", fxPreampLevel,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxPreampLevel);
-  gtk_box_pack_start (GTK_BOX (hbox11), fxPreampLevel, TRUE, TRUE, 0);
-
-  frame11 = gtk_frame_new (_("Looping"));
-  gtk_widget_ref (frame11);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "frame11", frame11,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (frame11);
-  gtk_box_pack_start (GTK_BOX (vbox7), frame11, TRUE, TRUE, 0);
-
-  vbox17 = gtk_vbox_new (FALSE, 0);
-  gtk_widget_ref (vbox17);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox17", vbox17,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (vbox17);
-  gtk_container_add (GTK_CONTAINER (frame11), vbox17);
-
-  fxNoLoop = gtk_radio_button_new_with_label (loopGroup_group, _("Don't loop"));
-  loopGroup_group = gtk_radio_button_group (GTK_RADIO_BUTTON (fxNoLoop));
-  gtk_widget_ref (fxNoLoop);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxNoLoop", fxNoLoop,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxNoLoop);
-  gtk_box_pack_start (GTK_BOX (vbox17), fxNoLoop, FALSE, FALSE, 0);
-
-  hbox13 = gtk_hbox_new (FALSE, 0);
-  gtk_widget_ref (hbox13);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "hbox13", hbox13,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (hbox13);
-  gtk_box_pack_start (GTK_BOX (vbox17), hbox13, FALSE, FALSE, 0);
-
-  fxLoopFinite = gtk_radio_button_new_with_label (loopGroup_group, _("Loop"));
-  loopGroup_group = gtk_radio_button_group (GTK_RADIO_BUTTON (fxLoopFinite));
-  gtk_widget_ref (fxLoopFinite);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxLoopFinite", fxLoopFinite,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxLoopFinite);
-  gtk_box_pack_start (GTK_BOX (hbox13), fxLoopFinite, FALSE, FALSE, 0);
-
-  fxLoopCount_adj = gtk_adjustment_new (1, 0, 100, 1, 10, 10);
-  fxLoopCount = gtk_spin_button_new (GTK_ADJUSTMENT (fxLoopCount_adj), 1, 0);
-  gtk_widget_ref (fxLoopCount);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxLoopCount", fxLoopCount,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxLoopCount);
-  gtk_box_pack_start (GTK_BOX (hbox13), fxLoopCount, FALSE, TRUE, 0);
-
-  label21 = gtk_label_new (_("time(s)"));
-  gtk_widget_ref (label21);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "label21", label21,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (label21);
-  gtk_box_pack_start (GTK_BOX (hbox13), label21, FALSE, FALSE, 0);
-
-  fxLoopForever = gtk_radio_button_new_with_label (loopGroup_group, _("Loop forever"));
-  loopGroup_group = gtk_radio_button_group (GTK_RADIO_BUTTON (fxLoopForever));
-  gtk_widget_ref (fxLoopForever);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "fxLoopForever", fxLoopForever,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (fxLoopForever);
-  gtk_box_pack_start (GTK_BOX (vbox17), fxLoopForever, FALSE, FALSE, 0);
-
-  label10 = gtk_label_new (_("Effects"));
-  gtk_widget_ref (label10);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "label10", label10,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (label10);
-  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 1), label10);
-
-  hbuttonbox2 = gtk_hbutton_box_new ();
-  gtk_widget_ref (hbuttonbox2);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "hbuttonbox2", hbuttonbox2,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (hbuttonbox2);
-  gtk_box_pack_start (GTK_BOX (vbox2), hbuttonbox2, TRUE, TRUE, 0);
-  gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox2), GTK_BUTTONBOX_END);
-  gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox2), 5);
-
-  config_ok = gtk_button_new_with_label (_("OK"));
-  gtk_widget_ref (config_ok);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "config_ok", config_ok,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (config_ok);
-  gtk_container_add (GTK_CONTAINER (hbuttonbox2), config_ok);
-  GTK_WIDGET_SET_FLAGS (config_ok, GTK_CAN_DEFAULT);
-
-  config_apply = gtk_button_new_with_label (_("Apply"));
-  gtk_widget_ref (config_apply);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "config_apply", config_apply,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (config_apply);
-  gtk_container_add (GTK_CONTAINER (hbuttonbox2), config_apply);
-  GTK_WIDGET_SET_FLAGS (config_apply, GTK_CAN_DEFAULT);
-
-  config_cancel = gtk_button_new_with_label (_("Cancel"));
-  gtk_widget_ref (config_cancel);
-  gtk_object_set_data_full (GTK_OBJECT (Config), "config_cancel", config_cancel,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (config_cancel);
-  gtk_container_add (GTK_CONTAINER (hbuttonbox2), config_cancel);
-  GTK_WIDGET_SET_FLAGS (config_cancel, GTK_CAN_DEFAULT);
-
-  gtk_signal_connect (GTK_OBJECT (Config), "delete_event",
-                      GTK_SIGNAL_FUNC (hide_window),
-                      NULL);
-  gtk_signal_connect (GTK_OBJECT (config_ok), "clicked",
-                      GTK_SIGNAL_FUNC (on_config_ok_clicked),
-                      NULL);
-  gtk_signal_connect (GTK_OBJECT (config_apply), "clicked",
-                      GTK_SIGNAL_FUNC (on_config_apply_clicked),
-                      NULL);
-  gtk_signal_connect (GTK_OBJECT (config_cancel), "clicked",
-                      GTK_SIGNAL_FUNC (on_config_cancel_clicked),
-                      NULL);
-
-  return Config;
-}
-
-GtkWidget*
-create_Info (void)
-{
-  GtkWidget *Info;
-  GtkWidget *vbox14;
-  GtkWidget *notebook2;
-  GtkWidget *hbox9;
-  GtkWidget *label11;
-  GtkWidget *info_general;
-  GtkWidget *label13;
-  GtkWidget *scrolledwindow1;
-  GtkWidget *viewport1;
-  GtkWidget *info_samples;
-  GtkWidget *label15;
-  GtkWidget *scrolledwindow2;
-  GtkWidget *viewport2;
-  GtkWidget *info_instruments;
-  GtkWidget *label17;
-  GtkWidget *scrolledwindow3;
-  GtkWidget *viewport3;
-  GtkWidget *info_message;
-  GtkWidget *label18;
-  GtkWidget *hbuttonbox3;
-  GtkWidget *info_close;
-
-  Info = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  gtk_object_set_data (GTK_OBJECT (Info), "Info", Info);
-  gtk_widget_set_usize (Info, 290, 264);
-  gtk_window_set_title (GTK_WINDOW (Info), _("MOD Info"));
-
-  vbox14 = gtk_vbox_new (FALSE, 0);
-  gtk_widget_ref (vbox14);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "vbox14", vbox14,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (vbox14);
-  gtk_container_add (GTK_CONTAINER (Info), vbox14);
-
-  notebook2 = gtk_notebook_new ();
-  gtk_widget_ref (notebook2);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "notebook2", notebook2,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (notebook2);
-  gtk_box_pack_start (GTK_BOX (vbox14), notebook2, TRUE, TRUE, 8);
-  gtk_container_set_border_width (GTK_CONTAINER (notebook2), 6);
-
-  hbox9 = gtk_hbox_new (FALSE, 0);
-  gtk_widget_ref (hbox9);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "hbox9", hbox9,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (hbox9);
-  gtk_container_add (GTK_CONTAINER (notebook2), hbox9);
-
-  label11 = gtk_label_new (_("Filename:\nTitle:\nType:\nLength:\nSpeed:\nTempo:\nSamples:\nInstruments:\nPatterns:\nChannels:"));
-  gtk_widget_ref (label11);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "label11", label11,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (label11);
-  gtk_box_pack_start (GTK_BOX (hbox9), label11, FALSE, FALSE, 4);
-  gtk_label_set_justify (GTK_LABEL (label11), GTK_JUSTIFY_LEFT);
-
-  info_general = gtk_label_new ("---\n---\n---\n---\n---\n---\n---\n---\n---\n---");
-  gtk_widget_ref (info_general);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "info_general", info_general,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (info_general);
-  gtk_box_pack_start (GTK_BOX (hbox9), info_general, FALSE, FALSE, 4);
-  gtk_label_set_justify (GTK_LABEL (info_general), GTK_JUSTIFY_LEFT);
-
-  label13 = gtk_label_new (_("General"));
-  gtk_widget_ref (label13);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "label13", label13,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (label13);
-  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 0), label13);
-
-  scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
-  gtk_widget_ref (scrolledwindow1);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "scrolledwindow1", scrolledwindow1,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (scrolledwindow1);
-  gtk_container_add (GTK_CONTAINER (notebook2), scrolledwindow1);
-  gtk_container_set_border_width (GTK_CONTAINER (scrolledwindow1), 6);
-  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
-
-  viewport1 = gtk_viewport_new (NULL, NULL);
-  gtk_widget_ref (viewport1);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "viewport1", viewport1,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (viewport1);
-  gtk_container_add (GTK_CONTAINER (scrolledwindow1), viewport1);
-
-  info_samples = gtk_label_new ("");
-  gtk_widget_ref (info_samples);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "info_samples", info_samples,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (info_samples);
-  gtk_container_add (GTK_CONTAINER (viewport1), info_samples);
-  gtk_label_set_justify (GTK_LABEL (info_samples), GTK_JUSTIFY_LEFT);
-  gtk_misc_set_alignment (GTK_MISC (info_samples), 7.45058e-09, 7.45058e-09);
-  gtk_label_set_selectable(GTK_LABEL (info_samples), TRUE);
-
-  label15 = gtk_label_new (_("Samples"));
-  gtk_widget_ref (label15);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "label15", label15,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (label15);
-  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 1), label15);
-
-  scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL);
-  gtk_widget_ref (scrolledwindow2);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "scrolledwindow2", scrolledwindow2,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (scrolledwindow2);
-  gtk_container_add (GTK_CONTAINER (notebook2), scrolledwindow2);
-  gtk_container_set_border_width (GTK_CONTAINER (scrolledwindow2), 6);
-  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
-
-  viewport2 = gtk_viewport_new (NULL, NULL);
-  gtk_widget_ref (viewport2);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "viewport2", viewport2,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (viewport2);
-  gtk_container_add (GTK_CONTAINER (scrolledwindow2), viewport2);
-
-  info_instruments = gtk_label_new ("");
-  gtk_widget_ref (info_instruments);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "info_instruments", info_instruments,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (info_instruments);
-  gtk_container_add (GTK_CONTAINER (viewport2), info_instruments);
-  gtk_label_set_justify (GTK_LABEL (info_instruments), GTK_JUSTIFY_LEFT);
-  gtk_misc_set_alignment (GTK_MISC (info_instruments), 1.49012e-08, 7.45058e-09);
-  gtk_label_set_selectable(GTK_LABEL (info_instruments), TRUE);
-
-  label17 = gtk_label_new (_("Instruments"));
-  gtk_widget_ref (label17);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "label17", label17,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (label17);
-  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 2), label17);
-
-  scrolledwindow3 = gtk_scrolled_window_new (NULL, NULL);
-  gtk_widget_ref (scrolledwindow3);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "scrolledwindow3", scrolledwindow3,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (scrolledwindow3);
-  gtk_container_add (GTK_CONTAINER (notebook2), scrolledwindow3);
-  gtk_container_set_border_width (GTK_CONTAINER (scrolledwindow3), 6);
-  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow3), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
-
-  viewport3 = gtk_viewport_new (NULL, NULL);
-  gtk_widget_ref (viewport3);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "viewport3", viewport3,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (viewport3);
-  gtk_container_add (GTK_CONTAINER (scrolledwindow3), viewport3);
-
-  info_message = gtk_label_new ("");
-  gtk_widget_ref (info_message);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "info_message", info_message,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (info_message);
-  gtk_container_add (GTK_CONTAINER (viewport3), info_message);
-  gtk_label_set_justify (GTK_LABEL (info_message), GTK_JUSTIFY_LEFT);
-  gtk_label_set_line_wrap(GTK_LABEL (info_message), TRUE);
-  gtk_label_set_selectable(GTK_LABEL (info_message), TRUE);
-
-  label18 = gtk_label_new (_("Message"));
-  gtk_widget_ref (label18);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "label18", label18,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (label18);
-  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 3), label18);
-
-  hbuttonbox3 = gtk_hbutton_box_new ();
-  gtk_widget_ref (hbuttonbox3);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "hbuttonbox3", hbuttonbox3,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (hbuttonbox3);
-  gtk_box_pack_start (GTK_BOX (vbox14), hbuttonbox3, FALSE, FALSE, 0);
-
-  info_close = gtk_button_new_with_label (_("Close"));
-  gtk_widget_ref (info_close);
-  gtk_object_set_data_full (GTK_OBJECT (Info), "info_close", info_close,
-                            (GtkDestroyNotify) gtk_widget_unref);
-  gtk_widget_show (info_close);
-  gtk_container_add (GTK_CONTAINER (hbuttonbox3), info_close);
-  GTK_WIDGET_SET_FLAGS (info_close, GTK_CAN_DEFAULT);
-
-  gtk_signal_connect (GTK_OBJECT (Info), "delete_event",
-                      GTK_SIGNAL_FUNC (hide_window),
-                      NULL);
-  gtk_signal_connect (GTK_OBJECT (info_close), "clicked",
-                      GTK_SIGNAL_FUNC (on_info_close_clicked),
-                      NULL);
-
-  return Info;
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/modplug/gui/interface.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,963 @@
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include "callbacks.h"
+#include "interface.h"
+#include "support.h"
+
+GtkWidget*
+create_Config (void)
+{
+  GtkWidget *Config;
+  GtkWidget *vbox2;
+  GtkWidget *notebook1;
+  GtkWidget *vbox3;
+  GtkWidget *hbox2;
+  GtkWidget *frame1;
+  GtkWidget *vbox4;
+  GSList *vbox4_group = NULL;
+  GtkWidget *bit16;
+  GtkWidget *bit8;
+  GtkWidget *frame2;
+  GtkWidget *vbox5;
+  GSList *vbox5_group = NULL;
+  GtkWidget *stereo;
+  GtkWidget *mono;
+  GtkWidget *hbox10;
+  GtkWidget *frame3;
+  GtkWidget *vbox6;
+  GSList *vbox6_group = NULL;
+  GtkWidget *samp48;
+  GtkWidget *samp44;
+  GtkWidget *samp22;
+  GtkWidget *samp11;
+  GtkWidget *frame9;
+  GtkWidget *vbox15;
+  GSList *vbox15_group = NULL;
+  GtkWidget *resampNearest;
+  GtkWidget *resampLinear;
+  GtkWidget *resampSpline;
+  GtkWidget *resampPolyphase;
+  GtkWidget *label2;
+  GtkWidget *vbox7;
+  GtkWidget *frame4;
+  GtkWidget *hbox3;
+  GtkWidget *vbox8;
+  GtkWidget *fxUseFilename;
+  GtkWidget *fxFastInfo;
+  GtkWidget *vbox9;
+  GtkWidget *fxNR;
+  GtkWidget *fxAmigaMOD;
+  GtkWidget *frame5;
+  GtkWidget *hbox4;
+  GtkWidget *fxReverb;
+  GtkWidget *vbox10;
+  GtkWidget *table1;
+  GtkWidget *fxReverbDepth;
+  GtkWidget *fxReverbDelay;
+  GtkWidget *label3;
+  GtkWidget *label4;
+  GtkWidget *frame6;
+  GtkWidget *hbox5;
+  GtkWidget *fxBassBoost;
+  GtkWidget *vbox11;
+  GtkWidget *table2;
+  GtkWidget *fxBassAmount;
+  GtkWidget *fxBassRange;
+  GtkWidget *label5;
+  GtkWidget *label6;
+  GtkWidget *frame7;
+  GtkWidget *hbox6;
+  GtkWidget *fxSurround;
+  GtkWidget *vbox12;
+  GtkWidget *table3;
+  GtkWidget *fxSurroundDepth;
+  GtkWidget *fxSurroundDelay;
+  GtkWidget *label7;
+  GtkWidget *label8;
+  GtkWidget *frame10;
+  GtkWidget *vbox16;
+  GtkWidget *label20;
+  GtkWidget *hbox11;
+  GtkWidget *fxPreamp;
+  GtkWidget *label19;
+  GtkWidget *fxPreampLevel;
+  GtkWidget *frame11;
+  GtkWidget *vbox17;
+  GSList *loopGroup_group = NULL;
+  GtkWidget *fxNoLoop;
+  GtkWidget *hbox13;
+  GtkWidget *fxLoopFinite;
+  GtkObject *fxLoopCount_adj;
+  GtkWidget *fxLoopCount;
+  GtkWidget *label21;
+  GtkWidget *fxLoopForever;
+  GtkWidget *label10;
+  GtkWidget *hbuttonbox2;
+  GtkWidget *config_ok;
+  GtkWidget *config_apply;
+  GtkWidget *config_cancel;
+
+  Config = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_object_set_data (GTK_OBJECT (Config), "Config", Config);
+  gtk_widget_set_usize (Config, 350, -2);
+  gtk_window_set_title (GTK_WINDOW (Config), _("ModPlug Configuration"));
+  gtk_window_set_policy (GTK_WINDOW (Config), FALSE, FALSE, FALSE);
+
+  vbox2 = gtk_vbox_new (FALSE, 0);
+  gtk_container_set_border_width(GTK_CONTAINER(vbox2),5);
+  gtk_widget_ref (vbox2);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox2", vbox2,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vbox2);
+  gtk_container_add (GTK_CONTAINER (Config), vbox2);
+
+  notebook1 = gtk_notebook_new ();
+  gtk_widget_ref (notebook1);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "notebook1", notebook1,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (notebook1);
+  gtk_box_pack_start (GTK_BOX (vbox2), notebook1, TRUE, TRUE, 5);
+  gtk_container_set_border_width (GTK_CONTAINER (notebook1), 0);
+
+  vbox3 = gtk_vbox_new (FALSE, 0);
+  gtk_widget_ref (vbox3);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox3", vbox3,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vbox3);
+  gtk_container_add (GTK_CONTAINER (notebook1), vbox3);
+  gtk_container_set_border_width (GTK_CONTAINER (vbox3), 6);
+
+  hbox2 = gtk_hbox_new (FALSE, 0);
+  gtk_widget_ref (hbox2);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "hbox2", hbox2,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (hbox2);
+  gtk_box_pack_start (GTK_BOX (vbox3), hbox2, TRUE, TRUE, 0);
+
+  frame1 = gtk_frame_new (_("Resolution"));
+  gtk_widget_ref (frame1);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "frame1", frame1,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (frame1);
+  gtk_box_pack_start (GTK_BOX (hbox2), frame1, TRUE, TRUE, 0);
+
+  vbox4 = gtk_vbox_new (FALSE, 0);
+  gtk_widget_ref (vbox4);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox4", vbox4,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vbox4);
+  gtk_container_add (GTK_CONTAINER (frame1), vbox4);
+
+  bit16 = gtk_radio_button_new_with_label (vbox4_group, _("16 bit"));
+  vbox4_group = gtk_radio_button_group (GTK_RADIO_BUTTON (bit16));
+  gtk_widget_ref (bit16);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "bit16", bit16,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (bit16);
+  gtk_box_pack_start (GTK_BOX (vbox4), bit16, FALSE, FALSE, 0);
+
+  bit8 = gtk_radio_button_new_with_label (vbox4_group, _("8 bit"));
+  vbox4_group = gtk_radio_button_group (GTK_RADIO_BUTTON (bit8));
+  gtk_widget_ref (bit8);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "bit8", bit8,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (bit8);
+  gtk_box_pack_start (GTK_BOX (vbox4), bit8, FALSE, FALSE, 0);
+
+  frame2 = gtk_frame_new (_("Channels"));
+  gtk_widget_ref (frame2);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "frame2", frame2,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (frame2);
+  gtk_box_pack_start (GTK_BOX (hbox2), frame2, TRUE, TRUE, 0);
+
+  vbox5 = gtk_vbox_new (FALSE, 0);
+  gtk_widget_ref (vbox5);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox5", vbox5,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vbox5);
+  gtk_container_add (GTK_CONTAINER (frame2), vbox5);
+
+  stereo = gtk_radio_button_new_with_label (vbox5_group, _("Stereo"));
+  vbox5_group = gtk_radio_button_group (GTK_RADIO_BUTTON (stereo));
+  gtk_widget_ref (stereo);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "stereo", stereo,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (stereo);
+  gtk_box_pack_start (GTK_BOX (vbox5), stereo, FALSE, FALSE, 0);
+
+  mono = gtk_radio_button_new_with_label (vbox5_group, _("Mono (downmix)"));
+  vbox5_group = gtk_radio_button_group (GTK_RADIO_BUTTON (mono));
+  gtk_widget_ref (mono);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "mono", mono,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (mono);
+  gtk_box_pack_start (GTK_BOX (vbox5), mono, FALSE, FALSE, 0);
+
+  hbox10 = gtk_hbox_new (FALSE, 0);
+  gtk_widget_ref (hbox10);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "hbox10", hbox10,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (hbox10);
+  gtk_box_pack_start (GTK_BOX (vbox3), hbox10, TRUE, TRUE, 0);
+
+  frame3 = gtk_frame_new (_("Sampling Rate"));
+  gtk_widget_ref (frame3);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "frame3", frame3,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (frame3);
+  gtk_box_pack_start (GTK_BOX (hbox10), frame3, TRUE, TRUE, 0);
+
+  vbox6 = gtk_vbox_new (FALSE, 0);
+  gtk_widget_ref (vbox6);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox6", vbox6,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vbox6);
+  gtk_container_add (GTK_CONTAINER (frame3), vbox6);
+
+  samp48 = gtk_radio_button_new_with_label (vbox6_group, _("48 kHz"));
+  vbox6_group = gtk_radio_button_group (GTK_RADIO_BUTTON (samp48));
+  gtk_widget_ref (samp48);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "samp48", samp48,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (samp48);
+  gtk_box_pack_start (GTK_BOX (vbox6), samp48, FALSE, FALSE, 0);
+
+  samp44 = gtk_radio_button_new_with_label (vbox6_group, _("44 kHz"));
+  vbox6_group = gtk_radio_button_group (GTK_RADIO_BUTTON (samp44));
+  gtk_widget_ref (samp44);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "samp44", samp44,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (samp44);
+  gtk_box_pack_start (GTK_BOX (vbox6), samp44, FALSE, FALSE, 0);
+
+  samp22 = gtk_radio_button_new_with_label (vbox6_group, _("22 kHz"));
+  vbox6_group = gtk_radio_button_group (GTK_RADIO_BUTTON (samp22));
+  gtk_widget_ref (samp22);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "samp22", samp22,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (samp22);
+  gtk_box_pack_start (GTK_BOX (vbox6), samp22, FALSE, FALSE, 0);
+
+  samp11 = gtk_radio_button_new_with_label (vbox6_group, _("11 kHz"));
+  vbox6_group = gtk_radio_button_group (GTK_RADIO_BUTTON (samp11));
+  gtk_widget_ref (samp11);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "samp11", samp11,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (samp11);
+  gtk_box_pack_start (GTK_BOX (vbox6), samp11, FALSE, FALSE, 0);
+
+  frame9 = gtk_frame_new (_("Resampling"));
+  gtk_widget_ref (frame9);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "frame9", frame9,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (frame9);
+  gtk_box_pack_start (GTK_BOX (hbox10), frame9, TRUE, TRUE, 0);
+
+  vbox15 = gtk_vbox_new (FALSE, 0);
+  gtk_widget_ref (vbox15);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox15", vbox15,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vbox15);
+  gtk_container_add (GTK_CONTAINER (frame9), vbox15);
+
+  resampNearest = gtk_radio_button_new_with_label (vbox15_group, _("Nearest (fastest)"));
+  vbox15_group = gtk_radio_button_group (GTK_RADIO_BUTTON (resampNearest));
+  gtk_widget_ref (resampNearest);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "resampNearest", resampNearest,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (resampNearest);
+  gtk_box_pack_start (GTK_BOX (vbox15), resampNearest, FALSE, FALSE, 0);
+
+  resampLinear = gtk_radio_button_new_with_label (vbox15_group, _("Linear (fast)"));
+  vbox15_group = gtk_radio_button_group (GTK_RADIO_BUTTON (resampLinear));
+  gtk_widget_ref (resampLinear);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "resampLinear", resampLinear,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (resampLinear);
+  gtk_box_pack_start (GTK_BOX (vbox15), resampLinear, FALSE, FALSE, 0);
+
+  resampSpline = gtk_radio_button_new_with_label (vbox15_group, _("Spline (good quality)"));
+  vbox15_group = gtk_radio_button_group (GTK_RADIO_BUTTON (resampSpline));
+  gtk_widget_ref (resampSpline);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "resampSpline", resampSpline,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (resampSpline);
+  gtk_box_pack_start (GTK_BOX (vbox15), resampSpline, FALSE, FALSE, 0);
+
+  resampPolyphase = gtk_radio_button_new_with_label (vbox15_group, _("8-tap Fir (extremely high quality)"));
+  vbox15_group = gtk_radio_button_group (GTK_RADIO_BUTTON (resampPolyphase));
+  gtk_widget_ref (resampPolyphase);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "resampPolyphase", resampPolyphase,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (resampPolyphase);
+  gtk_box_pack_start (GTK_BOX (vbox15), resampPolyphase, FALSE, FALSE, 0);
+
+  label2 = gtk_label_new (_("Quality"));
+  gtk_widget_ref (label2);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "label2", label2,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label2);
+  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 0), label2);
+
+  vbox7 = gtk_vbox_new (FALSE, 0);
+  gtk_widget_ref (vbox7);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox7", vbox7,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vbox7);
+  gtk_container_add (GTK_CONTAINER (notebook1), vbox7);
+  gtk_container_set_border_width (GTK_CONTAINER (vbox7), 6);
+
+  frame4 = gtk_frame_new (_("General"));
+  gtk_widget_ref (frame4);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "frame4", frame4,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (frame4);
+  gtk_box_pack_start (GTK_BOX (vbox7), frame4, TRUE, TRUE, 0);
+
+  hbox3 = gtk_hbox_new (FALSE, 0);
+  gtk_widget_ref (hbox3);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "hbox3", hbox3,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (hbox3);
+  gtk_container_add (GTK_CONTAINER (frame4), hbox3);
+
+  vbox8 = gtk_vbox_new (FALSE, 0);
+  gtk_widget_ref (vbox8);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox8", vbox8,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vbox8);
+  gtk_box_pack_start (GTK_BOX (hbox3), vbox8, TRUE, TRUE, 0);
+
+  fxUseFilename = gtk_check_button_new_with_label (_("Use Filename as Song Title"));
+  gtk_widget_ref (fxUseFilename);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxUseFilename", fxUseFilename,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxUseFilename);
+  gtk_box_pack_start (GTK_BOX (vbox8), fxUseFilename, FALSE, FALSE, 0);
+
+  fxFastInfo = gtk_check_button_new_with_label (_("Fast Playlist Info"));
+  gtk_widget_ref (fxFastInfo);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxFastInfo", fxFastInfo,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxFastInfo);
+  gtk_box_pack_start (GTK_BOX (vbox8), fxFastInfo, FALSE, FALSE, 0);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fxFastInfo), TRUE);
+
+  vbox9 = gtk_vbox_new (FALSE, 0);
+  gtk_widget_ref (vbox9);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox9", vbox9,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vbox9);
+  gtk_box_pack_start (GTK_BOX (hbox3), vbox9, TRUE, TRUE, 0);
+
+  fxNR = gtk_check_button_new_with_label (_("Noise Reduction"));
+  gtk_widget_ref (fxNR);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxNR", fxNR,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxNR);
+  gtk_box_pack_start (GTK_BOX (vbox9), fxNR, FALSE, FALSE, 0);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fxNR), TRUE);
+
+  fxAmigaMOD = gtk_check_button_new_with_label (_("Play Amiga MOD"));
+  gtk_widget_ref (fxAmigaMOD);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxAmigaMOD", fxAmigaMOD,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxAmigaMOD);
+  gtk_box_pack_start (GTK_BOX (vbox9), fxAmigaMOD, FALSE, FALSE, 0);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fxAmigaMOD), TRUE);
+
+  frame5 = gtk_frame_new (_("Reverb"));
+  gtk_widget_ref (frame5);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "frame5", frame5,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (frame5);
+  gtk_box_pack_start (GTK_BOX (vbox7), frame5, TRUE, TRUE, 0);
+
+  hbox4 = gtk_hbox_new (FALSE, 0);
+  gtk_widget_ref (hbox4);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "hbox4", hbox4,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (hbox4);
+  gtk_container_add (GTK_CONTAINER (frame5), hbox4);
+
+  fxReverb = gtk_check_button_new_with_label (_("Enable"));
+  gtk_widget_ref (fxReverb);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxReverb", fxReverb,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxReverb);
+  gtk_box_pack_start (GTK_BOX (hbox4), fxReverb, FALSE, FALSE, 0);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fxReverb), TRUE);
+
+  vbox10 = gtk_vbox_new (FALSE, 0);
+  gtk_widget_ref (vbox10);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox10", vbox10,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vbox10);
+  gtk_box_pack_start (GTK_BOX (hbox4), vbox10, TRUE, TRUE, 0);
+
+  table1 = gtk_table_new (2, 2, FALSE);
+  gtk_widget_ref (table1);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "table1", table1,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (table1);
+  gtk_box_pack_start (GTK_BOX (vbox10), table1, TRUE, TRUE, 0);
+
+  fxReverbDepth = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (30, 0, 100, 0, 0, 0)));
+  gtk_widget_ref (fxReverbDepth);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxReverbDepth", fxReverbDepth,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxReverbDepth);
+  gtk_table_attach (GTK_TABLE (table1), fxReverbDepth, 1, 2, 0, 1,
+                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
+
+  fxReverbDelay = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (90, 40, 200, 0, 0, 0)));
+  gtk_widget_ref (fxReverbDelay);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxReverbDelay", fxReverbDelay,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxReverbDelay);
+  gtk_table_attach (GTK_TABLE (table1), fxReverbDelay, 1, 2, 1, 2,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
+
+  label3 = gtk_label_new (_("Depth"));
+  gtk_widget_ref (label3);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "label3", label3,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label3);
+  gtk_table_attach (GTK_TABLE (table1), label3, 0, 1, 0, 1,
+                    (GtkAttachOptions) (0),
+                    (GtkAttachOptions) (0), 0, 0);
+
+  label4 = gtk_label_new (_("Delay"));
+  gtk_widget_ref (label4);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "label4", label4,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label4);
+  gtk_table_attach (GTK_TABLE (table1), label4, 0, 1, 1, 2,
+                    (GtkAttachOptions) (0),
+                    (GtkAttachOptions) (0), 0, 0);
+
+  frame6 = gtk_frame_new (_("Bass Boost"));
+  gtk_widget_ref (frame6);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "frame6", frame6,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (frame6);
+  gtk_box_pack_start (GTK_BOX (vbox7), frame6, TRUE, TRUE, 0);
+
+  hbox5 = gtk_hbox_new (FALSE, 0);
+  gtk_widget_ref (hbox5);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "hbox5", hbox5,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (hbox5);
+  gtk_container_add (GTK_CONTAINER (frame6), hbox5);
+
+  fxBassBoost = gtk_check_button_new_with_label (_("Enable"));
+  gtk_widget_ref (fxBassBoost);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxBassBoost", fxBassBoost,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxBassBoost);
+  gtk_box_pack_start (GTK_BOX (hbox5), fxBassBoost, FALSE, FALSE, 0);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fxBassBoost), TRUE);
+
+  vbox11 = gtk_vbox_new (FALSE, 0);
+  gtk_widget_ref (vbox11);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox11", vbox11,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vbox11);
+  gtk_box_pack_start (GTK_BOX (hbox5), vbox11, TRUE, TRUE, 0);
+
+  table2 = gtk_table_new (2, 2, FALSE);
+  gtk_widget_ref (table2);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "table2", table2,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (table2);
+  gtk_box_pack_start (GTK_BOX (vbox11), table2, TRUE, TRUE, 0);
+
+  fxBassAmount = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (30, 0, 100, 0, 0, 0)));
+  gtk_widget_ref (fxBassAmount);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxBassAmount", fxBassAmount,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxBassAmount);
+  gtk_table_attach (GTK_TABLE (table2), fxBassAmount, 1, 2, 0, 1,
+                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
+
+  fxBassRange = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (30, 10, 100, 0, 0, 0)));
+  gtk_widget_ref (fxBassRange);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxBassRange", fxBassRange,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxBassRange);
+  gtk_table_attach (GTK_TABLE (table2), fxBassRange, 1, 2, 1, 2,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
+
+  label5 = gtk_label_new (_("Amount"));
+  gtk_widget_ref (label5);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "label5", label5,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label5);
+  gtk_table_attach (GTK_TABLE (table2), label5, 0, 1, 0, 1,
+                    (GtkAttachOptions) (0),
+                    (GtkAttachOptions) (0), 0, 0);
+
+  label6 = gtk_label_new (_("Range"));
+  gtk_widget_ref (label6);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "label6", label6,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label6);
+  gtk_table_attach (GTK_TABLE (table2), label6, 0, 1, 1, 2,
+                    (GtkAttachOptions) (0),
+                    (GtkAttachOptions) (0), 0, 0);
+
+  frame7 = gtk_frame_new (_("Surround"));
+  gtk_widget_ref (frame7);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "frame7", frame7,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (frame7);
+  gtk_box_pack_start (GTK_BOX (vbox7), frame7, TRUE, TRUE, 0);
+
+  hbox6 = gtk_hbox_new (FALSE, 0);
+  gtk_widget_ref (hbox6);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "hbox6", hbox6,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (hbox6);
+  gtk_container_add (GTK_CONTAINER (frame7), hbox6);
+
+  fxSurround = gtk_check_button_new_with_label (_("Enable"));
+  gtk_widget_ref (fxSurround);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxSurround", fxSurround,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxSurround);
+  gtk_box_pack_start (GTK_BOX (hbox6), fxSurround, FALSE, FALSE, 0);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (fxSurround), TRUE);
+
+  vbox12 = gtk_vbox_new (FALSE, 0);
+  gtk_widget_ref (vbox12);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox12", vbox12,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vbox12);
+  gtk_box_pack_start (GTK_BOX (hbox6), vbox12, TRUE, TRUE, 0);
+
+  table3 = gtk_table_new (2, 2, FALSE);
+  gtk_widget_ref (table3);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "table3", table3,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (table3);
+  gtk_box_pack_start (GTK_BOX (vbox12), table3, TRUE, TRUE, 0);
+
+  fxSurroundDepth = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (20, 0, 100, 0, 0, 0)));
+  gtk_widget_ref (fxSurroundDepth);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxSurroundDepth", fxSurroundDepth,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxSurroundDepth);
+  gtk_table_attach (GTK_TABLE (table3), fxSurroundDepth, 1, 2, 0, 1,
+                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
+                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
+
+  fxSurroundDelay = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (20, 5, 40, 0, 0, 0)));
+  gtk_widget_ref (fxSurroundDelay);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxSurroundDelay", fxSurroundDelay,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxSurroundDelay);
+  gtk_table_attach (GTK_TABLE (table3), fxSurroundDelay, 1, 2, 1, 2,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 0, 0);
+
+  label7 = gtk_label_new (_("Depth"));
+  gtk_widget_ref (label7);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "label7", label7,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label7);
+  gtk_table_attach (GTK_TABLE (table3), label7, 0, 1, 0, 1,
+                    (GtkAttachOptions) (0),
+                    (GtkAttachOptions) (0), 0, 0);
+
+  label8 = gtk_label_new (_("Delay"));
+  gtk_widget_ref (label8);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "label8", label8,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label8);
+  gtk_table_attach (GTK_TABLE (table3), label8, 0, 1, 1, 2,
+                    (GtkAttachOptions) (0),
+                    (GtkAttachOptions) (0), 0, 0);
+
+  frame10 = gtk_frame_new (_("Preamp"));
+  gtk_widget_ref (frame10);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "frame10", frame10,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (frame10);
+  gtk_box_pack_start (GTK_BOX (vbox7), frame10, TRUE, TRUE, 0);
+
+  vbox16 = gtk_vbox_new (FALSE, 0);
+  gtk_widget_ref (vbox16);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox16", vbox16,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vbox16);
+  gtk_container_add (GTK_CONTAINER (frame10), vbox16);
+
+  label20 = gtk_label_new (_("Note:  Setting the preamp too high may cause\nclipping / distortion!"));
+  gtk_widget_ref (label20);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "label20", label20,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label20);
+  gtk_box_pack_start (GTK_BOX (vbox16), label20, FALSE, FALSE, 0);
+
+  hbox11 = gtk_hbox_new (FALSE, 0);
+  gtk_widget_ref (hbox11);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "hbox11", hbox11,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (hbox11);
+  gtk_box_pack_start (GTK_BOX (vbox16), hbox11, TRUE, TRUE, 0);
+
+  fxPreamp = gtk_check_button_new_with_label (_("Enable"));
+  gtk_widget_ref (fxPreamp);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxPreamp", fxPreamp,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxPreamp);
+  gtk_box_pack_start (GTK_BOX (hbox11), fxPreamp, FALSE, FALSE, 0);
+
+  label19 = gtk_label_new (_("Volume"));
+  gtk_widget_ref (label19);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "label19", label19,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label19);
+  gtk_box_pack_start (GTK_BOX (hbox11), label19, FALSE, FALSE, 0);
+
+  fxPreampLevel = gtk_hscale_new (GTK_ADJUSTMENT (gtk_adjustment_new (0, -3, 3, 1, 0, 0)));
+  gtk_widget_ref (fxPreampLevel);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxPreampLevel", fxPreampLevel,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxPreampLevel);
+  gtk_box_pack_start (GTK_BOX (hbox11), fxPreampLevel, TRUE, TRUE, 0);
+
+  frame11 = gtk_frame_new (_("Looping"));
+  gtk_widget_ref (frame11);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "frame11", frame11,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (frame11);
+  gtk_box_pack_start (GTK_BOX (vbox7), frame11, TRUE, TRUE, 0);
+
+  vbox17 = gtk_vbox_new (FALSE, 0);
+  gtk_widget_ref (vbox17);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "vbox17", vbox17,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vbox17);
+  gtk_container_add (GTK_CONTAINER (frame11), vbox17);
+
+  fxNoLoop = gtk_radio_button_new_with_label (loopGroup_group, _("Don't loop"));
+  loopGroup_group = gtk_radio_button_group (GTK_RADIO_BUTTON (fxNoLoop));
+  gtk_widget_ref (fxNoLoop);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxNoLoop", fxNoLoop,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxNoLoop);
+  gtk_box_pack_start (GTK_BOX (vbox17), fxNoLoop, FALSE, FALSE, 0);
+
+  hbox13 = gtk_hbox_new (FALSE, 0);
+  gtk_widget_ref (hbox13);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "hbox13", hbox13,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (hbox13);
+  gtk_box_pack_start (GTK_BOX (vbox17), hbox13, FALSE, FALSE, 0);
+
+  fxLoopFinite = gtk_radio_button_new_with_label (loopGroup_group, _("Loop"));
+  loopGroup_group = gtk_radio_button_group (GTK_RADIO_BUTTON (fxLoopFinite));
+  gtk_widget_ref (fxLoopFinite);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxLoopFinite", fxLoopFinite,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxLoopFinite);
+  gtk_box_pack_start (GTK_BOX (hbox13), fxLoopFinite, FALSE, FALSE, 0);
+
+  fxLoopCount_adj = gtk_adjustment_new (1, 0, 100, 1, 10, 10);
+  fxLoopCount = gtk_spin_button_new (GTK_ADJUSTMENT (fxLoopCount_adj), 1, 0);
+  gtk_widget_ref (fxLoopCount);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxLoopCount", fxLoopCount,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxLoopCount);
+  gtk_box_pack_start (GTK_BOX (hbox13), fxLoopCount, FALSE, TRUE, 0);
+
+  label21 = gtk_label_new (_("time(s)"));
+  gtk_widget_ref (label21);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "label21", label21,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label21);
+  gtk_box_pack_start (GTK_BOX (hbox13), label21, FALSE, FALSE, 0);
+
+  fxLoopForever = gtk_radio_button_new_with_label (loopGroup_group, _("Loop forever"));
+  loopGroup_group = gtk_radio_button_group (GTK_RADIO_BUTTON (fxLoopForever));
+  gtk_widget_ref (fxLoopForever);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "fxLoopForever", fxLoopForever,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (fxLoopForever);
+  gtk_box_pack_start (GTK_BOX (vbox17), fxLoopForever, FALSE, FALSE, 0);
+
+  label10 = gtk_label_new (_("Effects"));
+  gtk_widget_ref (label10);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "label10", label10,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label10);
+  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook1), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook1), 1), label10);
+
+  hbuttonbox2 = gtk_hbutton_box_new ();
+  gtk_widget_ref (hbuttonbox2);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "hbuttonbox2", hbuttonbox2,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (hbuttonbox2);
+  gtk_box_pack_start (GTK_BOX (vbox2), hbuttonbox2, TRUE, TRUE, 0);
+  gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox2), GTK_BUTTONBOX_END);
+  gtk_button_box_set_spacing (GTK_BUTTON_BOX (hbuttonbox2), 5);
+
+  config_ok = gtk_button_new_with_label (_("OK"));
+  gtk_widget_ref (config_ok);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "config_ok", config_ok,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (config_ok);
+  gtk_container_add (GTK_CONTAINER (hbuttonbox2), config_ok);
+  GTK_WIDGET_SET_FLAGS (config_ok, GTK_CAN_DEFAULT);
+
+  config_apply = gtk_button_new_with_label (_("Apply"));
+  gtk_widget_ref (config_apply);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "config_apply", config_apply,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (config_apply);
+  gtk_container_add (GTK_CONTAINER (hbuttonbox2), config_apply);
+  GTK_WIDGET_SET_FLAGS (config_apply, GTK_CAN_DEFAULT);
+
+  config_cancel = gtk_button_new_with_label (_("Cancel"));
+  gtk_widget_ref (config_cancel);
+  gtk_object_set_data_full (GTK_OBJECT (Config), "config_cancel", config_cancel,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (config_cancel);
+  gtk_container_add (GTK_CONTAINER (hbuttonbox2), config_cancel);
+  GTK_WIDGET_SET_FLAGS (config_cancel, GTK_CAN_DEFAULT);
+
+  gtk_signal_connect (GTK_OBJECT (Config), "delete_event",
+                      GTK_SIGNAL_FUNC (hide_window),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (config_ok), "clicked",
+                      GTK_SIGNAL_FUNC (on_config_ok_clicked),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (config_apply), "clicked",
+                      GTK_SIGNAL_FUNC (on_config_apply_clicked),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (config_cancel), "clicked",
+                      GTK_SIGNAL_FUNC (on_config_cancel_clicked),
+                      NULL);
+
+  return Config;
+}
+
+GtkWidget*
+create_Info (void)
+{
+  GtkWidget *Info;
+  GtkWidget *vbox14;
+  GtkWidget *notebook2;
+  GtkWidget *hbox9;
+  GtkWidget *label11;
+  GtkWidget *info_general;
+  GtkWidget *label13;
+  GtkWidget *scrolledwindow1;
+  GtkWidget *viewport1;
+  GtkWidget *info_samples;
+  GtkWidget *label15;
+  GtkWidget *scrolledwindow2;
+  GtkWidget *viewport2;
+  GtkWidget *info_instruments;
+  GtkWidget *label17;
+  GtkWidget *scrolledwindow3;
+  GtkWidget *viewport3;
+  GtkWidget *info_message;
+  GtkWidget *label18;
+  GtkWidget *hbuttonbox3;
+  GtkWidget *info_close;
+
+  Info = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_object_set_data (GTK_OBJECT (Info), "Info", Info);
+  gtk_widget_set_usize (Info, 290, 264);
+  gtk_window_set_title (GTK_WINDOW (Info), _("MOD Info"));
+
+  vbox14 = gtk_vbox_new (FALSE, 0);
+  gtk_widget_ref (vbox14);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "vbox14", vbox14,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (vbox14);
+  gtk_container_add (GTK_CONTAINER (Info), vbox14);
+
+  notebook2 = gtk_notebook_new ();
+  gtk_widget_ref (notebook2);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "notebook2", notebook2,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (notebook2);
+  gtk_box_pack_start (GTK_BOX (vbox14), notebook2, TRUE, TRUE, 8);
+  gtk_container_set_border_width (GTK_CONTAINER (notebook2), 6);
+
+  hbox9 = gtk_hbox_new (FALSE, 0);
+  gtk_widget_ref (hbox9);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "hbox9", hbox9,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (hbox9);
+  gtk_container_add (GTK_CONTAINER (notebook2), hbox9);
+
+  label11 = gtk_label_new (_("Filename:\nTitle:\nType:\nLength:\nSpeed:\nTempo:\nSamples:\nInstruments:\nPatterns:\nChannels:"));
+  gtk_widget_ref (label11);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "label11", label11,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label11);
+  gtk_box_pack_start (GTK_BOX (hbox9), label11, FALSE, FALSE, 4);
+  gtk_label_set_justify (GTK_LABEL (label11), GTK_JUSTIFY_LEFT);
+
+  info_general = gtk_label_new ("---\n---\n---\n---\n---\n---\n---\n---\n---\n---");
+  gtk_widget_ref (info_general);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "info_general", info_general,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (info_general);
+  gtk_box_pack_start (GTK_BOX (hbox9), info_general, FALSE, FALSE, 4);
+  gtk_label_set_justify (GTK_LABEL (info_general), GTK_JUSTIFY_LEFT);
+
+  label13 = gtk_label_new (_("General"));
+  gtk_widget_ref (label13);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "label13", label13,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label13);
+  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 0), label13);
+
+  scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
+  gtk_widget_ref (scrolledwindow1);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "scrolledwindow1", scrolledwindow1,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (scrolledwindow1);
+  gtk_container_add (GTK_CONTAINER (notebook2), scrolledwindow1);
+  gtk_container_set_border_width (GTK_CONTAINER (scrolledwindow1), 6);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
+
+  viewport1 = gtk_viewport_new (NULL, NULL);
+  gtk_widget_ref (viewport1);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "viewport1", viewport1,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (viewport1);
+  gtk_container_add (GTK_CONTAINER (scrolledwindow1), viewport1);
+
+  info_samples = gtk_label_new ("");
+  gtk_widget_ref (info_samples);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "info_samples", info_samples,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (info_samples);
+  gtk_container_add (GTK_CONTAINER (viewport1), info_samples);
+  gtk_label_set_justify (GTK_LABEL (info_samples), GTK_JUSTIFY_LEFT);
+  gtk_misc_set_alignment (GTK_MISC (info_samples), 7.45058e-09, 7.45058e-09);
+  gtk_label_set_selectable(GTK_LABEL (info_samples), TRUE);
+
+  label15 = gtk_label_new (_("Samples"));
+  gtk_widget_ref (label15);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "label15", label15,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label15);
+  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 1), label15);
+
+  scrolledwindow2 = gtk_scrolled_window_new (NULL, NULL);
+  gtk_widget_ref (scrolledwindow2);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "scrolledwindow2", scrolledwindow2,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (scrolledwindow2);
+  gtk_container_add (GTK_CONTAINER (notebook2), scrolledwindow2);
+  gtk_container_set_border_width (GTK_CONTAINER (scrolledwindow2), 6);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow2), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
+
+  viewport2 = gtk_viewport_new (NULL, NULL);
+  gtk_widget_ref (viewport2);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "viewport2", viewport2,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (viewport2);
+  gtk_container_add (GTK_CONTAINER (scrolledwindow2), viewport2);
+
+  info_instruments = gtk_label_new ("");
+  gtk_widget_ref (info_instruments);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "info_instruments", info_instruments,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (info_instruments);
+  gtk_container_add (GTK_CONTAINER (viewport2), info_instruments);
+  gtk_label_set_justify (GTK_LABEL (info_instruments), GTK_JUSTIFY_LEFT);
+  gtk_misc_set_alignment (GTK_MISC (info_instruments), 1.49012e-08, 7.45058e-09);
+  gtk_label_set_selectable(GTK_LABEL (info_instruments), TRUE);
+
+  label17 = gtk_label_new (_("Instruments"));
+  gtk_widget_ref (label17);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "label17", label17,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label17);
+  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 2), label17);
+
+  scrolledwindow3 = gtk_scrolled_window_new (NULL, NULL);
+  gtk_widget_ref (scrolledwindow3);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "scrolledwindow3", scrolledwindow3,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (scrolledwindow3);
+  gtk_container_add (GTK_CONTAINER (notebook2), scrolledwindow3);
+  gtk_container_set_border_width (GTK_CONTAINER (scrolledwindow3), 6);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow3), GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
+
+  viewport3 = gtk_viewport_new (NULL, NULL);
+  gtk_widget_ref (viewport3);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "viewport3", viewport3,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (viewport3);
+  gtk_container_add (GTK_CONTAINER (scrolledwindow3), viewport3);
+
+  info_message = gtk_label_new ("");
+  gtk_widget_ref (info_message);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "info_message", info_message,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (info_message);
+  gtk_container_add (GTK_CONTAINER (viewport3), info_message);
+  gtk_label_set_justify (GTK_LABEL (info_message), GTK_JUSTIFY_LEFT);
+  gtk_label_set_line_wrap(GTK_LABEL (info_message), TRUE);
+  gtk_label_set_selectable(GTK_LABEL (info_message), TRUE);
+
+  label18 = gtk_label_new (_("Message"));
+  gtk_widget_ref (label18);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "label18", label18,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (label18);
+  gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook2), gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook2), 3), label18);
+
+  hbuttonbox3 = gtk_hbutton_box_new ();
+  gtk_widget_ref (hbuttonbox3);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "hbuttonbox3", hbuttonbox3,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (hbuttonbox3);
+  gtk_box_pack_start (GTK_BOX (vbox14), hbuttonbox3, FALSE, FALSE, 0);
+
+  info_close = gtk_button_new_with_label (_("Close"));
+  gtk_widget_ref (info_close);
+  gtk_object_set_data_full (GTK_OBJECT (Info), "info_close", info_close,
+                            (GtkDestroyNotify) gtk_widget_unref);
+  gtk_widget_show (info_close);
+  gtk_container_add (GTK_CONTAINER (hbuttonbox3), info_close);
+  GTK_WIDGET_SET_FLAGS (info_close, GTK_CAN_DEFAULT);
+
+  gtk_signal_connect (GTK_OBJECT (Info), "delete_event",
+                      GTK_SIGNAL_FUNC (hide_window),
+                      NULL);
+  gtk_signal_connect (GTK_OBJECT (info_close), "clicked",
+                      GTK_SIGNAL_FUNC (on_info_close_clicked),
+                      NULL);
+
+  return Info;
+}
+
--- a/Plugins/Input/modplug/gui/main.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,308 +0,0 @@
-/*
- * Initial main.c file generated by Glade. Edit as required.
- * Glade will not overwrite this file.
- */
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include <gtk/gtk.h>
-#include <libintl.h>
-#include "libaudacious/util.c"
-
-#include "interface.h"
-#include "support.h"
-#include "main.h"
-
-#include <sstream>
-//open()
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-//mmap()
-#include <unistd.h>
-#include <sys/mman.h>
-#include <fstream>
-
-#include "../stddefs.h"
-#include <libmodplug/stdafx.h>
-#include <libmodplug/sndfile.h>
-#include "../archive/open.h"
-
-#define MAX_MESSAGE_LENGTH 4000
-
-GtkWidget *AboutWin    = NULL;
-GtkWidget *ConfigWin   = NULL;
-GtkWidget *InfoWin     = NULL;
-
-void ShowAboutWindow()
-{
-	if(!AboutWin)
-	{
-		gchar * about_text = g_strjoin( "" , _("Modplug Input Plugin for Audacious ver") ,
-				VERSION , _("\nModplug sound engine written by Olivier Lapicque.\nXMMS interface for Modplug by Kenton Varda.\n(c)2000 Olivier Lapicque and Kenton Varda.\nUpdates and Maintainance by Konstanty Bialkowski.\nPorted to BMP by Theofilos Intzoglou.") , NULL );
-		AboutWin = xmms_show_message( _("About Modplug") , about_text , _("Ok") , FALSE , NULL , NULL );
-		gtk_signal_connect( GTK_OBJECT(AboutWin) , "destroy" ,
-			GTK_SIGNAL_FUNC(gtk_widget_destroyed), &AboutWin);
-		g_free( about_text );
-	}
-	gtk_widget_show(AboutWin);
-}
-
-void ShowConfigureWindow(const ModplugXMMS::Settings& aProps)
-{
-	if(!ConfigWin)
-		ConfigWin = create_Config();
-	
-	if(aProps.mBits == 8)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "bit8"), TRUE);
-	else
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "bit16"), TRUE);
-	
-	if(aProps.mFrequency == 11025)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "samp11"), TRUE);
-	else if (aProps.mFrequency == 22050)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "samp22"), TRUE);
-	else if (aProps.mFrequency == 48000)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "samp48"), TRUE);
-	else
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "samp44"), TRUE);
-	
-	if(aProps.mChannels == 1)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "mono"), TRUE);
-	else
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "stereo"), TRUE);
-	
-	if(aProps.mResamplingMode == 0)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "resampNearest"), TRUE);
-	else if(aProps.mResamplingMode == 1)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "resampLinear"), TRUE);
-	else if(aProps.mResamplingMode == 2)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "resampSpline"), TRUE);
-	else
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "resampPolyphase"), TRUE);
-	
-	if(aProps.mNoiseReduction)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxNR"), TRUE);
-	else
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxNR"), FALSE);
-	
-	if(aProps.mGrabAmigaMOD)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxAmigaMOD"), TRUE);
-	else
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxAmigaMOD"), FALSE);
-	
-	if(aProps.mFastinfo)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxFastInfo"), TRUE);
-	else
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxFastInfo"), FALSE);
-	
-	if(aProps.mUseFilename)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxUseFilename"), TRUE);
-	else
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxUseFilename"), FALSE);
-	
-	if(aProps.mReverb)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxReverb"), TRUE);
-	else
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxReverb"), FALSE);
-	
-	if(aProps.mMegabass)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxBassBoost"), TRUE);
-	else
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxBassBoost"), FALSE);
-	
-	if(aProps.mSurround)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxSurround"), TRUE);
-	else
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxSurround"), FALSE);
-	
-	if(aProps.mPreamp)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxPreamp"), TRUE);
-	else
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxPreamp"), FALSE);
-	
-	gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)lookup_widget(ConfigWin, "fxReverbDepth")),   aProps.mReverbDepth);
-	gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)lookup_widget(ConfigWin, "fxReverbDelay")),   aProps.mReverbDelay);
-	gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)lookup_widget(ConfigWin, "fxBassAmount")),    aProps.mBassAmount);
-	gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)lookup_widget(ConfigWin, "fxBassRange")),     aProps.mBassRange);
-	gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)lookup_widget(ConfigWin, "fxSurroundDepth")), aProps.mSurroundDepth);
-	gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)lookup_widget(ConfigWin, "fxSurroundDelay")), aProps.mSurroundDelay);
-	gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)lookup_widget(ConfigWin, "fxPreampLevel")), aProps.mPreampLevel);
-	
-	if(aProps.mLoopCount < 0)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxLoopForever"), TRUE);
-	else if(aProps.mLoopCount == 0)
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxNoLoop"), TRUE);
-	else
-	{
-		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxLoopFinite"), TRUE);
-		gtk_adjustment_set_value(gtk_spin_button_get_adjustment(
-			(GtkSpinButton*)lookup_widget(ConfigWin, "fxLoopCount")), aProps.mLoopCount);
-	}
-	
-	gtk_widget_show(ConfigWin);
-}
-
-void ShowInfoWindow(const string& aFilename)
-{
-	if(!InfoWin)
-		InfoWin = create_Info();
-
-	uint32 lSongTime, lNumSamples, lNumInstruments, i;
-	string lInfo;
-	char lBuffer[33];
-	stringstream lStrStream(ios::out);   //C++ replacement for sprintf()
-
-	CSoundFile* lSoundFile;
-
-	Archive* lArchive;
-	string lShortFN;
-	uint32 lPos;
-
-	lPos = aFilename.find_last_of('/') + 1;
-	lShortFN = aFilename.substr(lPos);
-
-	//open and mmap the file
-	lArchive = OpenArchive(aFilename);
-	if(lArchive->Size() == 0)
-	{
-		delete lArchive;
-		return;
-	}
-
-	lSoundFile = new CSoundFile;
-	lSoundFile->Create((uchar*)lArchive->Map(), lArchive->Size());
-
-	lInfo = lShortFN;
-	lInfo += '\n';
-	lInfo += lSoundFile->GetTitle();
-	lInfo += '\n';
-
-	switch(lSoundFile->GetType())
-	{
-	case MOD_TYPE_MOD:
-		lInfo+= "ProTracker";
-		break;
-	case MOD_TYPE_S3M:
-		lInfo+= "Scream Tracker 3";
-		break;
-	case MOD_TYPE_XM:
-		lInfo+= "Fast Tracker 2";
-		break;
-	case MOD_TYPE_IT:
-		lInfo+= "Impulse Tracker";
-		break;
-	case MOD_TYPE_MED:
-		lInfo+= "OctaMed";
-		break;
-	case MOD_TYPE_MTM:
-		lInfo+= "MTM";
-		break;
-	case MOD_TYPE_669:
-		lInfo+= "669 Composer / UNIS 669";
-		break;
-	case MOD_TYPE_ULT:
-		lInfo+= "ULT";
-		break;
-	case MOD_TYPE_STM:
-		lInfo+= "Scream Tracker";
-		break;
-	case MOD_TYPE_FAR:
-		lInfo+= "Farandole";
-		break;
-	case MOD_TYPE_AMF:
-		lInfo+= "ASYLUM Music Format";
-		break;
-	case MOD_TYPE_AMS:
-		lInfo+= "AMS module";
-		break;
-	case MOD_TYPE_DSM:
-		lInfo+= "DSIK Internal Format";
-		break;
-	case MOD_TYPE_MDL:
-		lInfo+= "DigiTracker";
-		break;
-	case MOD_TYPE_OKT:
-		lInfo+= "Oktalyzer";
-		break;
-	case MOD_TYPE_DMF:
-		lInfo+= "Delusion Digital Music Fileformat (X-Tracker)";
-		break;
-	case MOD_TYPE_PTM:
-		lInfo+= "PolyTracker";
-		break;
-	case MOD_TYPE_DBM:
-		lInfo+= "DigiBooster Pro";
-		break;
-	case MOD_TYPE_MT2:
-		lInfo+= "MT2";
-		break;
-	case MOD_TYPE_AMF0:
-		lInfo+= "AMF0";
-		break;
-	case MOD_TYPE_PSM:
-		lInfo+= "PSM";
-		break;
-	default:
-		lInfo+= "Unknown";
-		break;
-	}
-	lInfo += '\n';
-
-	lSongTime = lSoundFile->GetSongTime();
-	lStrStream.clear();
-	lStrStream << (int)(lSongTime / 60) << ":";
-	if(lSongTime % 60 < 10)  //single digit for seconds?
-		lStrStream << '0';        //yes, so add a 0.
-	lStrStream << (int)(lSongTime % 60);
-
-	lStrStream << '\n';
-
-	lStrStream << (int)lSoundFile->GetMusicSpeed() << '\n';
-	lStrStream << (int)lSoundFile->GetMusicTempo() << '\n';
-	lStrStream << (int)(lNumSamples = lSoundFile->GetNumSamples()) << '\n';
-	lStrStream << (int)(lNumInstruments = lSoundFile->GetNumInstruments());
-	lStrStream << '\n';
-	lStrStream << (int)(lSoundFile->GetNumPatterns()) << '\n';
-	lStrStream << (int)lSoundFile->GetNumChannels();
-	lInfo += lStrStream.str();
-
-	gtk_label_set_text((GtkLabel*)lookup_widget(InfoWin, "info_general"), lInfo.c_str());
-
-	lInfo = "";
-	for(i = 0; i < lNumSamples; i++)
-	{
-		lSoundFile->GetSampleName(i, lBuffer);
-		lInfo += lBuffer;
-		lInfo += '\n';
-	}
-	gtk_label_set_text((GtkLabel*)lookup_widget(InfoWin, "info_samples"), lInfo.c_str());
-
-	lInfo = "";
-	for(i = 0; i < lNumInstruments; i++)
-	{
-		lSoundFile->GetInstrumentName(i, lBuffer);
-		lInfo += lBuffer;
-		lInfo += '\n';
-	}
-	gtk_label_set_text((GtkLabel*)lookup_widget(InfoWin, "info_instruments"), lInfo.c_str());
-
-	char message[MAX_MESSAGE_LENGTH];
-	static int length = 0;
-	
-	//textbox = (GtkLabel*)lookup_widget(InfoWin, "info_message");
-	//gtk_text_backward_delete(textbox, length);
-	length = lSoundFile->GetSongComments(message, MAX_MESSAGE_LENGTH, 80);
-	if (length != 0) {
-		gtk_label_set_text((GtkLabel*)lookup_widget(InfoWin, "info_message"), message);
-	}
-	
-	//unload the file
-	lSoundFile->Destroy();
-	delete lSoundFile;
-	delete lArchive;
-
-	gtk_widget_show(InfoWin);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/modplug/gui/main.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,308 @@
+/*
+ * Initial main.c file generated by Glade. Edit as required.
+ * Glade will not overwrite this file.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <gtk/gtk.h>
+#include <libintl.h>
+#include "libaudacious/util.c"
+
+#include "interface.h"
+#include "support.h"
+#include "main.h"
+
+#include <sstream>
+//open()
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+//mmap()
+#include <unistd.h>
+#include <sys/mman.h>
+#include <fstream>
+
+#include "../stddefs.h"
+#include <libmodplug/stdafx.h>
+#include <libmodplug/sndfile.h>
+#include "../archive/open.h"
+
+#define MAX_MESSAGE_LENGTH 4000
+
+GtkWidget *AboutWin    = NULL;
+GtkWidget *ConfigWin   = NULL;
+GtkWidget *InfoWin     = NULL;
+
+void ShowAboutWindow()
+{
+	if(!AboutWin)
+	{
+		gchar * about_text = g_strjoin( "" , _("Modplug Input Plugin for Audacious ver") ,
+				VERSION , _("\nModplug sound engine written by Olivier Lapicque.\nXMMS interface for Modplug by Kenton Varda.\n(c)2000 Olivier Lapicque and Kenton Varda.\nUpdates and Maintainance by Konstanty Bialkowski.\nPorted to BMP by Theofilos Intzoglou.") , NULL );
+		AboutWin = xmms_show_message( _("About Modplug") , about_text , _("Ok") , FALSE , NULL , NULL );
+		gtk_signal_connect( GTK_OBJECT(AboutWin) , "destroy" ,
+			GTK_SIGNAL_FUNC(gtk_widget_destroyed), &AboutWin);
+		g_free( about_text );
+	}
+	gtk_widget_show(AboutWin);
+}
+
+void ShowConfigureWindow(const ModplugXMMS::Settings& aProps)
+{
+	if(!ConfigWin)
+		ConfigWin = create_Config();
+	
+	if(aProps.mBits == 8)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "bit8"), TRUE);
+	else
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "bit16"), TRUE);
+	
+	if(aProps.mFrequency == 11025)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "samp11"), TRUE);
+	else if (aProps.mFrequency == 22050)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "samp22"), TRUE);
+	else if (aProps.mFrequency == 48000)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "samp48"), TRUE);
+	else
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "samp44"), TRUE);
+	
+	if(aProps.mChannels == 1)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "mono"), TRUE);
+	else
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "stereo"), TRUE);
+	
+	if(aProps.mResamplingMode == 0)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "resampNearest"), TRUE);
+	else if(aProps.mResamplingMode == 1)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "resampLinear"), TRUE);
+	else if(aProps.mResamplingMode == 2)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "resampSpline"), TRUE);
+	else
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "resampPolyphase"), TRUE);
+	
+	if(aProps.mNoiseReduction)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxNR"), TRUE);
+	else
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxNR"), FALSE);
+	
+	if(aProps.mGrabAmigaMOD)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxAmigaMOD"), TRUE);
+	else
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxAmigaMOD"), FALSE);
+	
+	if(aProps.mFastinfo)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxFastInfo"), TRUE);
+	else
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxFastInfo"), FALSE);
+	
+	if(aProps.mUseFilename)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxUseFilename"), TRUE);
+	else
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxUseFilename"), FALSE);
+	
+	if(aProps.mReverb)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxReverb"), TRUE);
+	else
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxReverb"), FALSE);
+	
+	if(aProps.mMegabass)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxBassBoost"), TRUE);
+	else
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxBassBoost"), FALSE);
+	
+	if(aProps.mSurround)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxSurround"), TRUE);
+	else
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxSurround"), FALSE);
+	
+	if(aProps.mPreamp)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxPreamp"), TRUE);
+	else
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxPreamp"), FALSE);
+	
+	gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)lookup_widget(ConfigWin, "fxReverbDepth")),   aProps.mReverbDepth);
+	gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)lookup_widget(ConfigWin, "fxReverbDelay")),   aProps.mReverbDelay);
+	gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)lookup_widget(ConfigWin, "fxBassAmount")),    aProps.mBassAmount);
+	gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)lookup_widget(ConfigWin, "fxBassRange")),     aProps.mBassRange);
+	gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)lookup_widget(ConfigWin, "fxSurroundDepth")), aProps.mSurroundDepth);
+	gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)lookup_widget(ConfigWin, "fxSurroundDelay")), aProps.mSurroundDelay);
+	gtk_adjustment_set_value(gtk_range_get_adjustment((GtkRange*)lookup_widget(ConfigWin, "fxPreampLevel")), aProps.mPreampLevel);
+	
+	if(aProps.mLoopCount < 0)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxLoopForever"), TRUE);
+	else if(aProps.mLoopCount == 0)
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxNoLoop"), TRUE);
+	else
+	{
+		gtk_toggle_button_set_active((GtkToggleButton*)lookup_widget(ConfigWin, "fxLoopFinite"), TRUE);
+		gtk_adjustment_set_value(gtk_spin_button_get_adjustment(
+			(GtkSpinButton*)lookup_widget(ConfigWin, "fxLoopCount")), aProps.mLoopCount);
+	}
+	
+	gtk_widget_show(ConfigWin);
+}
+
+void ShowInfoWindow(const string& aFilename)
+{
+	if(!InfoWin)
+		InfoWin = create_Info();
+
+	uint32 lSongTime, lNumSamples, lNumInstruments, i;
+	string lInfo;
+	char lBuffer[33];
+	stringstream lStrStream(ios::out);   //C++ replacement for sprintf()
+
+	CSoundFile* lSoundFile;
+
+	Archive* lArchive;
+	string lShortFN;
+	uint32 lPos;
+
+	lPos = aFilename.find_last_of('/') + 1;
+	lShortFN = aFilename.substr(lPos);
+
+	//open and mmap the file
+	lArchive = OpenArchive(aFilename);
+	if(lArchive->Size() == 0)
+	{
+		delete lArchive;
+		return;
+	}
+
+	lSoundFile = new CSoundFile;
+	lSoundFile->Create((uchar*)lArchive->Map(), lArchive->Size());
+
+	lInfo = lShortFN;
+	lInfo += '\n';
+	lInfo += lSoundFile->GetTitle();
+	lInfo += '\n';
+
+	switch(lSoundFile->GetType())
+	{
+	case MOD_TYPE_MOD:
+		lInfo+= "ProTracker";
+		break;
+	case MOD_TYPE_S3M:
+		lInfo+= "Scream Tracker 3";
+		break;
+	case MOD_TYPE_XM:
+		lInfo+= "Fast Tracker 2";
+		break;
+	case MOD_TYPE_IT:
+		lInfo+= "Impulse Tracker";
+		break;
+	case MOD_TYPE_MED:
+		lInfo+= "OctaMed";
+		break;
+	case MOD_TYPE_MTM:
+		lInfo+= "MTM";
+		break;
+	case MOD_TYPE_669:
+		lInfo+= "669 Composer / UNIS 669";
+		break;
+	case MOD_TYPE_ULT:
+		lInfo+= "ULT";
+		break;
+	case MOD_TYPE_STM:
+		lInfo+= "Scream Tracker";
+		break;
+	case MOD_TYPE_FAR:
+		lInfo+= "Farandole";
+		break;
+	case MOD_TYPE_AMF:
+		lInfo+= "ASYLUM Music Format";
+		break;
+	case MOD_TYPE_AMS:
+		lInfo+= "AMS module";
+		break;
+	case MOD_TYPE_DSM:
+		lInfo+= "DSIK Internal Format";
+		break;
+	case MOD_TYPE_MDL:
+		lInfo+= "DigiTracker";
+		break;
+	case MOD_TYPE_OKT:
+		lInfo+= "Oktalyzer";
+		break;
+	case MOD_TYPE_DMF:
+		lInfo+= "Delusion Digital Music Fileformat (X-Tracker)";
+		break;
+	case MOD_TYPE_PTM:
+		lInfo+= "PolyTracker";
+		break;
+	case MOD_TYPE_DBM:
+		lInfo+= "DigiBooster Pro";
+		break;
+	case MOD_TYPE_MT2:
+		lInfo+= "MT2";
+		break;
+	case MOD_TYPE_AMF0:
+		lInfo+= "AMF0";
+		break;
+	case MOD_TYPE_PSM:
+		lInfo+= "PSM";
+		break;
+	default:
+		lInfo+= "Unknown";
+		break;
+	}
+	lInfo += '\n';
+
+	lSongTime = lSoundFile->GetSongTime();
+	lStrStream.clear();
+	lStrStream << (int)(lSongTime / 60) << ":";
+	if(lSongTime % 60 < 10)  //single digit for seconds?
+		lStrStream << '0';        //yes, so add a 0.
+	lStrStream << (int)(lSongTime % 60);
+
+	lStrStream << '\n';
+
+	lStrStream << (int)lSoundFile->GetMusicSpeed() << '\n';
+	lStrStream << (int)lSoundFile->GetMusicTempo() << '\n';
+	lStrStream << (int)(lNumSamples = lSoundFile->GetNumSamples()) << '\n';
+	lStrStream << (int)(lNumInstruments = lSoundFile->GetNumInstruments());
+	lStrStream << '\n';
+	lStrStream << (int)(lSoundFile->GetNumPatterns()) << '\n';
+	lStrStream << (int)lSoundFile->GetNumChannels();
+	lInfo += lStrStream.str();
+
+	gtk_label_set_text((GtkLabel*)lookup_widget(InfoWin, "info_general"), lInfo.c_str());
+
+	lInfo = "";
+	for(i = 0; i < lNumSamples; i++)
+	{
+		lSoundFile->GetSampleName(i, lBuffer);
+		lInfo += lBuffer;
+		lInfo += '\n';
+	}
+	gtk_label_set_text((GtkLabel*)lookup_widget(InfoWin, "info_samples"), lInfo.c_str());
+
+	lInfo = "";
+	for(i = 0; i < lNumInstruments; i++)
+	{
+		lSoundFile->GetInstrumentName(i, lBuffer);
+		lInfo += lBuffer;
+		lInfo += '\n';
+	}
+	gtk_label_set_text((GtkLabel*)lookup_widget(InfoWin, "info_instruments"), lInfo.c_str());
+
+	char message[MAX_MESSAGE_LENGTH];
+	static int length = 0;
+	
+	//textbox = (GtkLabel*)lookup_widget(InfoWin, "info_message");
+	//gtk_text_backward_delete(textbox, length);
+	length = lSoundFile->GetSongComments(message, MAX_MESSAGE_LENGTH, 80);
+	if (length != 0) {
+		gtk_label_set_text((GtkLabel*)lookup_widget(InfoWin, "info_message"), message);
+	}
+	
+	//unload the file
+	lSoundFile->Destroy();
+	delete lSoundFile;
+	delete lArchive;
+
+	gtk_widget_show(InfoWin);
+}
--- a/Plugins/Input/modplug/gui/support.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,159 +0,0 @@
-/*
- * DO NOT EDIT THIS FILE - it is generated by Glade.
- */
-
-#ifdef HAVE_CONFIG_H
-#  include <config.h>
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-
-#include <gtk/gtk.h>
-
-#include "support.h"
-
-/* This is an internally used function to check if a pixmap file exists. */
-static gchar* check_file_exists        (const gchar     *directory,
-                                        const gchar     *filename);
-
-/* This is an internally used function to create pixmaps. */
-static GtkWidget* create_dummy_pixmap  (GtkWidget       *widget);
-
-GtkWidget*
-lookup_widget                          (GtkWidget       *widget,
-                                        const gchar     *widget_name)
-{
-  GtkWidget *parent, *found_widget;
-
-  for (;;)
-    {
-      if (GTK_IS_MENU (widget))
-        parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
-      else
-        parent = widget->parent;
-      if (parent == NULL)
-        break;
-      widget = parent;
-    }
-
-  found_widget = (GtkWidget*) gtk_object_get_data (GTK_OBJECT (widget),
-                                                   widget_name);
-  if (!found_widget)
-    g_warning ("Widget not found: %s", widget_name);
-  return found_widget;
-}
-
-/* This is a dummy pixmap we use when a pixmap can't be found. */
-static char *dummy_pixmap_xpm[] = {
-/* columns rows colors chars-per-pixel */
-"1 1 1 1",
-"  c None",
-/* pixels */
-" "
-};
-
-/* This is an internally used function to create pixmaps. */
-static GtkWidget*
-create_dummy_pixmap                    (GtkWidget       *widget)
-{
-  GdkColormap *colormap;
-  GdkPixmap *gdkpixmap;
-  GdkBitmap *mask;
-  GtkWidget *pixmap;
-
-  colormap = gtk_widget_get_colormap (widget);
-  gdkpixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mask,
-                                                     NULL, dummy_pixmap_xpm);
-  if (gdkpixmap == NULL)
-    g_error ("Couldn't create replacement pixmap.");
-  pixmap = gtk_pixmap_new (gdkpixmap, mask);
-  gdk_pixmap_unref (gdkpixmap);
-  gdk_bitmap_unref (mask);
-  return pixmap;
-}
-
-static GList *pixmaps_directories = NULL;
-
-/* Use this function to set the directory containing installed pixmaps. */
-void
-add_pixmap_directory                   (const gchar     *directory)
-{
-  pixmaps_directories = g_list_prepend (pixmaps_directories,
-                                        g_strdup (directory));
-}
-
-/* This is an internally used function to create pixmaps. */
-GtkWidget*
-create_pixmap                          (GtkWidget       *widget,
-                                        const gchar     *filename)
-{
-  gchar *found_filename = NULL;
-  GdkColormap *colormap;
-  GdkPixmap *gdkpixmap;
-  GdkBitmap *mask;
-  GtkWidget *pixmap;
-  GList *elem;
-
-  /* We first try any pixmaps directories set by the application. */
-  elem = pixmaps_directories;
-  while (elem)
-    {
-      found_filename = check_file_exists ((gchar*)elem->data, filename);
-      if (found_filename)
-        break;
-      elem = elem->next;
-    }
-
-  /* If we haven't found the pixmap, try the source directory. */
-  if (!found_filename)
-    {
-      found_filename = check_file_exists ("../pixmaps", filename);
-    }
-
-  if (!found_filename)
-    {
-      g_warning (_("Couldn't find pixmap file: %s"), filename);
-      return create_dummy_pixmap (widget);
-    }
-
-  colormap = gtk_widget_get_colormap (widget);
-  gdkpixmap = gdk_pixmap_colormap_create_from_xpm (NULL, colormap, &mask,
-                                                   NULL, found_filename);
-  if (gdkpixmap == NULL)
-    {
-      g_warning (_("Error loading pixmap file: %s"), found_filename);
-      g_free (found_filename);
-      return create_dummy_pixmap (widget);
-    }
-  g_free (found_filename);
-  pixmap = gtk_pixmap_new (gdkpixmap, mask);
-  gdk_pixmap_unref (gdkpixmap);
-  gdk_bitmap_unref (mask);
-  return pixmap;
-}
-
-/* This is an internally used function to check if a pixmap file exists. */
-gchar*
-check_file_exists                      (const gchar     *directory,
-                                        const gchar     *filename)
-{
-  gchar *full_filename;
-  struct stat s;
-  gint status;
-
-  full_filename = (gchar*) g_malloc (strlen (directory) + 1
-                                     + strlen (filename) + 1);
-  strcpy (full_filename, directory);
-  strcat (full_filename, G_DIR_SEPARATOR_S);
-  strcat (full_filename, filename);
-
-  status = stat (full_filename, &s);
-  if (status == 0 && S_ISREG (s.st_mode))
-    return full_filename;
-  g_free (full_filename);
-  return NULL;
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/modplug/gui/support.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,159 @@
+/*
+ * DO NOT EDIT THIS FILE - it is generated by Glade.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include "support.h"
+
+/* This is an internally used function to check if a pixmap file exists. */
+static gchar* check_file_exists        (const gchar     *directory,
+                                        const gchar     *filename);
+
+/* This is an internally used function to create pixmaps. */
+static GtkWidget* create_dummy_pixmap  (GtkWidget       *widget);
+
+GtkWidget*
+lookup_widget                          (GtkWidget       *widget,
+                                        const gchar     *widget_name)
+{
+  GtkWidget *parent, *found_widget;
+
+  for (;;)
+    {
+      if (GTK_IS_MENU (widget))
+        parent = gtk_menu_get_attach_widget (GTK_MENU (widget));
+      else
+        parent = widget->parent;
+      if (parent == NULL)
+        break;
+      widget = parent;
+    }
+
+  found_widget = (GtkWidget*) gtk_object_get_data (GTK_OBJECT (widget),
+                                                   widget_name);
+  if (!found_widget)
+    g_warning ("Widget not found: %s", widget_name);
+  return found_widget;
+}
+
+/* This is a dummy pixmap we use when a pixmap can't be found. */
+static char *dummy_pixmap_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"1 1 1 1",
+"  c None",
+/* pixels */
+" "
+};
+
+/* This is an internally used function to create pixmaps. */
+static GtkWidget*
+create_dummy_pixmap                    (GtkWidget       *widget)
+{
+  GdkColormap *colormap;
+  GdkPixmap *gdkpixmap;
+  GdkBitmap *mask;
+  GtkWidget *pixmap;
+
+  colormap = gtk_widget_get_colormap (widget);
+  gdkpixmap = gdk_pixmap_colormap_create_from_xpm_d (NULL, colormap, &mask,
+                                                     NULL, dummy_pixmap_xpm);
+  if (gdkpixmap == NULL)
+    g_error ("Couldn't create replacement pixmap.");
+  pixmap = gtk_pixmap_new (gdkpixmap, mask);
+  gdk_pixmap_unref (gdkpixmap);
+  gdk_bitmap_unref (mask);
+  return pixmap;
+}
+
+static GList *pixmaps_directories = NULL;
+
+/* Use this function to set the directory containing installed pixmaps. */
+void
+add_pixmap_directory                   (const gchar     *directory)
+{
+  pixmaps_directories = g_list_prepend (pixmaps_directories,
+                                        g_strdup (directory));
+}
+
+/* This is an internally used function to create pixmaps. */
+GtkWidget*
+create_pixmap                          (GtkWidget       *widget,
+                                        const gchar     *filename)
+{
+  gchar *found_filename = NULL;
+  GdkColormap *colormap;
+  GdkPixmap *gdkpixmap;
+  GdkBitmap *mask;
+  GtkWidget *pixmap;
+  GList *elem;
+
+  /* We first try any pixmaps directories set by the application. */
+  elem = pixmaps_directories;
+  while (elem)
+    {
+      found_filename = check_file_exists ((gchar*)elem->data, filename);
+      if (found_filename)
+        break;
+      elem = elem->next;
+    }
+
+  /* If we haven't found the pixmap, try the source directory. */
+  if (!found_filename)
+    {
+      found_filename = check_file_exists ("../pixmaps", filename);
+    }
+
+  if (!found_filename)
+    {
+      g_warning (_("Couldn't find pixmap file: %s"), filename);
+      return create_dummy_pixmap (widget);
+    }
+
+  colormap = gtk_widget_get_colormap (widget);
+  gdkpixmap = gdk_pixmap_colormap_create_from_xpm (NULL, colormap, &mask,
+                                                   NULL, found_filename);
+  if (gdkpixmap == NULL)
+    {
+      g_warning (_("Error loading pixmap file: %s"), found_filename);
+      g_free (found_filename);
+      return create_dummy_pixmap (widget);
+    }
+  g_free (found_filename);
+  pixmap = gtk_pixmap_new (gdkpixmap, mask);
+  gdk_pixmap_unref (gdkpixmap);
+  gdk_bitmap_unref (mask);
+  return pixmap;
+}
+
+/* This is an internally used function to check if a pixmap file exists. */
+gchar*
+check_file_exists                      (const gchar     *directory,
+                                        const gchar     *filename)
+{
+  gchar *full_filename;
+  struct stat s;
+  gint status;
+
+  full_filename = (gchar*) g_malloc (strlen (directory) + 1
+                                     + strlen (filename) + 1);
+  strcpy (full_filename, directory);
+  strcat (full_filename, G_DIR_SEPARATOR_S);
+  strcat (full_filename, filename);
+
+  status = stat (full_filename, &s);
+  if (status == 0 && S_ISREG (s.st_mode))
+    return full_filename;
+  g_free (full_filename);
+  return NULL;
+}
+
--- a/Plugins/Input/modplug/modplugbmp.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,800 +0,0 @@
-/* Modplug XMMS Plugin
- * Authors: Kenton Varda <temporal@gauge3d.org>
- *
- * This source code is public domain.
- */
-
-#include <fstream>
-#include <unistd.h>
-#include <math.h>
-
-#include "modplugbmp.h"
-#include <libmodplug/stdafx.h>
-#include <libmodplug/sndfile.h>
-#include "stddefs.h"
-#include "archive/open.h"
-#include "libaudacious/configdb.h"
-#include "libaudacious/vfs.h"
-extern "C" {
-#include "audacious/output.h"
-}
-
-// ModplugXMMS member functions ===============================
-
-// operations ----------------------------------------
-ModplugXMMS::ModplugXMMS()
-{
-	mSoundFile = new CSoundFile;
-}
-ModplugXMMS::~ModplugXMMS()
-{
-	delete mSoundFile;
-}
-
-ModplugXMMS::Settings::Settings()
-{
-	mSurround       = true;
-	mOversamp       = true;
-	mReverb         = false;
-	mMegabass       = false;
-	mNoiseReduction = true;
-	mVolumeRamp     = true;
-	mFastinfo       = true;
-	mUseFilename    = false;
-	mGrabAmigaMOD   = true;
-
-	mChannels       = 2;
-	mFrequency      = 44100;
-	mBits           = 16;
-	mResamplingMode = SRCMODE_POLYPHASE;
-
-	mReverbDepth    = 30;
-	mReverbDelay    = 100;
-	mBassAmount     = 40;
-	mBassRange      = 30;
-	mSurroundDepth  = 20;
-	mSurroundDelay  = 20;
-	
-	mPreamp         = false;
-	mPreampLevel    = 0.0f;
-	
-	mLoopCount      = 0;   //don't loop
-}
-
-void ModplugXMMS::Init(void)
-{
-	ConfigDb *db;
-	
-	db = bmp_cfg_db_open();
-
-	bmp_cfg_db_get_bool(db,"modplug","Surround", &mModProps.mSurround);
-        bmp_cfg_db_get_bool(db,"modplug","Oversampling", &mModProps.mOversamp);
-        bmp_cfg_db_get_bool(db,"modplug","Megabass", &mModProps.mMegabass);
-        bmp_cfg_db_get_bool(db,"modplug","NoiseReduction", &mModProps.mNoiseReduction);
-        bmp_cfg_db_get_bool(db,"modplug","VolumeRamp", &mModProps.mVolumeRamp);
-        bmp_cfg_db_get_bool(db,"modplug","Reverb", &mModProps.mReverb);
-        bmp_cfg_db_get_bool(db,"modplug","FastInfo", &mModProps.mFastinfo);
-        bmp_cfg_db_get_bool(db,"modplug","UseFileName", &mModProps.mUseFilename);
-        bmp_cfg_db_get_bool(db,"modplug","GrabAmigaMOD", &mModProps.mGrabAmigaMOD);
-        bmp_cfg_db_get_bool(db,"modplug","PreAmp", &mModProps.mPreamp);
-        bmp_cfg_db_get_float(db,"modplug","PreAmpLevel", &mModProps.mPreampLevel);
-        bmp_cfg_db_get_int(db,"modplug", "Channels", &mModProps.mChannels);
-        bmp_cfg_db_get_int(db,"modplug", "Bits", &mModProps.mBits);
-        bmp_cfg_db_get_int(db,"modplug", "Frequency", &mModProps.mFrequency);
-        bmp_cfg_db_get_int(db,"modplug", "ResamplineMode", &mModProps.mResamplingMode);
-        bmp_cfg_db_get_int(db,"modplug", "ReverbDepth", &mModProps.mReverbDepth);
-        bmp_cfg_db_get_int(db,"modplug", "ReverbDelay", &mModProps.mReverbDelay);
-        bmp_cfg_db_get_int(db,"modplug", "BassAmount", &mModProps.mBassAmount);
-        bmp_cfg_db_get_int(db,"modplug", "BassRange", &mModProps.mBassRange);
-        bmp_cfg_db_get_int(db,"modplug", "SurroundDepth", &mModProps.mSurroundDepth);
-        bmp_cfg_db_get_int(db,"modplug", "SurroundDelay", &mModProps.mSurroundDelay);
-        bmp_cfg_db_get_int(db,"modplug", "LoopCount", &mModProps.mLoopCount);
-
-	bmp_cfg_db_close(db);
-}
-
-bool ModplugXMMS::CanPlayFile(const string& aFilename)
-{
-	string lExt;
-	uint32 lPos;
-
-	VFSFile *file;
-	gchar magic[4];
-
-	if ((file = vfs_fopen(aFilename.c_str(), "rb"))) {
-	vfs_fread(magic, 1, 4, file);
-	if (!memcmp(magic, UMX_MAGIC, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, XM_MAGIC, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, M669_MAGIC, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, IT_MAGIC, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, MTM_MAGIC, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, PSM_MAGIC, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	vfs_fseek(file, 44, SEEK_SET);
-	vfs_fread(magic, 1, 4, file);
-	if (!memcmp(magic, S3M_MAGIC, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if(mModProps.mGrabAmigaMOD) {
-	vfs_fseek(file, 1080, SEEK_SET);
-	vfs_fread(magic, 1, 4, file);
-	if (!memcmp(magic, MOD_MAGIC_PROTRACKER4, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, MOD_MAGIC_PROTRACKER4X, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, MOD_MAGIC_NOISETRACKER, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, MOD_MAGIC_STARTRACKER4, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, MOD_MAGIC_STARTRACKER8, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, MOD_MAGIC_STARTRACKER4X, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, MOD_MAGIC_STARTRACKER8X, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, MOD_MAGIC_FASTTRACKER4, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, MOD_MAGIC_FASTTRACKER6, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, MOD_MAGIC_FASTTRACKER8, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, MOD_MAGIC_OKTALYZER8, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, MOD_MAGIC_OKTALYZER8X, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, MOD_MAGIC_TAKETRACKER16, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	if (!memcmp(magic, MOD_MAGIC_TAKETRACKER32, 4)) {
-		vfs_fclose(file);
-		return 1;
-	}
-	} /* end of if(mModProps.mGrabAmigaMOD) */
-
-	/* We didn't find the magic bytes, fall back to extension check */
-	vfs_fclose(file);
-	} /* end of vfs_open main if statement */
-
-	lPos = aFilename.find_last_of('.');
-	if((int)lPos == -1)
-		return false;
-	lExt = aFilename.substr(lPos);
-	for(uint32 i = 0; i < lExt.length(); i++)
-		lExt[i] = tolower(lExt[i]);
-
-	if (lExt == ".amf")
-		return true;
-	if (lExt == ".ams")
-		return true;
-	if (lExt == ".dbm")
-		return true;
-	if (lExt == ".dbf")
-		return true;
-	if (lExt == ".dsm")
-		return true;
-	if (lExt == ".far")
-		return true;
-	if (lExt == ".mdl")
-		return true;
-	if (lExt == ".stm")
-		return true;
-	if (lExt == ".ult")
-		return true;
-	if (lExt == ".j2b")
-		return true;
-	if (lExt == ".mt2")
-		return true;
-
-	if (lExt == ".mdz")
-		return true;
-	if (lExt == ".mdr")
-		return true;
-	if (lExt == ".mdgz")
-		return true;
-	if (lExt == ".mdbz")
-		return true;
-	if (lExt == ".s3z")
-		return true;
-	if (lExt == ".s3r")
-		return true;
-	if (lExt == ".s3gz")
-		return true;
-	if (lExt == ".xmz")
-		return true;
-	if (lExt == ".xmr")
-		return true;
-	if (lExt == ".xmgz")
-		return true;
-	if (lExt == ".itz")
-		return true;
-	if (lExt == ".itr")
-		return true;
-	if (lExt == ".itgz")
-		return true;
-	if (lExt == ".dmf")
-		return true;
-	
-	if (lExt == ".zip")
-		return ContainsMod(aFilename);
-	if (lExt == ".gz")
-		return ContainsMod(aFilename);
-	if (lExt == ".bz2")
-		return ContainsMod(aFilename);
-
-	return false;
-}
-
-void* ModplugXMMS::PlayThread(void* arg)
-{
-	((ModplugXMMS*)arg)->PlayLoop();
-	return NULL;
-}
-
-void ModplugXMMS::PlayLoop()
-{
-	uint32 lLength;
-	//the user might change the number of channels while playing.
-	// we don't want this to take effect until we are done!
-	uint8 lChannels = mModProps.mChannels;
-
-	while(!mStopped)
-	{
-		if(!(lLength = mSoundFile->Read(
-				mBuffer,
-				mBufSize)))
-		{
-			//no more to play.  Wait for output to finish and then stop.
-			while((mOutPlug->buffer_playing())
-			   && (!mStopped))
-				usleep(10000);
-			break;
-		}
-		
-		if(mModProps.mPreamp)
-		{
-			//apply preamp
-			if(mModProps.mBits == 16)
-			{
-				uint n = mBufSize >> 1;
-				for(uint i = 0; i < n; i++) {
-					short old = ((short*)mBuffer)[i];
-					((short*)mBuffer)[i] *= (short int)mPreampFactor;
-					// detect overflow and clip!
-					if ((old & 0x8000) != 
-					 (((short*)mBuffer)[i] & 0x8000))
-					  ((short*)mBuffer)[i] = old | 0x7FFF;
-						
-				}
-			}
-			else
-			{
-				for(uint i = 0; i < mBufSize; i++) {
-					uchar old = ((uchar*)mBuffer)[i];
-					((uchar*)mBuffer)[i] *= (short int)mPreampFactor;
-					// detect overflow and clip!
-					if ((old & 0x80) != 
-					 (((uchar*)mBuffer)[i] & 0x80))
-					  ((uchar*)mBuffer)[i] = old | 0x7F;
-				}
-			}
-		}
-		
-		if(mStopped)
-			break;
-	
-		//wait for buffer space to free up.
-		while(((mOutPlug->buffer_free()
-		    < (int)mBufSize))
-		   && (!mStopped))
-			usleep(10000);
-			
-		if(mStopped)
-			break;
-		
-		produce_audio
-		(
-			mPlayed,
-			mFormat,
-			lChannels,
-			mBufSize,
-			mBuffer,
-			NULL
-		);
-
-		mPlayed += mBufTime;
-	}
-
-//	mOutPlug->flush(0);
-	mOutPlug->close_audio();
-
-	//Unload the file
-	mSoundFile->Destroy();
-	delete mArchive;
-
-	if (mBuffer)
-	{
-		delete [] mBuffer;
-		mBuffer = NULL;
-	}
-
-	mPaused = false;
-	mStopped = true;
-
-	g_thread_exit(NULL);
-}
-
-void ModplugXMMS::PlayFile(const string& aFilename)
-{
-	mStopped = true;
-	mPaused = false;
-	
-	//open and mmap the file
-	mArchive = OpenArchive(aFilename);
-	if(mArchive->Size() == 0)
-	{
-		delete mArchive;
-		return;
-	}
-	
-	if (mBuffer)
-		delete [] mBuffer;
-	
-	//find buftime to get approx. 512 samples/block
-	mBufTime = 512000 / mModProps.mFrequency + 1;
-
-	mBufSize = mBufTime;
-	mBufSize *= mModProps.mFrequency;
-	mBufSize /= 1000;    //milliseconds
-	mBufSize *= mModProps.mChannels;
-	mBufSize *= mModProps.mBits / 8;
-
-	mBuffer = new uchar[mBufSize];
-	if(!mBuffer)
-		return;             //out of memory!
-
-	CSoundFile::SetWaveConfig
-	(
-		mModProps.mFrequency,
-		mModProps.mBits,
-		mModProps.mChannels
-	);
-	CSoundFile::SetWaveConfigEx
-	(
-		mModProps.mSurround,
-		!mModProps.mOversamp,
-		mModProps.mReverb,
-		true,
-		mModProps.mMegabass,
-		mModProps.mNoiseReduction,
-		false
-	);
-	
-	// [Reverb level 0(quiet)-100(loud)], [delay in ms, usually 40-200ms]
-	if(mModProps.mReverb)
-	{
-		CSoundFile::SetReverbParameters
-		(
-			mModProps.mReverbDepth,
-			mModProps.mReverbDelay
-		);
-	}
-	// [XBass level 0(quiet)-100(loud)], [cutoff in Hz 10-100]
-	if(mModProps.mMegabass)
-	{
-		CSoundFile::SetXBassParameters
-		(
-			mModProps.mBassAmount,
-			mModProps.mBassRange
-		);
-	}
-	// [Surround level 0(quiet)-100(heavy)] [delay in ms, usually 5-40ms]
-	if(mModProps.mSurround)
-	{
-		CSoundFile::SetSurroundParameters
-		(
-			mModProps.mSurroundDepth,
-			mModProps.mSurroundDelay
-		);
-	}
-	CSoundFile::SetResamplingMode(mModProps.mResamplingMode);
-	mSoundFile->SetRepeatCount(mModProps.mLoopCount);
-	mPreampFactor = exp(mModProps.mPreampLevel);
-	
-	mPaused = false;
-	mStopped = false;
-
-	mSoundFile->Create
-	(
-		(uchar*)mArchive->Map(),
-		mArchive->Size()
-	);
-	mPlayed = 0;
-	
-	bool useFilename = mModProps.mUseFilename;
-	
-	if(!useFilename)
-	{
-		strncpy(mModName, mSoundFile->GetTitle(), 100);
-		
-		for(int i = 0; mModName[i] == ' ' || mModName[i] == 0; i++)
-		{
-			if(mModName[i] == 0)
-			{
-				useFilename = true;  //mod name is blank -- use filename
-				break;
-			}
-		}
-	}
-	
-	if(useFilename)
-	{
-		strncpy(mModName, strrchr(aFilename.c_str(), '/') + 1, 100);
-		char* ext = strrchr(mModName, '.');
-		if(ext) *ext = '\0';
-	}
-	
-	mInPlug->set_info
-	(
-		mModName,
-		mSoundFile->GetSongTime() * 1000,
-		mSoundFile->GetNumChannels() * 1000,
-		mModProps.mFrequency,
-		mModProps.mChannels
-	);
-
-	mStopped = mPaused = false;
-
-	if(mModProps.mBits == 16)
-		mFormat = FMT_S16_NE;
-	else
-		mFormat = FMT_U8;
-
-	mOutPlug->open_audio
-	(
-		mFormat,
-		mModProps.mFrequency,
-		mModProps.mChannels
-	);
-
-	mDecodeThread = g_thread_create(
-		(GThreadFunc)PlayThread,
-		this,
-		TRUE,
-		NULL
-	);
-}
-
-void ModplugXMMS::Stop(void)
-{
-	if(mStopped)
-		return;
-
-	mStopped = true;
-	mPaused = false;
-	
-	g_thread_join(mDecodeThread);
-}
-
-void ModplugXMMS::Pause(bool aPaused)
-{
-	if(aPaused)
-		mPaused = true;
-	else
-		mPaused = false;
-	
-	mOutPlug->pause(aPaused);
-}
-
-void ModplugXMMS::Seek(float32 aTime)
-{
-	uint32  lMax;
-	uint32  lMaxtime;
-	float32 lPostime;
-	
-	if(aTime > (lMaxtime = mSoundFile->GetSongTime()))
-		aTime = lMaxtime;
-	lMax = mSoundFile->GetMaxPosition();
-	lPostime = float(lMax) / lMaxtime;
-
-	mSoundFile->SetCurrentPos(int(aTime * lPostime));
-
-	mOutPlug->flush(int(aTime * 1000));
-	mPlayed = uint32(aTime * 1000);
-}
-
-float32 ModplugXMMS::GetTime(void)
-{
-	if(mStopped)
-		return -1;
-	return (float32)mOutPlug->output_time() / 1000;
-}
-
-void ModplugXMMS::GetSongInfo(const string& aFilename, char*& aTitle, int32& aLength)
-{
-	aLength = -1;
-	fstream lTestFile;
-	string lError;
-	bool lDone;
-	
-	lTestFile.open(aFilename.c_str(), ios::in);
-	if(!lTestFile)
-	{
-		lError = "**no such file: ";
-		lError += strrchr(aFilename.c_str(), '/') + 1;
-		aTitle = new char[lError.length() + 1];
-		strcpy(aTitle, lError.c_str());
-		return;
-	}
-	
-	lTestFile.close();
-
-	if(mModProps.mFastinfo)
-	{
-		if(mModProps.mUseFilename)
-		{
-			//Use filename as name
-			aTitle = new char[aFilename.length() + 1];
-			strcpy(aTitle, strrchr(aFilename.c_str(), '/') + 1);
-			*strrchr(aTitle, '.') = '\0';
-			return;
-		}
-		
-		fstream lModFile;
-		string lExt;
-		uint32 lPos;
-		
-		lDone = true;
-
-		// previously ios::nocreate was used (X Standard C++ Library)
-		lModFile.open(aFilename.c_str(), ios::in);
-
-		lPos = aFilename.find_last_of('.');
-		if((int)lPos == 0)
-			return;
-		lExt = aFilename.substr(lPos);
-		for(uint32 i = 0; i < lExt.length(); i++)
-			lExt[i] = tolower(lExt[i]);
-
-		if (lExt == ".mod")
-		{
-			lModFile.read(mModName, 20);
-			mModName[20] = 0;
-		}
-		else if (lExt == ".s3m")
-		{
-			lModFile.read(mModName, 28);
-			mModName[28] = 0;
-		}
-		else if (lExt == ".xm")
-		{
-			lModFile.seekg(17);
-			lModFile.read(mModName, 20);
-			mModName[20] = 0;
-		}
-		else if (lExt == ".it")
-		{
-			lModFile.seekg(4);
-			lModFile.read(mModName, 28);
-			mModName[28] = 0;
-		}
-		else
-			lDone = false;     //fall back to slow info
-
-		lModFile.close();
-
-		if(lDone)
-		{
-			for(int i = 0; mModName[i] != 0; i++)
-			{
-				if(mModName[i] != ' ')
-				{
-					aTitle = new char[strlen(mModName) + 1];
-					strcpy(aTitle, mModName);
-					
-					return;
-				}
-			}
-			
-			//mod name is blank.  Use filename instead.
-			aTitle = new char[aFilename.length() + 1];
-			strcpy(aTitle, strrchr(aFilename.c_str(), '/') + 1);
-			*strrchr(aTitle, '.') = '\0';
-			return;
-		}
-	}
-		
-	Archive* lArchive;
-	CSoundFile* lSoundFile;
-	const char* lTitle;
-
-	//open and mmap the file
-	lArchive = OpenArchive(aFilename);
-	if(lArchive->Size() == 0)
-	{
-		lError = "**bad mod file: ";
-		lError += strrchr(aFilename.c_str(), '/') + 1;
-		aTitle = new char[lError.length() + 1];
-		strcpy(aTitle, lError.c_str());
-		delete lArchive;
-		return;
-	}
-
-	lSoundFile = new CSoundFile;
-	lSoundFile->Create((uchar*)lArchive->Map(), lArchive->Size());
-
-	if(!mModProps.mUseFilename)
-	{
-		lTitle = lSoundFile->GetTitle();
-		
-		for(int i = 0; lTitle[i] != 0; i++)
-		{
-			if(lTitle[i] != ' ')
-			{
-				aTitle = new char[strlen(lTitle) + 1];
-				strcpy(aTitle, lTitle);
-				goto therest;     //sorry
-			}
-		}
-	}
-	
-	//mod name is blank, or user wants the filename to be used as the title.
-	aTitle = new char[aFilename.length() + 1];
-	strcpy(aTitle, strrchr(aFilename.c_str(), '/') + 1);
-	*strrchr(aTitle, '.') = '\0';
-
-therest:
-	aLength = lSoundFile->GetSongTime() * 1000;                   //It wants milliseconds!?!
-
-	//unload the file
-	lSoundFile->Destroy();
-	delete lSoundFile;
-	delete lArchive;
-}
-
-void ModplugXMMS::SetInputPlugin(InputPlugin& aInPlugin)
-{
-	mInPlug = &aInPlugin;
-}
-void ModplugXMMS::SetOutputPlugin(OutputPlugin& aOutPlugin)
-{
-	mOutPlug = &aOutPlugin;
-}
-
-const ModplugXMMS::Settings& ModplugXMMS::GetModProps()
-{
-	return mModProps;
-}
-
-const char* ModplugXMMS::Bool2OnOff(bool aValue)
-{
-	if(aValue)
-		return "on";
-	else
-		return "off";
-}
-
-void ModplugXMMS::SetModProps(const Settings& aModProps)
-{
-	ConfigDb *db;
-	mModProps = aModProps;
-
-	// [Reverb level 0(quiet)-100(loud)], [delay in ms, usually 40-200ms]
-	if(mModProps.mReverb)
-	{
-		CSoundFile::SetReverbParameters
-		(
-			mModProps.mReverbDepth,
-			mModProps.mReverbDelay
-		);
-	}
-	// [XBass level 0(quiet)-100(loud)], [cutoff in Hz 10-100]
-	if(mModProps.mMegabass)
-	{
-		CSoundFile::SetXBassParameters
-		(
-			mModProps.mBassAmount,
-			mModProps.mBassRange
-		);
-	}
-	else //modplug seems to ignore the SetWaveConfigEx() setting for bass boost
-	{
-		CSoundFile::SetXBassParameters
-		(
-			0,
-			0
-		);
-	}
-	// [Surround level 0(quiet)-100(heavy)] [delay in ms, usually 5-40ms]
-	if(mModProps.mSurround)
-	{
-		CSoundFile::SetSurroundParameters
-		(
-			mModProps.mSurroundDepth,
-			mModProps.mSurroundDelay
-		);
-	}
-	CSoundFile::SetWaveConfigEx
-	(
-		mModProps.mSurround,
-		!mModProps.mOversamp,
-		mModProps.mReverb,
-		true,
-		mModProps.mMegabass,
-		mModProps.mNoiseReduction,
-		false
-	);
-	CSoundFile::SetResamplingMode(mModProps.mResamplingMode);
-	mPreampFactor = exp(mModProps.mPreampLevel);
-
-	db = bmp_cfg_db_open();
-
-	bmp_cfg_db_set_bool(db,"modplug","Surround", mModProps.mSurround);
-        bmp_cfg_db_set_bool(db,"modplug","Oversampling", mModProps.mOversamp);
-        bmp_cfg_db_set_bool(db,"modplug","Megabass", mModProps.mMegabass);
-        bmp_cfg_db_set_bool(db,"modplug","NoiseReduction", mModProps.mNoiseReduction);
-        bmp_cfg_db_set_bool(db,"modplug","VolumeRamp", mModProps.mVolumeRamp);
-        bmp_cfg_db_set_bool(db,"modplug","Reverb", mModProps.mReverb);
-        bmp_cfg_db_set_bool(db,"modplug","FastInfo", mModProps.mFastinfo);
-        bmp_cfg_db_set_bool(db,"modplug","UseFileName", mModProps.mUseFilename);
-        bmp_cfg_db_set_bool(db,"modplug","GrabAmigaMOD", mModProps.mGrabAmigaMOD);
-        bmp_cfg_db_set_bool(db,"modplug","PreAmp", mModProps.mPreamp);
-        bmp_cfg_db_set_float(db,"modplug","PreAmpLevel", mModProps.mPreampLevel);
-        bmp_cfg_db_set_int(db,"modplug", "Channels", mModProps.mChannels);
-        bmp_cfg_db_set_int(db,"modplug", "Bits", mModProps.mBits);
-        bmp_cfg_db_set_int(db,"modplug", "Frequency", mModProps.mFrequency);
-        bmp_cfg_db_set_int(db,"modplug", "ResamplineMode", mModProps.mResamplingMode);
-        bmp_cfg_db_set_int(db,"modplug", "ReverbDepth", mModProps.mReverbDepth);
-        bmp_cfg_db_set_int(db,"modplug", "ReverbDelay", mModProps.mReverbDelay);
-        bmp_cfg_db_set_int(db,"modplug", "BassAmount", mModProps.mBassAmount);
-        bmp_cfg_db_set_int(db,"modplug", "BassRange", mModProps.mBassRange);
-        bmp_cfg_db_set_int(db,"modplug", "SurroundDepth", mModProps.mSurroundDepth);
-        bmp_cfg_db_set_int(db,"modplug", "SurroundDelay", mModProps.mSurroundDelay);
-        bmp_cfg_db_set_int(db,"modplug", "LoopCount", mModProps.mLoopCount);
-
-	bmp_cfg_db_close(db);
-}
-
-ModplugXMMS gModplugXMMS;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/modplug/modplugbmp.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,800 @@
+/* Modplug XMMS Plugin
+ * Authors: Kenton Varda <temporal@gauge3d.org>
+ *
+ * This source code is public domain.
+ */
+
+#include <fstream>
+#include <unistd.h>
+#include <math.h>
+
+#include "modplugbmp.h"
+#include <libmodplug/stdafx.h>
+#include <libmodplug/sndfile.h>
+#include "stddefs.h"
+#include "archive/open.h"
+#include "libaudacious/configdb.h"
+#include "libaudacious/vfs.h"
+extern "C" {
+#include "audacious/output.h"
+}
+
+// ModplugXMMS member functions ===============================
+
+// operations ----------------------------------------
+ModplugXMMS::ModplugXMMS()
+{
+	mSoundFile = new CSoundFile;
+}
+ModplugXMMS::~ModplugXMMS()
+{
+	delete mSoundFile;
+}
+
+ModplugXMMS::Settings::Settings()
+{
+	mSurround       = true;
+	mOversamp       = true;
+	mReverb         = false;
+	mMegabass       = false;
+	mNoiseReduction = true;
+	mVolumeRamp     = true;
+	mFastinfo       = true;
+	mUseFilename    = false;
+	mGrabAmigaMOD   = true;
+
+	mChannels       = 2;
+	mFrequency      = 44100;
+	mBits           = 16;
+	mResamplingMode = SRCMODE_POLYPHASE;
+
+	mReverbDepth    = 30;
+	mReverbDelay    = 100;
+	mBassAmount     = 40;
+	mBassRange      = 30;
+	mSurroundDepth  = 20;
+	mSurroundDelay  = 20;
+	
+	mPreamp         = false;
+	mPreampLevel    = 0.0f;
+	
+	mLoopCount      = 0;   //don't loop
+}
+
+void ModplugXMMS::Init(void)
+{
+	ConfigDb *db;
+	
+	db = bmp_cfg_db_open();
+
+	bmp_cfg_db_get_bool(db,"modplug","Surround", &mModProps.mSurround);
+        bmp_cfg_db_get_bool(db,"modplug","Oversampling", &mModProps.mOversamp);
+        bmp_cfg_db_get_bool(db,"modplug","Megabass", &mModProps.mMegabass);
+        bmp_cfg_db_get_bool(db,"modplug","NoiseReduction", &mModProps.mNoiseReduction);
+        bmp_cfg_db_get_bool(db,"modplug","VolumeRamp", &mModProps.mVolumeRamp);
+        bmp_cfg_db_get_bool(db,"modplug","Reverb", &mModProps.mReverb);
+        bmp_cfg_db_get_bool(db,"modplug","FastInfo", &mModProps.mFastinfo);
+        bmp_cfg_db_get_bool(db,"modplug","UseFileName", &mModProps.mUseFilename);
+        bmp_cfg_db_get_bool(db,"modplug","GrabAmigaMOD", &mModProps.mGrabAmigaMOD);
+        bmp_cfg_db_get_bool(db,"modplug","PreAmp", &mModProps.mPreamp);
+        bmp_cfg_db_get_float(db,"modplug","PreAmpLevel", &mModProps.mPreampLevel);
+        bmp_cfg_db_get_int(db,"modplug", "Channels", &mModProps.mChannels);
+        bmp_cfg_db_get_int(db,"modplug", "Bits", &mModProps.mBits);
+        bmp_cfg_db_get_int(db,"modplug", "Frequency", &mModProps.mFrequency);
+        bmp_cfg_db_get_int(db,"modplug", "ResamplineMode", &mModProps.mResamplingMode);
+        bmp_cfg_db_get_int(db,"modplug", "ReverbDepth", &mModProps.mReverbDepth);
+        bmp_cfg_db_get_int(db,"modplug", "ReverbDelay", &mModProps.mReverbDelay);
+        bmp_cfg_db_get_int(db,"modplug", "BassAmount", &mModProps.mBassAmount);
+        bmp_cfg_db_get_int(db,"modplug", "BassRange", &mModProps.mBassRange);
+        bmp_cfg_db_get_int(db,"modplug", "SurroundDepth", &mModProps.mSurroundDepth);
+        bmp_cfg_db_get_int(db,"modplug", "SurroundDelay", &mModProps.mSurroundDelay);
+        bmp_cfg_db_get_int(db,"modplug", "LoopCount", &mModProps.mLoopCount);
+
+	bmp_cfg_db_close(db);
+}
+
+bool ModplugXMMS::CanPlayFile(const string& aFilename)
+{
+	string lExt;
+	uint32 lPos;
+
+	VFSFile *file;
+	gchar magic[4];
+
+	if ((file = vfs_fopen(aFilename.c_str(), "rb"))) {
+	vfs_fread(magic, 1, 4, file);
+	if (!memcmp(magic, UMX_MAGIC, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, XM_MAGIC, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, M669_MAGIC, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, IT_MAGIC, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MTM_MAGIC, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, PSM_MAGIC, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	vfs_fseek(file, 44, SEEK_SET);
+	vfs_fread(magic, 1, 4, file);
+	if (!memcmp(magic, S3M_MAGIC, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if(mModProps.mGrabAmigaMOD) {
+	vfs_fseek(file, 1080, SEEK_SET);
+	vfs_fread(magic, 1, 4, file);
+	if (!memcmp(magic, MOD_MAGIC_PROTRACKER4, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_PROTRACKER4X, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_NOISETRACKER, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_STARTRACKER4, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_STARTRACKER8, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_STARTRACKER4X, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_STARTRACKER8X, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_FASTTRACKER4, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_FASTTRACKER6, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_FASTTRACKER8, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_OKTALYZER8, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_OKTALYZER8X, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_TAKETRACKER16, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	if (!memcmp(magic, MOD_MAGIC_TAKETRACKER32, 4)) {
+		vfs_fclose(file);
+		return 1;
+	}
+	} /* end of if(mModProps.mGrabAmigaMOD) */
+
+	/* We didn't find the magic bytes, fall back to extension check */
+	vfs_fclose(file);
+	} /* end of vfs_open main if statement */
+
+	lPos = aFilename.find_last_of('.');
+	if((int)lPos == -1)
+		return false;
+	lExt = aFilename.substr(lPos);
+	for(uint32 i = 0; i < lExt.length(); i++)
+		lExt[i] = tolower(lExt[i]);
+
+	if (lExt == ".amf")
+		return true;
+	if (lExt == ".ams")
+		return true;
+	if (lExt == ".dbm")
+		return true;
+	if (lExt == ".dbf")
+		return true;
+	if (lExt == ".dsm")
+		return true;
+	if (lExt == ".far")
+		return true;
+	if (lExt == ".mdl")
+		return true;
+	if (lExt == ".stm")
+		return true;
+	if (lExt == ".ult")
+		return true;
+	if (lExt == ".j2b")
+		return true;
+	if (lExt == ".mt2")
+		return true;
+
+	if (lExt == ".mdz")
+		return true;
+	if (lExt == ".mdr")
+		return true;
+	if (lExt == ".mdgz")
+		return true;
+	if (lExt == ".mdbz")
+		return true;
+	if (lExt == ".s3z")
+		return true;
+	if (lExt == ".s3r")
+		return true;
+	if (lExt == ".s3gz")
+		return true;
+	if (lExt == ".xmz")
+		return true;
+	if (lExt == ".xmr")
+		return true;
+	if (lExt == ".xmgz")
+		return true;
+	if (lExt == ".itz")
+		return true;
+	if (lExt == ".itr")
+		return true;
+	if (lExt == ".itgz")
+		return true;
+	if (lExt == ".dmf")
+		return true;
+	
+	if (lExt == ".zip")
+		return ContainsMod(aFilename);
+	if (lExt == ".gz")
+		return ContainsMod(aFilename);
+	if (lExt == ".bz2")
+		return ContainsMod(aFilename);
+
+	return false;
+}
+
+void* ModplugXMMS::PlayThread(void* arg)
+{
+	((ModplugXMMS*)arg)->PlayLoop();
+	return NULL;
+}
+
+void ModplugXMMS::PlayLoop()
+{
+	uint32 lLength;
+	//the user might change the number of channels while playing.
+	// we don't want this to take effect until we are done!
+	uint8 lChannels = mModProps.mChannels;
+
+	while(!mStopped)
+	{
+		if(!(lLength = mSoundFile->Read(
+				mBuffer,
+				mBufSize)))
+		{
+			//no more to play.  Wait for output to finish and then stop.
+			while((mOutPlug->buffer_playing())
+			   && (!mStopped))
+				usleep(10000);
+			break;
+		}
+		
+		if(mModProps.mPreamp)
+		{
+			//apply preamp
+			if(mModProps.mBits == 16)
+			{
+				uint n = mBufSize >> 1;
+				for(uint i = 0; i < n; i++) {
+					short old = ((short*)mBuffer)[i];
+					((short*)mBuffer)[i] *= (short int)mPreampFactor;
+					// detect overflow and clip!
+					if ((old & 0x8000) != 
+					 (((short*)mBuffer)[i] & 0x8000))
+					  ((short*)mBuffer)[i] = old | 0x7FFF;
+						
+				}
+			}
+			else
+			{
+				for(uint i = 0; i < mBufSize; i++) {
+					uchar old = ((uchar*)mBuffer)[i];
+					((uchar*)mBuffer)[i] *= (short int)mPreampFactor;
+					// detect overflow and clip!
+					if ((old & 0x80) != 
+					 (((uchar*)mBuffer)[i] & 0x80))
+					  ((uchar*)mBuffer)[i] = old | 0x7F;
+				}
+			}
+		}
+		
+		if(mStopped)
+			break;
+	
+		//wait for buffer space to free up.
+		while(((mOutPlug->buffer_free()
+		    < (int)mBufSize))
+		   && (!mStopped))
+			usleep(10000);
+			
+		if(mStopped)
+			break;
+		
+		produce_audio
+		(
+			mPlayed,
+			mFormat,
+			lChannels,
+			mBufSize,
+			mBuffer,
+			NULL
+		);
+
+		mPlayed += mBufTime;
+	}
+
+//	mOutPlug->flush(0);
+	mOutPlug->close_audio();
+
+	//Unload the file
+	mSoundFile->Destroy();
+	delete mArchive;
+
+	if (mBuffer)
+	{
+		delete [] mBuffer;
+		mBuffer = NULL;
+	}
+
+	mPaused = false;
+	mStopped = true;
+
+	g_thread_exit(NULL);
+}
+
+void ModplugXMMS::PlayFile(const string& aFilename)
+{
+	mStopped = true;
+	mPaused = false;
+	
+	//open and mmap the file
+	mArchive = OpenArchive(aFilename);
+	if(mArchive->Size() == 0)
+	{
+		delete mArchive;
+		return;
+	}
+	
+	if (mBuffer)
+		delete [] mBuffer;
+	
+	//find buftime to get approx. 512 samples/block
+	mBufTime = 512000 / mModProps.mFrequency + 1;
+
+	mBufSize = mBufTime;
+	mBufSize *= mModProps.mFrequency;
+	mBufSize /= 1000;    //milliseconds
+	mBufSize *= mModProps.mChannels;
+	mBufSize *= mModProps.mBits / 8;
+
+	mBuffer = new uchar[mBufSize];
+	if(!mBuffer)
+		return;             //out of memory!
+
+	CSoundFile::SetWaveConfig
+	(
+		mModProps.mFrequency,
+		mModProps.mBits,
+		mModProps.mChannels
+	);
+	CSoundFile::SetWaveConfigEx
+	(
+		mModProps.mSurround,
+		!mModProps.mOversamp,
+		mModProps.mReverb,
+		true,
+		mModProps.mMegabass,
+		mModProps.mNoiseReduction,
+		false
+	);
+	
+	// [Reverb level 0(quiet)-100(loud)], [delay in ms, usually 40-200ms]
+	if(mModProps.mReverb)
+	{
+		CSoundFile::SetReverbParameters
+		(
+			mModProps.mReverbDepth,
+			mModProps.mReverbDelay
+		);
+	}
+	// [XBass level 0(quiet)-100(loud)], [cutoff in Hz 10-100]
+	if(mModProps.mMegabass)
+	{
+		CSoundFile::SetXBassParameters
+		(
+			mModProps.mBassAmount,
+			mModProps.mBassRange
+		);
+	}
+	// [Surround level 0(quiet)-100(heavy)] [delay in ms, usually 5-40ms]
+	if(mModProps.mSurround)
+	{
+		CSoundFile::SetSurroundParameters
+		(
+			mModProps.mSurroundDepth,
+			mModProps.mSurroundDelay
+		);
+	}
+	CSoundFile::SetResamplingMode(mModProps.mResamplingMode);
+	mSoundFile->SetRepeatCount(mModProps.mLoopCount);
+	mPreampFactor = exp(mModProps.mPreampLevel);
+	
+	mPaused = false;
+	mStopped = false;
+
+	mSoundFile->Create
+	(
+		(uchar*)mArchive->Map(),
+		mArchive->Size()
+	);
+	mPlayed = 0;
+	
+	bool useFilename = mModProps.mUseFilename;
+	
+	if(!useFilename)
+	{
+		strncpy(mModName, mSoundFile->GetTitle(), 100);
+		
+		for(int i = 0; mModName[i] == ' ' || mModName[i] == 0; i++)
+		{
+			if(mModName[i] == 0)
+			{
+				useFilename = true;  //mod name is blank -- use filename
+				break;
+			}
+		}
+	}
+	
+	if(useFilename)
+	{
+		strncpy(mModName, strrchr(aFilename.c_str(), '/') + 1, 100);
+		char* ext = strrchr(mModName, '.');
+		if(ext) *ext = '\0';
+	}
+	
+	mInPlug->set_info
+	(
+		mModName,
+		mSoundFile->GetSongTime() * 1000,
+		mSoundFile->GetNumChannels() * 1000,
+		mModProps.mFrequency,
+		mModProps.mChannels
+	);
+
+	mStopped = mPaused = false;
+
+	if(mModProps.mBits == 16)
+		mFormat = FMT_S16_NE;
+	else
+		mFormat = FMT_U8;
+
+	mOutPlug->open_audio
+	(
+		mFormat,
+		mModProps.mFrequency,
+		mModProps.mChannels
+	);
+
+	mDecodeThread = g_thread_create(
+		(GThreadFunc)PlayThread,
+		this,
+		TRUE,
+		NULL
+	);
+}
+
+void ModplugXMMS::Stop(void)
+{
+	if(mStopped)
+		return;
+
+	mStopped = true;
+	mPaused = false;
+	
+	g_thread_join(mDecodeThread);
+}
+
+void ModplugXMMS::Pause(bool aPaused)
+{
+	if(aPaused)
+		mPaused = true;
+	else
+		mPaused = false;
+	
+	mOutPlug->pause(aPaused);
+}
+
+void ModplugXMMS::Seek(float32 aTime)
+{
+	uint32  lMax;
+	uint32  lMaxtime;
+	float32 lPostime;
+	
+	if(aTime > (lMaxtime = mSoundFile->GetSongTime()))
+		aTime = lMaxtime;
+	lMax = mSoundFile->GetMaxPosition();
+	lPostime = float(lMax) / lMaxtime;
+
+	mSoundFile->SetCurrentPos(int(aTime * lPostime));
+
+	mOutPlug->flush(int(aTime * 1000));
+	mPlayed = uint32(aTime * 1000);
+}
+
+float32 ModplugXMMS::GetTime(void)
+{
+	if(mStopped)
+		return -1;
+	return (float32)mOutPlug->output_time() / 1000;
+}
+
+void ModplugXMMS::GetSongInfo(const string& aFilename, char*& aTitle, int32& aLength)
+{
+	aLength = -1;
+	fstream lTestFile;
+	string lError;
+	bool lDone;
+	
+	lTestFile.open(aFilename.c_str(), ios::in);
+	if(!lTestFile)
+	{
+		lError = "**no such file: ";
+		lError += strrchr(aFilename.c_str(), '/') + 1;
+		aTitle = new char[lError.length() + 1];
+		strcpy(aTitle, lError.c_str());
+		return;
+	}
+	
+	lTestFile.close();
+
+	if(mModProps.mFastinfo)
+	{
+		if(mModProps.mUseFilename)
+		{
+			//Use filename as name
+			aTitle = new char[aFilename.length() + 1];
+			strcpy(aTitle, strrchr(aFilename.c_str(), '/') + 1);
+			*strrchr(aTitle, '.') = '\0';
+			return;
+		}
+		
+		fstream lModFile;
+		string lExt;
+		uint32 lPos;
+		
+		lDone = true;
+
+		// previously ios::nocreate was used (X Standard C++ Library)
+		lModFile.open(aFilename.c_str(), ios::in);
+
+		lPos = aFilename.find_last_of('.');
+		if((int)lPos == 0)
+			return;
+		lExt = aFilename.substr(lPos);
+		for(uint32 i = 0; i < lExt.length(); i++)
+			lExt[i] = tolower(lExt[i]);
+
+		if (lExt == ".mod")
+		{
+			lModFile.read(mModName, 20);
+			mModName[20] = 0;
+		}
+		else if (lExt == ".s3m")
+		{
+			lModFile.read(mModName, 28);
+			mModName[28] = 0;
+		}
+		else if (lExt == ".xm")
+		{
+			lModFile.seekg(17);
+			lModFile.read(mModName, 20);
+			mModName[20] = 0;
+		}
+		else if (lExt == ".it")
+		{
+			lModFile.seekg(4);
+			lModFile.read(mModName, 28);
+			mModName[28] = 0;
+		}
+		else
+			lDone = false;     //fall back to slow info
+
+		lModFile.close();
+
+		if(lDone)
+		{
+			for(int i = 0; mModName[i] != 0; i++)
+			{
+				if(mModName[i] != ' ')
+				{
+					aTitle = new char[strlen(mModName) + 1];
+					strcpy(aTitle, mModName);
+					
+					return;
+				}
+			}
+			
+			//mod name is blank.  Use filename instead.
+			aTitle = new char[aFilename.length() + 1];
+			strcpy(aTitle, strrchr(aFilename.c_str(), '/') + 1);
+			*strrchr(aTitle, '.') = '\0';
+			return;
+		}
+	}
+		
+	Archive* lArchive;
+	CSoundFile* lSoundFile;
+	const char* lTitle;
+
+	//open and mmap the file
+	lArchive = OpenArchive(aFilename);
+	if(lArchive->Size() == 0)
+	{
+		lError = "**bad mod file: ";
+		lError += strrchr(aFilename.c_str(), '/') + 1;
+		aTitle = new char[lError.length() + 1];
+		strcpy(aTitle, lError.c_str());
+		delete lArchive;
+		return;
+	}
+
+	lSoundFile = new CSoundFile;
+	lSoundFile->Create((uchar*)lArchive->Map(), lArchive->Size());
+
+	if(!mModProps.mUseFilename)
+	{
+		lTitle = lSoundFile->GetTitle();
+		
+		for(int i = 0; lTitle[i] != 0; i++)
+		{
+			if(lTitle[i] != ' ')
+			{
+				aTitle = new char[strlen(lTitle) + 1];
+				strcpy(aTitle, lTitle);
+				goto therest;     //sorry
+			}
+		}
+	}
+	
+	//mod name is blank, or user wants the filename to be used as the title.
+	aTitle = new char[aFilename.length() + 1];
+	strcpy(aTitle, strrchr(aFilename.c_str(), '/') + 1);
+	*strrchr(aTitle, '.') = '\0';
+
+therest:
+	aLength = lSoundFile->GetSongTime() * 1000;                   //It wants milliseconds!?!
+
+	//unload the file
+	lSoundFile->Destroy();
+	delete lSoundFile;
+	delete lArchive;
+}
+
+void ModplugXMMS::SetInputPlugin(InputPlugin& aInPlugin)
+{
+	mInPlug = &aInPlugin;
+}
+void ModplugXMMS::SetOutputPlugin(OutputPlugin& aOutPlugin)
+{
+	mOutPlug = &aOutPlugin;
+}
+
+const ModplugXMMS::Settings& ModplugXMMS::GetModProps()
+{
+	return mModProps;
+}
+
+const char* ModplugXMMS::Bool2OnOff(bool aValue)
+{
+	if(aValue)
+		return "on";
+	else
+		return "off";
+}
+
+void ModplugXMMS::SetModProps(const Settings& aModProps)
+{
+	ConfigDb *db;
+	mModProps = aModProps;
+
+	// [Reverb level 0(quiet)-100(loud)], [delay in ms, usually 40-200ms]
+	if(mModProps.mReverb)
+	{
+		CSoundFile::SetReverbParameters
+		(
+			mModProps.mReverbDepth,
+			mModProps.mReverbDelay
+		);
+	}
+	// [XBass level 0(quiet)-100(loud)], [cutoff in Hz 10-100]
+	if(mModProps.mMegabass)
+	{
+		CSoundFile::SetXBassParameters
+		(
+			mModProps.mBassAmount,
+			mModProps.mBassRange
+		);
+	}
+	else //modplug seems to ignore the SetWaveConfigEx() setting for bass boost
+	{
+		CSoundFile::SetXBassParameters
+		(
+			0,
+			0
+		);
+	}
+	// [Surround level 0(quiet)-100(heavy)] [delay in ms, usually 5-40ms]
+	if(mModProps.mSurround)
+	{
+		CSoundFile::SetSurroundParameters
+		(
+			mModProps.mSurroundDepth,
+			mModProps.mSurroundDelay
+		);
+	}
+	CSoundFile::SetWaveConfigEx
+	(
+		mModProps.mSurround,
+		!mModProps.mOversamp,
+		mModProps.mReverb,
+		true,
+		mModProps.mMegabass,
+		mModProps.mNoiseReduction,
+		false
+	);
+	CSoundFile::SetResamplingMode(mModProps.mResamplingMode);
+	mPreampFactor = exp(mModProps.mPreampLevel);
+
+	db = bmp_cfg_db_open();
+
+	bmp_cfg_db_set_bool(db,"modplug","Surround", mModProps.mSurround);
+        bmp_cfg_db_set_bool(db,"modplug","Oversampling", mModProps.mOversamp);
+        bmp_cfg_db_set_bool(db,"modplug","Megabass", mModProps.mMegabass);
+        bmp_cfg_db_set_bool(db,"modplug","NoiseReduction", mModProps.mNoiseReduction);
+        bmp_cfg_db_set_bool(db,"modplug","VolumeRamp", mModProps.mVolumeRamp);
+        bmp_cfg_db_set_bool(db,"modplug","Reverb", mModProps.mReverb);
+        bmp_cfg_db_set_bool(db,"modplug","FastInfo", mModProps.mFastinfo);
+        bmp_cfg_db_set_bool(db,"modplug","UseFileName", mModProps.mUseFilename);
+        bmp_cfg_db_set_bool(db,"modplug","GrabAmigaMOD", mModProps.mGrabAmigaMOD);
+        bmp_cfg_db_set_bool(db,"modplug","PreAmp", mModProps.mPreamp);
+        bmp_cfg_db_set_float(db,"modplug","PreAmpLevel", mModProps.mPreampLevel);
+        bmp_cfg_db_set_int(db,"modplug", "Channels", mModProps.mChannels);
+        bmp_cfg_db_set_int(db,"modplug", "Bits", mModProps.mBits);
+        bmp_cfg_db_set_int(db,"modplug", "Frequency", mModProps.mFrequency);
+        bmp_cfg_db_set_int(db,"modplug", "ResamplineMode", mModProps.mResamplingMode);
+        bmp_cfg_db_set_int(db,"modplug", "ReverbDepth", mModProps.mReverbDepth);
+        bmp_cfg_db_set_int(db,"modplug", "ReverbDelay", mModProps.mReverbDelay);
+        bmp_cfg_db_set_int(db,"modplug", "BassAmount", mModProps.mBassAmount);
+        bmp_cfg_db_set_int(db,"modplug", "BassRange", mModProps.mBassRange);
+        bmp_cfg_db_set_int(db,"modplug", "SurroundDepth", mModProps.mSurroundDepth);
+        bmp_cfg_db_set_int(db,"modplug", "SurroundDelay", mModProps.mSurroundDelay);
+        bmp_cfg_db_set_int(db,"modplug", "LoopCount", mModProps.mLoopCount);
+
+	bmp_cfg_db_close(db);
+}
+
+ModplugXMMS gModplugXMMS;
--- a/Plugins/Input/modplug/plugin.cpp	Sat Sep 16 07:18:18 2006 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/* Modplug XMMS Plugin
- * Authors: Kenton Varda <temporal@gauge3d.org>
- *
- * This source code is public domain.
- */
-
-#include "audacious/plugin.h"
-#include <libmodplug/modplug.h>
-#include "gui/main.h"
-
-extern InputPlugin gModPlug;
-
-static void Init(void)
-{
-	gModplugXMMS.SetInputPlugin(gModPlug);
-	gModplugXMMS.Init();
-}
-
-static int CanPlayFile(char* aFilename)
-{
-	if(gModplugXMMS.CanPlayFile(aFilename))
-		return 1;
-	return 0;
-}
-
-static void PlayFile(char* aFilename)
-{
-	gModplugXMMS.SetOutputPlugin(*gModPlug.output);
-	gModplugXMMS.PlayFile(aFilename);
-}
-
-static void Stop(void)
-{
-	gModplugXMMS.Stop();
-}
-
-static void Pause(short aPaused)
-{
-	gModplugXMMS.Pause((bool)aPaused);
-}
-
-static void Seek(int aTime)
-{
-	gModplugXMMS.Seek(float32(aTime));
-}
-static int GetTime(void)
-{
-	float32 lTime;
-	
-	lTime = gModplugXMMS.GetTime();
-	if(lTime == -1)
-		return -1;
-	else
-		return (int)(lTime * 1000);
-}
-
-static void GetSongInfo(char* aFilename, char** aTitle, int* aLength)
-{
-	gModplugXMMS.GetSongInfo(aFilename, *aTitle, *aLength);
-}
-
-void ShowAboutBox(void)
-{
-	ShowAboutWindow();
-}
-
-void ShowConfigureBox(void)
-{
-	ShowConfigureWindow(gModplugXMMS.GetModProps());
-}
-
-void ShowFileInfoBox(char* aFilename)
-{
-	ShowInfoWindow(aFilename);
-}
-
-InputPlugin gModPlug =
-{
-	NULL,
-	NULL,
-	"ModPlug Player",
-	Init,
-	ShowAboutBox,
-	ShowConfigureBox,
-	CanPlayFile,
-	NULL,
-	PlayFile,
-	Stop,
-	Pause,
-	Seek,
-	NULL,
-	GetTime,
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-	NULL,
-	GetSongInfo,
-	ShowFileInfoBox,
-	NULL
-};
-
-extern "C"
-{
-	InputPlugin* get_iplugin_info (void)
-	{
-		return &gModPlug;
-	}
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Input/modplug/plugin.cxx	Sat Sep 16 07:33:28 2006 -0700
@@ -0,0 +1,111 @@
+/* Modplug XMMS Plugin
+ * Authors: Kenton Varda <temporal@gauge3d.org>
+ *
+ * This source code is public domain.
+ */
+
+#include "audacious/plugin.h"
+#include <libmodplug/modplug.h>
+#include "gui/main.h"
+
+extern InputPlugin gModPlug;
+
+static void Init(void)
+{
+	gModplugXMMS.SetInputPlugin(gModPlug);
+	gModplugXMMS.Init();
+}
+
+static int CanPlayFile(char* aFilename)
+{
+	if(gModplugXMMS.CanPlayFile(aFilename))
+		return 1;
+	return 0;
+}
+
+static void PlayFile(char* aFilename)
+{
+	gModplugXMMS.SetOutputPlugin(*gModPlug.output);
+	gModplugXMMS.PlayFile(aFilename);
+}
+
+static void Stop(void)
+{
+	gModplugXMMS.Stop();
+}
+
+static void Pause(short aPaused)
+{
+	gModplugXMMS.Pause((bool)aPaused);
+}
+
+static void Seek(int aTime)
+{
+	gModplugXMMS.Seek(float32(aTime));
+}
+static int GetTime(void)
+{
+	float32 lTime;
+	
+	lTime = gModplugXMMS.GetTime();
+	if(lTime == -1)
+		return -1;
+	else
+		return (int)(lTime * 1000);
+}
+
+static void GetSongInfo(char* aFilename, char** aTitle, int* aLength)
+{
+	gModplugXMMS.GetSongInfo(aFilename, *aTitle, *aLength);
+}
+
+void ShowAboutBox(void)
+{
+	ShowAboutWindow();
+}
+
+void ShowConfigureBox(void)
+{
+	ShowConfigureWindow(gModplugXMMS.GetModProps());
+}
+
+void ShowFileInfoBox(char* aFilename)
+{
+	ShowInfoWindow(aFilename);
+}
+
+InputPlugin gModPlug =
+{
+	NULL,
+	NULL,
+	"ModPlug Player",
+	Init,
+	ShowAboutBox,
+	ShowConfigureBox,
+	CanPlayFile,
+	NULL,
+	PlayFile,
+	Stop,
+	Pause,
+	Seek,
+	NULL,
+	GetTime,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	GetSongInfo,
+	ShowFileInfoBox,
+	NULL
+};
+
+extern "C"
+{
+	InputPlugin* get_iplugin_info (void)
+	{
+		return &gModPlug;
+	}
+}