aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Kiewitz2016-02-20 14:53:17 +0100
committerMartin Kiewitz2016-02-20 14:53:17 +0100
commit4ad1bbf108ac408be0ae7d53768d040fd9e32500 (patch)
tree9fbf20db70e98c88efeb19283f8ea24cd94f8848
parent62546273ca7deaf03cb1cbad6d99cf34e81ed949 (diff)
downloadscummvm-rg350-4ad1bbf108ac408be0ae7d53768d040fd9e32500.tar.gz
scummvm-rg350-4ad1bbf108ac408be0ae7d53768d040fd9e32500.tar.bz2
scummvm-rg350-4ad1bbf108ac408be0ae7d53768d040fd9e32500.zip
AGI: Add detection for fan games with broken volume bug #7035
Plenty of fan games set volume to mute, because they thought 15 would be loudest. It's in fact "mute" in AGI. Those games were made primarily for PC AGI, which did not use the volume setting. We do, so such games would get muted audio. We try to detect such games. Hopefully fully fixes bug #7035. Too many games to try them all out.
-rw-r--r--engines/agi/agi.cpp3
-rw-r--r--engines/agi/agi.h3
-rw-r--r--engines/agi/cycle.cpp2
-rw-r--r--engines/agi/global.cpp27
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;