From 956f3d46444bc043f9e3153c3dc76d76f6dee7ac Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Thu, 29 Sep 2011 19:26:17 -0400 Subject: PEGASUS: Add the auto dragger code --- engines/pegasus/items/autodragger.cpp | 91 +++++++++++++++++++++++++++++++++++ engines/pegasus/items/autodragger.h | 57 ++++++++++++++++++++++ engines/pegasus/module.mk | 1 + engines/pegasus/pegasus.cpp | 81 +++++++++++++++++++++++++++++-- engines/pegasus/pegasus.h | 8 ++- 5 files changed, 233 insertions(+), 5 deletions(-) create mode 100755 engines/pegasus/items/autodragger.cpp create mode 100755 engines/pegasus/items/autodragger.h (limited to 'engines') diff --git a/engines/pegasus/items/autodragger.cpp b/engines/pegasus/items/autodragger.cpp new file mode 100755 index 0000000000..baad699a7e --- /dev/null +++ b/engines/pegasus/items/autodragger.cpp @@ -0,0 +1,91 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * Additional copyright for this file: + * Copyright (C) 1995-1997 Presto Studios, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "pegasus/elements.h" +#include "pegasus/items/autodragger.h" + +namespace Pegasus { + +AutoDragger::AutoDragger() { + _draggingElement = NULL; + _lastTime = 0; + initCallBack(this, kCallBackAtExtremes); +} + +void AutoDragger::autoDrag(DisplayElement *dragElement, const Common::Point &startPoint, const Common::Point &stopPoint, + TimeValue dragTime, TimeScale dragScale) { + _draggingElement = dragElement; + + if (_draggingElement) { + _startLocation = startPoint; + _stopLocation = stopPoint; + _lastTime = 0; + _done = false; + _draggingElement->moveElementTo(_startLocation.x, _startLocation.y); + setScale(dragScale); + setSegment(0, dragTime); + setTime(0); + scheduleCallBack(kTriggerAtStop, 0, 0); + startIdling(); + start(); + } else { + stopDragging(); + } +} + +void AutoDragger::stopDragging() { + cancelCallBack(); + stopIdling(); + _draggingElement = 0; + _startLocation = Common::Point(); + _stopLocation = Common::Point(); + _lastTime = 0; + _done = true; +} + +bool AutoDragger::isDragging() { + return isIdling(); +} + +void AutoDragger::useIdleTime() { + TimeValue thisTime = getTime(); + + if (thisTime != _lastTime) { + uint32 offsetX = (_stopLocation.x - _startLocation.x) * thisTime / getDuration(); + uint32 offsetY = (_stopLocation.y - _startLocation.y) * thisTime / getDuration(); + _draggingElement->moveElementTo(_startLocation.x + offsetX, _startLocation.x + offsetY); + _lastTime = thisTime; + } + + if (_done) + stopDragging(); +} + +void AutoDragger::callBack() { + if (isIdling()) + _done = true; +} + +} // End of namespace Pegasus diff --git a/engines/pegasus/items/autodragger.h b/engines/pegasus/items/autodragger.h new file mode 100755 index 0000000000..6783fdf9a3 --- /dev/null +++ b/engines/pegasus/items/autodragger.h @@ -0,0 +1,57 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * Additional copyright for this file: + * Copyright (C) 1995-1997 Presto Studios, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef PEGASUS_ITEMS_AUTODRAGGER_H +#define PEGASUS_ITEMS_AUTODRAGGER_H + +#include "pegasus/timers.h" + +namespace Pegasus { + +class DisplayElement; + +class AutoDragger : private Idler, private TimeBase, private TimeBaseCallBack { +public: + AutoDragger(); + virtual ~AutoDragger() {} + + void autoDrag(DisplayElement *, const Common::Point &, const Common::Point &, TimeValue, TimeScale); + bool isDragging(); + void stopDragging(); + +protected: + void useIdleTime(); + void callBack(); + + DisplayElement *_draggingElement; + Common::Point _startLocation, _stopLocation; + TimeValue _lastTime; + bool _done; +}; + +} // End of namespace Pegasus + +#endif + diff --git a/engines/pegasus/module.mk b/engines/pegasus/module.mk index c3c0bd83e5..3759780b28 100644 --- a/engines/pegasus/module.mk +++ b/engines/pegasus/module.mk @@ -26,6 +26,7 @@ MODULE_OBJS = \ ai/ai_area.o \ ai/ai_condition.o \ ai/ai_rule.o \ + items/autodragger.o \ items/inventory.o \ items/inventorypicture.o \ items/item.o \ diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp index 690af4b214..9cb1bd250c 100644 --- a/engines/pegasus/pegasus.cpp +++ b/engines/pegasus/pegasus.cpp @@ -1468,7 +1468,7 @@ void PegasusEngine::dragTerminated(const Input &) { result = kTooMuchWeight; if (result != kInventoryOK) - warning("Auto drag item into the room"); + autoDragItemIntoRoom(_draggingItem, _draggingSprite); else delete _draggingSprite; } else if (_dragType == kDragBiochipPickup) { @@ -1478,7 +1478,7 @@ void PegasusEngine::dragTerminated(const Input &) { result = kTooMuchWeight; if (result != kInventoryOK) - warning("Auto drag item into the room"); + autoDragItemIntoRoom(_draggingItem, _draggingSprite); else delete _draggingSprite; } else if (_dragType == kDragInventoryUse) { @@ -1490,7 +1490,7 @@ void PegasusEngine::dragTerminated(const Input &) { _neighborhood->dropItemIntoRoom(_draggingItem, finalSpot); delete _draggingSprite; } else { - warning("Auto drag item into inventory"); + autoDragItemIntoInventory(_draggingItem, _draggingSprite); } } @@ -1701,4 +1701,79 @@ void PegasusEngine::pauseMenu(bool menuUp) { } } +void PegasusEngine::autoDragItemIntoRoom(Item *item, Sprite *draggingSprite) { + if (g_AIArea) + g_AIArea->lockAIOut(); + + Common::Point start, stop; + draggingSprite->getLocation(start.x, start.y); + + Hotspot *dropSpot = _neighborhood->getItemScreenSpot(item, draggingSprite); + + if (dropSpot) { + dropSpot->getCenter(stop.x, stop.y); + } else { + stop.x = kNavAreaLeft + 256; + stop.y = kNavAreaTop + 128; + } + + Common::Rect bounds; + draggingSprite->getBounds(bounds); + stop.x -= bounds.width() >> 1; + stop.y -= bounds.height() >> 1; + + int dx = ABS(stop.x - start.x); + int dy = ABS(stop.y = start.y); + TimeValue time = MAX(dx, dy); + + allowInput(false); + _autoDragger.autoDrag(draggingSprite, start, stop, time, kDefaultTimeScale); + + while (_autoDragger.isDragging()) { + checkCallBacks(); + refreshDisplay(); + _system->delayMillis(10); + } + + _neighborhood->dropItemIntoRoom(_draggingItem, dropSpot); + allowInput(true); + delete _draggingSprite; + + if (g_AIArea) + g_AIArea->unlockAI(); +} + +void PegasusEngine::autoDragItemIntoInventory(Item *, Sprite *draggingSprite) { + if (g_AIArea) + g_AIArea->lockAIOut(); + + Common::Point start; + draggingSprite->getLocation(start.x, start.y); + + Common::Rect r; + draggingSprite->getBounds(r); + + Common::Point stop((76 + 172 - r.width()) / 2, 334 - (2 * r.height() / 3)); + + int dx = ABS(stop.x - start.x); + int dy = ABS(stop.y = start.y); + TimeValue time = MAX(dx, dy); + + allowInput(false); + _autoDragger.autoDrag(draggingSprite, start, stop, time, kDefaultTimeScale); + + while (_autoDragger.isDragging()) { + checkCallBacks(); + refreshDisplay(); + _system->delayMillis(10); + } + + addItemToInventory((InventoryItem *)_draggingItem); + allowInput(true); + delete _draggingSprite; + + if (g_AIArea) + g_AIArea->unlockAI(); +} + } // End of namespace Pegasus diff --git a/engines/pegasus/pegasus.h b/engines/pegasus/pegasus.h index a79d2a7183..277f3bd687 100644 --- a/engines/pegasus/pegasus.h +++ b/engines/pegasus/pegasus.h @@ -39,6 +39,7 @@ #include "pegasus/hotspot.h" #include "pegasus/input.h" #include "pegasus/notification.h" +#include "pegasus/items/autodragger.h" #include "pegasus/items/inventory.h" #include "pegasus/items/itemdragger.h" #include "pegasus/neighborhood/neighborhood.h" @@ -157,9 +158,11 @@ public: // Dragging void dragItem(const Input &, Item *, tDragType); bool isDragging() const { return _dragType != kDragNoDrag; } - tDragType getDragType() const { return _dragType; } // TODO - Item *getDraggingItem() const { return _draggingItem; } // TODO + tDragType getDragType() const { return _dragType; } + Item *getDraggingItem() const { return _draggingItem; } void dragTerminated(const Input &); + void autoDragItemIntoRoom(Item *, Sprite *); + void autoDragItemIntoInventory(Item *, Sprite*); // Save/Load void makeContinuePoint(); @@ -268,6 +271,7 @@ private: Item *_draggingItem; Sprite *_draggingSprite; tDragType _dragType; + AutoDragger _autoDragger; // Interface void toggleInventoryDisplay(); -- cgit v1.2.3