From 54dd0c266eb8f5fe0d067f2298e6964e1ab9032f Mon Sep 17 00:00:00 2001 From: Matthew Hoops Date: Wed, 28 Sep 2011 14:25:55 -0400 Subject: PEGASUS: Import a bunch more code in preparation for actual gameplay --- engines/pegasus/constants.h | 5 +- engines/pegasus/graphics.cpp | 12 + engines/pegasus/graphics.h | 1 + engines/pegasus/input.h | 2 +- engines/pegasus/items/itemdragger.cpp | 8 +- engines/pegasus/items/itemdragger.h | 4 +- engines/pegasus/movie.cpp | 2 +- engines/pegasus/pegasus.cpp | 515 +++++++++++++++++++++++++++++++++- engines/pegasus/pegasus.h | 52 +++- 9 files changed, 583 insertions(+), 18 deletions(-) diff --git a/engines/pegasus/constants.h b/engines/pegasus/constants.h index 406122582f..4c31b45a50 100755 --- a/engines/pegasus/constants.h +++ b/engines/pegasus/constants.h @@ -737,8 +737,9 @@ static const tGameMode kModeBiochipPick = kModeInventoryPick + 1; static const tGameMode kModeInfoScreen = kModeBiochipPick + 1; // TODO: Remove me -const tRoomID kTSA37 = 42; -const tRoomID kTinyTSA37 = 0; +static const tRoomID kTSA37 = 42; +static const tRoomID kTinyTSA37 = 0; +static const tRoomID kCaldoria00 = 1; } // End of namespace Pegasus diff --git a/engines/pegasus/graphics.cpp b/engines/pegasus/graphics.cpp index 05217fabcd..6cce9ddbd8 100644 --- a/engines/pegasus/graphics.cpp +++ b/engines/pegasus/graphics.cpp @@ -189,5 +189,17 @@ void GraphicsManager::clearScreen() { g_system->unlockScreen(); _modifiedScreen = true; } + +DisplayElement *GraphicsManager::findDisplayElement(const tDisplayElementID id) { + DisplayElement *runner = _firstDisplayElement; + + while (runner) { + if (runner->getObjectID() == id) + return runner; + runner = runner->_nextElement; + } + + return 0; +} } // End of namespace Pegasus diff --git a/engines/pegasus/graphics.h b/engines/pegasus/graphics.h index 90d0f33a73..fffa3a6292 100644 --- a/engines/pegasus/graphics.h +++ b/engines/pegasus/graphics.h @@ -53,6 +53,7 @@ public: void updateDisplay(); Graphics::Surface *getWorkArea() { return &_workArea; } void clearScreen(); + DisplayElement *findDisplayElement(const tDisplayElementID id); private: PegasusEngine *_vm; diff --git a/engines/pegasus/input.h b/engines/pegasus/input.h index 298a78fb53..96df249737 100755 --- a/engines/pegasus/input.h +++ b/engines/pegasus/input.h @@ -438,7 +438,7 @@ protected: class Tracker : public InputHandler { public: Tracker() : InputHandler(0) {} - virtual ~Tracker(); + virtual ~Tracker() {} virtual void handleInput(const Input &, const Hotspot *); virtual bool stopTrackingInput(const Input &) { return false; } diff --git a/engines/pegasus/items/itemdragger.cpp b/engines/pegasus/items/itemdragger.cpp index 79cd101e29..4e3a9f1419 100755 --- a/engines/pegasus/items/itemdragger.cpp +++ b/engines/pegasus/items/itemdragger.cpp @@ -129,9 +129,6 @@ void SpriteDragger::pinPointInRect(const Common::Rect &r, Common::Point &pt) { ItemDragger::ItemDragger(PegasusEngine *owner) : _inventoryDropSpot(kInventoryDropSpotID), _biochipDropSpot(kBiochipDropSpotID), _inventoryHighlight(kInventoryDropHighlightID), _biochipHighlight(kBiochipDropHighlightID) { _owner = owner; - - _inventoryHighlight.setBounds(Common::Rect(76, 334, 172, 430)); - _biochipHighlight.setBounds(Common::Rect(364, 334, 460, 430)); Common::Rect r(kInventoryDropLeft, kInventoryDropTop, kInventoryDropRight, kInventoryDropBottom); _inventoryDropSpot.setArea(r); @@ -185,4 +182,9 @@ void ItemDragger::exitHotspot(Hotspot *spot) { _draggingSprite->setCurrentFrameIndex(0); } +void ItemDragger::setHighlightBounds() { + _inventoryHighlight.setBounds(Common::Rect(76, 334, 172, 430)); + _biochipHighlight.setBounds(Common::Rect(364, 334, 460, 430)); +} + } // End of namespace Pegasus diff --git a/engines/pegasus/items/itemdragger.h b/engines/pegasus/items/itemdragger.h index 3775fb2ceb..69612316f3 100755 --- a/engines/pegasus/items/itemdragger.h +++ b/engines/pegasus/items/itemdragger.h @@ -26,6 +26,7 @@ #ifndef PEGASUS_ITEMS_ITEMDRAGGER_H #define PEGASUS_ITEMS_ITEMDRAGGER_H +#include "pegasus/elements.h" #include "pegasus/input.h" namespace Pegasus { @@ -73,7 +74,8 @@ class ItemDragger : public SpriteDragger { public: ItemDragger(PegasusEngine *); virtual ~ItemDragger() {} - + + void setHighlightBounds(); void startTracking(const Input &); void stopTracking(const Input &); bool stopTrackingInput(const Input &); diff --git a/engines/pegasus/movie.cpp b/engines/pegasus/movie.cpp index e102c70272..bbe63a00a8 100755 --- a/engines/pegasus/movie.cpp +++ b/engines/pegasus/movie.cpp @@ -175,7 +175,7 @@ void Movie::checkCallBacks() { // The reason why we overrode TimeBase's checkCallBacks(): // Again, avoiding timers and handling it here - if (!_video->isPaused()) { + if (_video && !_video->isPaused()) { if (_video->needsUpdate()) redrawMovieWorld(); diff --git a/engines/pegasus/pegasus.cpp b/engines/pegasus/pegasus.cpp index 5eb3340c47..c63a01ff80 100644 --- a/engines/pegasus/pegasus.cpp +++ b/engines/pegasus/pegasus.cpp @@ -38,6 +38,7 @@ #include "pegasus/console.h" #include "pegasus/cursor.h" +#include "pegasus/energymonitor.h" #include "pegasus/gamestate.h" #include "pegasus/interface.h" #include "pegasus/menu.h" @@ -57,11 +58,13 @@ #include "pegasus/items/inventory/inventoryitem.h" #include "pegasus/items/inventory/keycard.h" #include "pegasus/neighborhood/neighborhood.h" +#include "pegasus/neighborhood/prehistoric/prehistoric.h" namespace Pegasus { PegasusEngine::PegasusEngine(OSystem *syst, const PegasusGameDescription *gamedesc) : Engine(syst), InputHandler(0), _gameDescription(gamedesc), - _shellNotification(kJMPDCShellNotificationID, this), _returnHotspot(kInfoReturnSpotID) { + _shellNotification(kJMPDCShellNotificationID, this), _returnHotspot(kInfoReturnSpotID), _itemDragger(this), _bigInfoMovie(kNoDisplayElement), + _smallInfoMovie(kNoDisplayElement) { _continuePoint = 0; _saveAllowed = _loadAllowed = true; _gameMenu = 0; @@ -70,6 +73,9 @@ PegasusEngine::PegasusEngine(OSystem *syst, const PegasusGameDescription *gamede _FXLevel = 0x80; _ambientLevel = 0x80; _gameMode = kNoMode; + _switchModesSync = false; + _draggingItem = 0; + _dragType = kDragNoDrag; } PegasusEngine::~PegasusEngine() { @@ -100,6 +106,9 @@ Common::Error PegasusEngine::run() { _cursor->addCursorFrames(0x80); // Main _cursor->addCursorFrames(900); // Mars Shuttle + // Initialize the item dragger bounds + _itemDragger.setHighlightBounds(); + if (!isDemo() && !detectOpeningClosingDirectory()) { Common::String message = "Missing intro directory. "; @@ -504,6 +513,10 @@ void PegasusEngine::receiveNotification(Notification *notification, const tNotif case kPlayerDiedFlag: doDeath(); break; + case kNeedNewJumpFlag: + performJump(GameState.getNextNeighborhood()); + startNeighborhood(); + break; default: break; } @@ -661,7 +674,7 @@ void PegasusEngine::doGameMenuCommand(const tGameMenuCommand command) { void PegasusEngine::handleInput(const Input &input, const Hotspot *cursorSpot) { if (!checkGameMenu()) - ; // TODO: Other input + shellGameInput(input, cursorSpot); // Handle the console here if (input.isConsoleRequested()) { @@ -1043,10 +1056,6 @@ void PegasusEngine::throwAwayEverything() { // TODO } -void PegasusEngine::dragItem(const Input &, Item *, tDragType) { - // TODO -} - void PegasusEngine::processShell() { checkCallBacks(); checkNotifications(); @@ -1069,7 +1078,38 @@ void PegasusEngine::setGameMode(const tGameMode newMode) { } void PegasusEngine::switchGameMode(const tGameMode newMode, const tGameMode oldMode) { - // TODO + // Start raising panels before lowering panels, to give the activating panel time + // to set itself up without cutting into the lowering panel's animation time. + + if (_switchModesSync) { + if (newMode == kModeInventoryPick) + raiseInventoryDrawerSync(); + else if (newMode == kModeBiochipPick) + raiseBiochipDrawerSync(); + else if (newMode == kModeInfoScreen) + showInfoScreen(); + + if (oldMode == kModeInventoryPick) + lowerInventoryDrawerSync(); + else if (oldMode == kModeBiochipPick) + lowerBiochipDrawerSync(); + else if (oldMode == kModeInfoScreen) + hideInfoScreen(); + } else { + if (newMode == kModeInventoryPick) + raiseInventoryDrawer(); + else if (newMode == kModeBiochipPick) + raiseBiochipDrawer(); + else if (newMode == kModeInfoScreen) + showInfoScreen(); + + if (oldMode == kModeInventoryPick) + lowerInventoryDrawer(); + else if (oldMode == kModeBiochipPick) + lowerBiochipDrawer(); + else if (oldMode == kModeInfoScreen) + hideInfoScreen(); + } } bool PegasusEngine::canSwitchGameMode(const tGameMode newMode, const tGameMode oldMode) { @@ -1128,4 +1168,465 @@ void PegasusEngine::useNeighborhood(Neighborhood *neighborhood) { } } +void PegasusEngine::performJump(const tNeighborhoodID neighborhoodID) { + if (neighborhoodID == kNoradSubChaseID) + error("TODO: Sub chase"); + + if (_neighborhood) + useNeighborhood(0); + + Neighborhood *neighborhood; + makeNeighborhood(neighborhoodID, neighborhood); + useNeighborhood(neighborhood); +} + +void PegasusEngine::startNeighborhood() { + if (_currentItemID != kNoItemID) + g_interface->setCurrentInventoryItemID(_currentItemID); + + if (_currentBiochipID != kNoItemID) + g_interface->setCurrentBiochipID(_currentBiochipID); + + setGameMode(kModeNavigation); + + if (_neighborhood) + _neighborhood->start(); +} + +void PegasusEngine::startNewGame() { + // WORKAROUND: The original game ignored the menu difficulty + // setting. We're going to pass it through here so that + // the menu actually makes sense now. + bool isWalkthrough = GameState.getWalkthroughMode(); + GameState.resetGameState(); + GameState.setWalkthroughMode(isWalkthrough); + + // TODO: Enable erase + // TODO: Fade out + useMenu(0); + _gfx->updateDisplay(); + + createInterface(); + + if (isDemo()) { + setLastEnergyValue(kFullEnergy); + jumpToNewEnvironment(kPrehistoricID, kPrehistoric02, kSouth); + GameState.setPrehistoricSeenTimeStream(false); + GameState.setPrehistoricSeenFlyer1(false); + GameState.setPrehistoricSeenFlyer2(false); + GameState.setPrehistoricSeenBridgeZoom(false); + GameState.setPrehistoricBreakerThrown(false); + } else { + jumpToNewEnvironment(kCaldoriaID, kCaldoria00, kEast); + } + + removeAllItemsFromInventory(); + removeAllItemsFromBiochips(); + + BiochipItem *biochip = (BiochipItem *)g_allItems.findItemByID(kAIBiochip); + addItemToBiochips(biochip); + + if (isDemo()) { + biochip = (BiochipItem *)g_allItems.findItemByID(kPegasusBiochip); + addItemToBiochips(biochip); + biochip = (BiochipItem *)g_allItems.findItemByID(kMapBiochip); + addItemToBiochips(biochip); + InventoryItem *item = (InventoryItem *)g_allItems.findItemByID(kKeyCard); + addItemToInventory(item); + item = (InventoryItem *)g_allItems.findItemByID(kJourneymanKey); + addItemToInventory(item); + _currentItemID = kJourneymanKey; + } else { + _currentItemID = kNoItemID; + } + + _currentBiochipID = kAIBiochip; + + // Clear jump notification flags and just perform the jump... + _shellNotification.setNotificationFlags(0, kNeedNewJumpFlag); + + performJump(GameState.getNextNeighborhood()); + + startNeighborhood(); +} + +void PegasusEngine::makeNeighborhood(tNeighborhoodID neighborhoodID, Neighborhood *&neighborhood) { + // TODO: CD check + + switch (neighborhoodID) { + case kPrehistoricID: + neighborhood = new Prehistoric(g_AIArea, this); + break; + } +} + +bool PegasusEngine::wantsCursor() { + return _gameMenu == 0; +} + +void PegasusEngine::updateCursor(const Common::Point, const Hotspot *cursorSpot) { + if (_itemDragger.isTracking()) { + _cursor->setCurrentFrameIndex(5); + } else { + if (!cursorSpot) { + _cursor->setCurrentFrameIndex(0); + } else { + uint32 id = cursorSpot->getObjectID(); + + switch (id) { + case kCurrentItemSpotID: + if (countInventoryItems() != 0) + _cursor->setCurrentFrameIndex(4); + else + _cursor->setCurrentFrameIndex(0); + break; + default: + tHotSpotFlags flags = cursorSpot->getHotspotFlags(); + + if (flags & kZoomInSpotFlag) + _cursor->setCurrentFrameIndex(1); + else if (flags & kZoomOutSpotFlag) + _cursor->setCurrentFrameIndex(2); + else if (flags & (kPickUpItemSpotFlag | kPickUpBiochipSpotFlag)) + _cursor->setCurrentFrameIndex(4); + else if (flags & kJMPClickingSpotFlags) + _cursor->setCurrentFrameIndex(3); + else + _cursor->setCurrentFrameIndex(0); + } + } + } +} + +void PegasusEngine::toggleInventoryDisplay() { + if (_gameMode == kModeInventoryPick) + setGameMode(kModeNavigation); + else + setGameMode(kModeInventoryPick); +} + +void PegasusEngine::toggleBiochipDisplay() { + if (_gameMode == kModeBiochipPick) + setGameMode(kModeNavigation); + else + setGameMode(kModeBiochipPick); +} + +void PegasusEngine::showInfoScreen() { + if (g_neighborhood) { + // Break the input handler chain... + _savedHandler = InputHandler::getCurrentHandler(); + InputHandler::setInputHandler(this); + + Picture *pushPicture = ((Neighborhood *)g_neighborhood)->getTurnPushPicture(); + + _bigInfoMovie.shareSurface(pushPicture); + _smallInfoMovie.shareSurface(pushPicture); + + g_neighborhood->hideNav(); + + _smallInfoMovie.initFromMovieFile("Images/Items/Info Right Movie"); + _smallInfoMovie.setDisplayOrder(kInfoSpinOrder); + _smallInfoMovie.moveElementTo(kNavAreaLeft + 304, kNavAreaTop + 8); + _smallInfoMovie.moveMovieBoxTo(304, 8); + _smallInfoMovie.startDisplaying(); + _smallInfoMovie.show(); + + TimeValue startTime, stopTime; + g_AIArea->getSmallInfoSegment(startTime, stopTime); + _smallInfoMovie.setSegment(startTime, stopTime); + _smallInfoMovie.setFlags(kLoopTimeBase); + + _bigInfoMovie.initFromMovieFile("Images/Items/Info Left Movie"); + _bigInfoMovie.setDisplayOrder(kInfoBackgroundOrder); + _bigInfoMovie.moveElementTo(kNavAreaLeft, kNavAreaTop); + _bigInfoMovie.startDisplaying(); + _bigInfoMovie.show(); + _bigInfoMovie.setTime(g_AIArea->getBigInfoTime()); + + _bigInfoMovie.redrawMovieWorld(); + _smallInfoMovie.redrawMovieWorld(); + _smallInfoMovie.start(); + } +} + +void PegasusEngine::hideInfoScreen() { + if (g_neighborhood) { + InputHandler::setInputHandler(_savedHandler); + + _bigInfoMovie.hide(); + _bigInfoMovie.stopDisplaying(); + _bigInfoMovie.releaseMovie(); + + _smallInfoMovie.hide(); + _smallInfoMovie.stopDisplaying(); + _smallInfoMovie.stop(); + _smallInfoMovie.releaseMovie(); + + g_neighborhood->showNav(); + } +} + +void PegasusEngine::raiseInventoryDrawer() { + if (g_interface) + g_interface->raiseInventoryDrawer(); +} + +void PegasusEngine::raiseBiochipDrawer() { + if (g_interface) + g_interface->raiseBiochipDrawer(); +} + +void PegasusEngine::lowerInventoryDrawer() { + if (g_interface) + g_interface->lowerInventoryDrawer(); +} + +void PegasusEngine::lowerBiochipDrawer() { + if (g_interface) + g_interface->lowerBiochipDrawer(); +} + +void PegasusEngine::raiseInventoryDrawerSync() { + if (g_interface) + g_interface->raiseInventoryDrawerSync(); +} + +void PegasusEngine::raiseBiochipDrawerSync() { + if (g_interface) + g_interface->raiseBiochipDrawerSync(); +} + +void PegasusEngine::lowerInventoryDrawerSync() { + if (g_interface) + g_interface->lowerInventoryDrawerSync(); +} + +void PegasusEngine::lowerBiochipDrawerSync() { + if (g_interface) + g_interface->lowerBiochipDrawerSync(); +} + +void PegasusEngine::toggleInfo() { + if (_gameMode == kModeInfoScreen) + setGameMode(kModeNavigation); + else if (_gameMode == kModeNavigation) + setGameMode(kModeInfoScreen); +} + +void PegasusEngine::dragTerminated(const Input &) { + Hotspot *finalSpot = _itemDragger.getLastHotspot(); + tInventoryResult result; + + if (_dragType == kDragInventoryPickup) { + if (finalSpot && finalSpot->getObjectID() == kInventoryDropSpotID) + result = addItemToInventory((InventoryItem *)_draggingItem); + else + result = kTooMuchWeight; + + if (result != kInventoryOK) + warning("Auto drag item into the room"); + else + delete _draggingSprite; + } else if (_dragType == kDragBiochipPickup) { + if (finalSpot && finalSpot->getObjectID() == kBiochipDropSpotID) + result = addItemToBiochips((BiochipItem *)_draggingItem); + else + result = kTooMuchWeight; + + if (result != kInventoryOK) + warning("Auto drag item into the room"); + else + delete _draggingSprite; + } else if (_dragType == kDragInventoryUse) { + if (finalSpot && (finalSpot->getHotspotFlags() & kDropItemSpotFlag) != 0) { + // *** Need to decide on a case by case basis what to do here. + // the crowbar should break the cover off the Mars reactor if its frozen, the + // global transport card should slide through the slot, the oxygen mask should + // attach to the filling station, and so on... + _neighborhood->dropItemIntoRoom(_draggingItem, finalSpot); + delete _draggingSprite; + } else { + warning("Auto drag item into inventory"); + } + } + + _dragType = kDragNoDrag; + + if (g_AIArea) + g_AIArea->unlockAI(); +} + + +void PegasusEngine::dragItem(const Input &input, Item *item, tDragType type) { + _draggingItem = item; + _dragType = type; + + // Create the sprite. + _draggingSprite = _draggingItem->getDragSprite(kDraggingSpriteID); + Common::Point where; + input.getInputLocation(where); + Common::Rect r1; + _draggingSprite->getBounds(r1); + r1 = Common::Rect::center(where.x, where.y, r1.width(), r1.height()); + _draggingSprite->setBounds(r1); + + // Set up drag constraints. + DisplayElement *navMovie = _gfx->findDisplayElement(kNavMovieID); + Common::Rect r2; + navMovie->getBounds(r2); + r2.left -= r1.width() / 3; + r2.right += r1.width() / 3; + r2.top -= r1.height() / 3; + r2.bottom += r2.height() / 3; + + r1 = Common::Rect(-30000, -30000, 30000, 30000); + _itemDragger.setDragConstraints(r2, r1); + + // Start dragging. + _draggingSprite->setDisplayOrder(kDragSpriteOrder); + _draggingSprite->startDisplaying(); + _draggingSprite->show(); + _itemDragger.setDragSprite(_draggingSprite); + _itemDragger.setNextHandler(_neighborhood); + _itemDragger.startTracking(input); + + if (g_AIArea) + g_AIArea->lockAIOut(); +} + +void PegasusEngine::shellGameInput(const Input &input, const Hotspot *cursorSpot) { + if (_gameMode == kModeInfoScreen) { + if (JMPPPInput::isToggleAIMiddleInput(input)) { + tLowerClientSignature middleOwner = g_AIArea->getMiddleAreaOwner(); + g_AIArea->toggleMiddleAreaOwner(); + + if (middleOwner != g_AIArea->getMiddleAreaOwner()) { + _bigInfoMovie.setTime(g_AIArea->getBigInfoTime()); + _smallInfoMovie.stop(); + _smallInfoMovie.setFlags(0); + + TimeValue startTime, stopTime; + g_AIArea->getSmallInfoSegment(startTime, stopTime); + _smallInfoMovie.setSegment(startTime, stopTime); + _smallInfoMovie.setFlags(kLoopTimeBase); + + _bigInfoMovie.redrawMovieWorld(); + _smallInfoMovie.redrawMovieWorld(); + _smallInfoMovie.start(); + } + } + } else { + if (JMPPPInput::isRaiseInventoryInput(input)) + toggleInventoryDisplay(); + + if (JMPPPInput::isRaiseBiochipsInput(input)) + toggleBiochipDisplay(); + + // TODO + if (JMPPPInput::isTogglePauseInput(input) && _neighborhood) + warning("Pause"); + } + + if (JMPPPInput::isToggleInfoInput(input)) + toggleInfo(); +} + +void PegasusEngine::activateHotspots() { + if (_gameMode == kModeInfoScreen) { + g_allHotspots.activateOneHotspot(kInfoReturnSpotID); + } else { + // Set up hot spots. + if (_dragType == kDragInventoryPickup) + g_allHotspots.activateOneHotspot(kInventoryDropSpotID); + else if (_dragType == kDragBiochipPickup) + g_allHotspots.activateOneHotspot(kBiochipDropSpotID); + else if (_dragType == kDragNoDrag) + g_allHotspots.activateMaskedHotspots(kShellSpotFlag); + } +} + +bool PegasusEngine::isClickInput(const Input &input, const Hotspot *cursorSpot) { + if (_cursor->isVisible() && cursorSpot) + return JMPPPInput::isClickInput(input); + else + return false; +} + +tInputBits PegasusEngine::getClickFilter() { + return JMPPPInput::getClickInputFilter(); +} + +void PegasusEngine::clickInHotspot(const Input &input, const Hotspot *clickedSpot) { + if (clickedSpot->getObjectID() == kCurrentItemSpotID) { + InventoryItem *currentItem = getCurrentInventoryItem(); + if (currentItem) { + removeItemFromInventory(currentItem); + dragItem(input, currentItem, kDragInventoryUse); + } + } else if (clickedSpot->getObjectID() == kInfoReturnSpotID) { + toggleInfo(); + } +} + +tInventoryResult PegasusEngine::removeItemFromInventory(InventoryItem *item) { + tInventoryResult result; + + if (g_interface) + result = g_interface->removeInventoryItem(item); + else + result = _items.removeItem(item); + + // This should never happen + assert(result == kInventoryOK); + + return result; +} + +void PegasusEngine::removeAllItemsFromInventory() { + if (g_interface) + g_interface->removeAllItemsFromInventory(); + else + _items.removeAllItems(); +} + +///////////////////////////////////////////// +// +// Biochip handling. + +// Adding biochips to the biochip drawer is a little funny, because of two things: +// -- We get the map biochip and pegasus biochip at the same time by dragging +// one sprite in TSA +// -- We can drag in more than one copy of the various biochips. +// Because of this we need to make sure that no more than one copy of each biochip +// is ever added. + +tInventoryResult PegasusEngine::addItemToBiochips(BiochipItem *biochip) { + tInventoryResult result; + + if (g_interface) + result = g_interface->addBiochip(biochip); + else + result = _biochips.addItem(biochip); + + // This can never happen + assert(result == kInventoryOK); + + GameState.setTakenItem(biochip, true); + + if (g_neighborhood) + g_neighborhood->pickedUpItem(biochip); + + g_AIArea->checkMiddleArea(); + + return result; +} + +void PegasusEngine::removeAllItemsFromBiochips() { + if (g_interface) + g_interface->removeAllItemsFromBiochips(); + else + _biochips.removeAllItems(); +} + } // End of namespace Pegasus diff --git a/engines/pegasus/pegasus.h b/engines/pegasus/pegasus.h index 5edc595610..8405a51dc1 100644 --- a/engines/pegasus/pegasus.h +++ b/engines/pegasus/pegasus.h @@ -40,6 +40,7 @@ #include "pegasus/input.h" #include "pegasus/notification.h" #include "pegasus/items/inventory.h" +#include "pegasus/items/itemdragger.h" #include "pegasus/neighborhood/neighborhood.h" namespace Video { @@ -127,12 +128,17 @@ public: bool itemInInventory(tItemID); Inventory *getItemsInventory() { return &_items; } tInventoryResult addItemToInventory(InventoryItem *); + void removeAllItemsFromInventory(); + tInventoryResult removeItemFromInventory(InventoryItem *); + uint32 countInventoryItems() { return _items.getNumItems(); } // Biochips BiochipItem *getCurrentBiochip(); bool itemInBiochips(BiochipItem *); bool itemInBiochips(tItemID); Inventory *getBiochipsInventory() { return &_biochips; } + void removeAllItemsFromBiochips(); + tInventoryResult addItemToBiochips(BiochipItem *); // AI Common::String getBriefingMovie(); @@ -148,9 +154,10 @@ public: // Dragging void dragItem(const Input &, Item *, tDragType); - tDragType getDragType() const { return (tDragType)0; } // TODO - Item *getDraggingItem() const { return 0; } // TODO - void dragTerminated(const Input &) {} // TODO + bool isDragging() const { return _dragType != kDragNoDrag; } + tDragType getDragType() const { return _dragType; } // TODO + Item *getDraggingItem() const { return _draggingItem; } // TODO + void dragTerminated(const Input &); // Save/Load void makeContinuePoint(); @@ -172,6 +179,14 @@ protected: virtual void receiveNotification(Notification *notification, const tNotificationFlags flags); void handleInput(const Input &input, const Hotspot *cursorSpot); + virtual bool isClickInput(const Input &, const Hotspot *); + virtual tInputBits getClickFilter(); + + void clickInHotspot(const Input &, const Hotspot *); + void activateHotspots(void); + + void updateCursor(const Common::Point, const Hotspot *); + bool wantsCursor(); private: // Console @@ -191,6 +206,8 @@ private: void createItem(tItemID itemID, tNeighborhoodID neighborhoodID, tRoomID roomID, tDirectionConstant direction); Inventory _items; Inventory _biochips; + tItemID _currentItemID; + tItemID _currentBiochipID; // TimeBases Common::List _timeBases; @@ -204,10 +221,12 @@ private: // Misc. Hotspot _returnHotspot; + InputHandler *_savedHandler; void showLoadDialog(); void showTempScreen(const Common::String &fileName); bool playMovieScaled(Video::SeekableVideoDecoder *video, uint16 x, uint16 y); void throwAwayEverything(); + void shellGameInput(const Input &input, const Hotspot *cursorSpot); // Menu GameMenu *_gameMenu; @@ -224,6 +243,10 @@ private: // Neighborhood Neighborhood *_neighborhood; void useNeighborhood(Neighborhood *neighborhood); + void performJump(const tNeighborhoodID start); + void startNewGame(); + void startNeighborhood(); + void makeNeighborhood(tNeighborhoodID, Neighborhood *&); // Sound uint16 _ambientLevel; @@ -231,8 +254,31 @@ private: // Game Mode tGameMode _gameMode; + bool _switchModesSync; void switchGameMode(const tGameMode, const tGameMode); bool canSwitchGameMode(const tGameMode, const tGameMode); + + // Dragging + ItemDragger _itemDragger; + Item *_draggingItem; + Sprite *_draggingSprite; + tDragType _dragType; + + // Interface + void toggleInventoryDisplay(); + void toggleBiochipDisplay(); + void raiseInventoryDrawer(); + void raiseBiochipDrawer(); + void lowerInventoryDrawer(); + void lowerBiochipDrawer(); + void raiseInventoryDrawerSync(); + void raiseBiochipDrawerSync(); + void lowerInventoryDrawerSync(); + void lowerBiochipDrawerSync(); + void showInfoScreen(); + void hideInfoScreen(); + void toggleInfo(); + Movie _bigInfoMovie, _smallInfoMovie; }; } // End of namespace Pegasus -- cgit v1.2.3