[Scummvm-git-logs] scummvm master -> a19438f21ee35abeae040eba05004784b6f4e364

mgerhardy noreply at scummvm.org
Thu Feb 13 16:32:47 UTC 2025


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
a19438f21e TWINE: started to support mixer balance changing for some samples


Commit: a19438f21ee35abeae040eba05004784b6f4e364
    https://github.com/scummvm/scummvm/commit/a19438f21ee35abeae040eba05004784b6f4e364
Author: Martin Gerhardy (martin.gerhardy at gmail.com)
Date: 2025-02-13T17:32:01+01:00

Commit Message:
TWINE: started to support mixer balance changing for some samples

also renamed methods to match better the original sources

Changed paths:
    engines/twine/audio/sound.cpp
    engines/twine/audio/sound.h
    engines/twine/movies.cpp
    engines/twine/renderer/redraw.cpp
    engines/twine/scene/actor.cpp
    engines/twine/scene/animations.cpp
    engines/twine/scene/extra.cpp
    engines/twine/scene/gamestate.cpp
    engines/twine/scene/scene.cpp
    engines/twine/script/script_move.cpp
    engines/twine/twine.cpp


diff --git a/engines/twine/audio/sound.cpp b/engines/twine/audio/sound.cpp
index 09a6beaaf7b..57f5b49c875 100644
--- a/engines/twine/audio/sound.cpp
+++ b/engines/twine/audio/sound.cpp
@@ -23,6 +23,7 @@
 #include "audio/audiostream.h"
 #include "audio/decoders/raw.h"
 #include "audio/decoders/voc.h"
+#include "audio/mixer.h"
 #include "common/config-manager.h"
 #include "common/memstream.h"
 #include "common/system.h"
@@ -36,6 +37,7 @@
 #include "twine/resources/hqr.h"
 #include "twine/scene/movements.h"
 #include "twine/resources/resources.h"
+#include "twine/shared.h"
 #include "twine/text.h"
 #include "twine/twine.h"
 
@@ -55,19 +57,37 @@ void Sound::startRainSample() {
 #if 0
 	const int sample = SAMPLE_RAIN;
 	if (CubeMode == CUBE_EXTERIEUR && !TEMPETE_FINIE && !isSamplePlaying(sample)) {
-		//const int frequency = 0x1000;
+		const int rate = 0x1000;
 		const int offset = 300;
 		const int repeat = 0;
 		const int panning = 64;
 		const int volumeRain = 70;
-		// TODO: playSample(sample, /*frequency,*/ offset, repeat, panning, volumeRain);
+		// TODO: mixSample(sample, rate, offset, repeat, panning, volumeRain);
 	}
 
 	RestartRainSample = false;
 #endif
 }
 
-void Sound::setSamplePosition(int32 channelIdx, int32 x, int32 y, int32 z) {
+void Sound::setChannelRate(int32 channelIdx, uint32 rate) {
+	if (channelIdx < 0 || channelIdx >= NUM_CHANNELS) {
+		return;
+	}
+	_engine->_system->getMixer()->setChannelRate(_samplesPlaying[channelIdx], rate);
+}
+
+void Sound::setChannelBalance(int32 channelIdx, uint8 volumeLeft, uint8 volumeRight) {
+	if (channelIdx < 0 || channelIdx >= NUM_CHANNELS) {
+		return;
+	}
+	Audio::Mixer *mixer = _engine->_system->getMixer();
+	const Audio::SoundHandle &handle = _samplesPlaying[channelIdx];
+	// balance value ranges from -127 to 127
+	int8 balance = (int8)(((int16)volumeRight - (int16)volumeLeft) * 127 / 255);
+	mixer->setChannelBalance(handle, balance);
+}
+
+void Sound::setChannelPosition(int32 channelIdx, int32 x, int32 y, int32 z) {
 	if (channelIdx < 0 || channelIdx >= NUM_CHANNELS) {
 		return;
 	}
@@ -77,13 +97,13 @@ void Sound::setSamplePosition(int32 channelIdx, int32 x, int32 y, int32 z) {
 	int32 distance = getDistance3D(camX, camY, camZ, x, y, z);
 	distance = boundRuleThree(0, distance, 10000, 255);
 	byte targetVolume = 0;
-	if (distance < 255) {
-		targetVolume = 255 - distance;
+	if (distance < Audio::Mixer::kMaxChannelVolume) {
+		targetVolume = Audio::Mixer::kMaxChannelVolume - distance;
 	}
-	_engine->_system->getMixer()->setChannelVolume(samplesPlaying[channelIdx], targetVolume);
+	_engine->_system->getMixer()->setChannelVolume(_samplesPlaying[channelIdx], targetVolume);
 }
 
-void Sound::playFlaSample(int32 index, int32 repeat, uint8 balance, int32 volumeLeft, int32 volumeRight) {
+void Sound::playFlaSample(int32 index, int16 rate, int32 repeat, uint8 volumeLeft, uint8 volumeRight) {
 	if (!_engine->_cfgfile.Sound) {
 		return;
 	}
@@ -110,10 +130,19 @@ void Sound::playFlaSample(int32 index, int32 repeat, uint8 balance, int32 volume
 
 	Common::MemoryReadStream *stream = new Common::MemoryReadStream(sampPtr, sampSize, DisposeAfterUse::YES);
 	Audio::SeekableAudioStream *audioStream = Audio::makeVOCStream(stream, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES);
-	playSample(channelIdx, index, audioStream, repeat, Resources::HQR_FLASAMP_FILE);
+	if (playSample(channelIdx, index, audioStream, repeat, Resources::HQR_FLASAMP_FILE)) {
+		setChannelRate(channelIdx, rate);
+		setChannelBalance(channelIdx, volumeLeft, volumeRight);
+	}
+}
+
+void Sound::mixSample(int32 index, uint16 pitchbend, int32 repeat, uint8 volumeLeft, uint8 volumeRight) {
+	mixSample3D(index, pitchbend, repeat, {}, -1);
+	int channelIdx = getSampleChannel(index);
+	setChannelBalance(channelIdx, volumeLeft, volumeRight);
 }
 
-void Sound::playSample(int32 index, uint16 pitchbend, int32 repeat, int32 x, int32 y, int32 z, int32 actorIdx) {
+void Sound::mixSample3D(int32 index, uint16 pitchbend, int32 repeat, const IVec3 &pos, int32 actorIdx) {
 	if (!_engine->_cfgfile.Sound) {
 		return;
 	}
@@ -125,11 +154,12 @@ void Sound::playSample(int32 index, uint16 pitchbend, int32 repeat, int32 x, int
 	}
 
 	if (actorIdx != -1) {
-		setSamplePosition(channelIdx, x, y, z);
+		// TODO: implement balance
+		setChannelPosition(channelIdx, pos.x, pos.y, pos.z);
 		// save the actor index for the channel so we can check the position
-		samplesPlayingActors[channelIdx] = actorIdx;
+		_samplesPlayingActors[channelIdx] = actorIdx;
 	} else {
-		samplesPlayingActors[channelIdx] = -1;
+		_samplesPlayingActors[channelIdx] = -1;
 	}
 
 	uint8 *sampPtr = _engine->_resources->_samplesTable[index];
@@ -137,8 +167,8 @@ void Sound::playSample(int32 index, uint16 pitchbend, int32 repeat, int32 x, int
 	Common::MemoryReadStream *stream = new Common::MemoryReadStream(sampPtr, sampSize, DisposeAfterUse::NO);
 	Audio::SeekableAudioStream *audioStream = Audio::makeVOCStream(stream, Audio::FLAG_UNSIGNED, DisposeAfterUse::YES);
 	playSample(channelIdx, index, audioStream, repeat, Resources::HQR_SAMPLES_FILE, Audio::Mixer::kSFXSoundType);
-	uint16 frequency = 11025 + (pitchbend - 0x1000);
-	_engine->_system->getMixer()->setChannelRate(samplesPlaying[channelIdx], frequency);
+	uint32 rate = 11025 + (pitchbend - 0x1000);
+	setChannelRate(channelIdx, rate);
 }
 
 bool Sound::playVoxSample(const TextEntry *text) {
@@ -187,7 +217,7 @@ bool Sound::playVoxSample(const TextEntry *text) {
 	return playSample(channelIdx, text->index, audioStream, 1, _engine->_text->_currentVoxBankFile.c_str(), Audio::Mixer::kSpeechSoundType);
 }
 
-bool Sound::playSample(int channelIdx, int index, Audio::SeekableAudioStream *audioStream, int32 loop, const char *name, Audio::Mixer::SoundType soundType) {
+bool Sound::playSample(int32 channelIdx, int32 index, Audio::SeekableAudioStream *audioStream, int32 loop, const char *name, Audio::Mixer::SoundType soundType) {
 	if (audioStream == nullptr) {
 		warning("Failed to create audio stream for %s: %i", name, index);
 		return false;
@@ -198,9 +228,8 @@ bool Sound::playSample(int channelIdx, int index, Audio::SeekableAudioStream *au
 		loop = 0;
 	}
 	Audio::AudioStream *loopStream = Audio::makeLoopingAudioStream(audioStream, loop);
-	Audio::SoundHandle *handle = &samplesPlaying[channelIdx];
+	Audio::SoundHandle *handle = &_samplesPlaying[channelIdx];
 	const byte volume = Audio::Mixer::kMaxChannelVolume;
-	// TODO: implement balance
 	_engine->_system->getMixer()->playStream(soundType, handle, loopStream, index, volume);
 	return true;
 }
@@ -224,64 +253,64 @@ void Sound::stopSamples() { // HQ_StopSample
 		return;
 	}
 
-	for (int i = 0; i < NUM_CHANNELS; i++) {
-		_engine->_system->getMixer()->stopHandle(samplesPlaying[i]);
+	for (int channelIdx = 0; channelIdx < NUM_CHANNELS; channelIdx++) {
+		_engine->_system->getMixer()->stopHandle(_samplesPlaying[channelIdx]);
 	}
-	memset(samplesPlayingActors, -1, sizeof(samplesPlayingActors));
+	memset(_samplesPlayingActors, -1, sizeof(_samplesPlayingActors));
 }
 
-int32 Sound::getActorChannel(int32 index) {
-	for (int32 c = 0; c < NUM_CHANNELS; c++) {
-		if (samplesPlayingActors[c] == index) {
-			return c;
+int32 Sound::getActorChannel(int32 actorIdx) {
+	for (int32 channelIdx = 0; channelIdx < NUM_CHANNELS; channelIdx++) {
+		if (_samplesPlayingActors[channelIdx] == actorIdx) {
+			return channelIdx;
 		}
 	}
 	return -1;
 }
 
 int32 Sound::getSampleChannel(int32 index) {
-	for (int32 c = 0; c < NUM_CHANNELS; c++) {
-		if (_engine->_system->getMixer()->getSoundID(samplesPlaying[c]) == index) {
-			return c;
+	for (int32 channelIdx = 0; channelIdx < NUM_CHANNELS; channelIdx++) {
+		if (_engine->_system->getMixer()->getSoundID(_samplesPlaying[channelIdx]) == index) {
+			return channelIdx;
 		}
 	}
 	return -1;
 }
 
-void Sound::removeSampleChannel(int32 c) {
-	samplesPlayingActors[c] = -1;
+void Sound::removeChannelWatch(int32 channelIdx) {
+	_samplesPlayingActors[channelIdx] = -1;
 }
 
 void Sound::stopSample(int32 index) {
 	if (!_engine->_cfgfile.Sound) {
 		return;
 	}
-	const int32 stopChannel = getSampleChannel(index);
-	if (stopChannel != -1) {
+	const int32 channelIdx = getSampleChannel(index);
+	if (channelIdx != -1) {
 		_engine->_system->getMixer()->stopID(index);
-		removeSampleChannel(stopChannel);
+		removeChannelWatch(channelIdx);
 	}
 }
 
-bool Sound::isChannelPlaying(int32 chan) {
-	if (chan >= 0 && chan < ARRAYSIZE(samplesPlaying)) {
-		if (_engine->_system->getMixer()->isSoundHandleActive(samplesPlaying[chan])) {
+bool Sound::isChannelPlaying(int32 channelIdx) {
+	if (channelIdx >= 0 && channelIdx < ARRAYSIZE(_samplesPlaying)) {
+		if (_engine->_system->getMixer()->isSoundHandleActive(_samplesPlaying[channelIdx])) {
 			return true;
 		}
-		removeSampleChannel(chan);
+		removeChannelWatch(channelIdx);
 	}
 	return false;
 }
 
 int32 Sound::isSamplePlaying(int32 index) {
-	const int32 chan = getSampleChannel(index);
-	return isChannelPlaying(chan);
+	const int32 channelIdx = getSampleChannel(index);
+	return isChannelPlaying(channelIdx);
 }
 
 int32 Sound::getFreeSampleChannelIndex() {
-	for (int i = 0; i < NUM_CHANNELS; i++) {
-		if (!_engine->_system->getMixer()->isSoundHandleActive(samplesPlaying[i])) {
-			return i;
+	for (int channelIdx = 0; channelIdx < NUM_CHANNELS; channelIdx++) {
+		if (!_engine->_system->getMixer()->isSoundHandleActive(_samplesPlaying[channelIdx])) {
+			return channelIdx;
 		}
 	}
 	return -1;
diff --git a/engines/twine/audio/sound.h b/engines/twine/audio/sound.h
index 3db1bd056f2..21172090dc0 100644
--- a/engines/twine/audio/sound.h
+++ b/engines/twine/audio/sound.h
@@ -54,56 +54,57 @@ class Sound {
 private:
 	TwinEEngine *_engine;
 
-	/** Get the channel where the sample is playing */
-	int32 getSampleChannel(int32 index);
-
 	/** Samples playing at the same time */
-	Audio::SoundHandle samplesPlaying[NUM_CHANNELS];
+	Audio::SoundHandle _samplesPlaying[NUM_CHANNELS];
 
 	/** Samples playing at a actors position */
-	int32 samplesPlayingActors[NUM_CHANNELS]{0};
+	int32 _samplesPlayingActors[NUM_CHANNELS]{0};
 
-	bool playSample(int channelIdx, int index, Audio::SeekableAudioStream *audioStream, int32 loop, const char *name, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
+	bool playSample(int32 channelIdx, int32 index, Audio::SeekableAudioStream *audioStream, int32 loop, const char *name, Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType);
 
-	bool isChannelPlaying(int32 channel);
+	bool isChannelPlaying(int32 channelIdx);
 
 	/** Find a free channel slot to use */
 	int32 getFreeSampleChannelIndex();
 
 	/** Remove a sample from the channel usage list */
-	void removeSampleChannel(int32 index);
-
+	void removeChannelWatch(int32 channelIdx);
 public:
 	Sound(TwinEEngine *engine);
 	~Sound();
 
+	/** Get the channel where the sample is playing */
+	int32 getSampleChannel(int32 index);
+
 	/**
 	 * Play FLA movie samples
 	 * @param index sample index under flasamp.hqr file
 	 * @param repeat number of times to repeat the sample
 	 */
-	void playFlaSample(int32 index, int32 repeat, uint8 balance, int32 volumeLeft, int32 volumeRight);
+	void playFlaSample(int32 index, int16 rate, int32 repeat, uint8 volumeLeft, uint8 volumeRight);
+
+	void setChannelBalance(int32 channelIdx, uint8 volumeLeft, uint8 volumeRight);
+
+	void setChannelRate(int32 channelIdx, uint32 rate);
 
 	/** Update sample position in channel */
-	void setSamplePosition(int32 channelIdx, int32 x, int32 y, int32 z);
+	void setChannelPosition(int32 channelIdx, int32 x, int32 y, int32 z);
 
-	inline void setSamplePosition(int32 channelIdx, const IVec3 &pos) {
-		setSamplePosition(channelIdx, pos.x, pos.y, pos.z);
+	inline void setChannelPosition(int32 channelIdx, const IVec3 &pos) {
+		setChannelPosition(channelIdx, pos.x, pos.y, pos.z);
 	}
 
 	/**
 	 * Play samples
 	 * @param index sample index under flasamp.hqr file
 	 * @param repeat number of times to repeat the sample
-	 * @param x sound generating entity x position
-	 * @param y sound generating entity y position
-	 * @param z sound generating entity z position
+	 * @param pos sound generating entity position
 	 * @param actorIdx
 	 */
-	void playSample(int32 index, uint16 pitchbend = 0x1000, int32 repeat = 1, int32 x = 128, int32 y = 128, int32 z = 128, int32 actorIdx = -1); // HQ_3D_MixSample
-	void playSample(int32 index, uint16 pitchbend, int32 repeat, const IVec3 &pos, int32 actorIdx = -1) { // HQ_MixSample
-		playSample(index, pitchbend, repeat, pos.x, pos.y, pos.z, actorIdx);
-	}
+	void mixSample3D(int32 index, uint16 pitchbend, int32 repeat, const IVec3 &pos, int32 actorIdx); // HQ_3D_MixSample
+
+	void mixSample(int32 index, uint16 pitchbend, int32 repeat, uint8 volumeLeft, uint8 volumeRight); // HQ_MixSample
+
 	/** Pause samples */
 	void pauseSamples();
 
@@ -116,13 +117,13 @@ public:
 	void stopSamples();
 
 	/** Get the channel where the actor sample is playing */
-	int32 getActorChannel(int32 index);
+	int32 getActorChannel(int32 actorIdx);
 
 	/** Stops a specific sample */
 	void stopSample(int32 index); // HQ_StopOneSample
 
 	/** Check if a sample is playing */
-	int32 isSamplePlaying(int32 index); // IsSamplePlaying
+	int32 isSamplePlaying(int32 index);
 
 	/** Play VOX sample */
 	bool playVoxSample(const TextEntry *text);
diff --git a/engines/twine/movies.cpp b/engines/twine/movies.cpp
index c227146805b..3302f8d3d52 100644
--- a/engines/twine/movies.cpp
+++ b/engines/twine/movies.cpp
@@ -234,7 +234,7 @@ void Movies::drawNextFrameFla() {
 			sample.balance = stream.readByte();
 			sample.volumeLeft = stream.readByte();
 			sample.volumeRight = stream.readByte();
-			_engine->_sound->playFlaSample(sample.sampleNum, sample.repeat, sample.balance, sample.volumeLeft, sample.volumeRight);
+			_engine->_sound->playFlaSample(sample.sampleNum, sample.freq, sample.repeat, sample.volumeLeft, sample.volumeRight);
 			break;
 		}
 		case kStopSample: {
@@ -276,13 +276,14 @@ void Movies::drawNextFrameFla() {
 			break;
 		}
 		case kSampleBalance: {
-			/* int16 num = */ stream.readSint16LE();
-			/* uint8 offset = */ stream.readByte();
+			const int16 sampleNum = stream.readSint16LE();
+			/* const uint8 offset = */ stream.readByte();
 			stream.skip(1); // padding
-			/* int16 balance = */ stream.readSint16LE();
-			/* uint8 volumeLeft = */ stream.readByte();
-			/* uint8 volumeRight = */ stream.readByte();
-			// TODO: change balance
+			/* const int16 balance = */ stream.readSint16LE();
+			const uint8 volumeLeft = stream.readByte();
+			const uint8 volumeRight = stream.readByte();
+			const int32 channelIdx = _engine->_sound->getSampleChannel(sampleNum);
+			_engine->_sound->setChannelBalance(channelIdx, volumeLeft, volumeRight);
 			break;
 		}
 		default: {
diff --git a/engines/twine/renderer/redraw.cpp b/engines/twine/renderer/redraw.cpp
index 084bb8f7bb3..39c172164da 100644
--- a/engines/twine/renderer/redraw.cpp
+++ b/engines/twine/renderer/redraw.cpp
@@ -333,7 +333,7 @@ int32 Redraw::fillExtraDrawingList(DrawListStruct *drawList, int32 drawListPos)
 			if (_engine->timerRef - extra->spawnTime > 35) {
 				extra->spawnTime = _engine->timerRef;
 				extra->type &= ~ExtraType::TIME_IN;
-				_engine->_sound->playSample(Samples::ItemPopup, 0x1000, 1, extra->pos);
+				_engine->_sound->mixSample3D(Samples::ItemPopup, 0x1000, 1, extra->pos, -1);
 			}
 			continue;
 		}
diff --git a/engines/twine/scene/actor.cpp b/engines/twine/scene/actor.cpp
index 69bafc003aa..e2c946a8e3e 100644
--- a/engines/twine/scene/actor.cpp
+++ b/engines/twine/scene/actor.cpp
@@ -441,13 +441,13 @@ void Actor::giveExtraBonus(int32 actorIdx) {
 	}
 	if (actor->_workFlags.bIsDead) {
 		_engine->_extra->addExtraBonus(actor->posObj(), LBAAngles::ANGLE_90, LBAAngles::ANGLE_0, bonusSprite, actor->_bonusAmount);
-		_engine->_sound->playSample(Samples::ItemPopup, 0x1000, 1, actor->posObj(), actorIdx);
+		_engine->_sound->mixSample3D(Samples::ItemPopup, 0x1000, 1, actor->posObj(), actorIdx);
 	} else {
 		const ActorStruct *sceneHero = _engine->_scene->_sceneHero;
 		const int32 angle = _engine->_movements->getAngle(actor->posObj(), sceneHero->posObj());
 		const IVec3 pos(actor->_posObj.x, actor->_posObj.y + actor->_boundingBox.maxs.y, actor->_posObj.z);
 		_engine->_extra->addExtraBonus(pos, LBAAngles::ANGLE_70, angle, bonusSprite, actor->_bonusAmount);
-		_engine->_sound->playSample(Samples::ItemPopup, 0x1000, 1, pos, actorIdx);
+		_engine->_sound->mixSample3D(Samples::ItemPopup, 0x1000, 1, pos, actorIdx);
 	}
 }
 
diff --git a/engines/twine/scene/animations.cpp b/engines/twine/scene/animations.cpp
index 44d335c7992..f8950a8483d 100644
--- a/engines/twine/scene/animations.cpp
+++ b/engines/twine/scene/animations.cpp
@@ -295,13 +295,13 @@ void Animations::processAnimActions(int32 actorIdx) { // GereAnimAction
 			break;
 		case ActionType::ACTION_SAMPLE:
 			if (action.animFrame == actor->_frame) {
-				_engine->_sound->playSample(action.sampleIndex, 0x1000, 1, actor->posObj(), actorIdx);
+				_engine->_sound->mixSample3D(action.sampleIndex, 0x1000, 1, actor->posObj(), actorIdx);
 			}
 			break;
 		case ActionType::ACTION_SAMPLE_FREQ:
 			if (action.animFrame == actor->_frame) {
 				const uint16 pitchBend = 0x1000 + _engine->getRandomNumber(action.frequency) - (action.frequency / 2);
-				_engine->_sound->playSample(action.sampleIndex, pitchBend, 1, actor->posObj(), actorIdx);
+				_engine->_sound->mixSample3D(action.sampleIndex, pitchBend, 1, actor->posObj(), actorIdx);
 			}
 			break;
 		case ActionType::ACTION_THROW_EXTRA_BONUS:
@@ -316,7 +316,7 @@ void Animations::processAnimActions(int32 actorIdx) { // GereAnimAction
 			break;
 		case ActionType::ACTION_SAMPLE_REPEAT:
 			if (action.animFrame == actor->_frame) {
-				_engine->_sound->playSample(action.sampleIndex, 0x1000, action.repeat, actor->posObj(), actorIdx);
+				_engine->_sound->mixSample3D(action.sampleIndex, 0x1000, action.repeat, actor->posObj(), actorIdx);
 			}
 			break;
 		case ActionType::ACTION_THROW_SEARCH:
@@ -338,14 +338,14 @@ void Animations::processAnimActions(int32 actorIdx) { // GereAnimAction
 			if (action.animFrame == actor->_frame && (actor->_brickSound & 0xF0U) != 0xF0U) {
 				const int16 sampleIdx = (actor->_brickSound & 0x0FU) + Samples::WalkFloorBegin;
 				const uint16 pitchBend = 0x1000 + _engine->getRandomNumber(1000) - 500;
-				_engine->_sound->playSample(sampleIdx, pitchBend, 1, actor->posObj(), actorIdx);
+				_engine->_sound->mixSample3D(sampleIdx, pitchBend, 1, actor->posObj(), actorIdx);
 			}
 			break;
 		case ActionType::ACTION_RIGHT_STEP:
 			if (action.animFrame == actor->_frame && (actor->_brickSound & 0xF0U) != 0xF0U) {
 				const int16 sampleIdx = (actor->_brickSound & 0x0FU) + Samples::WalkFloorRightBegin;
 				const uint16 pitchBend = 0x1000 + _engine->getRandomNumber(1000) - 500;
-				_engine->_sound->playSample(sampleIdx, pitchBend, 1, actor->posObj(), actorIdx);
+				_engine->_sound->mixSample3D(sampleIdx, pitchBend, 1, actor->posObj(), actorIdx);
 			}
 			break;
 		case ActionType::ACTION_HERO_HITTING:
diff --git a/engines/twine/scene/extra.cpp b/engines/twine/scene/extra.cpp
index 32631a1cb52..0b93bd2c3b4 100644
--- a/engines/twine/scene/extra.cpp
+++ b/engines/twine/scene/extra.cpp
@@ -610,7 +610,7 @@ void Extra::gereExtras() {
 			const int32 angle = ClampAngle(tmpAngle - extra->angle);
 
 			if (angle > LBAAngles::ANGLE_140 && angle < LBAAngles::ANGLE_210) {
-				_engine->_sound->playSample(Samples::ItemFound, 0x1000, 1, _engine->_scene->_sceneHero->posObj(), OWN_ACTOR_SCENE_INDEX);
+				_engine->_sound->mixSample3D(Samples::ItemFound, 0x1000, 1, _engine->_scene->_sceneHero->posObj(), OWN_ACTOR_SCENE_INDEX);
 
 				if (extraKey->info1 > 1) {
 					const IVec3 &projPos = _engine->_renderer->projectPoint(extraKey->pos - _engine->_grid->_worldCube);
@@ -643,7 +643,7 @@ void Extra::gereExtras() {
 			_engine->_movements->initRealValue(LBAAngles::ANGLE_0, extra->destPos.z, LBAAngles::ANGLE_17, &extra->trackActorMove);
 
 			if (extraIdx == _engine->_collision->extraCheckExtraCol(extra, _engine->_gameState->_magicBall)) {
-				_engine->_sound->playSample(Samples::ItemFound, 0x1000, 1, _engine->_scene->_sceneHero->posObj(), OWN_ACTOR_SCENE_INDEX);
+				_engine->_sound->mixSample3D(Samples::ItemFound, 0x1000, 1, _engine->_scene->_sceneHero->posObj(), OWN_ACTOR_SCENE_INDEX);
 
 				if (extraKey->info1 > 1) {
 					const IVec3 &projPos = _engine->_renderer->projectPoint(extraKey->pos - _engine->_grid->_worldCube);
@@ -721,7 +721,7 @@ void Extra::gereExtras() {
 				// if extra is magic ball
 				if (i == _engine->_gameState->_magicBall) {
 					const uint16 pitchBend = 0x1000 + _engine->getRandomNumber(300) - 150;
-					_engine->_sound->playSample(Samples::Hit, pitchBend, 1, extra->pos);
+					_engine->_sound->mixSample3D(Samples::Hit, pitchBend, 1, extra->pos, -1);
 
 					// can't bounce with not magic points
 					if (_engine->_gameState->_magicBallType <= 0) {
@@ -792,7 +792,7 @@ void Extra::gereExtras() {
 		if ((extra->type & ExtraType::TAKABLE) && !(extra->type & ExtraType::FLY)) {
 			// if hero touch extra
 			if (_engine->_collision->extraCheckObjCol(extra, -1) == 0) {
-				_engine->_sound->playSample(Samples::ItemFound, 0x1000, 1, extra->pos);
+				_engine->_sound->mixSample3D(Samples::ItemFound, 0x1000, 1, extra->pos, -1);
 
 				if (extra->info1 > 1) {
 					const IVec3 &projPos = _engine->_renderer->projectPoint(extra->pos - _engine->_grid->_worldCube);
diff --git a/engines/twine/scene/gamestate.cpp b/engines/twine/scene/gamestate.cpp
index 0982f330c60..21ec5eeaf77 100644
--- a/engines/twine/scene/gamestate.cpp
+++ b/engines/twine/scene/gamestate.cpp
@@ -366,7 +366,7 @@ void GameState::doFoundObj(InventoryItems item) {
 	const int32 boxBottomRightX = projPos.x + (SIZE_FOUND_OBJ / 2);
 	const int32 boxBottomRightY = projPos.y + (SIZE_FOUND_OBJ / 2);
 	const Common::Rect boxRect(boxTopLeftX, boxTopLeftY, boxBottomRightX, boxBottomRightY);
-	_engine->_sound->playSample(Samples::BigItemFound);
+	_engine->_sound->mixSample(Samples::BigItemFound, 0x1000, 1, 128, 128);
 
 	// process vox play
 	_engine->_music->stopMusic();
@@ -543,7 +543,8 @@ void GameState::processGameoverAnimation() {
 		debugC(3, kDebugLevels::kDebugTimers, "GameOver time: %i", _engine->timerRef);
 	}
 
-	_engine->_sound->playSample(Samples::Explode);
+	const uint16 pitchBend = 0x1000 + _engine->getRandomNumber(2000) - (2000 / 2);
+	_engine->_sound->mixSample(Samples::Explode, pitchBend, 1, 128, 128);
 	_engine->blitWorkToFront(rect);
 	_engine->_renderer->setFollowCamera(0, 0, 0, 0, 0, 0, zoom);
 	_engine->_renderer->affObjetIso(0, 0, 0, LBAAngles::ANGLE_0, LBAAngles::ANGLE_0, LBAAngles::ANGLE_0, gameOverPtr, dummy);
diff --git a/engines/twine/scene/scene.cpp b/engines/twine/scene/scene.cpp
index 8bfb351416b..59a6046eabf 100644
--- a/engines/twine/scene/scene.cpp
+++ b/engines/twine/scene/scene.cpp
@@ -23,6 +23,7 @@
 #include "common/config-manager.h"
 #include "common/file.h"
 #include "common/memstream.h"
+#include "common/textconsole.h"
 #include "common/util.h"
 #include "engines/enhancements.h"
 #include "twine/audio/music.h"
@@ -726,7 +727,7 @@ void Scene::processEnvironmentSound() {
 				int16 repeat = _sampleRepeat[currentAmb];
 
 				const uint16 pitchbend = 0x1000 + _engine->getRandomNumber(decal) - (decal / 2);
-				_engine->_sound->playSample(sampleIdx, pitchbend, repeat, 110, 110);
+				_engine->_sound->mixSample(sampleIdx, pitchbend, repeat, 110, 110);
 				break;
 			}
 		}
@@ -784,7 +785,8 @@ void Scene::checkZoneSce(int32 actorIdx) {
 		    (currentZ >= zone->mins.z && currentZ <= zone->maxs.z)) {
 			switch (zone->type) {
 			default:
-				error("lba2 zone types not yet implemented");
+				warning("lba2 zone types not yet implemented");
+				break;
 			case ZoneType::kFunFrockFix:
 				break;
 			case ZoneType::kCube:
diff --git a/engines/twine/script/script_move.cpp b/engines/twine/script/script_move.cpp
index 8737bbb00d7..d1a09a12f49 100644
--- a/engines/twine/script/script_move.cpp
+++ b/engines/twine/script/script_move.cpp
@@ -280,7 +280,7 @@ int32 ScriptMove::mWAIT_NUM_ANIM(TwinEEngine *engine, MoveScriptContext &ctx) {
 int32 ScriptMove::mSAMPLE(TwinEEngine *engine, MoveScriptContext &ctx) {
 	int32 sampleIdx = ctx.stream.readSint16LE();
 	debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::SAMPLE(%i)", (int)sampleIdx);
-	engine->_sound->playSample(sampleIdx, 0x1000, 1, ctx.actor->posObj(), ctx.actorIdx);
+	engine->_sound->mixSample3D(sampleIdx, 0x1000, 1, ctx.actor->posObj(), ctx.actorIdx);
 	return 0;
 }
 
@@ -492,7 +492,7 @@ int32 ScriptMove::mSAMPLE_RND(TwinEEngine *engine, MoveScriptContext &ctx) {
 	int32 sampleIdx = ctx.stream.readSint16LE();
 	debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::SAMPLE_RND(%i)", (int)sampleIdx);
 	const uint16 pitchbend = 0x800 + engine->getRandomNumber(0x800);
-	engine->_sound->playSample(sampleIdx, pitchbend, 1, ctx.actor->posObj(), ctx.actorIdx);
+	engine->_sound->mixSample3D(sampleIdx, pitchbend, 1, ctx.actor->posObj(), ctx.actorIdx);
 	return 0;
 }
 
@@ -504,7 +504,7 @@ int32 ScriptMove::mSAMPLE_ALWAYS(TwinEEngine *engine, MoveScriptContext &ctx) {
 	int32 sampleIdx = ctx.stream.readSint16LE();
 	debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::SAMPLE_ALWAYS(%i)", (int)sampleIdx);
 	if (!engine->_sound->isSamplePlaying(sampleIdx)) { // if its not playing
-		engine->_sound->playSample(sampleIdx, 0x1000, 0, ctx.actor->posObj(), ctx.actorIdx);
+		engine->_sound->mixSample3D(sampleIdx, 0x1000, 0, ctx.actor->posObj(), ctx.actorIdx);
 	}
 	return 0;
 }
@@ -565,7 +565,7 @@ int32 ScriptMove::mREPEAT_SAMPLE(TwinEEngine *engine, MoveScriptContext &ctx) {
 int32 ScriptMove::mSIMPLE_SAMPLE(TwinEEngine *engine, MoveScriptContext &ctx) {
 	int32 sampleIdx = ctx.stream.readSint16LE();
 	debugC(3, kDebugLevels::kDebugScriptsMove, "MOVE::SIMPLE_SAMPLE(%i)", (int)sampleIdx);
-	engine->_sound->playSample(sampleIdx, 0x1000, ctx.bigSampleRepeat, ctx.actor->posObj(), ctx.actorIdx);
+	engine->_sound->mixSample(sampleIdx, 0x1000, ctx.bigSampleRepeat, 128, 128);
 	ctx.bigSampleRepeat = 1;
 	return 0;
 }
diff --git a/engines/twine/twine.cpp b/engines/twine/twine.cpp
index c4aae736d10..d588723f879 100644
--- a/engines/twine/twine.cpp
+++ b/engines/twine/twine.cpp
@@ -735,7 +735,7 @@ void TwinEEngine::restoreTimer() {
 void TwinEEngine::processActorSamplePosition(int32 actorIdx) {
 	const ActorStruct *actor = _scene->getActor(actorIdx);
 	const int32 channelIdx = _sound->getActorChannel(actorIdx);
-	_sound->setSamplePosition(channelIdx, actor->posObj());
+	_sound->setChannelPosition(channelIdx, actor->posObj());
 }
 
 void TwinEEngine::processBookOfBu() {
@@ -1097,7 +1097,7 @@ bool TwinEEngine::runGameEngine() { // mainLoopInteration
 #endif
 			} else {
 				const uint16 pitchBend = 0x1000 + getRandomNumber(2000) - (2000 / 2);
-				_sound->playSample(Samples::Explode, pitchBend, 1, actor->posObj(), a);
+				_sound->mixSample3D(Samples::Explode, pitchBend, 1, actor->posObj(), a);
 
 				if (a == _scene->_mecaPenguinIdx) {
 					_extra->extraExplo(actor->posObj());
@@ -1162,7 +1162,7 @@ bool TwinEEngine::runGameEngine() { // mainLoopInteration
 					}
 				} else {
 					const uint16 pitchBend = 0x1000 + getRandomNumber(2000) - (2000 / 2);
-					_sound->playSample(Samples::Explode, pitchBend, 1, actor->posObj(), a);
+					_sound->mixSample3D(Samples::Explode, pitchBend, 1, actor->posObj(), a);
 					if (actor->_bonusParameter.cloverleaf || actor->_bonusParameter.kashes || actor->_bonusParameter.key || actor->_bonusParameter.lifepoints || actor->_bonusParameter.magicpoints) {
 						if (!actor->_bonusParameter.givenNothing) {
 							_actor->giveExtraBonus(a);




More information about the Scummvm-git-logs mailing list