aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-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;