diff options
author | Robert Göffringmann | 2004-01-07 17:47:46 +0000 |
---|---|---|
committer | Robert Göffringmann | 2004-01-07 17:47:46 +0000 |
commit | 8030f1b1483da8a96b7b8ff6bab246ffd3faad38 (patch) | |
tree | d8b6fc6bde1de078f6bd8fc69308620059d0f584 /sword1 | |
parent | c46d2f05304b1b871df549bba9b2aed0656b7c44 (diff) | |
download | scummvm-rg350-8030f1b1483da8a96b7b8ff6bab246ffd3faad38.tar.gz scummvm-rg350-8030f1b1483da8a96b7b8ff6bab246ffd3faad38.tar.bz2 scummvm-rg350-8030f1b1483da8a96b7b8ff6bab246ffd3faad38.zip |
implemented volume control panel
svn-id: r12220
Diffstat (limited to 'sword1')
-rw-r--r-- | sword1/control.cpp | 144 | ||||
-rw-r--r-- | sword1/control.h | 14 | ||||
-rw-r--r-- | sword1/music.cpp | 14 | ||||
-rw-r--r-- | sword1/music.h | 5 | ||||
-rw-r--r-- | sword1/sound.cpp | 16 | ||||
-rw-r--r-- | sword1/sound.h | 7 | ||||
-rw-r--r-- | sword1/sword1.cpp | 10 |
7 files changed, 172 insertions, 38 deletions
diff --git a/sword1/control.cpp b/sword1/control.cpp index 2ee19498d0..be1a523dc5 100644 --- a/sword1/control.cpp +++ b/sword1/control.cpp @@ -32,6 +32,8 @@ #include "common/util.h" #include "mouse.h" #include "music.h" +#include "sound.h" +#include <math.h> // for sqrt() #define SAVEFILE_WRITE true #define SAVEFILE_READ false @@ -150,12 +152,13 @@ void ControlButton::setSelected(uint8 selected) { draw(); } -SwordControl::SwordControl(ResMan *pResMan, ObjectMan *pObjMan, OSystem *system, SwordMouse *pMouse, SwordMusic *pMusic, const char *savePath) { +SwordControl::SwordControl(ResMan *pResMan, ObjectMan *pObjMan, OSystem *system, SwordMouse *pMouse, SwordSound *pSound, SwordMusic *pMusic, const char *savePath) { _resMan = pResMan; _objMan = pObjMan; _system = system; _mouse = pMouse; _music = pMusic; + _sound = pSound; strcpy(_savePath, savePath); _lStrings = _languageStrings + MIN(SwordEngine::_systemVars.language, (uint8)BS1_SPANISH) * 20; } @@ -212,6 +215,7 @@ void SwordControl::askForCd(void) { } uint8 SwordControl::runPanel(void) { + _mouseDown = false; _restoreBuf = NULL; _keyPressed = _numButtons = 0; _screenBuf = (uint8*)malloc(640 * 480); @@ -283,10 +287,16 @@ uint8 SwordControl::runPanel(void) { } uint8 SwordControl::getClicks(uint8 mode, uint8 *retVal) { + uint8 checkButtons = _numButtons; + if (mode == BUTTON_VOLUME_PANEL) { + handleVolumeClicks(); + checkButtons = 1; + } + if (!_mouseState) return 0; if (_mouseState & BS1L_BUTTON_DOWN) - for (uint8 cnt = 0; cnt < _numButtons; cnt++) + for (uint8 cnt = 0; cnt < checkButtons; cnt++) if (_buttons[cnt]->wasClicked(_mouseX, _mouseY)) { _selectedButton = cnt; _buttons[cnt]->setSelected(1); @@ -294,7 +304,7 @@ uint8 SwordControl::getClicks(uint8 mode, uint8 *retVal) { showSavegameNames(); } if (_mouseState & BS1L_BUTTON_UP) { - for (uint8 cnt = 0; cnt < _numButtons; cnt++) + for (uint8 cnt = 0; cnt < checkButtons; cnt++) if (_buttons[cnt]->wasClicked(_mouseX, _mouseY)) if (_selectedButton == cnt) { // saveslots stay selected after clicking @@ -303,7 +313,7 @@ uint8 SwordControl::getClicks(uint8 mode, uint8 *retVal) { _selectedButton = 255; return handleButtonClick(_buttons[cnt]->_id, mode, retVal); } - if (_selectedButton < _numButtons) { + if (_selectedButton < checkButtons) { _buttons[_selectedButton]->setSelected(0); if (_buttons[_selectedButton]->isSaveslot()) showSavegameNames(); @@ -436,10 +446,101 @@ void SwordControl::setupVolumePanel(void) { renderText(_lStrings[STR_SPEECH], 320, 39 + 40, TEXT_CENTER); renderText(_lStrings[STR_FX], 438, 39 + 40, TEXT_LEFT_ALIGN); - renderText((const uint8*)"NOT YET IMPLEMENTED", 320, 240, TEXT_CENTER); - - createButtons(_volumeButtons, 1); + createButtons(_volumeButtons, 4); renderText(_lStrings[STR_DONE], _volumeButtons[0].x - 10, _volumeButtons[0].y, TEXT_RIGHT_ALIGN); + + uint8 volL, volR; + _music->giveVolume(&volL, &volR); + renderVolumeBar(1, volL, volR); + _sound->giveSpeechVol(&volL, &volR); + renderVolumeBar(2, volL, volR); + _sound->giveSfxVol(&volL, &volR); + renderVolumeBar(3, volL, volR); +} + +void SwordControl::handleVolumeClicks(void) { + if (_mouseDown) { + uint8 clickedId = 0; + for (uint8 cnt = 1; cnt < 4; cnt++) + if (_buttons[cnt]->wasClicked(_mouseX, _mouseY)) + clickedId = cnt; + if (clickedId) { // these are circle shaped, so check again if it was clicked. + uint8 clickDest = 0; + int16 mouseDiffX = _mouseX - (_volumeButtons[clickedId].x + 48); + int16 mouseDiffY = _mouseY - (_volumeButtons[clickedId].y + 48); + int16 mouseOffs = (int16)sqrt(mouseDiffX * mouseDiffX + mouseDiffY * mouseDiffY); + // check if the player really hit the button (but not the center). + if ((mouseOffs <= 42) && (mouseOffs >= 8)) { + if (mouseDiffX > 8) { // right part + if (mouseDiffY < -8) // upper right + clickDest = 2; + else if (ABS(mouseDiffY) <= 8) // right + clickDest = 3; + else // lower right + clickDest = 4; + } else if (mouseDiffX < -8) { // left part + if (mouseDiffY < -8) // upper left + clickDest = 8; + else if (ABS(mouseDiffY) <= 8) // left + clickDest = 7; + else // lower left + clickDest = 6; + } else { // middle + if (mouseDiffY < -8) + clickDest = 1; // upper + else if (mouseDiffY > 8) + clickDest = 5; // lower + } + } + _buttons[clickedId]->setSelected(clickDest); + changeVolume(clickedId, clickDest); + } + } else if (_mouseState & BS1L_BUTTON_UP) { + _buttons[1]->setSelected(0); + _buttons[2]->setSelected(0); + _buttons[3]->setSelected(0); + } +} + +void SwordControl::changeVolume(uint8 id, uint8 action) { + // ids: 1 = music, 2 = speech, 3 = sfx + uint8 volL = 0, volR = 0; + if (id == 1) + _music->giveVolume(&volL, &volR); + else if (id == 2) + _sound->giveSpeechVol(&volL, &volR); + else if (id == 3) + _sound->giveSfxVol(&volL, &volR); + + int8 direction = 0; + if ((action >= 4) && (action <= 6)) // lower part of the button => decrease volume + direction = -1; + else if ((action == 8) || (action == 1) || (action == 2)) // upper part => increase volume + direction = 1; + else if ((action == 3) || (action == 7)) // middle part => pan volume + direction = 1; + int8 factorL = 8, factorR = 8; + if ((action >= 6) && (action <= 8)) { // left part => left pan + factorL = 8; + factorR = (action == 7) ? -8 : 0; + } else if ((action >= 2) && (action <= 4)) { // right part + factorR = 8; + factorL = (action == 3) ? -8 : 0; + } + int16 resVolL = volL + direction * factorL; + int16 resVolR = volR + direction * factorR; + + volL = (uint8)MAX((int16)0, MIN(resVolL, (int16)255)); + volR = (uint8)MAX((int16)0, MIN(resVolR, (int16)255)); + + if (id == 1) + _music->setVolume(volL, volR); + else if (id == 2) + _sound->setSpeechVol(volL, volR); + else if (id == 3) + _sound->setSfxVol(volL, volR); + + renderVolumeBar(id, volL, volR); } bool SwordControl::getConfirm(const uint8 *title) { @@ -701,8 +802,24 @@ void SwordControl::renderText(const uint8 *str, uint16 x, uint16 y, uint8 mode) _system->copy_rect(_screenBuf + y * SCREEN_WIDTH + x, SCREEN_WIDTH, x, y, (destX - x) + 3, 28); } -void SwordControl::renderVolumeBar(uint8 id) { - +void SwordControl::renderVolumeBar(uint8 id, uint8 volL, uint8 volR) { + uint16 destX = _volumeButtons[id].x + 20; + uint16 destY = _volumeButtons[id].y + 116; + + for (uint8 chCnt = 0; chCnt < 2; chCnt++) { + uint8 vol = (chCnt == 0) ? volL : volR; + FrameHeader *frHead = _resMan->fetchFrame(_resMan->openFetchRes(SR_VLIGHT), (vol + 15) >> 4); + uint8 *destMem = _screenBuf + destY * SCREEN_WIDTH + destX; + uint8 *srcMem = (uint8*)frHead + sizeof(FrameHeader); + for (uint16 cnty = 0; cnty < FROM_LE_16(frHead->height); cnty++) { + memcpy(destMem, srcMem, FROM_LE_16(frHead->width)); + srcMem += FROM_LE_16(frHead->width); + destMem += SCREEN_WIDTH; + } + _system->copy_rect(_screenBuf + destY * SCREEN_WIDTH + destX, SCREEN_WIDTH, destX, destY, FROM_LE_16(frHead->width), FROM_LE_16(frHead->height)); + _resMan->resClose(SR_VLIGHT); + destX += 32; + } } void SwordControl::saveGameToFile(uint8 slot) { @@ -823,6 +940,7 @@ void SwordControl::delay(uint32 msecs) { _mouseY = event.mouse.y; break; case OSystem::EVENT_LBUTTONDOWN: + _mouseDown = true; _mouseState |= BS1L_BUTTON_DOWN; #ifdef _WIN32_WCE _mouseX = event.mouse.x; @@ -830,6 +948,7 @@ void SwordControl::delay(uint32 msecs) { #endif break; case OSystem::EVENT_LBUTTONUP: + _mouseDown = false; _mouseState |= BS1L_BUTTON_UP; break; case OSystem::EVENT_QUIT: @@ -878,8 +997,11 @@ const ButtonInfo SwordControl::_saveButtons[16] = { {462, 338 + 40, SR_BUTTON, BUTTON_SAVE_CANCEL} }; -const ButtonInfo SwordControl::_volumeButtons[1] = { - { 478, 338 + 40, SR_BUTTON, BUTTON_MAIN_PANEL } +const ButtonInfo SwordControl::_volumeButtons[4] = { + { 478, 338 + 40, SR_BUTTON, BUTTON_MAIN_PANEL }, + { 138, 135, SR_VKNOB, 0 }, + { 273, 135, SR_VKNOB, 0 }, + { 404, 135, SR_VKNOB, 0 }, }; const uint8 SwordControl::_languageStrings[8 * 20][43] = { diff --git a/sword1/control.h b/sword1/control.h index e8959acea9..e83b0a6982 100644 --- a/sword1/control.h +++ b/sword1/control.h @@ -30,6 +30,7 @@ class ResMan; class OSystem; class SwordMouse; class SwordMusic; +class SwordSound; #define MAX_BUTTONS 16 @@ -63,16 +64,13 @@ struct ButtonInfo { class SwordControl { public: - SwordControl(ResMan *pResMan, ObjectMan *pObjMan, OSystem *system, SwordMouse *pMouse, SwordMusic *pMusic, const char *savePath); + SwordControl(ResMan *pResMan, ObjectMan *pObjMan, OSystem *system, SwordMouse *pMouse, SwordSound *pSound, SwordMusic *pMusic, const char *savePath); ~SwordControl(void); uint8 runPanel(void); void doRestore(void); void askForCd(void); bool savegamesExist(void); private: - void initData(void); - void closeData(void); - void saveGameToFile(uint8 slot); bool restoreGameFromFile(uint8 slot); void readSavegameDescriptions(void); @@ -88,6 +86,8 @@ private: uint8 getClicks(uint8 mode, uint8 *retVal); uint8 handleButtonClick(uint8 id, uint8 mode, uint8 *retVal); + void handleVolumeClicks(void); + void changeVolume(uint8 id, uint8 action); void setupMainPanel(void); void setupSaveRestorePanel(bool saving); @@ -101,7 +101,7 @@ private: bool keyAccepted(uint8 key); void handleSaveKey(uint8 key); - void renderVolumeBar(uint8 id); + void renderVolumeBar(uint8 id, uint8 volL, uint8 volR); uint16 getTextWidth(const uint8 *str); void renderText(const uint8 *str, uint16 x, uint16 y, uint8 mode); uint8 _numButtons; @@ -109,7 +109,7 @@ private: void createButtons(const ButtonInfo *buttons, uint8 num); void destroyButtons(void); ControlButton *_buttons[MAX_BUTTONS]; - static const ButtonInfo _deathButtons[3], _panelButtons[7], _saveButtons[16], _volumeButtons[1]; + static const ButtonInfo _deathButtons[3], _panelButtons[7], _saveButtons[16], _volumeButtons[4]; static const uint8 _languageStrings[8 * 20][43]; const uint8 (*_lStrings)[43]; ObjectMan *_objMan; @@ -117,12 +117,14 @@ private: OSystem *_system; SwordMouse *_mouse; SwordMusic *_music; + SwordSound *_sound; char _savePath[256]; uint8 *_font, *_redFont; uint8 *_screenBuf; uint8 _keyPressed; void delay(uint32 msecs); uint16 _mouseX, _mouseY, _mouseState; + bool _mouseDown; }; diff --git a/sword1/music.cpp b/sword1/music.cpp index fa23acbe46..3895cc95a5 100644 --- a/sword1/music.cpp +++ b/sword1/music.cpp @@ -116,7 +116,7 @@ SwordMusic::SwordMusic(OSystem *system, SoundMixer *pMixer) { _mutex = _system->create_mutex(); _converter[0] = NULL; _converter[1] = NULL; - _volume = 192; + _volumeL = _volumeR = 192; } SwordMusic::~SwordMusic() { @@ -135,11 +135,17 @@ void SwordMusic::mixer(int16 *buf, uint32 len) { Common::StackLock lock(_mutex); for (int i = 0; i < ARRAYSIZE(_handles); i++) if (_handles[i].streaming() && _converter[i]) - _converter[i]->flow(_handles[i], buf, len, _volume, _volume); + _converter[i]->flow(_handles[i], buf, len, _volumeL, _volumeR); } -void SwordMusic::setVolume(uint8 vol) { - _volume = (st_volume_t)vol; +void SwordMusic::setVolume(uint8 volL, uint8 volR) { + _volumeL = (st_volume_t)volL; + _volumeR = (st_volume_t)volR; +} + +void SwordMusic::giveVolume(uint8 *volL, uint8 *volR) { + *volL = (uint8)_volumeL; + *volR = (uint8)_volumeR; } void SwordMusic::startMusic(int32 tuneId, int32 loopFlag) { diff --git a/sword1/music.h b/sword1/music.h index 9e917fc003..c30c7cfce7 100644 --- a/sword1/music.h +++ b/sword1/music.h @@ -64,9 +64,10 @@ public: ~SwordMusic(); void startMusic(int32 tuneId, int32 loopFlag); void fadeDown(); - void setVolume(uint8 vol); + void setVolume(uint8 volL, uint8 volR); + void giveVolume(uint8 *volL, uint8 *volR); private: - st_volume_t _volume; + st_volume_t _volumeL, _volumeR; SwordMusicHandle _handles[2]; RateConverter *_converter[2]; OSystem *_system; diff --git a/sword1/sound.cpp b/sword1/sound.cpp index 31e6851f1a..026c6eb954 100644 --- a/sword1/sound.cpp +++ b/sword1/sound.cpp @@ -36,12 +36,7 @@ SwordSound::SwordSound(const char *searchPath, SoundMixer *mixer, ResMan *pResMa _cowHeader = NULL; _endOfQueue = 0; _currentCowFile = 0; - _speechVol = _sfxVol = 192; -} - -void SwordSound::setVolume(uint8 sfxVol, uint8 speechVol) { - _sfxVol = sfxVol; - _speechVol = speechVol; + _speechVolL = _speechVolR = _sfxVolL = _sfxVolR = 192; } int SwordSound::addToQueue(int32 fxNo) { @@ -140,11 +135,10 @@ void SwordSound::playSample(QueueElement *elem) { if ((_fxList[elem->id].roomVolList[cnt].roomNo == (int)SwordLogic::_scriptVars[SCREEN]) || (_fxList[elem->id].roomVolList[cnt].roomNo == -1)) { - uint8 volL = _fxList[elem->id].roomVolList[cnt].leftVol * 10; - uint8 volR = _fxList[elem->id].roomVolList[cnt].rightVol * 10; + uint8 volL = (_fxList[elem->id].roomVolList[cnt].leftVol * 10 * _sfxVolL) / 255; + uint8 volR = (_fxList[elem->id].roomVolList[cnt].rightVol * 10 * _sfxVolR) / 255; int8 pan = (volR - volL) / 2; uint8 volume = (volR + volL) / 2; - volume = (volume * _sfxVol) >> 8; uint32 size = READ_LE_UINT32(sampleData + 0x28); uint8 flags; if (READ_LE_UINT16(sampleData + 0x22) == 16) @@ -173,8 +167,10 @@ bool SwordSound::startSpeech(uint16 roomNo, uint16 localNo) { if (sampleSize) { uint32 size; int16 *data = uncompressSpeech(index + _cowHeaderSize, sampleSize, &size); + uint8 speechVol = (_speechVolR + _speechVolL) / 2; + int8 speechPan = (_speechVolR - _speechVolL) / 2; if (data) - _mixer->playRaw(&_speechHandle, data, size, 11025, SPEECH_FLAGS, SOUND_SPEECH_ID, _speechVol); + _mixer->playRaw(&_speechHandle, data, size, 11025, SPEECH_FLAGS, SOUND_SPEECH_ID, speechVol, speechPan); return true; } else return false; diff --git a/sword1/sound.h b/sword1/sound.h index 6ade373bff..ad06a93daf 100644 --- a/sword1/sound.h +++ b/sword1/sound.h @@ -59,7 +59,10 @@ class SwordSound { public: SwordSound(const char *searchPath, SoundMixer *mixer, ResMan *pResMan); ~SwordSound(void); - void setVolume(uint8 sfxVol, uint8 speechVol); + void setSpeechVol(uint8 volL, uint8 volR) { _speechVolL = volL; _speechVolR = volR; }; + void setSfxVol(uint8 volL, uint8 volR) { _sfxVolL = volL; _sfxVolR = volR; }; + void giveSpeechVol(uint8 *volL, uint8 *volR) { *volL = _speechVolL; *volR = _speechVolR; }; + void giveSfxVol(uint8 *volL, uint8 *volR) { *volL = _sfxVolL; *volR = _sfxVolR; }; void newScreen(uint32 screen); void quitScreen(void); void closeCowSystem(void); @@ -75,7 +78,7 @@ public: void engine(void); private: - uint8 _sfxVol, _speechVol; + uint8 _sfxVolL, _sfxVolR, _speechVolL, _speechVolR; void playSample(QueueElement *elem); void initCowSystem(void); diff --git a/sword1/sword1.cpp b/sword1/sword1.cpp index 20af1c038f..ce2d9db887 100644 --- a/sword1/sword1.cpp +++ b/sword1/sword1.cpp @@ -109,11 +109,15 @@ void SwordEngine::initialize(void) { _logic = new SwordLogic(_objectMan, _resMan, _screen, _mouse, _sound, _music, _menu); _mouse->useLogicAndMenu(_logic, _menu); - _music->setVolume((uint8)ConfMan.getInt("music_volume")); + uint8 musicVol = (uint8)ConfMan.getInt("music_volume"); uint8 speechVol = (uint8)ConfMan.getInt("speech_volume"); + uint8 sfxVol = (uint8)ConfMan.getInt("sfx_volume"); if (!speechVol) speechVol = 192; - _sound->setVolume((uint8)ConfMan.getInt("sfx_volume"), speechVol); + + _music->setVolume(musicVol, musicVol); // these routines expect left and right volume, + _sound->setSpeechVol(speechVol, speechVol); // but our config manager doesn't support it. + _sound->setSfxVol(sfxVol, sfxVol); _systemVars.justRestoredGame = _systemVars.currentCD = _systemVars.gamePaused = 0; @@ -151,7 +155,7 @@ void SwordEngine::initialize(void) { _logic->initialize(); _objectMan->initialize(); _mouse->initialize(); - _control = new SwordControl(_resMan, _objectMan, _system, _mouse, _music, getSavePath()); + _control = new SwordControl(_resMan, _objectMan, _system, _mouse, _sound, _music, getSavePath()); } void SwordEngine::reinitialize(void) { |