aboutsummaryrefslogtreecommitdiff
path: root/engines/mads
diff options
context:
space:
mode:
authorPaul Gilbert2014-03-17 21:53:22 -0400
committerPaul Gilbert2014-03-17 21:53:22 -0400
commit0c8a3a47e28075bd559be43bde910587af35d8ab (patch)
tree70f5dee3600fd38e1919553f9e44a7b77f7a9a8e /engines/mads
parentd57d4b876e90d1d043bd171c9de46d93c9e014f4 (diff)
downloadscummvm-rg350-0c8a3a47e28075bd559be43bde910587af35d8ab.tar.gz
scummvm-rg350-0c8a3a47e28075bd559be43bde910587af35d8ab.tar.bz2
scummvm-rg350-0c8a3a47e28075bd559be43bde910587af35d8ab.zip
MADS: Transformed ImageInterEntries to be User Interface UISlots
Diffstat (limited to 'engines/mads')
-rw-r--r--engines/mads/animation.cpp8
-rw-r--r--engines/mads/game.cpp7
-rw-r--r--engines/mads/nebular/nebular_scenes2.cpp2
-rw-r--r--engines/mads/player.cpp27
-rw-r--r--engines/mads/player.h4
-rw-r--r--engines/mads/scene.cpp2
-rw-r--r--engines/mads/scene.h1
-rw-r--r--engines/mads/scene_data.cpp172
-rw-r--r--engines/mads/scene_data.h55
-rw-r--r--engines/mads/screen.cpp173
-rw-r--r--engines/mads/screen.h58
-rw-r--r--engines/mads/sequence.cpp2
-rw-r--r--engines/mads/sprites.cpp70
-rw-r--r--engines/mads/sprites.h34
-rw-r--r--engines/mads/user_interface.cpp69
-rw-r--r--engines/mads/user_interface.h29
16 files changed, 383 insertions, 330 deletions
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<DirtyArea> {
-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<DirtyArea> {
+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<SpriteAsset *>::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<SpriteAsset *> {
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<ImageInterEntry> {
-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<UISlot> {
+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