TOLTECS: Implement volume handling and toggling of speech/text
This commit is contained in:
parent
4a5333893d
commit
72cdd019fc
9 changed files with 106 additions and 113 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue