diff options
| -rw-r--r-- | engines/neverhood/entity.h | 1 | ||||
| -rw-r--r-- | engines/neverhood/gamemodule.cpp | 6 | ||||
| -rw-r--r-- | engines/neverhood/klayman.cpp | 20 | ||||
| -rw-r--r-- | engines/neverhood/klayman.h | 2 | ||||
| -rw-r--r-- | engines/neverhood/module1000.cpp | 20 | ||||
| -rw-r--r-- | engines/neverhood/module1100.cpp | 45 | ||||
| -rw-r--r-- | engines/neverhood/module1200.cpp | 27 | ||||
| -rw-r--r-- | engines/neverhood/module1300.cpp | 42 | ||||
| -rw-r--r-- | engines/neverhood/module1400.cpp | 40 | ||||
| -rw-r--r-- | engines/neverhood/navigationscene.h | 2 | ||||
| -rw-r--r-- | engines/neverhood/neverhood.cpp | 4 | ||||
| -rw-r--r-- | engines/neverhood/neverhood.h | 2 | ||||
| -rw-r--r-- | engines/neverhood/resource.cpp | 44 | ||||
| -rw-r--r-- | engines/neverhood/resource.h | 16 | ||||
| -rw-r--r-- | engines/neverhood/resourceman.cpp | 2 | ||||
| -rw-r--r-- | engines/neverhood/scene.cpp | 16 | ||||
| -rw-r--r-- | engines/neverhood/sound.cpp | 463 | ||||
| -rw-r--r-- | engines/neverhood/sound.h | 120 | 
18 files changed, 673 insertions, 199 deletions
diff --git a/engines/neverhood/entity.h b/engines/neverhood/entity.h index 9256c13ba8..22eb780024 100644 --- a/engines/neverhood/entity.h +++ b/engines/neverhood/entity.h @@ -27,6 +27,7 @@  #include "neverhood/neverhood.h"  #include "neverhood/gamevars.h"  #include "neverhood/graphics.h" +#include "neverhood/sound.h"  namespace Neverhood { diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp index e2494af453..7841e278c3 100644 --- a/engines/neverhood/gamemodule.cpp +++ b/engines/neverhood/gamemodule.cpp @@ -298,9 +298,9 @@ uint32 GameModule::handleMessage(int messageNum, const MessageParam ¶m, Enti  void GameModule::startup() {  	// TODO: Displaying of error text probably not needed in ScummVM  //	createModule(1500, 0); // Logos and intro video //Real -#if 0 +#if 1  	_vm->gameState().sceneNum = 0; -	createModule(1200, -1); +	createModule(1400, -1);  #endif  #if 0  	_vm->gameState().sceneNum = 0; @@ -339,7 +339,7 @@ void GameModule::startup() {  	_vm->gameState().sceneNum = 8;  	createModule(2600, -1);  #endif -#if 1 +#if 0  	_vm->gameState().which = 0;  	_vm->gameState().sceneNum = 1;  	createModule(2700, -1); diff --git a/engines/neverhood/klayman.cpp b/engines/neverhood/klayman.cpp index ca30e3bccb..00008830e7 100644 --- a/engines/neverhood/klayman.cpp +++ b/engines/neverhood/klayman.cpp @@ -60,7 +60,7 @@ static const KlaymanIdleTableItem klaymanTable4[] = {  Klayman::Klayman(NeverhoodEngine *vm, Entity *parentScene, int16 x, int16 y, int surfacePriority, int objectPriority, NRectArray *clipRects)  	: AnimatedSprite(vm, objectPriority), _soundResource1(vm), _soundResource2(vm),  	_counterMax(0), _counter(0), _isMoveObjectRequested(false), _counter3Max(0), _isWalkingOpenDoorNotified(false), _counter1(0), -	_counter2(0), /*_field118(0), */_status2(0), _acceptInput(true), _attachedSprite(NULL), _isWalking(false), +	_tapesToInsert(0), /*_field118(0), */_status2(0), _acceptInput(true), _attachedSprite(NULL), _isWalking(false),  	_status3(1), _parentScene(parentScene), _isSneaking(false), _isLargeStep(false), _flagF6(false), _isLeverDown(false),  	_flagFA(false), _ladderStatus(0), _pathPoints(NULL), _resourceHandle(-1), _soundFlag(false) { @@ -2119,16 +2119,16 @@ void Klayman::cbLeverReleasedEvent() {  void Klayman::stInsertDisk() {  	if (!stStartActionFromIdle(AnimationCallback(&Klayman::stInsertDisk))) {  		_status2 = 2; -		_counter2 = 0; +		_tapesToInsert = 0;  		for (uint32 i = 0; i < 20; i++) {  			if (getSubVar(0x02038314, i)) {  				setSubVar(0x02720344, i, 1);  				setSubVar(0x02038314, i, 0); -				_counter2++; +				_tapesToInsert++;  			}  		} -		if (_counter2 == 0) { -			gotoState(NULL); +		if (_tapesToInsert == 0) { +			GotoState(NULL);  			gotoNextStateExt();  		} else {  			startAnimation(0xD8C8D100, 0, -1); @@ -2136,7 +2136,7 @@ void Klayman::stInsertDisk() {  			SetSpriteUpdate(&Klayman::spriteUpdate41F250);  			SetMessageHandler(&Klayman::hmInsertDisk);  			_acceptInput = false; -			_counter2--; +			_tapesToInsert--;  		}  	}  } @@ -2145,12 +2145,12 @@ uint32 Klayman::hmInsertDisk(int messageNum, const MessageParam ¶m, Entity *  	switch (messageNum) {  	case 0x100D:  		if (param.asInteger() == 0x06040580) { -			if (_counter2 == 0) { -				// TODO: Calc calcHash value somewhere else  +			if (_tapesToInsert == 0) { +				// TODO: Calc calcHash value somewhere else  				nextAnimationByHash(0xD8C8D100, calcHash("GoToStartLoop/Finish"), 0);  			} -		} else if (_counter2 != 0 && param.asInteger() == calcHash("GoToStartLoop/Finish")) { -			_counter2--; +		} else if (_tapesToInsert != 0 && param.asInteger() == calcHash("GoToStartLoop/Finish")) { +			_tapesToInsert--;  			startAnimationByHash(0xD8C8D100, 0x01084280, 0);  		} else if (param.asInteger() == 0x062A1510) {  			_soundResource1.play(0x41688704); diff --git a/engines/neverhood/klayman.h b/engines/neverhood/klayman.h index b752b1ecdb..cbf17a01f8 100644 --- a/engines/neverhood/klayman.h +++ b/engines/neverhood/klayman.h @@ -185,7 +185,7 @@ protected:  	int16 _counter, _counterMax;  	int16 _counter3, _counter3Max;  	int16 _counter1; -	int16 _counter2; +	int16 _tapesToInsert;  	bool _flagF6;  	bool _isLeverDown;  	bool _isWalkingOpenDoorNotified; diff --git a/engines/neverhood/module1000.cpp b/engines/neverhood/module1000.cpp index 1c30681401..2db598bb3e 100644 --- a/engines/neverhood/module1000.cpp +++ b/engines/neverhood/module1000.cpp @@ -31,8 +31,8 @@ Module1000::Module1000(NeverhoodEngine *vm, Module *parentModule, int which)  	_musicFileHash = getGlobalVar(0xD0A14D10) ? 0x81106480 : 0x00103144;		 -	// TODO SoundMan_addMusic(0x03294419, 0x061880C6); -	// TODO SoundMan_addMusic(0x03294419, _musicFileHash); +	_vm->_soundMan->addMusic(0x03294419, 0x061880C6); +	_vm->_soundMan->addMusic(0x03294419, _musicFileHash);  	if (which < 0) {  		createScene(_vm->gameState().sceneNum, -1); @@ -45,7 +45,7 @@ Module1000::Module1000(NeverhoodEngine *vm, Module *parentModule, int which)  }  Module1000::~Module1000() { -	// TODO SoundMan_deleteMusicGroup(0x03294419); +	_vm->_soundMan->deleteMusicGroup(0x03294419);  }  void Module1000::createScene(int sceneNum, int which) { @@ -53,24 +53,24 @@ void Module1000::createScene(int sceneNum, int which) {  	_vm->gameState().sceneNum = sceneNum;  	switch (_vm->gameState().sceneNum) {  	case 0: -		// TODO SoundMan_startMusic(0x061880C6, 0, 0, 1); +		_vm->_soundMan->startMusic(0x061880C6, 0, 0);  		_childObject = new Scene1001(_vm, this, which);  		break;  	case 1: -		// TODO SoundMan_startMusic(0x061880C6, 0, 0, 1); +		_vm->_soundMan->startMusic(0x061880C6, 0, 0);  		_childObject = new Scene1002(_vm, this, which);  		break;  	case 2: -		// TODO SoundMan_startMusic(0x061880C6, 0, 0); +		_vm->_soundMan->startMusic(0x061880C6, 0, 0);  		_childObject = new Class152(_vm, this, 0xC084110C, 0x41108C00);  		break;  	case 3: -		// TODO SoundMan_stopMusic(0x061880C6, 0, 2); +		_vm->_soundMan->stopMusic(0x061880C6, 0, 2);  		_childObject = new Scene1004(_vm, this, which);  		break;  	case 4: -		// TODO SoundMan_stopMusic(0x061880C6, 0, 0); -		// TODO SoundMan_startMusic(_musicFileHash, 0, 0, 1); +		_vm->_soundMan->stopMusic(0x061880C6, 0, 0); +		_vm->_soundMan->startMusic(_musicFileHash, 0, 0);  		_childObject = new Scene1005(_vm, this, which);  		break;  	} @@ -105,7 +105,7 @@ void Module1000::updateScene() {  				createScene(1, 2);  			break;  		case 4: -			// TODO SoundMan_stopMusic(_musicFileHash, 0, 1); +			_vm->_soundMan->stopMusic(_musicFileHash, 0, 1);  			createScene(3, 1);  			break;  		} diff --git a/engines/neverhood/module1100.cpp b/engines/neverhood/module1100.cpp index 8b73598e03..e948c2b045 100644 --- a/engines/neverhood/module1100.cpp +++ b/engines/neverhood/module1100.cpp @@ -22,6 +22,7 @@  #include "neverhood/module1100.h"  #include "neverhood/gamemodule.h" +#include "neverhood/navigationscene.h"  namespace Neverhood { @@ -36,16 +37,16 @@ Module1100::Module1100(NeverhoodEngine *vm, Module *parentModule, int which)  		createScene(9, 3);  	} -	// TODO SoundMan_addSoundList(0x2C818, dword_4B85B0, true); +	// TODO SoundMan_addSoundList(0x0002C818, dword_4B85B0, true);  	// TODO SoundMan_setSoundListParams(dword_4B85B0, true, 50, 600, 20, 250); -	// TODO SoundMan_setSoundParams(0x74E01054, false, 100, 200, 10, 20); -	// TODO SoundMan_setSoundVolume(0x74E01054, 60); -	// TODO SoundMan_playTwoSounds(0x2C818, 0x41861371, 0x43A2507F); +	_vm->_soundMan->setSoundParams(0x74E01054, false, 100, 200, 10, 20); +	_vm->_soundMan->setSoundVolume(0x74E01054, 60); +	_vm->_soundMan->playTwoSounds(0x0002C818, 0x41861371, 0x43A2507F, 0);  }  Module1100::~Module1100() { -	// TODO SoundMan_deleteGroup(0x2C818); +	_vm->_soundMan->deleteGroup(0x0002C818);  }  void Module1100::createScene(int sceneNum, int which) { @@ -86,11 +87,11 @@ void Module1100::createScene(int sceneNum, int which) {  			createSmackerScene(0x04180007, true, false, false);  		break;  	case 6: -		// TODO SoundMan_deleteSoundGroup(0x2C818); +		_vm->_soundMan->deleteSoundGroup(0x0002C818);  		createSmackerScene(kSmackerFileHashList06, true, true, false);  		break;  	case 7: -		// TODO SoundMan_setSoundParams(0x74E01054, false, 0, 0, 0, 0); +		_vm->_soundMan->setSoundParams(0x74E01054, false, 0, 0, 0, 0);  		createSmackerScene(kSmackerFileHashList07, true, true, false);  		break;  	case 8: @@ -98,7 +99,7 @@ void Module1100::createScene(int sceneNum, int which) {  		break;  	case 1002:  		_countdown = 40; -		// TODO SoundMan_setTwoSoundsPlayFlag(true); +		_vm->_soundMan->setTwoSoundsPlayFlag(true);  		createSmackerScene(0x00012211, true, true, false);  		break;  	} @@ -111,9 +112,9 @@ void Module1100::updateScene() {  		switch (_vm->gameState().sceneNum) {  		case 0:  			_countdown = 0; -			// TODO SoundMan_playTwoSounds(0x2C818, 0x48498E46, 0x50399F64); -			// TODO SoundMan_setSoundVolume(0x48498E46, 65); -			// TODO SoundMan_setSoundVolume(0x50399F64, 65); +			_vm->_soundMan->playTwoSounds(0x0002C818, 0x48498E46, 0x50399F64, 0); +			_vm->_soundMan->setSoundVolume(0x48498E46, 65); +			_vm->_soundMan->setSoundVolume(0x50399F64, 65);  			if (_moduleResult == 0) {  				createScene(1, 0);  			} else if (_moduleResult == 1) { @@ -121,7 +122,7 @@ void Module1100::updateScene() {  			}  			break;  		case 1: -			// TODO SoundMan_playTwoSounds(0x2C818, 0x41861371, 0x43A2507F); +			_vm->_soundMan->playTwoSounds(0x0002C818, 0x41861371, 0x43A2507F, 0);  			if (getGlobalVar(0x0C0288F4)) {  				if (_moduleResult == 0) {  					createScene(6, -1); @@ -137,7 +138,7 @@ void Module1100::updateScene() {  			}  			break;  		case 2: -			// TODO SoundMan_setSoundParams(0x74E01054, false, 0, 0, 0, 0); +			_vm->_soundMan->setSoundParams(0x74E01054, false, 0, 0, 0, 0);  			if (_navigationAreaType == 3) {  				createScene(7, -1);  			} else if (_moduleResult == 1) { @@ -161,6 +162,7 @@ void Module1100::updateScene() {  			}  			break;  		case 5: +			_vm->_soundMan->setTwoSoundsPlayFlag(false);  			if (getGlobalVar(0x610210B7)) {  				createScene(3, 0);  			} else { @@ -168,9 +170,11 @@ void Module1100::updateScene() {  			}  			break;  		case 6: +			_vm->_soundMan->setTwoSoundsPlayFlag(false);  			leaveModule(1);  			break;  		case 7: +			_vm->_soundMan->setTwoSoundsPlayFlag(false);  			createScene(2, 2);  			break;  		case 8: @@ -181,8 +185,9 @@ void Module1100::updateScene() {  			}  			break;  		case 1002: +			_vm->_soundMan->setTwoSoundsPlayFlag(false);  			_countdown = 0; -			// TODO SoundMan_playTwoSounds(0x2C818, 0x48498E46, 0x50399F64, 0); +			_vm->_soundMan->playTwoSounds(0x0002C818, 0x48498E46, 0x50399F64, 0);  			createScene(1, 1);  			break;  		} @@ -191,7 +196,7 @@ void Module1100::updateScene() {  		case 0:  #if 0 // TODO		  			if (navigationScene()->soundFlag1 && _countdown != 0 && (--_countdown == 0)) { -				SoundMan_playTwoSounds(0x2C818, 0x48498E46, 0x50399F64); +				SoundMan_playTwoSounds(0x0002C818, 0x48498E46, 0x50399F64);  				SoundMan_setSoundVolume(0x48498E46, 65);  				SoundMan_setSoundVolume(0x50399F64, 65);  			} @@ -200,21 +205,21 @@ void Module1100::updateScene() {  		case 1:  #if 0 // TODO		  			if (navigationScene()->soundFlag1 && _countdown != 0 && (--_countdown == 0)) { -				SoundMan_playTwoSounds(0x2C818, 0x41861371, 0x43A2507F); +				SoundMan_playTwoSounds(0x0002C818, 0x41861371, 0x43A2507F);  			}  #endif			  			break;  		case 2: -			// TODO SoundMan_setSoundParams(0x74E01054, !navigationScene()->soundFlag1, 0, 0, 0, 0); +			_vm->_soundMan->setSoundParams(0x74E01054, !navigationScene()->getSoundFlag1(), 0, 0, 0, 0);  			break;  		case 5:  		case 6:  		case 7:  		case 1002:  			if (_countdown != 0 && (--_countdown == 0)) { -				// TODO SoundMan_playTwoSounds(0x2C818, 0x48498E46, 0x50399F64); -				// TODO SoundMan_setSoundVolume(0x48498E46, 65); -				// TODO SoundMan_setSoundVolume(0x50399F64, 65); +				_vm->_soundMan->playTwoSounds(0x0002C818, 0x48498E46, 0x50399F64, 0); +				_vm->_soundMan->setSoundVolume(0x48498E46, 65); +				_vm->_soundMan->setSoundVolume(0x50399F64, 65);  			}  			break;  		} diff --git a/engines/neverhood/module1200.cpp b/engines/neverhood/module1200.cpp index 7599d7655d..33b791aa9b 100644 --- a/engines/neverhood/module1200.cpp +++ b/engines/neverhood/module1200.cpp @@ -39,12 +39,12 @@ Module1200::Module1200(NeverhoodEngine *vm, Module *parentModule, int which)  		createScene(0, 0);  	} -	// TODO SoundMan_addMusic(0x00478311, 0x62222CAE); -	// TODO SoundMan_startMusic(0x62222CAE, 0, 0, 1); +	_vm->_soundMan->addMusic(0x00478311, 0x62222CAE); +	_vm->_soundMan->startMusic(0x62222CAE, 0, 0);  }  Module1200::~Module1200() { -	// TODO SoundMan_deleteMusicGroup(0x00478311); +	_vm->_soundMan->deleteMusicGroup(0x00478311);  }  void Module1200::createScene(int sceneNum, int which) { @@ -58,7 +58,7 @@ void Module1200::createScene(int sceneNum, int which) {  		_childObject = new Scene1202(_vm, this, which);  		break;  	case 2: -		// TODO SoundMan_stopMusic(0x62222CAE, 0, 0); +		_vm->_soundMan->stopMusic(0x62222CAE, 0, 0);  		createSmackerScene(0x31890001, true, true, false);  		setGlobalVar(0x2A02C07B, 1);  		break; @@ -87,7 +87,7 @@ void Module1200::updateScene() {  			createScene(0, 1);  			break;  		case 2: -			// TODO SoundMan_startMusic(0x62222CAE, 0, 0, 1); +			_vm->_soundMan->startMusic(0x62222CAE, 0, 0);  			createScene(0, 3);  			break;  		} @@ -371,7 +371,7 @@ AsScene1201TntMan::AsScene1201TntMan(NeverhoodEngine *vm, Scene *parentScene, Sp  }  AsScene1201TntMan::~AsScene1201TntMan() { -	// TODO SoundMan_deleteSoundGroup(0x01D00560); +	_vm->_soundMan->deleteSoundGroup(0x01D00560);  }	   uint32 AsScene1201TntMan::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -426,8 +426,8 @@ void AsScene1201TntMan::sub40CD60() {  }  void AsScene1201TntMan::sub40CD90() { -	// TODO SoundMan_addSound(0x01D00560, 0x4B044624, true); -	// TODO SoundMan_playSoundLooping(0x4B044624); +	_vm->_soundMan->addSound(0x01D00560, 0x4B044624); +	_vm->_soundMan->playSoundLooping(0x4B044624);  	_flag = true;  	startAnimation(0x85084190, 0, -1);  	SetMessageHandler(&AsScene1201TntMan::handleMessage); @@ -447,7 +447,7 @@ Class465::Class465(NeverhoodEngine *vm, Sprite *asTntMan)  }  Class465::~Class465() { -	// TODO SoundMan_deleteSoundGroup(0x041080A4); +	_vm->_soundMan->deleteSoundGroup(0x041080A4);  }  void Class465::update() { @@ -455,8 +455,8 @@ void Class465::update() {  	if (getGlobalVar(0x20A0C516)) {  		setVisible(true);  		SetUpdateHandler(&AnimatedSprite::update); -		// TODO SoundMan_addSound(0x041080A4, 0x460A1050, true); -		// TODO SoundMan_playSoundLooping(0x460A1050); +		_vm->_soundMan->addSound(0x041080A4, 0x460A1050); +		_vm->_soundMan->playSoundLooping(0x460A1050);  	}  } @@ -1227,10 +1227,7 @@ bool Scene1202::isSolved() {  }  void Scene1202::doPaletteEffect() { -#if 0 // TODO -	Palette2 *palette2 = (Palette2*)_palette; -	palette2->startFadeToPalette(24); -#endif +	// TODO  }  } // End of namespace Neverhood diff --git a/engines/neverhood/module1300.cpp b/engines/neverhood/module1300.cpp index b7c588f114..ee4dc7a42c 100644 --- a/engines/neverhood/module1300.cpp +++ b/engines/neverhood/module1300.cpp @@ -35,12 +35,12 @@ namespace Neverhood {  Module1300::Module1300(NeverhoodEngine *vm, Module *parentModule, int which)  	: Module(vm, parentModule) { -	// TODO SoundMan_addMusic(0x61C090, 0x203197); +	_vm->_soundMan->addMusic(0x61C090, 0x203197);  	// TODO SoundMan_addSoundList(0x61C090, dword_4B2868, true);  	// TODO SoundMan_setSoundListParams(dword_4B2868, false, 50, 600, 20, 150); -	// TODO SoundMan_playTwoSounds(0x61C090, 0x48498E46, 0x50399F64, 0); -	// TODO SoundMan_setSoundVolume(0x48498E46, 70); -	// TODO SoundMan_setSoundVolume(0x50399F64, 70); +	_vm->_soundMan->playTwoSounds(0x61C090, 0x48498E46, 0x50399F64, 0); +	_vm->_soundMan->setSoundVolume(0x48498E46, 70); +	_vm->_soundMan->setSoundVolume(0x50399F64, 70);  	if (which < 0) {  		if (_vm->gameState().sceneNum >= 1 && _vm->gameState().sceneNum <= 17) @@ -94,7 +94,7 @@ Module1300::Module1300(NeverhoodEngine *vm, Module *parentModule, int which)  }  Module1300::~Module1300() { -	// TODO SoundMan_deleteGroup(0x61C090); +	_vm->_soundMan->deleteGroup(0x61C090);  }  void Module1300::createScene(int sceneNum, int which) { @@ -103,82 +103,82 @@ void Module1300::createScene(int sceneNum, int which) {  	switch (_vm->gameState().sceneNum) {  	case 1:  		// TODO SoundMan_setSoundListParams(dword_4B2868, false, 0, 0, 0, 0); -		// TODO SoundMan_startMusic(0x203197, 0, 2, 1); +		_vm->_soundMan->startMusic(0x203197, 0, 2);  		_childObject = new Scene1302(_vm, this, which);  		break;  	case 2:  		// TODO SoundMan_setSoundListParams(dword_4B2868, false, 0, 0, 0, 0); -		// TODO SoundMan_stopMusic(0x203197, 0, 2); +		_vm->_soundMan->stopMusic(0x203197, 0, 2);  		_childObject = new Scene1303(_vm, this, which);  		break;  	case 3:  		// TODO SoundMan_setSoundListParams(dword_4B2868, false, 0, 0, 0, 0); -		// TODO SoundMan_stopMusic(0x203197, 0, 2); +		_vm->_soundMan->stopMusic(0x203197, 0, 2);  		_childObject = new Scene1304(_vm, this, which);  		break;  	case 4:  		// TODO SoundMan_setSoundListParams(dword_4B2868, false, 0, 0, 0, 0); -		// TODO SoundMan_startMusic(0x203197, 0, 2, 1); +		_vm->_soundMan->startMusic(0x203197, 0, 2);  		_childObject = new Scene1305(_vm, this, which);  		break;  	case 5:  		// TODO SoundMan_setSoundListParams(dword_4B2868, false, 0, 0, 0, 0); -		// TODO SoundMan_startMusic(0x203197, 0, 2, 1); +		_vm->_soundMan->startMusic(0x203197, 0, 2);  		_childObject = new Scene1306(_vm, this, which);  		break;  	case 6:  		// TODO SoundMan_setSoundListParams(dword_4B2868, false, 0, 0, 0, 0); -		// TODO SoundMan_startMusic(0x203197, 0, 2, 1); +		_vm->_soundMan->startMusic(0x203197, 0, 2);  		_childObject = new Scene1307(_vm, this, which);  		break;  	case 7:  		// TODO SoundMan_setSoundListParams(dword_4B2868, false, 0, 0, 0, 0); -		// TODO SoundMan_startMusic(0x203197, 0, 2, 1); +		_vm->_soundMan->startMusic(0x203197, 0, 2);  		_childObject = new Scene1308(_vm, this, which);  		break;  	case 8:  		// TODO SoundMan_setSoundListParams(dword_4B2868, false, 0, 0, 0, 0); -		// TODO SoundMan_stopMusic(0x203197, 0, 2); +		_vm->_soundMan->stopMusic(0x203197, 0, 2);  		_childObject = new DiskplayerScene(_vm, this, 1);  		break;  	case 9:  		// TODO SoundMan_setSoundListParams(dword_4B2868, false, 0, 0, 0, 0); -		// TODO SoundMan_stopMusic(0x203197, 0, 2); +		_vm->_soundMan->stopMusic(0x203197, 0, 2);  		createSmackerScene(0x20082818, true, true, false);  		break;  	case 10:  		// TODO SoundMan_setSoundListParams(dword_4B2868, false, 0, 0, 0, 0); -		// TODO SoundMan_stopMusic(0x203197, 0, 2); +		_vm->_soundMan->stopMusic(0x203197, 0, 2);  		createSmackerScene(0x20082828, true, true, false);  		break;  	case 11:  		// TODO SoundMan_setSoundListParams(0xdword_4B2868, true, 0, 0, 0, 0); -		// TODO SoundMan_stopMusic(0x203197, 0, 2); +		_vm->_soundMan->stopMusic(0x203197, 0, 2);  		createNavigationScene(0x004B27A8, which);  		break;  	case 12:  		// TODO SoundMan_setSoundListParams(0xdword_4B2868, true, 0, 0, 0, 0); -		// TODO SoundMan_stopMusic(0x203197, 0, 2); +		_vm->_soundMan->stopMusic(0x203197, 0, 2);  		createNavigationScene(0x004B2718, which);  		break;  	case 13:  		// TODO SoundMan_setSoundListParams(0xdword_4B2868, true, 0, 0, 0, 0); -		// TODO SoundMan_stopMusic(0x203197, 0, 2); +		_vm->_soundMan->stopMusic(0x203197, 0, 2);  		createNavigationScene(0x004B27D8, which);  		break;  	case 14:  		// TODO SoundMan_setSoundListParams(0xdword_4B2868, true, 0, 0, 0, 0); -		// TODO SoundMan_stopMusic(0x203197, 0, 2); +		_vm->_soundMan->stopMusic(0x203197, 0, 2);  		createNavigationScene(0x004B2808, which);  		break;  	case 15:  		// TODO SoundMan_setSoundListParams(0xdword_4B2868, true, 0, 0, 0, 0); -		// TODO SoundMan_stopMusic(0x203197, 0, 2); +		_vm->_soundMan->stopMusic(0x203197, 0, 2);  		createNavigationScene(0x004B2838, which);  		break;  	case 16:  		// TODO SoundMan_setSoundListParams(dword_4B2868, false, 0, 0, 0, 0); -		// TODO SoundMan_stopMusic(0x203197, 0, 2); +		_vm->_soundMan->stopMusic(0x203197, 0, 2);  		_childObject = new Scene1317(_vm, this, which);  		break;  	case 17: diff --git a/engines/neverhood/module1400.cpp b/engines/neverhood/module1400.cpp index 370735695d..8d40c340ec 100644 --- a/engines/neverhood/module1400.cpp +++ b/engines/neverhood/module1400.cpp @@ -32,8 +32,8 @@ namespace Neverhood {  Module1400::Module1400(NeverhoodEngine *vm, Module *parentModule, int which)  	: Module(vm, parentModule) { -	// TODO SoundMan_addMusic(0x00AD0012, 0x06333232); -	// TODO SoundMan_addMusic(0x00AD0012, 0x624A220E); +	_vm->_soundMan->addMusic(0x00AD0012, 0x06333232); +	_vm->_soundMan->addMusic(0x00AD0012, 0x624A220E);  	if (which < 0) {  		createScene(_vm->gameState().sceneNum, -1); @@ -44,7 +44,7 @@ Module1400::Module1400(NeverhoodEngine *vm, Module *parentModule, int which)  }  Module1400::~Module1400() { -	// TODO SoundMan_deleteMusicGroup(0x00AD0012); +	_vm->_soundMan->deleteMusicGroup(0x00AD0012);  }  void Module1400::createScene(int sceneNum, int which) { @@ -52,33 +52,33 @@ void Module1400::createScene(int sceneNum, int which) {  	_vm->gameState().sceneNum = sceneNum;  	switch (_vm->gameState().sceneNum) {  	case 0: -		// TODO SoundMan_startMusic(0x06333232, 0, 2, 1); +		_vm->_soundMan->startMusic(0x06333232, 0, 2);  		_childObject = new Scene1401(_vm, this, which);  		break;  	case 1: -		// TODO SoundMan_stopMusic(0x06333232, 0, 2); -		// TODO SoundMan_stopMusic(0x624A220E, 0, 2); +		_vm->_soundMan->stopMusic(0x06333232, 0, 2); +		_vm->_soundMan->stopMusic(0x624A220E, 0, 2);  		_childObject = new Scene1402(_vm, this, which);  		break;  	case 2: -		// TODO SoundMan_stopMusic(0x06333232, 0, 2); -		// TODO SoundMan_startMusic(0x624A220E, 0, 2, 1); +		_vm->_soundMan->stopMusic(0x06333232, 0, 2); +		_vm->_soundMan->startMusic(0x624A220E, 0, 2);  		_childObject = new Scene1403(_vm, this, which);  		break;  	case 3: -		// TODO SoundMan_startMusic(0x06333232, 0, 2, 1); +		_vm->_soundMan->startMusic(0x06333232, 0, 2);  		_childObject = new Scene1404(_vm, this, which);  		break;  	case 4: -		// TODO SoundMan_startMusic(0x06333232, 0, 2, 1); +		_vm->_soundMan->startMusic(0x06333232, 0, 2);  		_childObject = new Scene1405(_vm, this, which);  		break;  	case 5: -		// TODO SoundMan_stopMusic(0x06333232, 0, 2); +		_vm->_soundMan->stopMusic(0x06333232, 0, 2);  		_childObject = new DiskplayerScene(_vm, this, 2);  		break;  	case 6: -		// TODO SoundMan_stopMusic(0x06333232, 0, 2); +		_vm->_soundMan->stopMusic(0x06333232, 0, 2);  		_childObject = new Scene1407(_vm, this, which);  		break;  	} @@ -148,7 +148,7 @@ Class525::Class525(NeverhoodEngine *vm)  }  Class525::~Class525() { -	// TODO SoundMan_deleteSoundGroup(0x01104C08); +	_vm->_soundMan->deleteSoundGroup(0x01104C08);  }  void Class525::update4662A0() { @@ -157,8 +157,8 @@ void Class525::update4662A0() {  		sub466460();  	}  	if (_countdown2 != 0 && (--_countdown2 == 0)) { -		// TODO SoundMan_addSound(0x01104C08, 0x4A116437, true); -		// TODO SoundMan_playSoundLooping(0x4A116437); +		_vm->_soundMan->addSound(0x01104C08, 0x4A116437); +		_vm->_soundMan->playSoundLooping(0x4A116437);  	}  } @@ -211,7 +211,7 @@ void Class525::sub466420() {  }  void Class525::sub466460() { -	// TODO SoundMan_deleteSound(0x4A116437); +	_vm->_soundMan->deleteSound(0x4A116437);  	_soundResource1.play(0x4A120435);  	startAnimation(0x4C210500, 0, -1);  } @@ -406,7 +406,7 @@ Class489::Class489(NeverhoodEngine *vm, Scene *parentScene, Sprite *klayman, Spr  }  Class489::~Class489() { -	// TODO SoundMan_deleteSoundGroup(0x05331081); +	_vm->_soundMan->deleteSoundGroup(0x05331081);  }  uint32 Class489::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { @@ -616,8 +616,8 @@ void Class489::sub434EC0() {  	NextState(&Class489::sub434F40);  	setGlobalVar(0x12A10DB3, 1);  	_soundResource1.play(0xCC4A8456); -	// TODO SoundMan_addSound(0x05331081, 0xCE428854, true); -	// TODO SoundMan_playSoundLooping(0xCE428854); +	_vm->_soundMan->addSound(0x05331081, 0xCE428854); +	_vm->_soundMan->playSoundLooping(0xCE428854);  }  void Class489::sub434F40() { @@ -634,7 +634,7 @@ void Class489::sub434F80() {  	NextState(&Class489::sub434E90);  	setGlobalVar(0x12A10DB3, 0);  	_soundResource1.play(0xCC4A8456); -	// TODO SoundMan_deleteSound(0xCE428854); +	_vm->_soundMan->deleteSound(0xCE428854);  }  void Class489::sub434FF0() { diff --git a/engines/neverhood/navigationscene.h b/engines/neverhood/navigationscene.h index c37a7fc178..4397a4372b 100644 --- a/engines/neverhood/navigationscene.h +++ b/engines/neverhood/navigationscene.h @@ -34,6 +34,8 @@ public:  	NavigationScene(NeverhoodEngine *vm, Module *parentModule, uint32 navigationListId, int navigationIndex, const byte *itemsTypes);  	virtual ~NavigationScene();  	int getNavigationAreaType(); +	bool getSoundFlag1() const { return _soundFlag1; } +	bool getSoundFlag2() const { return _soundFlag2; }  protected:  	SmackerPlayer *_smackerPlayer;  	bool _smackerDone; diff --git a/engines/neverhood/neverhood.cpp b/engines/neverhood/neverhood.cpp index abd937497e..e5c07b5b8d 100644 --- a/engines/neverhood/neverhood.cpp +++ b/engines/neverhood/neverhood.cpp @@ -100,6 +100,7 @@ Common::Error NeverhoodEngine::run() {  #if 1  	_soundMan = new SoundMan(this); +	_audioResourceMan = new AudioResourceMan(this);  	_collisionMan = new CollisionMan(this);  	_gameModule = new GameModule(this); @@ -139,6 +140,8 @@ Common::Error NeverhoodEngine::run() {  		//debug("millis %d", _system->getMillis());		  		_gameModule->handleUpdate();  		_gameModule->draw(); +		_soundMan->update(); +		_audioResourceMan->update();  		_screen->wait();  		_screen->update(); @@ -149,6 +152,7 @@ Common::Error NeverhoodEngine::run() {  	delete _gameModule;  	delete _collisionMan;  	delete _soundMan; +	delete _audioResourceMan;  #endif diff --git a/engines/neverhood/neverhood.h b/engines/neverhood/neverhood.h index 13ea39986a..2aa84e5cb7 100644 --- a/engines/neverhood/neverhood.h +++ b/engines/neverhood/neverhood.h @@ -46,6 +46,7 @@ class GameVars;  class ResourceMan;  class Screen;  class SoundMan; +class AudioResourceMan;  class StaticData;  struct NPoint; @@ -87,6 +88,7 @@ public:  	CollisionMan *_collisionMan;  	SoundMan *_soundMan; +	AudioResourceMan *_audioResourceMan;  public: diff --git a/engines/neverhood/resource.cpp b/engines/neverhood/resource.cpp index 7b0aa94b13..9bf6549ffe 100644 --- a/engines/neverhood/resource.cpp +++ b/engines/neverhood/resource.cpp @@ -640,44 +640,20 @@ DataResource::DRDirectoryItem *DataResource::findDRDirectoryItem(uint32 nameHash  	return NULL;  } -// SoundResource -// ALL TODO - -SoundResource::SoundResource(NeverhoodEngine *vm) -	: _vm(vm) { -} - -bool SoundResource::isPlaying() {  -	return false;  -} - -void SoundResource::load(uint32 fileHash) { -} - -void SoundResource::unload() { -} - -void SoundResource::play(uint32 fileHash, bool looping) { -} - -void SoundResource::play() { -} - -void SoundResource::setVolume(int volume) { -} -  uint32 calcHash(const char *value) {  	uint32 hash = 0, shiftValue = 0;  	while (*value != 0) {  		char ch = *value++; -		if (ch >= 'a' && ch <= 'z') -			ch -= 32; -		else if (ch >= '0' && ch <= '9') -			ch += 22; -		shiftValue += ch - 64; -		if (shiftValue >= 32) -			shiftValue -= 32; -		hash ^= 1 << shiftValue; +		if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9')) { +			if (ch >= 'a' && ch <= 'z') +				ch -= 32; +			else if (ch >= '0' && ch <= '9') +				ch += 22; +			shiftValue += ch - 64; +			if (shiftValue >= 32) +				shiftValue -= 32; +			hash ^= 1 << shiftValue; +		}  	}  	return hash;  } diff --git a/engines/neverhood/resource.h b/engines/neverhood/resource.h index b0cd464e06..16782968f8 100644 --- a/engines/neverhood/resource.h +++ b/engines/neverhood/resource.h @@ -191,22 +191,6 @@ protected:  	DataResource::DRDirectoryItem *findDRDirectoryItem(uint32 nameHash, uint16 type);   }; -// TODO: Dummy class atm - -class SoundResource { -public: -	SoundResource(NeverhoodEngine *vm); -	bool isPlaying(); -	void load(uint32 fileHash); -	void unload(); -	void play(uint32 fileHash, bool looping = false); -	void play(); -	void stop() { /*DUMMY*/ } -	void setVolume(int volume); -protected: -	NeverhoodEngine *_vm;	 -}; -  uint32 calcHash(const char *value);  } // End of namespace Neverhood diff --git a/engines/neverhood/resourceman.cpp b/engines/neverhood/resourceman.cpp index 0538f58e87..c073e976a4 100644 --- a/engines/neverhood/resourceman.cpp +++ b/engines/neverhood/resourceman.cpp @@ -35,7 +35,7 @@ void ResourceMan::addArchive(const Common::String &filename) {  	uint archiveIndex = _archives.size();  	archive->open(filename);  	_archives.push_back(archive); -	debug("ResourceMan::addArchive(%s) %d files", filename.c_str(), archive->getCount()); +	debug(3, "ResourceMan::addArchive(%s) %d files", filename.c_str(), archive->getCount());  	_entries.reserve(_entries.size() + archive->getCount());  	for (uint archiveEntryIndex = 0; archiveEntryIndex < archive->getCount(); archiveEntryIndex++) {  		BlbArchiveEntry *archiveEntry = archive->getEntry(archiveEntryIndex); diff --git a/engines/neverhood/scene.cpp b/engines/neverhood/scene.cpp index d189fad240..8520d6467d 100644 --- a/engines/neverhood/scene.cpp +++ b/engines/neverhood/scene.cpp @@ -375,7 +375,7 @@ uint32 Scene::smackerHandleMessage(int messageNum, const MessageParam ¶m, En  }  bool Scene::queryPositionSprite(int16 mouseX, int16 mouseY) { -	debug("Scene::queryPositionSprite(%d, %d)", mouseX, mouseY); +	//debug("Scene::queryPositionSprite(%d, %d)", mouseX, mouseY);  	for (uint i = 0; i < _vm->_collisionMan->getSpriteCount(); i++) {  		Sprite *sprite = _vm->_collisionMan->getSprite(i);  		if (sprite->hasMessageHandler() && sprite->isPointInside(mouseX, mouseY) &&  @@ -397,7 +397,7 @@ bool Scene::queryPositionRectList(int16 mouseX, int16 mouseY) {  				for (uint j = 0; j < rectList[i].subRects.size(); j++) {  					debug(2, "  (%d, %d) ? (%d, %d, %d, %d)", mouseX, mouseY, rectList[i].subRects[j].rect.x1, rectList[i].subRects[j].rect.y1, rectList[i].subRects[j].rect.x2, rectList[i].subRects[j].rect.y2);  					if (rectList[i].subRects[j].rect.contains(mouseX, mouseY)) { -						debug("Scene::queryPositionRectList() -> %08X", rectList[i].subRects[j].messageListId); +						//debug("Scene::queryPositionRectList() -> %08X", rectList[i].subRects[j].messageListId);  						return setMessageList2(rectList[i].subRects[j].messageListId);  					}  				} @@ -416,7 +416,7 @@ void Scene::setMessageList(uint32 id, bool messageListFlag, bool systemCallbackF  }  void Scene::setMessageList(MessageList *messageList, bool messageListFlag, bool systemCallbackFlag) { -	debug("Scene::setMessageList(%p)", (void*)messageList); +	//debug("Scene::setMessageList(%p)", (void*)messageList);  	_messageList = messageList;  	_messageListCount = _messageList ? _messageList->size() : 0;  	_messageListIndex = 0; @@ -426,11 +426,13 @@ void Scene::setMessageList(MessageList *messageList, bool messageListFlag, bool  	_messageListStatus = 1;  	sendMessage(_klayman, 0x101C, 0); +#if 0  	// DEBUG: Show message list  	for (uint i = 0; i < messageList->size(); i++) {  		debug("A: %02d: %04X, %08X", i, (*messageList)[i].messageNum, (*messageList)[i].messageValue);  	}  	debug("A: ================================================================"); +#endif	  } @@ -441,13 +443,15 @@ bool Scene::setMessageList2(uint32 id, bool messageListFlag, bool systemCallback  bool Scene::setMessageList2(MessageList *messageList, bool messageListFlag, bool systemCallbackFlag) {  	bool result = false; -	debug("Scene::setMessageList2(%p)", (void*)messageList); +	//debug("Scene::setMessageList2(%p)", (void*)messageList); +#if 0  	// DEBUG: Show message list  	for (uint i = 0; i < messageList->size(); i++) {  		debug("B: %02d: %04X, %08X", i, (*messageList)[i].messageNum, (*messageList)[i].messageValue);  	}  	debug("B: ================================================================"); +#endif  	if (_messageListStatus == 1) {  		if (messageList != _messageList2) { @@ -500,7 +504,7 @@ void Scene::runMessageList() {  			uint32 messageNum = (*_messageList)[_messageListIndex].messageNum;  			uint32 messageParam = (*_messageList)[_messageListIndex].messageValue; -			debug("Scene::runMessageList() %04X, %08X", messageNum, messageParam); +			//debug("Scene::runMessageList() %04X, %08X", messageNum, messageParam);  			_messageListIndex++;  			if (_messageListIndex == _messageListCount) { @@ -573,7 +577,7 @@ void Scene::clearRectList() {  void Scene::loadHitRectList() {  	HitRectList *hitRectList = _dataResource.getHitRectList(); -	debug("Scene::loadHitRectList() hitRectList = %p", (void*)hitRectList); +	//debug("Scene::loadHitRectList() hitRectList = %p", (void*)hitRectList);  	if (hitRectList) {  		_hitRectList = *hitRectList;  		_vm->_collisionMan->setHitRects(&_hitRectList); diff --git a/engines/neverhood/sound.cpp b/engines/neverhood/sound.cpp index 91a23bfc7b..bd2f223998 100644 --- a/engines/neverhood/sound.cpp +++ b/engines/neverhood/sound.cpp @@ -20,36 +20,101 @@   *   */ +#include "common/memstream.h"  #include "graphics/palette.h"  #include "neverhood/sound.h" +#include "neverhood/resourceman.h"  namespace Neverhood {  // TODO Put more stuff into the constructors/destructors of the item structs  // TODO Some parts are quite bad here, but my priority is to get sound working at all +SoundResource::SoundResource(NeverhoodEngine *vm) +	: _vm(vm), _soundIndex(-1) { +} + +SoundResource::~SoundResource() { +	unload(); +} + +bool SoundResource::isPlaying() {  +	return _soundIndex >= 0 && +		_vm->_audioResourceMan->isSoundPlaying(_soundIndex);  +} + +void SoundResource::load(uint32 fileHash) { +	unload(); +	_soundIndex = _vm->_audioResourceMan->addSound(fileHash); +	_vm->_audioResourceMan->loadSound(_soundIndex); +} + +void SoundResource::unload() { +	if (_soundIndex >= 0) { +		_vm->_audioResourceMan->removeSound(_soundIndex); +		_soundIndex = -1; +	} +} + +void SoundResource::play(uint32 fileHash) { +	load(fileHash); +	play(); +} + +void SoundResource::play() { +	if (_soundIndex >= 0) +		_vm->_audioResourceMan->playSound(_soundIndex, false); +} + +void SoundResource::stop() { +	if (_soundIndex >= 0) +		_vm->_audioResourceMan->stopSound(_soundIndex); +} + +void SoundResource::setVolume(int16 volume) { +	if (_soundIndex >= 0) +		_vm->_audioResourceMan->setSoundVolume(_soundIndex, volume); +} + +void SoundResource::setPan(int16 pan) { +	if (_soundIndex >= 0) +		_vm->_audioResourceMan->setSoundPan(_soundIndex, pan); +} +  MusicResource::MusicResource(NeverhoodEngine *vm) -	: _vm(vm) { +	: _vm(vm), _musicIndex(-1) {  }  bool MusicResource::isPlaying() {  -	return false;  +	return _musicIndex >= 0 && +		_vm->_audioResourceMan->isMusicPlaying(_musicIndex);   }  void MusicResource::load(uint32 fileHash) { -	// TODO +	unload(); +	_musicIndex = _vm->_audioResourceMan->loadMusic(fileHash);  }  void MusicResource::unload() { -	// TODO +	if (_musicIndex >= 0) { +		_vm->_audioResourceMan->unloadMusic(_musicIndex); +		_musicIndex = -1; +	}  }  void MusicResource::play(int16 fadeVolumeStep) { -	// TODO +	if (_musicIndex >= 0) +		_vm->_audioResourceMan->playMusic(_musicIndex, fadeVolumeStep);  }  void MusicResource::stop(int16 fadeVolumeStep) { -	// TODO +	if (_musicIndex >= 0) +		_vm->_audioResourceMan->stopMusic(_musicIndex, fadeVolumeStep); +} + +void MusicResource::setVolume(int16 volume) { +	if (_musicIndex >= 0) +		_vm->_audioResourceMan->setMusicVolume(_musicIndex, volume);  }  MusicItem::MusicItem() @@ -80,6 +145,8 @@ SoundItem::~SoundItem() {  	delete _soundResource;  } +// SoundMan +  SoundMan::SoundMan(NeverhoodEngine *vm)  	: _vm(vm),  	_soundIndex1(-1), _soundIndex2(-1), _soundIndex3(-1) { @@ -107,8 +174,8 @@ void SoundMan::deleteMusic(uint32 musicFileHash) {  	if (musicItem) {  		delete musicItem;  		for (uint i = 0; i < _musicItems.size(); ++i) -			if (_musicItems[i]->_musicFileHash == musicFileHash) { -				_musicItems.remove_at(i); +			if (_musicItems[i] == musicItem) { +				_musicItems[i] = NULL;  				break;  			}  	} @@ -149,8 +216,8 @@ void SoundMan::deleteSound(uint32 soundFileHash) {  	if (soundItem) {  		delete soundItem;  		for (uint i = 0; i < _soundItems.size(); ++i) -			if (_soundItems[i]->_soundFileHash == soundFileHash) { -				_soundItems.remove_at(i); +			if (_soundItems[i] == soundItem) { +				_soundItems[i] = NULL;  				break;  			}  	} @@ -213,35 +280,41 @@ void SoundMan::update() {  	for (uint i = 0; i < _soundItems.size(); ++i) {  		SoundItem *soundItem = _soundItems[i]; -		if (soundItem->_playOnceAfterCountdown) { -			if (soundItem->_currCountdown == 0) { -				soundItem->_currCountdown = soundItem->_initialCountdown; -			} else if (--soundItem->_currCountdown == 0) { -				soundItem->_soundResource->play(); +		if (soundItem) { +			if (soundItem->_playOnceAfterCountdown) { +				if (soundItem->_currCountdown == 0) { +					soundItem->_currCountdown = soundItem->_initialCountdown; +				} else if (--soundItem->_currCountdown == 0) { +					soundItem->_soundResource->play(); +				} +			} else if (soundItem->_playOnceAfterRandomCountdown) { +				if (soundItem->_currCountdown == 0) { +					if (soundItem->_minCountdown > 0 && soundItem->_maxCountdown > 0 && soundItem->_minCountdown < soundItem->_maxCountdown) +						soundItem->_currCountdown = _vm->_rnd->getRandomNumberRng(soundItem->_minCountdown, soundItem->_maxCountdown); +				} else if (--soundItem->_currCountdown == 0) { +					soundItem->_soundResource->play(); +				} +			} else if (soundItem->_playLooping && !soundItem->_soundResource->isPlaying()) { +				soundItem->_soundResource->play(); // TODO Looping parameter?  			} -		} else if (soundItem->_playOnceAfterRandomCountdown) { -			if (soundItem->_currCountdown == 0) { -				if (soundItem->_minCountdown > 0 && soundItem->_maxCountdown > 0 && soundItem->_minCountdown < soundItem->_maxCountdown) -					soundItem->_currCountdown = _vm->_rnd->getRandomNumberRng(soundItem->_minCountdown, soundItem->_maxCountdown); -			} else if (--soundItem->_currCountdown == 0) { -				soundItem->_soundResource->play(); -			} -		} else if (soundItem->_playLooping && !soundItem->_soundResource->isPlaying()) { -			soundItem->_soundResource->play(); // TODO Looping parameter?  		}  	}  	for (uint i = 0; i < _musicItems.size(); ++i) {  		MusicItem *musicItem = _musicItems[i]; -		if (musicItem->_countdown) { -			--musicItem->_countdown; -		} else if (musicItem->_play && !musicItem->_musicResource->isPlaying()) { -			musicItem->_musicResource->play(musicItem->_fadeVolumeStep); -			musicItem->_fadeVolumeStep = 0; -		} else if (musicItem->_stop) { -			musicItem->_musicResource->stop(musicItem->_fadeVolumeStep); -			musicItem->_fadeVolumeStep = 0; -			musicItem->_stop = false; +		if (musicItem) { +			if (musicItem->_countdown) { +				--musicItem->_countdown; +			} else if (musicItem->_play && !musicItem->_musicResource->isPlaying()) { +				debug("SoundMan: play music %08X (fade %d)", musicItem->_musicFileHash, musicItem->_fadeVolumeStep); +				musicItem->_musicResource->play(musicItem->_fadeVolumeStep); +				musicItem->_fadeVolumeStep = 0; +			} else if (musicItem->_stop) { +				debug("SoundMan: stop music %08X (fade %d)", musicItem->_musicFileHash, musicItem->_fadeVolumeStep); +				musicItem->_musicResource->stop(musicItem->_fadeVolumeStep); +				musicItem->_fadeVolumeStep = 0; +				musicItem->_stop = false; +			}  		}  	} @@ -253,11 +326,11 @@ void SoundMan::deleteGroup(uint32 nameHash) {  }  void SoundMan::deleteMusicGroup(uint32 nameHash) { -	for (int index = _musicItems.size() - 1; index >= 0; --index) { +	for (uint index = 0; index < _musicItems.size(); ++index) {  		MusicItem *musicItem = _musicItems[index]; -		if (musicItem->_nameHash == nameHash) { +		if (musicItem && musicItem->_nameHash == nameHash) {  			delete musicItem; -			_musicItems.remove_at(index); +			_musicItems[index] = NULL;  		}  	}  } @@ -276,11 +349,11 @@ void SoundMan::deleteSoundGroup(uint32 nameHash) {  		_soundIndex2 = -1;  	} -	for (int index = _soundItems.size() - 1; index >= 0; --index) { +	for (uint index = 0; index < _soundItems.size(); ++index) {  		soundItem = _soundItems[index]; -		if (soundItem->_nameHash == nameHash) { +		if (soundItem && soundItem->_nameHash == nameHash) {  			delete soundItem; -			_soundItems.remove_at(index); +			_soundItems[index] = NULL;  		}  	} @@ -359,21 +432,327 @@ void SoundMan::setSoundThreePlayFlag(bool playOnceAfterCountdown) {  MusicItem *SoundMan::getMusicItemByHash(uint32 musicFileHash) {  	for (uint i = 0; i < _musicItems.size(); ++i) -		if (_musicItems[i]->_musicFileHash == musicFileHash) +		if (_musicItems[i] && _musicItems[i]->_musicFileHash == musicFileHash)  			return _musicItems[i];  	return NULL;  }  SoundItem *SoundMan::getSoundItemByHash(uint32 soundFileHash) {  	for (uint i = 0; i < _soundItems.size(); ++i) -		if (_soundItems[i]->_soundFileHash == soundFileHash) +		if (_soundItems[i] && _soundItems[i]->_soundFileHash == soundFileHash)  			return _soundItems[i];  	return NULL;  } +int16 SoundMan::addMusicItem(MusicItem *musicItem) { +	return 0; // TODO +} + +int16 SoundMan::addSoundItem(SoundItem *soundItem) { +	for (uint i = 0; i < _soundItems.size(); ++i) +		if (!_soundItems[i]) { +			_soundItems[i] = soundItem; +			return i; +		} +	int16 soundIndex = _soundItems.size(); +	_soundItems.push_back(soundItem); +	return soundIndex; +} +  void SoundMan::deleteSoundByIndex(int index) {  	delete _soundItems[index]; -	_soundItems.remove_at(index); +	_soundItems[index] = NULL; +} + +// NeverhoodAudioStream + +NeverhoodAudioStream::NeverhoodAudioStream(int rate, byte shiftValue, bool isLooping, DisposeAfterUse::Flag disposeStream, Common::SeekableReadStream *stream) +	: _rate(rate), _shiftValue(shiftValue), _isLooping(isLooping), _isStereo(false), _stream(stream, disposeStream), _endOfData(false), _buffer(0), +	_isCompressed(_shiftValue != 0xFF), _prevValue(0) { +	// Setup our buffer for readBuffer +	_buffer = new byte[kSampleBufferLength * (_isCompressed ? 1 : 2)]; +	assert(_buffer); +} + +NeverhoodAudioStream::~NeverhoodAudioStream() { +	delete[] _buffer; +} + +int NeverhoodAudioStream::readBuffer(int16 *buffer, const int numSamples) { +	int samplesLeft = numSamples; +	 +	while (samplesLeft > 0 && !_endOfData) { + +		const int maxSamples = MIN<int>(kSampleBufferLength, samplesLeft); +		const int bytesToRead = maxSamples * (_isCompressed ? 1 : 2); +		int bytesRead = _stream->read(_buffer, bytesToRead); +		int samplesRead = bytesRead / (_isCompressed ? 1 : 2); +		 +		samplesLeft -= samplesRead; +		 +		const byte *src = _buffer; +		if (_isCompressed) { +			while (samplesRead--) { +				_prevValue += (int8)(*src++); +				*buffer++ = _prevValue << _shiftValue; +			} +		} else { +			memcpy(buffer, _buffer, bytesRead); +			buffer += bytesRead; +		} + +		if (bytesRead < bytesToRead || _stream->pos() >= _stream->size() || _stream->err() || _stream->eos()) { +			if (_isLooping) +				_stream->seek(0); +			else +				_endOfData = true; +		} + +	} + +	return numSamples - samplesLeft; +} + +AudioResourceMan::AudioResourceMan(NeverhoodEngine *vm) +	: _vm(vm) { +} + +AudioResourceMan::~AudioResourceMan() { +} + +int16 AudioResourceMan::addSound(uint32 fileHash) { +	AudioResourceManSoundItem *soundItem = new AudioResourceManSoundItem(); +	soundItem->_resourceHandle = _vm->_res->useResource(fileHash); +	soundItem->_fileHash = fileHash; +	soundItem->_data = NULL; +	soundItem->_isLoaded = false; +	soundItem->_isPlaying = false; +	soundItem->_volume = 100; +	soundItem->_panning = 50; + +	for (uint i = 0; i < _soundItems.size(); ++i) +		if (!_soundItems[i]) { +			_soundItems[i] = soundItem; +			return i; +		} + +	int16 soundIndex = (int16)_soundItems.size(); +	_soundItems.push_back(soundItem); +	return soundIndex; +} + +void AudioResourceMan::removeSound(int16 soundIndex) { +	AudioResourceManSoundItem *soundItem = _soundItems[soundIndex]; +	if (soundItem->_data) { +		_vm->_res->unloadResource(soundItem->_resourceHandle); +		soundItem->_data = NULL; +	} +	if (soundItem->_resourceHandle != 1) { +		_vm->_res->unuseResource(soundItem->_resourceHandle); +		soundItem->_resourceHandle = -1; +	} +	if (_vm->_mixer->isSoundHandleActive(soundItem->_soundHandle)) +		_vm->_mixer->stopHandle(soundItem->_soundHandle); +	delete soundItem; +	_soundItems[soundIndex] = NULL; +} + +void AudioResourceMan::loadSound(int16 soundIndex) { +	AudioResourceManSoundItem *soundItem = _soundItems[soundIndex]; +	if (!soundItem->_data) { +		// TODO Check if it's a sound resource +		soundItem->_data = _vm->_res->loadResource(soundItem->_resourceHandle); +	} +} + +void AudioResourceMan::unloadSound(int16 soundIndex) { +	AudioResourceManSoundItem *soundItem = _soundItems[soundIndex]; +	if (soundItem->_data) { +		_vm->_res->unloadResource(soundItem->_resourceHandle); +		soundItem->_data = NULL; +	} +} + +void AudioResourceMan::setSoundVolume(int16 soundIndex, int16 volume) { +	AudioResourceManSoundItem *soundItem = _soundItems[soundIndex]; +	soundItem->_volume = MIN<int16>(volume, 100); +	if (soundItem->_isPlaying && _vm->_mixer->isSoundHandleActive(soundItem->_soundHandle)) +		_vm->_mixer->setChannelVolume(soundItem->_soundHandle, VOLUME(soundItem->_volume)); +} + +void AudioResourceMan::setSoundPan(int16 soundIndex, int16 pan) { +	AudioResourceManSoundItem *soundItem = _soundItems[soundIndex]; +	soundItem->_panning = MIN<int16>(pan, 100); +	if (soundItem->_isPlaying && _vm->_mixer->isSoundHandleActive(soundItem->_soundHandle)) +		_vm->_mixer->setChannelVolume(soundItem->_soundHandle, PANNING(soundItem->_panning)); +} + +void AudioResourceMan::playSound(int16 soundIndex, bool looping) { +	AudioResourceManSoundItem *soundItem = _soundItems[soundIndex]; +	if (!soundItem->_data) +		loadSound(soundIndex); +		 +	uint32 soundSize = _vm->_res->getResourceSize(soundItem->_resourceHandle); +	Common::MemoryReadStream *stream = new Common::MemoryReadStream(soundItem->_data, soundSize, DisposeAfterUse::NO); +	byte *shiftValue = _vm->_res->getResourceExtData(soundItem->_resourceHandle); +	NeverhoodAudioStream *audioStream = new NeverhoodAudioStream(22050, *shiftValue, false, DisposeAfterUse::YES, stream); + +	_vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &soundItem->_soundHandle, +		audioStream, -1, VOLUME(soundItem->_volume), PANNING(soundItem->_panning)); +		 +	debug("playing sound %08X", soundItem->_fileHash); +	 +	soundItem->_isPlaying = true; +	 +} + +void AudioResourceMan::stopSound(int16 soundIndex) { +	AudioResourceManSoundItem *soundItem = _soundItems[soundIndex]; +	if (_vm->_mixer->isSoundHandleActive(soundItem->_soundHandle)) +		_vm->_mixer->stopHandle(soundItem->_soundHandle); +	soundItem->_isPlaying = false; +} + +bool AudioResourceMan::isSoundPlaying(int16 soundIndex) { +	AudioResourceManSoundItem *soundItem = _soundItems[soundIndex]; +	return soundItem->_isPlaying; +} + +int16 AudioResourceMan::loadMusic(uint32 fileHash) { + +	AudioResourceManMusicItem *musicItem; + +	for (uint i = 0; i < _musicItems.size(); ++i) { +		musicItem = _musicItems[i]; +		if (musicItem && musicItem->_fileHash == fileHash && musicItem->_remove) { +			musicItem->_remove = false; +			musicItem->_isFadingOut = false; +			musicItem->_isFadingIn = true; +			return i; +		} +	} +	 +	musicItem = new AudioResourceManMusicItem(); +	musicItem->_fileHash = fileHash; +	musicItem->_isPlaying = false; +	musicItem->_remove = false; +	musicItem->_volume = 100; +	musicItem->_panning = 50; +	musicItem->_start = false; +	musicItem->_isFadingIn = false; +	musicItem->_isFadingOut = false; + +	for (uint i = 0; i < _musicItems.size(); ++i) { +		if (!_musicItems[i]) { +			_musicItems[i] = musicItem; +			return i; +		} +	} +	 +	int16 musicIndex = _musicItems.size(); +	_musicItems.push_back(musicItem); +	return musicIndex; +	 +} + +void AudioResourceMan::unloadMusic(int16 musicIndex) { +	AudioResourceManMusicItem *musicItem = _musicItems[musicIndex]; +	if (musicItem->_isFadingOut) { +		musicItem->_remove = true; +	} else { +		if (_vm->_mixer->isSoundHandleActive(musicItem->_soundHandle)) +			_vm->_mixer->stopHandle(musicItem->_soundHandle); +		musicItem->_isPlaying = false; +		_musicItems[musicIndex] = NULL; +	} +} + +void AudioResourceMan::setMusicVolume(int16 musicIndex, int16 volume) { +	AudioResourceManMusicItem *musicItem = _musicItems[musicIndex]; +	musicItem->_volume = MIN<int16>(volume, 100); +	if (musicItem->_isPlaying && _vm->_mixer->isSoundHandleActive(musicItem->_soundHandle)) +		_vm->_mixer->setChannelVolume(musicItem->_soundHandle, VOLUME(musicItem->_volume)); +}	 + +void AudioResourceMan::playMusic(int16 musicIndex, int16 fadeVolumeStep) { +	AudioResourceManMusicItem *musicItem = _musicItems[musicIndex]; +	if (!musicItem->_isPlaying) { +		musicItem->_isFadingIn = false; +		musicItem->_isFadingOut = false; +		if (fadeVolumeStep != 0) { +			musicItem->_isFadingIn = true; +			musicItem->_fadeVolume = 0; +			musicItem->_fadeVolumeStep = fadeVolumeStep; +		} +		musicItem->_start = true; +	} +} + +void AudioResourceMan::stopMusic(int16 musicIndex, int16 fadeVolumeStep) { +	AudioResourceManMusicItem *musicItem = _musicItems[musicIndex]; +	if (_vm->_mixer->isSoundHandleActive(musicItem->_soundHandle)) { +		if (fadeVolumeStep != 0) { +			if (musicItem->_isFadingIn) +				musicItem->_isFadingIn = false; +			else +				musicItem->_fadeVolume = musicItem->_volume; +			musicItem->_isFadingOut = true; +			musicItem->_fadeVolumeStep = fadeVolumeStep; +		} else { +			_vm->_mixer->stopHandle(musicItem->_soundHandle); +		} +		musicItem->_isPlaying = false; +	} +} + +bool AudioResourceMan::isMusicPlaying(int16 musicIndex) { +	AudioResourceManMusicItem *musicItem = _musicItems[musicIndex]; +	return musicItem->_isPlaying; +} + +void AudioResourceMan::updateMusicItem(int16 musicIndex) { +	AudioResourceManMusicItem *musicItem = _musicItems[musicIndex]; + +	if (musicItem->_start && !_vm->_mixer->isSoundHandleActive(musicItem->_soundHandle)) { +		Common::SeekableReadStream *stream = _vm->_res->createStream(musicItem->_fileHash); +		byte *shiftValue = _vm->_res->getResourceExtDataByHash(musicItem->_fileHash); +		NeverhoodAudioStream *audioStream = new NeverhoodAudioStream(22050, *shiftValue, true, DisposeAfterUse::YES, stream); +		_vm->_mixer->playStream(Audio::Mixer::kMusicSoundType, &musicItem->_soundHandle, +			audioStream, -1, VOLUME(musicItem->_isFadingIn ? musicItem->_fadeVolume : musicItem->_volume), +			PANNING(musicItem->_panning)); +		musicItem->_start = false; +		musicItem->_isPlaying = true; +	} +	 +	if (_vm->_mixer->isSoundHandleActive(musicItem->_soundHandle)) { +		if (musicItem->_isFadingIn) { +			musicItem->_fadeVolume += musicItem->_fadeVolumeStep; +			if (musicItem->_fadeVolume >= musicItem->_volume) { +				musicItem->_fadeVolume = musicItem->_volume; +				musicItem->_isFadingIn = false; +			} +			_vm->_mixer->setChannelVolume(musicItem->_soundHandle, VOLUME(musicItem->_fadeVolume)); +		} +		if (musicItem->_isFadingOut) { +			musicItem->_fadeVolume -= musicItem->_fadeVolumeStep; +			if (musicItem->_fadeVolume < 0) +				musicItem->_fadeVolume = 0; +			_vm->_mixer->setChannelVolume(musicItem->_soundHandle, VOLUME(musicItem->_fadeVolume)); +			if (musicItem->_fadeVolume == 0) { +				musicItem->_isFadingOut = false; +				stopMusic(musicIndex, 0); +				if (musicItem->_remove) +					unloadMusic(musicIndex); +			} +		} +	} + +} + +void AudioResourceMan::update() { +	for (uint i = 0; i < _musicItems.size(); ++i) +		if (_musicItems[i]) +			updateMusicItem(i);  }  } // End of namespace Neverhood diff --git a/engines/neverhood/sound.h b/engines/neverhood/sound.h index 39bf7cd096..b724e898f0 100644 --- a/engines/neverhood/sound.h +++ b/engines/neverhood/sound.h @@ -23,6 +23,7 @@  #ifndef NEVERHOOD_SOUND_H  #define NEVERHOOD_SOUND_H +#include "audio/audiostream.h"  #include "common/array.h"  #include "graphics/surface.h"  #include "neverhood/neverhood.h" @@ -30,6 +31,29 @@  namespace Neverhood { +// Convert volume from percent to 0..255 +#define VOLUME(volume) (Audio::Mixer::kMaxChannelVolume / 100 * (volume)) + +// Convert panning from percent (50% equals center) to -127..0..+127 +#define PANNING(panning) (254 / 100 * (panning) - 127) + +class SoundResource { +public: +	SoundResource(NeverhoodEngine *vm); +	~SoundResource(); +	bool isPlaying(); +	void load(uint32 fileHash); +	void unload(); +	void play(uint32 fileHash); +	void play(); +	void stop(); +	void setVolume(int16 volume); +	void setPan(int16 pan); +protected: +	NeverhoodEngine *_vm; +	int16 _soundIndex;	 +}; +  class MusicResource {  public:  	MusicResource(NeverhoodEngine *vm); @@ -38,8 +62,10 @@ public:  	void unload();  	void play(int16 fadeVolumeStep);  	void stop(int16 fadeVolumeStep); +	void setVolume(int16 volume);  protected:  	NeverhoodEngine *_vm; +	int16 _musicIndex;	  };  struct MusicItem { @@ -72,6 +98,8 @@ struct SoundItem {  	~SoundItem();  }; +// TODO Give this a better name +  class SoundMan {  public:  	SoundMan(NeverhoodEngine *vm); @@ -122,10 +150,102 @@ protected:  	MusicItem *getMusicItemByHash(uint32 musicFileHash);  	SoundItem *getSoundItemByHash(uint32 soundFileHash); +	int16 addMusicItem(MusicItem *musicItem); +	int16 addSoundItem(SoundItem *soundItem);  	void deleteSoundByIndex(int index);  }; +class NeverhoodAudioStream : public Audio::AudioStream { +public: +	NeverhoodAudioStream(int rate, byte shiftValue, bool isLooping, DisposeAfterUse::Flag disposeStream, Common::SeekableReadStream *stream); +	~NeverhoodAudioStream(); +	int readBuffer(int16 *buffer, const int numSamples); +	bool isStereo() const  { return _isStereo; } +	bool endOfData() const { return _endOfData; } +	int getRate() const { return _rate; } +private: +	const int _rate; +	const bool _isLooping; +	const bool _isStereo; +	const byte _shiftValue; +	const bool _isCompressed; +	int16 _prevValue; +	Common::DisposablePtr<Common::SeekableReadStream> _stream; +	bool _endOfData; +	byte *_buffer; +	enum { +		kSampleBufferLength = 2048 +	}; +	int fillBuffer(int maxSamples); +}; + +// TODO Rename these + +struct AudioResourceManSoundItem { +	uint32 _fileHash; +	int _resourceHandle; +	byte *_data; +	bool _isLoaded; +	bool _isPlaying; +	int16 _volume; +	int16 _panning; +	Audio::SoundHandle _soundHandle; +}; + +struct AudioResourceManMusicItem { +	uint32 _fileHash; +	// streamIndex dw +	// needCreate db +	bool _isPlaying; +	bool _remove; +	int16 _volume; +	int16 _panning; +	bool _start; +	bool _isFadingIn; +	bool _isFadingOut; +	int16 _fadeVolume; +	int16 _fadeVolumeStep; +	Audio::SoundHandle _soundHandle; +	// status dw +	// updateCounter dd +}; + +class AudioResourceMan { +public: +	AudioResourceMan(NeverhoodEngine *vm); +	~AudioResourceMan(); +	 +	int16 addSound(uint32 fileHash); +	void removeSound(int16 soundIndex); +	void loadSound(int16 soundIndex); +	void unloadSound(int16 soundIndex); +	void setSoundVolume(int16 soundIndex, int16 volume); +	void setSoundPan(int16 soundIndex, int16 pan); +	void playSound(int16 soundIndex, bool looping); +	void stopSound(int16 soundIndex); +	bool isSoundPlaying(int16 soundIndex); +	 +	int16 loadMusic(uint32 fileHash); +	void unloadMusic(int16 musicIndex); +	void setMusicVolume(int16 musicIndex, int16 volume); +	void playMusic(int16 musicIndex, int16 fadeVolumeStep); +	void stopMusic(int16 musicIndex, int16 fadeVolumeStep); +	bool isMusicPlaying(int16 musicIndex); +	void updateMusicItem(int16 musicIndex); +	 +	void update(); +	 +protected: +	NeverhoodEngine *_vm; + +	Common::Array<AudioResourceManMusicItem*> _musicItems; +	Common::Array<AudioResourceManSoundItem*> _soundItems; + +	int16 addSoundItem(AudioResourceManSoundItem *soundItem); + +}; +  } // End of namespace Neverhood  #endif /* NEVERHOOD_SOUND_H */  | 
