diff options
author | Paul Gilbert | 2010-03-24 11:49:26 +0000 |
---|---|---|
committer | Paul Gilbert | 2010-03-24 11:49:26 +0000 |
commit | cf5cd833fde2765668aea3b8f234388da3f9f94d (patch) | |
tree | 725cdaa1ff530f6f412b4c98cfba6dee5a9e8615 /engines/m4 | |
parent | d34fd9cdd667dea9ce11bf4aa9028b3e91caf19a (diff) | |
download | scummvm-rg350-cf5cd833fde2765668aea3b8f234388da3f9f94d.tar.gz scummvm-rg350-cf5cd833fde2765668aea3b8f234388da3f9f94d.tar.bz2 scummvm-rg350-cf5cd833fde2765668aea3b8f234388da3f9f94d.zip |
Moved new MadsView related code into Mads_Views, where it's more appropriate. Added extra logic necessary for displaying text in the game dialogs
svn-id: r48378
Diffstat (limited to 'engines/m4')
-rw-r--r-- | engines/m4/mads_menus.cpp | 113 | ||||
-rw-r--r-- | engines/m4/mads_menus.h | 32 | ||||
-rw-r--r-- | engines/m4/mads_views.cpp | 130 | ||||
-rw-r--r-- | engines/m4/mads_views.h | 100 | ||||
-rw-r--r-- | engines/m4/viewmgr.cpp | 66 | ||||
-rw-r--r-- | engines/m4/viewmgr.h | 65 |
6 files changed, 360 insertions, 146 deletions
diff --git a/engines/m4/mads_menus.cpp b/engines/m4/mads_menus.cpp index c9cd1b129a..8b34d2c139 100644 --- a/engines/m4/mads_menus.cpp +++ b/engines/m4/mads_menus.cpp @@ -701,7 +701,10 @@ void RexDialogView::onRefresh(RectList *rects, M4Surface *destSurface) { // Add in the loaded background vertically centred _backgroundSurface->copyTo(this, 0, (height() - MADS_SURFACE_HEIGHT) / 2); - View::onRefresh(rects, destSurface); + // Check whether any of the dialog text entries need to be refreshed + refreshText(); + + MadsView::onRefresh(rects, destSurface); } void RexDialogView::setFrame(int frameNumber, int depth) { @@ -753,7 +756,7 @@ void RexDialogView::addLine(const char *msg_p, Font *font, MadsTextAlignment ali if (rec) { strcpy(rec->text, msg_p); rec->font = font; - rec->field_2 = 0; + rec->state = 0; rec->pos.y = top; rec->widthAdjust = -1; rec->in_use = true; @@ -819,6 +822,65 @@ void RexDialogView::addQuote(Font *font, MadsTextAlignment alignment, int left, addLine(buffer, font, alignment, left, top); } +/** + * Sets any previously created dialog text entries as clickable items + */ +void RexDialogView::setClickableLines() { + _screenObjects.clear(); + + for (int i = 0; i < DIALOG_LINES_SIZE; ++i) { + if (_dialogText[i].in_use) { + // Add an entry for the line + _screenObjects.add(Common::Rect(_dialogText[i].pos.x, _dialogText[i].pos.y, + _dialogText[i].pos.x + _dialogText[i].font->getWidth(_dialogText[i].text, _dialogText[i].widthAdjust), + _dialogText[i].pos.y + _dialogText[i].font->getHeight()), 19, i, 1); + } + } + + if ((_madsVm->globals()->dialogType == DIALOG_SAVE) || (_madsVm->globals()->dialogType == DIALOG_RESTORE)) { + // Extra entries for the scroller areas of the Save and Restor dialogs + _screenObjects.add(Common::Rect(293, 26, 312, 75), LAYER_GUI, 50, 2); + _screenObjects.add(Common::Rect(293, 78, 312, 127), LAYER_GUI, 51, 2); + } +} + +/** + * Handles creating text display objects for each dialog line initially, and when the selected state + * of any entry changes + */ +void RexDialogView::refreshText() { + for (uint i = 0; i < _dialogText.size(); ++i) { + if (!_dialogText[i].in_use) + continue; + + // Get the item's colours + uint colour; + if (_dialogText[i].state == STATE_DESELECTED) + colour = 0xB0A; + else if (_dialogText[i].state == STATE_HIGHLIGHTED) + colour = 0xD0C; + else + colour = 0xF0E; + + // If there's an associated text display entry, check to see if it's colour needs to change + if (_dialogText[i].textDisplay_index >= 0) { + MadsTextDisplayEntry &tdEntry = _textDisplay[_dialogText[i].textDisplay_index]; + + if ((tdEntry.colour1 == (colour & 0xff)) && (tdEntry.colour2 == (colour >> 8))) + // It's still the same, so no further action needed + continue; + + // Flag the currently assigned text display to be expired, so it can be re-created + _textDisplay.expire(_dialogText[i].textDisplay_index); + _dialogText[i].textDisplay_index = -1; + } + + // Create a new text display entry for the dialog text line + _dialogText[i].textDisplay_index = _textDisplay.add(_dialogText[i].pos.x, _dialogText[i].pos.y, + colour, _dialogText[i].widthAdjust, _dialogText[i].text, _dialogText[i].font); + } +} + /*-------------------------------------------------------------------------- * RexDialogView is the Rex Nebular Game Menu dialog *-------------------------------------------------------------------------- @@ -830,11 +892,13 @@ RexGameMenuDialog::RexGameMenuDialog(): RexDialogView() { _vm->_font->setFont(FONT_CONVERSATION_MADS); addLines(); + setClickableLines(); } void RexGameMenuDialog::addLines() { // Add the title - int top = -((_vm->_font->getHeight() + 1) * 12 - 78); + int top = (height() - MADS_SURFACE_HEIGHT) / 2 + -((((_vm->_font->getHeight() + 2) * 6) >> 1) - 78); + addQuote(_vm->_font, ALIGN_CENTER, 0, top, 10); // Loop for adding the option lines of the dialog @@ -849,4 +913,47 @@ void RexGameMenuDialog::onRefresh(RectList *rects, M4Surface *destSurface) { RexDialogView::onRefresh(rects, destSurface); } +bool RexGameMenuDialog::onEvent(M4EventType eventType, int32 param1, int x, int y, bool &captureEvents) { + bool handled = false; + + // Handle various event types + switch (eventType) { + case MEVENT_LEFT_CLICK: + // Left mouse click + // TODO: Check and figure out _selectedLine + handled = true; + break; + + case KEVENT_KEY: + // Handle standard dialog keypresses + + handled = true; + break; + + default: + break; + } + + if (_selectedLine > 0) { + switch (_selectedLine) { + case 1: + _madsVm->globals()->dialogType = DIALOG_SAVE; + case 2: + _madsVm->globals()->dialogType = DIALOG_RESTORE; + case 3: + _madsVm->globals()->dialogType = DIALOG_OPTIONS; + default: + // TODO: Extra logic for such as resuming scene if necessary + _madsVm->globals()->dialogType = DIALOG_NONE; + break; + } + + // Close this dialog + _madsVm->_viewManager->deleteView(this); + } + + return handled; +} + + } diff --git a/engines/m4/mads_menus.h b/engines/m4/mads_menus.h index 5d3258ab46..d732723fcf 100644 --- a/engines/m4/mads_menus.h +++ b/engines/m4/mads_menus.h @@ -28,6 +28,7 @@ #include "common/str-array.h" #include "m4/viewmgr.h" +#include "m4/mads_views.h" #include "m4/font.h" namespace M4 { @@ -36,6 +37,8 @@ namespace M4 { enum MadsGameAction {START_GAME, RESUME_GAME, SHOW_INTRO, CREDITS, QUOTES, EXIT}; +enum MadsLayers {LAYER_GUI = 19}; + class RexMainMenuView : public View { private: M4Surface *_bgSurface; @@ -88,10 +91,12 @@ public: void updateState(); }; +enum DialogTextState {STATE_DESELECTED = 0, STATE_HIGHLIGHTED = 1, STATE_SELECTED = 2}; + class DialogTextEntry { public: bool in_use; - int16 field_2; + int state; Common::Point pos; char text[80]; Font *font; @@ -116,26 +121,28 @@ private: void loadBackground(); void loadMenuSprites(); protected: - int _word_8502C; - int _selectedLine; - int _lineIndex; - bool _enterFlag; - Common::StringArray _textLines; - - void setFrame(int frameNumber, int depth); - void initVars(); - void addLine(const char *msg_p, Font *font, MadsTextAlignment alignment, int left, int top); - void addQuote(Font *font, MadsTextAlignment alignment, int left, int top, int id1, int id2 = 0); -protected: M4Surface *_backgroundSurface; RGBList *_bgPalData; SpriteAsset *_menuSprites; RGBList *_spritesPalData; Common::Array<DialogTextEntry> _dialogText; + Common::StringArray _textLines; int _totalTextEntries; int _dialogSelectedLine; Common::StringArray _saveList; + + int _word_8502C; + int _selectedLine; + int _lineIndex; + bool _enterFlag; + + void setFrame(int frameNumber, int depth); + void initVars(); + void addLine(const char *msg_p, Font *font, MadsTextAlignment alignment, int left, int top); + void addQuote(Font *font, MadsTextAlignment alignment, int left, int top, int id1, int id2 = 0); + void setClickableLines(); + void refreshText(); public: RexDialogView(); ~RexDialogView(); @@ -151,6 +158,7 @@ public: RexGameMenuDialog(); virtual void onRefresh(RectList *rects, M4Surface *destSurface); + 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 7aff856792..8b17a935f2 100644 --- a/engines/m4/mads_views.cpp +++ b/engines/m4/mads_views.cpp @@ -39,6 +39,136 @@ static const int INVENTORY_X = 160; static const int INVENTORY_Y = 159; static const int SCROLLER_DELAY = 200; +//-------------------------------------------------------------------------- + +MadsTextDisplay::MadsTextDisplay() { + for (int i = 0; i < TEXT_DISPLAY_SIZE; ++i) { + MadsTextDisplayEntry rec; + rec.active = false; + _entries.push_back(rec); + } +} + +int MadsTextDisplay::add(int xp, int yp, uint fontColour, int charSpacing, const char *msg, Font *font) { + int usedSlot = -1; + + for (int idx = 0; idx < TEXT_DISPLAY_SIZE; ++idx) { + if (!_entries[idx].active) { + usedSlot = idx; + + _entries[idx].bounds.left = xp; + _entries[idx].bounds.top = yp; + _entries[idx].font = font; + _entries[idx].msg = msg; + _entries[idx].bounds.setWidth(font->getWidth(msg, charSpacing)); + _entries[idx].bounds.setHeight(font->getHeight()); + _entries[idx].colour1 = fontColour & 0xff; + _entries[idx].colour2 = fontColour >> 8; + _entries[idx].spacing = charSpacing; + _entries[idx].expire = 1; + _entries[idx].active = true; + break; + } + } + + return usedSlot; +} + +void MadsTextDisplay::draw(View *view) { + for (uint idx = 0; idx < _entries.size(); ++idx) { + if (_entries[idx].active && (_entries[idx].expire >= 0)) { + _entries[idx].font->setColours(_entries[idx].colour1, 0xFF, + (_entries[idx].colour2 == 0) ? _entries[idx].colour1 : _entries[idx].colour2); + _entries[idx].font->writeString(view, _entries[idx].msg, + _entries[idx].bounds.left, _entries[idx].bounds.top, _entries[idx].bounds.width(), + _entries[idx].spacing); + } + } + + // Clear up any now text display entries that are to be expired + for (uint idx = 0; idx < _entries.size(); ++idx) { + if (_entries[idx].expire < 0) { + _entries[idx].active = false; + _entries[idx].expire = 0; + } + } +} + +//-------------------------------------------------------------------------- + +/** + * Clears the entries list + */ +void ScreenObjects::clear() { + _entries.clear(); +} + +/** + * Adds a new entry to the list of screen objects + */ +void ScreenObjects::add(const Common::Rect &bounds, int layer, int idx, int category) { + ScreenObjectEntry rec; + rec.bounds = bounds; + rec.layer = layer; + rec.index = idx; + rec.category = category; + rec.active = true; + + _entries.push_back(rec); +} + +/** + * Scans the list for an element that contains the given mode. The result will be 1 based for a match, + * with 0 indicating no entry was found + */ +int ScreenObjects::scan(int xp, int yp, int layer) { + for (uint i = 0; i < _entries.size(); ++i) { + if (_entries[i].active && _entries[i].bounds.contains(xp, yp) && (_entries[i].layer == layer)) + return i + 1; + } + + // Entry not found + return 0; +} + +int ScreenObjects::scanBackwards(int xp, int yp, int layer) { + for (uint i = _entries.size() - 1; i >= 0; --i) { + if (_entries[i].active && _entries[i].bounds.contains(xp, yp) && (_entries[i].layer == layer)) + return i + 1; + } + + // Entry not found + return 0; +} + +void ScreenObjects::setActive(int category, int idx, bool active) { + for (uint i = 0; i < _entries.size(); ++i) { + if (_entries[i].active && (_entries[i].category == category) && (_entries[i].index == idx)) + _entries[i].active = active; + } +} + +//-------------------------------------------------------------------------- + +MadsView::MadsView(MadsM4Engine *vm, const Common::Rect &viewBounds, bool transparent): View(vm, viewBounds, transparent) { + _spriteSlotsStart = 0; +} + +MadsView::MadsView(MadsM4Engine *vm, int x, int y, bool transparent): View(vm, x, y, transparent) { + _spriteSlotsStart = 0; +} + +int MadsView::getSpriteSlotsIndex() { + return _spriteSlotsStart++; +} + +void MadsView::onRefresh(RectList *rects, M4Surface *destSurface) { + // Draw text elements onto the view + _textDisplay.draw(this); + + View::onRefresh(rects, destSurface); +} + /*-------------------------------------------------------------------------- * MadsInterfaceView handles the user interface section at the bottom of * game screens in MADS games diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h index 4a80671ddc..98219e04bb 100644 --- a/engines/m4/mads_views.h +++ b/engines/m4/mads_views.h @@ -34,6 +34,106 @@ namespace M4 { +class MadsSpriteSlot { +public: + int spriteId; + int timerIndex; + int spriteListIndex; + int frameNumber; + int width; + int height; + int depth; + int scale; + + MadsSpriteSlot() { }; +}; + +#define SPRITE_SLOTS_SIZE 50 + +class MadsTextDisplayEntry { +public: + bool active; + int expire; + int spacing; + Common::Rect bounds; + uint8 colour1; + uint8 colour2; + Font *font; + const char *msg; + + MadsTextDisplayEntry() { active = false; } +}; + +#define TEXT_DISPLAY_SIZE 40 + +class MadsTextDisplay { +private: + Common::Array<MadsTextDisplayEntry> _entries; +public: + MadsTextDisplay(); + + MadsTextDisplayEntry &operator[](int idx) { + assert(idx < TEXT_DISPLAY_SIZE); + return _entries[idx]; + } + + void expire(int idx) { + assert(idx < TEXT_DISPLAY_SIZE); + _entries[idx].expire = -1; + } + + int add(int xp, int yp, uint fontColour, int charSpacing, const char *msg, Font *font); + void draw(View *view); +}; + +class ScreenObjectEntry { +public: + Common::Rect bounds; + int category; + int index; + int layer; + bool active; + + ScreenObjectEntry() { active = false; } +}; + +#define SCREEN_OBJECTS_SIZE + +class ScreenObjects { +private: + Common::Array<ScreenObjectEntry> _entries; +public: + ScreenObjects() {} + + ScreenObjectEntry &operator[](uint idx) { + assert(idx < _entries.size()); + return _entries[idx]; + } + + void clear(); + void add(const Common::Rect &bounds, int layer, int idx, int category); + void draw(View *view); + int scan(int xp, int yp, int layer); + int scanBackwards(int xp, int yp, int layer); + void setActive(int category, int idx, bool active); +}; + + +class MadsView: public View { +protected: + MadsSpriteSlot _spriteSlots[SPRITE_SLOTS_SIZE]; + MadsTextDisplay _textDisplay; + int _spriteSlotsStart; + ScreenObjects _screenObjects; + + int getSpriteSlotsIndex(); +public: + MadsView(MadsM4Engine *vm, const Common::Rect &viewBounds, bool transparent = false); + MadsView(MadsM4Engine *vm, int x = 0, int y = 0, bool transparent = false); + + void onRefresh(RectList *rects, M4Surface *destSurface); +}; + #define CHEAT_SEQUENCE_MAX 8 class IntegerList : public Common::Array<int> { diff --git a/engines/m4/viewmgr.cpp b/engines/m4/viewmgr.cpp index a1e9c3e584..46b4b5af9d 100644 --- a/engines/m4/viewmgr.cpp +++ b/engines/m4/viewmgr.cpp @@ -194,72 +194,6 @@ void View::onRefresh(RectList *rects, M4Surface *destSurface) { //-------------------------------------------------------------------------- -MadsTextDisplay::MadsTextDisplay() { - 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; - - for (int idx = 0; idx < TEXT_DISPLAY_SIZE; ++idx) { - if (!_entries[idx].active) { - usedSlot = idx; - - _entries[idx].bounds.left = xp; - _entries[idx].bounds.top = yp; - _entries[idx].font = font; - _entries[idx].msg = msg; - _entries[idx].bounds.setWidth(font->getWidth(msg, charSpacing)); - _entries[idx].bounds.setHeight(font->getHeight()); - _entries[idx].colour1 = fontColour & 0xff; - _entries[idx].colour2 = fontColour >> 8; - _entries[idx].spacing = charSpacing; - _entries[idx].active2 = 1; - _entries[idx].active = true; - break; - } - } - - return usedSlot; -} - -void MadsTextDisplay::draw(View *view) { - for (int idx = 0; idx < OLD_TEXT_DISPLAY_SIZE; ++idx) { - if (_entries[idx].active && (_entries[idx].active2 >= 0)) { - _entries[idx].font->setColours(_entries[idx].colour1, 0xFF, - (_entries[idx].colour2 == 0) ? _entries[idx].colour1 : _entries[idx].colour2); - _entries[idx].font->writeString(view, _entries[idx].msg, - _entries[idx].bounds.left, _entries[idx].bounds.top, _entries[idx].bounds.width(), - _entries[idx].spacing); - } - } - - // Clear up any now inactive text display entries - for (int idx = 0; idx < OLD_TEXT_DISPLAY_SIZE; ++idx) { - if (_entries[idx].active2 < 0) { - _entries[idx].active = false; - _entries[idx].active2 = 0; - } - } -} - -//-------------------------------------------------------------------------- - -MadsView::MadsView(MadsM4Engine *vm, const Common::Rect &viewBounds, bool transparent): View(vm, viewBounds, transparent) { - _spriteSlotsStart = 0; -} - -MadsView::MadsView(MadsM4Engine *vm, int x, int y, bool transparent): View(vm, x, y, transparent) { - _spriteSlotsStart = 0; -} - -int MadsView::getSpriteSlotsIndex() { - return _spriteSlotsStart++; -} - -//-------------------------------------------------------------------------- - ViewManager::ViewManager(MadsM4Engine *vm): _systemHotkeys(HotkeyList(NULL)), _vm(vm) { _captureScreen = NULL; _captureEvents = false; diff --git a/engines/m4/viewmgr.h b/engines/m4/viewmgr.h index 308240645d..16c3d6ecc3 100644 --- a/engines/m4/viewmgr.h +++ b/engines/m4/viewmgr.h @@ -148,71 +148,6 @@ protected: bool _transparent; }; -class MadsSpriteSlot { -public: - int spriteId; - int timerIndex; - int spriteListIndex; - int frameNumber; - int width; - int height; - int depth; - int scale; - - MadsSpriteSlot() { }; -}; - -#define SPRITE_SLOTS_SIZE 50 - -class MadsTextDisplayEntry { -public: - bool active; - int spacing; - Common::Rect bounds; - int active2; - uint8 colour1; - uint8 colour2; - Font *font; - const char *msg; - - MadsTextDisplayEntry() { active = false; } -}; - -#define TEXT_DISPLAY_SIZE 40 - -class MadsTextDisplay { -private: - MadsTextDisplayEntry _entries[TEXT_DISPLAY_SIZE]; -public: - MadsTextDisplay(); - - MadsTextDisplayEntry &operator[](int idx) { - assert(idx < TEXT_DISPLAY_SIZE); - return _entries[idx]; - } - - int setActive2(int idx) { - assert(idx < TEXT_DISPLAY_SIZE); - _entries[idx].active2 = -1; - } - - int add(int xp, int yp, uint fontColour, int charSpacing, const char *msg, Font *font); - void draw(View *view); -}; - -class MadsView: public View { -protected: - MadsSpriteSlot _spriteSlots[SPRITE_SLOTS_SIZE]; - MadsTextDisplay _textDisplay; - int _spriteSlotsStart; - - int getSpriteSlotsIndex(); -public: - MadsView(MadsM4Engine *vm, const Common::Rect &viewBounds, bool transparent = false); - MadsView(MadsM4Engine *vm, int x = 0, int y = 0, bool transparent = false); - -}; - class ViewManager { private: MadsM4Engine *_vm; |