mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-10 03:40:25 +00:00
NANCY: Initial main menu implementation
Implemented the original engine's main menu and added an option to enable it from the custom options dialog. Several buttons in the main menu don't work yet since they require implementing additional game states.
This commit is contained in:
parent
9f35d133ca
commit
68e54edd50
@ -32,18 +32,22 @@ NancyOptionsWidget::NancyOptionsWidget(GuiObject *boss, const Common::String &na
|
||||
OptionsContainerWidget(boss, name, "NancyOptionsDialog", false, domain) {
|
||||
_playerSpeechCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "NancyOptionsDialog.PlayerSpeech", _("Player Speech"), _("Enable player speech. Only works if speech is enabled in the Audio settings."));
|
||||
_characterSpeechCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "NancyOptionsDialog.CharacterSpeech", _("Character Speech"), _("Enable NPC speech. Only works if speech is enabled in the Audio settings."));
|
||||
_originalMenusCheckbox = new GUI::CheckboxWidget(widgetsBoss(), "NancyOptionsDialog.OriginalMenus", _("Use original menus"), _("Use the original engine's main, save/load, and setup menus. ScummVM's Global Main Menu can still be accessed through its keymap."));
|
||||
|
||||
new GUI::StaticTextWidget(widgetsBoss(), "NancyOptionsDialog.SpeechSettingsLabel", _("Speech Options"));
|
||||
new GUI::StaticTextWidget(widgetsBoss(), "NancyOptionsDialog.EngineSettingsLabel", _("Engine Options"));
|
||||
}
|
||||
|
||||
void NancyOptionsWidget::load() {
|
||||
_playerSpeechCheckbox->setState(ConfMan.getBool("player_speech", _domain));
|
||||
_characterSpeechCheckbox->setState(ConfMan.getBool("character_speech", _domain));
|
||||
_originalMenusCheckbox->setState(ConfMan.getBool("original_menus", _domain));
|
||||
}
|
||||
|
||||
bool NancyOptionsWidget::save() {
|
||||
ConfMan.setBool("player_speech", _playerSpeechCheckbox->getState(), _domain);
|
||||
ConfMan.setBool("character_speech", _characterSpeechCheckbox->getState(), _domain);
|
||||
ConfMan.setBool("original_menus", _characterSpeechCheckbox->getState(), _domain);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -55,6 +59,9 @@ void NancyOptionsWidget::defineLayout(GUI::ThemeEval &layouts, const Common::Str
|
||||
.addWidget("SpeechSettingsLabel", "OptionsLabel")
|
||||
.addWidget("PlayerSpeech", "Checkbox")
|
||||
.addWidget("CharacterSpeech", "Checkbox")
|
||||
.addSpace(16)
|
||||
.addWidget("EngineSettingsLabel", "OptionsLabel")
|
||||
.addWidget("OriginalMenus", "Checkbox")
|
||||
.closeLayout()
|
||||
.closeDialog();
|
||||
}
|
||||
|
@ -42,6 +42,7 @@ private:
|
||||
|
||||
GUI::CheckboxWidget *_playerSpeechCheckbox;
|
||||
GUI::CheckboxWidget *_characterSpeechCheckbox;
|
||||
GUI::CheckboxWidget *_originalMenusCheckbox;
|
||||
};
|
||||
|
||||
} // End of namespace Nancy
|
||||
|
@ -24,6 +24,7 @@ MODULE_OBJS = \
|
||||
state/credits.o \
|
||||
state/logo.o \
|
||||
state/help.o \
|
||||
state/mainmenu.o \
|
||||
state/map.o \
|
||||
state/scene.o \
|
||||
cheat.o \
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "engines/nancy/state/help.h"
|
||||
#include "engines/nancy/state/map.h"
|
||||
#include "engines/nancy/state/credits.h"
|
||||
#include "engines/nancy/state/mainmenu.h"
|
||||
|
||||
namespace Nancy {
|
||||
|
||||
@ -153,6 +154,11 @@ void NancyEngine::setState(NancyState::NancyState state, NancyState::NancyState
|
||||
setState(NancyState::kLogo);
|
||||
return;
|
||||
case NancyState::kMainMenu: {
|
||||
if (ConfMan.getBool("original_menus")) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Do not use the original engine's menus, call the GMM instead
|
||||
State::State *s = getStateObject(_gameFlow.curState);
|
||||
if (s) {
|
||||
s->onStateExit();
|
||||
@ -286,6 +292,7 @@ void NancyEngine::bootGameEngine() {
|
||||
// Register default settings
|
||||
ConfMan.registerDefault("player_speech", true);
|
||||
ConfMan.registerDefault("character_speech", true);
|
||||
ConfMan.registerDefault("original_menus", false);
|
||||
|
||||
// Load archive
|
||||
Common::SeekableReadStream *stream = SearchMan.createReadStreamForMember("data1.cab");
|
||||
@ -349,6 +356,8 @@ State::State *NancyEngine::getStateObject(NancyState::NancyState state) const {
|
||||
return &State::Help::instance();
|
||||
case NancyState::kScene:
|
||||
return &State::Scene::instance();
|
||||
case NancyState::kMainMenu:
|
||||
return &State::MainMenu::instance();
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -67,6 +67,7 @@ public:
|
||||
Common::Rect convertToScreen(const Common::Rect &rect) const;
|
||||
|
||||
Common::Rect getBounds() const { return Common::Rect(_drawSurface.w, _drawSurface.h); }
|
||||
Graphics::ManagedSurface &getDrawSurface() { return _drawSurface; }
|
||||
|
||||
protected:
|
||||
// Z order and blit type are extracted directly from the corresponding
|
||||
|
@ -20,6 +20,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/config-manager.h"
|
||||
|
||||
#include "engines/nancy/nancy.h"
|
||||
#include "engines/nancy/sound.h"
|
||||
#include "engines/nancy/input.h"
|
||||
@ -80,7 +82,12 @@ void Logo::stop() {
|
||||
// The original engine checks for N+D and N+C key combos here.
|
||||
// For the N+C key combo it looks for some kind of cheat file
|
||||
// to initialize the game state with.
|
||||
g_nancy->setState(NancyState::kScene);
|
||||
|
||||
if (ConfMan.getBool("original_menus")) {
|
||||
g_nancy->setState(NancyState::kMainMenu);
|
||||
} else {
|
||||
g_nancy->setState(NancyState::kScene);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace State
|
||||
|
178
engines/nancy/state/mainmenu.cpp
Normal file
178
engines/nancy/state/mainmenu.cpp
Normal file
@ -0,0 +1,178 @@
|
||||
/* 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 2
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "engines/nancy/nancy.h"
|
||||
#include "engines/nancy/cursor.h"
|
||||
#include "engines/nancy/sound.h"
|
||||
#include "engines/nancy/input.h"
|
||||
#include "engines/nancy/util.h"
|
||||
|
||||
#include "engines/nancy/state/mainmenu.h"
|
||||
#include "engines/nancy/state/scene.h"
|
||||
|
||||
namespace Common {
|
||||
DECLARE_SINGLETON(Nancy::State::MainMenu);
|
||||
}
|
||||
|
||||
namespace Nancy {
|
||||
namespace State {
|
||||
|
||||
void MainMenu::process() {
|
||||
switch (_state) {
|
||||
case kInit:
|
||||
init();
|
||||
// fall through
|
||||
case kRun:
|
||||
run();
|
||||
break;
|
||||
case kStop:
|
||||
stop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MainMenu::onStateExit() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void MainMenu::init() {
|
||||
Common::SeekableReadStream *chunk = g_nancy->getBootChunkStream("MENU");
|
||||
chunk->seek(0);
|
||||
|
||||
Common::String imageName;
|
||||
readFilename(*chunk, imageName);
|
||||
|
||||
_background.init(imageName);
|
||||
_background.registerGraphics();
|
||||
|
||||
g_nancy->_cursorManager->setCursorType(CursorManager::kNormalArrow);
|
||||
g_nancy->_cursorManager->showCursor(true);
|
||||
|
||||
if (!g_nancy->_sound->isSoundPlaying("MSND")) {
|
||||
g_nancy->_sound->playSound("MSND");
|
||||
}
|
||||
|
||||
chunk->seek(0x20);
|
||||
|
||||
// Unlike every other rect in the engine, these use int16 instead of int32
|
||||
for (uint i = 0; i < 8; ++i) {
|
||||
_destRects.push_back(Common::Rect());
|
||||
Common::Rect &rect = _destRects.back();
|
||||
rect.left = chunk->readSint16LE();
|
||||
rect.top = chunk->readSint16LE();
|
||||
rect.right = chunk->readSint16LE();
|
||||
rect.bottom = chunk->readSint16LE();
|
||||
}
|
||||
|
||||
for (uint i = 0; i < 8; ++i) {
|
||||
_srcRects.push_back(Common::Rect());
|
||||
Common::Rect &rect = _srcRects.back();
|
||||
rect.left = chunk->readSint16LE();
|
||||
rect.top = chunk->readSint16LE();
|
||||
rect.right = chunk->readSint16LE();
|
||||
rect.bottom = chunk->readSint16LE();
|
||||
}
|
||||
|
||||
_buttonDown.registerGraphics();
|
||||
_buttonDown._redrawFrom = &_background;
|
||||
|
||||
_state = kRun;
|
||||
}
|
||||
|
||||
void MainMenu::run() {
|
||||
NancyInput input = g_nancy->_input->getInput();
|
||||
|
||||
_buttonDown.setVisible(false);
|
||||
|
||||
if (input.input & NancyInput::kLeftMouseButtonUp) {
|
||||
for (uint i = 0; i < 8; ++i) {
|
||||
if (_destRects[i].contains(input.mousePos)) {
|
||||
if (i == 3 && !Scene::hasInstance()) {
|
||||
g_nancy->_sound->playSound("BUDE");
|
||||
_playedOKSound = false;
|
||||
} else {
|
||||
g_nancy->_sound->playSound("BUOK");
|
||||
_playedOKSound = true;
|
||||
}
|
||||
|
||||
_selected = i;
|
||||
_state = kStop;
|
||||
|
||||
_buttonDown._drawSurface.create(_background.getDrawSurface(), _srcRects[i]);
|
||||
_buttonDown._screenPosition = _destRects[i];
|
||||
_buttonDown.setVisible(true);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MainMenu::stop() {
|
||||
if (!g_nancy->_sound->isSoundPlaying(_playedOKSound ? "BUOK" : "BUDE")) {
|
||||
switch (_selected) {
|
||||
case 0:
|
||||
// Credits
|
||||
g_nancy->setState(NancyState::kCredits);
|
||||
break;
|
||||
case 1:
|
||||
// New Game
|
||||
if (Scene::hasInstance()) {
|
||||
NancySceneState.destroy(); // Simply destroy the existing Scene and create a new one
|
||||
}
|
||||
|
||||
g_nancy->setState(NancyState::kScene);
|
||||
break;
|
||||
case 2:
|
||||
// Load and Save Game, TODO
|
||||
_state = kRun;
|
||||
break;
|
||||
case 3:
|
||||
// Continue
|
||||
if (Scene::hasInstance()) {
|
||||
g_nancy->setState(NancyState::kScene);
|
||||
} else {
|
||||
_state = kRun;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
// Second Chance, TODO
|
||||
_state = kRun;
|
||||
break;
|
||||
case 5:
|
||||
// Game Setup, TODO
|
||||
_state = kRun;
|
||||
break;
|
||||
case 6:
|
||||
// Exit Game
|
||||
g_nancy->quitGame(); // Consider returning to launcher instead?
|
||||
break;
|
||||
case 7:
|
||||
// Help
|
||||
g_nancy->setState(NancyState::kHelp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace State
|
||||
} // End of namespace Nancy
|
75
engines/nancy/state/mainmenu.h
Normal file
75
engines/nancy/state/mainmenu.h
Normal file
@ -0,0 +1,75 @@
|
||||
/* 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 2
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef NANCY_STATE_MAINMENU_H
|
||||
#define NANCY_STATE_MAINMENU_H
|
||||
|
||||
#include "common/singleton.h"
|
||||
|
||||
#include "engines/nancy/state/state.h"
|
||||
|
||||
#include "engines/nancy/ui/fullscreenimage.h"
|
||||
|
||||
namespace Nancy {
|
||||
namespace State {
|
||||
|
||||
class MainMenu : public State, public Common::Singleton<MainMenu> {
|
||||
friend class MainMenuButton;
|
||||
public:
|
||||
MainMenu() : _state(kInit), _selected(-1), _playedOKSound(false) {}
|
||||
|
||||
// State API
|
||||
virtual void process() override;
|
||||
virtual void onStateExit() override;
|
||||
|
||||
private:
|
||||
// This is not a UI::Button subclass since the cursor doesn't change on hover
|
||||
class ButtonDownLabel : public RenderObject {
|
||||
friend class MainMenu;
|
||||
public:
|
||||
ButtonDownLabel() {}
|
||||
virtual ~ButtonDownLabel() override {}
|
||||
|
||||
protected:
|
||||
virtual uint16 getZOrder() const override { return 5; }
|
||||
};
|
||||
|
||||
void init();
|
||||
void run();
|
||||
void stop();
|
||||
|
||||
enum State { kInit, kRun, kStop };
|
||||
|
||||
UI::FullScreenImage _background;
|
||||
ButtonDownLabel _buttonDown;
|
||||
State _state;
|
||||
int16 _selected;
|
||||
bool _playedOKSound;
|
||||
|
||||
Common::Array<Common::Rect> _destRects;
|
||||
Common::Array<Common::Rect> _srcRects;
|
||||
};
|
||||
|
||||
} // End of namespace State
|
||||
} // End of namespace Nancy
|
||||
|
||||
#endif // NANCY_STATE_MAINMENU_H
|
Loading…
Reference in New Issue
Block a user