[Scummvm-cvs-logs] SF.net SVN: scummvm: [25189] scummvm/trunk/engines/gob

drmccoy at users.sourceforge.net drmccoy at users.sourceforge.net
Thu Jan 25 15:18:13 CET 2007


Revision: 25189
          http://scummvm.svn.sourceforge.net/scummvm/?rev=25189&view=rev
Author:   drmccoy
Date:     2007-01-25 06:18:12 -0800 (Thu, 25 Jan 2007)

Log Message:
-----------
- Some clean-up
- Fixed sound playing and looping
- Changed Paula to use non-absolute panning, defaulting to 0.25/0.75 and 0.75/0.25, as per madmoose's suggestion
- Prepared/Cleaned-up Paula and Infogrames for the move to sound/mods/

Modified Paths:
--------------
    scummvm/trunk/engines/gob/cdrom.cpp
    scummvm/trunk/engines/gob/game.cpp
    scummvm/trunk/engines/gob/game.h
    scummvm/trunk/engines/gob/gob.cpp
    scummvm/trunk/engines/gob/gob.h
    scummvm/trunk/engines/gob/goblin.cpp
    scummvm/trunk/engines/gob/goblin.h
    scummvm/trunk/engines/gob/goblin_v2.cpp
    scummvm/trunk/engines/gob/inter.h
    scummvm/trunk/engines/gob/inter_v2.cpp
    scummvm/trunk/engines/gob/mult_v2.cpp
    scummvm/trunk/engines/gob/music.cpp
    scummvm/trunk/engines/gob/music.h
    scummvm/trunk/engines/gob/sound.cpp

Modified: scummvm/trunk/engines/gob/cdrom.cpp
===================================================================
--- scummvm/trunk/engines/gob/cdrom.cpp	2007-01-25 12:52:27 UTC (rev 25188)
+++ scummvm/trunk/engines/gob/cdrom.cpp	2007-01-25 14:18:12 UTC (rev 25189)
@@ -158,7 +158,7 @@
 	if (!_LICbuffer)
 		return;
 
-	debugC(1, kDebugMusic, "startTrack(%s)", trackname);
+	debugC(1, kDebugMusic, "CDROM::startTrack(%s)", trackname);
 
 	matchPtr = 0;
 	curPtr = _LICbuffer;
@@ -200,7 +200,7 @@
 	// HSG encodes frame information into a double word:
 	// minute multiplied by 4500, plus second multiplied by 75,
 	// plus frame, minus 150
-	debugC(1, kDebugMusic, "play(%d, %d)", from, to);
+	debugC(1, kDebugMusic, "CDROM::play(%d, %d)", from, to);
 
 	AudioCD.play(1, 1, from, to - from + 1);
 	_cdPlaying = true;
@@ -226,7 +226,7 @@
 }
 
 void CDROM::stop(void) {
-	debugC(1, kDebugMusic, "stop()");
+	debugC(1, kDebugMusic, "CDROM::stop()");
 
 	AudioCD.stop();
 	_cdPlaying = false;

Modified: scummvm/trunk/engines/gob/game.cpp
===================================================================
--- scummvm/trunk/engines/gob/game.cpp	2007-01-25 12:52:27 UTC (rev 25188)
+++ scummvm/trunk/engines/gob/game.cpp	2007-01-25 14:18:12 UTC (rev 25189)
@@ -72,6 +72,8 @@
 		_soundFromExt[i] = 0;
 		_soundADL[i] = false;
 	}
+	_infIns = 0;
+	_infogrames = 0;
 
 	_curTotFile[0] = 0;
 	_curExtFile[0] = 0;
@@ -148,6 +150,8 @@
 		delete[] _imdVidBuffer;
 	if (_word_2FC80)
 		delete[] _word_2FC80;
+	if (_infIns)
+		delete _infIns;
 }
 
 char *Game::loadExtData(int16 itemId, int16 *pResWidth, int16 *pResHeight, uint32 *dataSize) {

Modified: scummvm/trunk/engines/gob/game.h
===================================================================
--- scummvm/trunk/engines/gob/game.h	2007-01-25 12:52:27 UTC (rev 25188)
+++ scummvm/trunk/engines/gob/game.h	2007-01-25 14:18:12 UTC (rev 25189)
@@ -24,6 +24,7 @@
 #define GOB_GAME_H
 
 #include "gob/sound.h"
+#include "gob/music.h"
 #include "gob/video.h"
 
 namespace Gob {
@@ -151,6 +152,10 @@
 	char _soundFromExt[60];
 	bool _soundADL[60];
 
+	Infogrames::Instruments *_infIns;
+	Infogrames *_infogrames;
+	Audio::SoundHandle _infHandle;
+
 	char _totToLoad[20];
 
 	int32 _startTimeKey;

Modified: scummvm/trunk/engines/gob/gob.cpp
===================================================================
--- scummvm/trunk/engines/gob/gob.cpp	2007-01-25 12:52:27 UTC (rev 25188)
+++ scummvm/trunk/engines/gob/gob.cpp	2007-01-25 14:18:12 UTC (rev 25189)
@@ -226,10 +226,6 @@
 	delete _util;
 	if (_adlib)
 		delete _adlib;
-	if (_infogrames) {
-		_infogrames->unload(true);
-		delete _infogrames;
-	}
 	delete _video;
 	delete[] _startTot;
 	delete[] _startTot0;
@@ -687,7 +683,6 @@
 }
 
 int GobEngine::init() {
-	_infogrames = 0;
 	_adlib = 0;
 	_snd = new Snd(this);
 	_global = new Global(this);
@@ -724,9 +719,11 @@
 	}
 	else
 		error("GobEngine::init(): Unknown version of game engine");
+	_noMusic = MidiDriver::parseMusicDriver(ConfMan.get("music_driver")) == MD_NULL;
 	if (!(_features & Gob::GF_AMIGA) &&
-			((_features & Gob::GF_MAC) || (_features & Gob::GF_GOB1) || (_features & Gob::GF_GOB2))) {
-		if (MidiDriver::parseMusicDriver(ConfMan.get("music_driver")) == MD_NULL)
+			(((_features & Gob::GF_MAC) && (_features & Gob::GF_GOB1)) ||
+			 (_features & Gob::GF_GOB2))) {
+		if (_noMusic)
 			_adlib = new Adlib_Dummy(this);
 		else
 			_adlib = new Adlib(this);

Modified: scummvm/trunk/engines/gob/gob.h
===================================================================
--- scummvm/trunk/engines/gob/gob.h	2007-01-25 12:52:27 UTC (rev 25188)
+++ scummvm/trunk/engines/gob/gob.h	2007-01-25 14:18:12 UTC (rev 25189)
@@ -146,6 +146,7 @@
 	char *_startTot;
 	char *_startTot0;
 	bool _copyProtection;
+	bool _noMusic;
 	bool _quitRequested;
 
 	Game *_game;
@@ -168,7 +169,6 @@
 	Util *_util;
 	Inter *_inter;
 	Adlib *_adlib;
-	Infogrames *_infogrames;
 	GobEngine *_vm;
 
 	void writeVarDebug(uint32 offs, uint32 v);

Modified: scummvm/trunk/engines/gob/goblin.cpp
===================================================================
--- scummvm/trunk/engines/gob/goblin.cpp	2007-01-25 12:52:27 UTC (rev 25188)
+++ scummvm/trunk/engines/gob/goblin.cpp	2007-01-25 14:18:12 UTC (rev 25189)
@@ -1793,170 +1793,6 @@
 
 }
 
-void Goblin::sub_19BD3(void) {
-	Mult::Mult_Object *obj0;
-	Mult::Mult_Object *obj1;
-	Mult::Mult_AnimData *anim0;
-	Mult::Mult_AnimData *anim1;
-	int16 pass;
-	int16 gob1X;
-	int16 gob2X;
-	int16 gob1Y;
-	int16 gob2Y;
-	int16 var_A;
-	int16 var_C;
-	int16 di;
-	int16 si;
-
-	obj0 = &_vm->_mult->_objects[0];
-	obj1 = &_vm->_mult->_objects[1];
-	anim0 = obj0->pAnimData;
-	anim1 = obj1->pAnimData;
-
-	si = anim0->state;
-	di = anim1->state;
-
-	if (anim0->isBusy == 0) {
-		if ((_word_2F9BC == 0) && (anim0->isStatic == 0)) {
-			if ((VAR(_dword_2F9B6) == 0) && (si == 28)) {
-				si = _vm->_util->getRandom(3) + 24;
-				sub_195C7(0, si);
-				WRITE_VAR(_dword_2F9B6, 100);
-			} else
-				WRITE_VAR(_dword_2F9B6, VAR(_dword_2F9B6) - 1);
-		}
-		if ((si == 8) || (si == 9) || (si == 29))
-			anim0->curLookDir = 6;
-	}
-	if (anim1->isBusy == 0) {
-		if ((_word_2F9BA == 0) && (anim1->isStatic == 0)) {
-			if ((VAR(_dword_2F9B2) == 0) && (di == 28)) {
-				di = _vm->_util->getRandom(3) + 24;
-				sub_195C7(1, di);
-				WRITE_VAR(_dword_2F9B2, 100);
-			} else
-				WRITE_VAR(_dword_2F9B2, VAR(_dword_2F9B2) - 1);
-		}
-		if ((di == 8) || (di == 9) || (di == 29))
-			anim1->curLookDir = 6;
-	}
-
-	if ((anim0->isBusy == 1) && (anim0->isStatic == 0) &&
-			((anim0->state == 28) || (anim0->state == 29)))
-		anim0->curLookDir = 0;
-	if ((anim1->isBusy == 1) && (anim1->isStatic == 0) &&
-			((anim1->state == 28) || (anim1->state == 29)))
-		anim1->curLookDir = 0;
-
-	if (VAR(18) != ((uint32) -1)) {
-		if (anim0->layer == 44)
-			anim0->curLookDir = 4;
-		else if (anim0->layer == 45)
-			anim0->curLookDir = 0;
-		if (anim0->isBusy == 0)
-			anim0->curLookDir = 6;
-	}
-	if (VAR(19) != ((uint32) -1)) {
-		if (anim1->layer == 48)
-			anim1->curLookDir = 4;
-		else if (anim1->layer == 49)
-			anim1->curLookDir = 0;
-		if (anim1->isBusy == 0)
-			anim1->curLookDir = 6;
-	}
-
-	if ((anim0->layer == 45) && (anim0->curLookDir == 4) && (anim0->pathExistence == 5) &&
-			(VAR(18) == ((uint32) -1)) && (_word_2F9C0 == 0)) {
-		sub_195C7(0, 19);
-	}
-	if ((anim0->layer == 44) && (anim0->curLookDir == 0) && (anim0->pathExistence == 5) &&
-			(VAR(18) == ((uint32) -1)) && (_word_2F9C0 == 0)) {
-		sub_195C7(0, 16);
-	}
-	if ((anim1->layer == 49) && (anim1->curLookDir == 4) && (anim1->pathExistence == 5) &&
-			(VAR(19) == ((uint32) -1)) && (_word_2F9BE == 0)) {
-		sub_195C7(1, 19);
-	}
-	if ((anim1->layer == 48) && (anim1->curLookDir == 0) && (anim1->pathExistence == 5) &&
-			(VAR(19) == ((uint32) -1)) && (_word_2F9BE == 0)) {
-		sub_195C7(1, 16);
-	}
-
-	gob1X = obj0->goblinX;
-	gob2X = obj1->goblinX;
-	gob1Y = obj0->goblinY;
-	gob2Y = obj1->goblinY;
-	di = anim0->field_13;
-	si = anim0->field_14;
-	var_A = anim1->field_13;
-	var_C = anim1->field_14;
-
-	pass = _vm->_map->getPass(gob1X, gob1Y);
-	if ((pass > 17) && (pass < 21))
-		sub_19AB7(anim0);
-	pass = _vm->_map->getPass(gob2X, gob2Y);
-	if ((pass > 17) && (pass < 21))
-		sub_19B45(anim1);
-
-	if ((di < 0) || (di > 39) || (si < 0) || (si > 39))
-		return;
-
-	if (gob1Y > si) {
-		if (_vm->_map->getPass(di, si) > 17) {
-			do {
-				si--;
-			} while (_vm->_map->getPass(di, si) > 17);
-			si++;
-			if (_vm->_map->getPass(di - 1, si) == 0) {
-				if (_vm->_map->getPass(di + 1, si) != 0)
-					di++;
-			} else
-				di--;
-			sub_197A6(di, si, 0);
-		}
-	} else {
-		if (_vm->_map->getPass(di, si) > 17) {
-			do {
-				si++;
-			} while (_vm->_map->getPass(di, si) > 17);
-			si--;
-			if (_vm->_map->getPass(di - 1, si) == 0) {
-				if (_vm->_map->getPass(di + 1, si) != 0)
-					di++;
-			} else
-				di--;
-			sub_197A6(di, si, 0);
-		}
-	}
-	if (gob2Y > var_C) {
-		if (_vm->_map->getPass(var_A, var_C) > 17) {
-			do {
-				var_C--;
-			} while (_vm->_map->getPass(var_A, var_C) > 17);
-			var_C++;
-			if (_vm->_map->getPass(var_A - 1, var_C) == 0) {
-				if (_vm->_map->getPass(var_A + 1, var_C) != 0)
-					var_A++;
-			} else
-				var_A--;
-			sub_197A6(var_A, var_C, 1);
-		}
-	} else {
-		if (_vm->_map->getPass(var_A, var_C) > 17) {
-			do {
-				var_C++;
-			} while (_vm->_map->getPass(var_A, var_C) > 17);
-			var_C--;
-			if (_vm->_map->getPass(var_A - 1, var_C) == 0) {
-				if (_vm->_map->getPass(var_A + 1, var_C) != 0)
-					var_A++;
-			} else
-				var_A--;
-			sub_197A6(var_A, var_C, 1);
-		}
-	}
-}
-
 void Goblin::sub_195C7(int16 index, int16 state) {
 	Mult::Mult_Object *obj;
 	Mult::Mult_AnimData *animData;

Modified: scummvm/trunk/engines/gob/goblin.h
===================================================================
--- scummvm/trunk/engines/gob/goblin.h	2007-01-25 12:52:27 UTC (rev 25188)
+++ scummvm/trunk/engines/gob/goblin.h	2007-01-25 14:18:12 UTC (rev 25189)
@@ -217,13 +217,13 @@
 	int16 treatItem(int16 action);
 	int16 doMove(Gob_Object *gobDesc, int16 cont, int16 action);
 
-	void sub_19BD3(void);
 	void sub_195C7(int16 index, int16 state);
 	void sub_11984(Mult::Mult_Object *obj);
 	void sub_197A6(int16 destX, int16 destY, int16 objIndex);
 	void sub_19AB7(Mult::Mult_AnimData *animData);
 	void sub_19B45(Mult::Mult_AnimData *animData);
 
+	virtual void handleGoblins(void) = 0;
 	virtual void placeObject(Gob_Object * objDesc, char animated,
 			int16 index, int16 x, int16 y, int16 state) = 0;
 	virtual void freeObjects(void) = 0;
@@ -257,6 +257,7 @@
 
 class Goblin_v1 : public Goblin {
 public:
+	virtual void handleGoblins(void) {}
 	virtual void placeObject(Gob_Object * objDesc, char animated,
 			int16 index, int16 x, int16 y, int16 state);
 	virtual void freeObjects(void);
@@ -273,6 +274,7 @@
 
 class Goblin_v2 : public Goblin_v1 {
 public:
+	virtual void handleGoblins(void);
 	virtual void placeObject(Gob_Object * objDesc, char animated,
 			int16 index, int16 x, int16 y, int16 state);
 	virtual void freeObjects(void);

Modified: scummvm/trunk/engines/gob/goblin_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/goblin_v2.cpp	2007-01-25 12:52:27 UTC (rev 25188)
+++ scummvm/trunk/engines/gob/goblin_v2.cpp	2007-01-25 14:18:12 UTC (rev 25189)
@@ -523,4 +523,168 @@
 	}
 }
 
+void Goblin_v2::handleGoblins(void) {
+	Mult::Mult_Object *obj0;
+	Mult::Mult_Object *obj1;
+	Mult::Mult_AnimData *anim0;
+	Mult::Mult_AnimData *anim1;
+	int16 pass;
+	int16 gob1X;
+	int16 gob2X;
+	int16 gob1Y;
+	int16 gob2Y;
+	int16 var_A;
+	int16 var_C;
+	int16 di;
+	int16 si;
+
+	obj0 = &_vm->_mult->_objects[0];
+	obj1 = &_vm->_mult->_objects[1];
+	anim0 = obj0->pAnimData;
+	anim1 = obj1->pAnimData;
+
+	si = anim0->state;
+	di = anim1->state;
+
+	if (anim0->isBusy == 0) {
+		if ((_word_2F9BC == 0) && (anim0->isStatic == 0)) {
+			if ((VAR(_dword_2F9B6) == 0) && (si == 28)) {
+				si = _vm->_util->getRandom(3) + 24;
+				sub_195C7(0, si);
+				WRITE_VAR(_dword_2F9B6, 100);
+			} else
+				WRITE_VAR(_dword_2F9B6, VAR(_dword_2F9B6) - 1);
+		}
+		if ((si == 8) || (si == 9) || (si == 29))
+			anim0->curLookDir = 6;
+	}
+	if (anim1->isBusy == 0) {
+		if ((_word_2F9BA == 0) && (anim1->isStatic == 0)) {
+			if ((VAR(_dword_2F9B2) == 0) && (di == 28)) {
+				di = _vm->_util->getRandom(3) + 24;
+				sub_195C7(1, di);
+				WRITE_VAR(_dword_2F9B2, 100);
+			} else
+				WRITE_VAR(_dword_2F9B2, VAR(_dword_2F9B2) - 1);
+		}
+		if ((di == 8) || (di == 9) || (di == 29))
+			anim1->curLookDir = 6;
+	}
+
+	if ((anim0->isBusy == 1) && (anim0->isStatic == 0) &&
+			((anim0->state == 28) || (anim0->state == 29)))
+		anim0->curLookDir = 0;
+	if ((anim1->isBusy == 1) && (anim1->isStatic == 0) &&
+			((anim1->state == 28) || (anim1->state == 29)))
+		anim1->curLookDir = 0;
+
+	if (VAR(18) != ((uint32) -1)) {
+		if (anim0->layer == 44)
+			anim0->curLookDir = 4;
+		else if (anim0->layer == 45)
+			anim0->curLookDir = 0;
+		if (anim0->isBusy == 0)
+			anim0->curLookDir = 6;
+	}
+	if (VAR(19) != ((uint32) -1)) {
+		if (anim1->layer == 48)
+			anim1->curLookDir = 4;
+		else if (anim1->layer == 49)
+			anim1->curLookDir = 0;
+		if (anim1->isBusy == 0)
+			anim1->curLookDir = 6;
+	}
+
+	if ((anim0->layer == 45) && (anim0->curLookDir == 4) && (anim0->pathExistence == 5) &&
+			(VAR(18) == ((uint32) -1)) && (_word_2F9C0 == 0)) {
+		sub_195C7(0, 19);
+	}
+	if ((anim0->layer == 44) && (anim0->curLookDir == 0) && (anim0->pathExistence == 5) &&
+			(VAR(18) == ((uint32) -1)) && (_word_2F9C0 == 0)) {
+		sub_195C7(0, 16);
+	}
+	if ((anim1->layer == 49) && (anim1->curLookDir == 4) && (anim1->pathExistence == 5) &&
+			(VAR(19) == ((uint32) -1)) && (_word_2F9BE == 0)) {
+		sub_195C7(1, 19);
+	}
+	if ((anim1->layer == 48) && (anim1->curLookDir == 0) && (anim1->pathExistence == 5) &&
+			(VAR(19) == ((uint32) -1)) && (_word_2F9BE == 0)) {
+		sub_195C7(1, 16);
+	}
+
+	gob1X = obj0->goblinX;
+	gob2X = obj1->goblinX;
+	gob1Y = obj0->goblinY;
+	gob2Y = obj1->goblinY;
+	di = anim0->field_13;
+	si = anim0->field_14;
+	var_A = anim1->field_13;
+	var_C = anim1->field_14;
+
+	pass = _vm->_map->getPass(gob1X, gob1Y);
+	if ((pass > 17) && (pass < 21))
+		sub_19AB7(anim0);
+	pass = _vm->_map->getPass(gob2X, gob2Y);
+	if ((pass > 17) && (pass < 21))
+		sub_19B45(anim1);
+
+	if ((di < 0) || (di > 39) || (si < 0) || (si > 39))
+		return;
+
+	if (gob1Y > si) {
+		if (_vm->_map->getPass(di, si) > 17) {
+			do {
+				si--;
+			} while (_vm->_map->getPass(di, si) > 17);
+			si++;
+			if (_vm->_map->getPass(di - 1, si) == 0) {
+				if (_vm->_map->getPass(di + 1, si) != 0)
+					di++;
+			} else
+				di--;
+			sub_197A6(di, si, 0);
+		}
+	} else {
+		if (_vm->_map->getPass(di, si) > 17) {
+			do {
+				si++;
+			} while (_vm->_map->getPass(di, si) > 17);
+			si--;
+			if (_vm->_map->getPass(di - 1, si) == 0) {
+				if (_vm->_map->getPass(di + 1, si) != 0)
+					di++;
+			} else
+				di--;
+			sub_197A6(di, si, 0);
+		}
+	}
+	if (gob2Y > var_C) {
+		if (_vm->_map->getPass(var_A, var_C) > 17) {
+			do {
+				var_C--;
+			} while (_vm->_map->getPass(var_A, var_C) > 17);
+			var_C++;
+			if (_vm->_map->getPass(var_A - 1, var_C) == 0) {
+				if (_vm->_map->getPass(var_A + 1, var_C) != 0)
+					var_A++;
+			} else
+				var_A--;
+			sub_197A6(var_A, var_C, 1);
+		}
+	} else {
+		if (_vm->_map->getPass(var_A, var_C) > 17) {
+			do {
+				var_C++;
+			} while (_vm->_map->getPass(var_A, var_C) > 17);
+			var_C--;
+			if (_vm->_map->getPass(var_A - 1, var_C) == 0) {
+				if (_vm->_map->getPass(var_A + 1, var_C) != 0)
+					var_A++;
+			} else
+				var_A--;
+			sub_197A6(var_A, var_C, 1);
+		}
+	}
+}
+
 } // End of namespace Gob

Modified: scummvm/trunk/engines/gob/inter.h
===================================================================
--- scummvm/trunk/engines/gob/inter.h	2007-01-25 12:52:27 UTC (rev 25188)
+++ scummvm/trunk/engines/gob/inter.h	2007-01-25 14:18:12 UTC (rev 25189)
@@ -362,7 +362,8 @@
 	void o2_playMult(void);
 	void o2_initCursor(void);
 	void o2_playImd(void);
-	void o2_setPickable(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
+	void o2_handleGoblins(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
+	void o2_playInfogrames(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc);
 };
 
 }				// End of namespace Gob

Modified: scummvm/trunk/engines/gob/inter_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/inter_v2.cpp	2007-01-25 12:52:27 UTC (rev 25188)
+++ scummvm/trunk/engines/gob/inter_v2.cpp	2007-01-25 14:18:12 UTC (rev 25189)
@@ -84,7 +84,7 @@
 	{50, 36},
 	{52, 37},
 	{53, 38},
-	{150, 39},
+	{100, 39},
 	{152, 40},
 	{200, 41},
 	{201, 42},
@@ -551,94 +551,94 @@
 
 	static const OpcodeGoblinEntryV2 opcodesGoblin[71] = {
 		/* 00 */
-		OPCODE(o1_setState),
-		OPCODE(o1_setCurFrame),
-		OPCODE(o1_setNextState),
-		OPCODE(o1_setMultState),
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
 		/* 04 */
-		OPCODE(o1_setOrder),
-		OPCODE(o1_setActionStartState),
-		OPCODE(o1_setCurLookDir),
-		OPCODE(o1_setType),
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
 		/* 08 */
-		OPCODE(o1_setNoTick),
-		OPCODE(o2_setPickable),
-		OPCODE(o1_setXPos),
-		OPCODE(o1_setYPos),
+		{NULL, ""},
+		OPCODE(o2_playInfogrames),
+		{NULL, ""},
+		{NULL, ""},
 		/* 0C */
-		OPCODE(o1_setDoAnim),
-		OPCODE(o1_setRelaxTime),
-		OPCODE(o1_setMaxTick),
-		OPCODE(o1_getState),
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
 		/* 10 */
-		OPCODE(o1_getCurFrame),
-		OPCODE(o1_getNextState),
-		OPCODE(o1_getMultState),
-		OPCODE(o1_getOrder),
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
 		/* 14 */
-		OPCODE(o1_getActionStartState),
-		OPCODE(o1_getCurLookDir),
-		OPCODE(o1_getType),
-		OPCODE(o1_getNoTick),
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
 		/* 18 */
-		OPCODE(o1_getPickable),
-		OPCODE(o1_getObjMaxFrame),
-		OPCODE(o1_getXPos),
-		OPCODE(o1_getYPos),
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
 		/* 1C */
-		OPCODE(o1_getDoAnim),
-		OPCODE(o1_getRelaxTime),
-		OPCODE(o1_getMaxTick),
-		OPCODE(o1_manipulateMap),
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
 		/* 20 */
-		OPCODE(o1_getItem),
-		OPCODE(o1_manipulateMapIndirect),
-		OPCODE(o1_getItemIndirect),
-		OPCODE(o1_setPassMap),
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
 		/* 24 */
-		OPCODE(o1_setGoblinPosH),
-		OPCODE(o1_getGoblinPosXH),
-		OPCODE(o1_getGoblinPosYH),
-		OPCODE(o1_setGoblinMultState),
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
+		OPCODE(o2_handleGoblins),
 		/* 28 */
-		OPCODE(o1_setGoblinUnk14),
-		OPCODE(o1_setItemIdInPocket),
-		OPCODE(o1_setItemIndInPocket),
-		OPCODE(o1_getItemIdInPocket),
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
 		/* 2C */
-		OPCODE(o1_getItemIndInPocket),
-		OPCODE(o1_setItemPos),
-		OPCODE(o1_setGoblinPos),
-		OPCODE(o1_setGoblinState),
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
 		/* 30 */
-		OPCODE(o1_setGoblinStateRedraw),
-		OPCODE(o1_decRelaxTime),
-		OPCODE(o1_getGoblinPosX),
-		OPCODE(o1_getGoblinPosY),
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
 		/* 34 */
-		OPCODE(o1_clearPathExistence),
-		OPCODE(o1_setGoblinVisible),
-		OPCODE(o1_setGoblinInvisible),
-		OPCODE(o1_getObjectIntersect),
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
 		/* 38 */
-		OPCODE(o1_getGoblinIntersect),
-		OPCODE(o1_setItemPos),
-		OPCODE(o1_loadObjects),
-		OPCODE(o1_freeObjects),
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
 		/* 3C */
-		OPCODE(o1_animateObjects),
-		OPCODE(o1_drawObjects),
-		OPCODE(o1_loadMap),
-		OPCODE(o1_moveGoblin),
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
 		/* 40 */
-		OPCODE(o1_switchGoblin),
-		OPCODE(o1_loadGoblin),
-		OPCODE(o1_writeTreatItem),
-		OPCODE(o1_moveGoblin0),
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
 		/* 44 */
-		OPCODE(o1_setGoblinTarget),
-		OPCODE(o1_setGoblinObjectsPos),
-		OPCODE(o1_initGoblin)
+		{NULL, ""},
+		{NULL, ""},
+		{NULL, ""},
 	};
 
 	_opcodesDrawV2 = opcodesDraw;
@@ -687,9 +687,11 @@
 		}
 
 	if (op == NULL) {
-		warning("unimplemented opcodeGoblin: %d", i);
+		int16 val;
+
 		_vm->_global->_inter_execPtr -= 2;
-		_vm->_global->_inter_execPtr += load16() * 2;
+		val = load16();
+		_vm->_global->_inter_execPtr += val << 1;
 	}
 	else
 		(this->*op) (extraData, retVarPtr, objDesc);
@@ -1613,52 +1615,13 @@
 
 bool Inter_v2::o2_goblinFunc(char &cmdCount, int16 &counter, int16 &retFlag) {
 	int16 cmd;
-	char fileName[20];
+	int16 extraData;
 
 	cmd = load16();
 	_vm->_global->_inter_execPtr += 2;
 
-	switch (cmd) {
-	case 0:
-	case 1:
-	case 2:
-	case 3:
-	case 11:
-	case 13:
-		load16();
-		break;
-
-	case 10:
-		strcpy(fileName, GET_VAR_STR(load16()));
-		strcat(fileName, ".DUM");
-		if (!_vm->_infogrames) {
-			_vm->_infogrames = new Infogrames(_vm, true);
-			_vm->_infogrames->loadInstruments("i1.ins");
-		}
-		_vm->_infogrames->load(fileName);
-		_vm->_infogrames->startPlay();
-		break;
-
-	case 100:
-		_vm->_goblin->_word_2F9C0 = VAR(load16());
-		_vm->_goblin->_word_2F9BE = VAR(load16());
-		_vm->_goblin->_dword_2F9B6 = load16();
-		_vm->_goblin->_dword_2F9B2 = load16();
-		_vm->_goblin->_word_2F9BC = VAR(load16());
-		_vm->_goblin->_word_2F9BA = VAR(load16());
-		_vm->_goblin->sub_19BD3();
-		break;
-
-	case 101:
-		break;
-
-	default:
-		_vm->_global->_inter_execPtr -= 2;
-		cmd = load16();
-		_vm->_global->_inter_execPtr += cmd << 1;
-		break;
-	}
-
+	if (cmd != 101)
+		executeGoblinOpcode(cmd, extraData, NULL, NULL);
 	return false;
 }
 
@@ -2346,6 +2309,51 @@
 	_vm->_game->switchTotSub(index, skipPlay);
 }
 
+void Inter_v2::o2_handleGoblins(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) {
+	_vm->_goblin->_word_2F9C0 = VAR(load16());
+	_vm->_goblin->_word_2F9BE = VAR(load16());
+	_vm->_goblin->_dword_2F9B6 = load16();
+	_vm->_goblin->_dword_2F9B2 = load16();
+	_vm->_goblin->_word_2F9BC = VAR(load16());
+	_vm->_goblin->_word_2F9BA = VAR(load16());
+	_vm->_goblin->handleGoblins();
+}
+
+void Inter_v2::o2_playInfogrames(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) {
+	int16 varName;
+	char fileName[20];
+
+	varName = load16();
+
+	if (_vm->_noMusic)
+		return;
+
+	strcpy(fileName, GET_VAR_STR(varName));
+	strcat(fileName, ".DUM");
+	debugC(1, kDebugMusic, "Playing Infogrames music file \"%s\"", fileName);
+	if (!_vm->_game->_infIns) {
+		_vm->_game->_infIns = new Infogrames::Instruments;
+		if (!_vm->_game->_infIns->load("i1.ins")) {
+			warning("Couldn't load instruments file");
+			delete _vm->_game->_infIns;
+			_vm->_game->_infIns = 0;
+		}
+	}
+	if (_vm->_game->_infIns) {
+		_vm->_mixer->stopHandle(_vm->_game->_infHandle);
+		_vm->_game->_infogrames =
+			new Infogrames(*_vm->_game->_infIns, true,
+					_vm->_mixer->getOutputRate());
+		if (!_vm->_game->_infogrames->load(fileName)) {
+			warning("Couldn't load infogrames music");
+			delete _vm->_game->_infogrames;
+			_vm->_game->_infogrames = 0;
+		} else
+			_vm->_mixer->playInputStream(Audio::Mixer::kMusicSoundType,
+					&_vm->_game->_infHandle, _vm->_game->_infogrames);
+	}
+}
+
 void Inter_v2::storeKey(int16 key) {
 	WRITE_VAR(12, _vm->_util->getTimeKey() - _vm->_game->_startTimeKey);
 
@@ -2388,10 +2396,6 @@
 	WRITE_VAR(4, _vm->_game->_mouseButtons);
 }
 
-void Inter_v2::o2_setPickable(int16 &extraData, int32 *retVarPtr, Goblin::Gob_Object *objDesc) {
-	warning("GOB2 Stub! o2_setPickable");
-}
-
 void Inter_v2::animPalette(void) {
 	int16 i;
 	int16 j;

Modified: scummvm/trunk/engines/gob/mult_v2.cpp
===================================================================
--- scummvm/trunk/engines/gob/mult_v2.cpp	2007-01-25 12:52:27 UTC (rev 25188)
+++ scummvm/trunk/engines/gob/mult_v2.cpp	2007-01-25 14:18:12 UTC (rev 25189)
@@ -516,7 +516,6 @@
 	}
 
 	do {
-		_vm->_snd->loopSounds();
 		stop = 1;
 
 		if (VAR(58) == 0) {
@@ -540,6 +539,7 @@
 
 		stop = doFadeAnim(stop);
 		stop = doSoundAnim(stop, _frame);
+		_vm->_snd->loopSounds();
 
 		if (_frame >= endFrame)
 			stopNoClear = 1;
@@ -1318,18 +1318,7 @@
 
 void Mult_v2::playSound(Snd::SoundDesc * soundDesc, int16 repCount, int16 freq,
 	    int16 channel) {
-//	warning("playSound, %d, %d, %d", repCount, freq, channel);
-	if (soundDesc->frequency >= 0) {
-		if (soundDesc->frequency == freq)
-			_vm->_snd->playSample(soundDesc, repCount, -channel);
-		else
-			_vm->_snd->playSample(soundDesc, repCount, freq);
-	} else {
-		if (soundDesc->frequency == -freq)
-			_vm->_snd->playSample(soundDesc, repCount, -channel);
-		else
-			_vm->_snd->playSample(soundDesc, repCount, freq);
-	}
+	_vm->_snd->playSample(soundDesc, repCount, freq);
 }
 
 void Mult_v2::freeMult(void) {

Modified: scummvm/trunk/engines/gob/music.cpp
===================================================================
--- scummvm/trunk/engines/gob/music.cpp	2007-01-25 12:52:27 UTC (rev 25188)
+++ scummvm/trunk/engines/gob/music.cpp	2007-01-25 14:18:12 UTC (rev 25189)
@@ -32,19 +32,15 @@
 
 namespace Gob {
 
-Paula::Paula(GobEngine *vm, bool stereo, int intFreq) : _vm(vm) {
+Paula::Paula(bool stereo, int rate, int interruptFreq) :
+		_stereo(stereo), _rate(rate), _intFreq(interruptFreq) {
 	_playing = false;
 
-	_stereo = stereo;
-	_rate = _vm->_mixer->getOutputRate();
-	_vm->_mixer->setupPremix(this, Audio::Mixer::kMusicSoundType);
-	_intFreq = intFreq;
-
 	clearVoices();
-	_voice[0].panning = 0;
-	_voice[1].panning = 1;
-	_voice[2].panning = 1;
-	_voice[3].panning = 0;
+	_voice[0].panning = 63;
+	_voice[1].panning = 191;
+	_voice[2].panning = 191;
+	_voice[3].panning = 63;
 
 	if (_intFreq <= 0)
 		_intFreq = _rate;
@@ -54,10 +50,12 @@
 }
 
 Paula::~Paula() {
-	_vm->_mixer->setupPremix(0);
 }
 
-void Paula::clearVoice(int voice) {
+void Paula::clearVoice(byte voice) {
+	if (voice >= 4)
+		return;
+
 	_voice[voice].data = 0;
 	_voice[voice].dataRepeat = 0;
 	_voice[voice].length = 0;
@@ -78,9 +76,14 @@
 	int16 *p;
 	int8 *data;
 
+	_mutex.lock();
+
 	memset(buffer, 0, numSamples * 2);
 	if (!_playing)
+	{
+		_mutex.unlock();
 		return numSamples;
+	}
 
 	samples = _stereo ? numSamples / 2 : numSamples;
 	while (samples > 0) {
@@ -101,7 +104,8 @@
 			p = buffer;
 
 			_voice[voice].volume &= 0x3F;
-			if ((_voice[voice].lengthRepeat > 2) && ((int)(offset + nSamples * rate) >= sLen)) {
+			if ((_voice[voice].lengthRepeat > 2) &&
+					((int)(offset + nSamples * rate) >= sLen)) {
 				int neededSamples = nSamples;
 
 				int end = (int)((sLen - offset) / rate);
@@ -122,7 +126,8 @@
 							mix(p, data[(int)(offset + rate * i)], voice);
 
 						_voice[voice].data = data = _voice[voice].dataRepeat;
-						_voice[voice].length = sLen = _voice[voice].lengthRepeat;
+						_voice[voice].length = sLen =
+							_voice[voice].lengthRepeat;
 						_voice[voice].offset = offset = 0;
 
 						neededSamples -= end;
@@ -132,7 +137,8 @@
 						_voice[voice].offset += rate * neededSamples;
 						if (ceil(_voice[voice].offset) >= sLen) {
 							_voice[voice].data = data = _voice[voice].dataRepeat;
-							_voice[voice].length = sLen = _voice[voice].lengthRepeat;
+							_voice[voice].length = sLen =
+								_voice[voice].lengthRepeat;
 							_voice[voice].offset = offset = 0;
 						}
 						neededSamples = 0;
@@ -148,7 +154,8 @@
 							mix(p, data[(int)(offset + rate * i)], voice);
 						_voice[voice].offset = sLen;
 					} else {
-						// The requested number of samples is the limiting factor, not the sample
+						// The requested number of samples is the limiting
+						// factor, not the sample
 
 						for (int i = 0; i < nSamples; i++)
 							mix(p, data[(int)(offset + rate * i)], voice);
@@ -161,10 +168,20 @@
 		_curInt += nSamples;
 		samples -= nSamples;
 	}
+	_mutex.unlock();
 	return numSamples;
 }
 
 Infogrames::Instruments::Instruments() {
+	init();
+}
+
+Infogrames::Instruments::~Instruments() {
+	if (_sampleData)
+		delete[] _sampleData;
+}
+
+void Infogrames::Instruments::init() {
 	int i;
 
 	for (i = 0; i < 32; i++) {
@@ -177,11 +194,6 @@
 	_sampleData = 0;
 }
 
-Infogrames::Instruments::~Instruments() {
-	if (_sampleData)
-		delete[] _sampleData;
-}
-
 bool Infogrames::Instruments::load(Common::SeekableReadStream &ins) {
 	int i;
 	uint32 fsize;
@@ -189,13 +201,16 @@
 	uint32 offsetRepeat[32];
 	uint32 dataOffset;
 
+	unload();
+
 	fsize = ins.readUint32BE();
 	dataOffset = fsize;
 	for (i = 0; (i < 32) && !ins.eos(); i++) {
 		offset[i] = ins.readUint32BE();
 		offsetRepeat[i] = ins.readUint32BE();
 		if ((offset[i] > fsize) || (offsetRepeat[i] > fsize) ||
-				(offset[i] < (ins.pos() + 4)) || (offsetRepeat[i] < (ins.pos() + 4))) {
+				(offset[i] < (ins.pos() + 4)) ||
+				(offsetRepeat[i] < (ins.pos() + 4))) {
 			// Definitely no real entry anymore
 			ins.seek(-8, SEEK_CUR);
 			break;
@@ -223,29 +238,38 @@
 	return true;
 }
 
+void Infogrames::Instruments::unload(void) {
+	if (_sampleData)
+		delete[] _sampleData;
+	init();
+}
+
+const uint8 Infogrames::tickCount[] =
+	{2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96};
 const uint16 Infogrames::periods[] =
 	{0x6ACC, 0x64CC, 0x5F25, 0x59CE, 0x54C3, 0x5003, 0x4B86, 0x4747, 0x4346,
-		0x3F8B, 0x3BF3, 0x3892, 0x3568, 0x3269, 0x2F93, 0x2CEA, 0x2A66, 0x2801,
-		0x2566, 0x23A5, 0x21AF, 0x1FC4, 0x1DFE, 0x1C4E, 0x1ABC, 0x1936, 0x17CC,
-		0x1676, 0x1533, 0x1401, 0x12E4, 0x11D5, 0x10D4, 0xFE3, 0xEFE, 0xE26, 
-		0xD5B, 0xC9B, 0xBE5, 0xB3B, 0xA9B, 0xA02, 0x972, 0x8E9, 0x869, 0x7F1,
-		0x77F, 0x713, 0x6AD, 0x64D, 0x5F2, 0x59D, 0x54D, 0x500, 0x4B8, 0x475,
-		0x435, 0x3F8, 0x3BF, 0x38A, 0x356, 0x326, 0x2F9, 0x2CF, 0x2A6, 0x280,
-		0x25C, 0x23A, 0x21A, 0x1FC, 0x1E0, 0x1C5, 0x1AB, 0x193, 0x17D, 0x167,
-		0x153, 0x140, 0x12E, 0x11D, 0x10D, 0xFE, 0xF0, 0xE2, 0xD6, 0xCA, 0xBE,
-		0xB4, 0xAA, 0xA0, 0x97, 0x8F, 0x87, 0x7F, 0x78, 0x70, 0x60, 0x50, 0x40,
-		0x30, 0x20, 0x10, 0, 0, 0x20, 0x2020, 0x2020, 0x2020, 0x2020, 0x3030,
-		0x3030, 0x3020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
-		0x2020, 0x2090, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040,
-		0x400C, 0xC0C, 0xC0C, 0xC0C, 0xC0C, 0xC40, 0x4040, 0x4040, 0x4040, 0x909,
-		0x909, 0x909, 0x101, 0x101, 0x101, 0x101, 0x101, 0x101, 0x101, 0x101, 0x101,
-		0x101, 0x4040, 0x4040, 0x4040, 0xA0A, 0xA0A, 0xA0A, 0x202, 0x202, 0x202, 
-		0x202, 0x202, 0x202, 0x202, 0x202, 0x202, 0x202, 0x4040, 0x4040, 0x2000};
-const uint8 Infogrames::tickCount[] = {2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96};
+	 0x3F8B, 0x3BF3, 0x3892, 0x3568, 0x3269, 0x2F93, 0x2CEA, 0x2A66, 0x2801,
+	 0x2566, 0x23A5, 0x21AF, 0x1FC4, 0x1DFE, 0x1C4E, 0x1ABC, 0x1936, 0x17CC,
+	 0x1676, 0x1533, 0x1401, 0x12E4, 0x11D5, 0x10D4, 0x0FE3, 0x0EFE, 0x0E26, 
+	 0x0D5B, 0x0C9B, 0x0BE5, 0x0B3B, 0x0A9B, 0x0A02, 0x0972, 0x08E9, 0x0869,
+	 0x07F1, 0x077F, 0x0713, 0x06AD, 0x064D, 0x05F2, 0x059D, 0x054D, 0x0500,
+	 0x04B8, 0x0475, 0x0435, 0x03F8, 0x03BF, 0x038A, 0x0356, 0x0326, 0x02F9,
+	 0x02CF, 0x02A6, 0x0280, 0x025C, 0x023A, 0x021A, 0x01FC, 0x01E0, 0x01C5,
+	 0x01AB, 0x0193, 0x017D, 0x0167, 0x0153, 0x0140, 0x012E, 0x011D, 0x010D,
+	 0x00FE, 0x00F0, 0x00E2, 0x00D6, 0x00CA, 0x00BE, 0x00B4, 0x00AA, 0x00A0,
+	 0x0097, 0x008F, 0x0087, 0x007F, 0x0078, 0x0070, 0x0060, 0x0050, 0x0040,
+	 0x0030, 0x0020, 0x0010, 0x0000, 0x0000, 0x0020, 0x2020, 0x2020, 0x2020,
+	 0x2020, 0x3030, 0x3030, 0x3020, 0x2020, 0x2020, 0x2020, 0x2020, 0x2020,
+	 0x2020, 0x2020, 0x2020, 0x2090, 0x4040, 0x4040, 0x4040, 0x4040, 0x4040,
+	 0x4040, 0x4040, 0x400C, 0x0C0C, 0x0C0C, 0x0C0C, 0x0C0C, 0x0C40, 0x4040,
+	 0x4040, 0x4040, 0x0909, 0x0909, 0x0909, 0x0101, 0x0101, 0x0101, 0x0101,
+	 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x0101, 0x4040, 0x4040, 0x4040,
+	 0x0A0A, 0x0A0A, 0x0A0A, 0x0202, 0x0202, 0x0202, 0x0202, 0x0202, 0x0202,
+	 0x0202, 0x0202, 0x0202, 0x0202, 0x4040, 0x4040, 0x2000};
 
-Infogrames::Infogrames(GobEngine *vm, bool stereo) :
-		Paula(vm, stereo, vm->_mixer->getOutputRate()/80) {
-	_instruments = 0;
+Infogrames::Infogrames(Instruments &ins, bool stereo, int rate) :
+		Paula(stereo, rate, rate/80) {
+	_instruments = &ins;
 	_data = 0;
 	_repCount = -1;
 
@@ -264,7 +288,6 @@
 	_period = 0;
 	_sample = 0;
 	_speedCounter = _speed;
-	_newVol = 0x3F;
 
 	for (i = 0; i < 4; i++) {
 		_chn[i].cmds = 0;
@@ -285,28 +308,20 @@
 		_chn[i].periodSlide.flags = 0;
 		_chn[i].periodSlide.curDelay1 = 0;
 		_chn[i].periodSlide.curDelay2 = 0;
-		_chn[i].curPeriod = 0;
 		_chn[i].period = 0;
-		_chn[i].curCmdBlock = 0;
-		_chn[i].flags = 0;
+		_chn[i].flags = 0x81;
 		_chn[i].ticks = 0;
 		_chn[i].tickCount = 0;
 		_chn[i].periodMod = 0;
-		_chn[i].field_2B = 0;
-		_chn[i].field_2C = 0;
-		_chn[i].field_2F = 0;
 	}
 
-	for (i = 0; i < 4; i++) {
-		_chn[i].flags = 0x81;
-		_chn[i].field_2B = 0x3F;
-		_chn[i].field_2F = 0x3F;
-	}
+	_end = _data == 0;
 }
 
 void Infogrames::reset() {
 	int i;
 
+	stopPlay();
 	init();
 
 	_volSlideBlocks = 0;
@@ -315,8 +330,6 @@
 	_cmdBlocks = 0;
 	_speedCounter = 0;
 	_speed = 0;
-	_newVol = 0;
-	_field_1E = 8;
 
 	for (i = 0; i < 4; i++)
 		_chn[i].cmdBlockIndices = 0;
@@ -350,11 +363,8 @@
 	for (i = 0; i < 4; i++) {
 		_chn[i].cmdBlockIndices = _subSong + dataStr.readUint16BE();
 		_chn[i].flags = 0x81;
-		_chn[i].field_2B = 0x3F;
-		_chn[i].field_2F = 0x3F;
 	}
 	_cmdBlocks = _data + dataStr.pos() + 2;
-	_newVol = 0x3F;
 
 	if ((_volSlideBlocks > (_data + size)) ||
 			(_periodSlideBlocks > (_data + size)) ||
@@ -366,10 +376,11 @@
 		return false;
 
 	_end = false;
+	_playing = true;
 	return true;
 }
 
-void Infogrames::unload(bool destroyInstruments) {
+void Infogrames::unload(void) {
 	stopPlay();
 
 	if (_data)
@@ -379,12 +390,6 @@
 	clearVoices();
 	reset();
 
-	if (destroyInstruments) {
-		if (_instruments)
-			delete _instruments;
-		_instruments = 0;
-	}
-
 	_end = true;
 }
 
@@ -397,28 +402,16 @@
 	if (chn.flags & 64)
 		return;
 
-	if (chn.field_2B != chn.field_2F) {
-		chn.field_2C++;
-		if (chn.field_2C > _field_1E) {
-			chn.field_2C = 0;
-			if (chn.field_2F <= chn.field_2B)
-				chn.field_2B--;
-			else
-				chn.field_2B++;
-		}
-	}
-
 	if (chn.flags & 1) {
 		chn.flags &= ~1;
 		chn.cmdBlocks = chn.cmdBlockIndices;
-		chn.curCmdBlock = 0;
 	} else {
 		chn.flags &= ~1;
 		if (_speedCounter == 0)
 			chn.ticks--;
 		if (chn.ticks != 0) {
-			_volume = MAX(0, tune(chn.volSlide, 0) - (0x3F - MAX(chn.field_2B, _newVol)));
-			_period = tune(chn.periodSlide, chn.curPeriod);
+			_volume = MAX((int16) 0, tune(chn.volSlide, 0));
+			_period = tune(chn.periodSlide, chn.period);
 			return;
 		} else {
 			chn.ticks = chn.tickCount;
@@ -430,8 +423,8 @@
 		while (cont || ((cmdBlock = *chn.cmdBlocks) != 0xFF)) {
 			if (!cont) {
 				chn.cmdBlocks++;
-				chn.curCmdBlock++;
-				chn.cmds = _subSong + READ_BE_UINT16(_cmdBlocks + (cmdBlock * 2));
+				chn.cmds = _subSong +
+					READ_BE_UINT16(_cmdBlocks + (cmdBlock * 2));
 			} else
 				cont = false;
 			while ((cmd = *chn.cmds) != 0xFF) {
@@ -463,7 +456,8 @@
 							chn.periodMod = (int8) *chn.cmds++;
 							break;
 						case 1: // Set continuous period slide
-							chn.periodSlide.data = _periodSlideBlocks + *chn.cmds++ * 13 + 1;
+							chn.periodSlide.data =
+								_periodSlideBlocks + *chn.cmds++ * 13 + 1;
 							chn.periodSlide.amount = 0;
 							chn.periodSlide.dataOffset = 0;
 							chn.periodSlide.finetunePos = 0;
@@ -473,7 +467,8 @@
 							chn.periodSlide.flags = 0x81;
 							break;
 						case 2: // Set non-continuous period slide
-							chn.periodSlide.data = _periodSlideBlocks + *chn.cmds++ * 13 + 1;
+							chn.periodSlide.data =
+								_periodSlideBlocks + *chn.cmds++ * 13 + 1;
 							chn.periodSlide.amount = 0;
 							chn.periodSlide.dataOffset = 0;
 							chn.periodSlide.finetunePos = 0;
@@ -492,7 +487,6 @@
 				} else { // 0xxxxxxx - Set period
 					if (cmd != 0)
 						cmd += chn.periodMod;
-					chn.curPeriod = periods[cmd];
 					chn.period = periods[cmd];
 					chn.volSlide.dataOffset = 0;
 					chn.volSlide.finetunePos = 0;
@@ -508,20 +502,18 @@
 					chn.periodSlide.curDelay2 = 0;
 					chn.periodSlide.flags |= 1;
 					chn.periodSlide.flags &= ~4;
-					_volume = MAX(0, tune(chn.volSlide, 0) - (0x3F - MAX(chn.field_2B, _newVol)));
-					_period = tune(chn.periodSlide, chn.curPeriod);
+					_volume = MAX((int16) 0, tune(chn.volSlide, 0));
+					_period = tune(chn.periodSlide, chn.period);
 					return;
 				}
 			}
 		}
-		if (chn.flags & 32) {
-			chn.cmdBlocks = chn.cmdBlockIndices;
-			chn.curCmdBlock = 0;
-		} else {
+		if (!(chn.flags & 32)) {
 			chn.flags |= 0x40;
 			_volume = 0;
 			return;
-		}
+		} else
+			chn.cmdBlocks = chn.cmdBlockIndices;
 	}
 }
 
@@ -586,7 +578,8 @@
 			_voice[chn].data = _instruments->_samples[_sample].data;
 			_voice[chn].length = _instruments->_samples[_sample].length;
 			_voice[chn].dataRepeat = _instruments->_samples[_sample].dataRepeat;
-			_voice[chn].lengthRepeat = _instruments->_samples[_sample].lengthRepeat;
+			_voice[chn].lengthRepeat =
+				_instruments->_samples[_sample].lengthRepeat;
 			_voice[chn].offset = 0;
 			_sample = 0xFF;
 		}
@@ -600,10 +593,12 @@
 		if (_repCount > 0) {
 			_repCount--;
 			init();
-		} else if (_repCount == -1)
-			init();
-		else
+		} else if (_repCount != -1) {
 			_end = true;
+			_playing = false;
+		}
+		else
+			init();
 	}
 }
 
@@ -698,7 +693,8 @@
 			uint datalen = len;
 			while (datalen && _playing) {
 				if (_samplesTillPoll) {
-					render = (datalen > _samplesTillPoll) ? (_samplesTillPoll) : (datalen);
+					render = (datalen > _samplesTillPoll) ?
+						(_samplesTillPoll) : (datalen);
 					datalen -= render;
 					_samplesTillPoll -= render;
 					YM3812UpdateOne(_opl, data, render);
@@ -759,10 +755,10 @@
 		// Run through the 12 columns
 		for (col = 0; col < 12; col ++) {
 			if (!col)
-				val = (((0x2710L + lin * 0x18) * 0xCB78 / 0x3D090) << 0xE) * 9 / 0x1B503;
+				val = (((0x2710L + lin * 0x18) * 0xCB78 / 0x3D090) << 0xE) *
+					9 / 0x1B503;
 			_freqs[lin][col] = (short)((val + 4) >> 3);
 			val = val * 0x6A / 0x64;
-	//      val = val *  392 / 370;
 		} 
 	}
 }
@@ -810,7 +806,8 @@
 		writeOPL(0x08, 0x00);
 		writeOPL(0x40 | channel, ((strct[0] & 3) << 6) | (strct[8] & 0x3F));
 		if (!i)
-			writeOPL(0xC0 | voice  , ((strct[2] & 7) << 1) | (1 - (strct[12] & 1)));
+			writeOPL(0xC0 | voice,
+					((strct[2] & 7) << 1) | (1 - (strct[12] & 1)));
 		writeOPL(0x60 | channel, ((strct[3] & 0xF) << 4) | (strct[6] & 0xF));
 		writeOPL(0x80 | channel, ((strct[4] & 0xF) << 4) | (strct[7] & 0xF));
 		writeOPL(0x20 | channel, ((strct[9] & 1) << 7) |
@@ -971,14 +968,16 @@
 				_samplesTillPoll = 0;
 				return;
 			default:
-				warning("Unknown special command in ADL, stopping playback: %X", instr & 0x0F);
+				warning("Unknown special command in ADL, stopping playback: %X",
+						instr & 0x0F);
 				_repCount = 0;
 				_ended = true;
 				break;
 			}
 			break;
 		default:
-			warning("Unknown command in ADL, stopping playback: %X", instr & 0xF0);
+			warning("Unknown command in ADL, stopping playback: %X",
+					instr & 0xF0);
 			_repCount = 0;
 			_ended = true;
 			break;
@@ -1000,13 +999,6 @@
 	_samplesTillPoll = tempo * (_rate / 1000);
 }
 
-void Adlib::startPlay(void) {
-	if (!_data)
-		return;
-	
-	_playing = true;
-}
-
 void Adlib::playBgMusic(void) {
 	for (int i = 0; i < ARRAYSIZE(_tracks); i++)
 		if (!scumm_stricmp(_vm->_game->_curTotFile, _tracks[i][0])) {

Modified: scummvm/trunk/engines/gob/music.h
===================================================================
--- scummvm/trunk/engines/gob/music.h	2007-01-25 12:52:27 UTC (rev 25188)
+++ scummvm/trunk/engines/gob/music.h	2007-01-25 14:18:12 UTC (rev 25189)
@@ -36,15 +36,24 @@
 
 class GobEngine;
 
-// Emulation of the "Paula" Amiga music chip
-class Paula: public Audio::AudioStream {
+/**
+ * Emulation of the "Paula" Amiga music chip
+ * The interrupt frequency specifies the number of mixed wavesamples between
+ * calls of the interrupt method
+ */
+class Paula : public Audio::AudioStream {
 public:
-	Paula(GobEngine *vm, bool stereo = false, int intFreq = 0);
+	Paula(bool stereo = false, int rate = 44100, int interruptFreq = 0);
 	~Paula();
 	
 	bool playing() const { return _playing; }
 	void setInterruptFreq(int freq) { _intFreq = freq; }
-	void clearVoice(int voice);
+	void setPanning(byte voice, byte panning)
+	{
+		if (voice < 4)
+			_voice[voice].panning = panning;
+	}
+	void clearVoice(byte voice);
 	void clearVoices() { int i; for (i = 0; i < 4; i++) clearVoice(i); }
 	virtual void startPlay(void) {}
 	virtual void stopPlay(void) {}
@@ -65,7 +74,7 @@
 		int16 period;
 		byte volume;
 		double offset;
-		byte panning; // For stereo mixing; 0: left, 1: right
+		byte panning; // For stereo mixing: 0 = far left, 255 = far right
 	} _voice[4];
 
 	int _rate;
@@ -74,23 +83,46 @@
 	bool _stereo;
 	bool _end;
 	bool _playing;
+	Common::Mutex _mutex;
 
-	GobEngine *_vm;
-
 	void mix(int16 *&buf, int8 data, int voice) {
 		if (_stereo) {
-			*buf++ += _voice[voice].panning == 0 ? 2 * _voice[voice].volume * data : 0;
-			*buf++ += _voice[voice].panning == 1 ? 2 * _voice[voice].volume * data : 0;
+			*buf++ += (((int32) data) * _voice[voice].volume *
+				 (255 - _voice[voice].panning)) >> 7;
+			*buf++ += (((int32) data) * _voice[voice].volume *
+				 (_voice[voice].panning)) >> 7;
 		} else
 			*buf++ += _voice[voice].volume * data;
 	}
 	virtual void interrupt(void) {};
 };
 
+/** A player for the Infogrames/RobHubbard2 format */
 class Infogrames : public Paula {
 public:
 	class Instruments {
 	public:
+		Instruments();
+		template<typename T> Instruments(T ins) {
+			init();
+			bool result = load(ins);
+			assert(result);
+		}
+		~Instruments();
+
+		bool load(Common::SeekableReadStream &ins);
+		bool load(const char *ins) {
+			Common::File f;
+
+			if (f.open(ins))
+				return load(f);
+			return false;
+		}
+		void unload(void);
+
+		uint8 getCount(void) const { return _count; }
+
+	protected:
 		struct Sample {
 			int8 *data;
 			int8 *dataRepeat;
@@ -101,28 +133,24 @@
 		uint8 _count;
 		int8 *_sampleData;
 
-		Instruments();
-		~Instruments();
+		void init();
 
-		bool load(Common::SeekableReadStream &ins);
-		bool load(const char *ins) {
-			Common::File f;
-
-			if (f.open(ins))
-				return load(f);
-			return false;
-		}
+		friend class Infogrames;
 	};
 
-	Infogrames(GobEngine *vm, bool stereo = false);
+	Infogrames(Instruments &ins, bool stereo = false, int rate = 44100);
 	~Infogrames();
 
 	Instruments *getInstruments(void) const { return _instruments; }
 	bool getRepeating(void) const { return _repCount != 0; }
 	void setRepeating (int32 repCount) { _repCount = repCount; }
-	void restart(void) { if (!_data || !_instruments) return; init(); _end = false; }
-	virtual void startPlay(void) { if (_data && _instruments) { restart(); _playing = true; } }
-	virtual void stopPlay(void) { _playing = false; }
+	virtual void startPlay(void) { _playing = true;}
+	virtual void stopPlay(void)
+	{
+		_mutex.lock();
+		_playing = false;
+		_mutex.unlock();
+	}
 	virtual void pausePlay(bool pause) { _playing = !pause; }
 
 	bool load(Common::SeekableReadStream &dum);
@@ -133,17 +161,8 @@
 			return load(f);
 		return false;
 	}
-	void unload(bool destroyInstruments = false);
-	template<typename T> bool loadInstruments(T ins) {
-		unload(true);
-		_instruments = new Instruments();
-		if (!_instruments->load(ins)) {
-			delete _instruments;
-			_instruments = 0;
-			return false;
-		}
-		return true;
-	}
+	void unload(void);
+	void restart(void) { if (_data) { stopPlay(); init(); startPlay(); } }
 
 protected:
 	Instruments *_instruments;
@@ -153,44 +172,38 @@
 	byte *_data;
 	int32 _repCount;
 
-	uint16 _volume;
-	int16 _period;
+	byte *_subSong;
+	byte *_cmdBlocks;
 	byte *_volSlideBlocks;
 	byte *_periodSlideBlocks;
-	byte *_subSong;
-	byte *_cmdBlocks;
-	uint8 _sample;
 	uint8 _speedCounter;
 	uint8 _speed;
-	uint8 _newVol;
-	uint8 _field_1E;
 
+	uint16 _volume;
+	int16 _period;
+	uint8 _sample;
+
 	struct Slide {
-		int16 finetuneNeg;
-		int16 finetunePos;
 		byte *data;
 		int8 amount;
 		uint8 dataOffset;
-		uint8 flags; // 0: Apply finetune modifier, 2: Don't slide, 7: Continuous
+		int16 finetuneNeg;
+		int16 finetunePos;
 		uint8 curDelay1;
 		uint8 curDelay2;
+		uint8 flags; // 0: Apply finetune modifier, 2: Don't slide, 7: Continuous
 	};
 	struct Channel {
 		byte *cmdBlockIndices;
+		byte *cmdBlocks;
 		byte *cmds;
-		byte *cmdBlocks;
+		uint8 ticks;
+		uint8 tickCount;
 		Slide volSlide;
 		Slide periodSlide;
-		int16 curPeriod;
 		int16 period;
-		uint16 curCmdBlock;
-		uint16 flags; // 0: Need init, 5: Loop cmdBlocks, 6: Ignore channel
-		uint8 ticks;
-		uint8 tickCount;
 		int8 periodMod;
-		uint8 field_2B;
-		uint8 field_2C;
-		uint8 field_2F;
+		uint8 flags; // 0: Need init, 5: Loop cmdBlocks, 6: Ignore channel
 	} _chn[4];
 
 	void init(void);
@@ -211,8 +224,13 @@
 	bool getRepeating(void) const { return _repCount != 0; }
 	void setRepeating (int32 repCount) { _repCount = repCount; }
 	int getIndex(void) const { return _index; }
-	virtual void startPlay(void);
-	virtual void stopPlay(void) { _mutex.lock(); _playing = false; _mutex.unlock(); }
+	virtual void startPlay(void) { if (_data) _playing = true; }
+	virtual void stopPlay(void)
+	{
+		_mutex.lock();
+		_playing = false;
+		_mutex.unlock();
+	}
 	virtual void playTrack(const char *trackname);
 	virtual void playBgMusic(void);
 	virtual bool load(const char *filename);
@@ -265,6 +283,9 @@
 	void pollMusic(void);
 };
 
+/**
+ * A dummy class for the "null" sound driver
+ */
 class Adlib_Dummy: public Adlib {
 public:
 	Adlib_Dummy(GobEngine *vm) : Adlib(vm) {}

Modified: scummvm/trunk/engines/gob/sound.cpp
===================================================================
--- scummvm/trunk/engines/gob/sound.cpp	2007-01-25 12:52:27 UTC (rev 25188)
+++ scummvm/trunk/engines/gob/sound.cpp	2007-01-25 14:18:12 UTC (rev 25189)
@@ -95,18 +95,14 @@
 }
 
 void Snd::playSample(Snd::SoundDesc *sndDesc, int16 repCount, int16 frequency) {
-	if (frequency == 0)
+	if (frequency <= 0)
 		frequency = sndDesc->frequency;
 
-	if (frequency <= 0) {
-		warning("Attempted to play a sample with a frequency of %d (sndDesc->freq = %d)", frequency, sndDesc->frequency);
-		return;
-	}
-//	assert(frequency > 0);
+	for (int i = 0; i < ARRAYSIZE(_loopingSounds); i++)
+		_loopingSounds[i] = 0;
+	_vm->_mixer->stopHandle(sndDesc->handle);
 
-	if (!_vm->_mixer->isSoundHandleActive(sndDesc->handle)) {
-		_vm->_mixer->playRaw(&sndDesc->handle, sndDesc->data, sndDesc->size, frequency, 0);
-	}
+	_vm->_mixer->playRaw(&sndDesc->handle, sndDesc->data, sndDesc->size, frequency, 0);
 
 	sndDesc->repCount = repCount - 1;
 	sndDesc->frequency = frequency;


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list