aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2010-03-27 10:44:38 +0000
committerPaul Gilbert2010-03-27 10:44:38 +0000
commita2de7bb0ef8118c32e6e3ad1a945a8021544c519 (patch)
treed90c6fa014f68bfd3ca73998263b08cecacf60c9
parent38f2c1b7a4eaa3dc136c6cd3c29d2b76f223d153 (diff)
downloadscummvm-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.h15
-rw-r--r--engines/m4/m4.cpp12
-rw-r--r--engines/m4/mads_menus.cpp164
-rw-r--r--engines/m4/mads_menus.h13
-rw-r--r--engines/m4/mads_views.cpp9
-rw-r--r--engines/m4/mads_views.h5
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);
};