mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-08 03:47:32 +00:00
![Johannes Schickel](/assets/img/avatar_default.png)
Check this for reference: http://en.wikipedia.org/wiki/Ad_Lib,_Inc. http://www.crossfire-designs.de/images/articles/soundcards/adlib.jpg (note the upper left of the card) This commit does not touch "adlib" and "ADLIB" uses! Also it does not update all the SCUMM detection entries, which still use "Adlib". svn-id: r47279
632 lines
17 KiB
C++
632 lines
17 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* This program is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU General Public License
|
|
* as published by the Free Software Foundation; either version 2
|
|
* of the License, or (at your option) any later version.
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* $URL$
|
|
* $Id$
|
|
*
|
|
*/
|
|
|
|
#include "common/config-manager.h"
|
|
#include "common/EventRecorder.h"
|
|
|
|
#include "sound/mididrv.h"
|
|
#include "sound/mixer.h"
|
|
|
|
#include "kyra/kyra_v1.h"
|
|
#include "kyra/sound_intern.h"
|
|
#include "kyra/resource.h"
|
|
#include "kyra/screen.h"
|
|
#include "kyra/text.h"
|
|
#include "kyra/timer.h"
|
|
#include "kyra/script.h"
|
|
#include "kyra/debugger.h"
|
|
|
|
namespace Kyra {
|
|
|
|
KyraEngine_v1::KyraEngine_v1(OSystem *system, const GameFlags &flags)
|
|
: Engine(system), _flags(flags) {
|
|
_res = 0;
|
|
_sound = 0;
|
|
_text = 0;
|
|
_staticres = 0;
|
|
_timer = 0;
|
|
_emc = 0;
|
|
_debugger = 0;
|
|
|
|
if (_flags.platform == Common::kPlatformAmiga)
|
|
_gameSpeed = 50;
|
|
else
|
|
_gameSpeed = 60;
|
|
_tickLength = (uint8)(1000.0 / _gameSpeed);
|
|
|
|
_trackMap = 0;
|
|
_trackMapSize = 0;
|
|
_lastMusicCommand = -1;
|
|
_curSfxFile = _curMusicTheme = -1;
|
|
|
|
_gameToLoad = -1;
|
|
|
|
_mouseState = -1;
|
|
_deathHandler = -1;
|
|
|
|
memset(_flagsTable, 0, sizeof(_flagsTable));
|
|
|
|
_isSaveAllowed = false;
|
|
|
|
_mouseX = _mouseY = 0;
|
|
|
|
// sets up all engine specific debug levels
|
|
Common::addDebugChannel(kDebugLevelScriptFuncs, "ScriptFuncs", "Script function debug level");
|
|
Common::addDebugChannel(kDebugLevelScript, "Script", "Script interpreter debug level");
|
|
Common::addDebugChannel(kDebugLevelSprites, "Sprites", "Sprite debug level");
|
|
Common::addDebugChannel(kDebugLevelScreen, "Screen", "Screen debug level");
|
|
Common::addDebugChannel(kDebugLevelSound, "Sound", "Sound debug level");
|
|
Common::addDebugChannel(kDebugLevelAnimator, "Animator", "Animator debug level");
|
|
Common::addDebugChannel(kDebugLevelMain, "Main", "Generic debug level");
|
|
Common::addDebugChannel(kDebugLevelGUI, "GUI", "GUI debug level");
|
|
Common::addDebugChannel(kDebugLevelSequence, "Sequence", "Sequence debug level");
|
|
Common::addDebugChannel(kDebugLevelMovie, "Movie", "Movie debug level");
|
|
Common::addDebugChannel(kDebugLevelTimer, "Timer", "Timer debug level");
|
|
|
|
g_eventRec.registerRandomSource(_rnd, "kyra");
|
|
}
|
|
|
|
::GUI::Debugger *KyraEngine_v1::getDebugger() {
|
|
return _debugger;
|
|
}
|
|
|
|
void KyraEngine_v1::pauseEngineIntern(bool pause) {
|
|
Engine::pauseEngineIntern(pause);
|
|
_timer->pause(pause);
|
|
}
|
|
|
|
Common::Error KyraEngine_v1::init() {
|
|
// Setup mixer
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
|
|
|
|
if (!_flags.useDigSound) {
|
|
// We prefer AdLib over MIDI, since generally AdLib is better supported
|
|
MidiDriverType midiDriver = MidiDriver::detectMusicDriver(MDT_PCSPK | MDT_MIDI | MDT_ADLIB);
|
|
|
|
if (_flags.platform == Common::kPlatformFMTowns) {
|
|
if (_flags.gameID == GI_KYRA1)
|
|
_sound = new SoundTowns(this, _mixer);
|
|
else
|
|
_sound = new SoundTownsPC98_v2(this, _mixer);
|
|
} else if (_flags.platform == Common::kPlatformPC98) {
|
|
if (_flags.gameID == GI_KYRA1)
|
|
_sound = new SoundPC98(this, _mixer);
|
|
else
|
|
_sound = new SoundTownsPC98_v2(this, _mixer);
|
|
} else if (_flags.platform == Common::kPlatformAmiga) {
|
|
_sound = new SoundAmiga(this, _mixer);
|
|
} else if (midiDriver == MD_ADLIB) {
|
|
_sound = new SoundAdLibPC(this, _mixer);
|
|
} else {
|
|
Sound::kType type;
|
|
|
|
if (midiDriver == MD_PCSPK)
|
|
type = Sound::kPCSpkr;
|
|
else if (midiDriver == MD_MT32 || ConfMan.getBool("native_mt32"))
|
|
type = Sound::kMidiMT32;
|
|
else
|
|
type = Sound::kMidiGM;
|
|
|
|
MidiDriver *driver = 0;
|
|
|
|
if (midiDriver == MD_PCSPK) {
|
|
driver = new MidiDriver_PCSpeaker(_mixer);
|
|
} else {
|
|
driver = MidiDriver::createMidi(midiDriver);
|
|
if (type == Sound::kMidiMT32)
|
|
driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
|
|
}
|
|
|
|
assert(driver);
|
|
|
|
SoundMidiPC *soundMidiPc = new SoundMidiPC(this, _mixer, driver, type);
|
|
_sound = soundMidiPc;
|
|
assert(_sound);
|
|
|
|
// Unlike some SCUMM games, it's not that the MIDI sounds are
|
|
// missing. It's just that at least at the time of writing they
|
|
// are decidedly inferior to the AdLib ones.
|
|
if (ConfMan.getBool("multi_midi")) {
|
|
SoundAdLibPC *adlib = new SoundAdLibPC(this, _mixer);
|
|
assert(adlib);
|
|
|
|
_sound = new MixedSoundDriver(this, _mixer, soundMidiPc, adlib);
|
|
}
|
|
}
|
|
|
|
assert(_sound);
|
|
}
|
|
|
|
if (_sound)
|
|
_sound->updateVolumeSettings();
|
|
|
|
_res = new Resource(this);
|
|
assert(_res);
|
|
_res->reset();
|
|
|
|
if (_flags.isDemo) {
|
|
// HACK: check whether this is the HOF demo or the LOL demo.
|
|
// The LOL demo needs to be detected and run as KyraEngine_HoF,
|
|
// but the static resource loader and the sequence player will
|
|
// need correct IDs.
|
|
if (_res->exists("scene1.cps"))
|
|
#ifdef ENABLE_LOL
|
|
_flags.gameID = GI_LOL;
|
|
#else
|
|
error("Lands of Lore demo is not supported in this build.");
|
|
#endif // !ENABLE_LOL
|
|
}
|
|
|
|
_staticres = new StaticResource(this);
|
|
assert(_staticres);
|
|
if (!_staticres->init())
|
|
error("_staticres->init() failed");
|
|
if (!screen()->init())
|
|
error("screen()->init() failed");
|
|
_timer = new TimerManager(this, _system);
|
|
assert(_timer);
|
|
setupTimers();
|
|
_emc = new EMCInterpreter(this);
|
|
assert(_emc);
|
|
|
|
setupOpcodeTable();
|
|
readSettings();
|
|
|
|
if (ConfMan.hasKey("save_slot")) {
|
|
_gameToLoad = ConfMan.getInt("save_slot");
|
|
if (!saveFileLoadable(_gameToLoad))
|
|
_gameToLoad = -1;
|
|
}
|
|
|
|
setupKeyMap();
|
|
|
|
// Prevent autosave on game startup
|
|
_lastAutosave = _system->getMillis();
|
|
|
|
return Common::kNoError;
|
|
}
|
|
|
|
KyraEngine_v1::~KyraEngine_v1() {
|
|
for (Common::Array<const Opcode*>::iterator i = _opcodes.begin(); i != _opcodes.end(); ++i)
|
|
delete *i;
|
|
_opcodes.clear();
|
|
_keyMap.clear();
|
|
|
|
delete _res;
|
|
delete _staticres;
|
|
delete _sound;
|
|
delete _text;
|
|
delete _timer;
|
|
delete _emc;
|
|
delete _debugger;
|
|
}
|
|
|
|
Common::Point KyraEngine_v1::getMousePos() const {
|
|
Common::Point mouse = _eventMan->getMousePos();
|
|
|
|
if (_flags.useHiResOverlay) {
|
|
mouse.x >>= 1;
|
|
mouse.y >>= 1;
|
|
}
|
|
|
|
return mouse;
|
|
}
|
|
|
|
void KyraEngine_v1::setMousePos(int x, int y) {
|
|
if (_flags.useHiResOverlay) {
|
|
x <<= 1;
|
|
y <<= 1;
|
|
}
|
|
_system->warpMouse(x, y);
|
|
}
|
|
|
|
int KyraEngine_v1::checkInput(Button *buttonList, bool mainLoop, int eventFlag) {
|
|
_isSaveAllowed = mainLoop;
|
|
updateInput();
|
|
_isSaveAllowed = false;
|
|
|
|
if (mainLoop)
|
|
checkAutosave();
|
|
|
|
int keys = 0;
|
|
int8 mouseWheel = 0;
|
|
|
|
while (_eventList.size()) {
|
|
Common::Event event = *_eventList.begin();
|
|
bool breakLoop = false;
|
|
|
|
switch (event.type) {
|
|
case Common::EVENT_KEYDOWN:
|
|
if (event.kbd.keycode >= '1' && event.kbd.keycode <= '9' &&
|
|
(event.kbd.flags == Common::KBD_CTRL || event.kbd.flags == Common::KBD_ALT) && mainLoop) {
|
|
int saveLoadSlot = 9 - (event.kbd.keycode - '0') + 990;
|
|
|
|
if (event.kbd.flags == Common::KBD_CTRL) {
|
|
loadGameStateCheck(saveLoadSlot);
|
|
_eventList.clear();
|
|
breakLoop = true;
|
|
} else {
|
|
char savegameName[14];
|
|
sprintf(savegameName, "Quicksave %d", event.kbd.keycode - '0');
|
|
saveGameState(saveLoadSlot, savegameName, 0);
|
|
}
|
|
} else if (event.kbd.flags == Common::KBD_CTRL) {
|
|
if (event.kbd.keycode == 'd') {
|
|
if (_debugger)
|
|
_debugger->attach();
|
|
} else if (event.kbd.keycode == 'q') {
|
|
quitGame();
|
|
}
|
|
} else {
|
|
KeyMap::const_iterator keycode = _keyMap.find(event.kbd.keycode);
|
|
if (keycode != _keyMap.end())
|
|
keys = keycode->_value;
|
|
else
|
|
keys = 0;
|
|
|
|
// When we got an keypress, which we might need to handle,
|
|
// break the event loop and pass it to GUI code.
|
|
if (keys)
|
|
breakLoop = true;
|
|
}
|
|
break;
|
|
|
|
case Common::EVENT_LBUTTONDOWN:
|
|
case Common::EVENT_LBUTTONUP: {
|
|
_mouseX = event.mouse.x;
|
|
_mouseY = event.mouse.y;
|
|
if (_flags.useHiResOverlay) {
|
|
_mouseX >>= 1;
|
|
_mouseY >>= 1;
|
|
}
|
|
keys = (event.type == Common::EVENT_LBUTTONDOWN ? 199 : (200 | 0x800));
|
|
breakLoop = true;
|
|
} break;
|
|
|
|
case Common::EVENT_RBUTTONDOWN:
|
|
case Common::EVENT_RBUTTONUP: {
|
|
_mouseX = event.mouse.x;
|
|
_mouseY = event.mouse.y;
|
|
if (_flags.useHiResOverlay) {
|
|
_mouseX >>= 1;
|
|
_mouseY >>= 1;
|
|
}
|
|
keys = (event.type == Common::EVENT_RBUTTONDOWN ? 201 : (202 | 0x800));
|
|
breakLoop = true;
|
|
} break;
|
|
|
|
case Common::EVENT_WHEELUP:
|
|
mouseWheel = -1;
|
|
break;
|
|
|
|
case Common::EVENT_WHEELDOWN:
|
|
mouseWheel = 1;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (_debugger && _debugger->isAttached())
|
|
_debugger->onFrame();
|
|
|
|
if (breakLoop)
|
|
break;
|
|
|
|
_eventList.erase(_eventList.begin());
|
|
}
|
|
|
|
GUI *guiInstance = gui();
|
|
if (guiInstance) {
|
|
if (keys)
|
|
return guiInstance->processButtonList(buttonList, keys | eventFlag, mouseWheel);
|
|
else
|
|
return guiInstance->processButtonList(buttonList, 0, mouseWheel);
|
|
} else {
|
|
return keys;
|
|
}
|
|
}
|
|
|
|
void KyraEngine_v1::setupKeyMap() {
|
|
static const Common::KeyCode keyboardEvents[] = {
|
|
Common::KEYCODE_SPACE, Common::KEYCODE_RETURN, Common::KEYCODE_UP, Common::KEYCODE_KP8,
|
|
Common::KEYCODE_RIGHT, Common::KEYCODE_KP6, Common::KEYCODE_DOWN, Common::KEYCODE_KP2,
|
|
Common::KEYCODE_LEFT, Common::KEYCODE_KP4, Common::KEYCODE_HOME, Common::KEYCODE_KP7,
|
|
Common::KEYCODE_PAGEUP, Common::KEYCODE_KP9, Common::KEYCODE_F1, Common::KEYCODE_F2,
|
|
Common::KEYCODE_F3, Common::KEYCODE_o, Common::KEYCODE_r, Common::KEYCODE_SLASH,
|
|
Common::KEYCODE_ESCAPE
|
|
};
|
|
|
|
static const int16 keyCodesDOS[] = { 61, 43, 96, 96, 102, 102, 97, 97, 92, 92, 91, 91, 101, 101, 112, 113, 114, 25, 20, 55, 110};
|
|
static const int16 keyCodesPC98[] = { 53, 29, 68, 68, 73, 73, 72, 72, 71, 71, 67, 67, 69, 69, 99, 100, 101, 25, 20, 55, 1 };
|
|
|
|
const int16 *keyCodes = _flags.platform == Common::kPlatformPC98 ? keyCodesPC98 : keyCodesDOS;
|
|
_keyMap.clear();
|
|
|
|
for (int i = 0; i < ARRAYSIZE(keyboardEvents); i++)
|
|
_keyMap[keyboardEvents[i]] = keyCodes[i];
|
|
}
|
|
|
|
void KyraEngine_v1::updateInput() {
|
|
Common::Event event;
|
|
|
|
bool updateScreen = false;
|
|
|
|
while (_eventMan->pollEvent(event)) {
|
|
switch (event.type) {
|
|
case Common::EVENT_KEYDOWN:
|
|
if (event.kbd.keycode == '.' || event.kbd.keycode == Common::KEYCODE_ESCAPE ||
|
|
event.kbd.keycode == Common::KEYCODE_SPACE || event.kbd.keycode == Common::KEYCODE_RETURN ||
|
|
event.kbd.keycode == Common::KEYCODE_UP || event.kbd.keycode == Common::KEYCODE_RIGHT ||
|
|
event.kbd.keycode == Common::KEYCODE_DOWN || event.kbd.keycode == Common::KEYCODE_LEFT)
|
|
_eventList.push_back(Event(event, true));
|
|
else if (event.kbd.keycode == 'q' && event.kbd.flags == Common::KBD_CTRL)
|
|
quitGame();
|
|
else
|
|
_eventList.push_back(event);
|
|
break;
|
|
|
|
case Common::EVENT_LBUTTONDOWN:
|
|
case Common::EVENT_RBUTTONDOWN:
|
|
_eventList.push_back(Event(event, true));
|
|
break;
|
|
|
|
case Common::EVENT_MOUSEMOVE:
|
|
if (screen()->isMouseVisible())
|
|
updateScreen = true;
|
|
break;
|
|
|
|
case Common::EVENT_LBUTTONUP:
|
|
case Common::EVENT_RBUTTONUP:
|
|
case Common::EVENT_WHEELUP:
|
|
case Common::EVENT_WHEELDOWN:
|
|
_eventList.push_back(event);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (updateScreen)
|
|
_system->updateScreen();
|
|
}
|
|
|
|
void KyraEngine_v1::removeInputTop() {
|
|
if (!_eventList.empty())
|
|
_eventList.erase(_eventList.begin());
|
|
}
|
|
|
|
bool KyraEngine_v1::skipFlag() const {
|
|
for (Common::List<Event>::const_iterator i = _eventList.begin(); i != _eventList.end(); ++i) {
|
|
if (i->causedSkip)
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void KyraEngine_v1::resetSkipFlag(bool removeEvent) {
|
|
for (Common::List<Event>::iterator i = _eventList.begin(); i != _eventList.end(); ++i) {
|
|
if (i->causedSkip) {
|
|
if (removeEvent)
|
|
_eventList.erase(i);
|
|
else
|
|
i->causedSkip = false;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
int KyraEngine_v1::setGameFlag(int flag) {
|
|
assert((flag >> 3) >= 0 && (flag >> 3) <= ARRAYSIZE(_flagsTable));
|
|
_flagsTable[flag >> 3] |= (1 << (flag & 7));
|
|
return 1;
|
|
}
|
|
|
|
int KyraEngine_v1::queryGameFlag(int flag) const {
|
|
assert((flag >> 3) >= 0 && (flag >> 3) <= ARRAYSIZE(_flagsTable));
|
|
return ((_flagsTable[flag >> 3] >> (flag & 7)) & 1);
|
|
}
|
|
|
|
int KyraEngine_v1::resetGameFlag(int flag) {
|
|
assert((flag >> 3) >= 0 && (flag >> 3) <= ARRAYSIZE(_flagsTable));
|
|
_flagsTable[flag >> 3] &= ~(1 << (flag & 7));
|
|
return 0;
|
|
}
|
|
|
|
void KyraEngine_v1::delayUntil(uint32 timestamp, bool updateTimers, bool update, bool isMainLoop) {
|
|
const uint32 curTime = _system->getMillis();
|
|
if (curTime > timestamp)
|
|
return;
|
|
|
|
uint32 del = timestamp - curTime;
|
|
while (del && !shouldQuit()) {
|
|
uint32 step = MIN<uint32>(del, _tickLength);
|
|
delay(step, update, isMainLoop);
|
|
del -= step;
|
|
}
|
|
}
|
|
|
|
void KyraEngine_v1::delay(uint32 amount, bool update, bool isMainLoop) {
|
|
_system->delayMillis(amount);
|
|
}
|
|
|
|
void KyraEngine_v1::delayWithTicks(int ticks) {
|
|
delay(ticks * _tickLength);
|
|
}
|
|
|
|
void KyraEngine_v1::registerDefaultSettings() {
|
|
if (_flags.platform == Common::kPlatformFMTowns)
|
|
ConfMan.registerDefault("cdaudio", true);
|
|
if (_flags.fanLang != Common::UNK_LANG) {
|
|
// HACK/WORKAROUND: Since we can't use registerDefault here to overwrite
|
|
// the global subtitles settings, we're using this hack to enable subtitles
|
|
// for fan translations
|
|
const Common::ConfigManager::Domain *cur = ConfMan.getActiveDomain();
|
|
if (!cur || (cur && cur->get("subtitles").empty()))
|
|
ConfMan.setBool("subtitles", true);
|
|
}
|
|
}
|
|
|
|
void KyraEngine_v1::readSettings() {
|
|
_configWalkspeed = ConfMan.getInt("walkspeed");
|
|
_configMusic = 0;
|
|
|
|
if (!ConfMan.getBool("music_mute")) {
|
|
if (_flags.platform == Common::kPlatformFMTowns)
|
|
_configMusic = ConfMan.getBool("cdaudio") ? 2 : 1;
|
|
else
|
|
_configMusic = 1;
|
|
}
|
|
_configSounds = ConfMan.getBool("sfx_mute") ? 0 : 1;
|
|
|
|
if (_sound) {
|
|
_sound->enableMusic(_configMusic);
|
|
_sound->enableSFX(_configSounds);
|
|
}
|
|
|
|
bool speechMute = ConfMan.getBool("speech_mute");
|
|
bool subtitles = ConfMan.getBool("subtitles");
|
|
|
|
if (!speechMute && subtitles)
|
|
_configVoice = 2; // Voice & Text
|
|
else if (!speechMute && !subtitles)
|
|
_configVoice = 1; // Voice only
|
|
else
|
|
_configVoice = 0; // Text only
|
|
|
|
setWalkspeed(_configWalkspeed);
|
|
}
|
|
|
|
void KyraEngine_v1::writeSettings() {
|
|
bool speechMute, subtitles;
|
|
|
|
ConfMan.setInt("walkspeed", _configWalkspeed);
|
|
ConfMan.setBool("music_mute", _configMusic == 0);
|
|
if (_flags.platform == Common::kPlatformFMTowns)
|
|
ConfMan.setBool("cdaudio", _configMusic == 2);
|
|
ConfMan.setBool("sfx_mute", _configSounds == 0);
|
|
|
|
switch (_configVoice) {
|
|
case 0: // Text only
|
|
speechMute = true;
|
|
subtitles = true;
|
|
break;
|
|
case 1: // Voice only
|
|
speechMute = false;
|
|
subtitles = false;
|
|
break;
|
|
default: // Voice & Text
|
|
speechMute = false;
|
|
subtitles = true;
|
|
}
|
|
|
|
if (_sound) {
|
|
if (!_configMusic)
|
|
_sound->beginFadeOut();
|
|
_sound->enableMusic(_configMusic);
|
|
_sound->enableSFX(_configSounds);
|
|
}
|
|
|
|
ConfMan.setBool("speech_mute", speechMute);
|
|
ConfMan.setBool("subtitles", subtitles);
|
|
|
|
ConfMan.flushToDisk();
|
|
}
|
|
|
|
bool KyraEngine_v1::speechEnabled() {
|
|
return _flags.isTalkie && (_configVoice == 1 || _configVoice == 2);
|
|
}
|
|
|
|
bool KyraEngine_v1::textEnabled() {
|
|
return !_flags.isTalkie || (_configVoice == 0 || _configVoice == 2);
|
|
}
|
|
|
|
int KyraEngine_v1::convertVolumeToMixer(int value) {
|
|
value -= 2;
|
|
return (value * Audio::Mixer::kMaxMixerVolume) / 95;
|
|
}
|
|
|
|
int KyraEngine_v1::convertVolumeFromMixer(int value) {
|
|
return (value * 95) / Audio::Mixer::kMaxMixerVolume + 2;
|
|
}
|
|
|
|
void KyraEngine_v1::setVolume(kVolumeEntry vol, uint8 value) {
|
|
switch (vol) {
|
|
case kVolumeMusic:
|
|
ConfMan.setInt("music_volume", convertVolumeToMixer(value));
|
|
break;
|
|
|
|
case kVolumeSfx:
|
|
ConfMan.setInt("sfx_volume", convertVolumeToMixer(value));
|
|
break;
|
|
|
|
case kVolumeSpeech:
|
|
ConfMan.setInt("speech_volume", convertVolumeToMixer(value));
|
|
break;
|
|
}
|
|
|
|
// Resetup mixer
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
|
|
_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, ConfMan.getInt("speech_volume"));
|
|
if (_sound)
|
|
_sound->updateVolumeSettings();
|
|
}
|
|
|
|
uint8 KyraEngine_v1::getVolume(kVolumeEntry vol) {
|
|
switch (vol) {
|
|
case kVolumeMusic:
|
|
return convertVolumeFromMixer(ConfMan.getInt("music_volume"));
|
|
break;
|
|
|
|
case kVolumeSfx:
|
|
return convertVolumeFromMixer(ConfMan.getInt("sfx_volume"));
|
|
break;
|
|
|
|
case kVolumeSpeech:
|
|
if (speechEnabled())
|
|
return convertVolumeFromMixer(ConfMan.getInt("speech_volume"));
|
|
else
|
|
return 2;
|
|
break;
|
|
}
|
|
|
|
return 2;
|
|
}
|
|
|
|
void KyraEngine_v1::syncSoundSettings() {
|
|
Engine::syncSoundSettings();
|
|
|
|
if (_sound)
|
|
_sound->updateVolumeSettings();
|
|
}
|
|
|
|
} // End of namespace Kyra
|
|
|