diff options
Diffstat (limited to 'engines')
-rw-r--r-- | engines/agi/agi.cpp | 3 | ||||
-rw-r--r-- | engines/agi/agi.h | 3 | ||||
-rw-r--r-- | engines/agi/cycle.cpp | 2 | ||||
-rw-r--r-- | engines/agi/global.cpp | 27 |
4 files changed, 34 insertions, 1 deletions
diff --git a/engines/agi/agi.cpp b/engines/agi/agi.cpp index d01b00aa9a..ec10344cfb 100644 --- a/engines/agi/agi.cpp +++ b/engines/agi/agi.cpp @@ -401,9 +401,12 @@ AgiEngine::AgiEngine(OSystem *syst, const AGIGameDescription *gameDesc) : AgiBas setupOpcodes(); _game._curLogic = NULL; + _veryFirstInitialCycle = true; _instructionCounter = 0; resetGetVarSecondsHeuristic(); + _setVolumeBrokenFangame = false; // for further study see AgiEngine::setVolumeViaScripts() + _lastSaveTime = 0; memset(_keyQueue, 0, sizeof(_keyQueue)); diff --git a/engines/agi/agi.h b/engines/agi/agi.h index 6540eea0f5..98d6bcff8a 100644 --- a/engines/agi/agi.h +++ b/engines/agi/agi.h @@ -863,8 +863,11 @@ public: void executeAgiCommand(uint8, uint8 *); private: + bool _veryFirstInitialCycle; /**< signals, that currently the very first cycle is executed (restarts, etc. do not count!) */ uint32 _instructionCounter; /**< counts every instruction, that got executed, can wrap around */ + bool _setVolumeBrokenFangame; + void resetGetVarSecondsHeuristic(); void getVarSecondsHeuristicTrigger(); uint32 _getVarSecondsHeuristicLastInstructionCounter; /**< last time VM_VAR_SECONDS were read */ diff --git a/engines/agi/cycle.cpp b/engines/agi/cycle.cpp index 8ccf69a2fc..211513ca36 100644 --- a/engines/agi/cycle.cpp +++ b/engines/agi/cycle.cpp @@ -153,9 +153,11 @@ void AgiEngine::interpretCycle() { oldScore = getVar(VM_VAR_SCORE); setFlag(VM_FLAG_ENTERED_CLI, false); _game.exitAllLogics = false; + _veryFirstInitialCycle = false; artificialDelay_CycleDone(); resetControllers(); } + _veryFirstInitialCycle = false; artificialDelay_CycleDone(); resetControllers(); diff --git a/engines/agi/global.cpp b/engines/agi/global.cpp index 48e1c224ce..23256f27fb 100644 --- a/engines/agi/global.cpp +++ b/engines/agi/global.cpp @@ -87,7 +87,32 @@ byte AgiEngine::getVar(int16 varNr) { // 15 - mute void AgiEngine::setVolumeViaScripts(byte newVolume) { newVolume = CLIP<byte>(newVolume, 0, 15); - newVolume = 15 - newVolume; // turn volume around + + if (_veryFirstInitialCycle) { + // WORKAROUND: + // The very first cycle is currently running and volume got changed + // This is surely the initial value. For plenty of fan games, a default of 15 is set + // Which actually means "mute" in AGI, but AGI on PC used PC speaker, which did not use + // volume setting. We do. So we detect such a situation and set a flag, so that the + // volume will get interpreted "correctly" for those fan games. + // Note: not all fan games are broken in that regard! + // See bug #7035 + if (getFeatures() & GF_FANMADE) { + // We only check for fan games, Sierra always did it properly of course + if (newVolume == 15) { + // Volume gets set to mute at the start? + // Probably broken fan game detected, set flag + debug("Broken volume in fan game detected, enabling workaround"); + _setVolumeBrokenFangame = true; + } + } + } + + if (!_setVolumeBrokenFangame) { + // In AGI 15 is mute, 0 is loudest + // Some fan games set this incorrectly as 15 for loudest, 0 for mute + newVolume = 15 - newVolume; // turn volume around + } int scummVMVolume = newVolume * Audio::Mixer::kMaxMixerVolume / 15; bool scummVMMute = false; |