diff options
author | Torbjörn Andersson | 2003-11-16 14:18:29 +0000 |
---|---|---|
committer | Torbjörn Andersson | 2003-11-16 14:18:29 +0000 |
commit | fa2b8ba8de31f5659c675b507553a2b0a1ebd841 (patch) | |
tree | 52841e821b3283a0ff9430cf8be0cc273208f6e6 /sword2/controls.cpp | |
parent | ab066c41e0a42320137bc6cb79d77720f932af0e (diff) | |
download | scummvm-rg350-fa2b8ba8de31f5659c675b507553a2b0a1ebd841.tar.gz scummvm-rg350-fa2b8ba8de31f5659c675b507553a2b0a1ebd841.tar.bz2 scummvm-rg350-fa2b8ba8de31f5659c675b507553a2b0a1ebd841.zip |
More cleanup. I've eliminated all the temporary global variables I've added
over the past few weeks, except for g_sword2. (Of course, this doesn't
necessarily make the code any prettier, but we can work on that later.)
svn-id: r11309
Diffstat (limited to 'sword2/controls.cpp')
-rw-r--r-- | sword2/controls.cpp | 794 |
1 files changed, 431 insertions, 363 deletions
diff --git a/sword2/controls.cpp b/sword2/controls.cpp index f95f08db88..0e4ad72049 100644 --- a/sword2/controls.cpp +++ b/sword2/controls.cpp @@ -17,27 +17,10 @@ * $Header$ */ -#include "stdafx.h" +#include "common/stdafx.h" #include "common/config-manager.h" -#include "sword2/driver/driver96.h" -#include "sword2/build_display.h" -#include "sword2/console.h" -#include "sword2/controls.h" -#include "sword2/defs.h" -#include "sword2/header.h" -#include "sword2/interpreter.h" -#include "sword2/layers.h" -#include "sword2/logic.h" -#include "sword2/maketext.h" // for font resource variables -#include "sword2/mouse.h" -#include "sword2/protocol.h" -#include "sword2/resman.h" -#include "sword2/router.h" -#include "sword2/save_rest.h" -#include "sword2/sound.h" #include "sword2/sword2.h" - -namespace Sword2 { +#include "sword2/defs.h" #define MAX_STRING_LEN 64 // 20 was too low; better to be safe ;) #define CHARACTER_OVERLAP 2 // overlap characters by 3 pixels @@ -45,80 +28,180 @@ namespace Sword2 { // our fonts start on SPACE character (32) #define SIZE_OF_CHAR_SET (256 - 32) -Gui *gui; +#define MAX_WIDGETS 25 + +namespace Sword2 { -enum { - kAlignLeft, - kAlignRight, - kAlignCenter +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(); + + virtual void onAction(Widget *widget, int result = 0) {} }; +/** + * Base class for all widgets. + */ + +class Widget { +protected: + Dialog *_parent; + + _spriteInfo *_sprites; + + struct WidgetSurface { + uint8 *_surface; + bool _original; + }; + + WidgetSurface *_surfaces; + int _numStates; + int _state; + + Common::Rect _hitRect; + +public: + Widget(Dialog *parent, int states); + + virtual ~Widget(); + + void createSurfaceImage(int state, uint32 res, int x, int y, uint32 pc); + void linkSurfaceImage(Widget *from, int state, int x, int y); + + void createSurfaceImages(uint32 res, int x, int y); + void linkSurfaceImages(Widget *from, int x, int y); + + void setHitRect(int x, int y, int width, int height); + bool isHit(int16 x, int16 y); + + void setState(int state); + int getState(); + + virtual void paint(Common::Rect *clipRect = NULL); + + virtual void onMouseEnter() {} + virtual void onMouseExit() {} + virtual void onMouseMove(int x, int y) {} + virtual void onMouseDown(int x, int y) {} + virtual void onMouseUp(int x, int y) {} + virtual void onKey(_keyboardEvent *ke) {} + virtual void onTick() {} + + virtual void releaseMouse(int x, int y) {} +}; + +/** + * This class is used to draw text in dialogs, buttons, etc. + */ + class FontRendererGui { private: + Gui *_gui; + struct Glyph { uint8 *_data; int _width; int _height; - } _glyph[SIZE_OF_CHAR_SET]; + }; + + Glyph _glyph[SIZE_OF_CHAR_SET]; + int _fontId; public: - FontRendererGui(int fontId) : _fontId(fontId) { - uint8 *font = res_man->openResource(fontId); - _frameHeader *head; - _spriteInfo sprite; - - sprite.type = RDSPR_NOCOMPRESSION | RDSPR_TRANS; - - for (int i = 0; i < SIZE_OF_CHAR_SET; i++) { - head = (_frameHeader *) g_sword2->fetchFrameHeader(font, i); - sprite.data = (uint8 *) (head + 1); - sprite.w = head->width; - sprite.h = head->height; - g_graphics->createSurface(&sprite, &_glyph[i]._data); - _glyph[i]._width = head->width; - _glyph[i]._height = head->height; - } + enum { + kAlignLeft, + kAlignRight, + kAlignCenter + }; - res_man->closeResource(fontId); - } + FontRendererGui(Gui *gui, int fontId); + ~FontRendererGui(); - ~FontRendererGui() { - for (int i = 0; i < SIZE_OF_CHAR_SET; i++) - g_graphics->deleteSurface(_glyph[i]._data); - } + void fetchText(int textId, char *buf); - void fetchText(int textId, char *buf) { - uint8 *data = g_sword2->fetchTextLine(res_man->openResource(textId / SIZE), textId & 0xffff); - int i; + int getTextWidth(char *text); + int getTextWidth(int textId); - for (i = 0; data[i + 2]; i++) { - if (buf) - buf[i] = data[i + 2]; - } - - buf[i] = 0; - res_man->closeResource(textId / SIZE); - } + void drawText(char *text, int x, int y, int alignment = kAlignLeft); + void drawText(int textId, int x, int y, int alignment = kAlignLeft); +}; - int getTextWidth(char *text) { - int textWidth = 0; +FontRendererGui::FontRendererGui(Gui *gui, int fontId) + : _gui(gui), _fontId(fontId) { + uint8 *font = _gui->_vm->_resman->openResource(fontId); + _frameHeader *head; + _spriteInfo sprite; - for (int i = 0; text[i]; i++) - textWidth += (_glyph[text[i] - 32]._width - CHARACTER_OVERLAP); - return textWidth; + sprite.type = RDSPR_NOCOMPRESSION | RDSPR_TRANS; + + for (int i = 0; i < SIZE_OF_CHAR_SET; i++) { + head = (_frameHeader *) _gui->_vm->fetchFrameHeader(font, i); + sprite.data = (uint8 *) (head + 1); + sprite.w = head->width; + sprite.h = head->height; + _gui->_vm->_graphics->createSurface(&sprite, &_glyph[i]._data); + _glyph[i]._width = head->width; + _glyph[i]._height = head->height; } - int getTextWidth(int textId) { - char text[MAX_STRING_LEN]; + _gui->_vm->_resman->closeResource(fontId); +} + +FontRendererGui::~FontRendererGui() { + for (int i = 0; i < SIZE_OF_CHAR_SET; i++) + _gui->_vm->_graphics->deleteSurface(_glyph[i]._data); +} + +void FontRendererGui::fetchText(int textId, char *buf) { + uint8 *data = _gui->_vm->fetchTextLine(_gui->_vm->_resman->openResource(textId / SIZE), textId & 0xffff); + int i; - fetchText(textId, text); - return getTextWidth(text); + for (i = 0; data[i + 2]; i++) { + if (buf) + buf[i] = data[i + 2]; } + + buf[i] = 0; + _gui->_vm->_resman->closeResource(textId / SIZE); +} - void drawText(char *text, int x, int y, int alignment = kAlignLeft); - void drawText(int textId, int x, int y, int alignment = kAlignLeft); -}; +int FontRendererGui::getTextWidth(char *text) { + int textWidth = 0; + + for (int i = 0; text[i]; i++) + textWidth += (_glyph[text[i] - 32]._width - CHARACTER_OVERLAP); + return textWidth; +} + +int FontRendererGui::getTextWidth(int textId) { + char text[MAX_STRING_LEN]; + + fetchText(textId, text); + return getTextWidth(text); +} void FontRendererGui::drawText(char *text, int x, int y, int alignment) { _spriteInfo sprite; @@ -144,7 +227,7 @@ void FontRendererGui::drawText(char *text, int x, int y, int alignment) { sprite.w = _glyph[text[i] - 32]._width; sprite.h = _glyph[text[i] - 32]._height; - g_graphics->drawSurface(&sprite, _glyph[text[i] - 32]._data); + _gui->_vm->_graphics->drawSurface(&sprite, _glyph[text[i] - 32]._data); sprite.x += (_glyph[(int) text[i] - 32]._width - CHARACTER_OVERLAP); } @@ -157,91 +240,127 @@ void FontRendererGui::drawText(int textId, int x, int y, int alignment) { drawText(text, x, y, alignment); } -class Dialog; +// +// Dialog class functions +// -typedef struct Surface { - uint8 *_surface; - bool _original; -} WidgetSurface; +Dialog::Dialog(Gui *gui) + : _numWidgets(0), _finish(false), _result(0), _gui(gui) { + _gui->_vm->setFullPalette(CONTROL_PANEL_PALETTE); +} -class Widget { -protected: - Dialog *_parent; +Dialog::~Dialog() { + for (int i = 0; i < _numWidgets; i++) + delete _widgets[i]; +} - _spriteInfo *_sprites; - WidgetSurface *_surfaces; - int _numStates; - int _state; +void Dialog::registerWidget(Widget *widget) { + if (_numWidgets < MAX_WIDGETS) + _widgets[_numWidgets++] = widget; +} - Common::Rect _hitRect; +void Dialog::paint() { + _gui->_vm->_graphics->clearScene(); + for (int i = 0; i < _numWidgets; i++) + _widgets[i]->paint(); +} -public: - Widget(Dialog *parent, int states) : - _parent(parent), _numStates(states), _state(0) { - _sprites = (_spriteInfo *) calloc(states, sizeof(_spriteInfo)); - _surfaces = (WidgetSurface *) calloc(states, sizeof(WidgetSurface)); +void Dialog::setResult(int result) { + _result = result; + _finish = true; +} - _hitRect.left = _hitRect.right = _hitRect.top = _hitRect.bottom = -1; - } +int Dialog::run() { + int i; - virtual ~Widget() { - for (int i = 0; i < _numStates; i++) { - if (_surfaces[i]._original) - g_graphics->deleteSurface(_surfaces[i]._surface); - } - free(_sprites); - free(_surfaces); - } + paint(); - void createSurfaceImage(int state, uint32 res, int x, int y, uint32 pc); - void linkSurfaceImage(Widget *from, int state, int x, int y); + int16 oldMouseX = -1; + int16 oldMouseY = -1; - void createSurfaceImages(uint32 res, int x, int y) { - for (int i = 0; i < _numStates; i++) - createSurfaceImage(i, res, x, y, i); - } + while (!_finish) { + // So that the menu icons will reach their full size + _gui->_vm->_graphics->processMenu(); + _gui->_vm->_graphics->updateDisplay(); - void linkSurfaceImages(Widget *from, int x, int y) { - for (int i = 0; i < from->_numStates; i++) - linkSurfaceImage(from, i, x, y); - } + int16 newMouseX = _gui->_vm->_input->_mouseX; + int16 newMouseY = _gui->_vm->_input->_mouseY + 40; - void setHitRect(int x, int y, int width, int height) { - _hitRect.left = x; - _hitRect.right = x + width; - _hitRect.top = y; - _hitRect.bottom = y + height; - } + _mouseEvent *me = _gui->_vm->_input->mouseEvent(); + _keyboardEvent ke; + int32 keyboardStatus = _gui->_vm->_input->readKey(&ke); - bool isHit(int16 x, int16 y) { - return _hitRect.left >= 0 && _hitRect.contains(x, y); - } + if (keyboardStatus == RD_OK) { + if (ke.keycode == 27) + setResult(0); + else if (ke.keycode == '\n' || ke.keycode == '\r') + setResult(1); + } - void setState(int state) { - if (state != _state) { - _state = state; - paint(); + for (i = 0; i < _numWidgets; i++) { + bool oldHit = _widgets[i]->isHit(oldMouseX, oldMouseY); + bool newHit = _widgets[i]->isHit(newMouseX, newMouseY); + + if (!oldHit && newHit) + _widgets[i]->onMouseEnter(); + if (oldHit && !newHit) + _widgets[i]->onMouseExit(); + if (_gui->_vm->_input->_mouseX != oldMouseX || _gui->_vm->_input->_mouseY != oldMouseY) + _widgets[i]->onMouseMove(newMouseX, newMouseY); + + if (me) { + switch (me->buttons) { + case RD_LEFTBUTTONDOWN: + if (newHit) + _widgets[i]->onMouseDown(newMouseX, newMouseY); + break; + case RD_LEFTBUTTONUP: + if (newHit) + _widgets[i]->onMouseUp(newMouseX, newMouseY); + // So that slider widgets will know + // when the user releases the mouse + // button, even if the cursor is + // outside of the slider's hit area. + _widgets[i]->releaseMouse(newMouseX, newMouseY); + break; + } + } + + if (keyboardStatus == RD_OK) + _widgets[i]->onKey(&ke); + + _widgets[i]->onTick(); } - } - int getState() { - return _state; - } + oldMouseX = newMouseX; + oldMouseY = newMouseY; - virtual void paint(Common::Rect *clipRect = NULL) { - g_graphics->drawSurface(&_sprites[_state], _surfaces[_state]._surface, clipRect); + _gui->_vm->_system->delay_msecs(20); } - virtual void onMouseEnter() {} - virtual void onMouseExit() {} - virtual void onMouseMove(int x, int y) {} - virtual void onMouseDown(int x, int y) {} - virtual void onMouseUp(int x, int y) {} - virtual void onKey(_keyboardEvent *ke) {} - virtual void onTick() {} + return _result; +} - virtual void releaseMouse(int x, int y) {} -}; +// +// Widget functions +// + +Widget::Widget(Dialog *parent, int states) + : _parent(parent), _numStates(states), _state(0) { + _sprites = (_spriteInfo *) calloc(states, sizeof(_spriteInfo)); + _surfaces = (WidgetSurface *) calloc(states, sizeof(WidgetSurface)); + + _hitRect.left = _hitRect.right = _hitRect.top = _hitRect.bottom = -1; +} + +Widget::~Widget() { + for (int i = 0; i < _numStates; i++) { + if (_surfaces[i]._original) + _parent->_gui->_vm->_graphics->deleteSurface(_surfaces[i]._surface); + } + free(_sprites); + free(_surfaces); +} void Widget::createSurfaceImage(int state, uint32 res, int x, int y, uint32 pc) { uint8 *file, *colTablePtr = NULL; @@ -251,11 +370,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 = res_man->openResource(res); + file = _parent->_gui->_vm->_resman->openResource(res); - anim_head = g_sword2->fetchAnimHeader(file); - cdt_entry = g_sword2->fetchCdtEntry(file, pc); - frame_head = g_sword2->fetchFrameHeader(file, pc); + anim_head = _parent->_gui->_vm->fetchAnimHeader(file); + cdt_entry = _parent->_gui->_vm->fetchCdtEntry(file, pc); + frame_head = _parent->_gui->_vm->fetchFrameHeader(file, pc); // If the frame is flipped. (Only really applicable to frames using // offsets.) @@ -292,11 +411,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 = (uint8 *) (frame_head + 1); - g_graphics->createSurface(&_sprites[state], &_surfaces[state]._surface); + _parent->_gui->_vm->_graphics->createSurface(&_sprites[state], &_surfaces[state]._surface); _surfaces[state]._original = true; // Release the anim resource - res_man->closeResource(res); + _parent->_gui->_vm->_resman->closeResource(res); }; void Widget::linkSurfaceImage(Widget *from, int state, int x, int y) { @@ -312,122 +431,50 @@ void Widget::linkSurfaceImage(Widget *from, int state, int x, int y) { _surfaces[state]._original = false; }; -#define MAX_WIDGETS 25 - -class Dialog { -private: - int _numWidgets; - Widget *_widgets[MAX_WIDGETS]; - bool _finish; - int _result; - -public: - Dialog() : _numWidgets(0), _finish(false), _result(0) { - g_sword2->setFullPalette(CONTROL_PANEL_PALETTE); - } - - virtual ~Dialog() { - for (int i = 0; i < _numWidgets; i++) - delete _widgets[i]; - } +void Widget::createSurfaceImages(uint32 res, int x, int y) { + for (int i = 0; i < _numStates; i++) + createSurfaceImage(i, res, x, y, i); +} - void registerWidget(Widget *widget) { - if (_numWidgets < MAX_WIDGETS) { - _widgets[_numWidgets++] = widget; - } - } +void Widget::linkSurfaceImages(Widget *from, int x, int y) { + for (int i = 0; i < from->_numStates; i++) + linkSurfaceImage(from, i, x, y); +} - virtual void onAction(Widget *widget, int result = 0) {} +void Widget::setHitRect(int x, int y, int width, int height) { + _hitRect.left = x; + _hitRect.right = x + width; + _hitRect.top = y; + _hitRect.bottom = y + height; +} - virtual void paint() { - g_graphics->clearScene(); - for (int i = 0; i < _numWidgets; i++) - _widgets[i]->paint(); - } +bool Widget::isHit(int16 x, int16 y) { + return _hitRect.left >= 0 && _hitRect.contains(x, y); +} - virtual void setResult(int result) { - _result = result; - _finish = true; +void Widget::setState(int state) { + if (state != _state) { + _state = state; + paint(); } +} - int run(); -}; - -int Dialog::run() { - int i; - - paint(); - - int16 oldMouseX = -1; - int16 oldMouseY = -1; - - while (!_finish) { - // So that the menu icons will reach their full size - g_graphics->processMenu(); - g_graphics->updateDisplay(); - - int16 newMouseX = g_input->_mouseX; - int16 newMouseY = g_input->_mouseY + 40; - - _mouseEvent *me = g_input->mouseEvent(); - _keyboardEvent ke; - int32 keyboardStatus = g_input->readKey(&ke); - - if (keyboardStatus == RD_OK) { - if (ke.keycode == 27) - setResult(0); - else if (ke.keycode == '\n' || ke.keycode == '\r') - setResult(1); - } - - for (i = 0; i < _numWidgets; i++) { - bool oldHit = _widgets[i]->isHit(oldMouseX, oldMouseY); - bool newHit = _widgets[i]->isHit(newMouseX, newMouseY); - - if (!oldHit && newHit) - _widgets[i]->onMouseEnter(); - if (oldHit && !newHit) - _widgets[i]->onMouseExit(); - if (g_input->_mouseX != oldMouseX || g_input->_mouseY != oldMouseY) - _widgets[i]->onMouseMove(newMouseX, newMouseY); - - if (me) { - switch (me->buttons) { - case RD_LEFTBUTTONDOWN: - if (newHit) - _widgets[i]->onMouseDown(newMouseX, newMouseY); - break; - case RD_LEFTBUTTONUP: - if (newHit) - _widgets[i]->onMouseUp(newMouseX, newMouseY); - // So that slider widgets will know - // when the user releases the mouse - // button, even if the cursor is - // outside of the slider's hit area. - _widgets[i]->releaseMouse(newMouseX, newMouseY); - break; - } - } - - if (keyboardStatus == RD_OK) - _widgets[i]->onKey(&ke); - - _widgets[i]->onTick(); - } - - oldMouseX = newMouseX; - oldMouseY = newMouseY; - - g_system->delay_msecs(20); - } +int Widget::getState() { + return _state; +} - return _result; +void Widget::paint(Common::Rect *clipRect) { + _parent->_gui->_vm->_graphics->drawSurface(&_sprites[_state], _surfaces[_state]._surface, clipRect); } +/** + * Standard button class. + */ + class Button : public Widget { public: - Button(Dialog *parent, int x, int y, int w, int h) : - Widget(parent, 2) { + Button(Dialog *parent, int x, int y, int w, int h) + : Widget(parent, 2) { setHitRect(x, y, w, h); } @@ -447,13 +494,18 @@ public: } }; +/** + * Scroll buttons are used to scroll the savegame list. The difference between + * this and a normal button is that we want this to repeat. + */ + class ScrollButton : public Widget { private: uint32 _holdCounter; public: - ScrollButton(Dialog *parent, int x, int y, int w, int h) : - Widget(parent, 2), _holdCounter(0) { + ScrollButton(Dialog *parent, int x, int y, int w, int h) + : Widget(parent, 2), _holdCounter(0) { setHitRect(x, y, w, h); } @@ -480,15 +532,20 @@ public: } }; +/** + * A switch is a button that changes state when clicked, and keeps that state + * until clicked again. + */ + class Switch : public Widget { private: bool _holding, _value; int _upState, _downState; public: - Switch(Dialog *parent, int x, int y, int w, int h) : - Widget(parent, 2), _holding(false), - _value(false), _upState(0), _downState(1) { + Switch(Dialog *parent, int x, int y, int w, int h) + : Widget(parent, 2), _holding(false), _value(false), + _upState(0), _downState(1) { setHitRect(x, y, w, h); } @@ -537,6 +594,10 @@ public: } }; +/** + * A slider is used to specify a value within a pre-defined range. + */ + class Slider : public Widget { private: Widget *_background; @@ -555,10 +616,10 @@ private: public: Slider(Dialog *parent, Widget *background, int max, - int x, int y, int w, int h, Widget *base = NULL) : - Widget(parent, 1), _background(background), - _dragging(false), _value(0), _targetValue(0), - _maxValue(max) { + int x, int y, int w, int h, Widget *base = NULL) + : Widget(parent, 1), _background(background), + _dragging(false), _value(0), _targetValue(0), + _maxValue(max) { setHitRect(x, y, w, h); if (base) @@ -654,9 +715,12 @@ public: } }; +/** + * A "mini" dialog is basically a yes/no question. + */ + class MiniDialog : public Dialog { private: - Sword2Engine *_vm; int _textId; FontRendererGui *_fr; Widget *_panel; @@ -664,8 +728,9 @@ private: Button *_cancelButton; public: - MiniDialog(int fontId, uint32 textId) : _textId(textId) { - _fr = new FontRendererGui(fontId); + MiniDialog(Gui *gui, uint32 textId) + : Dialog(gui), _textId(textId) { + _fr = new FontRendererGui(_gui, _gui->_vm->_controlsFontId); _panel = new Widget(this, 1); _panel->createSurfaceImages(1996, 203, 104); @@ -688,7 +753,7 @@ public: virtual void paint() { Dialog::paint(); - _fr->drawText(_textId, 310, 134, kAlignCenter); + _fr->drawText(_textId, 310, 134, FontRendererGui::kAlignCenter); _fr->drawText(149618688, 270, 214); // ok _fr->drawText(149618689, 270, 276); // cancel } @@ -701,6 +766,10 @@ public: } }; +/** + * The game settings dialog. + */ + class OptionsDialog : public Dialog { private: FontRendererGui *_fr; @@ -720,8 +789,8 @@ private: Button *_cancelButton; public: - OptionsDialog() { - _fr = new FontRendererGui(g_sword2->_controlsFontId); + OptionsDialog(Gui *gui) : Dialog(gui) { + _fr = new FontRendererGui(gui, gui->_vm->_controlsFontId); _panel = new Widget(this, 1); _panel->createSurfaceImages(3405, 0, 40); @@ -776,19 +845,19 @@ public: registerWidget(_okButton); registerWidget(_cancelButton); - gui->readOptionSettings(); + _gui->readOptionSettings(); - _objectLabelsSwitch->setValue(gui->_pointerTextSelected); - _subtitlesSwitch->setValue(gui->_subtitles); - _reverseStereoSwitch->setValue(gui->_stereoReversed); - _musicSwitch->setValue(!g_sound->isMusicMute()); - _speechSwitch->setValue(!g_sound->isSpeechMute()); - _fxSwitch->setValue(!g_sound->isFxMute()); - _musicSlider->setValue(g_sound->getMusicVolume()); - _speechSlider->setValue(g_sound->getSpeechVolume()); - _fxSlider->setValue(g_sound->getFxVolume()); - _gfxSlider->setValue(g_graphics->getRenderLevel()); - _gfxPreview->setState(g_graphics->getRenderLevel()); + _objectLabelsSwitch->setValue(_gui->_pointerTextSelected); + _subtitlesSwitch->setValue(_gui->_subtitles); + _reverseStereoSwitch->setValue(_gui->_stereoReversed); + _musicSwitch->setValue(!_gui->_vm->_sound->isMusicMute()); + _speechSwitch->setValue(!_gui->_vm->_sound->isSpeechMute()); + _fxSwitch->setValue(!_gui->_vm->_sound->isFxMute()); + _musicSlider->setValue(_gui->_vm->_sound->getMusicVolume()); + _speechSlider->setValue(_gui->_vm->_sound->getSpeechVolume()); + _fxSlider->setValue(_gui->_vm->_sound->getFxVolume()); + _gfxSlider->setValue(_gui->_vm->_graphics->getRenderLevel()); + _gfxPreview->setState(_gui->_vm->_graphics->getRenderLevel()); } ~OptionsDialog() { @@ -817,9 +886,9 @@ public: } // Options - _fr->drawText(149618698, 321, 55, kAlignCenter); + _fr->drawText(149618698, 321, 55, FontRendererGui::kAlignCenter); // Subtitles - _fr->drawText(149618699, 500, 103, kAlignRight); + _fr->drawText(149618699, 500, 103, FontRendererGui::kAlignRight); // Object labels _fr->drawText(149618700, 299 - maxWidth, 103); // Music volume @@ -833,9 +902,9 @@ public: // Graphics quality _fr->drawText(149618705, 299 - maxWidth, 341); // Ok - _fr->drawText(149618688, 193, 382, kAlignRight); + _fr->drawText(149618688, 193, 382, FontRendererGui::kAlignRight); // Cancel - _fr->drawText(149618689, 385, 382, kAlignRight); + _fr->drawText(149618689, 385, 382, FontRendererGui::kAlignRight); } virtual void onAction(Widget *widget, int result = 0) { @@ -843,10 +912,10 @@ public: // we need to update music volume immediately. if (widget == _musicSwitch) { - g_sound->muteMusic(result != 0); + _gui->_vm->_sound->muteMusic(result != 0); } else if (widget == _musicSlider) { - g_sound->setMusicVolume(result); - g_sound->muteMusic(result == 0); + _gui->_vm->_sound->setMusicVolume(result); + _gui->_vm->_sound->muteMusic(result == 0); _musicSwitch->setValue(result != 0); } else if (widget == _speechSlider) { _speechSwitch->setValue(result != 0); @@ -854,33 +923,35 @@ public: _fxSwitch->setValue(result != 0); } else if (widget == _gfxSlider) { _gfxPreview->setState(result); - gui->updateGraphicsLevel(result); + _gui->updateGraphicsLevel(result); } else if (widget == _okButton) { - gui->_subtitles = _subtitlesSwitch->getValue(); - gui->_pointerTextSelected = _objectLabelsSwitch->getValue(); - gui->_stereoReversed = _reverseStereoSwitch->getValue(); + _gui->_subtitles = _subtitlesSwitch->getValue(); + _gui->_pointerTextSelected = _objectLabelsSwitch->getValue(); + _gui->_stereoReversed = _reverseStereoSwitch->getValue(); // Apply the changes - g_sound->muteMusic(!_musicSwitch->getValue()); - g_sound->muteSpeech(!_speechSwitch->getValue()); - g_sound->muteFx(!_fxSwitch->getValue()); - g_sound->setMusicVolume(_musicSlider->getValue()); - g_sound->setSpeechVolume(_speechSlider->getValue()); - g_sound->setFxVolume(_fxSlider->getValue()); - g_sound->buildPanTable(gui->_stereoReversed); + _gui->_vm->_sound->muteMusic(!_musicSwitch->getValue()); + _gui->_vm->_sound->muteSpeech(!_speechSwitch->getValue()); + _gui->_vm->_sound->muteFx(!_fxSwitch->getValue()); + _gui->_vm->_sound->setMusicVolume(_musicSlider->getValue()); + _gui->_vm->_sound->setSpeechVolume(_speechSlider->getValue()); + _gui->_vm->_sound->setFxVolume(_fxSlider->getValue()); + _gui->_vm->_sound->buildPanTable(_gui->_stereoReversed); - gui->updateGraphicsLevel(_gfxSlider->getValue()); + _gui->updateGraphicsLevel(_gfxSlider->getValue()); - gui->writeOptionSettings(); + _gui->writeOptionSettings(); setResult(1); } else if (widget == _cancelButton) { // Revert the changes - gui->readOptionSettings(); + _gui->readOptionSettings(); setResult(0); } } }; +// FIXME: Move these into some class + enum { kSaveDialog, kLoadDialog @@ -902,9 +973,8 @@ private: bool _editable; public: - Slot(Dialog *parent, int x, int y, int w, int h) : - Widget(parent, 2), _clickable(false), - _editable(false) { + Slot(Dialog *parent, int x, int y, int w, int h) + : Widget(parent, 2), _clickable(false), _editable(false) { setHitRect(x, y, w, h); _text[0] = 0; } @@ -988,8 +1058,6 @@ public: class SaveLoadDialog : public Dialog { private: - Sword2Engine *_vm; - int _mode, _selectedSlot; char _editBuffer[SAVE_DESCRIPTION_LEN]; int _editPos, _firstPos; @@ -1009,15 +1077,15 @@ private: void saveLoadError(char *text); public: - SaveLoadDialog(Sword2Engine *vm, int mode) - : _vm(vm), _mode(mode), _selectedSlot(-1) { + SaveLoadDialog(Gui *gui, int mode) + : Dialog(gui), _mode(mode), _selectedSlot(-1) { int i; // FIXME: The "control font" and the "red font" are currently // always the same font, so one should be eliminated. - _fr1 = new FontRendererGui(_vm->_controlsFontId); - _fr2 = new FontRendererGui(_vm->_redFontId); + _fr1 = new FontRendererGui(_gui, _gui->_vm->_controlsFontId); + _fr2 = new FontRendererGui(_gui, _gui->_vm->_redFontId); _panel = new Widget(this, 1); _panel->createSurfaceImages(2016, 0, 40); @@ -1074,13 +1142,13 @@ public: void updateSlots() { for (int i = 0; i < 8; i++) { - Slot *slot = _slotButton[(gui->_baseSlot + i) % 8]; + Slot *slot = _slotButton[(_gui->_baseSlot + i) % 8]; FontRendererGui *fr; uint8 description[SAVE_DESCRIPTION_LEN]; slot->setY(72 + i * 36); - if (gui->_baseSlot + i == _selectedSlot) { + if (_gui->_baseSlot + i == _selectedSlot) { slot->setEditable(_mode == kSaveDialog); slot->setState(1); fr = _fr2; @@ -1090,11 +1158,11 @@ public: fr = _fr1; } - if (_vm->getSaveDescription(gui->_baseSlot + i, description) == SR_OK) { - slot->setText(fr, gui->_baseSlot + i, (char *) description); + if (_gui->_vm->getSaveDescription(_gui->_baseSlot + i, description) == SR_OK) { + slot->setText(fr, _gui->_baseSlot + i, (char *) description); slot->setClickable(true); } else { - slot->setText(fr, gui->_baseSlot + i, NULL); + slot->setText(fr, _gui->_baseSlot + i, NULL); slot->setClickable(_mode == kSaveDialog); } @@ -1107,29 +1175,29 @@ public: virtual void onAction(Widget *widget, int result = 0) { if (widget == _zupButton) { - if (gui->_baseSlot > 0) { - if (gui->_baseSlot >= 8) - gui->_baseSlot -= 8; + if (_gui->_baseSlot > 0) { + if (_gui->_baseSlot >= 8) + _gui->_baseSlot -= 8; else - gui->_baseSlot = 0; + _gui->_baseSlot = 0; updateSlots(); } } else if (widget == _upButton) { - if (gui->_baseSlot > 0) { - gui->_baseSlot--; + if (_gui->_baseSlot > 0) { + _gui->_baseSlot--; updateSlots(); } } else if (widget == _downButton) { - if (gui->_baseSlot < 92) { - gui->_baseSlot++; + if (_gui->_baseSlot < 92) { + _gui->_baseSlot++; updateSlots(); } } else if (widget == _zdownButton) { - if (gui->_baseSlot < 92) { - if (gui->_baseSlot <= 84) - gui->_baseSlot += 8; + if (_gui->_baseSlot < 92) { + if (_gui->_baseSlot <= 84) + _gui->_baseSlot += 8; else - gui->_baseSlot = 92; + _gui->_baseSlot = 92; updateSlots(); } } else if (widget == _okButton) { @@ -1187,7 +1255,7 @@ public: } } else { if (result == kSelectSlot) - _selectedSlot = gui->_baseSlot + (slot->getY() - 72) / 35; + _selectedSlot = _gui->_baseSlot + (slot->getY() - 72) / 35; else if (result == kDeselectSlot) _selectedSlot = -1; @@ -1215,7 +1283,7 @@ public: // but I doubt that will make any noticeable difference. slot->paint(); - _fr2->drawText(_editBuffer, 130, 78 + (_selectedSlot - gui->_baseSlot) * 36); + _fr2->drawText(_editBuffer, 130, 78 + (_selectedSlot - _gui->_baseSlot) * 36); } virtual void paint() { @@ -1251,7 +1319,7 @@ public: _editBuffer[_editPos] = 0; - uint32 rv = _vm->saveGame(_selectedSlot, (uint8 *) &_editBuffer[_firstPos]); + uint32 rv = _gui->_vm->saveGame(_selectedSlot, (uint8 *) &_editBuffer[_firstPos]); if (rv != SR_OK) { uint32 textId; @@ -1265,11 +1333,11 @@ public: break; } - saveLoadError((char *) (g_sword2->fetchTextLine(res_man->openResource(textId / SIZE), textId & 0xffff) + 2)); + saveLoadError((char *) (_gui->_vm->fetchTextLine(_gui->_vm->_resman->openResource(textId / SIZE), textId & 0xffff) + 2)); result = 0; } } else { - uint32 rv = _vm->restoreGame(_selectedSlot); + uint32 rv = _gui->_vm->restoreGame(_selectedSlot); if (rv != SR_OK) { uint32 textId; @@ -1286,20 +1354,20 @@ public: break; } - saveLoadError((char *) (g_sword2->fetchTextLine(res_man->openResource(textId / SIZE), textId & 0xffff) + 2)); + saveLoadError((char *) (_gui->_vm->fetchTextLine(_gui->_vm->_resman->openResource(textId / SIZE), textId & 0xffff) + 2)); result = 0; } else { // Prime system with a game cycle // Reset the graphic 'buildit' list before a // new logic list (see fnRegisterFrame) - _vm->resetRenderLists(); + _gui->_vm->resetRenderLists(); // Reset the mouse hot-spot list (see // fnRegisterMouse and fnRegisterFrame) - _vm->resetMouseList(); + _gui->_vm->resetMouseList(); - if (_vm->_logic->processSession()) + if (_gui->_vm->_logic->processSession()) error("restore 1st cycle failed??"); } } @@ -1310,31 +1378,31 @@ public: void SaveLoadDialog::saveLoadError(char* text) { // Print a message on screen. Second parameter is duration. - g_sword2->displayMsg((uint8 *) text, 0); + _gui->_vm->displayMsg((uint8 *) text, 0); // Wait for ESC or mouse click while (1) { _mouseEvent *me; - g_graphics->updateDisplay(); + _gui->_vm->_graphics->updateDisplay(); - if (g_input->keyWaiting()) { + if (_gui->_vm->_input->keyWaiting()) { _keyboardEvent ke; - g_input->readKey(&ke); + _gui->_vm->_input->readKey(&ke); if (ke.keycode == 27) break; } - me = g_input->mouseEvent(); + me = _gui->_vm->_input->mouseEvent(); if (me && (me->buttons & RD_LEFTBUTTONDOWN)) break; - g_system->delay_msecs(20); + _gui->_vm->_system->delay_msecs(20); } // Remove the message. - g_sword2->removeMsg(); + _gui->_vm->removeMsg(); } Gui::Gui(Sword2Engine *vm) : _vm(vm), _baseSlot(0) { @@ -1371,23 +1439,23 @@ void Gui::readOptionSettings(void) { updateGraphicsLevel((uint8) ConfMan.getInt("gfx_details")); - g_sound->setMusicVolume((16 * ConfMan.getInt("music_volume")) / 255); - g_sound->setSpeechVolume((14 * ConfMan.getInt("speech_volume")) / 255); - g_sound->setFxVolume((14 * ConfMan.getInt("sfx_volume")) / 255); - g_sound->muteMusic(ConfMan.getBool("music_mute")); - g_sound->muteSpeech(ConfMan.getBool("speech_mute")); - g_sound->muteFx(ConfMan.getBool("sfx_mute")); - g_sound->buildPanTable(_stereoReversed); + _vm->_sound->setMusicVolume((16 * ConfMan.getInt("music_volume")) / 255); + _vm->_sound->setSpeechVolume((14 * ConfMan.getInt("speech_volume")) / 255); + _vm->_sound->setFxVolume((14 * ConfMan.getInt("sfx_volume")) / 255); + _vm->_sound->muteMusic(ConfMan.getBool("music_mute")); + _vm->_sound->muteSpeech(ConfMan.getBool("speech_mute")); + _vm->_sound->muteFx(ConfMan.getBool("sfx_mute")); + _vm->_sound->buildPanTable(_stereoReversed); } void Gui::writeOptionSettings(void) { - ConfMan.set("music_volume", _musicVolume[g_sound->getMusicVolume()]); - ConfMan.set("speech_volume", _soundVolume[g_sound->getSpeechVolume()]); - ConfMan.set("sfx_volume", _soundVolume[g_sound->getFxVolume()]); - ConfMan.set("music_mute", g_sound->isMusicMute()); - ConfMan.set("speech_mute", g_sound->isSpeechMute()); - ConfMan.set("sfx_mute", g_sound->isFxMute()); - ConfMan.set("gfx_details", g_graphics->getRenderLevel()); + ConfMan.set("music_volume", _musicVolume[_vm->_sound->getMusicVolume()]); + ConfMan.set("speech_volume", _soundVolume[_vm->_sound->getSpeechVolume()]); + ConfMan.set("sfx_volume", _soundVolume[_vm->_sound->getFxVolume()]); + 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->_graphics->getRenderLevel()); ConfMan.set("nosubtitles", !_subtitles); ConfMan.set("object_labels", _pointerTextSelected); ConfMan.set("reverse_stereo", _stereoReversed); @@ -1399,17 +1467,17 @@ uint32 Gui::restoreControl(void) { // returns 0 for no restore // 1 for restored ok - SaveLoadDialog loadDialog(_vm, kLoadDialog); + SaveLoadDialog loadDialog(this, kLoadDialog); return loadDialog.run(); } void Gui::saveControl(void) { - SaveLoadDialog saveDialog(_vm, kSaveDialog); + SaveLoadDialog saveDialog(this, kSaveDialog); saveDialog.run(); } void Gui::quitControl(void) { - MiniDialog quitDialog(_vm->_controlsFontId, 149618692); + MiniDialog quitDialog(this, 149618692); if (quitDialog.run()) _vm->closeGame(); @@ -1418,7 +1486,7 @@ void Gui::quitControl(void) { void Gui::restartControl(void) { uint32 temp_demo_flag; - MiniDialog restartDialog(_vm->_controlsFontId, 149618693); + MiniDialog restartDialog(this, 149618693); if (!restartDialog.run()) return; @@ -1431,19 +1499,19 @@ void Gui::restartControl(void) { // In case we were dead - well we're not anymore! DEAD = 0; - g_graphics->clearScene(); + _vm->_graphics->clearScene(); // Restart the game. Clear all memory and reset the globals temp_demo_flag = DEMO; // Remove all resources from memory, including player object and // global variables - res_man->removeAll(); + _vm->_resman->removeAll(); // Reopen global variables resource & send address to interpreter - // it won't be moving - _vm->_logic->setGlobalInterpreterVariables((int32 *) (res_man->openResource(1) + sizeof(_standardHeader))); - res_man->closeResource(1); + _vm->_logic->setGlobalInterpreterVariables((int32 *) (_vm->_resman->openResource(1) + sizeof(_standardHeader))); + _vm->_resman->closeResource(1); DEMO = temp_demo_flag; @@ -1463,7 +1531,7 @@ void Gui::restartControl(void) { // fnRegisterFrame) _vm->resetMouseList(); - g_graphics->closeMenuImmediately(); + _vm->_graphics->closeMenuImmediately(); // FOR THE DEMO - FORCE THE SCROLLING TO BE RESET! // - this is taken from fnInitBackground @@ -1479,7 +1547,7 @@ void Gui::restartControl(void) { } void Gui::optionControl(void) { - OptionsDialog optionsDialog; + OptionsDialog optionsDialog(this); optionsDialog.run(); return; @@ -1491,7 +1559,7 @@ void Gui::updateGraphicsLevel(int newLevel) { else if (newLevel > 3) newLevel = 3; - g_graphics->setRenderLevel(newLevel); + _vm->_graphics->setRenderLevel(newLevel); // update our global variable - which needs to be checked when dimming // the palette in PauseGame() in sword2.cpp (since palette-matching |