aboutsummaryrefslogtreecommitdiff
path: root/engines/m4
diff options
context:
space:
mode:
authorPaul Gilbert2009-12-05 07:46:41 +0000
committerPaul Gilbert2009-12-05 07:46:41 +0000
commit0e85be840547009f60f25cf8f319a730d957be72 (patch)
tree5398152b56da56b505621fd6a23a02f8dcf8f310 /engines/m4
parentcb9068583103ed7270484067e97a64bc7e092a1b (diff)
downloadscummvm-rg350-0e85be840547009f60f25cf8f319a730d957be72.tar.gz
scummvm-rg350-0e85be840547009f60f25cf8f319a730d957be72.tar.bz2
scummvm-rg350-0e85be840547009f60f25cf8f319a730d957be72.zip
Implemented support for the inventory list scrollbar and directly selecting an object
svn-id: r46266
Diffstat (limited to 'engines/m4')
-rw-r--r--engines/m4/scene.cpp96
-rw-r--r--engines/m4/scene.h15
2 files changed, 90 insertions, 21 deletions
diff --git a/engines/m4/scene.cpp b/engines/m4/scene.cpp
index c555c9f546..2825035747 100644
--- a/engines/m4/scene.cpp
+++ b/engines/m4/scene.cpp
@@ -36,6 +36,12 @@
namespace M4 {
+static const int INV_ANIM_FRAME_SPEED = 8;
+static const int INVENTORY_X = 160;
+static const int INVENTORY_Y = 159;
+static const int SCROLLER_DELAY = 200;
+
+
Scene::Scene(M4Engine *vm): View(vm, Common::Rect(0, 0, vm->_screen->width(), vm->_screen->height())) {
_screenType = VIEWID_SCENE;
@@ -834,23 +840,18 @@ void MadsInterfaceView::setSelectedObject(int objectNumber) {
}
// Check to make sure the object is in the inventory, and also visible on-screen
- int idx = 0;
- while (idx < (int)_inventoryList.size()) {
- if (_inventoryList[idx] == objectNumber) {
- // Found the object
- if (idx < _topIndex)
- _topIndex = idx;
- else if (idx >= (_topIndex + 5))
- _topIndex = MAX(0, idx - 4);
- break;
- }
- ++idx;
- }
- if (idx == (int)_inventoryList.size()) {
+ int idx = _inventoryList.indexOf(objectNumber);
+ if (idx == -1) {
// Object wasn't found, so return
_selectedObject = -1;
return;
}
+
+ // Found the object
+ if (idx < _topIndex)
+ _topIndex = idx;
+ else if (idx >= (_topIndex + 5))
+ _topIndex = MAX(0, idx - 4);
_selectedObject = objectNumber;
sprintf(resName, "*OB%.3dI.SS", objectNumber);
@@ -867,10 +868,14 @@ void MadsInterfaceView::setSelectedObject(int objectNumber) {
_objectFrameNumber = 0;
}
-static const int FRAME_SPEED = 8;
-static const int INVENTORY_X = 160;
-static const int INVENTORY_Y = 159;
+void MadsInterfaceView::addObjectToInventory(int objectNumber) {
+ if (_inventoryList.indexOf(objectNumber) == -1) {
+ _vm->_globals->getObject(objectNumber)->roomNumber = PLAYER_INVENTORY;
+ _inventoryList.push_back(objectNumber);
+ }
+ setSelectedObject(objectNumber);
+}
void MadsInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) {
_vm->_font->setFont(FONT_INTERFACE_MADS);
@@ -905,7 +910,7 @@ void MadsInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) {
// Draw the horizontal line in the scroller representing the current top selected
const Common::Rect scroller(_screenObjects[SCROLL_SCROLLER]);
- int yP = (_inventoryList.size() == 0) ? 0 : (scroller.height() - 4) * _topIndex / _inventoryList.size();
+ int yP = (_inventoryList.size() < 2) ? 0 : (scroller.height() - 5) * _topIndex / (_inventoryList.size() - 1);
destSurface->setColor(4);
destSurface->hLine(scroller.left + 2, scroller.right - 3, scroller.top + 2 + yP);
@@ -934,12 +939,12 @@ void MadsInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) {
if (_objectSprites) {
// Display object sprite. Note that the frame number isn't used directly, because it would result
// in too fast an animation
- M4Sprite *spr = _objectSprites->getFrame(_objectFrameNumber / FRAME_SPEED);
+ M4Sprite *spr = _objectSprites->getFrame(_objectFrameNumber / INV_ANIM_FRAME_SPEED);
spr->copyTo(destSurface, INVENTORY_X, INVENTORY_Y, 0);
if (!_vm->_globals->invObjectsStill) {
// If objetcs are to animated, move to the next frame
- if (++_objectFrameNumber >= (_objectSprites->getCount() * FRAME_SPEED))
+ if (++_objectFrameNumber >= (_objectSprites->getCount() * INV_ANIM_FRAME_SPEED))
_objectFrameNumber = 0;
}
@@ -963,7 +968,13 @@ void MadsInterfaceView::onRefresh(RectList *rects, M4Surface *destSurface) {
}
bool MadsInterfaceView::onEvent(M4EventType eventType, int param1, int x, int y, bool &captureEvents) {
- if (eventType == MEVENT_MOVE) {
+ // If the mouse isn't being held down, then reset the repeated scroll timer
+ if (eventType != MEVENT_LEFT_HOLD)
+ _nextScrollerTicks = 0;
+
+ // Handle various event types
+ switch (eventType) {
+ case MEVENT_MOVE:
// If the cursor isn't in "wait mode", don't do any processing
if (_vm->_mouse->getCursorNum() == CURSOR_WAIT)
return true;
@@ -975,6 +986,51 @@ bool MadsInterfaceView::onEvent(M4EventType eventType, int param1, int x, int y,
_highlightedElement = _screenObjects.find(Common::Point(x, y));
return true;
+
+ case MEVENT_LEFT_CLICK:
+ // Left mouse click
+ // Check if an inventory object was selected
+ if ((_highlightedElement >= INVLIST_START) && (_highlightedElement < (INVLIST_START + 5))) {
+ // Ensure there is an inventory item listed in that cell
+ uint idx = _highlightedElement - INVLIST_START;
+ if ((_topIndex + idx) < _inventoryList.size()) {
+ // Set the selected object
+ setSelectedObject(_inventoryList[_topIndex + idx]);
+ }
+ return true;
+ }
+
+ return true;
+
+ case MEVENT_LEFT_HOLD:
+ // Left mouse hold
+ // Handle the scroller - the up/down buttons allow for multiple actions whilst the mouse is held down
+ if ((_highlightedElement == SCROLL_UP) || (_highlightedElement == SCROLL_DOWN)) {
+ if ((_nextScrollerTicks == 0) || (g_system->getMillis() >= _nextScrollerTicks)) {
+ // Handle scroll up/down action
+ _nextScrollerTicks = g_system->getMillis() + SCROLLER_DELAY;
+
+ if ((_highlightedElement == SCROLL_UP) && (_topIndex > 0))
+ --_topIndex;
+ if ((_highlightedElement == SCROLL_DOWN) && (_topIndex < (int)(_inventoryList.size() - 1)))
+ ++_topIndex;
+ }
+ }
+ return true;
+
+ case MEVENT_LEFT_DRAG:
+ // Left mouse drag
+ // Handle the the the scroller area that can be dragged to adjust the top displayed index
+ if (_highlightedElement == SCROLL_SCROLLER) {
+ // Calculate the new top index based on the Y position
+ const Common::Rect r(_screenObjects[SCROLL_SCROLLER]);
+ _topIndex = CLIP((int)(_inventoryList.size() - 1) * (y - r.top - 2) / (r.height() - 5),
+ 0, (int)_inventoryList.size() - 1);
+ }
+ return true;
+
+ default:
+ break;
}
return false;
diff --git a/engines/m4/scene.h b/engines/m4/scene.h
index 5f33d510ff..acdb3dfa9a 100644
--- a/engines/m4/scene.h
+++ b/engines/m4/scene.h
@@ -98,6 +98,7 @@ public:
SceneResources getSceneResources() { return _sceneResources; }
M4Surface *getBackgroundSurface() const { return _backgroundSurface; }
byte *getInverseColorTable() const { return _inverseColorTable; }
+ MadsInterfaceView *getMadsInterface() { return _madsInterfaceSurface; }
void update();
void setMADSStatusText(const char *text) { strcpy(_statusText, text); }
void showMADSV2TextBox(char *text, int x, int y, char *faceName);
@@ -127,12 +128,23 @@ enum InterfaceFontMode {ITEM_NORMAL, ITEM_HIGHLIGHTED, ITEM_SELECTED};
enum InterfaceObjects {ACTIONS_START = 0, SCROLL_UP = 10, SCROLL_SCROLLER = 11, SCROLL_DOWN = 12,
INVLIST_START = 13, VOCAB_START = 18};
+class IntegerList: public Common::Array<int> {
+public:
+ int indexOf(int v) {
+ for (uint i = 0; i < size(); ++i)
+ if (operator [](i) == v)
+ return i;
+ return -1;
+ }
+};
+
class MadsInterfaceView: public View {
private:
- Common::Array<int> _inventoryList;
+ IntegerList _inventoryList;
RectList _screenObjects;
int _highlightedElement;
int _topIndex;
+ uint32 _nextScrollerTicks;
// Object display fields
int _selectedObject;
@@ -147,6 +159,7 @@ public:
void initialise();
void setSelectedObject(int objectNumber);
+ void addObjectToInventory(int objectNumber);
void onRefresh(RectList *rects, M4Surface *destSurface);
bool onEvent(M4EventType eventType, int param1, int x, int y, bool &captureEvents);