TOLTECS: Implement volume handling and toggling of speech/text

This commit is contained in:
Filippos Karapetis 2012-09-10 21:53:00 +03:00
parent 4a5333893d
commit 72cdd019fc
9 changed files with 106 additions and 113 deletions

View file

@ -21,8 +21,11 @@
*
*/
#include "audio/mixer.h"
#include "common/savefile.h"
#include "common/config-manager.h"
#include "toltecs/toltecs.h"
#include "toltecs/menu.h"
#include "toltecs/palette.h"
@ -53,13 +56,7 @@ int MenuSystem::run() {
_newMenuID = kMenuIdMain;
_currItemID = kItemIdNone;
_editingDescription = false;
_cfgText = true;
_cfgVoices = true;
_cfgMasterVolume = 10;
_cfgVoicesVolume = 10;
_cfgMusicVolume = 10;
_cfgSoundFXVolume = 10;
_cfgBackgroundVolume = 10;
_running = true;
_top = 30 - _vm->_guiHeight / 2;
_needRedraw = false;
@ -241,8 +238,8 @@ void MenuSystem::initMenu(MenuID menuID) {
drawString(0, 74, 320, 1, 229, _vm->getSysString(kStrWhatCanIDoForYou));
addClickTextItem(kItemIdLoad, 0, 115, 320, 0, _vm->getSysString(kStrLoad), 229, 255);
addClickTextItem(kItemIdSave, 0, 135, 320, 0, _vm->getSysString(kStrSave), 229, 255);
addClickTextItem(kItemIdToggleText, 0, 165, 320, 0, _vm->getSysString(kStrTextOn), 229, 255);
addClickTextItem(kItemIdToggleVoices, 0, 185, 320, 0, _vm->getSysString(kStrVoicesOn), 229, 255);
addClickTextItem(kItemIdToggleText, 0, 165, 320, 0, _vm->getSysString(_vm->_cfgText ? kStrTextOn : kStrTextOff), 229, 255);
addClickTextItem(kItemIdToggleVoices, 0, 185, 320, 0, _vm->getSysString(_vm->_cfgVoices ? kStrVoicesOn : kStrVoicesOff), 229, 255);
addClickTextItem(kItemIdVolumesMenu, 0, 215, 320, 0, _vm->getSysString(kStrVolume), 229, 255);
addClickTextItem(kItemIdPlay, 0, 245, 320, 0, _vm->getSysString(kStrPlay), 229, 255);
addClickTextItem(kItemIdQuit, 0, 275, 320, 0, _vm->getSysString(kStrQuit), 229, 255);
@ -326,13 +323,13 @@ void MenuSystem::clickItem(ItemID id) {
_newMenuID = kMenuIdLoad;
break;
case kItemIdToggleText:
setCfgText(!_cfgText, true);
if (!_cfgVoices && !_cfgText)
setCfgText(!_vm->_cfgText, true);
if (!_vm->_cfgVoices && !_vm->_cfgText)
setCfgVoices(true, false);
break;
case kItemIdToggleVoices:
setCfgVoices(!_cfgVoices, true);
if (!_cfgVoices && !_cfgText)
setCfgVoices(!_vm->_cfgVoices, true);
if (!_vm->_cfgVoices && !_vm->_cfgText)
setCfgText(true, false);
break;
case kItemIdVolumesMenu:
@ -518,22 +515,24 @@ void MenuSystem::clickSavegameItem(ItemID id) {
}
void MenuSystem::setCfgText(bool value, bool active) {
if (_cfgText != value) {
if (_vm->_cfgText != value) {
Item *item = getItem(kItemIdToggleText);
_cfgText = value;
_vm->_cfgText = value;
restoreRect(item->rect.left, item->rect.top, item->rect.width() + 1, item->rect.height() - 2);
setItemCaption(item, _vm->getSysString(_cfgText ? kStrTextOn : kStrTextOff));
setItemCaption(item, _vm->getSysString(_vm->_cfgText ? kStrTextOn : kStrTextOff));
drawItem(kItemIdToggleText, true);
ConfMan.setBool("subtitles", value);
}
}
void MenuSystem::setCfgVoices(bool value, bool active) {
if (_cfgVoices != value) {
if (_vm->_cfgVoices != value) {
Item *item = getItem(kItemIdToggleVoices);
_cfgVoices = value;
_vm->_cfgVoices = value;
restoreRect(item->rect.left, item->rect.top, item->rect.width() + 1, item->rect.height() - 2);
setItemCaption(item, _vm->getSysString(_cfgVoices ? kStrVoicesOn : kStrVoicesOff));
setItemCaption(item, _vm->getSysString(_vm->_cfgVoices ? kStrVoicesOn : kStrVoicesOff));
drawItem(kItemIdToggleVoices, true);
ConfMan.setBool("speech_mute", !value);
}
}
@ -542,25 +541,25 @@ void MenuSystem::drawVolumeBar(ItemID itemID) {
char text[21];
switch (itemID) {
case kItemIdMaster:
case kItemIdMaster: // unused in ScummVM, always 20
y = 130 + 25 * 0;
volume = _cfgMasterVolume;
volume = 20;
break;
case kItemIdVoices:
y = 130 + 25 * 1;
volume = _cfgVoicesVolume;
volume = _vm->_cfgVoicesVolume;
break;
case kItemIdMusic:
y = 130 + 25 * 2;
volume = _cfgMusicVolume;
volume = _vm->_cfgMusicVolume;
break;
case kItemIdSoundFX:
y = 130 + 25 * 3;
volume = _cfgSoundFXVolume;
volume = _vm->_cfgSoundFXVolume;
break;
case kItemIdBackground:
case kItemIdBackground: // unused in ScummVM, always 20
y = 130 + 25 * 4;
volume = _cfgBackgroundVolume;
volume = 20;
break;
default:
return;
@ -578,36 +577,37 @@ void MenuSystem::drawVolumeBar(ItemID itemID) {
}
void MenuSystem::changeVolumeBar(ItemID itemID, int delta) {
int *volume, newVolume;
byte newVolume;
switch (itemID) {
case kItemIdMaster:
volume = &_cfgMasterVolume;
break;
case kItemIdVoices:
volume = &_cfgVoicesVolume;
_vm->_cfgVoicesVolume = CLIP(_vm->_cfgVoicesVolume + delta, 0, 20);
newVolume = ceil((double)_vm->_cfgVoicesVolume * Audio::Mixer::kMaxChannelVolume / 20);
_vm->_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, newVolume);
ConfMan.setInt("speech_volume", newVolume);
break;
case kItemIdMusic:
volume = &_cfgMusicVolume;
_vm->_cfgMusicVolume = CLIP(_vm->_cfgMusicVolume + delta, 0, 20);
newVolume = ceil((double)_vm->_cfgMusicVolume * Audio::Mixer::kMaxChannelVolume / 20);
_vm->_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, newVolume);
ConfMan.setInt("music_volume", newVolume);
break;
case kItemIdSoundFX:
volume = &_cfgSoundFXVolume;
_vm->_cfgSoundFXVolume = CLIP(_vm->_cfgSoundFXVolume + delta, 0, 20);
newVolume = ceil((double)_vm->_cfgSoundFXVolume * Audio::Mixer::kMaxChannelVolume / 20);
_vm->_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, newVolume);
ConfMan.setInt("sfx_volume", newVolume);
break;
case kItemIdMaster:
case kItemIdBackground:
volume = &_cfgBackgroundVolume;
// unused in ScummVM
break;
default:
return;
}
newVolume = CLIP(*volume + delta, 0, 20);
if (newVolume != *volume) {
*volume = newVolume;
_vm->syncSoundSettings();
drawVolumeBar(itemID);
}
}
} // End of namespace Toltecs

View file

@ -125,9 +125,6 @@ protected:
Common::Array<Item> _items;
Common::Array<SavegameItem> _savegames;
bool _cfgText, _cfgVoices;
int _cfgMasterVolume, _cfgVoicesVolume, _cfgMusicVolume, _cfgSoundFXVolume, _cfgBackgroundVolume;
void addClickTextItem(ItemID id, int x, int y, int w, uint fontNum, const char *caption, byte defaultColor, byte activeColor);
void drawItem(ItemID itemID, bool active);

View file

@ -20,15 +20,13 @@
*
*/
// FIXME: This code is taken from SAGA and needs more work (e.g. setVolume).
#include "audio/midiparser.h"
#include "common/textconsole.h"
#include "toltecs/toltecs.h"
#include "toltecs/music.h"
#include "toltecs/resource.h"
#include "audio/midiparser.h"
#include "common/textconsole.h"
namespace Toltecs {
MusicPlayer::MusicPlayer(bool isGM) : _isGM(isGM), _buffer(NULL) {
@ -77,7 +75,7 @@ void MusicPlayer::playMIDI(const byte *data, uint32 size, bool loop) {
_parser = parser;
setVolume(127);
syncVolume();
_isLooping = loop;
_isPlaying = true;
@ -86,16 +84,6 @@ void MusicPlayer::playMIDI(const byte *data, uint32 size, bool loop) {
}
}
void MusicPlayer::pause() {
setVolume(-1);
_isPlaying = false;
}
void MusicPlayer::resume() {
setVolume(127);
_isPlaying = true;
}
void MusicPlayer::stopAndClear() {
Common::StackLock lock(_mutex);
stop();

View file

@ -37,8 +37,6 @@ public:
MusicPlayer(bool isGM = true);
void playMIDI(const byte *data, uint32 size, bool loop = false);
void pause();
void resume();
void stopAndClear();
// MidiDriver_BASE interface implementation

View file

@ -469,7 +469,6 @@ void Screen::addTalkTextRect(Font &font, int16 x, int16 &y, int16 length, int16
}
void Screen::addTalkTextItemsToRenderQueue() {
for (int16 i = 0; i <= _talkTextItemNum; i++) {
TalkTextItem *item = &_talkTextItems[i];
byte *text = _vm->_script->getSlotData(item->slotIndex) + item->slotOffset;
@ -482,14 +481,15 @@ void Screen::addTalkTextItemsToRenderQueue() {
if (item->duration < 0)
item->duration = 0;
if (!_vm->_cfgText)
return;
for (byte j = 0; j < item->lineCount; j++) {
_renderQueue->addText(item->lines[j].x, item->lines[j].y, item->color, _fontResIndexArray[item->fontNum],
text, item->lines[j].length);
_renderQueue->addText(item->lines[j].x, item->lines[j].y, item->color,
_fontResIndexArray[item->fontNum], text, item->lines[j].length);
text += item->lines[j].length;
}
}
}
int16 Screen::getTalkTextDuration() {

View file

@ -44,38 +44,22 @@ Sound::~Sound() {
void Sound::playSpeech(int16 resIndex) {
debug(0, "playSpeech(%d)", resIndex);
if (_vm->_cfgVoices)
internalPlaySound(resIndex, kChannelTypeSpeech, 50 /*TODO*/, 0);
}
void Sound::playSound(int16 resIndex, int16 type, int16 volume) {
// TODO: Use the right volumes
debug(0, "playSound(%d, %d, %d)", resIndex, type, volume);
if (volume == -1 || type == -2) {
if (type == kChannelTypeBackground) {
internalPlaySound(resIndex, type, 50 /*TODO*/, 0);
} else {
internalPlaySound(resIndex, type, 100 /*TODO*/, 0);
}
} else {
internalPlaySound(resIndex, type, 100 /*TODO*/, 0);
}
internalPlaySound(resIndex, type, volume, 0);
}
void Sound::playSoundAtPos(int16 resIndex, int16 x, int16 y) {
debug(0, "playSoundAtPos(%d, %d, %d)", resIndex, x, y);
int16 volume, panning = 0, deltaX = 0;
int8 scaling = _vm->_segmap->getScalingAtPoint(x, y);
if (scaling >= 0)
volume = 50 + ABS(scaling) / 2;
else
volume = 50 - ABS(scaling) / 2;
int16 volume = 50 + ABS(_vm->_segmap->getScalingAtPoint(x, y)) / 2;
int16 panning = 0, deltaX = 0;
if (_vm->_cameraX > x)
deltaX = _vm->_cameraX - x;
@ -91,10 +75,11 @@ void Sound::playSoundAtPos(int16 resIndex, int16 x, int16 y) {
}
internalPlaySound(resIndex, 1, volume, panning);
}
void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 panning) {
// Change the game's sound volume (0 - 100) to Scummvm's scale (0 - 255)
volume = (volume == -1) ? 255 : volume * 255 / 100;
if (resIndex == -1) {
// Stop all sounds
@ -142,11 +127,7 @@ void Sound::internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 pa
channels[freeChannel].type = type;
channels[freeChannel].resIndex = resIndex;
Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType;
/*
switch (type) {
}
*/
Audio::Mixer::SoundType soundType = getScummVMSoundType((SoundChannelType)type);
_vm->_mixer->playStream(soundType, &channels[freeChannel].handle,
stream, -1, volume, panning);
@ -206,11 +187,7 @@ void Sound::loadState(Common::ReadStream *in) {
DisposeAfterUse::NO),
channels[i].type == kChannelTypeBackground ? 0 : 1);
Audio::Mixer::SoundType soundType = Audio::Mixer::kPlainSoundType;
/*
switch (type) {
}
*/
Audio::Mixer::SoundType soundType = getScummVMSoundType((SoundChannelType)channels[i].type);
// TODO: Volume and panning
int16 volume = (channels[i].type == kChannelTypeBackground) ? 50 : 100;
@ -221,4 +198,18 @@ void Sound::loadState(Common::ReadStream *in) {
}
}
Audio::Mixer::SoundType Sound::getScummVMSoundType(SoundChannelType type) const {
switch (type) {
case kChannelTypeBackground:
case kChannelTypeSfx:
return Audio::Mixer::kSFXSoundType;
case kChannelTypeSpeech:
return Audio::Mixer::kSpeechSoundType;
break;
default:
return Audio::Mixer::kSFXSoundType;
break;
}
}
} // End of namespace Toltecs

View file

@ -68,7 +68,7 @@ protected:
SoundChannel channels[kMaxChannels];
void internalPlaySound(int16 resIndex, int16 type, int16 volume, int16 panning);
Audio::Mixer::SoundType getScummVMSoundType(SoundChannelType type) const;
};

View file

@ -62,11 +62,6 @@ struct GameSettings {
};
ToltecsEngine::ToltecsEngine(OSystem *syst, const ToltecsGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
// Setup mixer
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, ConfMan.getInt("sfx_volume"));
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, ConfMan.getInt("music_volume"));
_rnd = new Common::RandomSource("toltecs");
}
@ -129,14 +124,24 @@ Common::Error ToltecsEngine::run() {
_sound = new Sound(this);
_cfgText = ConfMan.getBool("subtitles");
_cfgVoices = !ConfMan.getBool("speech_mute");
bool mute = false;
if (ConfMan.hasKey("mute"))
mute = ConfMan.getBool("mute");
_mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, mute ? 0 : ConfMan.getInt("speech_volume"));
_mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, mute ? 0 : ConfMan.getInt("music_volume"));
_mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, mute ? 0 : ConfMan.getInt("sfx_volume"));
syncSoundSettings();
CursorMan.showMouse(true);
setupSysStrings();
//#define TEST_MENU
#ifdef TEST_MENU
#if 0
// Menu test
_screen->registerFont(0, 0x0D);
_screen->registerFont(1, 0x0E);
_screen->loadMouseCursor(12);
@ -321,7 +326,6 @@ void ToltecsEngine::updateInput() {
//debug("key: flags = %02X; keycode = %d", _keyState.flags, _keyState.keycode);
// FIXME: This is just for debugging
switch (event.kbd.keycode) {
case Common::KEYCODE_F7:
savegame("toltecs.001", "Quicksave");
@ -638,4 +642,16 @@ int16 ToltecsEngine::findRectAtPoint(byte *rectData, int16 x, int16 y, int16 ind
}
void ToltecsEngine::syncSoundSettings() {
Engine::syncSoundSettings();
bool mute = false;
if (ConfMan.hasKey("mute"))
mute = ConfMan.getBool("mute");
_cfgVoicesVolume = (mute ? 0 : ConfMan.getInt("speech_volume")) * 20 / Audio::Mixer::kMaxChannelVolume;
_cfgMusicVolume = (mute ? 0 : ConfMan.getInt("music_volume")) * 20 / Audio::Mixer::kMaxChannelVolume;
_cfgSoundFXVolume = (mute ? 0 : ConfMan.getInt("sfx_volume")) * 20 / Audio::Mixer::kMaxChannelVolume;
}
} // End of namespace Toltecs

View file

@ -99,6 +99,7 @@ public:
uint32 getFeatures() const;
Common::Language getLanguage() const;
const Common::String& getTargetName() const { return _targetName; }
void syncSoundSettings();
void setupSysStrings();
void requestSavegame(int slotNum, Common::String &description);
@ -127,6 +128,8 @@ public:
int16 findRectAtPoint(byte *rectData, int16 x, int16 y, int16 index, int16 itemSize,
byte *rectDataEnd);
int _cfgVoicesVolume, _cfgMusicVolume, _cfgSoundFXVolume;
bool _cfgText, _cfgVoices;
public:
AnimationPlayer *_anim;