diff options
| -rw-r--r-- | engines/neverhood/module.mk | 1 | ||||
| -rw-r--r-- | engines/neverhood/modules/module2400.h | 1 | ||||
| -rw-r--r-- | engines/neverhood/modules/module2800.cpp | 962 | ||||
| -rw-r--r-- | engines/neverhood/modules/module2800.h | 236 | ||||
| -rw-r--r-- | engines/neverhood/modules/module2800_sprites.cpp | 1020 | ||||
| -rw-r--r-- | engines/neverhood/modules/module2800_sprites.h | 268 | 
6 files changed, 1296 insertions, 1192 deletions
| diff --git a/engines/neverhood/module.mk b/engines/neverhood/module.mk index 030c78a407..052c830182 100644 --- a/engines/neverhood/module.mk +++ b/engines/neverhood/module.mk @@ -33,6 +33,7 @@ MODULE_OBJS = \  	modules/module2600.o \  	modules/module2700.o \  	modules/module2800.o \ +	modules/module2800_sprites.o \  	modules/module2900.o \  	modules/module3000.o \  	mouse.o \ diff --git a/engines/neverhood/modules/module2400.h b/engines/neverhood/modules/module2400.h index b50fff91c4..3802c747f1 100644 --- a/engines/neverhood/modules/module2400.h +++ b/engines/neverhood/modules/module2400.h @@ -33,6 +33,7 @@  #include "neverhood/modules/module2100.h"  #include "neverhood/modules/module2200.h"  #include "neverhood/modules/module2800.h" +#include "neverhood/modules/module2800_sprites.h"  #include "neverhood/diskplayerscene.h"  namespace Neverhood { diff --git a/engines/neverhood/modules/module2800.cpp b/engines/neverhood/modules/module2800.cpp index 7980c6b308..3a33598090 100644 --- a/engines/neverhood/modules/module2800.cpp +++ b/engines/neverhood/modules/module2800.cpp @@ -26,6 +26,7 @@  #include "neverhood/modules/module1200.h"  #include "neverhood/modules/module1700.h"  #include "neverhood/modules/module2200.h" +#include "neverhood/modules/module2800_sprites.h"  #include "neverhood/diskplayerscene.h"  namespace Neverhood { @@ -643,154 +644,6 @@ void Scene2802::changeTuneStatus(int prevTuneStatus, int newTuneStatus) {  } -AsScene2803LightCord::AsScene2803LightCord(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int16 x, int16 y) -	: AnimatedSprite(vm, 1100), _parentScene(parentScene), _fileHash1(fileHash1), _fileHash2(fileHash2), -	_isPulled(false), _isBusy(false) { - -	createSurface(1010, 28, 379); -	SetUpdateHandler(&AnimatedSprite::update); -	SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); -	_x = x; -	_y = y; -	stIdle(); -} - -uint32 AsScene2803LightCord::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x100D: -		if (!_isBusy && param.asInteger() == calcHash("ClickSwitch")) { -			sendMessage(_parentScene, 0x480F, 0); -			playSound(0, 0x4E1CA4A0); -		} -		break; -	case 0x480F: -		stPulled(); -		break; -	case 0x482A: -		sendMessage(_parentScene, 0x1022, 990); -		break; -	case 0x482B: -		sendMessage(_parentScene, 0x1022, 1010); -		break; -	} -	return messageResult; -} - -uint32 AsScene2803LightCord::hmPulled(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x3002: -		gotoNextState(); -		break; -	} -	return messageResult; -} - -void AsScene2803LightCord::stPulled() { -	_isBusy = false; -	_isPulled = true; -	startAnimation(_fileHash2, 0, -1); -	SetMessageHandler(&AsScene2803LightCord::hmPulled); -	NextState(&AsScene2803LightCord::stIdle); -} - -void AsScene2803LightCord::stIdle() { -	_isPulled = false; -	startAnimation(_fileHash1, 0, -1); -	SetMessageHandler(&AsScene2803LightCord::handleMessage); -} - -void AsScene2803LightCord::setFileHashes(uint32 fileHash1, uint32 fileHash2) { -	_fileHash1 = fileHash1; -	_fileHash2 = fileHash2; -	if (_isPulled) { -		startAnimation(_fileHash2, _currFrameIndex, -1); -		_isBusy = true; -	} else { -		startAnimation(_fileHash1, 0, -1); -	} -} - -AsScene2803TestTubeOne::AsScene2803TestTubeOne(NeverhoodEngine *vm, uint32 fileHash1, uint32 fileHash2) -	: AnimatedSprite(vm, 1200), _fileHash1(fileHash1), _fileHash2(fileHash2) { - -	createSurface1(fileHash1, 100); -	SetUpdateHandler(&AnimatedSprite::update); -	SetMessageHandler(&AsScene2803TestTubeOne::handleMessage); -	_x = 529; -	_y = 326; -} - -uint32 AsScene2803TestTubeOne::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x2000: -		if (param.asInteger()) -			startAnimation(_fileHash2, 0, -1); -		else -			startAnimation(_fileHash1, 0, -1); -		break; -	} -	return messageResult; -} - -AsScene2803Rope::AsScene2803Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x) -	: AnimatedSprite(vm, 1100), _parentScene(parentScene) { - -	createSurface(990, 68, 476); -	SetUpdateHandler(&AnimatedSprite::update); -	SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); -	SetMessageHandler(&AsScene2803Rope::handleMessage); -	startAnimation(0x9D098C23, 35, 53); -	NextState(&AsScene2803Rope::stReleased); -	_x = x; -	_y = -276; -} - -uint32 AsScene2803Rope::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x3002: -		startAnimation(0x9D098C23, 50, -1); -		SetMessageHandler(&AsScene2803Rope::hmReleased); -		break; -	case 0x482A: -		sendMessage(_parentScene, 0x1022, 990); -		break; -	case 0x482B: -		sendMessage(_parentScene, 0x1022, 1010); -		break; -	} -	return messageResult; -} - -uint32 AsScene2803Rope::hmReleased(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x3002: -		gotoNextState(); -		break; -	case 0x482A: -		sendMessage(_parentScene, 0x1022, 990); -		break; -	case 0x482B: -		sendMessage(_parentScene, 0x1022, 1010); -		break; -	} -	return messageResult; -} - -void AsScene2803Rope::stReleased() { -	startAnimation(0x8258A030, 0, 1); -	NextState(&AsScene2803Rope::stHide); -} - -void AsScene2803Rope::stHide() { -	stopAnimation(); -	setVisible(false); -} -  Scene2803::Scene2803(NeverhoodEngine *vm, Module *parentModule, int which)  	: Scene(vm, parentModule), _paletteArea(0) { @@ -1306,379 +1159,6 @@ void Scene2803Small::updatePaletteArea(bool instantly) {  	_palette->startFadeToPalette(instantly ? 0 : 12);  } -SsScene2804RedButton::SsScene2804RedButton(NeverhoodEngine *vm, Scene2804 *parentScene) -	: StaticSprite(vm, 900), _countdown(0), _parentScene(parentScene) { - -	loadSprite(getGlobalVar(V_SHRINK_LIGHTS_ON) ? 0x51A10202 : 0x11814A21, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400); -	setVisible(false); -	SetUpdateHandler(&SsScene2804RedButton::update); -	SetMessageHandler(&SsScene2804RedButton::handleMessage); -	loadSound(0, 0x44241240); -} - -void SsScene2804RedButton::update() { -	updatePosition(); -	if (_countdown != 0 && (--_countdown) == 0) { -		setVisible(false); -	} -} - -uint32 SsScene2804RedButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x1011: -		if (_countdown == 0 && !_parentScene->isWorking()) { -			playSound(0); -			setVisible(true); -			_countdown = 4; -			sendMessage(_parentScene, 0x2000, 0); -		} -		messageResult = 1; -		break; -	} -	return messageResult; -} - -SsScene2804LightCoil::SsScene2804LightCoil(NeverhoodEngine *vm) -	: StaticSprite(vm, 900) { - -	loadSprite(0x8889B008, kSLFDefDrawOffset | kSLFDefPosition, 400); -	setVisible(false); -	SetMessageHandler(&SsScene2804LightCoil::handleMessage); -} - -uint32 SsScene2804LightCoil::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x2002: -		setVisible(true); -		updatePosition(); -		messageResult = 1; -		break; -	case 0x2003: -		setVisible(false); -		updatePosition(); -		messageResult = 1; -		break; -	} -	return messageResult; -} - -SsScene2804LightTarget::SsScene2804LightTarget(NeverhoodEngine *vm) -	: StaticSprite(vm, 900) { - -	loadSprite(0x06092132, kSLFDefDrawOffset | kSLFDefPosition, 400); -	setVisible(false); -	SetMessageHandler(&SsScene2804LightTarget::handleMessage); -} - -uint32 SsScene2804LightTarget::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x2004: -		setVisible(true); -		updatePosition(); -		messageResult = 1; -		break; -	case 0x2005: -		setVisible(false); -		updatePosition(); -		messageResult = 1; -		break; -	} -	return messageResult; -} - -SsScene2804Flash::SsScene2804Flash(NeverhoodEngine *vm) -	: StaticSprite(vm, 900) { - -	loadSprite(0x211003A0, kSLFDefDrawOffset | kSLFDefPosition, 400); -	setVisible(false); -	loadSound(0, 0xCB36BA54); -} - -void SsScene2804Flash::show() { -	setVisible(true); -	updatePosition(); -	playSound(0); -} - -SsScene2804BeamCoilBody::SsScene2804BeamCoilBody(NeverhoodEngine *vm) -	: StaticSprite(vm, 900) { - -	loadSprite(0x9A816000, kSLFDefDrawOffset | kSLFDefPosition, 400); -	setVisible(false); -} - -AsScene2804CrystalWaves::AsScene2804CrystalWaves(NeverhoodEngine *vm, uint crystalIndex) -	: AnimatedSprite(vm, 1100), _crystalIndex(crystalIndex) { - -	static const NPoint kAsScene2804CrystalWavesPoints[] = { -		{323, 245}, -		{387, 76}, -		{454, 260}, -		{527, 70} -	}; - -	_x = kAsScene2804CrystalWavesPoints[crystalIndex].x; -	_y = kAsScene2804CrystalWavesPoints[crystalIndex].y; -	createSurface1(0x840C41F0, 1200); -	if (crystalIndex & 1) -		setDoDeltaY(1); -	setVisible(false); -	_needRefresh = true; -	SetUpdateHandler(&AnimatedSprite::update); -	SetMessageHandler(&Sprite::handleMessage); -} - -void AsScene2804CrystalWaves::show() { -	setVisible(true); -	startAnimation(0x840C41F0, 0, -1); -} - -void AsScene2804CrystalWaves::hide() { -	setVisible(false); -	stopAnimation(); -} - -static const int16 kAsScene2804CrystalFrameNums[] = { -	0, 6, 2, 8, 1, 10, 0, 0 -}; - -static const uint32 kAsScene2804CrystalFileHashes[] = { -	0x000540B0, -	0x001280D0, -	0x003D0010, -	0x00620190, -	0x00DC0290 -}; - -AsScene2804Crystal::AsScene2804Crystal(NeverhoodEngine *vm, AsScene2804CrystalWaves *asCrystalWaves, uint crystalIndex) -	: AnimatedSprite(vm, 1100), _asCrystalWaves(asCrystalWaves), _crystalIndex(crystalIndex), _isShowing(false) { - -	static const NPoint kAsScene2804CrystalPoints[] = { -		{204, 196}, -		{272, 316}, -		{334, 206}, -		{410, 334}, -		{470, 180} -	}; - -	_colorNum = (int16)getSubVar(VA_CURR_CRYSTAL_COLORS, crystalIndex); -	_isLightOn = getGlobalVar(V_SHRINK_LIGHTS_ON) != 0; -	if (_isLightOn) { -		_x = kAsScene2804CrystalPoints[crystalIndex].x; -		_y = kAsScene2804CrystalPoints[crystalIndex].y; -		createSurface1(0x108DFB12, 1200); -		startAnimation(0x108DFB12, kAsScene2804CrystalFrameNums[_colorNum], -1); -		_needRefresh = true; -		_newStickFrameIndex = kAsScene2804CrystalFrameNums[_colorNum]; -	} else { -		_x = 320; -		_y = 240; -		createSurface1(kAsScene2804CrystalFileHashes[crystalIndex], 1200); -		startAnimation(kAsScene2804CrystalFileHashes[crystalIndex], _colorNum, -1); -		setVisible(false); -		_needRefresh = true; -		_newStickFrameIndex = _colorNum; -	} -	loadSound(0, 0x725294D4); -	SetUpdateHandler(&AnimatedSprite::update); -} - -void AsScene2804Crystal::show() { -	if (!_isLightOn) { -		setVisible(true); -		_isShowing = true; -		if (_asCrystalWaves) -			_asCrystalWaves->show(); -		playSound(0); -	} -} - -void AsScene2804Crystal::hide() { -	if (!_isLightOn) { -		setVisible(false); -		_isShowing = false; -		if (_asCrystalWaves) -			_asCrystalWaves->hide(); -	} -} - -void AsScene2804Crystal::activate() { -	if (!_isShowing) { -		int16 frameNum = kAsScene2804CrystalFrameNums[_colorNum]; -		_colorNum++; -		if (_colorNum >= 6) -			_colorNum = 0; -		if (_isLightOn) { -			startAnimation(0x108DFB12, frameNum, kAsScene2804CrystalFrameNums[_colorNum]); -			_playBackwards = kAsScene2804CrystalFrameNums[_colorNum] < _colorNum; -			_newStickFrameIndex = kAsScene2804CrystalFrameNums[_colorNum]; -		} else { -			startAnimation(kAsScene2804CrystalFileHashes[_crystalIndex], _colorNum, -1); -			_newStickFrameIndex = _colorNum; -		} -		setSubVar(VA_CURR_CRYSTAL_COLORS, _crystalIndex, _colorNum); -	} -} - -SsScene2804CrystalButton::SsScene2804CrystalButton(NeverhoodEngine *vm, Scene2804 *parentScene, AsScene2804Crystal *asCrystal, uint crystalIndex) -	: StaticSprite(vm, 900), _countdown(0), _parentScene(parentScene), _asCrystal(asCrystal), _crystalIndex(crystalIndex) { - -	static const uint32 kSsScene2804CrystalButtonFileHashes1[] = { -		0x911101B0, -		0x22226001, -		0x4444A362, -		0x888925A4, -		0x11122829 -	}; - -	static const uint32 kSsScene2804CrystalButtonFileHashes2[] = { -		0xB500A1A0, -		0x6A012021, -		0xD4022322, -		0xA8042525, -		0x5008292B -	}; - -	loadSprite(getGlobalVar(V_SHRINK_LIGHTS_ON) ? kSsScene2804CrystalButtonFileHashes1[crystalIndex] : kSsScene2804CrystalButtonFileHashes2[crystalIndex], -		kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400); -	setVisible(false); -	loadSound(0, 0x44045140); -	SetUpdateHandler(&SsScene2804CrystalButton::update); -	SetMessageHandler(&SsScene2804CrystalButton::handleMessage); -} - -void SsScene2804CrystalButton::update() { -	updatePosition(); -	if (_countdown != 0 && (--_countdown) == 0) { -		setVisible(false); -	} -} - -uint32 SsScene2804CrystalButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x1011: -		if (_countdown == 0 && !_parentScene->isWorking()) { -			playSound(0); -			setVisible(true); -			_countdown = 4; -			_asCrystal->activate(); -		} -		messageResult = 1; -		break; -	} -	return messageResult; -} - -AsScene2804BeamCoil::AsScene2804BeamCoil(NeverhoodEngine *vm, Scene *parentScene, SsScene2804BeamCoilBody *ssBeamCoilBody) -	: AnimatedSprite(vm, 1400), _parentScene(parentScene), _ssBeamCoilBody(ssBeamCoilBody), _countdown(0) { - -	createSurface1(0x00494891, 1000); -	_x = 125; -	_y = 184; -	setVisible(false); -	_needRefresh = true; -	AnimatedSprite::updatePosition(); -	loadSound(0, 0x6352F051); -	_vm->_soundMan->addSound(0xC5EA0B28, 0xEF56B094); -	SetUpdateHandler(&AsScene2804BeamCoil::update); -	SetMessageHandler(&AsScene2804BeamCoil::handleMessage); -} - -AsScene2804BeamCoil::~AsScene2804BeamCoil() { -	_vm->_soundMan->deleteSoundGroup(0xC5EA0B28); -} - -void AsScene2804BeamCoil::update() { -	updateAnim(); -	updatePosition(); -	if (_countdown != 0 && (--_countdown) == 0) { -		sendMessage(_parentScene, 0x2001, 0); -	} -} - -uint32 AsScene2804BeamCoil::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x2002: -		show(); -		_countdown = 92; -		messageResult = 1; -		break; -	case 0x2003: -		hide(); -		messageResult = 1; -		break; -	} -	return messageResult; -} - -void AsScene2804BeamCoil::show() { -	_ssBeamCoilBody->setVisible(true); -	setVisible(true); -	startAnimation(0x00494891, 0, -1); -	playSound(0); -	SetMessageHandler(&AsScene2804BeamCoil::hmBeaming); -	NextState(&AsScene2804BeamCoil::stBeaming); -} - -void AsScene2804BeamCoil::hide() { -	stopAnimation(); -	SetMessageHandler(&AsScene2804BeamCoil::handleMessage); -	setVisible(false); -	_ssBeamCoilBody->setVisible(false); -	_vm->_soundMan->stopSound(0xEF56B094); -} - -void AsScene2804BeamCoil::stBeaming() { -	startAnimation(0x00494891, 93, -1); -	NextState(&AsScene2804BeamCoil::stBeaming); -	_vm->_soundMan->playSoundLooping(0xEF56B094); -} - -uint32 AsScene2804BeamCoil::hmBeaming(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x3002: -		gotoNextState(); -		break; -	} -	return messageResult; -} - -AsScene2804BeamTarget::AsScene2804BeamTarget(NeverhoodEngine *vm) -	: AnimatedSprite(vm, 1400) { - -	createSurface1(0x03842000, 1000); -	_x = 475; -	_y = 278; -	setVisible(false); -	_needRefresh = true; -	updatePosition(); -	SetUpdateHandler(&AnimatedSprite::update); -	SetMessageHandler(&AsScene2804BeamTarget::handleMessage); -} - -uint32 AsScene2804BeamTarget::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x2004: -		setVisible(true); -		startAnimation(0x03842000, 0, -1); -		messageResult = 1; -		break; -	case 0x2005: -		setVisible(false); -		stopAnimation(); -		messageResult = 1; -		break; -	} -	return messageResult; -} -  Scene2804::Scene2804(NeverhoodEngine *vm, Module *parentModule, int which)  	: Scene(vm, parentModule), _countdown1(0), _countdown2(0), _countdown3(0),  	_beamStatus(0), _isSolved(false), _isWorking(false) { @@ -1848,34 +1328,6 @@ uint32 Scene2805::handleMessage(int messageNum, const MessageParam ¶m, Entit  	return 0;  } -AsScene2806Spew::AsScene2806Spew(NeverhoodEngine *vm) -	: AnimatedSprite(vm, 1200) { - -	createSurface1(0x04211490, 1200); -	_x = 378; -	_y = 423; -	SetUpdateHandler(&AnimatedSprite::update); -	SetMessageHandler(&AsScene2806Spew::handleMessage); -	setDoDeltaX(1); -	setVisible(false); -} - -uint32 AsScene2806Spew::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x2000: -		playSound(0, 0x48640244); -		startAnimation(0x04211490, 0, -1); -		setVisible(true); -		break; -	case 0x3002: -		stopAnimation(); -		setVisible(false); -		break; -	} -	return messageResult; -} -  Scene2806::Scene2806(NeverhoodEngine *vm, Module *parentModule, int which)  	: Scene(vm, parentModule) { @@ -2067,267 +1519,6 @@ static const uint32 kClass428FileHashes[] = {  	0x40800711  }; -static const int kClass428Countdowns1[] = { -	18, 16, 10, 0 -}; - -static const int kClass428Countdowns2[] = { -	9, 9, 8, 8, 5, 5, 0, 0 -}; - -static const uint32 kClass490FileHashes[] = { -	0x08100071, -	0x24084215, -	0x18980A10 -}; - -static const int16 kClass490FrameIndices1[] = { -	0, 8, 15, 19 -}; - -static const int16 kClass490FrameIndices2[] = { -	0, 4, 8, 11, 15, 17, 19, 0 -}; - -SsScene2808Dispenser::SsScene2808Dispenser(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum, int testTubeIndex) -	: StaticSprite(vm, 900), _parentScene(parentScene), _countdown(0), _testTubeSetNum(testTubeSetNum), -	_testTubeIndex(testTubeIndex) { - -	loadSprite(kClass428FileHashes[testTubeSetNum * 3 + testTubeIndex], kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 1500); -	setVisible(false); -	SetUpdateHandler(&SsScene2808Dispenser::update); -	SetMessageHandler(&SsScene2808Dispenser::handleMessage); -} - -void SsScene2808Dispenser::update() { -	updatePosition(); -	if (_countdown != 0 && (--_countdown) == 0) { -		setVisible(false); -	} -} - -uint32 SsScene2808Dispenser::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x1011: -		sendMessage(_parentScene, 0x2000, _testTubeIndex); -		messageResult = 1; -		break; -	} -	return messageResult; -} - -void SsScene2808Dispenser::startCountdown(int index) { -	setVisible(true); -	updatePosition(); -	if (_testTubeSetNum == 0) { -		_countdown = kClass428Countdowns1[index]; -	} else { -		_countdown = kClass428Countdowns2[index]; -	} -} - -AsScene2808TestTube::AsScene2808TestTube(NeverhoodEngine *vm, int testTubeSetNum, int testTubeIndex, SsScene2808Dispenser *ssDispenser) -	: AnimatedSprite(vm, 1100), _testTubeSetNum(testTubeSetNum), _testTubeIndex(testTubeIndex), _ssDispenser(ssDispenser), _fillLevel(0) { - -	if (testTubeSetNum == 0) { -		_x = 504; -		_y = 278; -	} else { -		setDoDeltaX(1); -		_x = 136; -		_y = 278; -	} - -	createSurface1(kClass490FileHashes[testTubeIndex], 1100); - -	if (testTubeSetNum == 0) { -		loadSound(0, 0x30809E2D); -		loadSound(1, 0x72811E2D); -		loadSound(2, 0x78B01625); -	} else { -		loadSound(3, 0x70A41E0C); -		loadSound(4, 0x50205E2D); -		loadSound(5, 0xF8621E2D); -		loadSound(6, 0xF1A03C2D); -		loadSound(7, 0x70A43D2D); -		loadSound(8, 0xF0601E2D); -	} - -	startAnimation(kClass490FileHashes[testTubeIndex], 0, -1); -	_newStickFrameIndex = 0; - -	SetUpdateHandler(&AnimatedSprite::update); -	SetMessageHandler(&AsScene2808TestTube::handleMessage); - -	if (_fillLevel == 0) -		setVisible(false); - -} - -uint32 AsScene2808TestTube::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x1011: -		fill(); -		messageResult = 1; -		break; -	} -	return messageResult; -} - -void AsScene2808TestTube::fill() { -	if ((int)_fillLevel < _testTubeSetNum * 3 + 3) { -		if (_testTubeSetNum == 0) { -			playSound(_fillLevel); -			setVisible(true); -			startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices1[_fillLevel], kClass490FrameIndices1[_fillLevel + 1]); -			_newStickFrameIndex = kClass490FrameIndices1[_fillLevel + 1]; -		} else { -			playSound(3 + _fillLevel); -			setVisible(true); -			startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices2[_fillLevel], kClass490FrameIndices2[_fillLevel + 1]); -			_newStickFrameIndex = kClass490FrameIndices2[_fillLevel + 1]; -		} -		_ssDispenser->startCountdown(_fillLevel); -		_fillLevel++; -	} -} - -void AsScene2808TestTube::flush() { -	if (_fillLevel != 0) { -		if (_testTubeSetNum == 0) { -			startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices1[_fillLevel], -1); -		} else { -			startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices2[_fillLevel], -1); -		} -		_newStickFrameIndex = 0; -		_playBackwards = true; -		setVisible(true); -	} -} - -AsScene2808Handle::AsScene2808Handle(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum) -	: AnimatedSprite(vm, 1300), _parentScene(parentScene), _testTubeSetNum(testTubeSetNum), _isActivated(false) { - -	loadSound(0, 0xE18D1F30); -	_x = 320; -	_y = 240; -	if (_testTubeSetNum == 1) -		setDoDeltaX(1); -	createSurface1(0x040900D0, 1300); -	startAnimation(0x040900D0, 0, -1); -	_needRefresh = true; -	_newStickFrameIndex = 0; -	SetUpdateHandler(&AnimatedSprite::update); -	SetMessageHandler(&AsScene2808Handle::handleMessage); -	AnimatedSprite::updatePosition(); -} - -uint32 AsScene2808Handle::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x1011: -		if (!_isActivated) { -			sendMessage(_parentScene, 0x2001, 0); -			playSound(0); -			activate(); -		} -		messageResult = 1; -		break; -	} -	return messageResult; -} - -uint32 AsScene2808Handle::hmActivating(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x3002: -		gotoNextState(); -		break; -	} -	return messageResult; -} - -void AsScene2808Handle::activate() { -	startAnimation(0x040900D0, 0, -1); -	SetMessageHandler(&AsScene2808Handle::hmActivating); -	NextState(&AsScene2808Handle::stActivated); -	_isActivated = true; -	_newStickFrameIndex = -1; -} - -void AsScene2808Handle::stActivated() { -	stopAnimation(); -	sendMessage(_parentScene, 0x2002, 0); -} - -AsScene2808Flow::AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum) -	: AnimatedSprite(vm, 1100), _parentScene(parentScene), _testTubeSetNum(testTubeSetNum) { - -	if (testTubeSetNum == 0) { -		_x = 312; -		_y = 444; -	} else { -		_x = 328; -		_y = 444; -	} -	createSurface1(0xB8414818, 1200); -	startAnimation(0xB8414818, 0, -1); -	setVisible(false); -	_newStickFrameIndex = 0; -	_needRefresh = true; -	loadSound(0, 0x6389B652); -	SetUpdateHandler(&AnimatedSprite::update); -	AnimatedSprite::updatePosition(); -} - -uint32 AsScene2808Flow::hmFlowing(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x3002: -		gotoNextState(); -		break; -	} -	return messageResult; -} - -void AsScene2808Flow::start() { -	startAnimation(0xB8414818, 0, -1); -	setVisible(true); -	SetMessageHandler(&AsScene2808Flow::hmFlowing); -	NextState(&AsScene2808Flow::stKeepFlowing); -	playSound(0); -} - -void AsScene2808Flow::stKeepFlowing() { -	startAnimation(0xB8414818, 1, -1); -	NextState(&AsScene2808Flow::stKeepFlowing); -} - -AsScene2808LightEffect::AsScene2808LightEffect(NeverhoodEngine *vm, int testTubeSetNum) -	: AnimatedSprite(vm, 800), _countdown(1) { - -	_x = 320; -	_y = 240; -	if (testTubeSetNum == 1) -		setDoDeltaX(1); -	createSurface1(0x804C2404, 800); -	SetUpdateHandler(&AsScene2808LightEffect::update); -	_needRefresh = true; -	AnimatedSprite::updatePosition(); -} - -void AsScene2808LightEffect::update() { -	if (_countdown != 0 && (--_countdown) == 0) { -		int16 frameIndex = _vm->_rnd->getRandomNumber(3 - 1); -		startAnimation(0x804C2404, frameIndex, frameIndex); -		updateAnim(); -		updatePosition(); -		_countdown = _vm->_rnd->getRandomNumber(3 - 1) + 1; -	} -} -  Scene2808::Scene2808(NeverhoodEngine *vm, Module *parentModule, int which)  	: Scene(vm, parentModule), _countdown(0), _testTubeSetNum(which), _leaveResult(0), _isFlowing(false) { @@ -2422,34 +1613,6 @@ bool Scene2808::isAnyTestTubeFilled() {  		_asTestTubes[2]->getFillLevel() > 0;  } -AsScene2809Spew::AsScene2809Spew(NeverhoodEngine *vm) -	: AnimatedSprite(vm, 1200) { - -	SetUpdateHandler(&AnimatedSprite::update); -	SetMessageHandler(&AsScene2809Spew::handleMessage); -	createSurface1(0x04211490, 1200); -	_x = 262; -	_y = 423; -	setDoDeltaX(0); -	setVisible(false); -} - -uint32 AsScene2809Spew::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x2000: -		playSound(0, 0x48640244); -		startAnimation(0x04211490, 0, -1); -		setVisible(true); -		break; -	case 0x3002: -		stopAnimation(); -		setVisible(false); -		break; -	} -	return messageResult; -} -  Scene2809::Scene2809(NeverhoodEngine *vm, Module *parentModule, int which)  	: Scene(vm, parentModule) { @@ -2569,34 +1732,6 @@ void Scene2809::findClosestPoint() {  } -AsScene2810Rope::AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x) -	: AnimatedSprite(vm, 1100) { - -	createSurface(990, 68, 476); -	SetUpdateHandler(&AnimatedSprite::update); -	SetMessageHandler(&AsScene2810Rope::handleMessage); -	SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); -	_x = x; -	_y = -276; -	startAnimation(0x9D098C23, 35, 53); -} - -uint32 AsScene2810Rope::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x3002: -		startAnimation(0x9D098C23, 35, 53); -		break; -	case 0x482A: -		sendMessage(_parentScene, 0x1022, 990); -		break; -	case 0x482B: -		sendMessage(_parentScene, 0x1022, 1010); -		break; -	} -	return messageResult; -} -  Scene2810::Scene2810(NeverhoodEngine *vm, Module *parentModule, int which)  	: Scene(vm, parentModule) { @@ -2818,101 +1953,6 @@ uint32 Scene2810::handleMessage(int messageNum, const MessageParam ¶m, Entit  	return messageResult;  } -AsScene2812Winch::AsScene2812Winch(NeverhoodEngine *vm) -	: AnimatedSprite(vm, 1100) { - -	createSurface1(0x20DA08A0, 1200); -	SetUpdateHandler(&AnimatedSprite::update); -	SetMessageHandler(&AsScene2812Winch::handleMessage); -	setVisible(false); -	_x = 280; -	_y = 184; -} - -AsScene2812Winch::~AsScene2812Winch() { -	_vm->_soundMan->deleteSoundGroup(0x00B000E2); -} - -uint32 AsScene2812Winch::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x2000: -		startAnimation(0x20DA08A0, 0, -1); -		setVisible(true); -		_vm->_soundMan->addSound(0x00B000E2, 0xC874EE6C); -		_vm->_soundMan->playSoundLooping(0xC874EE6C); -		break; -	case 0x3002: -		startAnimation(0x20DA08A0, 7, -1); -		break; -	} -	return messageResult; -} - -AsScene2812Rope::AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene) -	: AnimatedSprite(vm, 1100), _parentScene(parentScene) { - -	createSurface(990, 68, 476); -	SetUpdateHandler(&AnimatedSprite::update); -	SetMessageHandler(&AsScene2812Rope::handleMessage); -	SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); -	startAnimation(0xAE080551, 0, -1); -	_x = 334; -	_y = 201; -} - -uint32 AsScene2812Rope::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x4806: -		setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0); -		stRopingDown(); -		break; -	case 0x482A: -		sendMessage(_parentScene, 0x1022, 990); -		break; -	case 0x482B: -		sendMessage(_parentScene, 0x1022, 1010); -		break; -	} -	return messageResult; -} - -uint32 AsScene2812Rope::hmRopingDown(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x3002: -		gotoNextState(); -		break; -	} -	return messageResult; -} - -void AsScene2812Rope::stRopingDown() { -	sendMessage(_parentScene, 0x4806, 0); -	startAnimation(0x9D098C23, 0, -1); -	SetMessageHandler(&AsScene2812Rope::hmRopingDown); -} - -AsScene2812TrapDoor::AsScene2812TrapDoor(NeverhoodEngine *vm) -	: AnimatedSprite(vm, 0x805D0029, 100, 320, 240) { - -	SetMessageHandler(&AsScene2812TrapDoor::handleMessage); -	_newStickFrameIndex = 0; -} - -uint32 AsScene2812TrapDoor::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { -	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); -	switch (messageNum) { -	case 0x2000: -		startAnimation(0x805D0029, 0, -1); -		playSound(0, 0xEA005F40); -		_newStickFrameIndex = STICK_LAST_FRAME; -		break; -	} -	return messageResult; -} -  Scene2812::Scene2812(NeverhoodEngine *vm, Module *parentModule, int which)  	: Scene(vm, parentModule), _paletteArea(0) { diff --git a/engines/neverhood/modules/module2800.h b/engines/neverhood/modules/module2800.h index 54a9daeb16..26e44bc543 100644 --- a/engines/neverhood/modules/module2800.h +++ b/engines/neverhood/modules/module2800.h @@ -70,38 +70,7 @@ protected:  	void changeTuneStatus(int prevTuneStatus, int newTuneStatus);  }; -class AsScene2803LightCord : public AnimatedSprite { -public: -	AsScene2803LightCord(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int16 x, int16 y); -	void stPulled(); -	void stIdle(); -	void setFileHashes(uint32 fileHash1, uint32 fileHash2); -protected: -	Scene *_parentScene; -	uint32 _fileHash1, _fileHash2; -	bool _isPulled, _isBusy; -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -	uint32 hmPulled(int messageNum, const MessageParam ¶m, Entity *sender); -}; - -class AsScene2803TestTubeOne : public AnimatedSprite { -public: -	AsScene2803TestTubeOne(NeverhoodEngine *vm, uint32 fileHash1, uint32 fileHash2); -protected: -	uint32 _fileHash1, _fileHash2; -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -}; - -class AsScene2803Rope : public AnimatedSprite { -public: -	AsScene2803Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x); -protected: -	Scene *_parentScene; -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -	uint32 hmReleased(int messageNum, const MessageParam ¶m, Entity *sender); -	void stReleased(); -	void stHide(); -}; +class AsScene2803LightCord;  class Scene2803 : public Scene {  public: @@ -158,101 +127,8 @@ protected:  	void updatePaletteArea(bool instantly);  }; -class Scene2804; - -class SsScene2804RedButton : public StaticSprite { -public: -	SsScene2804RedButton(NeverhoodEngine *vm, Scene2804 *parentScene); -protected: -	Scene2804 *_parentScene; -	int _countdown; -	void update(); -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -}; - -class SsScene2804LightCoil : public StaticSprite { -public: -	SsScene2804LightCoil(NeverhoodEngine *vm); -protected: -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -}; - -class SsScene2804BeamCoilBody : public StaticSprite { -public: -	SsScene2804BeamCoilBody(NeverhoodEngine *vm); -}; - -class SsScene2804LightTarget : public StaticSprite { -public: -	SsScene2804LightTarget(NeverhoodEngine *vm); -protected: -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -}; - -class SsScene2804Flash : public StaticSprite { -public: -	SsScene2804Flash(NeverhoodEngine *vm); -	void show(); -}; - -class AsScene2804CrystalWaves : public AnimatedSprite { -public: -	AsScene2804CrystalWaves(NeverhoodEngine *vm, uint crystalIndex); -	void show(); -	void hide(); -protected: -	uint _crystalIndex; -}; - -class AsScene2804Crystal : public AnimatedSprite { -public: -	AsScene2804Crystal(NeverhoodEngine *vm, AsScene2804CrystalWaves *asCrystalWaves, uint crystalIndex); -	void show(); -	void hide(); -	void activate(); -	int16 getColorNum() const { return _colorNum; } -protected: -	AsScene2804CrystalWaves *_asCrystalWaves; -	uint _crystalIndex; -	int16 _colorNum; -	bool _isLightOn; -	bool _isShowing; -}; - -class SsScene2804CrystalButton : public StaticSprite { -public: -	SsScene2804CrystalButton(NeverhoodEngine *vm, Scene2804 *parentScene, AsScene2804Crystal *asCrystal, uint crystalIndex); -protected: -	Scene2804 *_parentScene; -	AsScene2804Crystal *_asCrystal; -	uint _crystalIndex; -	int _countdown; -	void update(); -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -}; - -class AsScene2804BeamCoil : public AnimatedSprite { -public: -	AsScene2804BeamCoil(NeverhoodEngine *vm, Scene *parentScene, SsScene2804BeamCoilBody *ssBeamCoilBody); -	virtual ~AsScene2804BeamCoil(); -protected: -	Scene *_parentScene; -	SsScene2804BeamCoilBody *_ssBeamCoilBody; -	int _countdown; -	void update(); -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -	void show(); -	void hide(); -	void stBeaming(); -	uint32 hmBeaming(int messageNum, const MessageParam ¶m, Entity *sender); -}; - -class AsScene2804BeamTarget : public AnimatedSprite { -public: -	AsScene2804BeamTarget(NeverhoodEngine *vm); -protected: -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -}; +class SsScene2804Flash; +class AsScene2804Crystal;  class Scene2804 : public Scene {  public: @@ -284,13 +160,6 @@ protected:  	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);  }; -class AsScene2806Spew : public AnimatedSprite { -public: -	AsScene2806Spew(NeverhoodEngine *vm); -protected: -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -}; -  class Scene2806 : public Scene {  public:  	Scene2806(NeverhoodEngine *vm, Module *parentModule, int which); @@ -315,63 +184,8 @@ protected:  	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender);  }; -class SsScene2808Dispenser : public StaticSprite { -public: -	SsScene2808Dispenser(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum, int testTubeIndex); -	void startCountdown(int index); -protected: -	Scene *_parentScene; -	int _countdown; -	int _testTubeSetNum, _testTubeIndex; -	void update(); -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -}; - -class AsScene2808TestTube : public AnimatedSprite { -public: -	AsScene2808TestTube(NeverhoodEngine *vm, int testTubeSetNum, int testTubeIndex, SsScene2808Dispenser *ssDispenser); -	void fill(); -	void flush(); -	uint32 getFillLevel() const { return _fillLevel; } -protected: -	SsScene2808Dispenser *_ssDispenser; -	int _testTubeSetNum; -	uint32 _fillLevel; -	int _testTubeIndex; -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -}; - -class AsScene2808Handle : public AnimatedSprite { -public: -	AsScene2808Handle(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum); -	void activate(); -	void stActivated(); -protected: -	Scene *_parentScene; -	int _testTubeSetNum; -	bool _isActivated; -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -	uint32 hmActivating(int messageNum, const MessageParam ¶m, Entity *sender); -}; - -class AsScene2808Flow : public AnimatedSprite { -public: -	AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum); -	void start(); -	void stKeepFlowing(); -protected: -	Scene *_parentScene; -	int _testTubeSetNum; -	uint32 hmFlowing(int messageNum, const MessageParam ¶m, Entity *sender); -}; - -class AsScene2808LightEffect : public AnimatedSprite { -public: -	AsScene2808LightEffect(NeverhoodEngine *vm, int which); -protected: -	int _countdown; -	void update(); -}; +class AsScene2808Flow; +class AsScene2808TestTube;  class Scene2808 : public Scene {  public: @@ -389,13 +203,6 @@ protected:  	bool isAnyTestTubeFilled();  }; -class AsScene2809Spew : public AnimatedSprite { -public: -	AsScene2809Spew(NeverhoodEngine *vm); -protected: -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -}; -  class Scene2809 : public Scene {  public:  	Scene2809(NeverhoodEngine *vm, Module *parentModule, int which); @@ -413,14 +220,6 @@ protected:  	void findClosestPoint();  }; -class AsScene2810Rope : public AnimatedSprite { -public: -	AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x); -protected: -	Scene *_parentScene; -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -}; -  class Scene2810 : public Scene {  public:  	Scene2810(NeverhoodEngine *vm, Module *parentModule, int which); @@ -440,31 +239,6 @@ protected:  	void insertKlaymenLadder();  }; -class AsScene2812Winch : public AnimatedSprite { -public: -	AsScene2812Winch(NeverhoodEngine *vm); -	virtual ~AsScene2812Winch(); -protected: -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -}; - -class AsScene2812Rope : public AnimatedSprite { -public: -	AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene); -protected: -	Scene *_parentScene; -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -	uint32 hmRopingDown(int messageNum, const MessageParam ¶m, Entity *sender); -	void stRopingDown(); -}; - -class AsScene2812TrapDoor : public AnimatedSprite { -public: -	AsScene2812TrapDoor(NeverhoodEngine *vm); -protected: -	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); -}; -  class Scene2812 : public Scene {  public:  	Scene2812(NeverhoodEngine *vm, Module *parentModule, int which); diff --git a/engines/neverhood/modules/module2800_sprites.cpp b/engines/neverhood/modules/module2800_sprites.cpp new file mode 100644 index 0000000000..28e2657ee7 --- /dev/null +++ b/engines/neverhood/modules/module2800_sprites.cpp @@ -0,0 +1,1020 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "neverhood/modules/module2800.h" +#include "neverhood/modules/module2800_sprites.h" +#include "neverhood/gamemodule.h" +#include "neverhood/modules/module1000.h" +#include "neverhood/modules/module1200.h" +#include "neverhood/modules/module1700.h" +#include "neverhood/modules/module2200.h" +#include "neverhood/diskplayerscene.h" + +namespace Neverhood { + +AsScene2803LightCord::AsScene2803LightCord(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int16 x, int16 y) +	: AnimatedSprite(vm, 1100), _parentScene(parentScene), _fileHash1(fileHash1), _fileHash2(fileHash2), +	_isPulled(false), _isBusy(false) { + +	createSurface(1010, 28, 379); +	SetUpdateHandler(&AnimatedSprite::update); +	SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); +	_x = x; +	_y = y; +	stIdle(); +} + +uint32 AsScene2803LightCord::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x100D: +		if (!_isBusy && param.asInteger() == calcHash("ClickSwitch")) { +			sendMessage(_parentScene, 0x480F, 0); +			playSound(0, 0x4E1CA4A0); +		} +		break; +	case 0x480F: +		stPulled(); +		break; +	case 0x482A: +		sendMessage(_parentScene, 0x1022, 990); +		break; +	case 0x482B: +		sendMessage(_parentScene, 0x1022, 1010); +		break; +	} +	return messageResult; +} + +uint32 AsScene2803LightCord::hmPulled(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x3002: +		gotoNextState(); +		break; +	} +	return messageResult; +} + +void AsScene2803LightCord::stPulled() { +	_isBusy = false; +	_isPulled = true; +	startAnimation(_fileHash2, 0, -1); +	SetMessageHandler(&AsScene2803LightCord::hmPulled); +	NextState(&AsScene2803LightCord::stIdle); +} + +void AsScene2803LightCord::stIdle() { +	_isPulled = false; +	startAnimation(_fileHash1, 0, -1); +	SetMessageHandler(&AsScene2803LightCord::handleMessage); +} + +void AsScene2803LightCord::setFileHashes(uint32 fileHash1, uint32 fileHash2) { +	_fileHash1 = fileHash1; +	_fileHash2 = fileHash2; +	if (_isPulled) { +		startAnimation(_fileHash2, _currFrameIndex, -1); +		_isBusy = true; +	} else { +		startAnimation(_fileHash1, 0, -1); +	} +} + +AsScene2803TestTubeOne::AsScene2803TestTubeOne(NeverhoodEngine *vm, uint32 fileHash1, uint32 fileHash2) +	: AnimatedSprite(vm, 1200), _fileHash1(fileHash1), _fileHash2(fileHash2) { + +	createSurface1(fileHash1, 100); +	SetUpdateHandler(&AnimatedSprite::update); +	SetMessageHandler(&AsScene2803TestTubeOne::handleMessage); +	_x = 529; +	_y = 326; +} + +uint32 AsScene2803TestTubeOne::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x2000: +		if (param.asInteger()) +			startAnimation(_fileHash2, 0, -1); +		else +			startAnimation(_fileHash1, 0, -1); +		break; +	} +	return messageResult; +} + +AsScene2803Rope::AsScene2803Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x) +	: AnimatedSprite(vm, 1100), _parentScene(parentScene) { + +	createSurface(990, 68, 476); +	SetUpdateHandler(&AnimatedSprite::update); +	SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); +	SetMessageHandler(&AsScene2803Rope::handleMessage); +	startAnimation(0x9D098C23, 35, 53); +	NextState(&AsScene2803Rope::stReleased); +	_x = x; +	_y = -276; +} + +uint32 AsScene2803Rope::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x3002: +		startAnimation(0x9D098C23, 50, -1); +		SetMessageHandler(&AsScene2803Rope::hmReleased); +		break; +	case 0x482A: +		sendMessage(_parentScene, 0x1022, 990); +		break; +	case 0x482B: +		sendMessage(_parentScene, 0x1022, 1010); +		break; +	} +	return messageResult; +} + +uint32 AsScene2803Rope::hmReleased(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x3002: +		gotoNextState(); +		break; +	case 0x482A: +		sendMessage(_parentScene, 0x1022, 990); +		break; +	case 0x482B: +		sendMessage(_parentScene, 0x1022, 1010); +		break; +	} +	return messageResult; +} + +void AsScene2803Rope::stReleased() { +	startAnimation(0x8258A030, 0, 1); +	NextState(&AsScene2803Rope::stHide); +} + +void AsScene2803Rope::stHide() { +	stopAnimation(); +	setVisible(false); +} + +SsScene2804RedButton::SsScene2804RedButton(NeverhoodEngine *vm, Scene2804 *parentScene) +	: StaticSprite(vm, 900), _countdown(0), _parentScene(parentScene) { + +	loadSprite(getGlobalVar(V_SHRINK_LIGHTS_ON) ? 0x51A10202 : 0x11814A21, kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400); +	setVisible(false); +	SetUpdateHandler(&SsScene2804RedButton::update); +	SetMessageHandler(&SsScene2804RedButton::handleMessage); +	loadSound(0, 0x44241240); +} + +void SsScene2804RedButton::update() { +	updatePosition(); +	if (_countdown != 0 && (--_countdown) == 0) { +		setVisible(false); +	} +} + +uint32 SsScene2804RedButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x1011: +		if (_countdown == 0 && !_parentScene->isWorking()) { +			playSound(0); +			setVisible(true); +			_countdown = 4; +			sendMessage(_parentScene, 0x2000, 0); +		} +		messageResult = 1; +		break; +	} +	return messageResult; +} + +SsScene2804LightCoil::SsScene2804LightCoil(NeverhoodEngine *vm) +	: StaticSprite(vm, 900) { + +	loadSprite(0x8889B008, kSLFDefDrawOffset | kSLFDefPosition, 400); +	setVisible(false); +	SetMessageHandler(&SsScene2804LightCoil::handleMessage); +} + +uint32 SsScene2804LightCoil::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x2002: +		setVisible(true); +		updatePosition(); +		messageResult = 1; +		break; +	case 0x2003: +		setVisible(false); +		updatePosition(); +		messageResult = 1; +		break; +	} +	return messageResult; +} + +SsScene2804LightTarget::SsScene2804LightTarget(NeverhoodEngine *vm) +	: StaticSprite(vm, 900) { + +	loadSprite(0x06092132, kSLFDefDrawOffset | kSLFDefPosition, 400); +	setVisible(false); +	SetMessageHandler(&SsScene2804LightTarget::handleMessage); +} + +uint32 SsScene2804LightTarget::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x2004: +		setVisible(true); +		updatePosition(); +		messageResult = 1; +		break; +	case 0x2005: +		setVisible(false); +		updatePosition(); +		messageResult = 1; +		break; +	} +	return messageResult; +} + +SsScene2804Flash::SsScene2804Flash(NeverhoodEngine *vm) +	: StaticSprite(vm, 900) { + +	loadSprite(0x211003A0, kSLFDefDrawOffset | kSLFDefPosition, 400); +	setVisible(false); +	loadSound(0, 0xCB36BA54); +} + +void SsScene2804Flash::show() { +	setVisible(true); +	updatePosition(); +	playSound(0); +} + +SsScene2804BeamCoilBody::SsScene2804BeamCoilBody(NeverhoodEngine *vm) +	: StaticSprite(vm, 900) { + +	loadSprite(0x9A816000, kSLFDefDrawOffset | kSLFDefPosition, 400); +	setVisible(false); +} + +AsScene2804CrystalWaves::AsScene2804CrystalWaves(NeverhoodEngine *vm, uint crystalIndex) +	: AnimatedSprite(vm, 1100), _crystalIndex(crystalIndex) { + +	static const NPoint kAsScene2804CrystalWavesPoints[] = { +		{323, 245}, +		{387, 76}, +		{454, 260}, +		{527, 70} +	}; + +	_x = kAsScene2804CrystalWavesPoints[crystalIndex].x; +	_y = kAsScene2804CrystalWavesPoints[crystalIndex].y; +	createSurface1(0x840C41F0, 1200); +	if (crystalIndex & 1) +		setDoDeltaY(1); +	setVisible(false); +	_needRefresh = true; +	SetUpdateHandler(&AnimatedSprite::update); +	SetMessageHandler(&Sprite::handleMessage); +} + +void AsScene2804CrystalWaves::show() { +	setVisible(true); +	startAnimation(0x840C41F0, 0, -1); +} + +void AsScene2804CrystalWaves::hide() { +	setVisible(false); +	stopAnimation(); +} + +static const int16 kAsScene2804CrystalFrameNums[] = { +	0, 6, 2, 8, 1, 10, 0, 0 +}; + +static const uint32 kAsScene2804CrystalFileHashes[] = { +	0x000540B0, +	0x001280D0, +	0x003D0010, +	0x00620190, +	0x00DC0290 +}; + +AsScene2804Crystal::AsScene2804Crystal(NeverhoodEngine *vm, AsScene2804CrystalWaves *asCrystalWaves, uint crystalIndex) +	: AnimatedSprite(vm, 1100), _asCrystalWaves(asCrystalWaves), _crystalIndex(crystalIndex), _isShowing(false) { + +	static const NPoint kAsScene2804CrystalPoints[] = { +		{204, 196}, +		{272, 316}, +		{334, 206}, +		{410, 334}, +		{470, 180} +	}; + +	_colorNum = (int16)getSubVar(VA_CURR_CRYSTAL_COLORS, crystalIndex); +	_isLightOn = getGlobalVar(V_SHRINK_LIGHTS_ON) != 0; +	if (_isLightOn) { +		_x = kAsScene2804CrystalPoints[crystalIndex].x; +		_y = kAsScene2804CrystalPoints[crystalIndex].y; +		createSurface1(0x108DFB12, 1200); +		startAnimation(0x108DFB12, kAsScene2804CrystalFrameNums[_colorNum], -1); +		_needRefresh = true; +		_newStickFrameIndex = kAsScene2804CrystalFrameNums[_colorNum]; +	} else { +		_x = 320; +		_y = 240; +		createSurface1(kAsScene2804CrystalFileHashes[crystalIndex], 1200); +		startAnimation(kAsScene2804CrystalFileHashes[crystalIndex], _colorNum, -1); +		setVisible(false); +		_needRefresh = true; +		_newStickFrameIndex = _colorNum; +	} +	loadSound(0, 0x725294D4); +	SetUpdateHandler(&AnimatedSprite::update); +} + +void AsScene2804Crystal::show() { +	if (!_isLightOn) { +		setVisible(true); +		_isShowing = true; +		if (_asCrystalWaves) +			_asCrystalWaves->show(); +		playSound(0); +	} +} + +void AsScene2804Crystal::hide() { +	if (!_isLightOn) { +		setVisible(false); +		_isShowing = false; +		if (_asCrystalWaves) +			_asCrystalWaves->hide(); +	} +} + +void AsScene2804Crystal::activate() { +	if (!_isShowing) { +		int16 frameNum = kAsScene2804CrystalFrameNums[_colorNum]; +		_colorNum++; +		if (_colorNum >= 6) +			_colorNum = 0; +		if (_isLightOn) { +			startAnimation(0x108DFB12, frameNum, kAsScene2804CrystalFrameNums[_colorNum]); +			_playBackwards = kAsScene2804CrystalFrameNums[_colorNum] < _colorNum; +			_newStickFrameIndex = kAsScene2804CrystalFrameNums[_colorNum]; +		} else { +			startAnimation(kAsScene2804CrystalFileHashes[_crystalIndex], _colorNum, -1); +			_newStickFrameIndex = _colorNum; +		} +		setSubVar(VA_CURR_CRYSTAL_COLORS, _crystalIndex, _colorNum); +	} +} + +SsScene2804CrystalButton::SsScene2804CrystalButton(NeverhoodEngine *vm, Scene2804 *parentScene, AsScene2804Crystal *asCrystal, uint crystalIndex) +	: StaticSprite(vm, 900), _countdown(0), _parentScene(parentScene), _asCrystal(asCrystal), _crystalIndex(crystalIndex) { + +	static const uint32 kSsScene2804CrystalButtonFileHashes1[] = { +		0x911101B0, +		0x22226001, +		0x4444A362, +		0x888925A4, +		0x11122829 +	}; + +	static const uint32 kSsScene2804CrystalButtonFileHashes2[] = { +		0xB500A1A0, +		0x6A012021, +		0xD4022322, +		0xA8042525, +		0x5008292B +	}; + +	loadSprite(getGlobalVar(V_SHRINK_LIGHTS_ON) ? kSsScene2804CrystalButtonFileHashes1[crystalIndex] : kSsScene2804CrystalButtonFileHashes2[crystalIndex], +		kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 400); +	setVisible(false); +	loadSound(0, 0x44045140); +	SetUpdateHandler(&SsScene2804CrystalButton::update); +	SetMessageHandler(&SsScene2804CrystalButton::handleMessage); +} + +void SsScene2804CrystalButton::update() { +	updatePosition(); +	if (_countdown != 0 && (--_countdown) == 0) { +		setVisible(false); +	} +} + +uint32 SsScene2804CrystalButton::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x1011: +		if (_countdown == 0 && !_parentScene->isWorking()) { +			playSound(0); +			setVisible(true); +			_countdown = 4; +			_asCrystal->activate(); +		} +		messageResult = 1; +		break; +	} +	return messageResult; +} + +AsScene2804BeamCoil::AsScene2804BeamCoil(NeverhoodEngine *vm, Scene *parentScene, SsScene2804BeamCoilBody *ssBeamCoilBody) +	: AnimatedSprite(vm, 1400), _parentScene(parentScene), _ssBeamCoilBody(ssBeamCoilBody), _countdown(0) { + +	createSurface1(0x00494891, 1000); +	_x = 125; +	_y = 184; +	setVisible(false); +	_needRefresh = true; +	AnimatedSprite::updatePosition(); +	loadSound(0, 0x6352F051); +	_vm->_soundMan->addSound(0xC5EA0B28, 0xEF56B094); +	SetUpdateHandler(&AsScene2804BeamCoil::update); +	SetMessageHandler(&AsScene2804BeamCoil::handleMessage); +} + +AsScene2804BeamCoil::~AsScene2804BeamCoil() { +	_vm->_soundMan->deleteSoundGroup(0xC5EA0B28); +} + +void AsScene2804BeamCoil::update() { +	updateAnim(); +	updatePosition(); +	if (_countdown != 0 && (--_countdown) == 0) { +		sendMessage(_parentScene, 0x2001, 0); +	} +} + +uint32 AsScene2804BeamCoil::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x2002: +		show(); +		_countdown = 92; +		messageResult = 1; +		break; +	case 0x2003: +		hide(); +		messageResult = 1; +		break; +	} +	return messageResult; +} + +void AsScene2804BeamCoil::show() { +	_ssBeamCoilBody->setVisible(true); +	setVisible(true); +	startAnimation(0x00494891, 0, -1); +	playSound(0); +	SetMessageHandler(&AsScene2804BeamCoil::hmBeaming); +	NextState(&AsScene2804BeamCoil::stBeaming); +} + +void AsScene2804BeamCoil::hide() { +	stopAnimation(); +	SetMessageHandler(&AsScene2804BeamCoil::handleMessage); +	setVisible(false); +	_ssBeamCoilBody->setVisible(false); +	_vm->_soundMan->stopSound(0xEF56B094); +} + +void AsScene2804BeamCoil::stBeaming() { +	startAnimation(0x00494891, 93, -1); +	NextState(&AsScene2804BeamCoil::stBeaming); +	_vm->_soundMan->playSoundLooping(0xEF56B094); +} + +uint32 AsScene2804BeamCoil::hmBeaming(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x3002: +		gotoNextState(); +		break; +	} +	return messageResult; +} + +AsScene2804BeamTarget::AsScene2804BeamTarget(NeverhoodEngine *vm) +	: AnimatedSprite(vm, 1400) { + +	createSurface1(0x03842000, 1000); +	_x = 475; +	_y = 278; +	setVisible(false); +	_needRefresh = true; +	updatePosition(); +	SetUpdateHandler(&AnimatedSprite::update); +	SetMessageHandler(&AsScene2804BeamTarget::handleMessage); +} + +uint32 AsScene2804BeamTarget::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x2004: +		setVisible(true); +		startAnimation(0x03842000, 0, -1); +		messageResult = 1; +		break; +	case 0x2005: +		setVisible(false); +		stopAnimation(); +		messageResult = 1; +		break; +	} +	return messageResult; +} + +AsScene2806Spew::AsScene2806Spew(NeverhoodEngine *vm) +	: AnimatedSprite(vm, 1200) { + +	createSurface1(0x04211490, 1200); +	_x = 378; +	_y = 423; +	SetUpdateHandler(&AnimatedSprite::update); +	SetMessageHandler(&AsScene2806Spew::handleMessage); +	setDoDeltaX(1); +	setVisible(false); +} + +uint32 AsScene2806Spew::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x2000: +		playSound(0, 0x48640244); +		startAnimation(0x04211490, 0, -1); +		setVisible(true); +		break; +	case 0x3002: +		stopAnimation(); +		setVisible(false); +		break; +	} +	return messageResult; +} + +static const uint32 kScene2808FileHashes1[] = { +	0x90B0392, +	0x90B0192 +}; + +static const uint32 kScene2808FileHashes2[] = { +	0xB0396098, +	0xB0196098 +}; + +static const uint32 kClass428FileHashes[] = { +	0x140022CA, +	0x4C30A602, +	0xB1633402, +	0x12982135, +	0x0540B728, +	0x002A81E3, +	0x08982841, +	0x10982841, +	0x20982841, +	0x40982841, +	0x80982841, +	0x40800711 +}; + +static const int kClass428Countdowns1[] = { +	18, 16, 10, 0 +}; + +static const int kClass428Countdowns2[] = { +	9, 9, 8, 8, 5, 5, 0, 0 +}; + +static const uint32 kClass490FileHashes[] = { +	0x08100071, +	0x24084215, +	0x18980A10 +}; + +static const int16 kClass490FrameIndices1[] = { +	0, 8, 15, 19 +}; + +static const int16 kClass490FrameIndices2[] = { +	0, 4, 8, 11, 15, 17, 19, 0 +}; + +SsScene2808Dispenser::SsScene2808Dispenser(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum, int testTubeIndex) +	: StaticSprite(vm, 900), _parentScene(parentScene), _countdown(0), _testTubeSetNum(testTubeSetNum), +	_testTubeIndex(testTubeIndex) { + +	loadSprite(kClass428FileHashes[testTubeSetNum * 3 + testTubeIndex], kSLFDefDrawOffset | kSLFDefPosition | kSLFDefCollisionBoundsOffset, 1500); +	setVisible(false); +	SetUpdateHandler(&SsScene2808Dispenser::update); +	SetMessageHandler(&SsScene2808Dispenser::handleMessage); +} + +void SsScene2808Dispenser::update() { +	updatePosition(); +	if (_countdown != 0 && (--_countdown) == 0) { +		setVisible(false); +	} +} + +uint32 SsScene2808Dispenser::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x1011: +		sendMessage(_parentScene, 0x2000, _testTubeIndex); +		messageResult = 1; +		break; +	} +	return messageResult; +} + +void SsScene2808Dispenser::startCountdown(int index) { +	setVisible(true); +	updatePosition(); +	if (_testTubeSetNum == 0) { +		_countdown = kClass428Countdowns1[index]; +	} else { +		_countdown = kClass428Countdowns2[index]; +	} +} + +AsScene2808TestTube::AsScene2808TestTube(NeverhoodEngine *vm, int testTubeSetNum, int testTubeIndex, SsScene2808Dispenser *ssDispenser) +	: AnimatedSprite(vm, 1100), _testTubeSetNum(testTubeSetNum), _testTubeIndex(testTubeIndex), _ssDispenser(ssDispenser), _fillLevel(0) { + +	if (testTubeSetNum == 0) { +		_x = 504; +		_y = 278; +	} else { +		setDoDeltaX(1); +		_x = 136; +		_y = 278; +	} + +	createSurface1(kClass490FileHashes[testTubeIndex], 1100); + +	if (testTubeSetNum == 0) { +		loadSound(0, 0x30809E2D); +		loadSound(1, 0x72811E2D); +		loadSound(2, 0x78B01625); +	} else { +		loadSound(3, 0x70A41E0C); +		loadSound(4, 0x50205E2D); +		loadSound(5, 0xF8621E2D); +		loadSound(6, 0xF1A03C2D); +		loadSound(7, 0x70A43D2D); +		loadSound(8, 0xF0601E2D); +	} + +	startAnimation(kClass490FileHashes[testTubeIndex], 0, -1); +	_newStickFrameIndex = 0; + +	SetUpdateHandler(&AnimatedSprite::update); +	SetMessageHandler(&AsScene2808TestTube::handleMessage); + +	if (_fillLevel == 0) +		setVisible(false); + +} + +uint32 AsScene2808TestTube::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x1011: +		fill(); +		messageResult = 1; +		break; +	} +	return messageResult; +} + +void AsScene2808TestTube::fill() { +	if ((int)_fillLevel < _testTubeSetNum * 3 + 3) { +		if (_testTubeSetNum == 0) { +			playSound(_fillLevel); +			setVisible(true); +			startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices1[_fillLevel], kClass490FrameIndices1[_fillLevel + 1]); +			_newStickFrameIndex = kClass490FrameIndices1[_fillLevel + 1]; +		} else { +			playSound(3 + _fillLevel); +			setVisible(true); +			startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices2[_fillLevel], kClass490FrameIndices2[_fillLevel + 1]); +			_newStickFrameIndex = kClass490FrameIndices2[_fillLevel + 1]; +		} +		_ssDispenser->startCountdown(_fillLevel); +		_fillLevel++; +	} +} + +void AsScene2808TestTube::flush() { +	if (_fillLevel != 0) { +		if (_testTubeSetNum == 0) { +			startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices1[_fillLevel], -1); +		} else { +			startAnimation(kClass490FileHashes[_testTubeIndex], kClass490FrameIndices2[_fillLevel], -1); +		} +		_newStickFrameIndex = 0; +		_playBackwards = true; +		setVisible(true); +	} +} + +AsScene2808Handle::AsScene2808Handle(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum) +	: AnimatedSprite(vm, 1300), _parentScene(parentScene), _testTubeSetNum(testTubeSetNum), _isActivated(false) { + +	loadSound(0, 0xE18D1F30); +	_x = 320; +	_y = 240; +	if (_testTubeSetNum == 1) +		setDoDeltaX(1); +	createSurface1(0x040900D0, 1300); +	startAnimation(0x040900D0, 0, -1); +	_needRefresh = true; +	_newStickFrameIndex = 0; +	SetUpdateHandler(&AnimatedSprite::update); +	SetMessageHandler(&AsScene2808Handle::handleMessage); +	AnimatedSprite::updatePosition(); +} + +uint32 AsScene2808Handle::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x1011: +		if (!_isActivated) { +			sendMessage(_parentScene, 0x2001, 0); +			playSound(0); +			activate(); +		} +		messageResult = 1; +		break; +	} +	return messageResult; +} + +uint32 AsScene2808Handle::hmActivating(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x3002: +		gotoNextState(); +		break; +	} +	return messageResult; +} + +void AsScene2808Handle::activate() { +	startAnimation(0x040900D0, 0, -1); +	SetMessageHandler(&AsScene2808Handle::hmActivating); +	NextState(&AsScene2808Handle::stActivated); +	_isActivated = true; +	_newStickFrameIndex = -1; +} + +void AsScene2808Handle::stActivated() { +	stopAnimation(); +	sendMessage(_parentScene, 0x2002, 0); +} + +AsScene2808Flow::AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum) +	: AnimatedSprite(vm, 1100), _parentScene(parentScene), _testTubeSetNum(testTubeSetNum) { + +	if (testTubeSetNum == 0) { +		_x = 312; +		_y = 444; +	} else { +		_x = 328; +		_y = 444; +	} +	createSurface1(0xB8414818, 1200); +	startAnimation(0xB8414818, 0, -1); +	setVisible(false); +	_newStickFrameIndex = 0; +	_needRefresh = true; +	loadSound(0, 0x6389B652); +	SetUpdateHandler(&AnimatedSprite::update); +	AnimatedSprite::updatePosition(); +} + +uint32 AsScene2808Flow::hmFlowing(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x3002: +		gotoNextState(); +		break; +	} +	return messageResult; +} + +void AsScene2808Flow::start() { +	startAnimation(0xB8414818, 0, -1); +	setVisible(true); +	SetMessageHandler(&AsScene2808Flow::hmFlowing); +	NextState(&AsScene2808Flow::stKeepFlowing); +	playSound(0); +} + +void AsScene2808Flow::stKeepFlowing() { +	startAnimation(0xB8414818, 1, -1); +	NextState(&AsScene2808Flow::stKeepFlowing); +} + +AsScene2808LightEffect::AsScene2808LightEffect(NeverhoodEngine *vm, int testTubeSetNum) +	: AnimatedSprite(vm, 800), _countdown(1) { + +	_x = 320; +	_y = 240; +	if (testTubeSetNum == 1) +		setDoDeltaX(1); +	createSurface1(0x804C2404, 800); +	SetUpdateHandler(&AsScene2808LightEffect::update); +	_needRefresh = true; +	AnimatedSprite::updatePosition(); +} + +void AsScene2808LightEffect::update() { +	if (_countdown != 0 && (--_countdown) == 0) { +		int16 frameIndex = _vm->_rnd->getRandomNumber(3 - 1); +		startAnimation(0x804C2404, frameIndex, frameIndex); +		updateAnim(); +		updatePosition(); +		_countdown = _vm->_rnd->getRandomNumber(3 - 1) + 1; +	} +} + +AsScene2809Spew::AsScene2809Spew(NeverhoodEngine *vm) +	: AnimatedSprite(vm, 1200) { + +	SetUpdateHandler(&AnimatedSprite::update); +	SetMessageHandler(&AsScene2809Spew::handleMessage); +	createSurface1(0x04211490, 1200); +	_x = 262; +	_y = 423; +	setDoDeltaX(0); +	setVisible(false); +} + +uint32 AsScene2809Spew::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x2000: +		playSound(0, 0x48640244); +		startAnimation(0x04211490, 0, -1); +		setVisible(true); +		break; +	case 0x3002: +		stopAnimation(); +		setVisible(false); +		break; +	} +	return messageResult; +} + +AsScene2810Rope::AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x) +	: AnimatedSprite(vm, 1100) { + +	createSurface(990, 68, 476); +	SetUpdateHandler(&AnimatedSprite::update); +	SetMessageHandler(&AsScene2810Rope::handleMessage); +	SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); +	_x = x; +	_y = -276; +	startAnimation(0x9D098C23, 35, 53); +} + +uint32 AsScene2810Rope::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x3002: +		startAnimation(0x9D098C23, 35, 53); +		break; +	case 0x482A: +		sendMessage(_parentScene, 0x1022, 990); +		break; +	case 0x482B: +		sendMessage(_parentScene, 0x1022, 1010); +		break; +	} +	return messageResult; +} + +AsScene2812Winch::AsScene2812Winch(NeverhoodEngine *vm) +	: AnimatedSprite(vm, 1100) { + +	createSurface1(0x20DA08A0, 1200); +	SetUpdateHandler(&AnimatedSprite::update); +	SetMessageHandler(&AsScene2812Winch::handleMessage); +	setVisible(false); +	_x = 280; +	_y = 184; +} + +AsScene2812Winch::~AsScene2812Winch() { +	_vm->_soundMan->deleteSoundGroup(0x00B000E2); +} + +uint32 AsScene2812Winch::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x2000: +		startAnimation(0x20DA08A0, 0, -1); +		setVisible(true); +		_vm->_soundMan->addSound(0x00B000E2, 0xC874EE6C); +		_vm->_soundMan->playSoundLooping(0xC874EE6C); +		break; +	case 0x3002: +		startAnimation(0x20DA08A0, 7, -1); +		break; +	} +	return messageResult; +} + +AsScene2812Rope::AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene) +	: AnimatedSprite(vm, 1100), _parentScene(parentScene) { + +	createSurface(990, 68, 476); +	SetUpdateHandler(&AnimatedSprite::update); +	SetMessageHandler(&AsScene2812Rope::handleMessage); +	SetSpriteUpdate(&AnimatedSprite::updateDeltaXY); +	startAnimation(0xAE080551, 0, -1); +	_x = 334; +	_y = 201; +} + +uint32 AsScene2812Rope::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x4806: +		setDoDeltaX(((Sprite*)sender)->isDoDeltaX() ? 1 : 0); +		stRopingDown(); +		break; +	case 0x482A: +		sendMessage(_parentScene, 0x1022, 990); +		break; +	case 0x482B: +		sendMessage(_parentScene, 0x1022, 1010); +		break; +	} +	return messageResult; +} + +uint32 AsScene2812Rope::hmRopingDown(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x3002: +		gotoNextState(); +		break; +	} +	return messageResult; +} + +void AsScene2812Rope::stRopingDown() { +	sendMessage(_parentScene, 0x4806, 0); +	startAnimation(0x9D098C23, 0, -1); +	SetMessageHandler(&AsScene2812Rope::hmRopingDown); +} + +AsScene2812TrapDoor::AsScene2812TrapDoor(NeverhoodEngine *vm) +	: AnimatedSprite(vm, 0x805D0029, 100, 320, 240) { + +	SetMessageHandler(&AsScene2812TrapDoor::handleMessage); +	_newStickFrameIndex = 0; +} + +uint32 AsScene2812TrapDoor::handleMessage(int messageNum, const MessageParam ¶m, Entity *sender) { +	uint32 messageResult = Sprite::handleMessage(messageNum, param, sender); +	switch (messageNum) { +	case 0x2000: +		startAnimation(0x805D0029, 0, -1); +		playSound(0, 0xEA005F40); +		_newStickFrameIndex = STICK_LAST_FRAME; +		break; +	} +	return messageResult; +} + +} // End of namespace Neverhood diff --git a/engines/neverhood/modules/module2800_sprites.h b/engines/neverhood/modules/module2800_sprites.h new file mode 100644 index 0000000000..39ca88ef73 --- /dev/null +++ b/engines/neverhood/modules/module2800_sprites.h @@ -0,0 +1,268 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef NEVERHOOD_MODULES_MODULE2800_SPRITES_H +#define NEVERHOOD_MODULES_MODULE2800_SPRITES_H + +#include "neverhood/neverhood.h" +#include "neverhood/module.h" +#include "neverhood/scene.h" + +namespace Neverhood { + +class AsScene2803LightCord : public AnimatedSprite { +public: +	AsScene2803LightCord(NeverhoodEngine *vm, Scene *parentScene, uint32 fileHash1, uint32 fileHash2, int16 x, int16 y); +	void stPulled(); +	void stIdle(); +	void setFileHashes(uint32 fileHash1, uint32 fileHash2); +protected: +	Scene *_parentScene; +	uint32 _fileHash1, _fileHash2; +	bool _isPulled, _isBusy; +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +	uint32 hmPulled(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class AsScene2803TestTubeOne : public AnimatedSprite { +public: +	AsScene2803TestTubeOne(NeverhoodEngine *vm, uint32 fileHash1, uint32 fileHash2); +protected: +	uint32 _fileHash1, _fileHash2; +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class AsScene2803Rope : public AnimatedSprite { +public: +	AsScene2803Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x); +protected: +	Scene *_parentScene; +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +	uint32 hmReleased(int messageNum, const MessageParam ¶m, Entity *sender); +	void stReleased(); +	void stHide(); +}; + +class Scene2804; + +class SsScene2804RedButton : public StaticSprite { +public: +	SsScene2804RedButton(NeverhoodEngine *vm, Scene2804 *parentScene); +protected: +	Scene2804 *_parentScene; +	int _countdown; +	void update(); +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class SsScene2804LightCoil : public StaticSprite { +public: +	SsScene2804LightCoil(NeverhoodEngine *vm); +protected: +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class SsScene2804BeamCoilBody : public StaticSprite { +public: +	SsScene2804BeamCoilBody(NeverhoodEngine *vm); +}; + +class SsScene2804LightTarget : public StaticSprite { +public: +	SsScene2804LightTarget(NeverhoodEngine *vm); +protected: +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class SsScene2804Flash : public StaticSprite { +public: +	SsScene2804Flash(NeverhoodEngine *vm); +	void show(); +}; + +class AsScene2804CrystalWaves : public AnimatedSprite { +public: +	AsScene2804CrystalWaves(NeverhoodEngine *vm, uint crystalIndex); +	void show(); +	void hide(); +protected: +	uint _crystalIndex; +}; + +class AsScene2804Crystal : public AnimatedSprite { +public: +	AsScene2804Crystal(NeverhoodEngine *vm, AsScene2804CrystalWaves *asCrystalWaves, uint crystalIndex); +	void show(); +	void hide(); +	void activate(); +	int16 getColorNum() const { return _colorNum; } +protected: +	AsScene2804CrystalWaves *_asCrystalWaves; +	uint _crystalIndex; +	int16 _colorNum; +	bool _isLightOn; +	bool _isShowing; +}; + +class SsScene2804CrystalButton : public StaticSprite { +public: +	SsScene2804CrystalButton(NeverhoodEngine *vm, Scene2804 *parentScene, AsScene2804Crystal *asCrystal, uint crystalIndex); +protected: +	Scene2804 *_parentScene; +	AsScene2804Crystal *_asCrystal; +	uint _crystalIndex; +	int _countdown; +	void update(); +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class AsScene2804BeamCoil : public AnimatedSprite { +public: +	AsScene2804BeamCoil(NeverhoodEngine *vm, Scene *parentScene, SsScene2804BeamCoilBody *ssBeamCoilBody); +	virtual ~AsScene2804BeamCoil(); +protected: +	Scene *_parentScene; +	SsScene2804BeamCoilBody *_ssBeamCoilBody; +	int _countdown; +	void update(); +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +	void show(); +	void hide(); +	void stBeaming(); +	uint32 hmBeaming(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class AsScene2804BeamTarget : public AnimatedSprite { +public: +	AsScene2804BeamTarget(NeverhoodEngine *vm); +protected: +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class AsScene2806Spew : public AnimatedSprite { +public: +	AsScene2806Spew(NeverhoodEngine *vm); +protected: +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class SsScene2808Dispenser : public StaticSprite { +public: +	SsScene2808Dispenser(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum, int testTubeIndex); +	void startCountdown(int index); +protected: +	Scene *_parentScene; +	int _countdown; +	int _testTubeSetNum, _testTubeIndex; +	void update(); +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class AsScene2808TestTube : public AnimatedSprite { +public: +	AsScene2808TestTube(NeverhoodEngine *vm, int testTubeSetNum, int testTubeIndex, SsScene2808Dispenser *ssDispenser); +	void fill(); +	void flush(); +	uint32 getFillLevel() const { return _fillLevel; } +protected: +	SsScene2808Dispenser *_ssDispenser; +	int _testTubeSetNum; +	uint32 _fillLevel; +	int _testTubeIndex; +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class AsScene2808Handle : public AnimatedSprite { +public: +	AsScene2808Handle(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum); +	void activate(); +	void stActivated(); +protected: +	Scene *_parentScene; +	int _testTubeSetNum; +	bool _isActivated; +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +	uint32 hmActivating(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class AsScene2808Flow : public AnimatedSprite { +public: +	AsScene2808Flow(NeverhoodEngine *vm, Scene *parentScene, int testTubeSetNum); +	void start(); +	void stKeepFlowing(); +protected: +	Scene *_parentScene; +	int _testTubeSetNum; +	uint32 hmFlowing(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class AsScene2808LightEffect : public AnimatedSprite { +public: +	AsScene2808LightEffect(NeverhoodEngine *vm, int which); +protected: +	int _countdown; +	void update(); +}; + +class AsScene2809Spew : public AnimatedSprite { +public: +	AsScene2809Spew(NeverhoodEngine *vm); +protected: +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class AsScene2810Rope : public AnimatedSprite { +public: +	AsScene2810Rope(NeverhoodEngine *vm, Scene *parentScene, int16 x); +protected: +	Scene *_parentScene; +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class AsScene2812Winch : public AnimatedSprite { +public: +	AsScene2812Winch(NeverhoodEngine *vm); +	virtual ~AsScene2812Winch(); +protected: +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +class AsScene2812Rope : public AnimatedSprite { +public: +	AsScene2812Rope(NeverhoodEngine *vm, Scene *parentScene); +protected: +	Scene *_parentScene; +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +	uint32 hmRopingDown(int messageNum, const MessageParam ¶m, Entity *sender); +	void stRopingDown(); +}; + +class AsScene2812TrapDoor : public AnimatedSprite { +public: +	AsScene2812TrapDoor(NeverhoodEngine *vm); +protected: +	uint32 handleMessage(int messageNum, const MessageParam ¶m, Entity *sender); +}; + +} // End of namespace Neverhood + +#endif /* NEVERHOOD_MODULES_MODULE2800_SPRITES_H */ | 
