diff options
author | Paul Gilbert | 2010-03-27 10:44:38 +0000 |
---|---|---|
committer | Paul Gilbert | 2010-03-27 10:44:38 +0000 |
commit | a2de7bb0ef8118c32e6e3ad1a945a8021544c519 (patch) | |
tree | d90c6fa014f68bfd3ca73998263b08cecacf60c9 | |
parent | 38f2c1b7a4eaa3dc136c6cd3c29d2b76f223d153 (diff) | |
download | scummvm-rg350-a2de7bb0ef8118c32e6e3ad1a945a8021544c519.tar.gz scummvm-rg350-a2de7bb0ef8118c32e6e3ad1a945a8021544c519.tar.bz2 scummvm-rg350-a2de7bb0ef8118c32e6e3ad1a945a8021544c519.zip |
Added the game options dialog, along with several bugfixes to dialog display code
svn-id: r48410
-rw-r--r-- | engines/m4/globals.h | 15 | ||||
-rw-r--r-- | engines/m4/m4.cpp | 12 | ||||
-rw-r--r-- | engines/m4/mads_menus.cpp | 164 | ||||
-rw-r--r-- | engines/m4/mads_menus.h | 13 | ||||
-rw-r--r-- | engines/m4/mads_views.cpp | 9 | ||||
-rw-r--r-- | engines/m4/mads_views.h | 5 |
6 files changed, 196 insertions, 22 deletions
diff --git a/engines/m4/globals.h b/engines/m4/globals.h index 5f106a3ce7..0ff67cb79c 100644 --- a/engines/m4/globals.h +++ b/engines/m4/globals.h @@ -213,6 +213,16 @@ enum RexPlayerSex { SEX_MALE = 0, SEX_FEMALE = 2, SEX_UNKNOWN = 1}; enum MadsDialogType { DIALOG_NONE = 0, DIALOG_GAME_MENU = 1, DIALOG_SAVE = 2, DIALOG_RESTORE = 3, DIALOG_OPTIONS = 4, DIALOG_DIFFICULTY = 5, DIALOG_ERROR = 6}; +struct MadsConfigData { + bool musicFlag; + bool soundFlag; + bool easyMouse; + bool invObjectsStill; + bool textWindowStill; + int storyMode; + int screenFades; +}; + class MadsGlobals : public Globals { private: struct MessageItem { @@ -234,10 +244,7 @@ public: // MADS variables int _globals[TOTAL_NUM_VARIABLES]; - bool easyMouse; - bool invObjectsStill; - bool textWindowStill; - int storyMode; + MadsConfigData _config; bool playerSpriteChanged; MadsDialogType dialogType; int sceneNumber; diff --git a/engines/m4/m4.cpp b/engines/m4/m4.cpp index 624c83e842..01c51a5e19 100644 --- a/engines/m4/m4.cpp +++ b/engines/m4/m4.cpp @@ -524,10 +524,11 @@ Common::Error MadsEngine::run() { globs->loadMadsObjects(); // Setup globals - globs->easyMouse = true; - globs->invObjectsStill = false; - globs->textWindowStill = false; - globs->storyMode = 0; + globs->_config.easyMouse = true; + globs->_config.invObjectsStill = false; + globs->_config.textWindowStill = false; + globs->_config.storyMode = 1; // Naughty + globs->_config.screenFades = 0; // Test code to dump all messages to the console //for (int i = 0; i < _globals->getMessagesSize(); i++) @@ -600,6 +601,9 @@ void MadsEngine::showDialog() { case DIALOG_GAME_MENU: dlg = new RexGameMenuDialog(); break; + case DIALOG_OPTIONS: + dlg = new RexOptionsDialog(); + break; default: error("Unknown dialog type"); }; diff --git a/engines/m4/mads_menus.cpp b/engines/m4/mads_menus.cpp index 8bfd42b2a7..d5fb0903eb 100644 --- a/engines/m4/mads_menus.cpp +++ b/engines/m4/mads_menus.cpp @@ -746,9 +746,10 @@ bool RexDialogView::onEvent(M4EventType eventType, int32 param1, int x, int y, b } } + int objIndex = -1; if ((idx > 0) && ((eventType == MEVENT_LEFT_HOLD) || (eventType == MEVENT_LEFT_DRAG) || (eventType == MEVENT_LEFT_RELEASE))) { - int objIndex = _screenObjects[idx].index; + objIndex = _screenObjects[idx].index; if ((_dialogType == DIALOG_SAVE) || (_dialogType == DIALOG_RESTORE)) { if ((objIndex > 7) && (objIndex <= 14)) @@ -773,8 +774,8 @@ bool RexDialogView::onEvent(M4EventType eventType, int32 param1, int x, int y, b } if (eventType == MEVENT_LEFT_RELEASE) { - if (!word_7F28C || (idx <= 18)) - _selectedLine = idx; + if (!word_7F28C || (objIndex <= 18)) + _selectedLine = objIndex; word_8502A = -1; } @@ -789,7 +790,7 @@ void RexDialogView::setFrame(int frameNumber, int depth) { _spriteSlots[slotIndex].spriteListIndex = 0; //_menuSpritesIndex; _spriteSlots[slotIndex].frameNumber = frameNumber; - M4Sprite *spr = _spriteSlots.getSprite(0).getFrame(0); + M4Sprite *spr = _spriteSlots.getSprite(0).getFrame(frameNumber - 1); _spriteSlots[slotIndex].xp = spr->x; _spriteSlots[slotIndex].yp = spr->y; _spriteSlots[slotIndex].depth = depth; @@ -841,7 +842,7 @@ void RexDialogView::addLine(const char *msg_p, Font *font, MadsTextAlignment ali switch (alignment) { case ALIGN_CENTER: // Center text - rec->pos.x = (width() - font->getWidth(rec->text)) / 2; + rec->pos.x = (width() - font->getWidth(rec->text)) / 2 + left; break; case ALIGN_CHAR_CENTER: { @@ -855,7 +856,7 @@ void RexDialogView::addLine(const char *msg_p, Font *font, MadsTextAlignment ali int strWidth = font->getWidth(rec->text, rec->widthAdjust); // Remove the character from the string. strcpy isn't used here because it's unsafe for // copying within the same string - while ((*p == *(p + 1)) != '\0') ++p; + while ((*p = *(p + 1)) != '\0') ++p; rec->pos.x = (width() / 2) - strWidth; } else { @@ -958,7 +959,7 @@ void RexDialogView::refreshText() { } /*-------------------------------------------------------------------------- - * RexDialogView is the Rex Nebular Game Menu dialog + * RexGameMenuDialog is the main game dialog for the game *-------------------------------------------------------------------------- */ @@ -986,10 +987,6 @@ void RexGameMenuDialog::addLines() { } } -void RexGameMenuDialog::onRefresh(RectList *rects, M4Surface *destSurface) { - RexDialogView::onRefresh(rects, destSurface); -} - bool RexGameMenuDialog::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) { // Call the parent event handler to handle line selection bool handled = RexDialogView::onEvent(eventType, param1, x, y, captureEvents); @@ -997,11 +994,25 @@ bool RexGameMenuDialog::onEvent(M4EventType eventType, int32 param1, int x, int if (_selectedLine > 0) { switch (_selectedLine) { case 1: + // Save Game _madsVm->globals()->dialogType = DIALOG_SAVE; + break; case 2: + // Restore Game _madsVm->globals()->dialogType = DIALOG_RESTORE; + break; case 3: + // Game Play Options _madsVm->globals()->dialogType = DIALOG_OPTIONS; + break; + case 4: + // Resume Current Game + _madsVm->globals()->dialogType = DIALOG_NONE; + break; + case 5: + // Exit From Game + _madsVm->quitGame(); + break; default: // TODO: Extra logic for such as resuming scene if necessary _madsVm->globals()->dialogType = DIALOG_NONE; @@ -1015,5 +1026,136 @@ bool RexGameMenuDialog::onEvent(M4EventType eventType, int32 param1, int x, int return handled; } +/*-------------------------------------------------------------------------- + * RexOptionsDialog is the game options dialog for Rex Nebular + *-------------------------------------------------------------------------- + */ + +RexOptionsDialog::RexOptionsDialog(): RexDialogView() { + _dialogType = DIALOG_OPTIONS; + _tempConfig = _madsVm->globals()->_config; + + setFrame(2, 2); + initVars(); + + _vm->_font->setFont(FONT_CONVERSATION_MADS); + addLines(); + setClickableLines(); +} + +void RexOptionsDialog::reload() { + for (int i = 0; i < DIALOG_LINES_SIZE; ++i) + _dialogText[i].in_use = false; + _totalTextEntries = 0; + _textDisplay.clear(); + _screenObjects.clear(); + + initVars(); + + _vm->_font->setFont(FONT_CONVERSATION_MADS); + addLines(); + setClickableLines(); +} + +void RexOptionsDialog::addLines() { + // Add the title + int top = MADS_Y_OFFSET - 2 - ((((_vm->_font->getHeight() + 1) * 9 + 12) >> 1) - 78); + + addQuote(_vm->_font, ALIGN_CENTER, 0, top, 16); + + // Music state line + top += _vm->_font->getHeight() + 1 + 6; + addQuote(_vm->_font, ALIGN_CHAR_CENTER, 0, top, 17, _tempConfig.musicFlag ? 24 : 25); + + // Sound state line + top += _vm->_font->getHeight() + 1; + addQuote(_vm->_font, ALIGN_CHAR_CENTER, 0, top, 18, _tempConfig.soundFlag ? 26 : 27); + + // Interface easy state line + top += _vm->_font->getHeight() + 1; + addQuote(_vm->_font, ALIGN_CHAR_CENTER, 0, top, 19, _tempConfig.easyMouse ? 29 : 28); + + // Inventory sppinng state line + top += _vm->_font->getHeight() + 1; + addQuote(_vm->_font, ALIGN_CHAR_CENTER, 0, top, 20, _tempConfig.invObjectsStill ? 31 : 30); + + // Text window state line + top += _vm->_font->getHeight() + 1; + addQuote(_vm->_font, ALIGN_CHAR_CENTER, 0, top, 21, _tempConfig.textWindowStill ? 33 : 32); + + // Screen fade state line + top += _vm->_font->getHeight() + 1; + addQuote(_vm->_font, ALIGN_CHAR_CENTER, 0, top, 22, _tempConfig.screenFades + 34); + + // Storyline mode line + top += _vm->_font->getHeight() + 1; + addQuote(_vm->_font, ALIGN_CHAR_CENTER, 0, top, 23, (_tempConfig.storyMode == 1) ? 37 : 38); + + // Add Done and Cancel button texts + top += _vm->_font->getHeight() + 1 + 6; + addQuote(_vm->_font, ALIGN_CENTER, -54, top, 1, 0); + addQuote(_vm->_font, ALIGN_CENTER, 54, top, 2, 0); +} + +bool RexOptionsDialog::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) { + // Call the parent event handler to handle line selection + bool handled = RexDialogView::onEvent(eventType, param1, x, y, captureEvents); + + if (_selectedLine > 0) { + switch (_selectedLine) { + case 0: + // Enter or Escape + _selectedLine = _enterFlag ? 8 : 9; + return true; + case 1: + // Music line + _tempConfig.musicFlag = !_tempConfig.musicFlag; + break; + case 2: + // Sound line + _tempConfig.soundFlag = !_tempConfig.soundFlag; + break; + case 3: + // Interface line + _tempConfig.easyMouse = !_tempConfig.easyMouse; + break; + case 4: + // Inventory line + _tempConfig.invObjectsStill = !_tempConfig.invObjectsStill; + break; + case 5: + // Text window line + _tempConfig.textWindowStill = !_tempConfig.textWindowStill; + break; + case 6: + // Screen fades line + if (++_tempConfig.screenFades > 2) + _tempConfig.screenFades = 0; + break; + case 7: + // Story mode line + if (_tempConfig.storyMode == 2) + _tempConfig.storyMode = 1; + else if (_tempConfig.storyMode == 1) + _tempConfig.storyMode = 2; + break; + case 8: + case 9: + // Done and Cancel buttons + // TODO: Proper re-loading of settings if Cancel button clicked + _madsVm->globals()->_config = _tempConfig; + + // Closing the dialog, so return to the game menu + _madsVm->globals()->dialogType = DIALOG_GAME_MENU; + _madsVm->_viewManager->deleteView(this); + return true; + } + + // Update the option selections + reload(); + } + + return handled; +} } diff --git a/engines/m4/mads_menus.h b/engines/m4/mads_menus.h index 3ef49cd6ee..278e07e3fd 100644 --- a/engines/m4/mads_menus.h +++ b/engines/m4/mads_menus.h @@ -158,7 +158,18 @@ private: public: RexGameMenuDialog(); - virtual void onRefresh(RectList *rects, M4Surface *destSurface); + virtual bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents); +}; + +class RexOptionsDialog : public RexDialogView { +private: + MadsConfigData _tempConfig; + + void reload(); + void addLines(); +public: + RexOptionsDialog(); + virtual bool onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents); }; diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp index 423784384c..e8a5aa6f4f 100644 --- a/engines/m4/mads_views.cpp +++ b/engines/m4/mads_views.cpp @@ -131,6 +131,11 @@ MadsTextDisplay::MadsTextDisplay() { } } +void MadsTextDisplay::clear() { + for (int i = 0; i < TEXT_DISPLAY_SIZE; ++i) + _entries[i].active = false; +} + int MadsTextDisplay::add(int xp, int yp, uint fontColour, int charSpacing, const char *msg, Font *font) { int usedSlot = -1; @@ -433,8 +438,8 @@ void MadsInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) { M4Sprite *spr = _objectSprites->getFrame(_objectFrameNumber / INV_ANIM_FRAME_SPEED); spr->copyTo(destSurface, INVENTORY_X, INVENTORY_Y, 0); - if (!_madsVm->globals()->invObjectsStill && !dialogVisible) { - // If objetcs are to animated, move to the next frame + if (!_madsVm->globals()->_config.invObjectsStill && !dialogVisible) { + // If objects need to be animated, move to the next frame if (++_objectFrameNumber >= (_objectSprites->getCount() * INV_ANIM_FRAME_SPEED)) _objectFrameNumber = 0; } diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h index 294eb3bd1a..8cd2024180 100644 --- a/engines/m4/mads_views.h +++ b/engines/m4/mads_views.h @@ -77,6 +77,10 @@ public: int getIndex(); void addSprites(const char *resName); + void clear() { + startIndex = 0; + _sprites.clear(); + } void draw(View *view); }; @@ -114,6 +118,7 @@ public: } int add(int xp, int yp, uint fontColour, int charSpacing, const char *msg, Font *font); + void clear(); void draw(View *view); }; |