MADS: Further fixes for hotspot highlighting
This commit is contained in:
parent
06766e930b
commit
0b351f79d8
8 changed files with 112 additions and 61 deletions
|
@ -136,13 +136,14 @@ void Font::setColorMode(int mode) {
|
||||||
|
|
||||||
int Font::writeString(MSurface *surface, const Common::String &msg, const Common::Point &pt,
|
int Font::writeString(MSurface *surface, const Common::String &msg, const Common::Point &pt,
|
||||||
int spaceWidth, int width) {
|
int spaceWidth, int width) {
|
||||||
|
int xEnd;
|
||||||
if (width > 0)
|
if (width > 0)
|
||||||
width = MIN((int)surface->w, pt.x + width);
|
xEnd = MIN((int)surface->w, pt.x + width);
|
||||||
else
|
else
|
||||||
width = surface->w - pt.x;
|
xEnd = surface->w - pt.x;
|
||||||
|
|
||||||
int x = pt.x + 1;
|
int x = pt.x;
|
||||||
int y = pt.y + 1;
|
int y = pt.y;
|
||||||
|
|
||||||
int skipY = 0;
|
int skipY = 0;
|
||||||
if (y < 0) {
|
if (y < 0) {
|
||||||
|
@ -174,7 +175,7 @@ int Font::writeString(MSurface *surface, const Common::String &msg, const Common
|
||||||
|
|
||||||
if (charWidth > 0) {
|
if (charWidth > 0) {
|
||||||
|
|
||||||
if (xPos + charWidth >= width)
|
if (xPos + charWidth > xEnd)
|
||||||
return xPos;
|
return xPos;
|
||||||
|
|
||||||
uint8 *charData = &_charData[_charOffs[(byte)theChar]];
|
uint8 *charData = &_charData[_charOffs[(byte)theChar]];
|
||||||
|
@ -221,8 +222,12 @@ int Font::getWidth(const Common::String &msg, int spaceWidth) {
|
||||||
int width = 0;
|
int width = 0;
|
||||||
const char *text = msg.c_str();
|
const char *text = msg.c_str();
|
||||||
|
|
||||||
while (*text)
|
if (msg.size() > 0) {
|
||||||
width += _charWidths[*text++ & 0x7F] + spaceWidth;
|
while (*text)
|
||||||
|
width += _charWidths[*text++ & 0x7F] + spaceWidth;
|
||||||
|
width -= spaceWidth;
|
||||||
|
}
|
||||||
|
|
||||||
return width;
|
return width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -146,8 +146,40 @@ void DynamicHotspots::refresh() {
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
void Hotspots::activate(int hotspotId, bool active) {
|
Hotspot::Hotspot() {
|
||||||
warning("TODO: Hotspots::activate");
|
_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
|
} // End of namespace MADS
|
||||||
|
|
|
@ -30,7 +30,6 @@ namespace MADS {
|
||||||
|
|
||||||
class MADSEngine;
|
class MADSEngine;
|
||||||
|
|
||||||
|
|
||||||
class DynamicHotspot {
|
class DynamicHotspot {
|
||||||
public:
|
public:
|
||||||
bool _active;
|
bool _active;
|
||||||
|
@ -74,6 +73,7 @@ public:
|
||||||
Common::Point _feetPos;
|
Common::Point _feetPos;
|
||||||
int _facing;
|
int _facing;
|
||||||
int _articleNumber;
|
int _articleNumber;
|
||||||
|
bool _active;
|
||||||
CursorType _cursor;
|
CursorType _cursor;
|
||||||
int _vocabId;
|
int _vocabId;
|
||||||
int _verbId;
|
int _verbId;
|
||||||
|
@ -83,8 +83,15 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
class Hotspots : public Common::Array<Hotspot> {
|
class Hotspots : public Common::Array<Hotspot> {
|
||||||
|
private:
|
||||||
|
MADSEngine *_vm;
|
||||||
public:
|
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
|
} // End of namespace MADS
|
||||||
|
|
|
@ -29,8 +29,8 @@
|
||||||
namespace MADS {
|
namespace MADS {
|
||||||
|
|
||||||
Scene::Scene(MADSEngine *vm): _vm(vm), _action(_vm), _depthSurface(vm),
|
Scene::Scene(MADSEngine *vm): _vm(vm), _action(_vm), _depthSurface(vm),
|
||||||
_dirtyAreas(_vm), _dynamicHotspots(vm), _kernelMessages(vm),
|
_dirtyAreas(_vm), _dynamicHotspots(vm), _hotspots(vm),
|
||||||
_sequences(vm), _sprites(vm), _spriteSlots(vm),
|
_kernelMessages(vm), _sequences(vm), _sprites(vm), _spriteSlots(vm),
|
||||||
_textDisplay(vm), _userInterface(vm) {
|
_textDisplay(vm), _userInterface(vm) {
|
||||||
_priorSceneId = 0;
|
_priorSceneId = 0;
|
||||||
_nextSceneId = 0;
|
_nextSceneId = 0;
|
||||||
|
|
|
@ -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) {
|
void ARTHeader::load(Common::SeekableReadStream *f) {
|
||||||
// Read in dimensions of image
|
// Read in dimensions of image
|
||||||
_width = f->readUint16LE();
|
_width = f->readUint16LE();
|
||||||
|
|
|
@ -276,6 +276,7 @@ void ScreenObjects::add(const Common::Rect &bounds, Layer layer, ScrCategory cat
|
||||||
so._category = category;
|
so._category = category;
|
||||||
so._descId = descId;
|
so._descId = descId;
|
||||||
so._layer = layer;
|
so._layer = layer;
|
||||||
|
so._active = true;
|
||||||
|
|
||||||
push_back(so);
|
push_back(so);
|
||||||
}
|
}
|
||||||
|
@ -361,9 +362,10 @@ void ScreenObjects::check(bool scanFlag) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int ScreenObjects::scanBackwards(const Common::Point &pt, int layer) {
|
int ScreenObjects::scanBackwards(const Common::Point &pt, int layer) {
|
||||||
for (int i = (int)size() - 1; i >= 0; --i) {
|
for (int i = (int)size(); i >= 1; --i) {
|
||||||
if ((*this)[i]._bounds.contains(pt) && ((*this)[i]._layer == layer))
|
ScreenObject &sObj = (*this)[i];
|
||||||
return i + 1;
|
if (sObj._active && sObj._bounds.contains(pt) && sObj._layer == layer)
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entry not found
|
// Entry not found
|
||||||
|
@ -462,7 +464,7 @@ void ScreenObjects::elementHighlighted() {
|
||||||
int uiCount;
|
int uiCount;
|
||||||
|
|
||||||
switch (userInterface._category) {
|
switch (userInterface._category) {
|
||||||
case CAT_INV_LIST:
|
case CAT_ACTION:
|
||||||
index = 10;
|
index = 10;
|
||||||
indexEnd = 9;
|
indexEnd = 9;
|
||||||
varA = 5;
|
varA = 5;
|
||||||
|
@ -475,7 +477,7 @@ void ScreenObjects::elementHighlighted() {
|
||||||
var4 = _released && !_v7FECA ? 1 : 0;
|
var4 = _released && !_v7FECA ? 1 : 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAT_INV_VOCAB:
|
case CAT_INV_LIST:
|
||||||
userInterface.scrollInventory();
|
userInterface.scrollInventory();
|
||||||
|
|
||||||
index = MIN((int)invList.size() - userInterface._inventoryTopIndex, 5);
|
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;
|
var4 = (!_released || (_vm->_events->_mouseButtons && action._v83338 == 1)) ? 0 : 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAT_HOTSPOT:
|
case CAT_INV_VOCAB:
|
||||||
if (userInterface._selectedInvIndex >= 0) {
|
if (userInterface._selectedInvIndex >= 0) {
|
||||||
InventoryObject &invObject = _vm->_game->_objects.getItem(
|
InventoryObject &invObject = _vm->_game->_objects.getItem(
|
||||||
userInterface._selectedInvIndex);
|
userInterface._selectedInvIndex);
|
||||||
|
@ -506,7 +508,7 @@ void ScreenObjects::elementHighlighted() {
|
||||||
var4 = _released && !_v7FECA ? 1 : 0;
|
var4 = _released && !_v7FECA ? 1 : 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAT_TALK_ENTRY:
|
case CAT_INV_ANIM:
|
||||||
index = 1;
|
index = 1;
|
||||||
indexEnd = invList.size() - 1;
|
indexEnd = invList.size() - 1;
|
||||||
varA = 0;
|
varA = 0;
|
||||||
|
@ -515,17 +517,7 @@ void ScreenObjects::elementHighlighted() {
|
||||||
var4 = -1;
|
var4 = -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CAT_INV_SCROLLER:
|
case CAT_TALK_ENTRY:
|
||||||
uiCount = size() - _uiCount;
|
|
||||||
index = scene._hotspots.size();
|
|
||||||
indexEnd = index - 1;
|
|
||||||
varA = 0;
|
|
||||||
topIndex = 0;
|
|
||||||
var6 = &var8;
|
|
||||||
var4 = -1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
index = 0;
|
index = 0;
|
||||||
for (int idx = 0; idx < 5; ++idx) {
|
for (int idx = 0; idx < 5; ++idx) {
|
||||||
if (!userInterface._talkStrings[idx].empty())
|
if (!userInterface._talkStrings[idx].empty())
|
||||||
|
@ -538,6 +530,16 @@ void ScreenObjects::elementHighlighted() {
|
||||||
var6 = &userInterface._v1A;
|
var6 = &userInterface._v1A;
|
||||||
var4 = -1;
|
var4 = -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
uiCount = size() - _uiCount;
|
||||||
|
index = scene._hotspots.size();
|
||||||
|
indexEnd = index - 1;
|
||||||
|
varA = 0;
|
||||||
|
topIndex = 0;
|
||||||
|
var6 = &var8;
|
||||||
|
var4 = -1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
int newIndex = -1;
|
int newIndex = -1;
|
||||||
|
@ -550,13 +552,17 @@ void ScreenObjects::elementHighlighted() {
|
||||||
catIndex + idx;
|
catIndex + idx;
|
||||||
|
|
||||||
ScreenObject &scrObject = (*this)[scrObjIndex];
|
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);
|
newY = MAX((int)bounds.bottom, newY);
|
||||||
newX = MAX((int)bounds.left, newX);
|
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 (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;
|
newIndex = scrObjIndex - catIndex;
|
||||||
if (_category == CAT_HOTSPOT && newIndex < (int)scene._hotspots.size())
|
if (_category == CAT_HOTSPOT && newIndex < (int)scene._hotspots.size())
|
||||||
newIndex = scene._hotspots.size() - newIndex - 1;
|
newIndex = scene._hotspots.size() - newIndex - 1;
|
||||||
|
@ -602,6 +608,14 @@ void ScreenObjects::elementHighlighted() {
|
||||||
userInterface.drawInventory(_category, newIndex, var6);
|
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() {
|
ScreenSurface::ScreenSurface() {
|
||||||
|
|
|
@ -125,6 +125,7 @@ public:
|
||||||
|
|
||||||
class ScreenObject {
|
class ScreenObject {
|
||||||
public:
|
public:
|
||||||
|
bool _active;
|
||||||
Common::Rect _bounds;
|
Common::Rect _bounds;
|
||||||
ScrCategory _category;
|
ScrCategory _category;
|
||||||
int _descId;
|
int _descId;
|
||||||
|
@ -179,6 +180,23 @@ public:
|
||||||
* Handle element being highlighted on the screen
|
* Handle element being highlighted on the screen
|
||||||
*/
|
*/
|
||||||
void elementHighlighted();
|
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 {
|
class ScreenSurface : public MSurface {
|
||||||
|
|
|
@ -447,7 +447,7 @@ void UserInterface::loadElements() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_vm->_game->_screenObjects._v832EC || _vm->_game->_screenObjects._v832EC == 2) {
|
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) {
|
for (int hotspotIdx = scene._hotspots.size() - 1; hotspotIdx >= 0; --hotspotIdx) {
|
||||||
Hotspot &hs = scene._hotspots[hotspotIdx];
|
Hotspot &hs = scene._hotspots[hotspotIdx];
|
||||||
_vm->_game->_screenObjects.add(hs._bounds, LAYER_GUI, CAT_HOTSPOT, hotspotIdx);
|
_vm->_game->_screenObjects.add(hs._bounds, LAYER_GUI, CAT_HOTSPOT, hotspotIdx);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue