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 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();
|
||||
|
||||
if (msg.size() > 0) {
|
||||
while (*text)
|
||||
width += _charWidths[*text++ & 0x7F] + spaceWidth;
|
||||
width -= spaceWidth;
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
@ -550,13 +552,17 @@ void ScreenObjects::elementHighlighted() {
|
|||
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() {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue