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

neuromancer noreply at scummvm.org
Sat Mar 9 07:24:20 UTC 2024


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

Summary:
95b29b9b82 FREESCAPE: initial implementation of loadSpeakerFxZX
c93a209b16 FREESCAPE: improved zx sound reading and emulation
1562c8dd9f FREESCAPE: added basic code for zx sounds
dfda92956a FREESCAPE: added more sounds for dark and eclipse in zx


Commit: 95b29b9b82c2d96a1f7409f811f1802be2d49f88
    https://github.com/scummvm/scummvm/commit/95b29b9b82c2d96a1f7409f811f1802be2d49f88
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2024-03-09T08:15:06+01:00

Commit Message:
FREESCAPE: initial implementation of loadSpeakerFxZX

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/castle.cpp
    engines/freescape/games/dark/dos.cpp
    engines/freescape/games/dark/zx.cpp
    engines/freescape/games/driller/dos.cpp
    engines/freescape/games/eclipse/dos.cpp
    engines/freescape/sound.cpp


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index 267709e14e3..b032356a0cf 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -383,9 +383,13 @@ public:
 	virtual void playSoundFx(int index, bool sync);
 	virtual void loadSoundsFx(Common::SeekableReadStream *file, int offset, int number);
 	Common::HashMap<uint16, soundFx *> _soundsFx;
-	void loadSpeakerFx(Common::SeekableReadStream *file, int offsetFreq, int offsetDuration);
+	void loadSpeakerFxDOS(Common::SeekableReadStream *file, int offsetFreq, int offsetDuration);
+	void loadSpeakerFxZX(Common::SeekableReadStream *file, int sfxTable, int sfxData);
 	Common::HashMap<uint16, soundSpeakerFx *> _soundsSpeakerFx;
 
+	void playSoundZX(Common::Array<uint16> *data);
+	Common::HashMap<uint16, Common::Array<uint16>*> _soundsSpeakerFxZX;
+
 	// Rendering
 	int _screenW, _screenH;
 	Renderer *_gfx;
diff --git a/engines/freescape/games/castle.cpp b/engines/freescape/games/castle.cpp
index b50485c54e4..d29f970dbde 100644
--- a/engines/freescape/games/castle.cpp
+++ b/engines/freescape/games/castle.cpp
@@ -141,7 +141,7 @@ void CastleEngine::loadAssetsDOSFullGame() {
 		file.open("CME.EXE");
 		stream = unpackEXE(file);
 		if (stream) {
-			loadSpeakerFx(stream, 0x636d + 0x200, 0x63ed + 0x200);
+			loadSpeakerFxDOS(stream, 0x636d + 0x200, 0x63ed + 0x200);
 		}
 
 		delete stream;
diff --git a/engines/freescape/games/dark/dos.cpp b/engines/freescape/games/dark/dos.cpp
index c05a82596ef..84e9fb32445 100644
--- a/engines/freescape/games/dark/dos.cpp
+++ b/engines/freescape/games/dark/dos.cpp
@@ -105,7 +105,7 @@ void DarkEngine::loadAssetsDOSDemo() {
 		if (!file.isOpen())
 			error("Failed to open DSIDEE.EXE");
 
-		loadSpeakerFx(&file, 0x4837 + 0x200, 0x46e8 + 0x200);
+		loadSpeakerFxDOS(&file, 0x4837 + 0x200, 0x46e8 + 0x200);
 		loadMessagesFixedSize(&file, 0x4525, 16, 27);
 		loadMessagesFixedSize(&file, 0x993f - 2, 308, 5);
 		loadFonts(&file, 0xa598);
@@ -140,7 +140,7 @@ void DarkEngine::loadAssetsDOSDemo() {
 		if (!file.isOpen())
 			error("Failed to open DSIDEC.EXE");
 
-		loadSpeakerFx(&file, 0x3077 + 0x200, 0x2f28 + 0x200);
+		loadSpeakerFxDOS(&file, 0x3077 + 0x200, 0x2f28 + 0x200);
 		loadFonts(&file, 0x8907);
 		loadMessagesFixedSize(&file, 0x2d65, 16, 27);
 		loadMessagesFixedSize(&file, 0x7c3a, 308, 5);
@@ -173,7 +173,7 @@ void DarkEngine::loadAssetsDOSFullGame() {
 		if (!file.isOpen())
 			error("Failed to open DSIDEE.EXE");
 
-		loadSpeakerFx(&file, 0x4837 + 0x200, 0x46e8 + 0x200);
+		loadSpeakerFxDOS(&file, 0x4837 + 0x200, 0x46e8 + 0x200);
 		loadFonts(&file, 0xa113);
 		loadMessagesFixedSize(&file, 0x4525, 16, 27);
 		loadGlobalObjects(&file, 0x3d04, 23);
@@ -207,7 +207,7 @@ void DarkEngine::loadAssetsDOSFullGame() {
 		if (!file.isOpen())
 			error("Failed to open DSIDEC.EXE");
 
-		loadSpeakerFx(&file, 0x3077 + 0x200, 0x2f28 + 0x200);
+		loadSpeakerFxDOS(&file, 0x3077 + 0x200, 0x2f28 + 0x200);
 		loadFonts(&file, 0x8496);
 		loadMessagesFixedSize(&file, 0x2d65, 16, 27);
 		loadGlobalObjects(&file, 0x2554, 23);
diff --git a/engines/freescape/games/dark/zx.cpp b/engines/freescape/games/dark/zx.cpp
index 2a02a5b7a44..3901e5ffd11 100644
--- a/engines/freescape/games/dark/zx.cpp
+++ b/engines/freescape/games/dark/zx.cpp
@@ -64,6 +64,7 @@ void DarkEngine::loadAssetsZXFullGame() {
 		addECDs(it._value);
 		addSkanner(it._value);
 	}
+	loadSpeakerFxZX(&file, 0x9c1, 0xa55);
 
 	_indicators.push_back(loadBundledImage("dark_fallen_indicator"));
 	_indicators.push_back(loadBundledImage("dark_crouch_indicator"));
diff --git a/engines/freescape/games/driller/dos.cpp b/engines/freescape/games/driller/dos.cpp
index e5e34f2307c..73b25a9b735 100644
--- a/engines/freescape/games/driller/dos.cpp
+++ b/engines/freescape/games/driller/dos.cpp
@@ -316,7 +316,7 @@ void DrillerEngine::loadAssetsDOSFullGame() {
 		if (!file.isOpen())
 			error("Failed to open DRILLE.EXE");
 
-		loadSpeakerFx(&file, 0x4397 + 0x200, 0x4324 + 0x200);
+		loadSpeakerFxDOS(&file, 0x4397 + 0x200, 0x4324 + 0x200);
 		loadMessagesFixedSize(&file, 0x4135, 14, 20);
 		loadFonts(&file, 0x99dd);
 		loadGlobalObjects(&file, 0x3b42, 8);
@@ -341,7 +341,7 @@ void DrillerEngine::loadAssetsDOSFullGame() {
 		if (!file.isOpen())
 			error("Failed to open DRILLC.EXE");
 
-		loadSpeakerFx(&file, 0x27e7 + 0x200, 0x2774 + 0x200);
+		loadSpeakerFxDOS(&file, 0x27e7 + 0x200, 0x2774 + 0x200);
 
 		loadFonts(&file, 0x07a4a);
 		loadMessagesFixedSize(&file, 0x2585, 14, 20);
diff --git a/engines/freescape/games/eclipse/dos.cpp b/engines/freescape/games/eclipse/dos.cpp
index df856246ed0..300859d6daf 100644
--- a/engines/freescape/games/eclipse/dos.cpp
+++ b/engines/freescape/games/eclipse/dos.cpp
@@ -56,7 +56,7 @@ void EclipseEngine::loadAssetsDOSFullGame() {
 
 		loadMessagesFixedSize(&file, 0x710f, 16, 17);
 		loadSoundsFx(&file, 0xd670, 1);
-		loadSpeakerFx(&file, 0x7396 + 0x200, 0x72a1 + 0x200);
+		loadSpeakerFxDOS(&file, 0x7396 + 0x200, 0x72a1 + 0x200);
 		loadFonts(&file, 0xd403);
 		load8bitBinary(&file, 0x3ce0, 16);
 		for (auto &it : _areaMap) {
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index 9a874028a2e..a7f4852da0c 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -27,7 +27,105 @@
 
 namespace Freescape {
 
-void FreescapeEngine::loadSpeakerFx(Common::SeekableReadStream *file, int offsetFreq, int offsetTable) {
+void FreescapeEngine::loadSpeakerFxZX(Common::SeekableReadStream *file, int sfxTable, int sfxData) {
+	for (int i = 1; i < 34; i++) {
+		debug("Reading sound table entry: %d ", i);
+		_soundsSpeakerFxZX[i] = new Common::Array<uint16>();
+		int soundIdx = (i - 1) * 4;
+		file->seek(sfxTable + soundIdx);
+
+		byte *SFXtempStruct = (byte *)malloc(8 * sizeof(byte));
+		for (int j = 0; j < 8; j++)
+			SFXtempStruct[j] = 0;
+
+		uint8 dataIndex = file->readByte();
+		uint16 soundValue = file->readUint16LE();
+		SFXtempStruct[0] = file->readByte();
+
+		file->seek(sfxData + dataIndex * 4);
+		uint8 soundType = file->readByte();
+		int original_sound_ptr = sfxData + dataIndex * 4 + 1;
+		int sound_ptr = original_sound_ptr;
+		uint8 soundSize = 0;
+		int16 repetitions = 0;
+		debug("dataIndex: %x, value: %x, SFXtempStruct[0]: %x, type: %x", dataIndex, soundValue, SFXtempStruct[0], soundType);
+
+		if ((soundType & 0x80) == 0) {
+			SFXtempStruct[6] = 0;
+			SFXtempStruct[4] = soundType;
+
+			while (true) {
+				while (true) {
+					file->seek(sound_ptr);
+					soundSize = file->readByte();
+					SFXtempStruct[1] = soundSize;
+					SFXtempStruct[2] = file->readByte();
+					SFXtempStruct[3] = file->readByte();
+
+					do {
+						uint32 var9 = 0xffffff & (7 * soundValue);
+						int16 soundValueVar = int16(var9) - 0x1e;
+						if (soundValueVar < 0)
+							soundValueVar = 1;
+
+						debug("playSFX(%x, %x)", soundValueVar >> 8, soundValueVar & 0xff);
+						_soundsSpeakerFxZX[i]->push_back(soundValueVar);
+						uint8 var6 = 0;
+
+						if ((SFXtempStruct[2] & 0x80) != 0) {
+							var6 = 0xff;
+						}
+
+						soundValue = soundValue + (((var6 << 8) | SFXtempStruct[2]) & 0xfff);
+						soundSize = soundSize - 1;
+					} while (soundSize != 0);
+					SFXtempStruct[5] = SFXtempStruct[5] + 1;
+					if (SFXtempStruct[5] == SFXtempStruct[4])
+						break;
+
+					sound_ptr = original_sound_ptr + SFXtempStruct[5] * 3;
+				}
+
+				soundSize = SFXtempStruct[0];
+				SFXtempStruct[0] = soundSize - 1;
+				sound_ptr = original_sound_ptr;
+				if ((soundSize - 1) == 0) 
+					break;
+				SFXtempStruct[5] = 0;
+			}
+		} else if (soundType & 0x80) {
+			file->seek(sound_ptr);
+			for (int j = 1; j <= 7; j++) {
+				SFXtempStruct[j] = file->readByte();
+				debug("SFXtempStruct[%d]: %x", j, SFXtempStruct[j]);
+				//sound_ptr = sound_ptr + 1;
+			}
+			soundSize = SFXtempStruct[0];
+			repetitions = SFXtempStruct[1] | (SFXtempStruct[2] << 8);
+			uint16 increment = SFXtempStruct[5] | (SFXtempStruct[6] << 8);
+			uint16 soundValueVar = soundValue;
+			debug("Repetitions: %x", repetitions);
+			if ((soundType & 0x7f) == 1) {
+				do  {
+					do {
+						debug("playSFX(%x, %x)", soundValueVar >> 8, soundValueVar & 0xff);
+						_soundsSpeakerFxZX[i]->push_back(soundValueVar);
+						//queueSoundConst(soundValueVar & 0xff, soundValueVar >> 8);
+
+						soundValueVar += increment; 
+						repetitions--;
+					} while ((byte)((byte)repetitions | (byte)((ushort)repetitions >> 8)) != 0);
+					soundSize--;
+					repetitions = SFXtempStruct[1] | (SFXtempStruct[2] << 8);
+					soundValueVar = soundValue;
+				} while (soundSize != 0);
+			}
+		}
+	}
+	//assert(0);
+}
+
+void FreescapeEngine::loadSpeakerFxDOS(Common::SeekableReadStream *file, int offsetFreq, int offsetTable) {
 	for (int i = 1; i < 20; i++) {
 		debugC(1, kFreescapeDebugParser, "Reading sound table entry: %d ", i);
 		int soundIdx = (i - 1) * 4;
@@ -112,6 +210,9 @@ void FreescapeEngine::playSound(int index, bool sync) {
 			debugC(1, kFreescapeDebugMedia, "WARNING: Sound %d is not available", index);
 
 		return;
+	} else if (isSpectrum()) {
+		playSoundZX(_soundsSpeakerFxZX[index]);
+		return;
 	}
 
 	switch (index) {
@@ -273,6 +374,18 @@ uint16 FreescapeEngine::playSoundDOSSpeaker(uint16 frequencyStart, soundSpeakerF
 	return freq;
 }
 
+void FreescapeEngine::playSoundZX(Common::Array<uint16> *data) {
+	for (auto &it : *data) {
+		uint16 value = it;
+		float hzFreq = (value & 0xff);
+		debug("hz: %f, duration: %d", hzFreq, value >> 8);
+		_speaker->playQueue(Audio::PCSpeaker::kWaveFormSquare, hzFreq, 5 * 1000 * (value >> 8));
+	}
+
+	_mixer->stopHandle(_soundFxHandle);
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundFxHandle, _speaker, -1, Audio::Mixer::kMaxChannelVolume / 2, 0, DisposeAfterUse::NO);
+}
+
 void FreescapeEngine::playSoundDOS(soundSpeakerFx *speakerFxInfo, bool sync) {
 	uint freq = speakerFxInfo->frequencyStart;
 


Commit: c93a209b1653c796cfe1820488dad0eca04db0a3
    https://github.com/scummvm/scummvm/commit/c93a209b1653c796cfe1820488dad0eca04db0a3
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2024-03-09T08:15:06+01:00

Commit Message:
FREESCAPE: improved zx sound reading and emulation

Changed paths:
    engines/freescape/freescape.h
    engines/freescape/games/dark/dark.cpp
    engines/freescape/movement.cpp
    engines/freescape/sound.cpp
    engines/freescape/sound.h


diff --git a/engines/freescape/freescape.h b/engines/freescape/freescape.h
index b032356a0cf..509723b36f5 100644
--- a/engines/freescape/freescape.h
+++ b/engines/freescape/freescape.h
@@ -387,8 +387,9 @@ public:
 	void loadSpeakerFxZX(Common::SeekableReadStream *file, int sfxTable, int sfxData);
 	Common::HashMap<uint16, soundSpeakerFx *> _soundsSpeakerFx;
 
-	void playSoundZX(Common::Array<uint16> *data);
-	Common::HashMap<uint16, Common::Array<uint16>*> _soundsSpeakerFxZX;
+	void playSoundZX(Common::Array<soundUnitZX> *data);
+	Common::HashMap<uint16, Common::Array<soundUnitZX>*> _soundsSpeakerFxZX;
+	int _nextSoundToPlay = 1;
 
 	// Rendering
 	int _screenW, _screenH;
diff --git a/engines/freescape/games/dark/dark.cpp b/engines/freescape/games/dark/dark.cpp
index 89f5f65f268..1427d8c464c 100644
--- a/engines/freescape/games/dark/dark.cpp
+++ b/engines/freescape/games/dark/dark.cpp
@@ -507,8 +507,12 @@ void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
 		playSound(9, true);
 	} else if (areaID == _endArea && entranceID == _endEntrance) {
 		_pitch = 10;
-	} else
-		playSound(5, false);
+	} else {
+		if (isSpectrum())
+			playSound(0x1c, false);
+		else
+			playSound(5, false);
+	}
 
 	debugC(1, kFreescapeDebugMove, "starting player position: %f, %f, %f", _position.x(), _position.y(), _position.z());
 	clearTemporalMessages();
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index ca3f7ba5ed2..c03786fd819 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -184,7 +184,10 @@ void FreescapeEngine::activate() {
 
 
 void FreescapeEngine::shoot() {
-	playSound(1, false);
+	if (isDark() && isDark())
+		playSound(0xf, false);
+	else 
+		playSound(8, false);
 	g_system->delayMillis(2);
 	_shootingFrames = 10;
 
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index a7f4852da0c..7c0b063bf53 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -29,8 +29,8 @@ namespace Freescape {
 
 void FreescapeEngine::loadSpeakerFxZX(Common::SeekableReadStream *file, int sfxTable, int sfxData) {
 	for (int i = 1; i < 34; i++) {
-		debug("Reading sound table entry: %d ", i);
-		_soundsSpeakerFxZX[i] = new Common::Array<uint16>();
+		//debug("Reading sound table entry: %d ", i);
+		_soundsSpeakerFxZX[i] = new Common::Array<soundUnitZX>();
 		int soundIdx = (i - 1) * 4;
 		file->seek(sfxTable + soundIdx);
 
@@ -48,7 +48,7 @@ void FreescapeEngine::loadSpeakerFxZX(Common::SeekableReadStream *file, int sfxT
 		int sound_ptr = original_sound_ptr;
 		uint8 soundSize = 0;
 		int16 repetitions = 0;
-		debug("dataIndex: %x, value: %x, SFXtempStruct[0]: %x, type: %x", dataIndex, soundValue, SFXtempStruct[0], soundType);
+		//debug("dataIndex: %x, value: %x, SFXtempStruct[0]: %x, type: %x", dataIndex, soundValue, SFXtempStruct[0], soundType);
 
 		if ((soundType & 0x80) == 0) {
 			SFXtempStruct[6] = 0;
@@ -57,26 +57,38 @@ void FreescapeEngine::loadSpeakerFxZX(Common::SeekableReadStream *file, int sfxT
 			while (true) {
 				while (true) {
 					file->seek(sound_ptr);
+					//debug("start sound ptr: %x", sound_ptr);
 					soundSize = file->readByte();
 					SFXtempStruct[1] = soundSize;
 					SFXtempStruct[2] = file->readByte();
 					SFXtempStruct[3] = file->readByte();
 
+					//for (int j = 0; j <= 7; j++)
+					//	debug("SFXtempStruct[%d]: %x", j, SFXtempStruct[j]);
+
 					do {
-						uint32 var9 = 0xffffff & (7 * soundValue);
-						int16 soundValueVar = int16(var9) - 0x1e;
-						if (soundValueVar < 0)
-							soundValueVar = 1;
+						uint32 var9 = 0xffffff & (SFXtempStruct[3] * 0xd0);
+						uint32 var10 = var9 / soundValue;
+
+						var9 = 0xffffff & (7 * soundValue);
+						uint16 var5 = (0xffff & var9) - 0x1e;
+						if ((short)var5 < 0)
+							var5 = 1;
 
-						debug("playSFX(%x, %x)", soundValueVar >> 8, soundValueVar & 0xff);
-						_soundsSpeakerFxZX[i]->push_back(soundValueVar);
-						uint8 var6 = 0;
+						soundUnitZX soundUnit;
+						soundUnit.freqTimesSeconds = (var10 & 0xffff) + 1;
+						soundUnit.tStates = var5;
+						//debug("playSFX(%x, %x)", soundUnit.freqTimesSeconds, soundUnit.tStates);
+						_soundsSpeakerFxZX[i]->push_back(soundUnit);
+						int16 var4 = 0;
 
 						if ((SFXtempStruct[2] & 0x80) != 0) {
-							var6 = 0xff;
+							var4 = 0xff;
 						}
-
-						soundValue = soundValue + (((var6 << 8) | SFXtempStruct[2]) & 0xfff);
+						//debug("var4: %d", var4);
+						//debug("soundValue delta: %d", int16(((var4 << 8) | SFXtempStruct[2])));
+						soundValue = soundValue + int16(((var4 << 8) | SFXtempStruct[2]));
+						//debug("soundValue: %x", soundValue);
 						soundSize = soundSize - 1;
 					} while (soundSize != 0);
 					SFXtempStruct[5] = SFXtempStruct[5] + 1;
@@ -84,6 +96,7 @@ void FreescapeEngine::loadSpeakerFxZX(Common::SeekableReadStream *file, int sfxT
 						break;
 
 					sound_ptr = original_sound_ptr + SFXtempStruct[5] * 3;
+					//debug("sound ptr: %x", sound_ptr);
 				}
 
 				soundSize = SFXtempStruct[0];
@@ -97,30 +110,35 @@ void FreescapeEngine::loadSpeakerFxZX(Common::SeekableReadStream *file, int sfxT
 			file->seek(sound_ptr);
 			for (int j = 1; j <= 7; j++) {
 				SFXtempStruct[j] = file->readByte();
-				debug("SFXtempStruct[%d]: %x", j, SFXtempStruct[j]);
+				//debug("SFXtempStruct[%d]: %x", j, SFXtempStruct[j]);
 				//sound_ptr = sound_ptr + 1;
 			}
 			soundSize = SFXtempStruct[0];
 			repetitions = SFXtempStruct[1] | (SFXtempStruct[2] << 8);
-			uint16 increment = SFXtempStruct[5] | (SFXtempStruct[6] << 8);
-			uint16 soundValueVar = soundValue;
-			debug("Repetitions: %x", repetitions);
+			uint16 var5 = soundValue;
+			//debug("Repetitions: %x", repetitions);
 			if ((soundType & 0x7f) == 1) {
 				do  {
 					do {
-						debug("playSFX(%x, %x)", soundValueVar >> 8, soundValueVar & 0xff);
-						_soundsSpeakerFxZX[i]->push_back(soundValueVar);
-						//queueSoundConst(soundValueVar & 0xff, soundValueVar >> 8);
+						soundUnitZX soundUnit;
+						soundUnit.tStates = var5;
+						soundUnit.freqTimesSeconds = SFXtempStruct[3] | (SFXtempStruct[4] << 8);
+						//debug("playSFX(%x, %x)", soundUnit.freqTimesSeconds, soundUnit.tStates);
+						_soundsSpeakerFxZX[i]->push_back(soundUnit);
+						repetitions = repetitions - 1;
+						var5 = var5 + (SFXtempStruct[5] | (SFXtempStruct[6] << 8)); 
 
-						soundValueVar += increment; 
-						repetitions--;
 					} while ((byte)((byte)repetitions | (byte)((ushort)repetitions >> 8)) != 0);
-					soundSize--;
+					soundSize = soundSize - 1;
 					repetitions = SFXtempStruct[1] | (SFXtempStruct[2] << 8);
-					soundValueVar = soundValue;
+					var5 = soundValue;
 				} while (soundSize != 0);
+			} else if ((soundType & 0x7f) == 2) { 
+			} else {
+				debug("Unknown sound type: %x", soundType);
 			}
 		}
+		free(SFXtempStruct);
 	}
 	//assert(0);
 }
@@ -374,16 +392,18 @@ uint16 FreescapeEngine::playSoundDOSSpeaker(uint16 frequencyStart, soundSpeakerF
 	return freq;
 }
 
-void FreescapeEngine::playSoundZX(Common::Array<uint16> *data) {
+void FreescapeEngine::playSoundZX(Common::Array<soundUnitZX> *data) {
 	for (auto &it : *data) {
-		uint16 value = it;
-		float hzFreq = (value & 0xff);
-		debug("hz: %f, duration: %d", hzFreq, value >> 8);
-		_speaker->playQueue(Audio::PCSpeaker::kWaveFormSquare, hzFreq, 5 * 1000 * (value >> 8));
+		soundUnitZX value = it;
+		float hzFreq = 1 / ((value.tStates + 30.125) / 437500.0);
+		float waveDuration = value.freqTimesSeconds / hzFreq;
+		waveDuration = 400 * 1000 * (waveDuration + 1);
+		debugC(1, kFreescapeDebugMedia, "hz: %f, duration: %d", hzFreq, waveDuration);
+		_speaker->playQueue(Audio::PCSpeaker::kWaveFormSquare, hzFreq, waveDuration);
 	}
 
 	_mixer->stopHandle(_soundFxHandle);
-	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundFxHandle, _speaker, -1, Audio::Mixer::kMaxChannelVolume / 2, 0, DisposeAfterUse::NO);
+	_mixer->playStream(Audio::Mixer::kSFXSoundType, &_soundFxHandle, _speaker, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
 }
 
 void FreescapeEngine::playSoundDOS(soundSpeakerFx *speakerFxInfo, bool sync) {
diff --git a/engines/freescape/sound.h b/engines/freescape/sound.h
index 422a6f94685..28fae66a8fe 100644
--- a/engines/freescape/sound.h
+++ b/engines/freescape/sound.h
@@ -33,6 +33,11 @@ struct soundFx {
 	byte *data;
 };
 
+struct soundUnitZX {
+	uint16 freqTimesSeconds;
+	uint16 tStates;
+};
+
 struct soundSpeakerFx {
 	uint16 frequencyStart;
 	uint8 frequencyDuration;


Commit: 1562c8dd9f488ffcae3a8a67e2f91cb6c5b8e3ef
    https://github.com/scummvm/scummvm/commit/1562c8dd9f488ffcae3a8a67e2f91cb6c5b8e3ef
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2024-03-09T08:15:06+01:00

Commit Message:
FREESCAPE: added basic code for zx sounds

Changed paths:
    engines/freescape/games/dark/dark.cpp
    engines/freescape/games/dark/zx.cpp
    engines/freescape/sound.cpp
    engines/freescape/sound.h


diff --git a/engines/freescape/games/dark/dark.cpp b/engines/freescape/games/dark/dark.cpp
index 1427d8c464c..adc60932a32 100644
--- a/engines/freescape/games/dark/dark.cpp
+++ b/engines/freescape/games/dark/dark.cpp
@@ -504,7 +504,10 @@ void DarkEngine::gotoArea(uint16 areaID, int entranceID) {
 	if (areaID == _startArea && entranceID == _startEntrance) {
 		_yaw = 90;
 		_pitch = 0;
-		playSound(9, true);
+		if (isSpectrum())
+			playSound(11, true);
+		else
+			playSound(9, true);
 	} else if (areaID == _endArea && entranceID == _endEntrance) {
 		_pitch = 10;
 	} else {
@@ -644,6 +647,8 @@ void DarkEngine::drawIndicator(Graphics::Surface *surface, int xPosition, int yP
 }
 
 void DarkEngine::drawSensorShoot(Sensor *sensor) {
+	if (isSpectrum())
+		playSound(2, false);
 	Math::Vector3d target;
 	target = _position;
 	target.y() = target.y() - _playerHeight;
diff --git a/engines/freescape/games/dark/zx.cpp b/engines/freescape/games/dark/zx.cpp
index 3901e5ffd11..85b013276a8 100644
--- a/engines/freescape/games/dark/zx.cpp
+++ b/engines/freescape/games/dark/zx.cpp
@@ -98,6 +98,7 @@ void DarkEngine::loadAssetsZXDemo() {
 
 	loadMessagesFixedSize(&file, 0x56b, 16, 27);
 	loadMessagesFixedSize(&file, 0x5761, 264, 5);
+	loadSpeakerFxZX(&file, 0x9c7, 0xa5b);
 
 	loadFonts(&file, 0x6164);
 	loadGlobalObjects(&file, 0x20, 23);
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index 7c0b063bf53..1b848fbb9b7 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -78,6 +78,7 @@ void FreescapeEngine::loadSpeakerFxZX(Common::SeekableReadStream *file, int sfxT
 						soundUnitZX soundUnit;
 						soundUnit.freqTimesSeconds = (var10 & 0xffff) + 1;
 						soundUnit.tStates = var5;
+						soundUnit.multiplier = 400;
 						//debug("playSFX(%x, %x)", soundUnit.freqTimesSeconds, soundUnit.tStates);
 						_soundsSpeakerFxZX[i]->push_back(soundUnit);
 						int16 var4 = 0;
@@ -123,6 +124,7 @@ void FreescapeEngine::loadSpeakerFxZX(Common::SeekableReadStream *file, int sfxT
 						soundUnitZX soundUnit;
 						soundUnit.tStates = var5;
 						soundUnit.freqTimesSeconds = SFXtempStruct[3] | (SFXtempStruct[4] << 8);
+						soundUnit.multiplier = 400;
 						//debug("playSFX(%x, %x)", soundUnit.freqTimesSeconds, soundUnit.tStates);
 						_soundsSpeakerFxZX[i]->push_back(soundUnit);
 						repetitions = repetitions - 1;
@@ -134,6 +136,13 @@ void FreescapeEngine::loadSpeakerFxZX(Common::SeekableReadStream *file, int sfxT
 					var5 = soundValue;
 				} while (soundSize != 0);
 			} else if ((soundType & 0x7f) == 2) { 
+				int size = 2 * (SFXtempStruct[1] + SFXtempStruct[2]);
+
+				soundUnitZX soundUnit;
+				soundUnit.freqTimesSeconds = 100;
+				soundUnit.tStates = 437500 / 100 - 30.125;
+				soundUnit.multiplier = 2 * size;
+				_soundsSpeakerFxZX[i]->push_back(soundUnit);
 			} else {
 				debug("Unknown sound type: %x", soundType);
 			}
@@ -397,8 +406,8 @@ void FreescapeEngine::playSoundZX(Common::Array<soundUnitZX> *data) {
 		soundUnitZX value = it;
 		float hzFreq = 1 / ((value.tStates + 30.125) / 437500.0);
 		float waveDuration = value.freqTimesSeconds / hzFreq;
-		waveDuration = 400 * 1000 * (waveDuration + 1);
-		debugC(1, kFreescapeDebugMedia, "hz: %f, duration: %d", hzFreq, waveDuration);
+		waveDuration = value.multiplier * 1000 * (waveDuration + 1);
+		debugC(1, kFreescapeDebugMedia, "hz: %f, duration: %f", hzFreq, waveDuration);
 		_speaker->playQueue(Audio::PCSpeaker::kWaveFormSquare, hzFreq, waveDuration);
 	}
 
diff --git a/engines/freescape/sound.h b/engines/freescape/sound.h
index 28fae66a8fe..0777c7a6c6e 100644
--- a/engines/freescape/sound.h
+++ b/engines/freescape/sound.h
@@ -36,6 +36,7 @@ struct soundFx {
 struct soundUnitZX {
 	uint16 freqTimesSeconds;
 	uint16 tStates;
+	uint32 multiplier;
 };
 
 struct soundSpeakerFx {


Commit: dfda92956aebf9b1825758220e1cbfe7dc92a476
    https://github.com/scummvm/scummvm/commit/dfda92956aebf9b1825758220e1cbfe7dc92a476
Author: neuromancer (gustavo.grieco at gmail.com)
Date: 2024-03-09T08:15:06+01:00

Commit Message:
FREESCAPE: added more sounds for dark and eclipse in zx

Changed paths:
    engines/freescape/freescape.cpp
    engines/freescape/games/dark/dark.cpp
    engines/freescape/games/eclipse/eclipse.cpp
    engines/freescape/games/eclipse/zx.cpp
    engines/freescape/movement.cpp
    engines/freescape/sound.cpp
    engines/freescape/sound.h


diff --git a/engines/freescape/freescape.cpp b/engines/freescape/freescape.cpp
index e93fdf2aae5..13f2d459ca0 100644
--- a/engines/freescape/freescape.cpp
+++ b/engines/freescape/freescape.cpp
@@ -757,6 +757,8 @@ bool FreescapeEngine::checkIfGameEnded() {
 			insertTemporaryMessage(_crushedMessage, _countdown - 4);
 		_gameStateControl = kFreescapeGameStateEnd;
 	} else if (_forceEndGame) {
+		if (isSpectrum())
+			playSound(8, true);
 		_forceEndGame = false;
 		if (!_forceEndGameMessage.empty())
 			insertTemporaryMessage(_forceEndGameMessage, _countdown - 4);
diff --git a/engines/freescape/games/dark/dark.cpp b/engines/freescape/games/dark/dark.cpp
index adc60932a32..0e10f15e730 100644
--- a/engines/freescape/games/dark/dark.cpp
+++ b/engines/freescape/games/dark/dark.cpp
@@ -383,6 +383,9 @@ bool DarkEngine::checkIfGameEnded() {
 	if (_gameStateVars[kVariableDarkECD] > 0) {
 		int index = _gameStateVars[kVariableDarkECD] - 1;
 		bool destroyed = tryDestroyECD(index);
+		if (isSpectrum())
+			playSound(7, false);
+
 		if (destroyed) {
 			_gameStateVars[kVariableActiveECDs] -= 4;
 			_gameStateVars[k8bitVariableScore] += 52750;
@@ -390,7 +393,10 @@ bool DarkEngine::checkIfGameEnded() {
 		} else {
 			restoreECD(*_currentArea, index);
 			insertTemporaryMessage(_messagesList[1], _countdown - 2);
-			playSound(19, true);
+			if (isSpectrum())
+				playSound(30, false);
+			else 
+				playSound(19, true);
 		}
 		_gameStateVars[kVariableDarkECD] = 0;
 	}
diff --git a/engines/freescape/games/eclipse/eclipse.cpp b/engines/freescape/games/eclipse/eclipse.cpp
index 6247c4217e9..47cc0b67ccd 100644
--- a/engines/freescape/games/eclipse/eclipse.cpp
+++ b/engines/freescape/games/eclipse/eclipse.cpp
@@ -119,6 +119,8 @@ void EclipseEngine::endGame() {
 	}
 
 	if (_endGameKeyPressed && _countdown == 0) {
+		if (isSpectrum())
+			playSound(5, true);
 		_gameStateControl = kFreescapeGameStateRestart;
 	}
 	_endGameKeyPressed = false;
@@ -142,13 +144,20 @@ void EclipseEngine::gotoArea(uint16 areaID, int entranceID) {
 
 	_lastPosition = _position;
 
-	if (areaID == _startArea && entranceID == _startEntrance)
-		playSound(9, true);
-	if (areaID == _endArea && entranceID == _endEntrance) {
+	if (areaID == _startArea && entranceID == _startEntrance) {
+		if (isSpectrum())
+			playSound(7, true);
+		else
+			playSound(9, true);
+	} if (areaID == _endArea && entranceID == _endEntrance) {
 		_flyMode = true;
 		_pitch = 20;
-	} else
-		playSound(5, false);
+	} else {
+		if (isSpectrum())
+			playSound(7, false);
+		else
+			playSound(5, false);
+	}
 
 	_gfx->_keyColor = 0;
 	swapPalette(areaID);
@@ -193,8 +202,11 @@ void EclipseEngine::borderScreen() {
 				drawFullscreenMessageAndWait(_messagesList[23]);
 			} else if (_variant & GF_ZX_DEMO_CRASH) {
 				drawFullscreenMessageAndWait(_messagesList[9]);
+				playSound(3, true);
 				drawFullscreenMessageAndWait(_messagesList[10]);
+				playSound(3, true);
 				drawFullscreenMessageAndWait(_messagesList[11]);
+				playSound(3, true);
 			}
 		} else {
 			FreescapeEngine::borderScreen();
diff --git a/engines/freescape/games/eclipse/zx.cpp b/engines/freescape/games/eclipse/zx.cpp
index 679602aee36..2f34f67e0c3 100644
--- a/engines/freescape/games/eclipse/zx.cpp
+++ b/engines/freescape/games/eclipse/zx.cpp
@@ -60,6 +60,7 @@ void EclipseEngine::loadAssetsZXDemo() {
 		loadFonts(&file, 0x5f7b);
 		load8bitBinary(&file, 0x6173, 4);
 	} else if (_variant & GF_ZX_DEMO_CRASH) {
+		loadSpeakerFxZX(&file, 0x65c, 0x6b0);
 		loadMessagesFixedSize(&file, 0x364, 16, 9);
 		loadMessagesFixedSize(&file, 0x5901, 264, 5);
 		loadFonts(&file, 0x6589);
diff --git a/engines/freescape/movement.cpp b/engines/freescape/movement.cpp
index c03786fd819..aa6ff3001a8 100644
--- a/engines/freescape/movement.cpp
+++ b/engines/freescape/movement.cpp
@@ -184,10 +184,16 @@ void FreescapeEngine::activate() {
 
 
 void FreescapeEngine::shoot() {
-	if (isDark() && isDark())
-		playSound(0xf, false);
-	else 
+	if (isSpectrum()) {
+		if (isDark())
+			playSound(15, false);
+		else if (isEclipse())
+			playSound(5, false);
+		else 
+			playSound(8, false);
+	} else 
 		playSound(8, false);
+
 	g_system->delayMillis(2);
 	_shootingFrames = 10;
 
diff --git a/engines/freescape/sound.cpp b/engines/freescape/sound.cpp
index 1b848fbb9b7..318bc838a22 100644
--- a/engines/freescape/sound.cpp
+++ b/engines/freescape/sound.cpp
@@ -28,8 +28,13 @@
 namespace Freescape {
 
 void FreescapeEngine::loadSpeakerFxZX(Common::SeekableReadStream *file, int sfxTable, int sfxData) {
-	for (int i = 1; i < 34; i++) {
-		//debug("Reading sound table entry: %d ", i);
+	int numberSounds = 25;
+
+	if (isDark())
+		numberSounds = 34;
+
+	for (int i = 1; i < numberSounds; i++) {
+		debugC(1, kFreescapeDebugParser, "Reading sound table entry: %d ", i);
 		_soundsSpeakerFxZX[i] = new Common::Array<soundUnitZX>();
 		int soundIdx = (i - 1) * 4;
 		file->seek(sfxTable + soundIdx);
@@ -48,7 +53,7 @@ void FreescapeEngine::loadSpeakerFxZX(Common::SeekableReadStream *file, int sfxT
 		int sound_ptr = original_sound_ptr;
 		uint8 soundSize = 0;
 		int16 repetitions = 0;
-		//debug("dataIndex: %x, value: %x, SFXtempStruct[0]: %x, type: %x", dataIndex, soundValue, SFXtempStruct[0], soundType);
+		debugC(1, kFreescapeDebugParser, "dataIndex: %x, value: %x, SFXtempStruct[0]: %x, type: %x", dataIndex, soundValue, SFXtempStruct[0], soundType);
 
 		if ((soundType & 0x80) == 0) {
 			SFXtempStruct[6] = 0;
@@ -78,7 +83,7 @@ void FreescapeEngine::loadSpeakerFxZX(Common::SeekableReadStream *file, int sfxT
 						soundUnitZX soundUnit;
 						soundUnit.freqTimesSeconds = (var10 & 0xffff) + 1;
 						soundUnit.tStates = var5;
-						soundUnit.multiplier = 400;
+						soundUnit.multiplier = 200;
 						//debug("playSFX(%x, %x)", soundUnit.freqTimesSeconds, soundUnit.tStates);
 						_soundsSpeakerFxZX[i]->push_back(soundUnit);
 						int16 var4 = 0;
@@ -124,7 +129,7 @@ void FreescapeEngine::loadSpeakerFxZX(Common::SeekableReadStream *file, int sfxT
 						soundUnitZX soundUnit;
 						soundUnit.tStates = var5;
 						soundUnit.freqTimesSeconds = SFXtempStruct[3] | (SFXtempStruct[4] << 8);
-						soundUnit.multiplier = 400;
+						soundUnit.multiplier = 1.8;
 						//debug("playSFX(%x, %x)", soundUnit.freqTimesSeconds, soundUnit.tStates);
 						_soundsSpeakerFxZX[i]->push_back(soundUnit);
 						repetitions = repetitions - 1;
@@ -144,7 +149,7 @@ void FreescapeEngine::loadSpeakerFxZX(Common::SeekableReadStream *file, int sfxT
 				soundUnit.multiplier = 2 * size;
 				_soundsSpeakerFxZX[i]->push_back(soundUnit);
 			} else {
-				debug("Unknown sound type: %x", soundType);
+				debugC(1, kFreescapeDebugParser, "Unknown sound type: %x", soundType);
 			}
 		}
 		free(SFXtempStruct);
diff --git a/engines/freescape/sound.h b/engines/freescape/sound.h
index 0777c7a6c6e..c10e866b9d1 100644
--- a/engines/freescape/sound.h
+++ b/engines/freescape/sound.h
@@ -36,7 +36,7 @@ struct soundFx {
 struct soundUnitZX {
 	uint16 freqTimesSeconds;
 	uint16 tStates;
-	uint32 multiplier;
+	float multiplier;
 };
 
 struct soundSpeakerFx {




More information about the Scummvm-git-logs mailing list