aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/mads/font.cpp19
-rw-r--r--engines/mads/hotspots.cpp36
-rw-r--r--engines/mads/hotspots.h11
-rw-r--r--engines/mads/scene.cpp4
-rw-r--r--engines/mads/scene_data.cpp25
-rw-r--r--engines/mads/screen.cpp58
-rw-r--r--engines/mads/screen.h18
-rw-r--r--engines/mads/user_interface.cpp2
8 files changed, 112 insertions, 61 deletions
diff --git a/engines/mads/font.cpp b/engines/mads/font.cpp
index ed7542d2e5..e3497b3b14 100644
--- a/engines/mads/font.cpp
+++ b/engines/mads/font.cpp
@@ -136,13 +136,14 @@ void Font::setColorMode(int mode) {
int Font::writeString(MSurface *surface, const Common::String &msg, const Common::Point &pt,
int spaceWidth, int width) {
+ int xEnd;
if (width > 0)
- width = MIN((int)surface->w, pt.x + width);
+ xEnd = MIN((int)surface->w, pt.x + width);
else
- width = surface->w - pt.x;
+ xEnd = surface->w - pt.x;
- int x = pt.x + 1;
- int y = pt.y + 1;
+ int x = pt.x;
+ int y = pt.y;
int skipY = 0;
if (y < 0) {
@@ -174,7 +175,7 @@ int Font::writeString(MSurface *surface, const Common::String &msg, const Common
if (charWidth > 0) {
- if (xPos + charWidth >= width)
+ if (xPos + charWidth > xEnd)
return xPos;
uint8 *charData = &_charData[_charOffs[(byte)theChar]];
@@ -221,8 +222,12 @@ int Font::getWidth(const Common::String &msg, int spaceWidth) {
int width = 0;
const char *text = msg.c_str();
- while (*text)
- width += _charWidths[*text++ & 0x7F] + spaceWidth;
+ if (msg.size() > 0) {
+ while (*text)
+ width += _charWidths[*text++ & 0x7F] + spaceWidth;
+ width -= spaceWidth;
+ }
+
return width;
}
diff --git a/engines/mads/hotspots.cpp b/engines/mads/hotspots.cpp
index 4356e787d6..e082a1e3ce 100644
--- a/engines/mads/hotspots.cpp
+++ b/engines/mads/hotspots.cpp
@@ -146,8 +146,40 @@ void DynamicHotspots::refresh() {
/*------------------------------------------------------------------------*/
-void Hotspots::activate(int hotspotId, bool active) {
- warning("TODO: Hotspots::activate");
+Hotspot::Hotspot() {
+ _facing = 0;
+ _articleNumber = 0;
+ _cursor = CURSOR_NONE;
+ _vocabId = 0;
+ _verbId = 0;
+ _active = false;
+}
+
+Hotspot::Hotspot(Common::SeekableReadStream &f) {
+ _bounds.left = f.readSint16LE();
+ _bounds.top = f.readSint16LE();
+ _bounds.right = f.readSint16LE();
+ _bounds.bottom = f.readSint16LE();
+ _feetPos.x = f.readSint16LE();
+ _feetPos.y = f.readSint16LE();
+ _facing = f.readByte();
+ _articleNumber = f.readByte();
+ _active = f.readByte() != 0;
+ _cursor = (CursorType)f.readByte();
+ _vocabId = f.readUint16LE();
+ _verbId = f.readUint16LE();
+}
+
+/*------------------------------------------------------------------------*/
+
+void Hotspots::activate(int vocabId, bool active) {
+ for (uint idx = 0; idx < size(); ++idx) {
+ Hotspot &hotspot = (*this)[idx];
+ if (hotspot._vocabId == vocabId) {
+ hotspot._active = active;
+ _vm->_game->_screenObjects.setActive(CAT_HOTSPOT, idx, active);
+ }
+ }
}
} // End of namespace MADS
diff --git a/engines/mads/hotspots.h b/engines/mads/hotspots.h
index ed18fbf252..a53b86d880 100644
--- a/engines/mads/hotspots.h
+++ b/engines/mads/hotspots.h
@@ -30,7 +30,6 @@ namespace MADS {
class MADSEngine;
-
class DynamicHotspot {
public:
bool _active;
@@ -74,6 +73,7 @@ public:
Common::Point _feetPos;
int _facing;
int _articleNumber;
+ bool _active;
CursorType _cursor;
int _vocabId;
int _verbId;
@@ -83,8 +83,15 @@ public:
};
class Hotspots : public Common::Array<Hotspot> {
+private:
+ MADSEngine *_vm;
public:
- void activate(int hotspotId, bool active);
+ Hotspots(MADSEngine *vm) : _vm(vm) {}
+
+ /**
+ * Sets the active state of a given hotspot
+ */
+ void activate(int vocabId, bool active);
};
} // End of namespace MADS
diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp
index e357f8b1ad..da64def95d 100644
--- a/engines/mads/scene.cpp
+++ b/engines/mads/scene.cpp
@@ -29,8 +29,8 @@
namespace MADS {
Scene::Scene(MADSEngine *vm): _vm(vm), _action(_vm), _depthSurface(vm),
- _dirtyAreas(_vm), _dynamicHotspots(vm), _kernelMessages(vm),
- _sequences(vm), _sprites(vm), _spriteSlots(vm),
+ _dirtyAreas(_vm), _dynamicHotspots(vm), _hotspots(vm),
+ _kernelMessages(vm), _sequences(vm), _sprites(vm), _spriteSlots(vm),
_textDisplay(vm), _userInterface(vm) {
_priorSceneId = 0;
_nextSceneId = 0;
diff --git a/engines/mads/scene_data.cpp b/engines/mads/scene_data.cpp
index a1f273459c..712d065fb9 100644
--- a/engines/mads/scene_data.cpp
+++ b/engines/mads/scene_data.cpp
@@ -58,31 +58,6 @@ KernelMessage::KernelMessage() {
/*------------------------------------------------------------------------*/
-Hotspot::Hotspot() {
- _facing = 0;
- _articleNumber = 0;
- _cursor = CURSOR_NONE;
- _vocabId = 0;
- _verbId = 0;
-}
-
-Hotspot::Hotspot(Common::SeekableReadStream &f) {
- _bounds.left = f.readSint16LE();
- _bounds.top = f.readSint16LE();
- _bounds.right = f.readSint16LE();
- _bounds.bottom = f.readSint16LE();
- _feetPos.x = f.readSint16LE();
- _feetPos.y = f.readSint16LE();
- _facing = f.readByte();
- _articleNumber = f.readByte();
- f.skip(1);
- _cursor = (CursorType)f.readByte();
- _vocabId = f.readUint16LE();
- _verbId = f.readUint16LE();
-}
-
-/*------------------------------------------------------------------------*/
-
void ARTHeader::load(Common::SeekableReadStream *f) {
// Read in dimensions of image
_width = f->readUint16LE();
diff --git a/engines/mads/screen.cpp b/engines/mads/screen.cpp
index d191f49f14..22896e011b 100644
--- a/engines/mads/screen.cpp
+++ b/engines/mads/screen.cpp
@@ -276,6 +276,7 @@ void ScreenObjects::add(const Common::Rect &bounds, Layer layer, ScrCategory cat
so._category = category;
so._descId = descId;
so._layer = layer;
+ so._active = true;
push_back(so);
}
@@ -361,9 +362,10 @@ void ScreenObjects::check(bool scanFlag) {
}
int ScreenObjects::scanBackwards(const Common::Point &pt, int layer) {
- for (int i = (int)size() - 1; i >= 0; --i) {
- if ((*this)[i]._bounds.contains(pt) && ((*this)[i]._layer == layer))
- return i + 1;
+ for (int i = (int)size(); i >= 1; --i) {
+ ScreenObject &sObj = (*this)[i];
+ if (sObj._active && sObj._bounds.contains(pt) && sObj._layer == layer)
+ return i;
}
// Entry not found
@@ -462,7 +464,7 @@ void ScreenObjects::elementHighlighted() {
int uiCount;
switch (userInterface._category) {
- case CAT_INV_LIST:
+ case CAT_ACTION:
index = 10;
indexEnd = 9;
varA = 5;
@@ -475,7 +477,7 @@ void ScreenObjects::elementHighlighted() {
var4 = _released && !_v7FECA ? 1 : 0;
break;
- case CAT_INV_VOCAB:
+ case CAT_INV_LIST:
userInterface.scrollInventory();
index = MIN((int)invList.size() - userInterface._inventoryTopIndex, 5);
@@ -486,7 +488,7 @@ void ScreenObjects::elementHighlighted() {
var4 = (!_released || (_vm->_events->_mouseButtons && action._v83338 == 1)) ? 0 : 1;
break;
- case CAT_HOTSPOT:
+ case CAT_INV_VOCAB:
if (userInterface._selectedInvIndex >= 0) {
InventoryObject &invObject = _vm->_game->_objects.getItem(
userInterface._selectedInvIndex);
@@ -506,7 +508,7 @@ void ScreenObjects::elementHighlighted() {
var4 = _released && !_v7FECA ? 1 : 0;
break;
- case CAT_TALK_ENTRY:
+ case CAT_INV_ANIM:
index = 1;
indexEnd = invList.size() - 1;
varA = 0;
@@ -515,17 +517,7 @@ void ScreenObjects::elementHighlighted() {
var4 = -1;
break;
- case CAT_INV_SCROLLER:
- uiCount = size() - _uiCount;
- index = scene._hotspots.size();
- indexEnd = index - 1;
- varA = 0;
- topIndex = 0;
- var6 = &var8;
- var4 = -1;
- break;
-
- default:
+ case CAT_TALK_ENTRY:
index = 0;
for (int idx = 0; idx < 5; ++idx) {
if (!userInterface._talkStrings[idx].empty())
@@ -538,6 +530,16 @@ void ScreenObjects::elementHighlighted() {
var6 = &userInterface._v1A;
var4 = -1;
break;
+
+ default:
+ uiCount = size() - _uiCount;
+ index = scene._hotspots.size();
+ indexEnd = index - 1;
+ varA = 0;
+ topIndex = 0;
+ var6 = &var8;
+ var4 = -1;
+ break;
}
int newIndex = -1;
@@ -548,15 +550,19 @@ void ScreenObjects::elementHighlighted() {
for (int idx = 0; idx < index && newIndex < 0; ++idx) {
int scrObjIndex = (_category == CAT_HOTSPOT) ? catIndex - idx + index - 1 :
catIndex + idx;
-
+
ScreenObject &scrObject = (*this)[scrObjIndex];
- Common::Rect bounds = scrObject._bounds;
+ if (!scrObject._active)
+ continue;
+
+ const Common::Rect &bounds = scrObject._bounds;
newY = MAX((int)bounds.bottom, newY);
newX = MAX((int)bounds.left, newX);
- if (currentPos.y > newY && currentPos.y < bounds.bottom) {
+ if (currentPos.y >= bounds.top && currentPos.y < bounds.bottom) {
if (var4) {
- if (currentPos.x > newX && currentPos.x < bounds.right) {
+ if (currentPos.x >= bounds.left && currentPos.x < bounds.right) {
+ // Cursor is inside hotspot bounds
newIndex = scrObjIndex - catIndex;
if (_category == CAT_HOTSPOT && newIndex < (int)scene._hotspots.size())
newIndex = scene._hotspots.size() - newIndex - 1;
@@ -602,6 +608,14 @@ void ScreenObjects::elementHighlighted() {
userInterface.drawInventory(_category, newIndex, var6);
}
+void ScreenObjects::setActive(ScrCategory category, int descId, bool active) {
+ for (uint idx = 1; idx < size(); ++idx) {
+ ScreenObject &sObj = (*this)[idx];
+ if (sObj._category == category && sObj._descId == descId)
+ sObj._active = active;
+ }
+}
+
/*------------------------------------------------------------------------*/
ScreenSurface::ScreenSurface() {
diff --git a/engines/mads/screen.h b/engines/mads/screen.h
index 1d1e6d34f0..7fa5722e18 100644
--- a/engines/mads/screen.h
+++ b/engines/mads/screen.h
@@ -125,6 +125,7 @@ public:
class ScreenObject {
public:
+ bool _active;
Common::Rect _bounds;
ScrCategory _category;
int _descId;
@@ -179,6 +180,23 @@ public:
* Handle element being highlighted on the screen
*/
void elementHighlighted();
+
+ /**
+ * Retrieve a ScreenObject from the list
+ * @remarks This array is 1-based indexed by the game
+ */
+ ScreenObject &operator[](int idx) {
+ assert(idx > 0);
+ return Common::Array<ScreenObject>::operator[](idx - 1);
+ }
+
+ /**
+ * Sets an item identified by category and Desc Id as active or not
+ * @param category Screen category
+ * @param descId Description for item
+ * @param active Whether to set item as active or not
+ */
+ void setActive(ScrCategory category, int descId, bool active);
};
class ScreenSurface : public MSurface {
diff --git a/engines/mads/user_interface.cpp b/engines/mads/user_interface.cpp
index cae5c116d2..4a35d24ad0 100644
--- a/engines/mads/user_interface.cpp
+++ b/engines/mads/user_interface.cpp
@@ -447,7 +447,7 @@ void UserInterface::loadElements() {
}
if (!_vm->_game->_screenObjects._v832EC || _vm->_game->_screenObjects._v832EC == 2) {
- _categoryIndexes[CAT_HOTSPOT - 1] = _vm->_game->_screenObjects.size();
+ _categoryIndexes[CAT_HOTSPOT - 1] = _vm->_game->_screenObjects.size() + 1;
for (int hotspotIdx = scene._hotspots.size() - 1; hotspotIdx >= 0; --hotspotIdx) {
Hotspot &hs = scene._hotspots[hotspotIdx];
_vm->_game->_screenObjects.add(hs._bounds, LAYER_GUI, CAT_HOTSPOT, hotspotIdx);