Initial commit
This commit is contained in:
390
engines/stark/ui/menu/dialogmenu.cpp
Normal file
390
engines/stark/ui/menu/dialogmenu.cpp
Normal file
@@ -0,0 +1,390 @@
|
||||
/* 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 "engines/stark/ui/menu/dialogmenu.h"
|
||||
#include "engines/stark/services/services.h"
|
||||
#include "engines/stark/services/userinterface.h"
|
||||
#include "engines/stark/services/diary.h"
|
||||
#include "engines/stark/services/gamechapter.h"
|
||||
#include "engines/stark/services/staticprovider.h"
|
||||
#include "engines/stark/services/global.h"
|
||||
#include "engines/stark/gfx/renderentry.h"
|
||||
#include "engines/stark/resources/location.h"
|
||||
#include "engines/stark/resources/item.h"
|
||||
|
||||
namespace Stark {
|
||||
|
||||
DialogScreen::DialogScreen(Gfx::Driver *gfx, Cursor *cursor) :
|
||||
StaticLocationScreen(gfx, cursor, "DiaryLog", Screen::kScreenDialog),
|
||||
_startTitleIndex(0), _nextTitleIndex(0),
|
||||
_startLineIndex(0), _nextLineIndex(0),
|
||||
_curMaxChapter(0), _curLogIndex(0),
|
||||
_indexFrame(nullptr),
|
||||
_logFrame(nullptr),
|
||||
_chapterTitleTexts(),
|
||||
_prevTitleIndexStack(),
|
||||
_prevLineIndexStack() {
|
||||
}
|
||||
|
||||
DialogScreen::~DialogScreen() {
|
||||
freeResources();
|
||||
}
|
||||
|
||||
void DialogScreen::open() {
|
||||
StaticLocationScreen::open();
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"BGImage",
|
||||
nullptr,
|
||||
nullptr));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Return",
|
||||
CLICK_HANDLER(DialogScreen, backHandler),
|
||||
nullptr));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Back",
|
||||
CLICK_HANDLER(DialogScreen, backHandler),
|
||||
nullptr));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"IndexBack",
|
||||
CLICK_HANDLER(DialogScreen, indexBackHandler),
|
||||
nullptr));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"IndexNext",
|
||||
CLICK_HANDLER(DialogScreen, indexNextHandler),
|
||||
nullptr));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"LogBack",
|
||||
CLICK_HANDLER(DialogScreen, logBackHandler),
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Index",
|
||||
CLICK_HANDLER(DialogScreen, backIndexHandler),
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"LogNext",
|
||||
CLICK_HANDLER(DialogScreen, logNextHandler),
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
|
||||
for (uint i = 1; i < _widgets.size(); ++i) {
|
||||
_widgets[i]->setupSounds(0, 1);
|
||||
}
|
||||
|
||||
Resources::Location *location = StarkStaticProvider->getLocation();
|
||||
_indexFrame = location->getRenderEntryByName("IndexFrame");
|
||||
_logFrame = location->getRenderEntryByName("LogFrame");
|
||||
|
||||
_nextTitleIndex = 0;
|
||||
loadIndex();
|
||||
}
|
||||
|
||||
void DialogScreen::close() {
|
||||
freeResources();
|
||||
StaticLocationScreen::close();
|
||||
}
|
||||
|
||||
void DialogScreen::freeResources() {
|
||||
freeChapterTitleTexts();
|
||||
freeDialogLineTexts();
|
||||
_prevTitleIndexStack.clear();
|
||||
_prevLineIndexStack.clear();
|
||||
}
|
||||
|
||||
void DialogScreen::onScreenChanged() {
|
||||
StaticLocationScreen::onScreenChanged();
|
||||
for (uint i = 0; i < _chapterTitleTexts.size(); ++i) {
|
||||
_chapterTitleTexts[i]->onScreenChanged();
|
||||
}
|
||||
for (uint i = 0; i < _dialogLineTexts.size(); ++i) {
|
||||
_dialogLineTexts[i]->onScreenChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void DialogScreen::onDialogClick(uint logIndex) {
|
||||
freeLogTitleWidgets();
|
||||
freeChapterTitleTexts();
|
||||
|
||||
_widgets[kWidgetIndexBack]->setVisible(false);
|
||||
_widgets[kWidgetIndexNext]->setVisible(false);
|
||||
_widgets[kWidgetIndex]->setVisible(true);
|
||||
|
||||
_nextLineIndex = 0;
|
||||
_curLogIndex = logIndex;
|
||||
loadDialog();
|
||||
}
|
||||
|
||||
void DialogScreen::onRender() {
|
||||
StaticLocationScreen::onRender();
|
||||
for (uint i = 0; i < _chapterTitleTexts.size(); ++i) {
|
||||
_chapterTitleTexts[i]->render();
|
||||
}
|
||||
for (uint i = 0; i < _dialogLineTexts.size(); ++i) {
|
||||
_dialogLineTexts[i]->render();
|
||||
}
|
||||
}
|
||||
|
||||
void DialogScreen::loadIndex() {
|
||||
static const int space = 4;
|
||||
|
||||
freeLogTitleWidgets();
|
||||
freeChapterTitleTexts();
|
||||
|
||||
_startTitleIndex = _nextTitleIndex;
|
||||
|
||||
Common::Point pos = _indexFrame->getPosition();
|
||||
int bottom = _indexFrame->getText()->getTargetHeight() + pos.y;
|
||||
int height;
|
||||
ChapterTitleText *chapterTitleText;
|
||||
DialogTitleWidget *dialogTitleWidget;
|
||||
|
||||
_curMaxChapter = 99;
|
||||
while (_nextTitleIndex < StarkDiary->countDialog()) {
|
||||
height = 0;
|
||||
chapterTitleText = nullptr;
|
||||
|
||||
dialogTitleWidget = new DialogTitleWidget(this, _gfx, _nextTitleIndex);
|
||||
height += dialogTitleWidget->getHeight();
|
||||
|
||||
if (dialogTitleWidget->getChapter() != _curMaxChapter) {
|
||||
_curMaxChapter = dialogTitleWidget->getChapter();
|
||||
chapterTitleText = new ChapterTitleText(_gfx, _curMaxChapter);
|
||||
height += chapterTitleText->getHeight() + 2 * space;
|
||||
}
|
||||
|
||||
if (pos.y + height > bottom) {
|
||||
delete dialogTitleWidget;
|
||||
delete chapterTitleText;
|
||||
break;
|
||||
}
|
||||
|
||||
if (chapterTitleText) {
|
||||
pos.y += space;
|
||||
chapterTitleText->setPosition(pos);
|
||||
pos.y += chapterTitleText->getHeight() + space;
|
||||
}
|
||||
dialogTitleWidget->setPosition(pos);
|
||||
pos.y += dialogTitleWidget->getHeight() + space;
|
||||
|
||||
_widgets.push_back(dialogTitleWidget);
|
||||
if (chapterTitleText) {
|
||||
_chapterTitleTexts.push_back(chapterTitleText);
|
||||
}
|
||||
|
||||
++_nextTitleIndex;
|
||||
|
||||
if (pos.y > bottom) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_widgets[kWidgetIndexBack]->setVisible(_startTitleIndex > 0);
|
||||
_widgets[kWidgetIndexNext]->setVisible(_nextTitleIndex < StarkDiary->countDialog());
|
||||
}
|
||||
|
||||
void DialogScreen::loadDialog() {
|
||||
static const int space = 16;
|
||||
|
||||
freeDialogLineTexts();
|
||||
|
||||
_startLineIndex = _nextLineIndex;
|
||||
|
||||
Common::Point pos = _logFrame->getPosition();
|
||||
int boxWidth = _logFrame->getText()->getTargetWidth();
|
||||
int bottom = _logFrame->getText()->getTargetHeight() + pos.y;
|
||||
int height;
|
||||
DialogLineText *dialogLineText;
|
||||
|
||||
Diary::ConversationLog dialog = StarkDiary->getDialog(_curLogIndex);
|
||||
|
||||
while (_nextLineIndex < dialog.lines.size()) {
|
||||
height = 0;
|
||||
|
||||
dialogLineText = new DialogLineText(_gfx, _curLogIndex, _nextLineIndex, boxWidth);
|
||||
height = dialogLineText->getHeight();
|
||||
|
||||
if (pos.y + height + space > bottom) {
|
||||
delete dialogLineText;
|
||||
break;
|
||||
}
|
||||
|
||||
dialogLineText->setPosition(pos);
|
||||
_dialogLineTexts.push_back(dialogLineText);
|
||||
|
||||
pos.y += height + space;
|
||||
|
||||
++_nextLineIndex;
|
||||
}
|
||||
|
||||
_widgets[kWidgetLogBack]->setVisible(_startLineIndex > 0);
|
||||
_widgets[kWidgetLogNext]->setVisible(_nextLineIndex < dialog.lines.size());
|
||||
}
|
||||
|
||||
void DialogScreen::backHandler() {
|
||||
StarkUserInterface->backPrevScreen();
|
||||
}
|
||||
|
||||
void DialogScreen::indexBackHandler() {
|
||||
_nextTitleIndex = _prevTitleIndexStack.back();
|
||||
_prevTitleIndexStack.pop_back();
|
||||
loadIndex();
|
||||
}
|
||||
|
||||
void DialogScreen::indexNextHandler() {
|
||||
_prevTitleIndexStack.push_back(_startTitleIndex);
|
||||
loadIndex();
|
||||
}
|
||||
|
||||
void DialogScreen::logBackHandler() {
|
||||
_nextLineIndex = _prevLineIndexStack.back();
|
||||
_prevLineIndexStack.pop_back();
|
||||
loadDialog();
|
||||
}
|
||||
|
||||
void DialogScreen::backIndexHandler() {
|
||||
freeDialogLineTexts();
|
||||
_prevLineIndexStack.clear();
|
||||
|
||||
_widgets[kWidgetLogBack]->setVisible(false);
|
||||
_widgets[kWidgetLogNext]->setVisible(false);
|
||||
_widgets[kWidgetIndex]->setVisible(false);
|
||||
|
||||
_nextTitleIndex = _startTitleIndex;
|
||||
loadIndex();
|
||||
}
|
||||
|
||||
void DialogScreen::logNextHandler() {
|
||||
_prevLineIndexStack.push_back(_startLineIndex);
|
||||
loadDialog();
|
||||
}
|
||||
|
||||
void DialogScreen::freeLogTitleWidgets() {
|
||||
uint size = _widgets.size();
|
||||
for (uint i = 0; i < size - _dialogTitleWidgetOffset; ++i) {
|
||||
delete _widgets.back();
|
||||
_widgets.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void DialogScreen::freeChapterTitleTexts() {
|
||||
for (uint i = 0; i < _chapterTitleTexts.size(); ++i) {
|
||||
delete _chapterTitleTexts[i];
|
||||
}
|
||||
_chapterTitleTexts.clear();
|
||||
}
|
||||
|
||||
void DialogScreen::freeDialogLineTexts() {
|
||||
for (uint i = 0; i < _dialogLineTexts.size(); ++i) {
|
||||
delete _dialogLineTexts[i];
|
||||
}
|
||||
_dialogLineTexts.clear();
|
||||
}
|
||||
|
||||
ChapterTitleText::ChapterTitleText(Gfx::Driver *gfx, uint chapter) :
|
||||
_pos(), _text(gfx) {
|
||||
Common::String text = Common::String::format(
|
||||
"%s: %s",
|
||||
StarkGameChapter->getChapterTitle(chapter).c_str(),
|
||||
StarkGameChapter->getChapterSubtitle(chapter).c_str());
|
||||
text.toUppercase();
|
||||
|
||||
_text.setText(text);
|
||||
_text.setColor(_color);
|
||||
_text.setFont(FontProvider::kCustomFont, 5);
|
||||
}
|
||||
|
||||
DialogLineText::DialogLineText(Gfx::Driver *gfx, uint logIndex, uint lineIndex, uint boxWidth) :
|
||||
_namePos(), _linePos(), _boxWidth(boxWidth),
|
||||
_nameText(gfx), _lineText(gfx) {
|
||||
Diary::ConversationLogLine logLine = StarkDiary->getDialog(logIndex).lines[lineIndex];
|
||||
|
||||
Common::String name = StarkGlobal->getCharacterName(logLine.characterId);
|
||||
name.toUppercase();
|
||||
|
||||
Gfx::Color color = logLine.characterId == StarkGlobal->getApril()->getCharacterIndex() ? _textColorApril : _textColorNormal;
|
||||
|
||||
_nameText.setText(name);
|
||||
_nameText.setColor(color);
|
||||
_nameText.setFont(FontProvider::kCustomFont, 5);
|
||||
|
||||
_lineText.setTargetWidth(_boxWidth);
|
||||
_lineText.setText(logLine.line);
|
||||
_lineText.setColor(color);
|
||||
_lineText.setFont(FontProvider::kCustomFont, 3);
|
||||
|
||||
Common::Rect rect = _nameText.getRect();
|
||||
_nameWidth = rect.right - rect.left;
|
||||
_nameHeight = rect.bottom - rect.top;
|
||||
|
||||
rect = _lineText.getRect();
|
||||
_lineHeight = rect.bottom - rect.top;
|
||||
}
|
||||
|
||||
void DialogLineText::setPosition(const Common::Point &pos) {
|
||||
static const uint space = 4;
|
||||
|
||||
_namePos.x = pos.x + (_boxWidth - _nameWidth) / 2;
|
||||
_namePos.y = pos.y;
|
||||
|
||||
_linePos.x = pos.x;
|
||||
_linePos.y = pos.y + _nameHeight + space;
|
||||
}
|
||||
|
||||
DialogTitleWidget::DialogTitleWidget(DialogScreen *screen, Gfx::Driver *gfx, uint logIndex) :
|
||||
StaticLocationWidget(nullptr, nullptr, nullptr),
|
||||
_logIndex(logIndex), _pos(), _text(gfx),
|
||||
_screen(screen) {
|
||||
const Diary::ConversationLog &dialog = StarkDiary->getDialog(_logIndex);
|
||||
|
||||
_chapter = dialog.chapter;
|
||||
|
||||
_text.setText(dialog.title);
|
||||
_text.setColor(_textColorDefault);
|
||||
_text.setFont(FontProvider::kCustomFont, 3);
|
||||
|
||||
Common::Rect rect = _text.getRect();
|
||||
_width = rect.right - rect.left;
|
||||
_height = rect.bottom - rect.top;
|
||||
}
|
||||
|
||||
bool DialogTitleWidget::isMouseInside(const Common::Point &mousePos) const {
|
||||
return mousePos.x >= _pos.x && mousePos.x <= _pos.x + _width &&
|
||||
mousePos.y >= _pos.y && mousePos.y <= _pos.y + _height;
|
||||
}
|
||||
|
||||
void DialogTitleWidget::onClick() {
|
||||
_screen->onDialogClick(_logIndex);
|
||||
}
|
||||
|
||||
void DialogTitleWidget::onScreenChanged() {
|
||||
_text.reset();
|
||||
}
|
||||
|
||||
} // End of namespace Stark
|
||||
174
engines/stark/ui/menu/dialogmenu.h
Normal file
174
engines/stark/ui/menu/dialogmenu.h
Normal file
@@ -0,0 +1,174 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STARK_UI_MENU_DIALOG_H
|
||||
#define STARK_UI_MENU_DIALOG_H
|
||||
|
||||
#include "engines/stark/ui/menu/locationscreen.h"
|
||||
#include "engines/stark/visual/text.h"
|
||||
|
||||
namespace Stark {
|
||||
|
||||
class ChapterTitleText;
|
||||
class DialogLineText;
|
||||
|
||||
/**
|
||||
* The conversation log menu
|
||||
*/
|
||||
class DialogScreen : public StaticLocationScreen {
|
||||
public:
|
||||
DialogScreen(Gfx::Driver *gfx, Cursor *cursor);
|
||||
virtual ~DialogScreen();
|
||||
|
||||
// StaticLocationScreen API
|
||||
void open() override;
|
||||
void close() override;
|
||||
void onScreenChanged() override;
|
||||
|
||||
void onDialogClick(uint logIndex);
|
||||
|
||||
protected:
|
||||
// Window API
|
||||
void onRender() override;
|
||||
|
||||
private:
|
||||
static const uint _dialogTitleWidgetOffset = 8;
|
||||
|
||||
enum WidgetIndex {
|
||||
kWidgetIndexBack = 3,
|
||||
kWidgetIndexNext = 4,
|
||||
kWidgetLogBack = 5,
|
||||
kWidgetIndex = 6,
|
||||
kWidgetLogNext = 7
|
||||
};
|
||||
|
||||
Gfx::RenderEntry *_indexFrame, *_logFrame;
|
||||
uint _startTitleIndex, _nextTitleIndex, _startLineIndex, _nextLineIndex;
|
||||
uint _curMaxChapter, _curLogIndex;
|
||||
Common::Array<ChapterTitleText *> _chapterTitleTexts;
|
||||
Common::Array<uint> _prevTitleIndexStack;
|
||||
Common::Array<DialogLineText *> _dialogLineTexts;
|
||||
Common::Array<uint> _prevLineIndexStack;
|
||||
|
||||
void loadIndex();
|
||||
void loadDialog();
|
||||
|
||||
void backHandler();
|
||||
void indexBackHandler();
|
||||
void indexNextHandler();
|
||||
void logBackHandler();
|
||||
void backIndexHandler();
|
||||
void logNextHandler();
|
||||
|
||||
void freeLogTitleWidgets();
|
||||
void freeChapterTitleTexts();
|
||||
void freeDialogLineTexts();
|
||||
void freeResources();
|
||||
};
|
||||
|
||||
/**
|
||||
* The chapter title displayed on the menu
|
||||
*/
|
||||
class ChapterTitleText {
|
||||
public:
|
||||
ChapterTitleText(Gfx::Driver *gfx, uint chapter);
|
||||
~ChapterTitleText() {}
|
||||
|
||||
void setPosition(const Common::Point &pos) { _pos = pos; }
|
||||
uint getHeight() { return _text.getRect().bottom - _text.getRect().top; }
|
||||
|
||||
void render() { _text.render(_pos); }
|
||||
void onScreenChanged() { _text.reset(); }
|
||||
|
||||
private:
|
||||
const Gfx::Color _color = Gfx::Color(0x68, 0x05, 0x04);
|
||||
|
||||
Common::Point _pos;
|
||||
VisualText _text;
|
||||
};
|
||||
|
||||
/**
|
||||
* The dialog text displayed
|
||||
*/
|
||||
class DialogLineText {
|
||||
public:
|
||||
DialogLineText(Gfx::Driver *gfx, uint logIndex, uint lineIndex, uint boxWidth);
|
||||
~DialogLineText() {}
|
||||
|
||||
void setPosition(const Common::Point &pos);
|
||||
uint getHeight() { return _nameHeight + _lineHeight + 4; }
|
||||
|
||||
void render() {
|
||||
_nameText.render(_namePos);
|
||||
_lineText.render(_linePos);
|
||||
}
|
||||
|
||||
void onScreenChanged() {
|
||||
_nameText.reset();
|
||||
_lineText.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
const Gfx::Color _textColorApril = Gfx::Color(0x68, 0x05, 0x04);
|
||||
const Gfx::Color _textColorNormal = Gfx::Color(0x1E, 0x1E, 0x96);
|
||||
|
||||
Common::Point _namePos, _linePos;
|
||||
VisualText _nameText, _lineText;
|
||||
|
||||
uint _nameWidth, _nameHeight, _lineHeight, _boxWidth;
|
||||
};
|
||||
|
||||
/**
|
||||
* The dialog widget
|
||||
*/
|
||||
class DialogTitleWidget : public StaticLocationWidget {
|
||||
public:
|
||||
DialogTitleWidget(DialogScreen *screen, Gfx::Driver *gfx, uint logIndex);
|
||||
virtual ~DialogTitleWidget() {}
|
||||
|
||||
void setPosition(const Common::Point &pos) { _pos = pos; }
|
||||
uint getHeight() { return _height; }
|
||||
uint getChapter() { return _chapter; }
|
||||
|
||||
// StaticLocationWidget API
|
||||
void render() override { _text.render(_pos); }
|
||||
bool isMouseInside(const Common::Point &mousePos) const override;
|
||||
void onClick() override;
|
||||
void onMouseMove(const Common::Point &mousePos) override {
|
||||
_text.setColor(isMouseInside(mousePos) ? _textColorHovered : _textColorDefault);
|
||||
}
|
||||
void onScreenChanged() override;
|
||||
|
||||
private:
|
||||
const Gfx::Color _textColorHovered = Gfx::Color(0x1E, 0x1E, 0x96);
|
||||
const Gfx::Color _textColorDefault = Gfx::Color(0x00, 0x00, 0x00);
|
||||
|
||||
uint _logIndex, _chapter;
|
||||
int _width, _height;
|
||||
Common::Point _pos;
|
||||
VisualText _text;
|
||||
|
||||
DialogScreen *_screen;
|
||||
};
|
||||
|
||||
} // End of namespace Stark
|
||||
|
||||
#endif // STARK_UI_MENU_DIALOG_H
|
||||
145
engines/stark/ui/menu/diaryindex.cpp
Normal file
145
engines/stark/ui/menu/diaryindex.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
/* 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 "engines/stark/ui/menu/diaryindex.h"
|
||||
#include "engines/stark/gfx/driver.h"
|
||||
#include "engines/stark/services/services.h"
|
||||
#include "engines/stark/services/diary.h"
|
||||
#include "engines/stark/services/userinterface.h"
|
||||
#include "engines/stark/services/gamemessage.h"
|
||||
#include "engines/stark/ui/cursor.h"
|
||||
|
||||
#include "engines/engine.h"
|
||||
|
||||
#include "gui/message.h"
|
||||
#include "gui/saveload.h"
|
||||
|
||||
namespace Stark {
|
||||
|
||||
DiaryIndexScreen::DiaryIndexScreen(Gfx::Driver *gfx, Cursor *cursor) :
|
||||
StaticLocationScreen(gfx, cursor, "DiaryIndexLocation", Screen::kScreenDiaryIndex) {
|
||||
}
|
||||
|
||||
DiaryIndexScreen::~DiaryIndexScreen() {
|
||||
}
|
||||
|
||||
void DiaryIndexScreen::open() {
|
||||
StaticLocationScreen::open();
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"BGImage",
|
||||
nullptr,
|
||||
nullptr));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"SaveGame",
|
||||
CLICK_HANDLER(DiaryIndexScreen, saveHandler),
|
||||
MOVE_HANDLER(DiaryIndexScreen, widgetTextColorHandler)));
|
||||
_widgets.back()->setVisible(g_engine->canSaveGameStateCurrently());
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Continue",
|
||||
CLICK_HANDLER(DiaryIndexScreen, loadHandler),
|
||||
MOVE_HANDLER(DiaryIndexScreen, widgetTextColorHandler)));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Options",
|
||||
CLICK_HANDLER(DiaryIndexScreen, settingsHandler),
|
||||
MOVE_HANDLER(DiaryIndexScreen, widgetTextColorHandler)));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Log",
|
||||
CLICK_HANDLER(DiaryIndexScreen, dialogHandler),
|
||||
MOVE_HANDLER(DiaryIndexScreen, widgetTextColorHandler)));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Fmv",
|
||||
CLICK_HANDLER(DiaryIndexScreen, fmvHandler),
|
||||
MOVE_HANDLER(DiaryIndexScreen, widgetTextColorHandler)));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Diary",
|
||||
CLICK_HANDLER(DiaryIndexScreen, diaryHandler),
|
||||
MOVE_HANDLER(DiaryIndexScreen, widgetTextColorHandler)));
|
||||
_widgets.back()->setVisible(StarkDiary->isEnabled());
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Return",
|
||||
CLICK_HANDLER(DiaryIndexScreen, backHandler),
|
||||
nullptr));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Quit",
|
||||
CLICK_HANDLER(DiaryIndexScreen, quitHandler),
|
||||
MOVE_HANDLER(DiaryIndexScreen, widgetTextColorHandler)));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Back",
|
||||
CLICK_HANDLER(DiaryIndexScreen, backHandler),
|
||||
nullptr));
|
||||
|
||||
for (uint i = 1; i < _widgets.size(); i++) {
|
||||
// The background image is intentionally ignored
|
||||
_widgets[i]->setupSounds(0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void DiaryIndexScreen::widgetTextColorHandler(StaticLocationWidget &widget, const Common::Point &mousePos) {
|
||||
if (widget.isVisible()) {
|
||||
Gfx::Color textColor = widget.isMouseInside(mousePos) ? _textColorHovered : _textColorDefault;
|
||||
widget.setTextColor(textColor);
|
||||
}
|
||||
}
|
||||
|
||||
void DiaryIndexScreen::settingsHandler() {
|
||||
StarkUserInterface->changeScreen(Screen::kScreenSettingsMenu);
|
||||
}
|
||||
|
||||
void DiaryIndexScreen::fmvHandler() {
|
||||
StarkUserInterface->changeScreen(Screen::kScreenFMVMenu);
|
||||
}
|
||||
|
||||
void DiaryIndexScreen::backHandler() {
|
||||
StarkUserInterface->backPrevScreen();
|
||||
}
|
||||
|
||||
void DiaryIndexScreen::quitHandler() {
|
||||
StarkUserInterface->confirm(GameMessage::kQuitGamePrompt, StarkUserInterface,
|
||||
&UserInterface::requestQuitToMainMenu);
|
||||
}
|
||||
|
||||
void DiaryIndexScreen::loadHandler() {
|
||||
StarkUserInterface->changeScreen(Screen::kScreenLoadMenu);
|
||||
}
|
||||
|
||||
void DiaryIndexScreen::saveHandler() {
|
||||
StarkUserInterface->changeScreen(Screen::kScreenSaveMenu);
|
||||
}
|
||||
|
||||
void DiaryIndexScreen::diaryHandler() {
|
||||
StarkUserInterface->changeScreen(Screen::kScreenDiaryPages);
|
||||
}
|
||||
|
||||
void DiaryIndexScreen::dialogHandler() {
|
||||
StarkUserInterface->changeScreen(Screen::kScreenDialog);
|
||||
}
|
||||
|
||||
} // End of namespace Stark
|
||||
57
engines/stark/ui/menu/diaryindex.h
Normal file
57
engines/stark/ui/menu/diaryindex.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STARK_UI_MENU_DIARY_INDEX_H
|
||||
#define STARK_UI_MENU_DIARY_INDEX_H
|
||||
|
||||
#include "engines/stark/ui/menu/locationscreen.h"
|
||||
|
||||
namespace Stark {
|
||||
|
||||
/**
|
||||
* The diary index is the in-game menu
|
||||
*/
|
||||
class DiaryIndexScreen : public StaticLocationScreen {
|
||||
public:
|
||||
DiaryIndexScreen(Gfx::Driver *gfx, Cursor *cursor);
|
||||
virtual ~DiaryIndexScreen();
|
||||
|
||||
// StaticLocationScreen API
|
||||
void open() override;
|
||||
|
||||
private:
|
||||
void widgetTextColorHandler(StaticLocationWidget &widget, const Common::Point &mousePos);
|
||||
void backHandler();
|
||||
void settingsHandler();
|
||||
void fmvHandler();
|
||||
void loadHandler();
|
||||
void saveHandler();
|
||||
void diaryHandler();
|
||||
void dialogHandler();
|
||||
void quitHandler();
|
||||
|
||||
const Gfx::Color _textColorHovered = Gfx::Color(0x1E, 0x1E, 0x96);
|
||||
const Gfx::Color _textColorDefault = Gfx::Color(0x00, 0x00, 0x00);
|
||||
};
|
||||
|
||||
} // End of namespace Stark
|
||||
|
||||
#endif // STARK_UI_MENU_DIARY_INDEX_H
|
||||
122
engines/stark/ui/menu/diarypages.cpp
Normal file
122
engines/stark/ui/menu/diarypages.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
/* 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 "engines/stark/ui/menu/diarypages.h"
|
||||
#include "engines/stark/services/services.h"
|
||||
#include "engines/stark/services/userinterface.h"
|
||||
#include "engines/stark/services/diary.h"
|
||||
#include "engines/stark/services/staticprovider.h"
|
||||
#include "engines/stark/resources/location.h"
|
||||
#include "engines/stark/resources/layer.h"
|
||||
#include "engines/stark/gfx/renderentry.h"
|
||||
|
||||
namespace Stark {
|
||||
|
||||
DiaryPagesScreen::DiaryPagesScreen(Gfx::Driver *gfx, Cursor *cursor) :
|
||||
StaticLocationScreen(gfx, cursor, "DiaryPages", Screen::kScreenDiaryPages),
|
||||
_page(0) {
|
||||
}
|
||||
|
||||
DiaryPagesScreen::~DiaryPagesScreen() {
|
||||
}
|
||||
|
||||
void DiaryPagesScreen::open() {
|
||||
StaticLocationScreen::open();
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"BGImage",
|
||||
nullptr,
|
||||
nullptr));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Return",
|
||||
CLICK_HANDLER(DiaryPagesScreen, backHandler),
|
||||
nullptr));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"GoBack",
|
||||
CLICK_HANDLER(DiaryPagesScreen, backHandler),
|
||||
nullptr));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Back",
|
||||
CLICK_HANDLER(DiaryPagesScreen, prevPageHandler),
|
||||
nullptr));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Next",
|
||||
CLICK_HANDLER(DiaryPagesScreen, nextPageHandler),
|
||||
nullptr));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
|
||||
_page = StarkDiary->getPageIndex();
|
||||
|
||||
if (StarkDiary->countDiary() > 0) {
|
||||
_widgets.push_back(new DiaryWidget(_page));
|
||||
_widgets[kWidgetBack]->setVisible(_page > 0);
|
||||
_widgets[kWidgetNext]->setVisible(_page < StarkDiary->countDiary() - 1);
|
||||
} else {
|
||||
_widgets[kWidgetBack]->setVisible(false);
|
||||
_widgets[kWidgetNext]->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void DiaryPagesScreen::close() {
|
||||
StarkDiary->setPageIndex(_page);
|
||||
StarkDiary->setDiaryAllRead();
|
||||
StaticLocationScreen::close();
|
||||
}
|
||||
|
||||
void DiaryPagesScreen::backHandler() {
|
||||
StarkUserInterface->backPrevScreen();
|
||||
}
|
||||
|
||||
void DiaryPagesScreen::changePage(uint page) {
|
||||
assert(page < StarkDiary->countDiary());
|
||||
|
||||
delete _widgets.back();
|
||||
_widgets.pop_back();
|
||||
_widgets.push_back(new DiaryWidget(page));
|
||||
|
||||
_widgets[kWidgetBack]->setVisible(page > 0);
|
||||
_widgets[kWidgetNext]->setVisible(page < StarkDiary->countDiary() - 1);
|
||||
|
||||
_page = page;
|
||||
}
|
||||
|
||||
DiaryWidget::DiaryWidget(uint diaryIndex):
|
||||
StaticLocationWidget(nullptr, nullptr, nullptr) {
|
||||
Resources::Location *location = StarkStaticProvider->getLocation();
|
||||
Resources::Layer *layer = location->getLayerByName(StarkDiary->getDiary(diaryIndex));
|
||||
|
||||
if (!layer) {
|
||||
debug("Unable to retrieve diary in layer %s.", StarkDiary->getDiary(diaryIndex).c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
// Diary page layer contains only one item, the text
|
||||
_renderEntry = layer->listRenderEntries()[0];
|
||||
}
|
||||
|
||||
} // End of namespace Stark
|
||||
67
engines/stark/ui/menu/diarypages.h
Normal file
67
engines/stark/ui/menu/diarypages.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STARK_UI_MENU_DIARY_PAGES_H
|
||||
#define STARK_UI_MENU_DIARY_PAGES_H
|
||||
|
||||
#include "engines/stark/ui/menu/locationscreen.h"
|
||||
|
||||
namespace Stark {
|
||||
|
||||
/**
|
||||
* The screen where diary pages are shown in the game
|
||||
*/
|
||||
class DiaryPagesScreen : public StaticLocationScreen {
|
||||
public:
|
||||
DiaryPagesScreen(Gfx::Driver *gfx, Cursor *cursor);
|
||||
virtual ~DiaryPagesScreen();
|
||||
|
||||
// StaticLocationScreen API
|
||||
void open() override;
|
||||
void close() override;
|
||||
|
||||
private:
|
||||
enum WidgetIndex {
|
||||
kWidgetBack = 3,
|
||||
kWidgetNext = 4
|
||||
};
|
||||
|
||||
uint _page;
|
||||
|
||||
void backHandler();
|
||||
|
||||
void prevPageHandler() { changePage(_page - 1); }
|
||||
void nextPageHandler() { changePage(_page + 1); }
|
||||
void changePage(uint page);
|
||||
};
|
||||
|
||||
/**
|
||||
* The widget displaying diary text
|
||||
*/
|
||||
class DiaryWidget : public StaticLocationWidget {
|
||||
public:
|
||||
DiaryWidget(uint diaryIndex);
|
||||
~DiaryWidget() {}
|
||||
};
|
||||
|
||||
} // End of namespace Stark
|
||||
|
||||
#endif // STARK_UI_MENU_DIARY_PAGES_H
|
||||
197
engines/stark/ui/menu/fmvmenu.cpp
Normal file
197
engines/stark/ui/menu/fmvmenu.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
/* 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 "engines/stark/ui/menu/fmvmenu.h"
|
||||
#include "engines/stark/services/services.h"
|
||||
#include "engines/stark/services/userinterface.h"
|
||||
#include "engines/stark/services/diary.h"
|
||||
#include "engines/stark/services/staticprovider.h"
|
||||
#include "engines/stark/resources/location.h"
|
||||
#include "engines/stark/visual/text.h"
|
||||
|
||||
namespace Stark {
|
||||
|
||||
FMVMenuScreen::FMVMenuScreen(Gfx::Driver *gfx, Cursor *cursor) :
|
||||
StaticLocationScreen(gfx, cursor, "DiaryFMV", Screen::kScreenFMVMenu),
|
||||
_fmvWidgets(),
|
||||
_page(0),
|
||||
_maxPage(0) {
|
||||
_formatRectPos = Common::Point(202, 61);
|
||||
_fontHeight = 16;
|
||||
_fmvPerPage = 18;
|
||||
}
|
||||
|
||||
FMVMenuScreen::~FMVMenuScreen() {
|
||||
freeFMVWidgets();
|
||||
}
|
||||
|
||||
void FMVMenuScreen::open() {
|
||||
StaticLocationScreen::open();
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"BGImage",
|
||||
nullptr,
|
||||
nullptr));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Return",
|
||||
CLICK_HANDLER(FMVMenuScreen, backHandler),
|
||||
nullptr));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Back",
|
||||
CLICK_HANDLER(FMVMenuScreen, backHandler),
|
||||
nullptr));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"PreviousPage",
|
||||
CLICK_HANDLER(FMVMenuScreen, prevPageHandler),
|
||||
nullptr));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"NextPage",
|
||||
CLICK_HANDLER(FMVMenuScreen, nextPageHandler),
|
||||
nullptr));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
|
||||
// Acquire data for FMVWidget from the format rectangle
|
||||
|
||||
int formatRectHeight = 379;
|
||||
|
||||
Resources::Location *location = StarkStaticProvider->getLocation();
|
||||
Gfx::RenderEntry *formatRect = location->getRenderEntryByName("FormatRectangle");
|
||||
|
||||
if (formatRect) {
|
||||
_formatRectPos = formatRect->getPosition();
|
||||
formatRectHeight = formatRect->getText()->getTargetHeight();
|
||||
|
||||
// The format rectangle contains one line,
|
||||
// which can be used to retrieve the font's height
|
||||
Common::Rect textRect = formatRect->getText()->getRect();
|
||||
_fontHeight = textRect.bottom - textRect.top;
|
||||
|
||||
_fmvPerPage = formatRectHeight / (_fontHeight + 4);
|
||||
}
|
||||
|
||||
_maxPage = StarkDiary->countFMV() / _fmvPerPage;
|
||||
changePage(0);
|
||||
}
|
||||
|
||||
void FMVMenuScreen::close() {
|
||||
freeFMVWidgets();
|
||||
StaticLocationScreen::close();
|
||||
}
|
||||
|
||||
void FMVMenuScreen::onScreenChanged() {
|
||||
StaticLocationScreen::onScreenChanged();
|
||||
for (uint i = 0; i < _fmvWidgets.size(); ++i) {
|
||||
_fmvWidgets[i]->onScreenChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void FMVMenuScreen::onMouseMove(const Common::Point &pos) {
|
||||
StaticLocationScreen::onMouseMove(pos);
|
||||
for (uint i = 0; i < _fmvWidgets.size(); ++i) {
|
||||
_fmvWidgets[i]->onMouseMove(pos);
|
||||
}
|
||||
}
|
||||
|
||||
void FMVMenuScreen::onClick(const Common::Point &pos) {
|
||||
StaticLocationScreen::onClick(pos);
|
||||
for (uint i = 0; i < _fmvWidgets.size(); ++i) {
|
||||
if (_fmvWidgets[i]->isMouseInside(pos)) {
|
||||
_fmvWidgets[i]->onClick();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FMVMenuScreen::onRender() {
|
||||
StaticLocationScreen::onRender();
|
||||
for (uint i = 0; i < _fmvWidgets.size(); ++i) {
|
||||
_fmvWidgets[i]->render();
|
||||
}
|
||||
}
|
||||
|
||||
void FMVMenuScreen::backHandler() {
|
||||
StarkUserInterface->backPrevScreen();
|
||||
}
|
||||
|
||||
void FMVMenuScreen::freeFMVWidgets() {
|
||||
for (uint i = 0; i < _fmvWidgets.size(); ++i) {
|
||||
delete _fmvWidgets[i];
|
||||
}
|
||||
_fmvWidgets.clear();
|
||||
}
|
||||
|
||||
void FMVMenuScreen::loadFMVWidgets(uint page) {
|
||||
uint start = page * _fmvPerPage;
|
||||
uint end = start + _fmvPerPage;
|
||||
end = end < StarkDiary->countFMV() ? end : StarkDiary->countFMV();
|
||||
|
||||
for (uint i = start; i < end; ++i) {
|
||||
_fmvWidgets.push_back(new FMVWidget(_gfx, i));
|
||||
}
|
||||
}
|
||||
|
||||
void FMVMenuScreen::changePage(uint page) {
|
||||
assert(page <= _maxPage);
|
||||
|
||||
freeFMVWidgets();
|
||||
loadFMVWidgets(page);
|
||||
|
||||
_widgets[kWidgetPrevious]->setVisible(page > 0);
|
||||
_widgets[kWidgetNext]->setVisible(page < _maxPage);
|
||||
|
||||
_page = page;
|
||||
}
|
||||
|
||||
FMVWidget::FMVWidget(Gfx::Driver *gfx, uint fmvIndex) :
|
||||
_filename(StarkDiary->getFMVFilename(fmvIndex)),
|
||||
_title(gfx) {
|
||||
_title.setText(StarkDiary->getFMVTitle(fmvIndex));
|
||||
_title.setColor(_textColorDefault);
|
||||
_title.setFont(FontProvider::kCustomFont, 3);
|
||||
|
||||
Common::Rect rect = _title.getRect();
|
||||
_width = rect.right - rect.left;
|
||||
|
||||
_formatRectPos = Common::Point(202, 61);
|
||||
_fontHeight = 16;
|
||||
_fmvPerPage = 18;
|
||||
|
||||
_position.x = _formatRectPos.x;
|
||||
_position.y = _formatRectPos.y + (fmvIndex % _fmvPerPage) * (_fontHeight + 4);
|
||||
}
|
||||
|
||||
void FMVWidget::onClick() {
|
||||
StarkUserInterface->requestFMVPlayback(_filename);
|
||||
}
|
||||
|
||||
bool FMVWidget::isMouseInside(const Common::Point &mousePos) const {
|
||||
return mousePos.x >= _position.x && mousePos.x <= _position.x + _width &&
|
||||
mousePos.y >= _position.y && mousePos.y <= _position.y + _fontHeight;
|
||||
}
|
||||
|
||||
} // End of namespace Stark
|
||||
116
engines/stark/ui/menu/fmvmenu.h
Normal file
116
engines/stark/ui/menu/fmvmenu.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STARK_UI_MENU_FMV_MENU_H
|
||||
#define STARK_UI_MENU_FMV_MENU_H
|
||||
|
||||
#include "engines/stark/ui/menu/locationscreen.h"
|
||||
#include "engines/stark/visual/text.h"
|
||||
|
||||
#include "common/path.h"
|
||||
|
||||
namespace Stark {
|
||||
|
||||
class FMVWidget;
|
||||
|
||||
/**
|
||||
* The video replay menu
|
||||
*/
|
||||
class FMVMenuScreen : public StaticLocationScreen {
|
||||
public:
|
||||
FMVMenuScreen(Gfx::Driver *gfx, Cursor *cursor);
|
||||
virtual ~FMVMenuScreen();
|
||||
|
||||
// StaticLocationScreen API
|
||||
void open() override;
|
||||
void close() override;
|
||||
void onScreenChanged() override;
|
||||
|
||||
protected:
|
||||
// Window API
|
||||
void onMouseMove(const Common::Point &pos) override;
|
||||
void onClick(const Common::Point &pos) override;
|
||||
void onRender() override;
|
||||
|
||||
private:
|
||||
enum WidgetIndex {
|
||||
kWidgetPrevious = 3,
|
||||
kWidgetNext = 4
|
||||
};
|
||||
|
||||
Common::Array<FMVWidget *> _fmvWidgets;
|
||||
|
||||
Common::Point _formatRectPos;
|
||||
int _fontHeight;
|
||||
uint _fmvPerPage;
|
||||
|
||||
// Count from zero
|
||||
uint _page, _maxPage;
|
||||
|
||||
void backHandler();
|
||||
void prevPageHandler() { changePage(_page - 1); }
|
||||
void nextPageHandler() { changePage(_page + 1); }
|
||||
|
||||
void freeFMVWidgets();
|
||||
void loadFMVWidgets(uint page);
|
||||
void changePage(uint page);
|
||||
};
|
||||
|
||||
/**
|
||||
* The widget for FMV entry, specifically built for FMVMenuScreen
|
||||
*/
|
||||
class FMVWidget {
|
||||
public:
|
||||
FMVWidget(Gfx::Driver *gfx, uint fmvIndex);
|
||||
~FMVWidget() {}
|
||||
|
||||
void render() { _title.render(_position); }
|
||||
|
||||
bool isMouseInside(const Common::Point &mousePos) const;
|
||||
|
||||
void onMouseMove(const Common::Point &mousePos) {
|
||||
setTextColor(isMouseInside(mousePos) ? _textColorHovered : _textColorDefault);
|
||||
}
|
||||
|
||||
void onClick();
|
||||
|
||||
void setTextColor(const Gfx::Color &color) { _title.setColor(color); }
|
||||
|
||||
void onScreenChanged() { _title.reset(); }
|
||||
|
||||
private:
|
||||
const Gfx::Color _textColorHovered = Gfx::Color(0x1E, 0x1E, 0x96);
|
||||
const Gfx::Color _textColorDefault = Gfx::Color(0x00, 0x00, 0x00);
|
||||
|
||||
Common::Point _formatRectPos;
|
||||
int _fontHeight;
|
||||
uint _fmvPerPage;
|
||||
|
||||
const Common::Path &_filename;
|
||||
VisualText _title;
|
||||
|
||||
int _width;
|
||||
Common::Point _position;
|
||||
};
|
||||
|
||||
} // End of namespace Stark
|
||||
|
||||
#endif // STARK_UI_MENU_FMV_MENU_H
|
||||
268
engines/stark/ui/menu/locationscreen.cpp
Normal file
268
engines/stark/ui/menu/locationscreen.cpp
Normal file
@@ -0,0 +1,268 @@
|
||||
/* 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 "engines/stark/ui/menu/locationscreen.h"
|
||||
|
||||
#include "engines/stark/gfx/driver.h"
|
||||
|
||||
#include "engines/stark/services/services.h"
|
||||
#include "engines/stark/services/staticprovider.h"
|
||||
|
||||
#include "engines/stark/resources/item.h"
|
||||
#include "engines/stark/resources/location.h"
|
||||
#include "engines/stark/resources/sound.h"
|
||||
|
||||
#include "engines/stark/ui/cursor.h"
|
||||
|
||||
#include "engines/stark/visual/text.h"
|
||||
|
||||
#include "audio/mixer.h"
|
||||
#include "common/system.h"
|
||||
|
||||
namespace Stark {
|
||||
|
||||
StaticLocationScreen::StaticLocationScreen(Gfx::Driver *gfx, Cursor *cursor,
|
||||
const char *locationName, Screen::Name screenName) :
|
||||
SingleWindowScreen(screenName, gfx, cursor),
|
||||
_locationName(locationName),
|
||||
_location(nullptr),
|
||||
_hoveredWidgetIndex(-1) {
|
||||
_position = Common::Rect(Gfx::Driver::kOriginalWidth, Gfx::Driver::kOriginalHeight);
|
||||
_visible = true;
|
||||
}
|
||||
|
||||
StaticLocationScreen::~StaticLocationScreen() {
|
||||
freeWidgets();
|
||||
}
|
||||
|
||||
void StaticLocationScreen::open() {
|
||||
_location = StarkStaticProvider->loadLocation(_locationName);
|
||||
}
|
||||
|
||||
void StaticLocationScreen::close() {
|
||||
freeWidgets();
|
||||
|
||||
StarkStaticProvider->unloadLocation(_location);
|
||||
_location = nullptr;
|
||||
}
|
||||
|
||||
void StaticLocationScreen::freeWidgets() {
|
||||
for (uint i = 0; i < _widgets.size(); i++) {
|
||||
delete _widgets[i];
|
||||
}
|
||||
|
||||
_widgets.clear();
|
||||
_hoveredWidgetIndex = -1;
|
||||
}
|
||||
|
||||
void StaticLocationScreen::onGameLoop() {
|
||||
for (uint i = 0; i < _widgets.size(); i++) {
|
||||
StaticLocationWidget *widget = _widgets[i];
|
||||
if (widget->isVisible()) {
|
||||
widget->onGameLoop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StaticLocationScreen::onMouseMove(const Common::Point &pos) {
|
||||
int newHoveredWidget = -1;
|
||||
|
||||
for (uint i = 0; i < _widgets.size(); i++) {
|
||||
StaticLocationWidget *widget = _widgets[i];
|
||||
widget->onMouseMove(pos);
|
||||
|
||||
if (widget->isVisible() && widget->isMouseInside(pos)) {
|
||||
newHoveredWidget = i;
|
||||
}
|
||||
}
|
||||
|
||||
// The first widget is always the background. It is ignored below.
|
||||
|
||||
if (newHoveredWidget != _hoveredWidgetIndex) {
|
||||
if (_hoveredWidgetIndex > 0 && uint(_hoveredWidgetIndex) < _widgets.size()) {
|
||||
_widgets[_hoveredWidgetIndex]->onMouseLeave();
|
||||
}
|
||||
|
||||
if (newHoveredWidget > 0) {
|
||||
_widgets[newHoveredWidget]->onMouseEnter();
|
||||
}
|
||||
|
||||
_hoveredWidgetIndex = newHoveredWidget;
|
||||
}
|
||||
|
||||
_cursor->setCursorType(_hoveredWidgetIndex > 0 ? Cursor::kActive : Cursor::kDefault);
|
||||
}
|
||||
|
||||
void StaticLocationScreen::onClick(const Common::Point &pos) {
|
||||
for (uint i = 1; i < _widgets.size(); i++) {
|
||||
StaticLocationWidget *widget = _widgets[i];
|
||||
if (widget->isVisible() && widget->isMouseInside(pos)) {
|
||||
widget->onClick();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StaticLocationScreen::onRender() {
|
||||
for (uint i = 0; i < _widgets.size(); i++) {
|
||||
if (_widgets[i]->isVisible()) {
|
||||
_widgets[i]->render();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StaticLocationScreen::onScreenChanged() {
|
||||
for (uint i = 0; i < _widgets.size(); i++) {
|
||||
_widgets[i]->onScreenChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void StaticLocationScreen::waitForSoundsToComplete() {
|
||||
while (g_system->getMixer()->hasActiveChannelOfType(Audio::Mixer::kSFXSoundType)) {
|
||||
StarkGfx->clearScreen();
|
||||
g_system->delayMillis(10);
|
||||
StarkGfx->flipBuffer();
|
||||
}
|
||||
}
|
||||
|
||||
StaticLocationWidget::StaticLocationWidget(const char *renderEntryName, WidgetOnClickCallback *onClickCallback,
|
||||
WidgetOnMouseMoveCallback *onMouseMoveCallback):
|
||||
_onClick(onClickCallback),
|
||||
_onMouseMove(onMouseMoveCallback),
|
||||
_renderEntry(nullptr),
|
||||
_item(nullptr),
|
||||
_soundMouseEnter(nullptr),
|
||||
_soundMouseClick(nullptr),
|
||||
_visible(true) {
|
||||
if (renderEntryName) {
|
||||
Resources::Location *location = StarkStaticProvider->getLocation();
|
||||
_renderEntry = location->getRenderEntryByName(renderEntryName);
|
||||
|
||||
if (_renderEntry == nullptr) {
|
||||
debug("Widget disabled: unable to find render entry with name '%s' in location '%s'",
|
||||
renderEntryName, location->getName().c_str());
|
||||
setVisible(false);
|
||||
} else {
|
||||
_item = _renderEntry->getOwner();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StaticLocationWidget::render() {
|
||||
if (_renderEntry) {
|
||||
_renderEntry->render();
|
||||
}
|
||||
}
|
||||
|
||||
bool StaticLocationWidget::isVisible() const {
|
||||
return _visible;
|
||||
}
|
||||
|
||||
void StaticLocationWidget::setVisible(bool visible) {
|
||||
_visible = visible;
|
||||
}
|
||||
|
||||
bool StaticLocationWidget::isMouseInside(const Common::Point &mousePos) const {
|
||||
if (!_renderEntry) return false;
|
||||
|
||||
Common::Point relativePosition;
|
||||
return _renderEntry->containsPoint(mousePos, relativePosition, Common::Rect());
|
||||
}
|
||||
|
||||
void StaticLocationWidget::onClick() {
|
||||
onMouseLeave();
|
||||
|
||||
if (_soundMouseClick) {
|
||||
_soundMouseClick->play();
|
||||
_soundMouseClick->setStopOnDestroy(false);
|
||||
}
|
||||
|
||||
if (_onClick) {
|
||||
(*_onClick)();
|
||||
}
|
||||
}
|
||||
|
||||
void StaticLocationWidget::onGameLoop() {
|
||||
if (_item) {
|
||||
_item->onGameLoop();
|
||||
}
|
||||
}
|
||||
|
||||
void StaticLocationWidget::onMouseEnter() {
|
||||
if (_soundMouseEnter && !_soundMouseEnter->isPlaying()) {
|
||||
_soundMouseEnter->play();
|
||||
}
|
||||
}
|
||||
|
||||
void StaticLocationWidget::onMouseLeave() {
|
||||
if (_soundMouseEnter) {
|
||||
_soundMouseEnter->stop();
|
||||
}
|
||||
}
|
||||
|
||||
void StaticLocationWidget::setupSounds(int16 enterSound, int16 clickSound) {
|
||||
if (enterSound != -1) {
|
||||
_soundMouseEnter = StarkStaticProvider->getLocationSound(enterSound);
|
||||
}
|
||||
|
||||
if (clickSound != -1) {
|
||||
_soundMouseClick = StarkStaticProvider->getLocationSound(clickSound);
|
||||
}
|
||||
}
|
||||
|
||||
void StaticLocationWidget::setTextColor(const Gfx::Color &textColor) {
|
||||
if (!_renderEntry) return;
|
||||
|
||||
VisualText *text = _renderEntry->getText();
|
||||
assert(text);
|
||||
|
||||
text->setColor(textColor);
|
||||
}
|
||||
|
||||
void StaticLocationWidget::onScreenChanged() {
|
||||
if (!_renderEntry) return;
|
||||
|
||||
VisualText *text = _renderEntry->getText();
|
||||
if (text) {
|
||||
text->reset();
|
||||
}
|
||||
}
|
||||
|
||||
void StaticLocationWidget::onMouseMove(const Common::Point &mousePos) {
|
||||
if (_onMouseMove) {
|
||||
(*_onMouseMove)(*this, mousePos);
|
||||
}
|
||||
}
|
||||
|
||||
Common::Point StaticLocationWidget::getPosition() const {
|
||||
if (_renderEntry) {
|
||||
return _renderEntry->getPosition();
|
||||
}
|
||||
|
||||
return Common::Point(0, 0);
|
||||
}
|
||||
|
||||
StaticLocationWidget::~StaticLocationWidget() {
|
||||
delete _onClick;
|
||||
delete _onMouseMove;
|
||||
}
|
||||
|
||||
} // End of namespace Stark
|
||||
156
engines/stark/ui/menu/locationscreen.h
Normal file
156
engines/stark/ui/menu/locationscreen.h
Normal file
@@ -0,0 +1,156 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STARK_UI_MENU_LOCATION_SCREEN_H
|
||||
#define STARK_UI_MENU_LOCATION_SCREEN_H
|
||||
|
||||
#include "engines/stark/ui/screen.h"
|
||||
#include "engines/stark/ui/window.h"
|
||||
#include "engines/stark/gfx/color.h"
|
||||
|
||||
namespace Stark {
|
||||
|
||||
namespace Gfx {
|
||||
class RenderEntry;
|
||||
}
|
||||
|
||||
namespace Resources {
|
||||
class ItemVisual;
|
||||
class Location;
|
||||
class Sound;
|
||||
}
|
||||
|
||||
class StaticLocationWidget;
|
||||
|
||||
/**
|
||||
* Abstract user interface screen using resources from a static Location sub-tree
|
||||
*/
|
||||
class StaticLocationScreen : public SingleWindowScreen {
|
||||
public:
|
||||
StaticLocationScreen(Gfx::Driver *gfx, Cursor *cursor, const char *locationName, Screen::Name screenName);
|
||||
~StaticLocationScreen() override;
|
||||
|
||||
// Screen API
|
||||
void open() override;
|
||||
void close() override;
|
||||
void onScreenChanged() override;
|
||||
|
||||
/**
|
||||
* Wait for all effect sounds to complete
|
||||
*
|
||||
* Used to ensure the button press sounds are no longer
|
||||
* playing before performing the next action that
|
||||
* would produce a sound.
|
||||
*/
|
||||
void waitForSoundsToComplete();
|
||||
|
||||
protected:
|
||||
// Window API
|
||||
void onMouseMove(const Common::Point &pos) override;
|
||||
void onClick(const Common::Point &pos) override;
|
||||
void onGameLoop() override;
|
||||
void onRender() override;
|
||||
|
||||
Common::Array<StaticLocationWidget *> _widgets;
|
||||
|
||||
private:
|
||||
const char *_locationName;
|
||||
Resources::Location *_location;
|
||||
int _hoveredWidgetIndex;
|
||||
|
||||
void freeWidgets();
|
||||
};
|
||||
|
||||
typedef Common::Functor0<void> WidgetOnClickCallback;
|
||||
typedef Common::Functor2<StaticLocationWidget &, const Common::Point &, void> WidgetOnMouseMoveCallback;
|
||||
#define CLICK_HANDLER(cls, method) new Common::Functor0Mem<void, cls>(this, &cls::method)
|
||||
#define MOVE_HANDLER(cls, method) new Common::Functor2Mem<StaticLocationWidget &, const Common::Point &, void, cls>(this, &cls::method)
|
||||
|
||||
/**
|
||||
* User interface widget bound to a Location RenderEntry
|
||||
*
|
||||
* Also used without bounding the RenderEntry, as a base class
|
||||
*/
|
||||
class StaticLocationWidget {
|
||||
public:
|
||||
StaticLocationWidget(const char *renderEntryName, WidgetOnClickCallback *onClickCallback,
|
||||
WidgetOnMouseMoveCallback *onMouseMoveCallback);
|
||||
virtual ~StaticLocationWidget();
|
||||
|
||||
/** Draw the widget */
|
||||
virtual void render();
|
||||
|
||||
/** Is the specified point inside the widget? */
|
||||
virtual bool isMouseInside(const Common::Point &mousePos) const;
|
||||
|
||||
/** Called when the widget is clicked */
|
||||
virtual void onClick();
|
||||
|
||||
/** Called when the mouse hovers the widget */
|
||||
virtual void onMouseMove(const Common::Point &mousePos);
|
||||
|
||||
/** Called when the mouse's left button just gets up */
|
||||
virtual void onMouseUp() {}
|
||||
|
||||
/** Called when the screen's resolution is changed */
|
||||
virtual void onScreenChanged();
|
||||
|
||||
/** Lookup sounds in the static location for use when hovering / clicking the widget */
|
||||
void setupSounds(int16 enterSound, int16 clickSound);
|
||||
|
||||
/**
|
||||
* Override the text color
|
||||
*
|
||||
* Only applies for widget referring to a RenderEntry for a text visual
|
||||
*/
|
||||
void setTextColor(const Gfx::Color &textColor);
|
||||
|
||||
/** Widgets must be visible to be rendered and interactive */
|
||||
bool isVisible() const;
|
||||
void setVisible(bool visible);
|
||||
|
||||
/** Per frame widget state update callback */
|
||||
void onGameLoop();
|
||||
|
||||
/** Called when the mouse enters the widget */
|
||||
void onMouseEnter();
|
||||
|
||||
/** Called when the mouse leaves the widget */
|
||||
void onMouseLeave();
|
||||
|
||||
protected:
|
||||
Common::Point getPosition() const;
|
||||
Gfx::RenderEntry *_renderEntry;
|
||||
|
||||
private:
|
||||
Resources::ItemVisual *_item;
|
||||
bool _visible;
|
||||
|
||||
Resources::Sound *_soundMouseEnter;
|
||||
Resources::Sound *_soundMouseClick;
|
||||
|
||||
WidgetOnClickCallback *_onClick;
|
||||
WidgetOnMouseMoveCallback *_onMouseMove;
|
||||
};
|
||||
|
||||
} // End of namespace Stark
|
||||
|
||||
#endif // STARK_UI_MENU_LOCATION_SCREEN_H
|
||||
197
engines/stark/ui/menu/mainmenu.cpp
Normal file
197
engines/stark/ui/menu/mainmenu.cpp
Normal file
@@ -0,0 +1,197 @@
|
||||
/* 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 "engines/stark/ui/menu/mainmenu.h"
|
||||
#include "engines/stark/services/userinterface.h"
|
||||
#include "engines/stark/services/resourceprovider.h"
|
||||
#include "engines/stark/services/global.h"
|
||||
#include "engines/stark/services/settings.h"
|
||||
#include "engines/stark/services/gamemessage.h"
|
||||
|
||||
#include "engines/stark/gfx/renderentry.h"
|
||||
#include "engines/stark/visual/text.h"
|
||||
|
||||
#include "engines/stark/scene.h"
|
||||
|
||||
#include "common/config-manager.h"
|
||||
|
||||
namespace Stark {
|
||||
|
||||
MainMenuScreen::MainMenuScreen(Gfx::Driver *gfx, Cursor *cursor) :
|
||||
StaticLocationScreen(gfx, cursor, "MainMenuLocation", Screen::kScreenMainMenu) {
|
||||
}
|
||||
|
||||
MainMenuScreen::~MainMenuScreen() {
|
||||
}
|
||||
|
||||
void MainMenuScreen::open() {
|
||||
StaticLocationScreen::open();
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"BGImage",
|
||||
nullptr,
|
||||
nullptr));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"NewGame",
|
||||
CLICK_HANDLER(MainMenuScreen, newGameHandler),
|
||||
MOVE_HANDLER(MainMenuScreen, helpTextHandler<kNewGame>)));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Continue",
|
||||
CLICK_HANDLER(MainMenuScreen, loadHandler),
|
||||
MOVE_HANDLER(MainMenuScreen, helpTextHandler<kContinue>)));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Options",
|
||||
CLICK_HANDLER(MainMenuScreen, settingsHandler),
|
||||
MOVE_HANDLER(MainMenuScreen, helpTextHandler<kOption>)));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Box",
|
||||
CLICK_HANDLER(MainMenuScreen, boxHandler),
|
||||
MOVE_HANDLER(MainMenuScreen, helpTextHandler<kBox>)));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Quit",
|
||||
CLICK_HANDLER(MainMenuScreen, quitHandler),
|
||||
MOVE_HANDLER(MainMenuScreen, helpTextHandler<kQuit>)));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"OptionHelp",
|
||||
nullptr,
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"BeginHelp",
|
||||
nullptr,
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"ContinueHelp",
|
||||
nullptr,
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"BoxHelp",
|
||||
nullptr,
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"QuitHelp",
|
||||
nullptr,
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Credits",
|
||||
CLICK_HANDLER(MainMenuScreen, creditsHandler),
|
||||
MOVE_HANDLER(MainMenuScreen, helpTextHandler<kCredits>)));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"CreditHelp",
|
||||
nullptr,
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
|
||||
_widgets.push_back(new VersionInfoText());
|
||||
}
|
||||
|
||||
template<MainMenuScreen::HelpTextIndex N>
|
||||
void MainMenuScreen::helpTextHandler(StaticLocationWidget &widget, const Common::Point &mousePos) {
|
||||
if (widget.isVisible()) {
|
||||
_widgets[N]->setVisible(widget.isMouseInside(mousePos));
|
||||
}
|
||||
}
|
||||
|
||||
void MainMenuScreen::creditsHandler() {
|
||||
if (!StarkSettings->isDemo()) {
|
||||
waitForSoundsToComplete();
|
||||
StarkUserInterface->requestFMVPlayback("0e02.bbb");
|
||||
}
|
||||
}
|
||||
|
||||
void MainMenuScreen::newGameHandler() {
|
||||
waitForSoundsToComplete();
|
||||
|
||||
StarkUserInterface->changeScreen(kScreenGame);
|
||||
|
||||
StarkResourceProvider->initGlobal();
|
||||
|
||||
if (ConfMan.hasKey("startup_chapter")) {
|
||||
StarkGlobal->setCurrentChapter(ConfMan.getInt("startup_chapter"));
|
||||
} else {
|
||||
StarkGlobal->setCurrentChapter(0);
|
||||
}
|
||||
|
||||
if (ConfMan.hasKey("startup_level") && ConfMan.hasKey("startup_location")) {
|
||||
uint levelIndex = strtol(ConfMan.get("startup_level").c_str(), nullptr, 16);
|
||||
uint locationIndex = strtol(ConfMan.get("startup_location").c_str(), nullptr, 16);
|
||||
StarkResourceProvider->requestLocationChange(levelIndex, locationIndex);
|
||||
} else {
|
||||
if (StarkSettings->isDemo()) {
|
||||
StarkResourceProvider->requestLocationChange(0x4f, 0x00);
|
||||
} else {
|
||||
// Start us up at the house of all worlds
|
||||
StarkResourceProvider->requestLocationChange(0x45, 0x00);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainMenuScreen::loadHandler() {
|
||||
StarkUserInterface->changeScreen(Screen::kScreenLoadMenu);
|
||||
}
|
||||
|
||||
void MainMenuScreen::settingsHandler() {
|
||||
StarkUserInterface->changeScreen(Screen::kScreenSettingsMenu);
|
||||
}
|
||||
|
||||
void MainMenuScreen::boxHandler() {
|
||||
if (!StarkSettings->isDemo() && StarkSettings->hasBookOfSecrets()) {
|
||||
StarkUserInterface->changeScreen(kScreenGame);
|
||||
StarkResourceProvider->initGlobal();
|
||||
StarkResourceProvider->requestLocationChange(0x7c, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
void MainMenuScreen::quitHandler() {
|
||||
StarkUserInterface->confirm(GameMessage::kQuitGamePrompt, StarkUserInterface,
|
||||
&UserInterface::notifyShouldExit);
|
||||
}
|
||||
|
||||
VersionInfoText::VersionInfoText() :
|
||||
StaticLocationWidget("VERSION INFO", nullptr, nullptr) {
|
||||
Common::String text = _copyrightSymbol + Common::String("1999 Funcom");
|
||||
_renderEntry->getText()->setText(text);
|
||||
_renderEntry->setPosition(Common::Point(_posX, _posY));
|
||||
}
|
||||
|
||||
} // End of namespace Stark
|
||||
76
engines/stark/ui/menu/mainmenu.h
Normal file
76
engines/stark/ui/menu/mainmenu.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STARK_UI_MENU_MAIN_MENU_H
|
||||
#define STARK_UI_MENU_MAIN_MENU_H
|
||||
|
||||
#include "engines/stark/ui/menu/locationscreen.h"
|
||||
|
||||
namespace Stark {
|
||||
|
||||
/**
|
||||
* The main menu of the game when it is opened
|
||||
*/
|
||||
class MainMenuScreen : public StaticLocationScreen {
|
||||
public:
|
||||
MainMenuScreen(Gfx::Driver *gfx, Cursor *cursor);
|
||||
virtual ~MainMenuScreen();
|
||||
|
||||
// StaticLocationScreen API
|
||||
void open() override;
|
||||
|
||||
private:
|
||||
enum HelpTextIndex {
|
||||
kNewGame = 7,
|
||||
kContinue = 8,
|
||||
kOption = 6,
|
||||
kBox = 9,
|
||||
kQuit = 10,
|
||||
kCredits = 12
|
||||
};
|
||||
|
||||
template<HelpTextIndex N>
|
||||
void helpTextHandler(StaticLocationWidget &widget, const Common::Point &mousePos);
|
||||
|
||||
void newGameHandler();
|
||||
void loadHandler();
|
||||
void creditsHandler();
|
||||
void settingsHandler();
|
||||
void boxHandler();
|
||||
void quitHandler();
|
||||
};
|
||||
|
||||
/**
|
||||
* The version info text
|
||||
*/
|
||||
class VersionInfoText : public StaticLocationWidget {
|
||||
public:
|
||||
VersionInfoText();
|
||||
virtual ~VersionInfoText() {}
|
||||
|
||||
private:
|
||||
static const char _copyrightSymbol = char(0xA9);
|
||||
static const int _posX = 16, _posY = 419;
|
||||
};
|
||||
|
||||
} // End of namespace Stark
|
||||
|
||||
#endif // STARK_UI_MENU_MAIN_MENU_H
|
||||
360
engines/stark/ui/menu/saveloadmenu.cpp
Normal file
360
engines/stark/ui/menu/saveloadmenu.cpp
Normal file
@@ -0,0 +1,360 @@
|
||||
/* 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 "engines/stark/ui/menu/saveloadmenu.h"
|
||||
#include "engines/stark/services/services.h"
|
||||
#include "engines/stark/services/userinterface.h"
|
||||
#include "engines/stark/services/stateprovider.h"
|
||||
#include "engines/stark/services/global.h"
|
||||
#include "engines/stark/services/settings.h"
|
||||
#include "engines/stark/services/gamechapter.h"
|
||||
#include "engines/stark/services/gamemessage.h"
|
||||
#include "engines/stark/gfx/driver.h"
|
||||
#include "engines/stark/gfx/bitmap.h"
|
||||
#include "engines/stark/gfx/surfacerenderer.h"
|
||||
#include "engines/stark/stark.h"
|
||||
#include "engines/stark/savemetadata.h"
|
||||
|
||||
#include "engines/engine.h"
|
||||
|
||||
#include "common/config-manager.h"
|
||||
#include "common/savefile.h"
|
||||
|
||||
#include "gui/message.h"
|
||||
|
||||
namespace Stark {
|
||||
|
||||
SaveLoadMenuScreen::SaveLoadMenuScreen(Gfx::Driver *gfx, Cursor *cursor, Screen::Name screenName) :
|
||||
StaticLocationScreen(gfx, cursor, "LoadSaveLocation", screenName),
|
||||
_page(0),
|
||||
_maxPage(10) {
|
||||
}
|
||||
|
||||
SaveLoadMenuScreen::~SaveLoadMenuScreen() {
|
||||
}
|
||||
|
||||
void SaveLoadMenuScreen::open() {
|
||||
StaticLocationScreen::open();
|
||||
|
||||
_maxPage = computeMaxPage();
|
||||
|
||||
_page = StarkSettings->getIntSetting(Settings::kSaveLoadPage);
|
||||
if (_page > _maxPage) {
|
||||
_page = _maxPage;
|
||||
}
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"loadsavebg",
|
||||
nullptr,
|
||||
nullptr));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"back to index",
|
||||
CLICK_HANDLER(SaveLoadMenuScreen, backHandler),
|
||||
nullptr));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Cancel",
|
||||
CLICK_HANDLER(SaveLoadMenuScreen, backHandler),
|
||||
nullptr));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"SaveText",
|
||||
nullptr,
|
||||
nullptr));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"LoadText",
|
||||
nullptr,
|
||||
nullptr));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Back",
|
||||
CLICK_HANDLER(SaveLoadMenuScreen, prevPageHandler),
|
||||
nullptr));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
_widgets.back()->setTextColor(Gfx::Color(0, 0, 0));
|
||||
_widgets.back()->setVisible(_page > 0);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Next",
|
||||
CLICK_HANDLER(SaveLoadMenuScreen, nextPageHandler),
|
||||
nullptr));
|
||||
_widgets.back()->setupSounds(0, 1);
|
||||
_widgets.back()->setTextColor(Gfx::Color(0, 0, 0));
|
||||
_widgets.back()->setVisible(_page < _maxPage);
|
||||
|
||||
loadSaveData(_page);
|
||||
}
|
||||
|
||||
void SaveLoadMenuScreen::close() {
|
||||
ConfMan.flushToDisk();
|
||||
StaticLocationScreen::close();
|
||||
}
|
||||
|
||||
int SaveLoadMenuScreen::computeMaxPage() {
|
||||
const char *target = ConfMan.getActiveDomainName().c_str();
|
||||
|
||||
int maxSlot = 0;
|
||||
Common::StringArray saves = StarkEngine::listSaveNames(target);
|
||||
for (Common::StringArray::const_iterator filename = saves.begin(); filename != saves.end(); filename++) {
|
||||
int slot = StarkEngine::getSaveNameSlot(target, *filename);
|
||||
|
||||
if (slot > maxSlot) {
|
||||
maxSlot = slot;
|
||||
}
|
||||
}
|
||||
|
||||
// Allow using one more page than the last page with saves
|
||||
int maxPage = CLIP((maxSlot / _slotPerPage) + 1, 0, 110);
|
||||
if (maxPage < 10) {
|
||||
maxPage = 10;
|
||||
}
|
||||
|
||||
return maxPage;
|
||||
}
|
||||
|
||||
void SaveLoadMenuScreen::backHandler() {
|
||||
StarkUserInterface->backPrevScreen();
|
||||
}
|
||||
|
||||
void SaveLoadMenuScreen::checkError(Common::Error error) {
|
||||
if (error.getCode() != Common::kNoError) {
|
||||
GUI::MessageDialog dialog(error.getDesc());
|
||||
dialog.runModal();
|
||||
}
|
||||
}
|
||||
|
||||
void SaveLoadMenuScreen::removeSaveDataWidgets() {
|
||||
assert(_widgets.size() == 7 + _slotPerPage);
|
||||
|
||||
for (int i = 0; i < _slotPerPage; ++i) {
|
||||
delete _widgets.back();
|
||||
_widgets.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
void SaveLoadMenuScreen::loadSaveData(int page) {
|
||||
for (int i = 0; i < _slotPerPage; ++i) {
|
||||
_widgets.push_back(new SaveDataWidget(i + page * _slotPerPage, _gfx, this));
|
||||
}
|
||||
}
|
||||
|
||||
void SaveLoadMenuScreen::changePage(int page) {
|
||||
assert(page >= 0 && page <= _maxPage);
|
||||
|
||||
removeSaveDataWidgets();
|
||||
loadSaveData(page);
|
||||
|
||||
_widgets[kWidgetBack]->setVisible(page > 0);
|
||||
_widgets[kWidgetNext]->setVisible(page < _maxPage);
|
||||
|
||||
StarkSettings->setIntSetting(Settings::kSaveLoadPage, page);
|
||||
_page = page;
|
||||
}
|
||||
|
||||
void SaveMenuScreen::open() {
|
||||
SaveLoadMenuScreen::open();
|
||||
_widgets[kWidgetLoadText]->setVisible(false);
|
||||
}
|
||||
|
||||
void SaveMenuScreen::onWidgetSelected(SaveDataWidget *widget) {
|
||||
if (widget->hasSave()) {
|
||||
_slotToSaveAfterConfirm = widget;
|
||||
|
||||
Common::String format = StarkGameMessage->getTextByKey(GameMessage::kOverwriteSave);
|
||||
Common::String prompt = Common::String::format(format.c_str(), widget->getName().c_str());
|
||||
|
||||
StarkUserInterface->confirm(prompt, this, &SaveMenuScreen::saveConfirmSlot);
|
||||
} else {
|
||||
saveGameToSlot(widget);
|
||||
}
|
||||
}
|
||||
|
||||
void SaveMenuScreen::saveConfirmSlot() {
|
||||
assert(_slotToSaveAfterConfirm);
|
||||
|
||||
saveGameToSlot(_slotToSaveAfterConfirm);
|
||||
_slotToSaveAfterConfirm = nullptr;
|
||||
}
|
||||
|
||||
void SaveMenuScreen::saveGameToSlot(SaveDataWidget *widget) {
|
||||
checkError(g_engine->saveGameState(widget->getSlot(), StarkGameChapter->getCurrentChapterTitle()));
|
||||
|
||||
// Freeze the screen for a while to let the user notice the change
|
||||
widget->loadSaveDataElements();
|
||||
render();
|
||||
StarkGfx->flipBuffer();
|
||||
g_system->delayMillis(100);
|
||||
render();
|
||||
StarkGfx->flipBuffer();
|
||||
|
||||
StarkUserInterface->backPrevScreen();
|
||||
}
|
||||
|
||||
void LoadMenuScreen::open() {
|
||||
SaveLoadMenuScreen::open();
|
||||
_widgets[kWidgetSaveText]->setVisible(false);
|
||||
}
|
||||
|
||||
void LoadMenuScreen::onWidgetSelected(SaveDataWidget *widget) {
|
||||
if (!StarkGlobal->getCurrent()) {
|
||||
checkError(g_engine->loadGameState(widget->getSlot()));
|
||||
} else {
|
||||
_slotToLoadAfterConfirm = widget->getSlot();
|
||||
StarkUserInterface->confirm(GameMessage::kEndAndLoad, this, &LoadMenuScreen::loadConfirmSlot);
|
||||
}
|
||||
}
|
||||
|
||||
void LoadMenuScreen::loadConfirmSlot() {
|
||||
assert(_slotToLoadAfterConfirm >= 0);
|
||||
|
||||
checkError(g_engine->loadGameState(_slotToLoadAfterConfirm));
|
||||
_slotToLoadAfterConfirm = -1;
|
||||
}
|
||||
|
||||
SaveDataWidget::SaveDataWidget(int slot, Gfx::Driver *gfx, SaveLoadMenuScreen *screen) :
|
||||
StaticLocationWidget(nullptr, nullptr, nullptr),
|
||||
_slot(slot),
|
||||
_screen(screen),
|
||||
_thumbWidth(kThumbnailWidth),
|
||||
_thumbHeight(kThumbnailHeight),
|
||||
_bitmap(gfx->createBitmap()),
|
||||
_outline(gfx->createBitmap()),
|
||||
_surfaceRenderer(gfx->createSurfaceRenderer()),
|
||||
_textDesc(gfx),
|
||||
_textTime(gfx),
|
||||
_isMouseHovered(false),
|
||||
_hasSave(false),
|
||||
_name() {
|
||||
// Load from the save data
|
||||
loadSaveDataElements();
|
||||
|
||||
_textDesc.setColor(_textColor);
|
||||
_textDesc.setFont(FontProvider::kCustomFont, 3);
|
||||
|
||||
_textTime.setColor(_textColor);
|
||||
_textTime.setFont(FontProvider::kCustomFont, 3);
|
||||
|
||||
Graphics::PixelFormat pixelFormat = Gfx::Driver::getRGBAPixelFormat();
|
||||
uint32 outlineColor = pixelFormat.ARGBToColor(
|
||||
_outlineColor.a, _outlineColor.r, _outlineColor.g, _outlineColor.b
|
||||
);
|
||||
|
||||
// Create the outline bitmap
|
||||
Graphics::Surface lineSurface;
|
||||
lineSurface.create(_thumbWidth, _thumbHeight, pixelFormat);
|
||||
lineSurface.drawThickLine(0, 0, _thumbWidth - 1, 0, 2, 2, outlineColor);
|
||||
lineSurface.drawThickLine(0, 0, 0, _thumbHeight - 1, 2, 2, outlineColor);
|
||||
lineSurface.drawThickLine(_thumbWidth - 2, 0, _thumbWidth - 2, _thumbHeight - 2, 2, 2, outlineColor);
|
||||
lineSurface.drawThickLine(0, _thumbHeight - 2, _thumbWidth - 2, _thumbHeight - 2, 2, 2, outlineColor);
|
||||
|
||||
_outline->update(&lineSurface);
|
||||
lineSurface.free();
|
||||
|
||||
// Set the position
|
||||
_thumbPos.x = 41 + (_slot % SaveLoadMenuScreen::_slotPerRow) * (_thumbWidth + 39);
|
||||
_thumbPos.y = 61 + (_slot % SaveLoadMenuScreen::_slotPerPage / SaveLoadMenuScreen::_slotPerColumn) * (_thumbHeight + 38);
|
||||
|
||||
_textDescPos.x = _thumbPos.x;
|
||||
_textDescPos.y = _thumbPos.y + _thumbHeight + 2;
|
||||
|
||||
_textTimePos.x = _thumbPos.x;
|
||||
_textTimePos.y = _textDescPos.y + 12;
|
||||
}
|
||||
|
||||
SaveDataWidget::~SaveDataWidget() {
|
||||
delete _bitmap;
|
||||
delete _outline;
|
||||
delete _surfaceRenderer;
|
||||
}
|
||||
|
||||
void SaveDataWidget::render() {
|
||||
_surfaceRenderer->render(_bitmap, _thumbPos);
|
||||
_textDesc.render(_textDescPos);
|
||||
_textTime.render(_textTimePos);
|
||||
if (_isMouseHovered) {
|
||||
_surfaceRenderer->render(_outline, _thumbPos);
|
||||
}
|
||||
}
|
||||
|
||||
bool SaveDataWidget::isMouseInside(const Common::Point &mousePos) const {
|
||||
return mousePos.x >= _thumbPos.x && mousePos.x <= _thumbPos.x + _thumbWidth &&
|
||||
mousePos.y >= _thumbPos.y && mousePos.y <= _thumbPos.y + _thumbHeight;
|
||||
}
|
||||
|
||||
void SaveDataWidget::onClick() {
|
||||
StaticLocationWidget::onClick();
|
||||
_screen->onWidgetSelected(this);
|
||||
}
|
||||
|
||||
void SaveDataWidget::onMouseMove(const Common::Point &mousePos) {
|
||||
StaticLocationWidget::onMouseMove(mousePos);
|
||||
_isMouseHovered = isMouseInside(mousePos);
|
||||
}
|
||||
|
||||
void SaveDataWidget::onScreenChanged() {
|
||||
StaticLocationWidget::onScreenChanged();
|
||||
_textDesc.reset();
|
||||
_textTime.reset();
|
||||
}
|
||||
|
||||
void SaveDataWidget::loadSaveDataElements() {
|
||||
Common::String filename = StarkEngine::formatSaveName(ConfMan.getActiveDomainName().c_str(), _slot);
|
||||
Common::InSaveFile *save = g_system->getSavefileManager()->openForLoading(filename);
|
||||
if (save) {
|
||||
_hasSave = true;
|
||||
|
||||
SaveMetadata metadata;
|
||||
StateReadStream stream(save);
|
||||
Common::ErrorCode metadataErrorCode = metadata.read(&stream, filename);
|
||||
if (metadataErrorCode != Common::kNoError) {
|
||||
error("Unable to read save metadata with error code %d.", metadataErrorCode);
|
||||
}
|
||||
|
||||
// Obtain the thumbnail
|
||||
if (metadata.version >= 9) {
|
||||
Graphics::Surface *thumb = metadata.readGameScreenThumbnail(&stream);
|
||||
_bitmap->update(thumb);
|
||||
_bitmap->setSamplingFilter(StarkSettings->getImageSamplingFilter());
|
||||
|
||||
thumb->free();
|
||||
delete thumb;
|
||||
}
|
||||
|
||||
// Obtain the text
|
||||
Common::String desc = metadata.description;
|
||||
Common::String time = Common::String::format("%02d:%02d:%02d %02d/%02d/%02d",
|
||||
metadata.saveHour, metadata.saveMinute, metadata.saveSecond,
|
||||
metadata.saveMonth, metadata.saveDay, metadata.saveYear % 100);
|
||||
|
||||
_textDesc.setText(desc);
|
||||
_textTime.setText(time);
|
||||
_name = desc + " " + time;
|
||||
} else {
|
||||
_hasSave = false;
|
||||
setVisible(_screen->isSaveMenu());
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Stark
|
||||
182
engines/stark/ui/menu/saveloadmenu.h
Normal file
182
engines/stark/ui/menu/saveloadmenu.h
Normal file
@@ -0,0 +1,182 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STARK_UI_MENU_SAVELOAD_MENU_H
|
||||
#define STARK_UI_MENU_SAVELOAD_MENU_H
|
||||
|
||||
#include "engines/stark/ui/menu/locationscreen.h"
|
||||
#include "engines/stark/visual/text.h"
|
||||
|
||||
#include "common/error.h"
|
||||
|
||||
namespace Stark {
|
||||
|
||||
namespace Gfx {
|
||||
class Bitmap;
|
||||
class SurfaceRenderer;
|
||||
}
|
||||
|
||||
class SaveDataWidget;
|
||||
|
||||
/**
|
||||
* The base class of the save and load menu of the game
|
||||
*/
|
||||
class SaveLoadMenuScreen : public StaticLocationScreen {
|
||||
public:
|
||||
static const int _slotPerRow = 3;
|
||||
static const int _slotPerColumn = 3;
|
||||
static const int _slotPerPage = 9;
|
||||
|
||||
SaveLoadMenuScreen(Gfx::Driver *gfx, Cursor *cursor, Screen::Name screenName);
|
||||
virtual ~SaveLoadMenuScreen();
|
||||
|
||||
// StaticLocationScreen API
|
||||
void open() override;
|
||||
void close() override;
|
||||
|
||||
/** Called when a SaveDataWidget is selected */
|
||||
virtual void onWidgetSelected(SaveDataWidget *widget) = 0;
|
||||
|
||||
/** Check whether the menu is used for saving */
|
||||
virtual bool isSaveMenu() = 0;
|
||||
|
||||
protected:
|
||||
static void checkError(Common::Error error);
|
||||
|
||||
enum WidgetIndex {
|
||||
kWidgetSaveText = 3,
|
||||
kWidgetLoadText = 4,
|
||||
kWidgetBack = 5,
|
||||
kWidgetNext = 6
|
||||
};
|
||||
|
||||
private:
|
||||
// Start from zero
|
||||
int _page;
|
||||
int _maxPage;
|
||||
|
||||
void backHandler();
|
||||
|
||||
void prevPageHandler() { changePage(_page - 1); }
|
||||
void nextPageHandler() { changePage(_page + 1); }
|
||||
|
||||
void removeSaveDataWidgets();
|
||||
void loadSaveData(int page);
|
||||
void changePage(int page);
|
||||
int computeMaxPage();
|
||||
};
|
||||
|
||||
/**
|
||||
* The save menu of the game
|
||||
*/
|
||||
class SaveMenuScreen : public SaveLoadMenuScreen {
|
||||
public:
|
||||
SaveMenuScreen(Gfx::Driver *gfx, Cursor *cursor) :
|
||||
SaveLoadMenuScreen(gfx, cursor, Screen::kScreenSaveMenu),
|
||||
_slotToSaveAfterConfirm(nullptr) {}
|
||||
virtual ~SaveMenuScreen() {}
|
||||
|
||||
// SaveLoadMenuScreen API
|
||||
void open() override;
|
||||
|
||||
void onWidgetSelected(SaveDataWidget *widget) override;
|
||||
|
||||
bool isSaveMenu() override { return true; }
|
||||
|
||||
private:
|
||||
void saveGameToSlot(SaveDataWidget *widget);
|
||||
void saveConfirmSlot();
|
||||
|
||||
SaveDataWidget *_slotToSaveAfterConfirm;
|
||||
};
|
||||
|
||||
/**
|
||||
* The load menu of the game
|
||||
*/
|
||||
class LoadMenuScreen : public SaveLoadMenuScreen {
|
||||
public:
|
||||
LoadMenuScreen(Gfx::Driver *gfx, Cursor *cursor) :
|
||||
SaveLoadMenuScreen(gfx, cursor, Screen::kScreenLoadMenu),
|
||||
_slotToLoadAfterConfirm(-1) {}
|
||||
~LoadMenuScreen() override {}
|
||||
|
||||
// SaveLoadMenuScreen API
|
||||
void open() override;
|
||||
|
||||
void onWidgetSelected(SaveDataWidget *widget) override;
|
||||
|
||||
bool isSaveMenu() override { return false; }
|
||||
|
||||
private:
|
||||
void loadConfirmSlot();
|
||||
|
||||
int _slotToLoadAfterConfirm;
|
||||
};
|
||||
|
||||
/**
|
||||
* The widget of save data
|
||||
*/
|
||||
class SaveDataWidget : public StaticLocationWidget {
|
||||
public:
|
||||
SaveDataWidget(int slot, Gfx::Driver *gfx, SaveLoadMenuScreen *screen);
|
||||
~SaveDataWidget();
|
||||
|
||||
// StaticLocationWidget API
|
||||
void render() override;
|
||||
bool isMouseInside(const Common::Point &mousePos) const override;
|
||||
void onClick() override;
|
||||
void onMouseMove(const Common::Point &mousePos) override;
|
||||
void onScreenChanged() override;
|
||||
|
||||
int getSlot() { return _slot; }
|
||||
Common::String getName() { return _name; }
|
||||
|
||||
/** Load the thumbnail and info from the save data */
|
||||
void loadSaveDataElements();
|
||||
|
||||
/** Check whether the save slot has data */
|
||||
bool hasSave() { return _hasSave; }
|
||||
|
||||
private:
|
||||
const Gfx::Color _outlineColor = Gfx::Color(0x1E, 0x1E, 0x96);
|
||||
const Gfx::Color _textColor = Gfx::Color(0x5C, 0x48, 0x3D);
|
||||
|
||||
int _slot;
|
||||
SaveLoadMenuScreen *_screen;
|
||||
|
||||
Common::Point _thumbPos, _textDescPos, _textTimePos;
|
||||
int _thumbWidth, _thumbHeight;
|
||||
|
||||
Gfx::Bitmap *_bitmap;
|
||||
Gfx::Bitmap *_outline;
|
||||
Gfx::SurfaceRenderer *_surfaceRenderer;
|
||||
|
||||
VisualText _textDesc, _textTime;
|
||||
|
||||
bool _isMouseHovered;
|
||||
bool _hasSave;
|
||||
|
||||
Common::String _name;
|
||||
};
|
||||
|
||||
} // End of namespace Stark
|
||||
|
||||
#endif // STARK_UI_MENU_SETTING_MENU_H
|
||||
399
engines/stark/ui/menu/settingsmenu.cpp
Normal file
399
engines/stark/ui/menu/settingsmenu.cpp
Normal file
@@ -0,0 +1,399 @@
|
||||
/* 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 "engines/stark/ui/menu/settingsmenu.h"
|
||||
#include "engines/stark/ui/cursor.h"
|
||||
#include "engines/stark/services/services.h"
|
||||
#include "engines/stark/services/userinterface.h"
|
||||
#include "engines/stark/services/staticprovider.h"
|
||||
#include "engines/stark/visual/image.h"
|
||||
#include "engines/stark/resources/sound.h"
|
||||
|
||||
namespace Stark {
|
||||
|
||||
SettingsMenuScreen::SettingsMenuScreen(Gfx::Driver *gfx, Cursor *cursor) :
|
||||
StaticLocationScreen(gfx, cursor, "OptionLocation", Screen::kScreenSettingsMenu),
|
||||
_soundManager() {
|
||||
}
|
||||
|
||||
SettingsMenuScreen::~SettingsMenuScreen() {
|
||||
}
|
||||
|
||||
void SettingsMenuScreen::open() {
|
||||
StaticLocationScreen::open();
|
||||
|
||||
_soundManager.load();
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
// This is the background image
|
||||
"The Longest Journey",
|
||||
nullptr,
|
||||
nullptr));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Return",
|
||||
CLICK_HANDLER(SettingsMenuScreen, backHandler),
|
||||
nullptr));
|
||||
_widgets.back()->setupSounds(3, 4);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"Back",
|
||||
CLICK_HANDLER(SettingsMenuScreen, backHandler),
|
||||
nullptr));
|
||||
_widgets.back()->setupSounds(3, 4);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"GSettings",
|
||||
nullptr,
|
||||
nullptr));
|
||||
|
||||
_widgets.push_back(new CheckboxWidget(
|
||||
"AprilHighRes",
|
||||
StarkSettings->getBoolSetting(Settings::kHighModel),
|
||||
CLICK_HANDLER(SettingsMenuScreen, flipSettingHandler<Settings::kHighModel>),
|
||||
MOVE_HANDLER(SettingsMenuScreen, textHandler<kHighRes>)));
|
||||
_widgets.back()->setupSounds(3, 4);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"HighResHelp",
|
||||
nullptr,
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
|
||||
_widgets.push_back(new CheckboxWidget(
|
||||
"Subtitles",
|
||||
StarkSettings->getBoolSetting(Settings::kSubtitle),
|
||||
CLICK_HANDLER(SettingsMenuScreen, flipSettingHandler<Settings::kSubtitle>),
|
||||
MOVE_HANDLER(SettingsMenuScreen, textHandler<kSubtitles>)));
|
||||
_widgets.back()->setupSounds(3, 4);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"SubtitleHelp",
|
||||
nullptr,
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
|
||||
_widgets.push_back(new CheckboxWidget(
|
||||
"SpecialFX",
|
||||
StarkSettings->getBoolSetting(Settings::kSpecialFX),
|
||||
CLICK_HANDLER(SettingsMenuScreen, flipSettingHandler<Settings::kSpecialFX>),
|
||||
MOVE_HANDLER(SettingsMenuScreen, textHandler<kSpecialFX>)));
|
||||
_widgets.back()->setupSounds(3, 4);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"SpecialFXHelp",
|
||||
nullptr,
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
|
||||
_widgets.push_back(new CheckboxWidget(
|
||||
"Shadows",
|
||||
StarkSettings->getBoolSetting(Settings::kShadow),
|
||||
CLICK_HANDLER(SettingsMenuScreen, flipSettingHandler<Settings::kShadow>),
|
||||
MOVE_HANDLER(SettingsMenuScreen, textHandler<kShadows>)));
|
||||
_widgets.back()->setupSounds(3, 4);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"ShadowsHelp",
|
||||
nullptr,
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
|
||||
_widgets.push_back(new CheckboxWidget(
|
||||
"HighResFMV",
|
||||
StarkSettings->getBoolSetting(Settings::kHighFMV),
|
||||
CLICK_HANDLER(SettingsMenuScreen, flipSettingHandler<Settings::kHighFMV>),
|
||||
MOVE_HANDLER(SettingsMenuScreen, textHandler<kHighResFMV>)));
|
||||
_widgets.back()->setupSounds(3, 4);
|
||||
_widgets.back()->setVisible(StarkSettings->hasLowResFMV());
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"FMVHelp",
|
||||
nullptr,
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"VSettings",
|
||||
nullptr,
|
||||
nullptr));
|
||||
|
||||
_widgets.push_back(new VolumeWidget(
|
||||
"Voice",
|
||||
_cursor,
|
||||
_soundManager, 0,
|
||||
Settings::kVoice,
|
||||
MOVE_HANDLER(SettingsMenuScreen, textHandler<kVoice>)));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"VoiceHelp",
|
||||
nullptr,
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
|
||||
_widgets.push_back(new VolumeWidget(
|
||||
"Music",
|
||||
_cursor,
|
||||
_soundManager, 2,
|
||||
Settings::kMusic,
|
||||
MOVE_HANDLER(SettingsMenuScreen, textHandler<kMusic>)));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"MusicHelp",
|
||||
nullptr,
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
|
||||
_widgets.push_back(new VolumeWidget(
|
||||
"Sfx",
|
||||
_cursor,
|
||||
_soundManager, 1,
|
||||
Settings::kSfx,
|
||||
MOVE_HANDLER(SettingsMenuScreen, textHandler<kSfx>)));
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"SfxHelp",
|
||||
nullptr,
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
|
||||
_widgets.push_back(new CheckboxWidget(
|
||||
"AllowFF",
|
||||
StarkSettings->getBoolSetting(Settings::kTimeSkip),
|
||||
CLICK_HANDLER(SettingsMenuScreen, flipSettingHandler<Settings::kTimeSkip>),
|
||||
MOVE_HANDLER(SettingsMenuScreen, textHandler<kAllowFF>)));
|
||||
_widgets.back()->setupSounds(3, 4);
|
||||
|
||||
_widgets.push_back(new StaticLocationWidget(
|
||||
"AllowFFHelp",
|
||||
nullptr,
|
||||
nullptr));
|
||||
_widgets.back()->setVisible(false);
|
||||
}
|
||||
|
||||
void SettingsMenuScreen::close() {
|
||||
_soundManager.close();
|
||||
ConfMan.flushToDisk();
|
||||
StaticLocationScreen::close();
|
||||
}
|
||||
|
||||
void SettingsMenuScreen::onGameLoop() {
|
||||
_soundManager.update();
|
||||
}
|
||||
|
||||
void SettingsMenuScreen::handleMouseUp() {
|
||||
if (!_widgets.empty()) {
|
||||
_soundManager.endLoop();
|
||||
_widgets[kWidgetVoice]->onMouseUp();
|
||||
_widgets[kWidgetMusic]->onMouseUp();
|
||||
_widgets[kWidgetSfx]->onMouseUp();
|
||||
}
|
||||
}
|
||||
|
||||
template<SettingsMenuScreen::HelpTextIndex N>
|
||||
void SettingsMenuScreen::textHandler(StaticLocationWidget &widget, const Common::Point &mousePos) {
|
||||
if (widget.isVisible()) {
|
||||
if (widget.isMouseInside(mousePos)) {
|
||||
widget.setTextColor(_textColorHovered);
|
||||
_widgets[N]->setVisible(true);
|
||||
} else {
|
||||
widget.setTextColor(_textColorDefault);
|
||||
_widgets[N]->setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<Settings::BoolSettingIndex N>
|
||||
void SettingsMenuScreen::flipSettingHandler() {
|
||||
StarkSettings->flipSetting(N);
|
||||
}
|
||||
|
||||
void SettingsMenuScreen::backHandler() {
|
||||
StarkUserInterface->backPrevScreen();
|
||||
}
|
||||
|
||||
CheckboxWidget::CheckboxWidget(const char *renderEntryName, bool isChecked,
|
||||
WidgetOnClickCallback *onClickCallback,
|
||||
WidgetOnMouseMoveCallback *onMouseMoveCallback) :
|
||||
StaticLocationWidget(renderEntryName, onClickCallback, onMouseMoveCallback),
|
||||
_isChecked(isChecked) {
|
||||
// Load images
|
||||
_checkBoxImage[0] = StarkStaticProvider->getUIElement(StaticProvider::kCheckMark, 0);
|
||||
_checkBoxImage[1] = StarkStaticProvider->getUIElement(StaticProvider::kCheckMark, 1);
|
||||
_checkboxWidth = _checkBoxImage[0]->getWidth();
|
||||
_checkboxHeight = _checkBoxImage[0]->getHeight();
|
||||
_currentImage = _checkBoxImage[_isChecked];
|
||||
|
||||
// Set positions
|
||||
Common::Point textPosition = getPosition();
|
||||
_position.x = textPosition.x - _checkboxWidth - 8;
|
||||
_position.y = textPosition.y - 4;
|
||||
}
|
||||
|
||||
void CheckboxWidget::render() {
|
||||
StaticLocationWidget::render();
|
||||
_currentImage->render(_position, true);
|
||||
}
|
||||
|
||||
bool CheckboxWidget::isMouseInside(const Common::Point &mousePos) const {
|
||||
return StaticLocationWidget::isMouseInside(mousePos) || isMouseInsideCheckbox(mousePos);
|
||||
}
|
||||
|
||||
void CheckboxWidget::onClick() {
|
||||
StaticLocationWidget::onClick();
|
||||
_isChecked = !_isChecked;
|
||||
_currentImage = _checkBoxImage[_isChecked];
|
||||
}
|
||||
|
||||
bool CheckboxWidget::isMouseInsideCheckbox(const Common::Point &mousePos) const {
|
||||
return mousePos.x >= _position.x && mousePos.x <= _position.x + _checkboxWidth &&
|
||||
mousePos.y >= _position.y && mousePos.y <= _position.y + _checkboxHeight;
|
||||
}
|
||||
|
||||
VolumeWidget::VolumeWidget(const char *renderEntryName, Cursor *cursor,
|
||||
TestSoundManager &soundManager, int soundIndex,
|
||||
Settings::IntSettingIndex settingIndex,
|
||||
WidgetOnMouseMoveCallback *onMouseMoveCallback) :
|
||||
StaticLocationWidget(renderEntryName, nullptr, onMouseMoveCallback),
|
||||
_cursor(cursor),
|
||||
_soundManager(soundManager),
|
||||
_soundIndex(soundIndex),
|
||||
_settingIndex(settingIndex),
|
||||
_isDragged(false) {
|
||||
// Load images
|
||||
_sliderImage = StarkStaticProvider->getUIElement(StaticProvider::kVolume, 0);
|
||||
_bgImage = StarkStaticProvider->getUIElement(StaticProvider::kVolume, 1);
|
||||
_bgWidth = _bgImage->getWidth();
|
||||
_bgHeight = _bgImage->getHeight();
|
||||
_sliderWidth = _sliderImage->getWidth();
|
||||
|
||||
// Set positions
|
||||
_bgPosition.x = 313;
|
||||
_bgPosition.y = 303 + _settingIndex * 51;
|
||||
_sliderPosition.y = _bgPosition.y;
|
||||
|
||||
_minX = _bgPosition.x;
|
||||
_maxX = _bgPosition.x + _bgWidth - _sliderWidth;
|
||||
}
|
||||
|
||||
void VolumeWidget::render() {
|
||||
StaticLocationWidget::render();
|
||||
|
||||
_sliderPosition.x = volumeToX(StarkSettings->getIntSetting(_settingIndex));
|
||||
|
||||
_sliderImage->render(_sliderPosition, false);
|
||||
_bgImage->render(_bgPosition, false);
|
||||
}
|
||||
|
||||
bool VolumeWidget::isMouseInside(const Common::Point &mousePos) const {
|
||||
return StaticLocationWidget::isMouseInside(mousePos) || isMouseInsideBg(mousePos);
|
||||
}
|
||||
|
||||
void VolumeWidget::onClick() {
|
||||
if (isMouseInsideBg(_cursor->getMousePosition())) {
|
||||
_isDragged = true;
|
||||
_soundManager.play(_soundIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void VolumeWidget::onMouseMove(const Common::Point &mousePos) {
|
||||
if (isMouseInsideBg(mousePos)) {
|
||||
setTextColor(_textColorBgHovered);
|
||||
} else {
|
||||
StaticLocationWidget::onMouseMove(mousePos);
|
||||
}
|
||||
|
||||
if (_isDragged) {
|
||||
int posX = mousePos.x - _sliderWidth / 2;
|
||||
if (posX < _minX) {
|
||||
posX = _minX;
|
||||
}
|
||||
if (posX > _maxX) {
|
||||
posX = _maxX;
|
||||
}
|
||||
StarkSettings->setIntSetting(_settingIndex, xToVolume(posX));
|
||||
}
|
||||
}
|
||||
|
||||
void VolumeWidget::onMouseUp() {
|
||||
_isDragged = false;
|
||||
}
|
||||
|
||||
bool VolumeWidget::isMouseInsideBg(const Common::Point &mousePos) const {
|
||||
return mousePos.x >= _bgPosition.x && mousePos.x <= _bgPosition.x + _bgWidth &&
|
||||
mousePos.y >= _bgPosition.y && mousePos.y <= _bgPosition.y + _bgHeight;
|
||||
}
|
||||
|
||||
TestSoundManager::TestSoundManager() :
|
||||
_currentSound(nullptr),
|
||||
_isLopping(false) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
_sounds[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void TestSoundManager::load() {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
_sounds[i] = StarkStaticProvider->getLocationSound(i);
|
||||
_sounds[i]->setLooping(false);
|
||||
}
|
||||
}
|
||||
|
||||
void TestSoundManager::close() {
|
||||
stop();
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
_sounds[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void TestSoundManager::play(int index) {
|
||||
stop();
|
||||
_currentSound = _sounds[index];
|
||||
if (_currentSound) {
|
||||
_currentSound->play();
|
||||
_isLopping = true;
|
||||
}
|
||||
}
|
||||
|
||||
void TestSoundManager::endLoop() {
|
||||
_isLopping = false;
|
||||
}
|
||||
|
||||
void TestSoundManager::stop() {
|
||||
if (_currentSound) {
|
||||
_currentSound->stop();
|
||||
_currentSound = nullptr;
|
||||
}
|
||||
_isLopping = false;
|
||||
}
|
||||
|
||||
void TestSoundManager::update() {
|
||||
if (_currentSound && !_currentSound->isPlaying()) {
|
||||
if (_isLopping) {
|
||||
_currentSound->play();
|
||||
} else {
|
||||
_currentSound->stop();
|
||||
_currentSound = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Stark
|
||||
188
engines/stark/ui/menu/settingsmenu.h
Normal file
188
engines/stark/ui/menu/settingsmenu.h
Normal file
@@ -0,0 +1,188 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef STARK_UI_MENU_SETTINGS_MENU_H
|
||||
#define STARK_UI_MENU_SETTINGS_MENU_H
|
||||
|
||||
#include "engines/stark/ui/menu/locationscreen.h"
|
||||
#include "engines/stark/services/services.h"
|
||||
#include "engines/stark/services/settings.h"
|
||||
|
||||
namespace Stark {
|
||||
|
||||
class VisualImageXMG;
|
||||
|
||||
/**
|
||||
* Manager of test sound
|
||||
*/
|
||||
class TestSoundManager {
|
||||
public:
|
||||
TestSoundManager();
|
||||
~TestSoundManager() {}
|
||||
|
||||
/** Load sounds **/
|
||||
void load();
|
||||
|
||||
/** Close the sound manager and reset pointers **/
|
||||
void close();
|
||||
|
||||
/** play a specific sound in a loop */
|
||||
void play(int index);
|
||||
|
||||
/** request to end the playing loop */
|
||||
void endLoop();
|
||||
|
||||
/** stop any currently playing sound */
|
||||
void stop();
|
||||
|
||||
/** update on game frame */
|
||||
void update();
|
||||
|
||||
private:
|
||||
Resources::Sound *_currentSound;
|
||||
Resources::Sound *_sounds[3];
|
||||
bool _isLopping;
|
||||
};
|
||||
|
||||
/**
|
||||
* The setting menu of the game
|
||||
*/
|
||||
class SettingsMenuScreen : public StaticLocationScreen {
|
||||
public:
|
||||
SettingsMenuScreen(Gfx::Driver *gfx, Cursor *cursor);
|
||||
virtual ~SettingsMenuScreen();
|
||||
|
||||
// StaticLocationScreen API
|
||||
void open() override;
|
||||
void close() override;
|
||||
void onGameLoop() override;
|
||||
|
||||
void handleMouseUp();
|
||||
|
||||
private:
|
||||
enum HelpTextIndex {
|
||||
kHighRes = 5,
|
||||
kSubtitles = 7,
|
||||
kSpecialFX = 9,
|
||||
kShadows = 11,
|
||||
kHighResFMV = 13,
|
||||
kVoice = 16,
|
||||
kMusic = 18,
|
||||
kSfx = 20,
|
||||
kAllowFF = 22
|
||||
};
|
||||
|
||||
enum WidgetIndex {
|
||||
kWidgetVoice = 15,
|
||||
kWidgetMusic = 17,
|
||||
kWidgetSfx = 19
|
||||
};
|
||||
|
||||
template<HelpTextIndex N>
|
||||
void textHandler(StaticLocationWidget &widget, const Common::Point &mousePos);
|
||||
|
||||
template<Settings::BoolSettingIndex N>
|
||||
void flipSettingHandler();
|
||||
|
||||
void backHandler();
|
||||
|
||||
private:
|
||||
const Gfx::Color _textColorHovered = Gfx::Color(0x1E, 0x1E, 0x96);
|
||||
const Gfx::Color _textColorDefault = Gfx::Color(0x00, 0x00, 0x00);
|
||||
|
||||
TestSoundManager _soundManager;
|
||||
};
|
||||
|
||||
/**
|
||||
* Widget with a checkbox
|
||||
*/
|
||||
class CheckboxWidget : public StaticLocationWidget {
|
||||
public:
|
||||
CheckboxWidget(const char *renderEntryName, bool isChecked,
|
||||
WidgetOnClickCallback *onClickCallback,
|
||||
WidgetOnMouseMoveCallback *onMouseMoveCallback);
|
||||
virtual ~CheckboxWidget() {};
|
||||
|
||||
// StaticLocationWidget API
|
||||
void render() override;
|
||||
bool isMouseInside(const Common::Point &mousePos) const override;
|
||||
void onClick() override;
|
||||
|
||||
private:
|
||||
VisualImageXMG *_currentImage;
|
||||
VisualImageXMG *_checkBoxImage[2];
|
||||
Common::Point _position;
|
||||
int _checkboxWidth, _checkboxHeight;
|
||||
bool _isChecked;
|
||||
|
||||
bool isMouseInsideCheckbox(const Common::Point &mousePos) const;
|
||||
};
|
||||
|
||||
/**
|
||||
* Widget with a dragged slider for twisting the volume
|
||||
*/
|
||||
class VolumeWidget : public StaticLocationWidget {
|
||||
public:
|
||||
VolumeWidget(const char *renderEntryName, Cursor *cursor,
|
||||
TestSoundManager &soundManager, int soundIndex,
|
||||
Settings::IntSettingIndex settingIndex,
|
||||
WidgetOnMouseMoveCallback *onMouseMoveCallback);
|
||||
virtual ~VolumeWidget() {};
|
||||
|
||||
// StaticLocationWidget API
|
||||
void render() override;
|
||||
bool isMouseInside(const Common::Point &mousePos) const override;
|
||||
void onClick() override;
|
||||
void onMouseMove(const Common::Point &mousePos) override;
|
||||
void onMouseUp() override;
|
||||
|
||||
private:
|
||||
const Gfx::Color _textColorBgHovered = Gfx::Color(0xFF, 0xFF, 0xFF);
|
||||
static const int _maxVolume = 256;
|
||||
|
||||
VisualImageXMG *_sliderImage;
|
||||
VisualImageXMG *_bgImage;
|
||||
|
||||
Cursor *_cursor;
|
||||
|
||||
TestSoundManager &_soundManager;
|
||||
const int _soundIndex;
|
||||
|
||||
Common::Point _sliderPosition, _bgPosition;
|
||||
int _bgWidth, _bgHeight, _sliderWidth, _minX, _maxX;
|
||||
|
||||
bool _isDragged;
|
||||
const Settings::IntSettingIndex _settingIndex;
|
||||
|
||||
bool isMouseInsideBg(const Common::Point &mousePos) const;
|
||||
|
||||
int volumeToX(int volume) {
|
||||
return volume * (_maxX - _minX) / _maxVolume + _minX;
|
||||
}
|
||||
|
||||
int xToVolume(int x) {
|
||||
return (x - _minX) * _maxVolume / (_maxX - _minX);
|
||||
}
|
||||
};
|
||||
|
||||
} // End of namespace Stark
|
||||
|
||||
#endif // STARK_UI_MENU_SETTING_MENU_H
|
||||
Reference in New Issue
Block a user