From 0c8a3a47e28075bd559be43bde910587af35d8ab Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Mon, 17 Mar 2014 21:53:22 -0400 Subject: MADS: Transformed ImageInterEntries to be User Interface UISlots --- engines/mads/animation.cpp | 8 +- engines/mads/game.cpp | 7 +- engines/mads/nebular/nebular_scenes2.cpp | 2 +- engines/mads/player.cpp | 27 ++--- engines/mads/player.h | 4 +- engines/mads/scene.cpp | 2 +- engines/mads/scene.h | 1 - engines/mads/scene_data.cpp | 172 +----------------------------- engines/mads/scene_data.h | 55 ---------- engines/mads/screen.cpp | 173 +++++++++++++++++++++++++++++++ engines/mads/screen.h | 58 +++++++++++ engines/mads/sequence.cpp | 2 +- engines/mads/sprites.cpp | 70 ++++--------- engines/mads/sprites.h | 34 ++---- engines/mads/user_interface.cpp | 69 ++++++++++-- engines/mads/user_interface.h | 29 ++++++ 16 files changed, 383 insertions(+), 330 deletions(-) (limited to 'engines/mads') diff --git a/engines/mads/animation.cpp b/engines/mads/animation.cpp index 783611e3da..b0b69b946a 100644 --- a/engines/mads/animation.cpp +++ b/engines/mads/animation.cpp @@ -403,7 +403,7 @@ void Animation::update() { for (uint idx = 0; idx < scene._spriteSlots.size(); ++idx) { if (scene._spriteSlots[idx]._seqIndex >= 0x80) - scene._spriteSlots[idx]._spriteType = ST_EXPIRED; + scene._spriteSlots[idx]._SlotType = ST_EXPIRED; } // Validate the current frame @@ -445,7 +445,7 @@ void Animation::update() { if (paChanged) { newIndex = scene._spriteSlots.add(); scene._spriteSlots[newIndex]._seqIndex = -1; - scene._spriteSlots[newIndex]._spriteType = ST_FULL_SCREEN_REFRESH; + scene._spriteSlots[newIndex]._SlotType = ST_FULL_SCREEN_REFRESH; } // Main frame animation loop - frames get animated by being placed, as necessary, into the @@ -463,7 +463,7 @@ void Animation::update() { int seqIndex = _frameEntries[_oldFrameEntry]._seqIndex - scene._spriteSlots[index]._seqIndex; if (seqIndex == 0x80) { if (scene._spriteSlots[index] == _frameEntries[_oldFrameEntry]._spriteSlot) { - scene._spriteSlots[index]._spriteType = ST_NONE; + scene._spriteSlots[index]._SlotType = ST_NONE; spriteSlotIndex = -1; } } @@ -479,7 +479,7 @@ void Animation::update() { SpriteAsset &spriteSet = *scene._sprites[ scene._spriteSlots[slotIndex]._spritesIndex]; - slot._spriteType = spriteSet.isBackground() ? ST_BACKGROUND : ST_FOREGROUND; + slot._SlotType = spriteSet.isBackground() ? ST_BACKGROUND : ST_FOREGROUND; } break; } diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp index 3778e834ed..e65330a5d4 100644 --- a/engines/mads/game.cpp +++ b/engines/mads/game.cpp @@ -235,7 +235,12 @@ void Game::sectionLoop() { _player._priorTimer = _scene._frameStartTime + _player._ticksAmount; _player.idle(); - warning("TODO: _selectedObject IF block"); + if (_scene._userInterface._selectedInvIndex >= 0) { + _scene._userInterface.loadInventoryAnim( + _objects._inventoryList[_scene._userInterface._selectedInvIndex]); + } else { + _scene._userInterface.noInventoryAnim(); + } _v1 = 5; _scene._roomChanged = false; diff --git a/engines/mads/nebular/nebular_scenes2.cpp b/engines/mads/nebular/nebular_scenes2.cpp index d3284cc649..63c03dc5c8 100644 --- a/engines/mads/nebular/nebular_scenes2.cpp +++ b/engines/mads/nebular/nebular_scenes2.cpp @@ -197,7 +197,7 @@ void Scene201::enter() { _scene->_sequences.addSubEntry(_globals._spriteIndexes[21], SM_FRAME_INDEX, 12, 70); _scene->_sequences.setDepth(_globals._spriteIndexes[21], 1); _globals._frameTime = 0; - _game._player.sub7E53C(Common::Point(157, 143), 8); + _game._player.startWalking(Common::Point(157, 143), 8); _vm->_palette->setEntry(252, 45, 63, 45); _vm->_palette->setEntry(253, 20, 45, 20); _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 2, 0, 120, _game.getQuote(90)); diff --git a/engines/mads/player.cpp b/engines/mads/player.cpp index 44dfc88ede..80343609b9 100644 --- a/engines/mads/player.cpp +++ b/engines/mads/player.cpp @@ -246,7 +246,7 @@ void Player::update() { if (_forceRefresh || (_visible != _priorVisible)) { int slotIndex = getSpriteSlot(); if (slotIndex >= 0) - scene._spriteSlots[slotIndex]._spriteType = ST_EXPIRED; + scene._spriteSlots[slotIndex]._SlotType = ST_EXPIRED; int newDepth = 1; int yp = MAX(_playerPos.y, (int16)(MADS_SCENE_HEIGHT - 1)); @@ -264,7 +264,7 @@ void Player::update() { if (_visible) { // Player sprite needs to be rendered SpriteSlot slot; - slot._spriteType = ST_FOREGROUND; + slot._SlotType = ST_FOREGROUND; slot._seqIndex = PLAYER_SEQ_INDEX; slot._spritesIndex = _spritesStart + _spritesIdx; slot._frameNumber = _frameOffset + _frameNum; @@ -285,7 +285,7 @@ void Player::update() { if (equal) // Undo the prior expiry of the player sprite - s2._spriteType = ST_NONE; + s2._SlotType = ST_NONE; else slotIndex = -1; } @@ -359,6 +359,16 @@ void Player::setDest(const Common::Point &pt, int facing) { } } +void Player::startWalking(const Common::Point &pos, int direction) { + Scene &scene = _vm->_game->_scene; + + reset(); + scene._action._startWalkFlag = true; + scene._action._walkFlag = true; + scene._destPos = pos; + scene._destFacing = direction; +} + void Player::nextFrame() { Scene &scene = _vm->_game->_scene; @@ -528,7 +538,7 @@ int Player::getSpriteSlot() { for (uint idx = 0; idx < spriteSlots.size(); ++idx) { if (spriteSlots[idx]._seqIndex == PLAYER_SEQ_INDEX && - spriteSlots[idx]._spriteType >= ST_NONE) + spriteSlots[idx]._SlotType >= ST_NONE) return idx; } @@ -737,13 +747,4 @@ void Player::startMovement() { _v8452E = -_v84530; } -void Player::sub7E53C(Common::Point pos, int direction) { - Scene &scene = _vm->_game->_scene; - - reset(); - scene._action._startWalkFlag = true; - scene._action._walkFlag = true; - scene._destPos = pos; - scene._destFacing = direction; -} } // End of namespace MADS diff --git a/engines/mads/player.h b/engines/mads/player.h index ed44de2c20..e330c650de 100644 --- a/engines/mads/player.h +++ b/engines/mads/player.h @@ -152,9 +152,9 @@ public: void setDest(const Common::Point &pt, int facing); - void nextFrame(); + void startWalking(const Common::Point &pos, int direction); - void sub7E53C(Common::Point pos, int direction); + void nextFrame(); }; } // End of namespace MADS diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp index 88533a9ffd..ed5fca5f6e 100644 --- a/engines/mads/scene.cpp +++ b/engines/mads/scene.cpp @@ -379,7 +379,7 @@ void Scene::doFrame() { _kernelMessages.update(); } - _imageInterEntries.call(_vm->_game->_abortTimers2 == kTransitionFadeIn ? 0xff : 0, + _userInterface._uiSlots.call(_vm->_game->_abortTimers2 == kTransitionFadeIn ? 0xff : 0, _vm->_game->_abortTimers2); // Write any text needed by the interface diff --git a/engines/mads/scene.h b/engines/mads/scene.h index 3a94754dd2..f5163bb43d 100644 --- a/engines/mads/scene.h +++ b/engines/mads/scene.h @@ -90,7 +90,6 @@ public: int _textSpacing; Hotspots _hotspots; ScreenObjects _screenObjects; - ImageInterEntries _imageInterEntries; DirtyAreas _dirtyAreas; int _v1; SceneInfo *_sceneInfo; diff --git a/engines/mads/scene_data.cpp b/engines/mads/scene_data.cpp index c37f0b1f74..8980bd4428 100644 --- a/engines/mads/scene_data.cpp +++ b/engines/mads/scene_data.cpp @@ -136,173 +136,11 @@ void ScreenObjects::proc1() { /*------------------------------------------------------------------------*/ -MADSEngine *DirtyArea::_vm = nullptr; - -DirtyArea::DirtyArea() { - _active = false; - _textActive = false; -} - -void DirtyArea::setArea(int width, int height, int maxWidth, int maxHeight) { - if (_bounds.left % 2) { - --_bounds.left; - ++width; - } - - if (_bounds.left < 0) - _bounds.left = 0; - else if (_bounds.left > maxWidth) - _bounds.left = maxWidth; - int right = _bounds.left + width; - if (right < 0) - right = 0; - if (right > maxWidth) - right = maxWidth; - - _bounds.right = right; - _bounds2.left = _bounds.width() / 2; - _bounds2.right = _bounds.left + (_bounds.width() + 1) / 2 - 1; - - if (_bounds.top < 0) - _bounds.top = 0; - else if (_bounds.top > maxHeight) - _bounds.top = maxHeight; - int bottom = _bounds.top + height; - if (bottom < 0) - bottom = 0; - if (bottom > maxHeight) - bottom = maxHeight; - - _bounds.bottom = bottom; - _bounds2.top = _bounds.height() / 2; - _bounds2.bottom = _bounds.top + (_bounds.height() + 1) / 2 - 1; - - _active = true; -} - - -void DirtyArea::setSpriteSlot(const SpriteSlot *spriteSlot) { - int width, height; - Scene &scene = _vm->_game->_scene; - - if (spriteSlot->_spriteType == ST_FULL_SCREEN_REFRESH) { - // Special entry to refresh the entire screen - _bounds.left = 0; - _bounds.top = 0; - width = MADS_SCREEN_WIDTH; - height = MADS_SCENE_HEIGHT; - } else { - // Standard sprite slots - _bounds.left = spriteSlot->_position.x - scene._posAdjust.x; - _bounds.top = spriteSlot->_position.y - scene._posAdjust.y; - - SpriteAsset &spriteSet = *scene._sprites[spriteSlot->_spritesIndex]; - MSprite *frame = spriteSet.getFrame(((spriteSlot->_frameNumber & 0x7fff) - 1) & 0x7f); - - if (spriteSlot->_scale == -1) { - width = frame->w; - height = frame->h; - } else { - width = frame->w * spriteSlot->_scale / 100; - height = frame->h * spriteSlot->_scale / 100; - - _bounds.left -= width / 2; - _bounds.top += -(height - 1); - } - } - - setArea(width, height, MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT); -} - -void DirtyArea::setTextDisplay(const TextDisplay *textDisplay) { - _bounds.left = textDisplay->_bounds.left; - _bounds.top = textDisplay->_bounds.top; - - setArea(textDisplay->_bounds.width(), textDisplay->_bounds.height(), - MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT); -} - -/*------------------------------------------------------------------------*/ - -DirtyAreas::DirtyAreas(MADSEngine *vm) : _vm(vm) { - DirtyArea::_vm = vm; - - for (int i = 0; i < DIRTY_AREAS_SIZE; ++i) { - DirtyArea rec; - rec._active = false; - push_back(rec); - } -} - -void DirtyAreas::merge(int startIndex, int count) { - if (startIndex >= count) - return; - - for (int outerCtr = startIndex - 1, idx = 0; idx < count; ++outerCtr, ++idx) { - if (!(*this)[outerCtr]._active) - continue; - - for (int innerCtr = outerCtr + 1; innerCtr < count; ++innerCtr) { - if (!(*this)[innerCtr]._active || !intersects(outerCtr, innerCtr)) - continue; - - if ((*this)[outerCtr]._textActive && (*this)[innerCtr]._textActive) - mergeAreas(outerCtr, innerCtr); - } - } -} - -/** -* Returns true if two dirty areas intersect -*/ -bool DirtyAreas::intersects(int idx1, int idx2) { - return (*this)[idx1]._bounds2.intersects((*this)[idx2]._bounds2); -} - -void DirtyAreas::mergeAreas(int idx1, int idx2) { - DirtyArea &da1 = (*this)[idx1]; - DirtyArea &da2 = (*this)[idx2]; - - da1._bounds.extend(da2._bounds); - - da1._bounds2.left = da1._bounds.width() / 2; - da1._bounds2.right = da1._bounds.left + (da1._bounds.width() + 1) / 2 - 1; - da1._bounds2.top = da1._bounds.height() / 2; - da1._bounds2.bottom = da1._bounds.top + (da1._bounds.height() + 1) / 2 - 1; - - da2._active = false; - da1._textActive = true; -} - -void DirtyAreas::copy(MSurface *srcSurface, MSurface *destSurface, const Common::Point &posAdjust) { - for (uint i = 0; i < size(); ++i) { - const Common::Rect &srcBounds = (*this)[i]._bounds; - - Common::Rect bounds(srcBounds.left + posAdjust.x, srcBounds.top + posAdjust.y, - srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y); - - if ((*this)[i]._active && bounds.isValidRect()) { - srcSurface->copyTo(destSurface, bounds, Common::Point(bounds.left, bounds.top)); - } - } -} - -void DirtyAreas::copyToScreen(const Common::Point &posAdjust) { - for (uint i = 0; i < size(); ++i) { - const Common::Rect &srcBounds = (*this)[i]._bounds; - - Common::Rect bounds(srcBounds.left + posAdjust.x, srcBounds.top + posAdjust.y, - srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y); - - if ((*this)[i]._active && (*this)[i]._bounds.isValidRect()) { - _vm->_screen.copyRectToScreen(bounds); - } - } -} - -void DirtyAreas::reset() { - for (uint i = 0; i < size(); ++i) - (*this)[i]._active = false; +void SceneNode::load(Common::SeekableReadStream *f) { + _walkPos.x = f->readSint16LE(); + _walkPos.y = f->readSint16LE(); + for (int i = 0; i < MAX_ROUTE_NODES; ++i) + _indexes[i] = f->readUint16LE(); } /*------------------------------------------------------------------------*/ diff --git a/engines/mads/scene_data.h b/engines/mads/scene_data.h index f2893c5fe1..1543669f7f 100644 --- a/engines/mads/scene_data.h +++ b/engines/mads/scene_data.h @@ -108,61 +108,6 @@ public: void check(bool scanFlag); }; -class DirtyArea { -private: - static MADSEngine *_vm; - friend class DirtyAreas; -public: - Common::Rect _bounds; - Common::Rect _bounds2; - bool _textActive; - bool _active; - - DirtyArea(); - - void setArea(int width, int height, int maxWidth, int maxHeight); - - void setSpriteSlot(const SpriteSlot *spriteSlot); - - /** - * Set up a dirty area for a text display - */ - void setTextDisplay(const TextDisplay *textDisplay); -}; - -class DirtyAreas: public Common::Array { -private: - MADSEngine *_vm; -public: - DirtyAreas(MADSEngine *vm); - - /** - * Merge together any designated dirty areas that overlap - * @param startIndex 1-based starting dirty area starting index - * @param count Number of entries to process - */ - void merge(int startIndex, int count); - - bool intersects(int idx1, int idx2); - void mergeAreas(int idx1, int idx2); - - /** - * Copy the data specified by the dirty rect list between surfaces - * @param srcSurface Source surface - * @param destSurface Dest surface - * @param posAdjust Position adjustment - */ - void copy(MSurface *srcSurface, MSurface *destSurface, const Common::Point &posAdjust); - - /** - * Use the lsit of dirty areas to copy areas of the screen surface to - * the physical screen - * @param posAdjust Position adjustment */ - void copyToScreen(const Common::Point &posAdjust); - - void reset(); -}; - class SceneLogic { protected: MADSEngine *_vm; diff --git a/engines/mads/screen.cpp b/engines/mads/screen.cpp index 20ff4f6df2..e760aa465d 100644 --- a/engines/mads/screen.cpp +++ b/engines/mads/screen.cpp @@ -28,6 +28,179 @@ namespace MADS { +MADSEngine *DirtyArea::_vm = nullptr; + +DirtyArea::DirtyArea() { + _active = false; + _textActive = false; +} + +void DirtyArea::setArea(int width, int height, int maxWidth, int maxHeight) { + if (_bounds.left % 2) { + --_bounds.left; + ++width; + } + + if (_bounds.left < 0) + _bounds.left = 0; + else if (_bounds.left > maxWidth) + _bounds.left = maxWidth; + int right = _bounds.left + width; + if (right < 0) + right = 0; + if (right > maxWidth) + right = maxWidth; + + _bounds.right = right; + _bounds2.left = _bounds.width() / 2; + _bounds2.right = _bounds.left + (_bounds.width() + 1) / 2 - 1; + + if (_bounds.top < 0) + _bounds.top = 0; + else if (_bounds.top > maxHeight) + _bounds.top = maxHeight; + int bottom = _bounds.top + height; + if (bottom < 0) + bottom = 0; + if (bottom > maxHeight) + bottom = maxHeight; + + _bounds.bottom = bottom; + _bounds2.top = _bounds.height() / 2; + _bounds2.bottom = _bounds.top + (_bounds.height() + 1) / 2 - 1; + + _active = true; +} + + +void DirtyArea::setSpriteSlot(const SpriteSlot *spriteSlot) { + int width, height; + Scene &scene = _vm->_game->_scene; + + if (spriteSlot->_SlotType == ST_FULL_SCREEN_REFRESH) { + // Special entry to refresh the entire screen + _bounds.left = 0; + _bounds.top = 0; + width = MADS_SCREEN_WIDTH; + height = MADS_SCENE_HEIGHT; + } + else { + // Standard sprite slots + _bounds.left = spriteSlot->_position.x - scene._posAdjust.x; + _bounds.top = spriteSlot->_position.y - scene._posAdjust.y; + + SpriteAsset &spriteSet = *scene._sprites[spriteSlot->_spritesIndex]; + MSprite *frame = spriteSet.getFrame(((spriteSlot->_frameNumber & 0x7fff) - 1) & 0x7f); + + if (spriteSlot->_scale == -1) { + width = frame->w; + height = frame->h; + } + else { + width = frame->w * spriteSlot->_scale / 100; + height = frame->h * spriteSlot->_scale / 100; + + _bounds.left -= width / 2; + _bounds.top += -(height - 1); + } + } + + setArea(width, height, MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT); +} + +void DirtyArea::setTextDisplay(const TextDisplay *textDisplay) { + _bounds.left = textDisplay->_bounds.left; + _bounds.top = textDisplay->_bounds.top; + + setArea(textDisplay->_bounds.width(), textDisplay->_bounds.height(), + MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT); +} + +/*------------------------------------------------------------------------*/ + +DirtyAreas::DirtyAreas(MADSEngine *vm) : _vm(vm) { + DirtyArea::_vm = vm; + + for (int i = 0; i < DIRTY_AREAS_SIZE; ++i) { + DirtyArea rec; + rec._active = false; + push_back(rec); + } +} + +void DirtyAreas::merge(int startIndex, int count) { + if (startIndex >= count) + return; + + for (int outerCtr = startIndex - 1, idx = 0; idx < count; ++outerCtr, ++idx) { + if (!(*this)[outerCtr]._active) + continue; + + for (int innerCtr = outerCtr + 1; innerCtr < count; ++innerCtr) { + if (!(*this)[innerCtr]._active || !intersects(outerCtr, innerCtr)) + continue; + + if ((*this)[outerCtr]._textActive && (*this)[innerCtr]._textActive) + mergeAreas(outerCtr, innerCtr); + } + } +} + +/** +* Returns true if two dirty areas intersect +*/ +bool DirtyAreas::intersects(int idx1, int idx2) { + return (*this)[idx1]._bounds2.intersects((*this)[idx2]._bounds2); +} + +void DirtyAreas::mergeAreas(int idx1, int idx2) { + DirtyArea &da1 = (*this)[idx1]; + DirtyArea &da2 = (*this)[idx2]; + + da1._bounds.extend(da2._bounds); + + da1._bounds2.left = da1._bounds.width() / 2; + da1._bounds2.right = da1._bounds.left + (da1._bounds.width() + 1) / 2 - 1; + da1._bounds2.top = da1._bounds.height() / 2; + da1._bounds2.bottom = da1._bounds.top + (da1._bounds.height() + 1) / 2 - 1; + + da2._active = false; + da1._textActive = true; +} + +void DirtyAreas::copy(MSurface *srcSurface, MSurface *destSurface, const Common::Point &posAdjust) { + for (uint i = 0; i < size(); ++i) { + const Common::Rect &srcBounds = (*this)[i]._bounds; + + Common::Rect bounds(srcBounds.left + posAdjust.x, srcBounds.top + posAdjust.y, + srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y); + + if ((*this)[i]._active && bounds.isValidRect()) { + srcSurface->copyTo(destSurface, bounds, Common::Point(bounds.left, bounds.top)); + } + } +} + +void DirtyAreas::copyToScreen(const Common::Point &posAdjust) { + for (uint i = 0; i < size(); ++i) { + const Common::Rect &srcBounds = (*this)[i]._bounds; + + Common::Rect bounds(srcBounds.left + posAdjust.x, srcBounds.top + posAdjust.y, + srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y); + + if ((*this)[i]._active && (*this)[i]._bounds.isValidRect()) { + _vm->_screen.copyRectToScreen(bounds); + } + } +} + +void DirtyAreas::reset() { + for (uint i = 0; i < size(); ++i) + (*this)[i]._active = false; +} + +/*------------------------------------------------------------------------*/ + ScreenSurface::ScreenSurface() { _dataP = nullptr; } diff --git a/engines/mads/screen.h b/engines/mads/screen.h index e101020fc8..2860462ff1 100644 --- a/engines/mads/screen.h +++ b/engines/mads/screen.h @@ -45,6 +45,64 @@ enum ScreenTransition { kVertTransition7, kCenterVertTransition }; +class SpriteSlot; +class TextDisplay; + +class DirtyArea { +private: + static MADSEngine *_vm; + friend class DirtyAreas; +public: + Common::Rect _bounds; + Common::Rect _bounds2; + bool _textActive; + bool _active; + + DirtyArea(); + + void setArea(int width, int height, int maxWidth, int maxHeight); + + void setSpriteSlot(const SpriteSlot *spriteSlot); + + /** + * Set up a dirty area for a text display + */ + void setTextDisplay(const TextDisplay *textDisplay); +}; + +class DirtyAreas : public Common::Array { +private: + MADSEngine *_vm; +public: + DirtyAreas(MADSEngine *vm); + + /** + * Merge together any designated dirty areas that overlap + * @param startIndex 1-based starting dirty area starting index + * @param count Number of entries to process + */ + void merge(int startIndex, int count); + + bool intersects(int idx1, int idx2); + void mergeAreas(int idx1, int idx2); + + /** + * Copy the data specified by the dirty rect list between surfaces + * @param srcSurface Source surface + * @param destSurface Dest surface + * @param posAdjust Position adjustment + */ + void copy(MSurface *srcSurface, MSurface *destSurface, const Common::Point &posAdjust); + + /** + * Use the lsit of dirty areas to copy areas of the screen surface to + * the physical screen + * @param posAdjust Position adjustment */ + void copyToScreen(const Common::Point &posAdjust); + + void reset(); +}; + class ScreenSurface : public MSurface { private: /** diff --git a/engines/mads/sequence.cpp b/engines/mads/sequence.cpp index 6418a03477..684e4996bc 100644 --- a/engines/mads/sequence.cpp +++ b/engines/mads/sequence.cpp @@ -178,7 +178,7 @@ void SequenceList::setSpriteSlot(int seqIndex, SpriteSlot &spriteSlot) { SequenceEntry &timerEntry = _entries[seqIndex]; SpriteAsset &spriteSet = *scene._sprites[timerEntry._spritesIndex]; - spriteSlot._spriteType = spriteSet.isBackground() ? ST_BACKGROUND : ST_FOREGROUND; + spriteSlot._SlotType = spriteSet.isBackground() ? ST_BACKGROUND : ST_FOREGROUND; spriteSlot._seqIndex = seqIndex; spriteSlot._spritesIndex = timerEntry._spritesIndex; spriteSlot._frameNumber = (timerEntry._flipped ? 0x8000 : 0) | timerEntry._frameIndex; diff --git a/engines/mads/sprites.cpp b/engines/mads/sprites.cpp index be066ba2db..18f6a642fd 100644 --- a/engines/mads/sprites.cpp +++ b/engines/mads/sprites.cpp @@ -139,7 +139,7 @@ byte MSprite::getTransparencyIndex() const { MADSEngine *SpriteSlot::_vm = nullptr; SpriteSlot::SpriteSlot() { - _spriteType = ST_NONE; + _SlotType = ST_NONE; _seqIndex = 0; _spritesIndex = 0; _frameNumber = 0; @@ -147,8 +147,8 @@ SpriteSlot::SpriteSlot() { _scale = 0; } -SpriteSlot::SpriteSlot(SpriteType type, int seqIndex) { - _spriteType = type; +SpriteSlot::SpriteSlot(SlotType type, int seqIndex) { + _SlotType = type; _seqIndex = seqIndex; _spritesIndex = 0; _frameNumber = 0; @@ -208,11 +208,11 @@ void SpriteSlots::setDirtyAreas() { Scene &scene = _vm->_game->_scene; for (uint i = 0; i < size(); ++i) { - if ((*this)[i]._spriteType >= ST_NONE) { + if ((*this)[i]._SlotType >= ST_NONE) { scene._dirtyAreas[i].setSpriteSlot(&(*this)[i]); - scene._dirtyAreas[i]._textActive = ((*this)[i]._spriteType <= ST_NONE) ? 0 : 1; - (*this)[i]._spriteType = ST_NONE; + scene._dirtyAreas[i]._textActive = ((*this)[i]._SlotType <= ST_NONE) ? 0 : 1; + (*this)[i]._SlotType = ST_NONE; } } } @@ -247,14 +247,14 @@ void SpriteSlots::drawBackground() { SpriteSlot &spriteSlot = (*this)[i]; DirtyArea &dirtyArea = scene._dirtyAreas[i]; - if (spriteSlot._spriteType >= ST_NONE) { + if (spriteSlot._SlotType >= ST_NONE) { // Foreground sprite, so we can ignore it dirtyArea._active = false; } else { dirtyArea._active = true; dirtyArea.setSpriteSlot(&spriteSlot); - if (spriteSlot._spriteType == ST_BACKGROUND) { + if (spriteSlot._SlotType == ST_BACKGROUND) { // Background object, so need to draw it assert(spriteSlot._frameNumber > 0); SpriteAsset *asset = scene._sprites[spriteSlot._spritesIndex]; @@ -304,7 +304,7 @@ void SpriteSlots::drawForeground(MSurface *s) { // Get a list of sprite object depths for active objects for (uint i = 0; i < size(); ++i) { SpriteSlot &spriteSlot = (*this)[i]; - if (spriteSlot._spriteType >= ST_NONE) { + if (spriteSlot._SlotType >= ST_NONE) { DepthEntry rec(16 - spriteSlot._depth, i); depthList.push_back(rec); } @@ -367,7 +367,7 @@ void SpriteSlots::drawForeground(MSurface *s) { void SpriteSlots::cleanUp() { for (int i = (int)size() - 1; i >= 0; --i) { - if ((*this)[i]._spriteType < ST_NONE) + if ((*this)[i]._SlotType < ST_NONE) remove_at(i); } } @@ -391,6 +391,7 @@ int SpriteSets::add(SpriteAsset *asset, int idx) { } int SpriteSets::addSprites(const Common::String &resName, int flags) { + ++_assetCount; return add(new SpriteAsset(_vm, resName, flags)); } @@ -398,52 +399,17 @@ void SpriteSets::clear() { for (uint i = 0; i < size(); ++i) delete (*this)[i]; + _assetCount = 0; Common::Array::clear(); } -/*------------------------------------------------------------------------*/ - -ImageInterEntry::ImageInterEntry() { - _field0 = 0; - _field2 = 0; - _field3 = 0; - _field4 = 0; - _field6 = 0; - _field8 = 0; -} - -/*------------------------------------------------------------------------*/ - -void ImageInterEntries::add(int v1, int v2) { - ImageInterEntry ie; - ie._field0 = -2; - ie._field2 = -1; - - push_back(ie); -} +void SpriteSets::remove(int idx) { + if (idx >= 0) { + delete (*this)[idx]; + (*this)[idx] = nullptr; -void ImageInterEntries::add(int v1, int v2, int v3, int v4) { - assert(size() < 50); - - ImageInterEntry ie; - ie._field0 = -3; - ie._field2 = 201; - ie._field6 = v1; - ie._field8 = v2; - ie._field4 = v3; - ie._field3 = v4; - - push_back(ie); -} - -ImageInterEntry &ImageInterEntries::add() { - resize(size() + 1); - return (*this)[size() - 1]; -} - - -void ImageInterEntries::call(int v1, int v2) { - debug("TODO: ImageInterEntries::call"); + --_assetCount; + } } } // End of namespace MADS diff --git a/engines/mads/sprites.h b/engines/mads/sprites.h index 82f0a9b10d..cf45be6806 100644 --- a/engines/mads/sprites.h +++ b/engines/mads/sprites.h @@ -30,7 +30,7 @@ namespace MADS { -enum SpriteType { +enum SlotType { ST_NONE = 0, ST_FOREGROUND = 1, ST_BACKGROUND = -4, ST_FULL_SCREEN_REFRESH = -2, ST_EXPIRED = -1 }; @@ -129,11 +129,11 @@ private: static MADSEngine *_vm; friend class SpriteSlots; public: - SpriteType _spriteType; + SlotType _SlotType; int _seqIndex; public: SpriteSlot(); - SpriteSlot(SpriteType type, int seqIndex); + SpriteSlot(SlotType type, int seqIndex); void setup(int dirtyAreaIndex); bool operator==(const SpriteSlotSubset &other) const; @@ -200,10 +200,12 @@ class SpriteSets : public Common::Array { private: MADSEngine *_vm; public: + int _assetCount; + /** * Constructor */ - SpriteSets(MADSEngine *vm) : _vm(vm) {} + SpriteSets(MADSEngine *vm) : _vm(vm), _assetCount(0) {} /** * Destructor @@ -224,27 +226,11 @@ public: * Adds a sprite asset to the list by name */ int addSprites(const Common::String &resName, int flags = 0); -}; - -class ImageInterEntry { -public: - int _field0; - int _field2; - int _field3; - int _field4; - int _field6; - int _field8; - - ImageInterEntry(); -}; -class ImageInterEntries: public Common::Array { -public: - void add(int v1, int v2); - void add(int v1, int v2, int v3, int v4); - ImageInterEntry &add(); - - void call(int v1, int v2); + /** + * Remove an asset from the list + */ + void remove(int idx); }; } // End of namespace MADS diff --git a/engines/mads/user_interface.cpp b/engines/mads/user_interface.cpp index 5ab0b0f356..fd9f4c0153 100644 --- a/engines/mads/user_interface.cpp +++ b/engines/mads/user_interface.cpp @@ -27,16 +27,47 @@ namespace MADS { -void SceneNode::load(Common::SeekableReadStream *f) { - _walkPos.x = f->readSint16LE(); - _walkPos.y = f->readSint16LE(); - for (int i = 0; i < MAX_ROUTE_NODES; ++i) - _indexes[i] = f->readUint16LE(); +UISlot::UISlot() { + _slotType = ST_NONE; + _field2 = 0; + _field3 = 0; + _field4 = 0; + _field6 = 0; + _field8 = 0; +} + +/*------------------------------------------------------------------------*/ + +void UISlots::fullRefresh() { + UISlot slot; + slot._slotType = ST_FULL_SCREEN_REFRESH; + slot._field2 = -1; + + push_back(slot); +} + +void UISlots::add(int v1, int v2, int v3, int v4) { + assert(size() < 50); + + UISlot ie; + ie._slotType = -3; + ie._field2 = 201; + ie._field6 = v1; + ie._field8 = v2; + ie._field4 = v3; + ie._field3 = v4; + + push_back(ie); +} + +void UISlots::call(int v1, int v2) { + debug("TODO: UISlots::call"); } /*------------------------------------------------------------------------*/ UserInterface::UserInterface(MADSEngine *vm) : _vm(vm) { + _invSpritesIndex = -1; _category = CAT_NONE; _screenObjectsCount = 0; _inventoryTopIndex = 0; @@ -99,8 +130,8 @@ void UserInterface::setup(int id) { } scene._screenObjects._v832EC = id; - scene._imageInterEntries.clear(); - scene._imageInterEntries.add(-2, 0xff); + scene._userInterface._uiSlots.clear(); + scene._userInterface._uiSlots.fullRefresh(); _vm->_game->_ticksExpiry = _vm->_events->getFrameCounter(); _v1A = -1; _v1E = -1; @@ -110,7 +141,7 @@ void UserInterface::setup(int id) { copyTo(&_surface); if (_vm->_game->_v1 == 5) - scene._imageInterEntries.call(0, 0); + scene._userInterface._uiSlots.call(0, 0); scene._action.clear(); drawTextElements(); @@ -400,5 +431,27 @@ void UserInterface::drawTalkList() { warning("TODO: drawTalkList"); } +void UserInterface::loadInventoryAnim(int objectId) { + +} + +void UserInterface::noInventoryAnim() { + Scene &scene = _vm->_game->_scene; + + if (_invSpritesIndex >= 0) { + scene._sprites.remove(_invSpritesIndex); + _vm->_game->_ticksExpiry = _vm->_events->getFrameCounter(); + _invSpritesIndex = -1; + } + + if (!scene._screenObjects._v832EC) + refresh(); +} + +void UserInterface::refresh() { + Scene &scene = _vm->_game->_scene; + scene._userInterface._uiSlots.clear(); +// scene._userInterface._uiSlots.new() +} } // End of namespace MADS diff --git a/engines/mads/user_interface.h b/engines/mads/user_interface.h index cab26534c4..65c7e1ce55 100644 --- a/engines/mads/user_interface.h +++ b/engines/mads/user_interface.h @@ -36,9 +36,31 @@ enum ScrCategory { CAT_12 = 12 }; +class UISlot { +public: + int _slotType; + int _field2; + int _field3; + int _field4; + int _field6; + int _field8; + + UISlot(); +}; + +class UISlots : public Common::Array { +public: + void add(int v1, int v2, int v3, int v4); + void fullRefresh(); + + void call(int v1, int v2); +}; + + class UserInterface : public MSurface { private: MADSEngine *_vm; + int _invSpritesIndex; /** * Loads the elements of the user interface @@ -84,6 +106,8 @@ private: * Draw a UI textual element */ void writeVocab(ScrCategory category, int id); + + void refresh(); public: ScrCategory _category; int _screenObjectsCount; @@ -99,6 +123,7 @@ public: int _v1A; int _v1C; int _v1E; + UISlots _uiSlots; public: /** * Constructor @@ -120,6 +145,10 @@ public: void drawTextElements(); void setBounds(const Common::Rect &r); + + void loadInventoryAnim(int objectId); + + void noInventoryAnim(); }; } // End of namespace MADS -- cgit v1.2.3