Files
scummvm-cursorfix/engines/mm/xeen/dialogs/dialogs_control_panel.cpp
2026-02-02 04:50:13 +01:00

266 lines
7.6 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "mm/xeen/dialogs/dialogs_control_panel.h"
#include "mm/xeen/dialogs/dialogs_query.h"
#include "mm/xeen/party.h"
#include "mm/xeen/resources.h"
#include "mm/xeen/xeen.h"
namespace MM {
namespace Xeen {
#ifdef USE_TTS
static const uint8 kControlPanelTextCount = 7;
static const uint8 kControlPanelEfxIndex = 1;
static const uint8 kControlPanelMusicIndex = 3;
#endif
enum ControlPanelButtonTTSTextIndex {
kControlPanelLoad = 0,
kControlPanelEfx = 1,
kControlPanelSave = 2,
kControlPanelMusic = 3,
kControlPanelQuit = 4,
kControlPanelWizard = 5
};
int ControlPanel::show(XeenEngine *vm) {
ControlPanel *dlg = new ControlPanel(vm);
int result = dlg->execute();
delete dlg;
return result;
}
int ControlPanel::execute() {
EventsManager &events = *_vm->_events;
Interface &intf = *_vm->_interface;
Map &map = *_vm->_map;
Party &party = *_vm->_party;
SavesManager &saves = *_vm->_saves;
Sound &sound = *_vm->_sound;
Windows &windows = *_vm->_windows;
Window &w = windows[23];
Window &w3 = windows[3];
loadButtons();
int result = 0, debugCtr = 0;
w.open();
#ifdef USE_TTS
bool voiceText = true;
_vm->stopTextToSpeech();
#endif
do {
Common::String btnText = getButtonText();
Common::String text = Common::String::format(Res.CONTROL_PANEL_TEXT, btnText.c_str());
drawButtons(&w);
Common::String ttsMessage;
w.writeString(text, false, &ttsMessage);
w.writeString("\xB""000\t000\x1");
w.update();
#ifdef USE_TTS
if (voiceText) {
speakText(ttsMessage);
voiceText = false;
}
#endif
events.updateGameCounter();
intf.draw3d(false, false);
do {
w.writeString("\r", false);
drawButtons(&w);
w.writeString(text, false);
w.writeString("\v000\t000", false);
w.frame();
if (_debugFlag)
w.writeString(getTimeText());
w3.update();
w.update();
events.pollEventsAndWait();
checkEvents(_vm);
if (_vm->shouldExit())
return 0;
} while (!_buttonValue && events.timeElapsed() < 2);
if (Res.KeyConstants.DialogsControlPanel.KEY_QUIT == _buttonValue) {
if (Confirm::show(g_vm, Res.CONFIRM_QUIT)) {
g_vm->_gameMode = GMODE_QUIT;
result = 1;
}
} else if (Res.KeyConstants.DialogsControlPanel.KEY_MRWIZARD == _buttonValue) {
if (Confirm::show(g_vm, Res.MR_WIZARD)) {
w.close();
if (!windows[2]._enabled) {
sound.playFX(51);
if (g_vm->getGameID() == GType_WorldOfXeen) {
map._loadCcNum = 0;
map.load(28);
party._mazeDirection = DIR_EAST;
} else {
map._loadCcNum = 1;
map.load(29);
party._mazeDirection = DIR_SOUTH;
}
party.moveToRunLocation();
}
party._gems = 0;
result = 2;
}
} else if (Res.KeyConstants.DialogsControlPanel.KEY_LOAD == _buttonValue) {
if (_vm->_mode == MODE_COMBAT) {
ErrorScroll::show(_vm, Res.NO_LOADING_IN_COMBAT);
} else {
// Close dialog and show loading dialog
result = 3;
}
} else if (Res.KeyConstants.DialogsControlPanel.KEY_SAVE == _buttonValue) {
if (_vm->_mode == MODE_COMBAT) {
ErrorScroll::show(_vm, Res.NO_SAVING_IN_COMBAT);
} else {
// Close dialog and show saving dialog
result = 4;
}
} else if (Res.KeyConstants.DialogsControlPanel.KEY_FXON == _buttonValue) {
sound.setFxOn(!sound._fxOn);
if (sound._fxOn)
sound.playFX(20);
#ifdef USE_TTS
voiceOnOffText(sound._fxOn, kControlPanelEfxIndex);
#endif
} else if (Res.KeyConstants.DialogsControlPanel.KEY_MUSICON == _buttonValue) {
sound.setMusicOn(!sound._musicOn);
#ifdef USE_TTS
voiceOnOffText(sound._musicOn, kControlPanelMusicIndex);
#endif
} else if (Common::KEYCODE_ESCAPE == _buttonValue) {
result = 1;
} else if (Common::KEYCODE_g == _buttonValue) { // Goober cheat sequence
debugCtr = 1;
} else if (Common::KEYCODE_o == _buttonValue) {
debugCtr = (debugCtr == 1 || debugCtr == 2) ? 2 : 0;
} else if (Common::KEYCODE_b == _buttonValue) {
debugCtr = (debugCtr == 2) ? 3 : 0;
} else if (Common::KEYCODE_r == _buttonValue) {
if (debugCtr == 3)
_debugFlag = true;
else
debugCtr = 0;
}
} while (!result);
w.close();
intf.drawParty(true);
if (result == 3) {
if (g_vm->canLoadGameStateCurrently())
saves.loadGame();
} else if (result == 4) {
saves.saveGame();
}
return result;
}
void ControlPanel::loadButtons() {
_iconSprites.load("cpanel.icn");
addButton(Common::Rect(214, 56, 244, 69), Res.KeyConstants.DialogsControlPanel.KEY_FXON, 0, &_iconSprites, kControlPanelEfx);
addButton(Common::Rect(214, 75, 244, 88), Res.KeyConstants.DialogsControlPanel.KEY_MUSICON, 0, &_iconSprites, kControlPanelMusic);
addButton(Common::Rect(135, 56, 165, 69), Res.KeyConstants.DialogsControlPanel.KEY_LOAD, 0, &_iconSprites, kControlPanelLoad);
addButton(Common::Rect(135, 75, 165, 88), Res.KeyConstants.DialogsControlPanel.KEY_SAVE, 0, &_iconSprites, kControlPanelSave);
// For ScummVM we've merged both Save and Save As into a single
// save item, so we don't need this one
addButton(Common::Rect(), 0);
addButton(Common::Rect(135, 94, 165, 107), Res.KeyConstants.DialogsControlPanel.KEY_QUIT, 0, &_iconSprites, kControlPanelQuit);
addButton(Common::Rect(175, 113, 205, 126), Res.KeyConstants.DialogsControlPanel.KEY_MRWIZARD, 0, &_iconSprites, kControlPanelWizard);
}
Common::String ControlPanel::getButtonText() {
Sound &sound = *g_vm->_sound;
_btnSoundText = sound._fxOn ? Res.ON : Res.OFF;
_btnMusicText = sound._musicOn ? Res.ON : Res.OFF;
return Common::String::format(Res.CONTROL_PANEL_BUTTONS,
_btnSoundText.c_str(), _btnMusicText.c_str());
}
Common::String ControlPanel::getTimeText() const {
TimeDate td;
g_system->getTimeAndDate(td);
Common::String timeStr = Common::String::format("%d:%.2d:%.2d%c",
td.tm_hour == 0 || td.tm_hour == 12 ? 12 : (td.tm_hour % 12),
td.tm_min, td.tm_sec, (td.tm_hour >= 12) ? 'p' : 'c');
uint32 playtime = g_vm->_events->playTime() / GAME_FRAME_RATE;
Common::String playtimeStr = Common::String::format("%d:%.2d:%.2d",
playtime / 3600, (playtime / 60) % 60, playtime % 60);
return Common::String::format(
"\x2\x3l\xB""000\t000\x4""160%s\x3r\xB""000\t000%s\x1",
timeStr.c_str(), playtimeStr.c_str());
}
#ifdef USE_TTS
void ControlPanel::speakText(const Common::String &text) {
uint index = 0;
_vm->sayText(getNextTextSection(text, index, kControlPanelTextCount));
addNextTextToButtons(text, index, kControlPanelTextCount - 1);
}
void ControlPanel::voiceOnOffText(bool on, uint buttonTextIndex) {
const char *baseMessage = on ? Res.ON : Res.OFF;
Common::String cleanedMessage;
for (uint i = 0; i < strlen(baseMessage); ++i) {
if (Common::isAlpha(baseMessage[i])) {
cleanedMessage += baseMessage[i];
}
}
_vm->sayText(cleanedMessage, Common::TextToSpeechManager::INTERRUPT);
_buttonTexts[buttonTextIndex] = cleanedMessage;
}
#endif
} // End of namespace Xeen
} // End of namespace MM