aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sword2/anims.cpp3
-rw-r--r--sword2/controls.cpp1226
-rw-r--r--sword2/controls.h149
-rw-r--r--sword2/defs.h15
-rw-r--r--sword2/function.cpp5
-rw-r--r--sword2/mouse.cpp27
-rw-r--r--sword2/mouse.h5
-rw-r--r--sword2/save_rest.cpp47
-rw-r--r--sword2/speech.cpp1
-rw-r--r--sword2/sword2.cpp125
-rw-r--r--sword2/sword2.h11
11 files changed, 832 insertions, 782 deletions
diff --git a/sword2/anims.cpp b/sword2/anims.cpp
index f8db3c57eb..7f4a78b152 100644
--- a/sword2/anims.cpp
+++ b/sword2/anims.cpp
@@ -30,7 +30,6 @@
#include "sword2/sword2.h"
#include "sword2/defs.h"
#include "sword2/build_display.h"
-#include "sword2/controls.h"
#include "sword2/interpreter.h"
#include "sword2/logic.h"
#include "sword2/maketext.h"
@@ -246,7 +245,7 @@ void Logic::createSequenceSpeech(MovieTextObject *sequenceText[]) {
// if we want subtitles, or speech failed to load
- if (_vm->_gui->_subtitles || !speechRunning) {
+ if (_vm->getSubtitles() || !speechRunning) {
// open text resource & get the line
text = _vm->fetchTextLine(_vm->_resman->openResource(text_res), local_text);
// make the sprite
diff --git a/sword2/controls.cpp b/sword2/controls.cpp
index 5ff77f8008..ece196e6c8 100644
--- a/sword2/controls.cpp
+++ b/sword2/controls.cpp
@@ -24,52 +24,23 @@
#include "common/system.h"
#include "sword2/sword2.h"
-#include "sword2/controls.h"
#include "sword2/defs.h"
-#include "sword2/logic.h"
+#include "sword2/controls.h"
#include "sword2/mouse.h"
#include "sword2/resman.h"
-#include "sword2/router.h"
#include "sword2/sound.h"
-#define MAX_STRING_LEN 64 // 20 was too low; better to be safe ;)
-#define CHARACTER_OVERLAP 2 // overlap characters by 3 pixels
+#define MAX_STRING_LEN 64 // 20 was too low; better to be safe ;)
+#define CHARACTER_OVERLAP 2 // overlap characters by 3 pixels
// our fonts start on SPACE character (32)
-#define SIZE_OF_CHAR_SET (256 - 32)
-
-#define MAX_WIDGETS 25
+#define SIZE_OF_CHAR_SET (256 - 32)
namespace Sword2 {
-class Widget;
-
-/**
- * Base class for all dialogs.
- */
-
-class Dialog {
-private:
- int _numWidgets;
- Widget *_widgets[MAX_WIDGETS];
- bool _finish;
- int _result;
-
-public:
- Gui *_gui;
-
- Dialog(Gui *gui);
- virtual ~Dialog();
-
- void registerWidget(Widget *widget);
-
- virtual void paint();
- virtual void setResult(int result);
-
- int run();
+static int baseSlot = 0;
- virtual void onAction(Widget *widget, int result = 0) {}
-};
+class Widget;
/**
* Base class for all widgets.
@@ -77,6 +48,7 @@ public:
class Widget {
protected:
+ Sword2Engine *_vm;
Dialog *_parent;
SpriteInfo *_sprites;
@@ -130,7 +102,7 @@ public:
class FontRendererGui {
private:
- Gui *_gui;
+ Sword2Engine *_vm;
struct Glyph {
byte *_data;
@@ -149,7 +121,7 @@ public:
kAlignCenter
};
- FontRendererGui(Gui *gui, int fontId);
+ FontRendererGui(Sword2Engine *vm, int fontId);
~FontRendererGui();
void fetchText(uint32 textId, byte *buf);
@@ -164,34 +136,34 @@ public:
void drawText(uint32 textId, int x, int y, int alignment = kAlignLeft);
};
-FontRendererGui::FontRendererGui(Gui *gui, int fontId)
- : _gui(gui), _fontId(fontId) {
- byte *font = _gui->_vm->_resman->openResource(fontId);
+FontRendererGui::FontRendererGui(Sword2Engine *vm, int fontId)
+ : _vm(vm), _fontId(fontId) {
+ byte *font = _vm->_resman->openResource(fontId);
FrameHeader *head;
SpriteInfo sprite;
sprite.type = RDSPR_NOCOMPRESSION | RDSPR_TRANS;
for (int i = 0; i < SIZE_OF_CHAR_SET; i++) {
- head = (FrameHeader *) _gui->_vm->fetchFrameHeader(font, i);
+ head = (FrameHeader *) _vm->fetchFrameHeader(font, i);
sprite.data = (byte *) (head + 1);
sprite.w = head->width;
sprite.h = head->height;
- _gui->_vm->_screen->createSurface(&sprite, &_glyph[i]._data);
+ _vm->_screen->createSurface(&sprite, &_glyph[i]._data);
_glyph[i]._width = head->width;
_glyph[i]._height = head->height;
}
- _gui->_vm->_resman->closeResource(fontId);
+ _vm->_resman->closeResource(fontId);
}
FontRendererGui::~FontRendererGui() {
for (int i = 0; i < SIZE_OF_CHAR_SET; i++)
- _gui->_vm->_screen->deleteSurface(_glyph[i]._data);
+ _vm->_screen->deleteSurface(_glyph[i]._data);
}
void FontRendererGui::fetchText(uint32 textId, byte *buf) {
- byte *data = _gui->_vm->fetchTextLine(_gui->_vm->_resman->openResource(textId / SIZE), textId & 0xffff);
+ byte *data = _vm->fetchTextLine(_vm->_resman->openResource(textId / SIZE), textId & 0xffff);
int i;
for (i = 0; data[i + 2]; i++) {
@@ -200,7 +172,7 @@ void FontRendererGui::fetchText(uint32 textId, byte *buf) {
}
buf[i] = 0;
- _gui->_vm->_resman->closeResource(textId / SIZE);
+ _vm->_resman->closeResource(textId / SIZE);
}
int FontRendererGui::getCharWidth(byte c) {
@@ -256,7 +228,7 @@ void FontRendererGui::drawText(byte *text, int x, int y, int alignment) {
sprite.w = getCharWidth(text[i]);
sprite.h = getCharHeight(text[i]);
- _gui->_vm->_screen->drawSurface(&sprite, _glyph[text[i] - 32]._data);
+ _vm->_screen->drawSurface(&sprite, _glyph[text[i] - 32]._data);
sprite.x += (getCharWidth(text[i]) - CHARACTER_OVERLAP);
}
@@ -274,16 +246,16 @@ void FontRendererGui::drawText(uint32 textId, int x, int y, int alignment) {
// Dialog class functions
//
-Dialog::Dialog(Gui *gui)
- : _numWidgets(0), _finish(false), _result(0), _gui(gui) {
- _gui->_vm->_screen->setFullPalette(CONTROL_PANEL_PALETTE);
- _gui->_vm->_screen->clearScene();
+Dialog::Dialog(Sword2Engine *vm)
+ : _numWidgets(0), _finish(false), _result(0), _vm(vm) {
+ _vm->_screen->setFullPalette(CONTROL_PANEL_PALETTE);
+ _vm->_screen->clearScene();
// HACK: Since the dialogs don't do normal scene updates we need to
// trigger a full redraw manually.
- _gui->_vm->_screen->setNeedFullRedraw();
- _gui->_vm->_screen->updateDisplay();
+ _vm->_screen->setNeedFullRedraw();
+ _vm->_screen->updateDisplay();
}
Dialog::~Dialog() {
@@ -297,7 +269,7 @@ void Dialog::registerWidget(Widget *widget) {
}
void Dialog::paint() {
- _gui->_vm->_screen->clearScene();
+ _vm->_screen->clearScene();
for (int i = 0; i < _numWidgets; i++)
_widgets[i]->paint();
}
@@ -307,8 +279,8 @@ void Dialog::setResult(int result) {
_finish = true;
}
-int Dialog::run() {
- uint32 oldFilter = _gui->_vm->setEventFilter(0);
+int Dialog::runModal() {
+ uint32 oldFilter = _vm->setEventFilter(0);
int i;
@@ -319,17 +291,17 @@ int Dialog::run() {
while (!_finish) {
// So that the menu icons will reach their full size
- _gui->_vm->_mouse->processMenu();
- _gui->_vm->_screen->updateDisplay(false);
+ _vm->_mouse->processMenu();
+ _vm->_screen->updateDisplay(false);
int newMouseX, newMouseY;
- _gui->_vm->_mouse->getPos(newMouseX, newMouseY);
+ _vm->_mouse->getPos(newMouseX, newMouseY);
newMouseY += 40;
- MouseEvent *me = _gui->_vm->mouseEvent();
- KeyboardEvent *ke = _gui->_vm->keyboardEvent();
+ MouseEvent *me = _vm->mouseEvent();
+ KeyboardEvent *ke = _vm->keyboardEvent();
if (ke) {
if (ke->keycode == 27)
@@ -408,13 +380,13 @@ int Dialog::run() {
oldMouseX = newMouseX;
oldMouseY = newMouseY;
- _gui->_vm->_system->delayMillis(20);
+ _vm->_system->delayMillis(20);
- if (_gui->_vm->_quit)
+ if (_vm->_quit)
setResult(0);
}
- _gui->_vm->setEventFilter(oldFilter);
+ _vm->setEventFilter(oldFilter);
return _result;
}
@@ -423,7 +395,7 @@ int Dialog::run() {
//
Widget::Widget(Dialog *parent, int states)
- : _parent(parent), _numStates(states), _state(0) {
+ : _vm(parent->_vm), _parent(parent), _numStates(states), _state(0) {
_sprites = (SpriteInfo *) calloc(states, sizeof(SpriteInfo));
_surfaces = (WidgetSurface *) calloc(states, sizeof(WidgetSurface));
@@ -433,7 +405,7 @@ Widget::Widget(Dialog *parent, int states)
Widget::~Widget() {
for (int i = 0; i < _numStates; i++) {
if (_surfaces[i]._original)
- _parent->_gui->_vm->_screen->deleteSurface(_surfaces[i]._surface);
+ _vm->_screen->deleteSurface(_surfaces[i]._surface);
}
free(_sprites);
free(_surfaces);
@@ -447,11 +419,11 @@ void Widget::createSurfaceImage(int state, uint32 res, int x, int y, uint32 pc)
uint32 spriteType = RDSPR_TRANS;
// open anim resource file, point to base
- file = _parent->_gui->_vm->_resman->openResource(res);
+ file = _vm->_resman->openResource(res);
- anim_head = _parent->_gui->_vm->fetchAnimHeader(file);
- cdt_entry = _parent->_gui->_vm->fetchCdtEntry(file, pc);
- frame_head = _parent->_gui->_vm->fetchFrameHeader(file, pc);
+ anim_head = _vm->fetchAnimHeader(file);
+ cdt_entry = _vm->fetchCdtEntry(file, pc);
+ frame_head = _vm->fetchFrameHeader(file, pc);
// If the frame is flipped. (Only really applicable to frames using
// offsets.)
@@ -488,11 +460,11 @@ void Widget::createSurfaceImage(int state, uint32 res, int x, int y, uint32 pc)
// Points to just after frame header, ie. start of sprite data
_sprites[state].data = (byte *) (frame_head + 1);
- _parent->_gui->_vm->_screen->createSurface(&_sprites[state], &_surfaces[state]._surface);
+ _vm->_screen->createSurface(&_sprites[state], &_surfaces[state]._surface);
_surfaces[state]._original = true;
// Release the anim resource
- _parent->_gui->_vm->_resman->closeResource(res);
+ _vm->_resman->closeResource(res);
}
void Widget::linkSurfaceImage(Widget *from, int state, int x, int y) {
@@ -541,7 +513,7 @@ int Widget::getState() {
}
void Widget::paint(Common::Rect *clipRect) {
- _parent->_gui->_vm->_screen->drawSurface(&_sprites[_state], _surfaces[_state]._surface, clipRect);
+ _vm->_screen->drawSurface(&_sprites[_state], _surfaces[_state]._surface, clipRect);
}
/**
@@ -801,257 +773,258 @@ public:
};
/**
- * A "mini" dialog is usually a yes/no question, but also used for the
- * restart/restore dialog at the beginning of the game.
+ * The "mini" dialog.
*/
-class MiniDialog : public Dialog {
-private:
- uint32 _headerTextId;
- uint32 _okTextId;
- uint32 _cancelTextId;
- FontRendererGui *_fr;
- Widget *_panel;
- Button *_okButton;
- Button *_cancelButton;
+MiniDialog::MiniDialog(Sword2Engine *vm, uint32 headerTextId, uint32 okTextId, uint32 cancelTextId) : Dialog(vm) {
+ _headerTextId = headerTextId;
+ _okTextId = okTextId;
+ _cancelTextId = cancelTextId;
-public:
- MiniDialog(Gui *gui, uint32 headerTextId, uint32 okTextId = 149618688, uint32 cancelTextId = 149618689)
- : Dialog(gui), _headerTextId(headerTextId), _okTextId(okTextId), _cancelTextId(cancelTextId) {
- _fr = new FontRendererGui(_gui, _gui->_vm->_controlsFontId);
+ _fr = new FontRendererGui(_vm, _vm->_controlsFontId);
- _panel = new Widget(this, 1);
- _panel->createSurfaceImages(1996, 203, 104);
+ _panel = new Widget(this, 1);
+ _panel->createSurfaceImages(1996, 203, 104);
- _okButton = new Button(this, 243, 214, 24, 24);
- _okButton->createSurfaceImages(2002, 243, 214);
+ _okButton = new Button(this, 243, 214, 24, 24);
+ _okButton->createSurfaceImages(2002, 243, 214);
- _cancelButton = new Button(this, 243, 276, 24, 24);
- _cancelButton->linkSurfaceImages(_okButton, 243, 276);
+ _cancelButton = new Button(this, 243, 276, 24, 24);
+ _cancelButton->linkSurfaceImages(_okButton, 243, 276);
- registerWidget(_panel);
- registerWidget(_okButton);
- registerWidget(_cancelButton);
- }
+ registerWidget(_panel);
+ registerWidget(_okButton);
+ registerWidget(_cancelButton);
+}
- ~MiniDialog() {
- delete _fr;
- }
+MiniDialog::~MiniDialog() {
+ delete _fr;
+}
- virtual void paint() {
- Dialog::paint();
+void MiniDialog::paint() {
+ Dialog::paint();
- if (_headerTextId)
- _fr->drawText(_headerTextId, 310, 134, FontRendererGui::kAlignCenter);
- _fr->drawText(_okTextId, 270, 214);
- _fr->drawText(_cancelTextId, 270, 276);
- }
+ if (_headerTextId)
+ _fr->drawText(_headerTextId, 310, 134, FontRendererGui::kAlignCenter);
+ _fr->drawText(_okTextId, 270, 214);
+ _fr->drawText(_cancelTextId, 270, 276);
+}
- virtual void onAction(Widget *widget, int result = 0) {
- if (widget == _okButton)
- setResult(1);
- else if (widget == _cancelButton)
- setResult(0);
+void MiniDialog::onAction(Widget *widget, int result) {
+ if (widget == _okButton)
+ setResult(1);
+ else if (widget == _cancelButton)
+ setResult(0);
+}
+
+StartDialog::StartDialog(Sword2Engine *vm) : MiniDialog(vm, 0) {}
+
+int StartDialog::runModal() {
+ while (1) {
+ MiniDialog startDialog(_vm, 0, TEXT_RESTART, TEXT_RESTORE);
+
+ if (startDialog.runModal())
+ return 1;
+
+ if (_vm->_quit)
+ return 0;
+
+ SaveLoadDialog loadDialog(_vm, kLoadDialog);
+
+ if (loadDialog.runModal())
+ return 0;
+
+ if (_vm->_quit)
+ return 0;
}
-};
+
+ return 1;
+}
/**
- * The game settings dialog.
+ * The restart dialog.
*/
-class OptionsDialog : public Dialog {
-private:
- FontRendererGui *_fr;
- Widget *_panel;
- Switch *_objectLabelsSwitch;
- Switch *_subtitlesSwitch;
- Switch *_reverseStereoSwitch;
- Switch *_musicSwitch;
- Switch *_speechSwitch;
- Switch *_fxSwitch;
- Slider *_musicSlider;
- Slider *_speechSlider;
- Slider *_fxSlider;
- Slider *_gfxSlider;
- Widget *_gfxPreview;
- Button *_okButton;
- Button *_cancelButton;
-
- SoundMixer *_mixer;
+RestartDialog::RestartDialog(Sword2Engine *vm) : MiniDialog(vm, TEXT_RESTART) {}
-public:
- OptionsDialog(Gui *gui) : Dialog(gui) {
- _fr = new FontRendererGui(gui, gui->_vm->_controlsFontId);
+int RestartDialog::runModal() {
+ int result = MiniDialog::runModal();
+
+ if (result)
+ _vm->restartGame();
+
+ return result;
+}
+
+/**
+ * The quit dialog.
+ */
+
+QuitDialog::QuitDialog(Sword2Engine *vm) : MiniDialog(vm, TEXT_QUIT) {}
+
+int QuitDialog::runModal() {
+ int result = MiniDialog::runModal();
+
+ if (result)
+ _vm->closeGame();
+
+ return result;
+}
+
+/**
+ * The game settings dialog.
+ */
+
+OptionsDialog::OptionsDialog(Sword2Engine *vm) : Dialog(vm) {
+ _fr = new FontRendererGui(_vm, _vm->_controlsFontId);
- _mixer = _gui->_vm->_mixer;
-
- _panel = new Widget(this, 1);
- _panel->createSurfaceImages(3405, 0, 40);
-
- _objectLabelsSwitch = new Switch(this, 304, 100, 53, 32);
- _objectLabelsSwitch->createSurfaceImages(3687, 304, 100);
-
- _subtitlesSwitch = new Switch(this, 510, 100, 53, 32);
- _subtitlesSwitch->linkSurfaceImages(_objectLabelsSwitch, 510, 100);
-
- _reverseStereoSwitch = new Switch(this, 304, 293, 53, 32);
- _reverseStereoSwitch->linkSurfaceImages(_objectLabelsSwitch, 304, 293);
-
- _musicSwitch = new Switch(this, 516, 157, 40, 32);
- _musicSwitch->createSurfaceImages(3315, 516, 157);
- _musicSwitch->reverseStates();
-
- _speechSwitch = new Switch(this, 516, 205, 40, 32);
- _speechSwitch->linkSurfaceImages(_musicSwitch, 516, 205);
- _speechSwitch->reverseStates();
-
- _fxSwitch = new Switch(this, 516, 250, 40, 32);
- _fxSwitch->linkSurfaceImages(_musicSwitch, 516, 250);
- _fxSwitch->reverseStates();
-
- int volStep = SoundMixer::kMaxMixerVolume / 10;
-
- _musicSlider = new Slider(this, _panel, SoundMixer::kMaxMixerVolume, 309, 161, 170, 27, volStep);
- _speechSlider = new Slider(this, _panel, SoundMixer::kMaxMixerVolume, 309, 208, 170, 27, volStep, _musicSlider);
- _fxSlider = new Slider(this, _panel, SoundMixer::kMaxMixerVolume, 309, 254, 170, 27, volStep, _musicSlider);
- _gfxSlider = new Slider(this, _panel, 3, 309, 341, 170, 27, 1, _musicSlider);
-
- _gfxPreview = new Widget(this, 4);
- _gfxPreview->createSurfaceImages(256, 495, 310);
-
- _okButton = new Button(this, 203, 382, 53, 32);
- _okButton->createSurfaceImages(901, 203, 382);
-
- _cancelButton = new Button(this, 395, 382, 53, 32);
- _cancelButton->linkSurfaceImages(_okButton, 395, 382);
-
- registerWidget(_panel);
- registerWidget(_objectLabelsSwitch);
- registerWidget(_subtitlesSwitch);
- registerWidget(_reverseStereoSwitch);
- registerWidget(_musicSwitch);
- registerWidget(_speechSwitch);
- registerWidget(_fxSwitch);
- registerWidget(_musicSlider);
- registerWidget(_speechSlider);
- registerWidget(_fxSlider);
- registerWidget(_gfxSlider);
- registerWidget(_gfxPreview);
- registerWidget(_okButton);
- registerWidget(_cancelButton);
-
- _gui->readOptionSettings();
-
- _objectLabelsSwitch->setValue(_gui->_pointerTextSelected);
- _subtitlesSwitch->setValue(_gui->_subtitles);
- _reverseStereoSwitch->setValue(_gui->_vm->_sound->isReverseStereo());
- _musicSwitch->setValue(!_gui->_vm->_sound->isMusicMute());
- _speechSwitch->setValue(!_gui->_vm->_sound->isSpeechMute());
- _fxSwitch->setValue(!_gui->_vm->_sound->isFxMute());
-
- _musicSlider->setValue(_mixer->getVolumeForSoundType(SoundMixer::kMusicAudioDataType));
- _speechSlider->setValue(_mixer->getVolumeForSoundType(SoundMixer::kSpeechAudioDataType));
- _fxSlider->setValue(_mixer->getVolumeForSoundType(SoundMixer::kSFXAudioDataType));
-
- _gfxSlider->setValue(_gui->_vm->_screen->getRenderLevel());
- _gfxPreview->setState(_gui->_vm->_screen->getRenderLevel());
- }
+ _mixer = _vm->_mixer;
+
+ _panel = new Widget(this, 1);
+ _panel->createSurfaceImages(3405, 0, 40);
+
+ _objectLabelsSwitch = new Switch(this, 304, 100, 53, 32);
+ _objectLabelsSwitch->createSurfaceImages(3687, 304, 100);
+
+ _subtitlesSwitch = new Switch(this, 510, 100, 53, 32);
+ _subtitlesSwitch->linkSurfaceImages(_objectLabelsSwitch, 510, 100);
+
+ _reverseStereoSwitch = new Switch(this, 304, 293, 53, 32);
+ _reverseStereoSwitch->linkSurfaceImages(_objectLabelsSwitch, 304, 293);
+
+ _musicSwitch = new Switch(this, 516, 157, 40, 32);
+ _musicSwitch->createSurfaceImages(3315, 516, 157);
+ _musicSwitch->reverseStates();
+
+ _speechSwitch = new Switch(this, 516, 205, 40, 32);
+ _speechSwitch->linkSurfaceImages(_musicSwitch, 516, 205);
+ _speechSwitch->reverseStates();
+
+ _fxSwitch = new Switch(this, 516, 250, 40, 32);
+ _fxSwitch->linkSurfaceImages(_musicSwitch, 516, 250);
+ _fxSwitch->reverseStates();
+
+ int volStep = SoundMixer::kMaxMixerVolume / 10;
+
+ _musicSlider = new Slider(this, _panel, SoundMixer::kMaxMixerVolume, 309, 161, 170, 27, volStep);
+ _speechSlider = new Slider(this, _panel, SoundMixer::kMaxMixerVolume, 309, 208, 170, 27, volStep, _musicSlider);
+ _fxSlider = new Slider(this, _panel, SoundMixer::kMaxMixerVolume, 309, 254, 170, 27, volStep, _musicSlider);
+ _gfxSlider = new Slider(this, _panel, 3, 309, 341, 170, 27, 1, _musicSlider);
+
+ _gfxPreview = new Widget(this, 4);
+ _gfxPreview->createSurfaceImages(256, 495, 310);
+
+ _okButton = new Button(this, 203, 382, 53, 32);
+ _okButton->createSurfaceImages(901, 203, 382);
+
+ _cancelButton = new Button(this, 395, 382, 53, 32);
+ _cancelButton->linkSurfaceImages(_okButton, 395, 382);
+
+ registerWidget(_panel);
+ registerWidget(_objectLabelsSwitch);
+ registerWidget(_subtitlesSwitch);
+ registerWidget(_reverseStereoSwitch);
+ registerWidget(_musicSwitch);
+ registerWidget(_speechSwitch);
+ registerWidget(_fxSwitch);
+ registerWidget(_musicSlider);
+ registerWidget(_speechSlider);
+ registerWidget(_fxSlider);
+ registerWidget(_gfxSlider);
+ registerWidget(_gfxPreview);
+ registerWidget(_okButton);
+ registerWidget(_cancelButton);
+
+ _objectLabelsSwitch->setValue(_vm->_mouse->getObjectLabels());
+ _subtitlesSwitch->setValue(_vm->getSubtitles());
+ _reverseStereoSwitch->setValue(_vm->_sound->isReverseStereo());
+ _musicSwitch->setValue(!_vm->_sound->isMusicMute());
+ _speechSwitch->setValue(!_vm->_sound->isSpeechMute());
+ _fxSwitch->setValue(!_vm->_sound->isFxMute());
+
+ _musicSlider->setValue(_mixer->getVolumeForSoundType(SoundMixer::kMusicAudioDataType));
+ _speechSlider->setValue(_mixer->getVolumeForSoundType(SoundMixer::kSpeechAudioDataType));
+ _fxSlider->setValue(_mixer->getVolumeForSoundType(SoundMixer::kSFXAudioDataType));
+
+ _gfxSlider->setValue(_vm->_screen->getRenderLevel());
+ _gfxPreview->setState(_vm->_screen->getRenderLevel());
+}
- ~OptionsDialog() {
- delete _fr;
- }
+OptionsDialog::~OptionsDialog() {
+ delete _fr;
+}
- virtual void paint() {
- Dialog::paint();
-
- int maxWidth = 0;
- int width;
-
- uint32 alignTextIds[] = {
- 149618700, // object labels
- 149618702, // music volume
- 149618703, // speech volume
- 149618704, // fx volume
- 149618705, // graphics quality
- 149618709, // reverse stereo
- };
-
- for (int i = 0; i < ARRAYSIZE(alignTextIds); i++) {
- width = _fr->getTextWidth(alignTextIds[i]);
- if (width > maxWidth)
- maxWidth = width;
- }
+void OptionsDialog::paint() {
+ Dialog::paint();
- // Options
- _fr->drawText(149618698, 321, 55, FontRendererGui::kAlignCenter);
- // Subtitles
- _fr->drawText(149618699, 500, 103, FontRendererGui::kAlignRight);
- // Object labels
- _fr->drawText(149618700, 299 - maxWidth, 103);
- // Music volume
- _fr->drawText(149618702, 299 - maxWidth, 161);
- // Speech volume
- _fr->drawText(149618703, 299 - maxWidth, 208);
- // FX volume
- _fr->drawText(149618704, 299 - maxWidth, 254);
- // Reverse stereo
- _fr->drawText(149618709, 299 - maxWidth, 296);
- // Graphics quality
- _fr->drawText(149618705, 299 - maxWidth, 341);
- // Ok
- _fr->drawText(149618688, 193, 382, FontRendererGui::kAlignRight);
- // Cancel
- _fr->drawText(149618689, 385, 382, FontRendererGui::kAlignRight);
- }
+ int maxWidth = 0;
+ int width;
- virtual void onAction(Widget *widget, int result = 0) {
- // Since there is music playing while the dialog is displayed
- // we need to update music volume immediately.
-
- if (widget == _musicSwitch) {
- _gui->_vm->_sound->muteMusic(result != 0);
- } else if (widget == _musicSlider) {
- _mixer->setVolumeForSoundType(SoundMixer::kMusicAudioDataType, result);
- _gui->_vm->_sound->muteMusic(result == 0);
- _musicSwitch->setValue(result != 0);
- } else if (widget == _speechSlider) {
- _speechSwitch->setValue(result != 0);
- } else if (widget == _fxSlider) {
- _fxSwitch->setValue(result != 0);
- } else if (widget == _gfxSlider) {
- _gfxPreview->setState(result);
- _gui->updateGraphicsLevel(result);
- } else if (widget == _okButton) {
- _gui->_subtitles = _subtitlesSwitch->getValue();
- _gui->_pointerTextSelected = _objectLabelsSwitch->getValue();
-
- // Apply the changes
- _gui->_vm->_sound->muteMusic(!_musicSwitch->getValue());
- _gui->_vm->_sound->muteSpeech(!_speechSwitch->getValue());
- _gui->_vm->_sound->muteFx(!_fxSwitch->getValue());
- _gui->_vm->_sound->setReverseStereo(_reverseStereoSwitch->getValue());
- _mixer->setVolumeForSoundType(SoundMixer::kMusicAudioDataType, _musicSlider->getValue());
- _mixer->setVolumeForSoundType(SoundMixer::kSpeechAudioDataType, _speechSlider->getValue());
- _mixer->setVolumeForSoundType(SoundMixer::kSFXAudioDataType, _fxSlider->getValue());
-
- _gui->updateGraphicsLevel(_gfxSlider->getValue());
-
- _gui->writeOptionSettings();
- setResult(1);
- } else if (widget == _cancelButton) {
- // Revert the changes
- _gui->readOptionSettings();
- setResult(0);
- }
- }
-};
+ uint32 alignTextIds[] = {
+ TEXT_OBJECT_LABELS,
+ TEXT_MUSIC_VOLUME,
+ TEXT_SPEECH_VOLUME,
+ TEXT_FX_VOLUME,
+ TEXT_GFX_QUALITY,
+ TEXT_REVERSE_STEREO
+ };
-// FIXME: Move these into some class
+ for (int i = 0; i < ARRAYSIZE(alignTextIds); i++) {
+ width = _fr->getTextWidth(alignTextIds[i]);
+ if (width > maxWidth)
+ maxWidth = width;
+ }
+
+ _fr->drawText(TEXT_OPTIONS, 321, 55, FontRendererGui::kAlignCenter);
+ _fr->drawText(TEXT_SUBTITLES, 500, 103, FontRendererGui::kAlignRight);
+ _fr->drawText(TEXT_OBJECT_LABELS, 299 - maxWidth, 103);
+ _fr->drawText(TEXT_MUSIC_VOLUME, 299 - maxWidth, 161);
+ _fr->drawText(TEXT_SPEECH_VOLUME, 299 - maxWidth, 208);
+ _fr->drawText(TEXT_FX_VOLUME, 299 - maxWidth, 254);
+ _fr->drawText(TEXT_REVERSE_STEREO, 299 - maxWidth, 296);
+ _fr->drawText(TEXT_GFX_QUALITY, 299 - maxWidth, 341);
+ _fr->drawText(TEXT_OK, 193, 382, FontRendererGui::kAlignRight);
+ _fr->drawText(TEXT_CANCEL, 385, 382, FontRendererGui::kAlignRight);
+}
-enum {
- kSaveDialog,
- kLoadDialog
-};
+void OptionsDialog::onAction(Widget *widget, int result) {
+ // Since there is music playing while the dialog is displayed we need
+ // to update music volume immediately.
+
+ if (widget == _musicSwitch) {
+ _vm->_sound->muteMusic(result != 0);
+ } else if (widget == _musicSlider) {
+ _vm->_mixer->setVolumeForSoundType(SoundMixer::kMusicAudioDataType, result);
+ _vm->_sound->muteMusic(result == 0);
+ _musicSwitch->setValue(result != 0);
+ } else if (widget == _speechSlider) {
+ _speechSwitch->setValue(result != 0);
+ } else if (widget == _fxSlider) {
+ _fxSwitch->setValue(result != 0);
+ } else if (widget == _gfxSlider) {
+ _gfxPreview->setState(result);
+ _vm->_screen->setRenderLevel(result);
+ } else if (widget == _okButton) {
+ // Apply the changes
+ _vm->setSubtitles(_subtitlesSwitch->getValue());
+ _vm->_mouse->setObjectLabels(_objectLabelsSwitch->getValue());
+ _vm->_sound->muteMusic(!_musicSwitch->getValue());
+ _vm->_sound->muteSpeech(!_speechSwitch->getValue());
+ _vm->_sound->muteFx(!_fxSwitch->getValue());
+ _vm->_sound->setReverseStereo(_reverseStereoSwitch->getValue());
+ _mixer->setVolumeForSoundType(SoundMixer::kMusicAudioDataType, _musicSlider->getValue());
+ _mixer->setVolumeForSoundType(SoundMixer::kSpeechAudioDataType, _speechSlider->getValue());
+ _mixer->setVolumeForSoundType(SoundMixer::kSFXAudioDataType, _fxSlider->getValue());
+ _vm->_screen->setRenderLevel(_gfxSlider->getValue());
+
+ _vm->writeSettings();
+ setResult(1);
+ } else if (widget == _cancelButton) {
+ // Revert the changes
+ _vm->readSettings();
+ setResult(0);
+ }
+}
// Slot button actions. Note that keyboard input generates positive actions
@@ -1168,498 +1141,273 @@ public:
}
};
-class SaveLoadDialog : public Dialog {
-private:
- int _mode, _selectedSlot;
- byte _editBuffer[SAVE_DESCRIPTION_LEN];
- int _editPos, _firstPos;
- int _cursorTick;
-
- FontRendererGui *_fr1;
- FontRendererGui *_fr2;
- Widget *_panel;
- Slot *_slotButton[8];
- ScrollButton *_zupButton;
- ScrollButton *_upButton;
- ScrollButton *_downButton;
- ScrollButton *_zdownButton;
- Button *_okButton;
- Button *_cancelButton;
+SaveLoadDialog::SaveLoadDialog(Sword2Engine *vm, int mode) : Dialog(vm) {
+ int i;
-public:
- SaveLoadDialog(Gui *gui, int mode)
- : Dialog(gui), _mode(mode), _selectedSlot(-1) {
- int i;
+ _mode = mode;
+ _selectedSlot = -1;
- // FIXME: The "control font" and the "red font" are currently
- // always the same font, so one should be eliminated.
+ // FIXME: The "control font" and the "red font" are currently always
+ // the same font, so one should be eliminated.
- _fr1 = new FontRendererGui(_gui, _gui->_vm->_controlsFontId);
- _fr2 = new FontRendererGui(_gui, _gui->_vm->_redFontId);
+ _fr1 = new FontRendererGui(_vm, _vm->_controlsFontId);
+ _fr2 = new FontRendererGui(_vm, _vm->_redFontId);
- _panel = new Widget(this, 1);
- _panel->createSurfaceImages(2016, 0, 40);
+ _panel = new Widget(this, 1);
+ _panel->createSurfaceImages(2016, 0, 40);
- for (i = 0; i < 4; i++) {
- _slotButton[i] = new Slot(this, 114, 0, 384, 36);
- _slotButton[i]->createSurfaceImages(2006 + i, 114, 0);
- _slotButton[i]->setMode(mode);
- _slotButton[i + 4] = new Slot(this, 114, 0, 384, 36);
- _slotButton[i + 4]->linkSurfaceImages(_slotButton[i], 114, 0);
- _slotButton[i + 4]->setMode(mode);
- }
+ for (i = 0; i < 4; i++) {
+ _slotButton[i] = new Slot(this, 114, 0, 384, 36);
+ _slotButton[i]->createSurfaceImages(2006 + i, 114, 0);
+ _slotButton[i]->setMode(mode);
+ _slotButton[i + 4] = new Slot(this, 114, 0, 384, 36);
+ _slotButton[i + 4]->linkSurfaceImages(_slotButton[i], 114, 0);
+ _slotButton[i + 4]->setMode(mode);
+ }
- updateSlots();
+ updateSlots();
- _zupButton = new ScrollButton(this, 516, 65, 17, 17);
- _zupButton->createSurfaceImages(1982, 516, 65);
+ _zupButton = new ScrollButton(this, 516, 65, 17, 17);
+ _zupButton->createSurfaceImages(1982, 516, 65);
- _upButton = new ScrollButton(this, 516, 85, 17, 17);
- _upButton->createSurfaceImages(2067, 516, 85);
+ _upButton = new ScrollButton(this, 516, 85, 17, 17);
+ _upButton->createSurfaceImages(2067, 516, 85);
- _downButton = new ScrollButton(this, 516, 329, 17, 17);
- _downButton->createSurfaceImages(1986, 516, 329);
+ _downButton = new ScrollButton(this, 516, 329, 17, 17);
+ _downButton->createSurfaceImages(1986, 516, 329);
- _zdownButton = new ScrollButton(this, 516, 350, 17, 17);
- _zdownButton->createSurfaceImages(1988, 516, 350);
+ _zdownButton = new ScrollButton(this, 516, 350, 17, 17);
+ _zdownButton->createSurfaceImages(1988, 516, 350);
- _okButton = new Button(this, 130, 377, 24, 24);
- _okButton->createSurfaceImages(2002, 130, 377);
+ _okButton = new Button(this, 130, 377, 24, 24);
+ _okButton->createSurfaceImages(2002, 130, 377);
- _cancelButton = new Button(this, 350, 377, 24, 24);
- _cancelButton->linkSurfaceImages(_okButton, 350, 377);
+ _cancelButton = new Button(this, 350, 377, 24, 24);
+ _cancelButton->linkSurfaceImages(_okButton, 350, 377);
- registerWidget(_panel);
+ registerWidget(_panel);
- for (i = 0; i < 8; i++)
- registerWidget(_slotButton[i]);
+ for (i = 0; i < 8; i++)
+ registerWidget(_slotButton[i]);
- registerWidget(_zupButton);
- registerWidget(_upButton);
- registerWidget(_downButton);
- registerWidget(_zdownButton);
- registerWidget(_okButton);
- registerWidget(_cancelButton);
- }
+ registerWidget(_zupButton);
+ registerWidget(_upButton);
+ registerWidget(_downButton);
+ registerWidget(_zdownButton);
+ registerWidget(_okButton);
+ registerWidget(_cancelButton);
+}
- ~SaveLoadDialog() {
- delete _fr1;
- delete _fr2;
- }
+SaveLoadDialog::~SaveLoadDialog() {
+ delete _fr1;
+ delete _fr2;
+}
- // There aren't really a hundred different button objects of course,
- // there are only eight. Re-arrange them to simulate scrolling.
-
- void updateSlots() {
- for (int i = 0; i < 8; i++) {
- Slot *slot = _slotButton[(_gui->_baseSlot + i) % 8];
- FontRendererGui *fr;
- byte description[SAVE_DESCRIPTION_LEN];
-
- slot->setY(72 + i * 36);
-
- if (_gui->_baseSlot + i == _selectedSlot) {
- slot->setEditable(_mode == kSaveDialog);
- slot->setState(1);
- fr = _fr2;
- } else {
- slot->setEditable(false);
- slot->setState(0);
- fr = _fr1;
- }
+// There aren't really a hundred different button objects of course, there are
+// only eight. Re-arrange them to simulate scrolling.
- if (_gui->_vm->getSaveDescription(_gui->_baseSlot + i, description) == SR_OK) {
- slot->setText(fr, _gui->_baseSlot + i, description);
- slot->setClickable(true);
- } else {
- slot->setText(fr, _gui->_baseSlot + i, NULL);
- slot->setClickable(_mode == kSaveDialog);
- }
+void SaveLoadDialog::updateSlots() {
+ for (int i = 0; i < 8; i++) {
+ Slot *slot = _slotButton[(baseSlot + i) % 8];
+ FontRendererGui *fr;
+ byte description[SAVE_DESCRIPTION_LEN];
- if (slot->isEditable())
- drawEditBuffer(slot);
- else
- slot->paint();
- }
- }
+ slot->setY(72 + i * 36);
- virtual void onAction(Widget *widget, int result = 0) {
- if (widget == _zupButton) {
- if (_gui->_baseSlot > 0) {
- if (_gui->_baseSlot >= 8)
- _gui->_baseSlot -= 8;
- else
- _gui->_baseSlot = 0;
- updateSlots();
- }
- } else if (widget == _upButton) {
- if (_gui->_baseSlot > 0) {
- _gui->_baseSlot--;
- updateSlots();
- }
- } else if (widget == _downButton) {
- if (_gui->_baseSlot < 92) {
- _gui->_baseSlot++;
- updateSlots();
- }
- } else if (widget == _zdownButton) {
- if (_gui->_baseSlot < 92) {
- if (_gui->_baseSlot <= 84)
- _gui->_baseSlot += 8;
- else
- _gui->_baseSlot = 92;
- updateSlots();
- }
- } else if (widget == _okButton) {
- setResult(1);
- } else if (widget == _cancelButton) {
- setResult(0);
+ if (baseSlot + i == _selectedSlot) {
+ slot->setEditable(_mode == kSaveDialog);
+ slot->setState(1);
+ fr = _fr2;
} else {
- Slot *slot = (Slot *) widget;
- int textWidth;
- byte tmp;
- int i;
- int j;
-
- switch (result) {
- case kWheelUp:
- onAction(_upButton);
- break;
- case kWheelDown:
- onAction(_downButton);
- break;
- case kSelectSlot:
- case kDeselectSlot:
- if (result == kSelectSlot)
- _selectedSlot = _gui->_baseSlot + (slot->getY() - 72) / 35;
- else if (result == kDeselectSlot)
- _selectedSlot = -1;
-
- for (i = 0; i < 8; i++)
- if (widget == _slotButton[i])
- break;
-
- for (j = 0; j < 8; j++) {
- if (j != i) {
- _slotButton[j]->setEditable(false);
- _slotButton[j]->setState(0);
- }
- }
- break;
- case kStartEditing:
- if (_selectedSlot >= 10)
- _firstPos = 5;
- else
- _firstPos = 4;
-
- strcpy((char *) _editBuffer, (char *) slot->getText());
- _editPos = strlen((char *) _editBuffer);
- _cursorTick = 0;
- _editBuffer[_editPos] = '_';
- _editBuffer[_editPos + 1] = 0;
- slot->setEditable(true);
- drawEditBuffer(slot);
- break;
- case kCursorTick:
- _cursorTick++;
- if (_cursorTick == 7) {
- _editBuffer[_editPos] = ' ';
- drawEditBuffer(slot);
- } else if (_cursorTick == 14) {
- _cursorTick = 0;
- _editBuffer[_editPos] = '_';
- drawEditBuffer(slot);
- }
- break;
- case 8:
- if (_editPos > _firstPos) {
- _editBuffer[_editPos - 1] = _editBuffer[_editPos];
- _editBuffer[_editPos--] = 0;
- drawEditBuffer(slot);
- }
- break;
- default:
- tmp = _editBuffer[_editPos];
- _editBuffer[_editPos] = 0;
- textWidth = _fr2->getTextWidth(_editBuffer);
- _editBuffer[_editPos] = tmp;
-
- if (textWidth < 340 && _editPos < SAVE_DESCRIPTION_LEN - 2) {
- _editBuffer[_editPos + 1] = _editBuffer[_editPos];
- _editBuffer[_editPos + 2] = 0;
- _editBuffer[_editPos++] = result;
- drawEditBuffer(slot);
- }
- break;
- }
+ slot->setEditable(false);
+ slot->setState(0);
+ fr = _fr1;
}
- }
-
- void drawEditBuffer(Slot *slot) {
- if (_selectedSlot == -1)
- return;
-
- // This will redraw a bit more than is strictly necessary,
- // but I doubt that will make any noticeable difference.
- slot->paint();
- _fr2->drawText(_editBuffer, 130, 78 + (_selectedSlot - _gui->_baseSlot) * 36);
- }
-
- virtual void paint() {
- Dialog::paint();
-
- if (_mode == kLoadDialog) {
- // Restore
- _fr1->drawText(149618690, 165, 377);
+ if (_vm->getSaveDescription(baseSlot + i, description) == SR_OK) {
+ slot->setText(fr, baseSlot + i, description);
+ slot->setClickable(true);
} else {
- // Save
- _fr1->drawText(149618691, 165, 377);
- }
- // Cancel
- _fr1->drawText(149618689, 382, 377);
- }
-
- virtual void setResult(int result) {
- // Cancel
-
- if (result == 0) {
- Dialog::setResult(result);
- return;
+ slot->setText(fr, baseSlot + i, NULL);
+ slot->setClickable(_mode == kSaveDialog);
}
- // Save / Restore
-
- if (_selectedSlot == -1)
- return;
+ if (slot->isEditable())
+ drawEditBuffer(slot);
+ else
+ slot->paint();
+ }
+}
- if (_mode == kSaveDialog) {
- if (_editPos <= _firstPos)
- return;
+void SaveLoadDialog::drawEditBuffer(Slot *slot) {
+ if (_selectedSlot == -1)
+ return;
- _editBuffer[_editPos] = 0;
+ // This will redraw a bit more than is strictly necessary, but I doubt
+ // that will make any noticeable difference.
- uint32 rv = _gui->_vm->saveGame(_selectedSlot, (byte *) &_editBuffer[_firstPos]);
+ slot->paint();
+ _fr2->drawText(_editBuffer, 130, 78 + (_selectedSlot - baseSlot) * 36);
+}
- if (rv != SR_OK) {
- uint32 textId;
+void SaveLoadDialog::onAction(Widget *widget, int result) {
+ if (widget == _zupButton) {
+ if (baseSlot > 0) {
+ if (baseSlot >= 8)
+ baseSlot -= 8;
+ else
+ baseSlot = 0;
+ updateSlots();
+ }
+ } else if (widget == _upButton) {
+ if (baseSlot > 0) {
+ baseSlot--;
+ updateSlots();
+ }
+ } else if (widget == _downButton) {
+ if (baseSlot < 92) {
+ baseSlot++;
+ updateSlots();
+ }
+ } else if (widget == _zdownButton) {
+ if (baseSlot < 92) {
+ if (baseSlot <= 84)
+ baseSlot += 8;
+ else
+ baseSlot = 92;
+ updateSlots();
+ }
+ } else if (widget == _okButton) {
+ setResult(1);
+ } else if (widget == _cancelButton) {
+ setResult(0);
+ } else {
+ Slot *slot = (Slot *) widget;
+ int textWidth;
+ byte tmp;
+ int i;
+ int j;
- switch (rv) {
- case SR_ERR_FILEOPEN:
- textId = 213516674;
- break;
- default: // SR_ERR_WRITEFAIL
- textId = 213516676;
+ switch (result) {
+ case kWheelUp:
+ onAction(_upButton);
+ break;
+ case kWheelDown:
+ onAction(_downButton);
+ break;
+ case kSelectSlot:
+ case kDeselectSlot:
+ if (result == kSelectSlot)
+ _selectedSlot = baseSlot + (slot->getY() - 72) / 35;
+ else if (result == kDeselectSlot)
+ _selectedSlot = -1;
+
+ for (i = 0; i < 8; i++)
+ if (widget == _slotButton[i])
break;
- }
-
- _gui->_vm->_screen->displayMsg(_gui->_vm->fetchTextLine(_gui->_vm->_resman->openResource(textId / SIZE), textId & 0xffff) + 2, 0);
- result = 0;
- }
- } else {
- uint32 rv = _gui->_vm->restoreGame(_selectedSlot);
- if (rv != SR_OK) {
- uint32 textId;
-
- switch (rv) {
- case SR_ERR_FILEOPEN:
- textId = 213516670;
- break;
- case SR_ERR_INCOMPATIBLE:
- textId = 213516671;
- break;
- default: // SR_ERR_READFAIL
- textId = 213516673;
- break;
+ for (j = 0; j < 8; j++) {
+ if (j != i) {
+ _slotButton[j]->setEditable(false);
+ _slotButton[j]->setState(0);
}
+ }
+ break;
+ case kStartEditing:
+ if (_selectedSlot >= 10)
+ _firstPos = 5;
+ else
+ _firstPos = 4;
+
+ strcpy((char *) _editBuffer, (char *) slot->getText());
+ _editPos = strlen((char *) _editBuffer);
+ _cursorTick = 0;
+ _editBuffer[_editPos] = '_';
+ _editBuffer[_editPos + 1] = 0;
+ slot->setEditable(true);
+ drawEditBuffer(slot);
+ break;
+ case kCursorTick:
+ _cursorTick++;
+ if (_cursorTick == 7) {
+ _editBuffer[_editPos] = ' ';
+ drawEditBuffer(slot);
+ } else if (_cursorTick == 14) {
+ _cursorTick = 0;
+ _editBuffer[_editPos] = '_';
+ drawEditBuffer(slot);
+ }
+ break;
+ case 8:
+ if (_editPos > _firstPos) {
+ _editBuffer[_editPos - 1] = _editBuffer[_editPos];
+ _editBuffer[_editPos--] = 0;
+ drawEditBuffer(slot);
+ }
+ break;
+ default:
+ tmp = _editBuffer[_editPos];
+ _editBuffer[_editPos] = 0;
+ textWidth = _fr2->getTextWidth(_editBuffer);
+ _editBuffer[_editPos] = tmp;
- _gui->_vm->_screen->displayMsg(_gui->_vm->fetchTextLine(_gui->_vm->_resman->openResource(textId / SIZE), textId & 0xffff) + 2, 0);
- result = 0;
- } else {
- // Prime system with a game cycle
-
- // Reset the graphic 'BuildUnit' list before a
- // new logic list (see fnRegisterFrame)
- _gui->_vm->_screen->resetRenderLists();
-
- // Reset the mouse hot-spot list (see
- // fnRegisterMouse and fnRegisterFrame)
- _gui->_vm->_mouse->resetMouseList();
-
- if (_gui->_vm->_logic->processSession())
- error("restore 1st cycle failed??");
+ if (textWidth < 340 && _editPos < SAVE_DESCRIPTION_LEN - 2) {
+ _editBuffer[_editPos + 1] = _editBuffer[_editPos];
+ _editBuffer[_editPos + 2] = 0;
+ _editBuffer[_editPos++] = result;
+ drawEditBuffer(slot);
}
+ break;
}
-
- Dialog::setResult(result);
}
-};
-
-Gui::Gui(Sword2Engine *vm) : _vm(vm), _baseSlot(0) {
- ConfMan.registerDefault("music_mute", false);
- ConfMan.registerDefault("speech_mute", false);
- ConfMan.registerDefault("sfx_mute", false);
- ConfMan.registerDefault("gfx_details", 2);
- ConfMan.registerDefault("subtitles", false);
- ConfMan.registerDefault("reverse_stereo", false);
}
-void Gui::readOptionSettings(void) {
- _subtitles = ConfMan.getBool("subtitles");
- _pointerTextSelected = ConfMan.getBool("object_labels");
+void SaveLoadDialog::paint() {
+ Dialog::paint();
- updateGraphicsLevel((uint8) ConfMan.getInt("gfx_details"));
-
- _vm->_mixer->setVolumeForSoundType(SoundMixer::kMusicAudioDataType, ConfMan.getInt("music_volume"));
- _vm->_mixer->setVolumeForSoundType(SoundMixer::kSpeechAudioDataType, ConfMan.getInt("speech_volume"));
- _vm->_mixer->setVolumeForSoundType(SoundMixer::kSFXAudioDataType, ConfMan.getInt("sfx_volume"));
- _vm->_sound->muteMusic(ConfMan.getBool("music_mute"));
- _vm->_sound->muteSpeech(ConfMan.getBool("speech_mute"));
- _vm->_sound->muteFx(ConfMan.getBool("sfx_mute"));
- _vm->_sound->setReverseStereo(ConfMan.getBool("reverse_stereo"));
-}
-
-void Gui::writeOptionSettings(void) {
- ConfMan.set("music_volume", _vm->_mixer->getVolumeForSoundType(SoundMixer::kMusicAudioDataType));
- ConfMan.set("speech_volume", _vm->_mixer->getVolumeForSoundType(SoundMixer::kSpeechAudioDataType));
- ConfMan.set("sfx_volume", _vm->_mixer->getVolumeForSoundType(SoundMixer::kSFXAudioDataType));
- ConfMan.set("music_mute", _vm->_sound->isMusicMute());
- ConfMan.set("speech_mute", _vm->_sound->isSpeechMute());
- ConfMan.set("sfx_mute", _vm->_sound->isFxMute());
- ConfMan.set("gfx_details", _vm->_screen->getRenderLevel());
- ConfMan.set("subtitles", _subtitles);
- ConfMan.set("object_labels", _pointerTextSelected);
- ConfMan.set("reverse_stereo", _vm->_sound->isReverseStereo());
-
- ConfMan.flushToDisk();
+ _fr1->drawText((_mode == kLoadDialog) ? TEXT_RESTORE : TEXT_SAVE, 165, 377);
+ _fr1->drawText(TEXT_CANCEL, 382, 377);
}
-uint32 Gui::restoreControl(void) {
- // returns 0 for no restore
- // 1 for restored ok
-
- SaveLoadDialog loadDialog(this, kLoadDialog);
- return loadDialog.run();
-}
-
-void Gui::saveControl(void) {
- SaveLoadDialog saveDialog(this, kSaveDialog);
- _vm->_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
- saveDialog.run();
- _vm->_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
-}
-
-bool Gui::startControl(void) {
- while (1) {
- MiniDialog startDialog(this, 0, 149618693, 149618690);
-
- if (startDialog.run())
- return true;
-
- if (_vm->_quit)
- return false;
+void SaveLoadDialog::setResult(int result) {
+ if (result) {
+ if (_selectedSlot == -1)
+ return;
- if (restoreControl())
- return false;
+ if (_mode == kSaveDialog) {
+ if (_editPos <= _firstPos)
+ return;
- if (_vm->_quit)
- return false;
+ _editBuffer[_editPos] = 0;
+ }
}
- return true;
-}
-
-void Gui::quitControl(void) {
- MiniDialog quitDialog(this, 149618692);
-
- if (quitDialog.run())
- _vm->closeGame();
-}
-
-void Gui::restartControl(void) {
- ScreenInfo *screenInfo = _vm->_screen->getScreenInfo();
- uint32 temp_demo_flag;
-
- MiniDialog restartDialog(this, 149618693);
-
- if (!restartDialog.run())
- return;
-
- _vm->_mouse->closeMenuImmediately();
-
- // Restart the game. To do this, we must...
-
- // Stop music instantly!
- _vm->_sound->stopMusic(true);
-
- // In case we were dead - well we're not anymore!
- Logic::_scriptVars[DEAD] = 0;
-
- // Restart the game. Clear all memory and reset the globals
- temp_demo_flag = Logic::_scriptVars[DEMO];
-
- // Remove all resources from memory, including player object and
- // global variables
- _vm->_resman->removeAll();
-
- // Reopen global variables resource and player object
- _vm->setupPersistentResources();
-
- Logic::_scriptVars[DEMO] = temp_demo_flag;
-
- // Free all the route memory blocks from previous game
- _vm->_logic->_router->freeAllRouteMem();
-
- // Call the same function that first started us up
- _vm->startGame();
-
- // Prime system with a game cycle
-
- // Reset the graphic 'BuildUnit' list before a new logic list
- // (see fnRegisterFrame)
- _vm->_screen->resetRenderLists();
-
- // Reset the mouse hot-spot list (see fnRegisterMouse and
- // fnRegisterFrame)
- _vm->_mouse->resetMouseList();
-
- _vm->_mouse->closeMenuImmediately();
-
- // FOR THE DEMO - FORCE THE SCROLLING TO BE RESET!
- // - this is taken from fnInitBackground
- // switch on scrolling (2 means first time on screen)
- screenInfo->scroll_flag = 2;
-
- if (_vm->_logic->processSession())
- error("restart 1st cycle failed??");
-
- // So palette not restored immediately after control panel - we want
- // to fade up instead!
- screenInfo->new_palette = 99;
+ Dialog::setResult(result);
}
-void Gui::optionControl(void) {
- OptionsDialog optionsDialog(this);
-
- optionsDialog.run();
- return;
-}
+int SaveLoadDialog::runModal() {
+ if (_mode == kSaveDialog)
+ _vm->_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
-void Gui::updateGraphicsLevel(int newLevel) {
- if (newLevel < 0)
- newLevel = 0;
- else if (newLevel > 3)
- newLevel = 3;
+ int result = Dialog::runModal();
- _vm->_screen->setRenderLevel(newLevel);
+ if (_mode == kSaveDialog)
+ _vm->_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
- // update our global variable - which needs to be checked when dimming
- // the palette in PauseGame() in sword2.cpp (since palette-matching
- // cannot be done with dimmed palette so we turn down one notch while
- // dimmed, if at top level)
+ if (result) {
+ switch (_mode) {
+ case kSaveDialog:
+ if (_vm->saveGame(_selectedSlot, (byte *) &_editBuffer[_firstPos]) != SR_OK)
+ result = 0;
+ break;
+ case kLoadDialog:
+ if (_vm->restoreGame(_selectedSlot) != SR_OK)
+ result = 0;
+ break;
+ }
+ }
- _currentGraphicsLevel = newLevel;
+ return result;
}
} // End of namespace Sword2
diff --git a/sword2/controls.h b/sword2/controls.h
index 27cf07f9f5..9fa95a6b85 100644
--- a/sword2/controls.h
+++ b/sword2/controls.h
@@ -21,33 +21,152 @@
#ifndef _CONTROL_S
#define _CONTROL_S
+#include "sword2/defs.h"
+
+#define MAX_WIDGETS 25
+
namespace Sword2 {
class Sword2Engine;
+class FontRendererGui;
+class Widget;
+class Switch;
+class Slider;
+class Button;
+class ScrollButton;
+class Slot;
+
+enum {
+ kSaveDialog,
+ kLoadDialog
+};
+
+/**
+ * Base class for all dialogs.
+ */
+
+class Dialog {
+private:
+ int _numWidgets;
+ Widget *_widgets[MAX_WIDGETS];
+ bool _finish;
+ int _result;
-class Gui {
public:
Sword2Engine *_vm;
- int _baseSlot;
- uint8 _currentGraphicsLevel;
+ Dialog(Sword2Engine *vm);
+ virtual ~Dialog();
+
+ void registerWidget(Widget *widget);
+
+ virtual void paint();
+ virtual void setResult(int result);
+
+ virtual int runModal();
+
+ virtual void onAction(Widget *widget, int result = 0) {}
+};
+
+class OptionsDialog : public Dialog {
+private:
+ FontRendererGui *_fr;
+ Widget *_panel;
+ Switch *_objectLabelsSwitch;
+ Switch *_subtitlesSwitch;
+ Switch *_reverseStereoSwitch;
+ Switch *_musicSwitch;
+ Switch *_speechSwitch;
+ Switch *_fxSwitch;
+ Slider *_musicSlider;
+ Slider *_speechSlider;
+ Slider *_fxSlider;
+ Slider *_gfxSlider;
+ Widget *_gfxPreview;
+ Button *_okButton;
+ Button *_cancelButton;
+
+ SoundMixer *_mixer;
+
+public:
+ OptionsDialog(Sword2Engine *vm);
+ ~OptionsDialog();
+
+ virtual void paint();
+ virtual void onAction(Widget *widget, int result = 0);
+};
+
+class SaveLoadDialog : public Dialog {
+private:
+ int _mode, _selectedSlot;
+ byte _editBuffer[SAVE_DESCRIPTION_LEN];
+ int _editPos, _firstPos;
+ int _cursorTick;
+
+ FontRendererGui *_fr1;
+ FontRendererGui *_fr2;
+ Widget *_panel;
+ Slot *_slotButton[8];
+ ScrollButton *_zupButton;
+ ScrollButton *_upButton;
+ ScrollButton *_downButton;
+ ScrollButton *_zdownButton;
+ Button *_okButton;
+ Button *_cancelButton;
- bool _subtitles;
- bool _pointerTextSelected;
+public:
+ SaveLoadDialog(Sword2Engine *vm, int mode);
+ ~SaveLoadDialog();
- Gui(Sword2Engine *vm);
+ void updateSlots();
+ void drawEditBuffer(Slot *slot);
+
+ virtual void onAction(Widget *widget, int result = 0);
+ virtual void paint();
+ virtual void setResult(int result);
+ virtual int runModal();
+};
- uint32 restoreControl(void);
- void saveControl(void);
- bool startControl(void);
- void quitControl(void);
- void restartControl(void);
- void optionControl(void);
- void readOptionSettings(void);
- void writeOptionSettings(void);
- void updateGraphicsLevel(int newLevel);
+/**
+ * A "mini" dialog is usually a yes/no question, but also used for the
+ * restart/restore dialog at the beginning of the game.
+ */
+
+class MiniDialog : public Dialog {
+private:
+ uint32 _headerTextId;
+ uint32 _okTextId;
+ uint32 _cancelTextId;
+ FontRendererGui *_fr;
+ Widget *_panel;
+ Button *_okButton;
+ Button *_cancelButton;
+
+public:
+ MiniDialog(Sword2Engine *vm, uint32 headerTextId, uint32 okTextId = TEXT_OK, uint32 cancelTextId = TEXT_CANCEL);
+ virtual ~MiniDialog();
+ virtual void paint();
+ virtual void onAction(Widget *widget, int result = 0);
};
+class StartDialog : public MiniDialog {
+public:
+ StartDialog(Sword2Engine *vm);
+ virtual int runModal();
+};
+
+class RestartDialog : public MiniDialog {
+public:
+ RestartDialog(Sword2Engine *vm);
+ virtual int runModal();
+};
+
+class QuitDialog : public MiniDialog {
+public:
+ QuitDialog(Sword2Engine *vm);
+ virtual int runModal();
+};
+
} // End of namespace Sword2
#endif
diff --git a/sword2/defs.h b/sword2/defs.h
index 9c17517455..e6f8639516 100644
--- a/sword2/defs.h
+++ b/sword2/defs.h
@@ -24,6 +24,21 @@
#define SIZE 0x10000 // 65536 items per section
#define NuSIZE 0xffff // & with this
+#define TEXT_OK 0x08EB0000
+#define TEXT_CANCEL 0x08EB0001
+#define TEXT_RESTORE 0x08EB0002
+#define TEXT_SAVE 0x08EB0003
+#define TEXT_QUIT 0x08EB0004
+#define TEXT_RESTART 0x08EB0005
+#define TEXT_OPTIONS 0x08EB000A
+#define TEXT_SUBTITLES 0x08EB000B
+#define TEXT_OBJECT_LABELS 0x08EB000C
+#define TEXT_MUSIC_VOLUME 0x08EB000E
+#define TEXT_SPEECH_VOLUME 0x08EB000F
+#define TEXT_FX_VOLUME 0x08EB0010
+#define TEXT_GFX_QUALITY 0x08EB0011
+#define TEXT_REVERSE_STEREO 0x08EB0015
+
// always 8 (George object used for Nico player character as well)
#define CUR_PLAYER_ID 8
diff --git a/sword2/function.cpp b/sword2/function.cpp
index 51931417b2..b20335b57a 100644
--- a/sword2/function.cpp
+++ b/sword2/function.cpp
@@ -26,7 +26,6 @@
#include "sword2/defs.h"
#include "sword2/build_display.h"
#include "sword2/console.h"
-#include "sword2/controls.h"
#include "sword2/interpreter.h"
#include "sword2/logic.h"
#include "sword2/maketext.h"
@@ -1246,7 +1245,7 @@ int32 Logic::fnISpeak(int32 *params) {
// we don't want to use a wav for this line either, then just
// quit back to script right now!
- if (!_vm->_gui->_subtitles && !wantSpeechForLine(params[S_WAV]))
+ if (!_vm->getSubtitles() && !wantSpeechForLine(params[S_WAV]))
return IR_CONT;
// Drop out for 1st cycle to allow walks/anims to end and
@@ -1411,7 +1410,7 @@ int32 Logic::fnISpeak(int32 *params) {
}
}
- if (_vm->_gui->_subtitles || !speechRunning) {
+ if (_vm->getSubtitles() || !speechRunning) {
// We want subtitles, or the speech failed to load.
// Either way, we're going to show the text so create
// the text sprite.
diff --git a/sword2/mouse.cpp b/sword2/mouse.cpp
index be8953c254..a0ee7361ac 100644
--- a/sword2/mouse.cpp
+++ b/sword2/mouse.cpp
@@ -326,19 +326,34 @@ void Mouse::systemMenuMouse(void) {
switch (hit) {
case 0:
- _vm->_gui->optionControl();
+ {
+ OptionsDialog dialog(_vm);
+ dialog.runModal();
+ }
break;
case 1:
- _vm->_gui->quitControl();
+ {
+ QuitDialog dialog(_vm);
+ dialog.runModal();
+ }
break;
case 2:
- _vm->_gui->saveControl();
+ {
+ SaveLoadDialog dialog(_vm, kSaveDialog);
+ dialog.runModal();
+ }
break;
case 3:
- _vm->_gui->restoreControl();
+ {
+ SaveLoadDialog dialog(_vm, kLoadDialog);
+ dialog.runModal();
+ }
break;
case 4:
- _vm->_gui->restartControl();
+ {
+ RestartDialog dialog(_vm);
+ dialog.runModal();
+ }
break;
}
@@ -993,7 +1008,7 @@ void Mouse::createPointerText(uint32 text_id, uint32 pointer_res) {
int16 xOffset, yOffset;
uint8 justification;
- if (!_vm->_gui->_pointerTextSelected || !text_id)
+ if (!_objectLabels || !text_id)
return;
// Check what the pointer is, to set offsets correctly for text
diff --git a/sword2/mouse.h b/sword2/mouse.h
index e304db086b..1f277c9a9f 100644
--- a/sword2/mouse.h
+++ b/sword2/mouse.h
@@ -135,6 +135,8 @@ private:
uint32 _mouseTouching;
uint32 _oldMouseTouching;
+ bool _objectLabels;
+
uint32 _menuSelectedPos;
void decompressMouse(byte *decomp, byte *comp, int width, int height, int pitch, int xOff = 0, int yOff = 0);
@@ -151,6 +153,9 @@ public:
void getPos(int &x, int &y);
void setPos(int x, int y);
+ bool getObjectLabels() { return _objectLabels; }
+ void setObjectLabels(bool b) { _objectLabels = b; }
+
bool getMouseStatus() { return _mouseStatus; }
uint32 getMouseTouching() { return _mouseTouching; }
void setMouseTouching(uint32 touching) { _mouseTouching = touching; }
diff --git a/sword2/save_rest.cpp b/sword2/save_rest.cpp
index ea1b34f5c0..8fbe6e98b5 100644
--- a/sword2/save_rest.cpp
+++ b/sword2/save_rest.cpp
@@ -102,6 +102,22 @@ uint32 Sword2Engine::saveGame(uint16 slotNo, byte *desc) {
uint32 errorCode = saveData(slotNo, saveBufferMem, bufferSize);
free(saveBufferMem);
+
+ if (errorCode != SR_OK) {
+ uint32 textId;
+
+ switch (errorCode) {
+ case SR_ERR_FILEOPEN:
+ textId = 213516674;
+ break;
+ default: // SR_ERR_WRITEFAIL
+ textId = 213516676;
+ break;
+ }
+
+ _screen->displayMsg(fetchTextLine(_resman->openResource(textId / SIZE), textId & 0xffff) + 2, 0);
+ }
+
return errorCode;
}
@@ -205,6 +221,37 @@ uint32 Sword2Engine::restoreGame(uint16 slotNo) {
else
free(saveBufferMem);
+ if (errorCode != SR_OK) {
+ uint32 textId;
+
+ switch (errorCode) {
+ case SR_ERR_FILEOPEN:
+ textId = 213516670;
+ break;
+ case SR_ERR_INCOMPATIBLE:
+ textId = 213516671;
+ break;
+ default: // SR_ERR_READFAIL
+ textId = 213516673;
+ break;
+ }
+
+ _screen->displayMsg(fetchTextLine(_resman->openResource(textId / SIZE), textId & 0xffff) + 2, 0);
+ } else {
+ // Prime system with a game cycle
+
+ // Reset the graphic 'BuildUnit' list before a new logic list
+ // (see fnRegisterFrame)
+ _screen->resetRenderLists();
+
+ // Reset the mouse hot-spot list. See fnRegisterMouse()
+ // and fnRegisterFrame()
+ _mouse->resetMouseList();
+
+ if (_logic->processSession())
+ error("restore 1st cycle failed??");
+ }
+
// Force the game engine to pick a cursor. This appears to be needed
// when using the -x command-line option to restore a game.
_mouse->setMouseTouching(1);
diff --git a/sword2/speech.cpp b/sword2/speech.cpp
index abf0e67d85..232526c949 100644
--- a/sword2/speech.cpp
+++ b/sword2/speech.cpp
@@ -23,7 +23,6 @@
#include "sword2/sword2.h"
#include "sword2/console.h"
-#include "sword2/controls.h"
#include "sword2/defs.h"
#include "sword2/interpreter.h"
#include "sword2/logic.h"
diff --git a/sword2/sword2.cpp b/sword2/sword2.cpp
index 461401b8a7..2c1c861969 100644
--- a/sword2/sword2.cpp
+++ b/sword2/sword2.cpp
@@ -38,6 +38,7 @@
#include "sword2/memory.h"
#include "sword2/mouse.h"
#include "sword2/resman.h"
+#include "sword2/router.h"
#include "sword2/sound.h"
#ifdef _WIN32_WCE
@@ -128,7 +129,6 @@ Sword2Engine::Sword2Engine(GameDetector *detector, OSystem *syst) : Engine(syst)
_mouse = NULL;
_logic = NULL;
_fontRenderer = NULL;
- _gui = NULL;
_debugger = NULL;
_keyboardEvent.pending = false;
@@ -152,7 +152,6 @@ Sword2Engine::Sword2Engine(GameDetector *detector, OSystem *syst) : Engine(syst)
Sword2Engine::~Sword2Engine() {
delete _debugger;
delete _sound;
- delete _gui;
delete _fontRenderer;
delete _screen;
delete _mouse;
@@ -179,6 +178,43 @@ void Sword2Engine::errorString(const char *buf1, char *buf2) {
}
}
+void Sword2Engine::registerDefaultSettings() {
+ ConfMan.registerDefault("music_mute", false);
+ ConfMan.registerDefault("speech_mute", false);
+ ConfMan.registerDefault("sfx_mute", false);
+ ConfMan.registerDefault("gfx_details", 2);
+ ConfMan.registerDefault("subtitles", false);
+ ConfMan.registerDefault("reverse_stereo", false);
+}
+
+void Sword2Engine::readSettings() {
+ _mixer->setVolumeForSoundType(SoundMixer::kMusicAudioDataType, ConfMan.getInt("music_volume"));
+ _mixer->setVolumeForSoundType(SoundMixer::kSpeechAudioDataType, ConfMan.getInt("speech_volume"));
+ _mixer->setVolumeForSoundType(SoundMixer::kSFXAudioDataType, ConfMan.getInt("sfx_volume"));
+ setSubtitles(ConfMan.getBool("subtitles"));
+ _sound->muteMusic(ConfMan.getBool("music_mute"));
+ _sound->muteSpeech(ConfMan.getBool("speech_mute"));
+ _sound->muteFx(ConfMan.getBool("sfx_mute"));
+ _sound->setReverseStereo(ConfMan.getBool("reverse_stereo"));
+ _mouse->setObjectLabels(ConfMan.getBool("object_labels"));
+ _screen->setRenderLevel(ConfMan.getInt("gfx_details"));
+}
+
+void Sword2Engine::writeSettings() {
+ ConfMan.set("music_volume", _mixer->getVolumeForSoundType(SoundMixer::kMusicAudioDataType));
+ ConfMan.set("speech_volume", _mixer->getVolumeForSoundType(SoundMixer::kSpeechAudioDataType));
+ ConfMan.set("sfx_volume", _mixer->getVolumeForSoundType(SoundMixer::kSFXAudioDataType));
+ ConfMan.set("music_mute", _sound->isMusicMute());
+ ConfMan.set("speech_mute", _sound->isSpeechMute());
+ ConfMan.set("sfx_mute", _sound->isFxMute());
+ ConfMan.set("gfx_details", _screen->getRenderLevel());
+ ConfMan.set("subtitles", getSubtitles());
+ ConfMan.set("object_labels", _mouse->getObjectLabels());
+ ConfMan.set("reverse_stereo", _sound->isReverseStereo());
+
+ ConfMan.flushToDisk();
+}
+
/**
* The global script variables and player object should be kept open throughout
* the game, so that they are never expelled by the resource manager.
@@ -209,7 +245,6 @@ int Sword2Engine::init(GameDetector &detector) {
_resman = new ResourceManager(this);
_logic = new Logic(this);
_fontRenderer = new FontRenderer(this);
- _gui = new Gui(this);
_sound = new Sound(this);
_mouse = new Mouse(this);
@@ -217,9 +252,8 @@ int Sword2Engine::init(GameDetector &detector) {
if (!_mixer->isReady())
warning("Sound initialization failed");
- _mixer->setVolumeForSoundType(SoundMixer::kMusicAudioDataType, ConfMan.getInt("music_volume"));
- _mixer->setVolumeForSoundType(SoundMixer::kSpeechAudioDataType, ConfMan.getInt("speech_volume"));
- _mixer->setVolumeForSoundType(SoundMixer::kSFXAudioDataType, ConfMan.getInt("sfx_volume"));
+ registerDefaultSettings();
+ readSettings();
initStartMenu();
@@ -235,14 +269,15 @@ int Sword2Engine::init(GameDetector &detector) {
else
Logic::_scriptVars[DEMO] = 0;
- _gui->readOptionSettings();
-
if (_saveSlot != -1) {
if (saveExists(_saveSlot))
restoreGame(_saveSlot);
else {
+ SaveLoadDialog dialog(this, kLoadDialog);
+
_mouse->setMouse(NORMAL_MOUSE_ID);
- if (!_gui->restoreControl())
+
+ if (!dialog.runModal())
startGame();
}
} else if (!_bootParam && saveExists()) {
@@ -251,7 +286,10 @@ int Sword2Engine::init(GameDetector &detector) {
_mouse->setMouse(NORMAL_MOUSE_ID);
_logic->fnPlayMusic(pars);
- result = _gui->startControl();
+
+ StartDialog dialog(this);
+
+ result = dialog.runModal();
// If the game is started from the beginning, the cutscene
// player will kill the music for us. Otherwise, the restore
@@ -350,6 +388,63 @@ void Sword2Engine::closeGame() {
_quit = true;
}
+void Sword2Engine::restartGame() {
+ ScreenInfo *screenInfo = _screen->getScreenInfo();
+ uint32 temp_demo_flag;
+
+ _mouse->closeMenuImmediately();
+
+ // Restart the game. To do this, we must...
+
+ // Stop music instantly!
+ _sound->stopMusic(true);
+
+ // In case we were dead - well we're not anymore!
+ Logic::_scriptVars[DEAD] = 0;
+
+ // Restart the game. Clear all memory and reset the globals
+ temp_demo_flag = Logic::_scriptVars[DEMO];
+
+ // Remove all resources from memory, including player object and
+ // global variables
+ _resman->removeAll();
+
+ // Reopen global variables resource and player object
+ setupPersistentResources();
+
+ Logic::_scriptVars[DEMO] = temp_demo_flag;
+
+ // Free all the route memory blocks from previous game
+ _logic->_router->freeAllRouteMem();
+
+ // Call the same function that first started us up
+ startGame();
+
+ // Prime system with a game cycle
+
+ // Reset the graphic 'BuildUnit' list before a new logic list
+ // (see fnRegisterFrame)
+ _screen->resetRenderLists();
+
+ // Reset the mouse hot-spot list (see fnRegisterMouse and
+ // fnRegisterFrame)
+ _mouse->resetMouseList();
+
+ _mouse->closeMenuImmediately();
+
+ // FOR THE DEMO - FORCE THE SCROLLING TO BE RESET!
+ // - this is taken from fnInitBackground
+ // switch on scrolling (2 means first time on screen)
+ screenInfo->scroll_flag = 2;
+
+ if (_logic->processSession())
+ error("restart 1st cycle failed??");
+
+ // So palette not restored immediately after control panel - we want
+ // to fade up instead!
+ screenInfo->new_palette = 99;
+}
+
bool Sword2Engine::checkForMouseEvents() {
return _mouseEvent.pending;
}
@@ -529,11 +624,11 @@ void Sword2Engine::pauseGame() {
_sound->pauseAllSound();
_mouse->pauseGame();
- // If level at max, turn down because palette-matching won't work
- // when dimmed
+ // If render level is at max, turn it down because palette-matching
+ // won't work when the palette is dimmed.
- if (_gui->_currentGraphicsLevel == 3) {
- _gui->updateGraphicsLevel(2);
+ if (_screen->getRenderLevel() == 3) {
+ _screen->setRenderLevel(2);
_graphicsLevelFudged = true;
}
@@ -559,7 +654,7 @@ void Sword2Engine::unpauseGame() {
// If graphics level at max, turn up again
if (_graphicsLevelFudged) {
- _gui->updateGraphicsLevel(3);
+ _screen->setRenderLevel(3);
_graphicsLevelFudged = false;
}
diff --git a/sword2/sword2.h b/sword2/sword2.h
index 8de53d64e4..8a30dad63e 100644
--- a/sword2/sword2.h
+++ b/sword2/sword2.h
@@ -111,6 +111,8 @@ private:
uint32 _totalScreenManagers;
uint32 _startRes;
+ bool _useSubtitles;
+
struct StartUp {
char description[MAX_description];
@@ -131,8 +133,15 @@ public:
int go();
int init(GameDetector &detector);
+ void registerDefaultSettings();
+ void readSettings();
+ void writeSettings();
+
void setupPersistentResources();
+ bool getSubtitles() { return _useSubtitles; }
+ void setSubtitles(bool b) { _useSubtitles = b; }
+
bool _quit;
uint32 _features;
@@ -145,7 +154,6 @@ public:
Mouse *_mouse;
Logic *_logic;
FontRenderer *_fontRenderer;
- Gui *_gui;
Debugger *_debugger;
@@ -238,6 +246,7 @@ public:
void startGame();
void gameCycle();
void closeGame();
+ void restartGame();
void sleepUntil(uint32 time);