[Scummvm-git-logs] scummvm master -> 8d228df41853d78a6dcaa20f5b086d9006605f5e
elasota
noreply at scummvm.org
Tue Apr 4 02:09:44 UTC 2023
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:
8d228df418 VCRUISE: Add ambient sound support
Commit: 8d228df41853d78a6dcaa20f5b086d9006605f5e
https://github.com/scummvm/scummvm/commit/8d228df41853d78a6dcaa20f5b086d9006605f5e
Author: elasota (ejlasota at gmail.com)
Date: 2023-04-03T22:09:25-04:00
Commit Message:
VCRUISE: Add ambient sound support
Changed paths:
engines/vcruise/runtime.cpp
engines/vcruise/runtime.h
diff --git a/engines/vcruise/runtime.cpp b/engines/vcruise/runtime.cpp
index d7e857a8471..7dc2e5dc514 100644
--- a/engines/vcruise/runtime.cpp
+++ b/engines/vcruise/runtime.cpp
@@ -385,6 +385,34 @@ SoundInstance::SoundInstance()
SoundInstance::~SoundInstance() {
}
+RandomAmbientSound::RandomAmbientSound() : volume(0), balance(0), frequency(0), sceneChangesRemaining(0) {
+}
+
+void RandomAmbientSound::write(Common::WriteStream *stream) const {
+ stream->writeUint32BE(name.size());
+ stream->writeString(name);
+
+ stream->writeUint32BE(volume);
+ stream->writeSint32BE(balance);
+
+ stream->writeUint32BE(frequency);
+ stream->writeUint32BE(sceneChangesRemaining);
+}
+
+void RandomAmbientSound::read(Common::ReadStream *stream) {
+ uint nameLen = stream->readUint32BE();
+ if (stream->eos() || stream->err())
+ nameLen = 0;
+
+ name = stream->readString(0, nameLen);
+
+ volume = stream->readUint32BE();
+ balance = stream->readSint32BE();
+
+ frequency = stream->readUint32BE();
+ sceneChangesRemaining = stream->readUint32BE();
+}
+
TriggeredOneShot::TriggeredOneShot() : soundID(0), uniqueSlot(0) {
}
@@ -538,6 +566,7 @@ void SaveGameSnapshot::write(Common::WriteStream *stream) const {
stream->writeUint32BE(inventory.size());
stream->writeUint32BE(sounds.size());
stream->writeUint32BE(triggeredOneShots.size());
+ stream->writeUint32BE(randomAmbientSounds.size());
stream->writeUint32BE(variables.size());
stream->writeUint32BE(timers.size());
@@ -551,6 +580,9 @@ void SaveGameSnapshot::write(Common::WriteStream *stream) const {
for (const TriggeredOneShot &triggeredOneShot : triggeredOneShots)
triggeredOneShot.write(stream);
+ for (const RandomAmbientSound &randomAmbientSound : randomAmbientSounds)
+ randomAmbientSound.write(stream);
+
for (const Common::HashMap<uint32, int32>::Node &var : variables) {
stream->writeUint32BE(var._key);
stream->writeSint32BE(var._value);
@@ -600,6 +632,10 @@ LoadGameOutcome SaveGameSnapshot::read(Common::ReadStream *stream) {
uint numSounds = stream->readUint32BE();
uint numOneShots = stream->readUint32BE();
+ uint numRandomAmbientSounds = 0;
+ if (saveVersion >= 3)
+ numRandomAmbientSounds = stream->readUint32BE();
+
uint numVars = stream->readUint32BE();
uint numTimers = stream->readUint32BE();
@@ -642,7 +678,7 @@ LoadGameOutcome SaveGameSnapshot::read(Common::ReadStream *stream) {
Runtime::Runtime(OSystem *system, Audio::Mixer *mixer, const Common::FSNode &rootFSNode, VCruiseGameID gameID)
: _system(system), _mixer(mixer), _roomNumber(1), _screenNumber(0), _direction(0), _haveHorizPanAnimations(false), _loadedRoomNumber(0), _activeScreenNumber(0),
_gameState(kGameStateBoot), _gameID(gameID), _havePendingScreenChange(false), _forceScreenChange(false), _havePendingReturnToIdleState(false), _havePendingCompletionCheck(false),
- _scriptNextInstruction(0), _escOn(false), _debugMode(false), _fastAnimationMode(false), _musicTrack(0), _panoramaDirectionFlags(0),
+ _havePendingPlayAmbientSounds(false), _ambientSoundFinishTime(0), _scriptNextInstruction(0), _escOn(false), _debugMode(false), _fastAnimationMode(false), _musicTrack(0), _panoramaDirectionFlags(0),
_loadedAnimation(0), _animPendingDecodeFrame(0), _animDisplayingFrame(0), _animFirstFrame(0), _animLastFrame(0), _animStopFrame(0),
_animStartTime(0), _animFramesDecoded(0), _animDecoderState(kAnimDecoderStateStopped),
_animPlayWhileIdle(false), _idleIsOnInteraction(false), _idleHaveClickInteraction(false), _idleHaveDragInteraction(false), _idleInteractionID(0), _haveIdleStaticAnimation(false),
@@ -845,6 +881,11 @@ bool Runtime::runIdle() {
return true;
}
+ if (_havePendingPlayAmbientSounds) {
+ _havePendingPlayAmbientSounds = false;
+ triggerAmbientSounds();
+ }
+
if (_havePendingReturnToIdleState) {
_havePendingReturnToIdleState = false;
@@ -1852,6 +1893,7 @@ void Runtime::changeToScreen(uint roomNumber, uint screenNumber) {
_havePendingReturnToIdleState = true;
_haveIdleStaticAnimation = false;
+ _havePendingPlayAmbientSounds = true;
recordSaveGameSnapshot();
}
@@ -2456,6 +2498,47 @@ bool Runtime::computeEffectiveVolumeAndBalance(SoundInstance &snd) {
return changed;
}
+void Runtime::triggerAmbientSounds() {
+ if (_randomAmbientSounds.size() == 0)
+ return;
+
+ uint32 timestamp = g_system->getMillis();
+
+ if (timestamp < _ambientSoundFinishTime)
+ return;
+
+ // This has been mostly confirmed to match Reah's behavior, including not decrementing sound scene change
+ // counters if an existing sound was playing when this is checked.
+ for (uint i = 0; i < _randomAmbientSounds.size(); i++) {
+ if (_randomAmbientSounds[i].sceneChangesRemaining == 0) {
+ // Found a sound to play
+ RandomAmbientSound sound = Common::move(_randomAmbientSounds[i]);
+ _randomAmbientSounds.remove_at(i);
+
+ if (sound.frequency > 0)
+ sound.sceneChangesRemaining = sound.frequency - 1;
+
+ StackInt_t soundID = 0;
+ SoundInstance *cachedSound = nullptr;
+ resolveSoundByName(sound.name, soundID, cachedSound);
+
+ if (cachedSound) {
+ triggerSound(false, *cachedSound, sound.volume, sound.balance, false, false);
+ if (cachedSound->cache)
+ _ambientSoundFinishTime = timestamp + static_cast<uint>(cachedSound->cache->stream->getLength().msecs());
+ }
+
+ // Requeue at the end
+ _randomAmbientSounds.push_back(Common::move(sound));
+ return;
+ }
+ }
+
+ // No ambient sound was ready
+ for (RandomAmbientSound &snd : _randomAmbientSounds)
+ snd.sceneChangesRemaining--;
+}
+
AnimationDef Runtime::stackArgsToAnimDef(const StackInt_t *args) const {
AnimationDef def;
def.animNum = args[0];
@@ -2952,6 +3035,8 @@ void Runtime::recordSaveGameSnapshot() {
snapshot->listenerX = _listenerX;
snapshot->listenerY = _listenerY;
snapshot->listenerAngle = _listenerAngle;
+
+ snapshot->randomAmbientSounds = _randomAmbientSounds;
}
void Runtime::restoreSaveGameSnapshot() {
@@ -3003,6 +3088,8 @@ void Runtime::restoreSaveGameSnapshot() {
_listenerY = _saveGame->listenerY;
_listenerAngle = _saveGame->listenerAngle;
+ _randomAmbientSounds = _saveGame->randomAmbientSounds;
+
for (const SaveGameSnapshot::Sound &sound : _saveGame->sounds) {
Common::SharedPtr<SoundInstance> si(new SoundInstance());
@@ -3653,14 +3740,20 @@ void Runtime::scriptOpStopAL(ScriptArg_t arg) {
}
void Runtime::scriptOpAddXSound(ScriptArg_t arg) {
- TAKE_STACK_INT(4);
+ TAKE_STACK_INT_NAMED(3, sndParamArgs);
+ TAKE_STACK_STR_NAMED(1, sndNameArgs);
- warning("AddXSound not implemented yet");
- (void)stackArgs;
+ RandomAmbientSound sound;
+ sound.name = sndNameArgs[0];
+ sound.volume = sndParamArgs[0];
+ sound.balance = sndParamArgs[1];
+ sound.frequency = sndParamArgs[2];
+
+ _randomAmbientSounds.push_back(sound);
}
void Runtime::scriptOpClrXSound(ScriptArg_t arg) {
- warning("ClrXSound not implemented yet");
+ _randomAmbientSounds.clear();
}
void Runtime::scriptOpStopSndLA(ScriptArg_t arg) {
diff --git a/engines/vcruise/runtime.h b/engines/vcruise/runtime.h
index 4c8c908edc4..19fe91b5c36 100644
--- a/engines/vcruise/runtime.h
+++ b/engines/vcruise/runtime.h
@@ -229,6 +229,21 @@ struct SoundInstance {
uint32 endTime;
};
+struct RandomAmbientSound {
+ RandomAmbientSound();
+
+ Common::String name;
+
+ uint volume;
+ int32 balance;
+
+ uint frequency;
+ uint sceneChangesRemaining;
+
+ void write(Common::WriteStream *stream) const;
+ void read(Common::ReadStream *stream);
+};
+
struct TriggeredOneShot {
TriggeredOneShot();
@@ -317,7 +332,7 @@ struct SaveGameSnapshot {
LoadGameOutcome read(Common::ReadStream *stream);
static const uint kSaveGameIdentifier = 0x53566372;
- static const uint kSaveGameCurrentVersion = 2;
+ static const uint kSaveGameCurrentVersion = 3;
static const uint kSaveGameEarliestSupportedVersion = 2;
struct InventoryItem {
@@ -371,6 +386,7 @@ struct SaveGameSnapshot {
Common::Array<InventoryItem> inventory;
Common::Array<Sound> sounds;
Common::Array<TriggeredOneShot> triggeredOneShots;
+ Common::Array<RandomAmbientSound> randomAmbientSounds;
Common::HashMap<uint32, int32> variables;
Common::HashMap<uint, uint32> timers;
@@ -623,6 +639,7 @@ private:
void updateSounds(uint32 timestamp);
void update3DSounds();
bool computeEffectiveVolumeAndBalance(SoundInstance &snd);
+ void triggerAmbientSounds();
AnimationDef stackArgsToAnimDef(const StackInt_t *args) const;
void pushAnimDef(const AnimationDef &animDef);
@@ -823,6 +840,9 @@ private:
bool _havePendingCompletionCheck;
GameState _gameState;
+ bool _havePendingPlayAmbientSounds;
+ uint32 _ambientSoundFinishTime;
+
bool _escOn;
bool _debugMode;
bool _fastAnimationMode;
@@ -900,6 +920,7 @@ private:
SoundParams3D _pendingSoundParams3D;
Common::Array<TriggeredOneShot> _triggeredOneShots;
+ Common::Array<RandomAmbientSound> _randomAmbientSounds;
int32 _listenerX;
int32 _listenerY;
More information about the Scummvm-git-logs
mailing list