Initial commit
This commit is contained in:
1
engines/pegasus/POTFILES
Normal file
1
engines/pegasus/POTFILES
Normal file
@@ -0,0 +1 @@
|
||||
engines/pegasus/pegasus.cpp
|
||||
78
engines/pegasus/ai/ai_action.cpp
Normal file
78
engines/pegasus/ai/ai_action.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/ai/ai_action.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
AICompoundAction::~AICompoundAction() {
|
||||
for (AIActionList::iterator it = _compoundActions.begin(); it != _compoundActions.end(); it++)
|
||||
delete *it;
|
||||
}
|
||||
|
||||
void AICompoundAction::performAIAction(AIRule *rule) {
|
||||
for (AIActionList::iterator it = _compoundActions.begin(); it != _compoundActions.end(); it++)
|
||||
(*it)->performAIAction(rule);
|
||||
}
|
||||
|
||||
AIPlayMessageAction::AIPlayMessageAction(const Common::Path &movieName, bool keepLastFrame, const InputBits interruptionFilter) {
|
||||
_movieName = movieName;
|
||||
_keepLastFrame = keepLastFrame;
|
||||
_interruptionFilter = interruptionFilter;
|
||||
}
|
||||
|
||||
void AIPlayMessageAction::performAIAction(AIRule *) {
|
||||
if (g_AIArea && g_vm->isChattyAI()) {
|
||||
g_AIArea->checkMiddleArea();
|
||||
g_AIArea->playAIMovie(kRightAreaSignature, _movieName, _keepLastFrame, _interruptionFilter);
|
||||
}
|
||||
}
|
||||
|
||||
AIStartTimerAction::AIStartTimerAction(AITimerCondition *timerCondition) {
|
||||
_timerCondition = timerCondition;
|
||||
}
|
||||
|
||||
void AIStartTimerAction::performAIAction(AIRule *) {
|
||||
_timerCondition->startTimer();
|
||||
}
|
||||
|
||||
AIActivateRuleAction::AIActivateRuleAction(AIRule *rule) {
|
||||
_rule = rule;
|
||||
}
|
||||
|
||||
void AIActivateRuleAction::performAIAction(AIRule *) {
|
||||
_rule->activateRule();
|
||||
}
|
||||
|
||||
AIDeactivateRuleAction::AIDeactivateRuleAction(AIRule *rule) {
|
||||
_rule = rule;
|
||||
}
|
||||
|
||||
void AIDeactivateRuleAction::performAIAction(AIRule *) {
|
||||
_rule->deactivateRule();
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
135
engines/pegasus/ai/ai_action.h
Normal file
135
engines/pegasus/ai/ai_action.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_AI_AIACTION_H
|
||||
#define PEGASUS_AI_AIACTION_H
|
||||
|
||||
#include "common/list.h"
|
||||
|
||||
#include "pegasus/input.h"
|
||||
#include "pegasus/types.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class AIRule;
|
||||
class AITimerCondition;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AIAction
|
||||
|
||||
class AIAction {
|
||||
friend class AIRule;
|
||||
public:
|
||||
AIAction() { _actionCount = 1; }
|
||||
virtual ~AIAction() {}
|
||||
|
||||
virtual void performAIAction(AIRule *) = 0;
|
||||
|
||||
void setActionCount(const uint32 count) { _actionCount = count; }
|
||||
|
||||
protected:
|
||||
uint32 _actionCount;
|
||||
};
|
||||
|
||||
typedef Common::List<AIAction *> AIActionList;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AICompoundAction
|
||||
|
||||
class AICompoundAction : public AIAction {
|
||||
public:
|
||||
AICompoundAction() {}
|
||||
~AICompoundAction() override;
|
||||
|
||||
void addAction(AIAction *action) { _compoundActions.push_back(action); }
|
||||
|
||||
void performAIAction(AIRule *) override;
|
||||
|
||||
protected:
|
||||
AIActionList _compoundActions;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AIPlayMessageAction
|
||||
|
||||
class AIPlayMessageAction : public AIAction {
|
||||
public:
|
||||
AIPlayMessageAction(const Common::Path &movieName, bool keepLastFrame, const InputBits = kWarningInterruption);
|
||||
|
||||
void performAIAction(AIRule *) override;
|
||||
|
||||
protected:
|
||||
Common::Path _movieName;
|
||||
InputBits _interruptionFilter;
|
||||
bool _keepLastFrame;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AIStartTimerAction
|
||||
|
||||
class AIStartTimerAction : public AIAction {
|
||||
public:
|
||||
AIStartTimerAction(AITimerCondition *);
|
||||
|
||||
void performAIAction(AIRule *) override;
|
||||
|
||||
protected:
|
||||
AITimerCondition *_timerCondition;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AIActivateRuleAction
|
||||
|
||||
class AIActivateRuleAction : public AIAction {
|
||||
public:
|
||||
AIActivateRuleAction(AIRule *);
|
||||
|
||||
void performAIAction(AIRule *) override;
|
||||
|
||||
protected:
|
||||
AIRule *_rule;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AIDeactivateRuleAction
|
||||
|
||||
class AIDeactivateRuleAction : public AIAction {
|
||||
public:
|
||||
AIDeactivateRuleAction(AIRule *rule);
|
||||
|
||||
void performAIAction(AIRule *) override;
|
||||
|
||||
protected:
|
||||
AIRule *_rule;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
628
engines/pegasus/ai/ai_area.cpp
Normal file
628
engines/pegasus/ai/ai_area.cpp
Normal file
@@ -0,0 +1,628 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/memstream.h"
|
||||
|
||||
#include "pegasus/cursor.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/items/biochips/aichip.h"
|
||||
#include "pegasus/items/biochips/arthurchip.h"
|
||||
#include "pegasus/items/biochips/biochipitem.h"
|
||||
#include "pegasus/items/biochips/opticalchip.h"
|
||||
#include "pegasus/items/biochips/pegasuschip.h"
|
||||
#include "pegasus/items/inventory/airmask.h"
|
||||
#include "pegasus/items/inventory/inventoryitem.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
AIArea *g_AIArea = nullptr;
|
||||
|
||||
AIArea::AIArea(InputHandler *nextHandler) : InputHandler(nextHandler), _leftAreaMovie(kAILeftAreaID),
|
||||
_middleAreaMovie(kAIMiddleAreaID), _rightAreaMovie(kAIRightAreaID), _AIMovie(kAIMovieID) {
|
||||
g_AIArea = this;
|
||||
_leftAreaOwner = kNoClientSignature;
|
||||
_middleAreaOwner = kNoClientSignature;
|
||||
_rightAreaOwner = kNoClientSignature;
|
||||
_leftInventoryTime = 0xffffffff;
|
||||
_middleInventoryTime = 0xffffffff;
|
||||
_middleBiochipTime = 0xffffffff;
|
||||
_rightBiochipTime = 0xffffffff;
|
||||
_lockCount = 0;
|
||||
g_vm->requestToggle(false);
|
||||
startIdling();
|
||||
}
|
||||
|
||||
AIArea::~AIArea() {
|
||||
if (_middleAreaOwner == kBiochipSignature) {
|
||||
BiochipItem *currentBiochip = g_vm->getCurrentBiochip();
|
||||
if (currentBiochip && currentBiochip->isSelected())
|
||||
currentBiochip->giveUpSharedArea();
|
||||
} else if (_middleAreaOwner == kInventorySignature) {
|
||||
InventoryItem *currentItem = g_vm->getCurrentInventoryItem();
|
||||
if (currentItem && currentItem->isSelected())
|
||||
currentItem->giveUpSharedArea();
|
||||
}
|
||||
|
||||
stopIdling();
|
||||
|
||||
for (AIRuleList::iterator it = _AIRules.begin(); it != _AIRules.end(); it++)
|
||||
delete *it;
|
||||
|
||||
g_AIArea = nullptr;
|
||||
}
|
||||
|
||||
// Save last state of AI rules...
|
||||
void AIArea::saveAIState() {
|
||||
delete g_vm->_aiSaveStream;
|
||||
|
||||
Common::MemoryWriteStreamDynamic out(DisposeAfterUse::NO);
|
||||
writeAIRules(&out);
|
||||
|
||||
g_vm->_aiSaveStream = new Common::MemoryReadStream(out.getData(), out.size(), DisposeAfterUse::YES);
|
||||
}
|
||||
|
||||
void AIArea::restoreAIState() {
|
||||
if (g_vm->_aiSaveStream)
|
||||
readAIRules(g_vm->_aiSaveStream);
|
||||
}
|
||||
|
||||
void AIArea::writeAIRules(Common::WriteStream *stream) {
|
||||
_AIRules.writeAIRules(stream);
|
||||
}
|
||||
|
||||
void AIArea::readAIRules(Common::ReadStream *stream) {
|
||||
_AIRules.readAIRules(stream);
|
||||
}
|
||||
|
||||
void AIArea::initAIArea() {
|
||||
allocateSurface(Common::Rect(0, 0, 384, 96));
|
||||
|
||||
_leftAreaMovie.shareSurface(this);
|
||||
_leftAreaMovie.initFromMovieFile("Images/Items/Left Area Movie");
|
||||
_leftAreaMovie.moveElementTo(kAILeftAreaLeft, kAILeftAreaTop);
|
||||
_leftAreaMovie.setDisplayOrder(kAILeftAreaOrder);
|
||||
_leftAreaMovie.startDisplaying();
|
||||
_leftAreaMovie.setVolume(g_vm->getSoundFXLevel());
|
||||
|
||||
_middleAreaMovie.shareSurface(this);
|
||||
_middleAreaMovie.initFromMovieFile("Images/Items/Middle Area Movie");
|
||||
_middleAreaMovie.moveElementTo(kAIMiddleAreaLeft, kAIMiddleAreaTop);
|
||||
_middleAreaMovie.moveMovieBoxTo(kAIMiddleAreaLeft - kAILeftAreaLeft, 0);
|
||||
_middleAreaMovie.setDisplayOrder(kAIMiddleAreaOrder);
|
||||
_middleAreaMovie.startDisplaying();
|
||||
_middleAreaMovie.setVolume(g_vm->getSoundFXLevel());
|
||||
|
||||
_rightAreaMovie.shareSurface(this);
|
||||
_rightAreaMovie.initFromMovieFile("Images/Items/Right Area Movie");
|
||||
_rightAreaMovie.moveElementTo(kAIRightAreaLeft, kAIRightAreaTop);
|
||||
_rightAreaMovie.moveMovieBoxTo(kAIRightAreaLeft - kAILeftAreaLeft, 0);
|
||||
_rightAreaMovie.setDisplayOrder(kAIRightAreaOrder);
|
||||
_rightAreaMovie.startDisplaying();
|
||||
_rightAreaMovie.setVolume(g_vm->getSoundFXLevel());
|
||||
|
||||
_AIMovie.setDisplayOrder(kAIMovieOrder);
|
||||
}
|
||||
|
||||
void AIArea::setAIVolume(const uint16 volume) {
|
||||
_leftAreaMovie.setVolume(volume);
|
||||
_middleAreaMovie.setVolume(volume);
|
||||
_rightAreaMovie.setVolume(volume);
|
||||
}
|
||||
|
||||
// There are only so many legal combinations of client/area.
|
||||
// Here is the list of supported pairs:
|
||||
// kInventorySignature kLeftAreaSignature
|
||||
// kInventorySignature kMiddleAreaSignature
|
||||
// kBiochipSignature kMiddleAreaSignature
|
||||
// kBiochipSignature kRightAreaSignature
|
||||
// kAISignature kLeftAreaSignature
|
||||
// Further, the kAISignature never sets a static frame time in the left area,
|
||||
// but only plays a sequence.
|
||||
|
||||
// If this function is called while a sequence is playing, it will just "remember"
|
||||
// the time value, so that when the sequence finishes, the new time is asserted.
|
||||
|
||||
void AIArea::setAIAreaToTime(const LowerClientSignature client, const LowerAreaSignature area, const TimeValue time) {
|
||||
switch (area) {
|
||||
case kLeftAreaSignature:
|
||||
// Only support kInventorySignature client, since AI never calls SetAIAreaToTime.
|
||||
_leftAreaMovie.setSegment(0, _leftAreaMovie.getDuration());
|
||||
|
||||
if (time == 0xffffffff) {
|
||||
_leftAreaMovie.hide();
|
||||
_leftAreaOwner = kNoClientSignature;
|
||||
} else {
|
||||
setLeftMovieTime(time);
|
||||
}
|
||||
break;
|
||||
case kMiddleAreaSignature:
|
||||
// Only support kInventorySignature and kBiochipSignature clients.
|
||||
_middleAreaMovie.stop();
|
||||
_middleAreaMovie.setFlags(0);
|
||||
_middleAreaMovie.setSegment(0, _middleAreaMovie.getDuration());
|
||||
|
||||
if (time == 0xffffffff) {
|
||||
if (client == kInventorySignature) {
|
||||
if (_middleBiochipTime != 0xffffffff) {
|
||||
setMiddleMovieTime(kBiochipSignature, _middleBiochipTime);
|
||||
} else {
|
||||
_middleAreaMovie.hide();
|
||||
_middleAreaOwner = kNoClientSignature;
|
||||
}
|
||||
} else { // client == kBiochipSignature
|
||||
if (_middleInventoryTime != 0xffffffff) {
|
||||
setMiddleMovieTime(kInventorySignature, _middleInventoryTime);
|
||||
} else {
|
||||
_middleAreaMovie.hide();
|
||||
_middleAreaOwner = kNoClientSignature;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
setMiddleMovieTime(client, time);
|
||||
}
|
||||
break;
|
||||
case kRightAreaSignature:
|
||||
// Only support kBiochipSignature client.
|
||||
_rightAreaMovie.setSegment(0, _rightAreaMovie.getDuration());
|
||||
|
||||
if (time == 0xffffffff) {
|
||||
_rightAreaMovie.hide();
|
||||
_rightAreaOwner = kNoClientSignature;
|
||||
} else {
|
||||
setRightMovieTime(time);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Plays a sequence on an area. When the sequence ends, the previous image
|
||||
// is restored.
|
||||
// Also, is input disabled or not?
|
||||
// Easy answer: yes.
|
||||
|
||||
// There are only so many legal combinations of client/area.
|
||||
// Here is the list of supported pairs:
|
||||
// kBiochipSignature kMiddleAreaSignature
|
||||
// kBiochipSignature kRightAreaSignature
|
||||
// kInventorySignature kMiddleAreaSignature
|
||||
|
||||
void AIArea::playAIAreaSequence(const LowerClientSignature, const LowerAreaSignature area, const TimeValue start, const TimeValue stop) {
|
||||
lockAIOut();
|
||||
|
||||
switch (area) {
|
||||
case kLeftAreaSignature:
|
||||
break;
|
||||
case kMiddleAreaSignature:
|
||||
if (_middleAreaOwner == kInventorySignature)
|
||||
_middleInventoryTime = _middleAreaMovie.getTime();
|
||||
else if (_middleAreaOwner == kBiochipSignature)
|
||||
_middleBiochipTime = _middleAreaMovie.getTime();
|
||||
|
||||
_middleAreaMovie.stop();
|
||||
_middleAreaMovie.setFlags(0);
|
||||
_middleAreaMovie.setSegment(start, stop);
|
||||
_middleAreaMovie.setTime(start);
|
||||
_middleAreaMovie.show();
|
||||
_middleAreaMovie.start();
|
||||
g_vm->_cursor->hide();
|
||||
|
||||
while (_middleAreaMovie.isRunning()) {
|
||||
InputDevice.pumpEvents();
|
||||
g_vm->checkCallBacks();
|
||||
g_vm->refreshDisplay();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
|
||||
_middleAreaMovie.stop();
|
||||
g_vm->_cursor->hideUntilMoved();
|
||||
|
||||
if (_middleAreaOwner == kInventorySignature)
|
||||
setAIAreaToTime(_middleAreaOwner, kMiddleAreaSignature, _middleInventoryTime);
|
||||
else if (_middleAreaOwner == kBiochipSignature)
|
||||
setAIAreaToTime(_middleAreaOwner, kMiddleAreaSignature, _middleBiochipTime);
|
||||
else
|
||||
setAIAreaToTime(_middleAreaOwner, kMiddleAreaSignature, 0xffffffff);
|
||||
break;
|
||||
case kRightAreaSignature:
|
||||
_rightBiochipTime = _rightAreaMovie.getTime();
|
||||
_rightAreaMovie.setSegment(start, stop);
|
||||
_rightAreaMovie.setTime(start);
|
||||
_rightAreaMovie.show();
|
||||
_rightAreaMovie.start();
|
||||
g_vm->_cursor->hide();
|
||||
|
||||
while (_rightAreaMovie.isRunning()) {
|
||||
InputDevice.pumpEvents();
|
||||
g_vm->checkCallBacks();
|
||||
g_vm->refreshDisplay();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
|
||||
_rightAreaMovie.stop();
|
||||
g_vm->_cursor->hideUntilMoved();
|
||||
setAIAreaToTime(_rightAreaOwner, kRightAreaSignature, _rightBiochipTime);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
unlockAI();
|
||||
}
|
||||
|
||||
bool AIArea::playAIMovie(const LowerAreaSignature area, const Common::Path &movieName, bool keepLastFrame, const InputBits interruptFilter) {
|
||||
lockAIOut();
|
||||
|
||||
InputDevice.waitInput(interruptFilter);
|
||||
if (_AIMovie.isMovieValid())
|
||||
_AIMovie.releaseMovie();
|
||||
|
||||
_AIMovie.shareSurface(this);
|
||||
_AIMovie.initFromMovieFile(movieName);
|
||||
|
||||
if (area == kLeftAreaSignature) {
|
||||
_AIMovie.moveElementTo(kAILeftAreaLeft, kAILeftAreaTop);
|
||||
_leftAreaMovie.hide();
|
||||
} else {
|
||||
_AIMovie.moveElementTo(kAIRightAreaLeft, kAIRightAreaTop);
|
||||
_AIMovie.moveMovieBoxTo(kAIRightAreaLeft - kAILeftAreaLeft, 0);
|
||||
_rightAreaMovie.hide();
|
||||
}
|
||||
|
||||
_AIMovie.setTime(0);
|
||||
_AIMovie.startDisplaying();
|
||||
_AIMovie.show();
|
||||
_AIMovie.redrawMovieWorld();
|
||||
_AIMovie.setVolume(g_vm->getSoundFXLevel());
|
||||
_AIMovie.start();
|
||||
g_vm->_cursor->hide();
|
||||
|
||||
bool result = true;
|
||||
bool saveAllowed = g_vm->swapSaveAllowed(false);
|
||||
bool openAllowed = g_vm->swapLoadAllowed(false);
|
||||
|
||||
while (_AIMovie.isRunning()) {
|
||||
Input input;
|
||||
InputDevice.getInput(input, interruptFilter);
|
||||
|
||||
if (input.anyInput() || g_vm->shouldQuit() || g_vm->saveRequested() || g_vm->loadRequested()) {
|
||||
result = false;
|
||||
break;
|
||||
}
|
||||
|
||||
g_vm->checkCallBacks();
|
||||
g_vm->refreshDisplay();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
|
||||
_AIMovie.stop();
|
||||
|
||||
g_vm->swapSaveAllowed(saveAllowed);
|
||||
g_vm->swapLoadAllowed(openAllowed);
|
||||
|
||||
// This used to keep the last frame up even if the movie was interrupted.
|
||||
// However, this only occurs in the recalibration, where interruption means skip the
|
||||
// whole thing, so skipping causes the AI to go away even when keepLastFrame is true.
|
||||
|
||||
if (!(result && keepLastFrame)) {
|
||||
_AIMovie.stopDisplaying();
|
||||
_AIMovie.releaseMovie();
|
||||
|
||||
if (area == kLeftAreaSignature) {
|
||||
_leftAreaMovie.setTime(_leftInventoryTime);
|
||||
_leftAreaMovie.show();
|
||||
_leftAreaMovie.redrawMovieWorld();
|
||||
} else {
|
||||
_rightAreaMovie.setTime(_rightBiochipTime);
|
||||
_rightAreaMovie.show();
|
||||
_rightAreaMovie.redrawMovieWorld();
|
||||
}
|
||||
}
|
||||
|
||||
g_vm->_cursor->hideUntilMoved();
|
||||
unlockAI();
|
||||
return result;
|
||||
}
|
||||
|
||||
// Only implemented for kMiddleAreaSignature, kInventorySignature
|
||||
void AIArea::loopAIAreaSequence(const LowerClientSignature owner, const LowerAreaSignature area, const TimeValue start, const TimeValue stop) {
|
||||
if (area == kMiddleAreaSignature && owner == kInventorySignature && owner == _middleAreaOwner) {
|
||||
_middleAreaMovie.stop();
|
||||
_middleAreaMovie.setFlags(0);
|
||||
_middleAreaMovie.setSegment(start, stop);
|
||||
_middleAreaMovie.setFlags(kLoopTimeBase);
|
||||
_middleAreaMovie.setTime(start);
|
||||
_middleAreaMovie.show();
|
||||
_middleAreaMovie.start();
|
||||
}
|
||||
}
|
||||
|
||||
// Only called by kInventorySignature.
|
||||
void AIArea::setLeftMovieTime(const TimeValue time) {
|
||||
if (!_AIMovie.isSurfaceValid()) {
|
||||
_leftAreaMovie.setTime(time);
|
||||
_leftAreaMovie.show();
|
||||
_leftAreaMovie.redrawMovieWorld();
|
||||
}
|
||||
|
||||
_leftAreaOwner = kInventorySignature;
|
||||
_leftInventoryTime = time;
|
||||
}
|
||||
|
||||
void AIArea::setMiddleMovieTime(const LowerClientSignature client, const TimeValue time) {
|
||||
if (client == kInventorySignature) {
|
||||
_middleInventoryTime = time;
|
||||
if (_middleAreaOwner == kBiochipSignature) {
|
||||
BiochipItem *currentBiochip = g_vm->getCurrentBiochip();
|
||||
if (currentBiochip && currentBiochip->isSelected())
|
||||
currentBiochip->giveUpSharedArea();
|
||||
}
|
||||
} else {
|
||||
_middleBiochipTime = time;
|
||||
if (_middleAreaOwner == kInventorySignature) {
|
||||
InventoryItem *currentItem = g_vm->getCurrentInventoryItem();
|
||||
if (currentItem && currentItem->isSelected())
|
||||
currentItem->giveUpSharedArea();
|
||||
}
|
||||
}
|
||||
|
||||
_middleAreaMovie.setSegment(0, _middleAreaMovie.getDuration());
|
||||
_middleAreaMovie.stop();
|
||||
_middleAreaMovie.setFlags(0);
|
||||
_middleAreaMovie.setTime(time);
|
||||
_middleAreaMovie.show();
|
||||
_middleAreaMovie.redrawMovieWorld();
|
||||
_middleAreaOwner = client;
|
||||
}
|
||||
|
||||
// Only called by kBiochipSignature.
|
||||
void AIArea::setRightMovieTime(const TimeValue time) {
|
||||
if (!_AIMovie.isSurfaceValid()) {
|
||||
// Can't do it when the AI movie is up...
|
||||
_rightAreaMovie.setTime(time);
|
||||
_rightAreaMovie.show();
|
||||
_rightAreaMovie.redrawMovieWorld();
|
||||
}
|
||||
|
||||
_rightAreaOwner = kBiochipSignature;
|
||||
_rightBiochipTime = time;
|
||||
}
|
||||
|
||||
void AIArea::handleInput(const Input &input, const Hotspot *cursorSpot) {
|
||||
if (JMPPPInput::isToggleAIMiddleInput(input))
|
||||
toggleMiddleAreaOwner();
|
||||
else
|
||||
InputHandler::handleInput(input, cursorSpot);
|
||||
}
|
||||
|
||||
void AIArea::toggleMiddleAreaOwner() {
|
||||
if (_middleAreaOwner == kInventorySignature) {
|
||||
BiochipItem *currentBiochip = g_vm->getCurrentBiochip();
|
||||
if (currentBiochip) {
|
||||
setMiddleMovieTime(kBiochipSignature, currentBiochip->getSharedAreaTime());
|
||||
currentBiochip->takeSharedArea();
|
||||
}
|
||||
} else if (_middleAreaOwner == kBiochipSignature) {
|
||||
InventoryItem *currentItem = g_vm->getCurrentInventoryItem();
|
||||
if (currentItem) {
|
||||
setMiddleMovieTime(kInventorySignature, currentItem->getSharedAreaTime());
|
||||
currentItem->takeSharedArea();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AIArea::activateHotspots() {
|
||||
if (_middleAreaOwner == kBiochipSignature) {
|
||||
BiochipItem *currentBiochip = g_vm->getCurrentBiochip();
|
||||
if (currentBiochip)
|
||||
switch (currentBiochip->getObjectID()) {
|
||||
case kAIBiochip:
|
||||
((AIChip *)currentBiochip)->activateAIHotspots();
|
||||
break;
|
||||
case kPegasusBiochip:
|
||||
if (!g_vm->isDemo())
|
||||
((PegasusChip *)currentBiochip)->activatePegasusHotspots();
|
||||
break;
|
||||
case kOpticalBiochip:
|
||||
((OpticalChip *)currentBiochip)->activateOpticalHotspots();
|
||||
break;
|
||||
case kArthurBiochip:
|
||||
if (g_vm->isDVD())
|
||||
((ArthurChip *)currentBiochip)->activateArthurHotspots();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if (_middleAreaOwner == kInventorySignature) {
|
||||
InventoryItem *currentItem = g_vm->getCurrentInventoryItem();
|
||||
if (currentItem && currentItem->getObjectID() == kAirMask)
|
||||
((AirMask *)currentItem)->activateAirMaskHotspots();
|
||||
}
|
||||
|
||||
InputHandler::activateHotspots();
|
||||
}
|
||||
|
||||
void AIArea::clickInHotspot(const Input &input, const Hotspot *hotspot) {
|
||||
bool handled = false;
|
||||
|
||||
if (_middleAreaOwner == kBiochipSignature) {
|
||||
BiochipItem *currentBiochip = g_vm->getCurrentBiochip();
|
||||
|
||||
if (currentBiochip) {
|
||||
switch (currentBiochip->getObjectID()) {
|
||||
case kAIBiochip:
|
||||
if ((hotspot->getHotspotFlags() & kAIBiochipSpotFlag) != 0) {
|
||||
((AIChip *)currentBiochip)->clickInAIHotspot(hotspot->getObjectID());
|
||||
handled = true;
|
||||
}
|
||||
break;
|
||||
case kPegasusBiochip:
|
||||
if (!g_vm->isDemo() && ((hotspot->getHotspotFlags() & kPegasusBiochipSpotFlag) != 0)) {
|
||||
((PegasusChip *)currentBiochip)->clickInPegasusHotspot();
|
||||
handled = true;
|
||||
}
|
||||
break;
|
||||
case kOpticalBiochip:
|
||||
if ((hotspot->getHotspotFlags() & kOpticalBiochipSpotFlag) != 0) {
|
||||
((OpticalChip *)currentBiochip)->clickInOpticalHotspot(hotspot->getObjectID());
|
||||
handled = true;
|
||||
}
|
||||
break;
|
||||
case kArthurBiochip:
|
||||
if (g_vm->isDVD() && (hotspot->getHotspotFlags() & kArthurBiochipSpotFlag) != 0) {
|
||||
((ArthurChip *)currentBiochip)->clickInArthurHotspot(hotspot->getObjectID());
|
||||
handled = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (_middleAreaOwner == kInventorySignature) {
|
||||
InventoryItem *currentItem = g_vm->getCurrentInventoryItem();
|
||||
|
||||
if (currentItem) {
|
||||
switch (currentItem->getObjectID()) {
|
||||
case kAirMask:
|
||||
if ((hotspot->getHotspotFlags() & kAirMaskSpotFlag) != 0) {
|
||||
((AirMask *)currentItem)->clickInAirMaskHotspot();
|
||||
handled = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!handled)
|
||||
InputHandler::clickInHotspot(input, hotspot);
|
||||
}
|
||||
|
||||
void AIArea::lockAIOut() {
|
||||
if (_lockCount == 0)
|
||||
stopIdling();
|
||||
|
||||
_lockCount++;
|
||||
}
|
||||
|
||||
void AIArea::unlockAI() {
|
||||
if (_lockCount > 0) {
|
||||
_lockCount--;
|
||||
if (_lockCount == 0)
|
||||
startIdling();
|
||||
}
|
||||
}
|
||||
|
||||
void AIArea::forceAIUnlocked() {
|
||||
if (_lockCount > 0) {
|
||||
_lockCount = 1;
|
||||
unlockAI();
|
||||
}
|
||||
}
|
||||
|
||||
void AIArea::checkRules() {
|
||||
if (_lockCount == 0 && g_vm->playerAlive())
|
||||
for (AIRuleList::iterator it = _AIRules.begin(); it != _AIRules.end(); it++)
|
||||
if ((*it)->fireRule())
|
||||
break;
|
||||
}
|
||||
|
||||
void AIArea::useIdleTime() {
|
||||
checkRules();
|
||||
}
|
||||
|
||||
void AIArea::addAIRule(AIRule *rule) {
|
||||
_AIRules.push_back(rule);
|
||||
}
|
||||
|
||||
void AIArea::removeAllRules() {
|
||||
for (AIRuleList::iterator it = _AIRules.begin(); it != _AIRules.end(); it++)
|
||||
delete *it;
|
||||
|
||||
_AIRules.clear();
|
||||
}
|
||||
|
||||
void AIArea::checkMiddleArea() {
|
||||
BiochipItem *currentBiochip = g_vm->getCurrentBiochip();
|
||||
|
||||
if (currentBiochip) {
|
||||
if (_middleAreaOwner == kBiochipSignature) {
|
||||
switch (currentBiochip->getObjectID()) {
|
||||
case kAIBiochip:
|
||||
((AIChip *)currentBiochip)->setUpAIChip();
|
||||
break;
|
||||
case kPegasusBiochip:
|
||||
((PegasusChip *)currentBiochip)->setUpPegasusChip();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (currentBiochip->getObjectID()) {
|
||||
case kAIBiochip:
|
||||
((AIChip *)currentBiochip)->setUpAIChipRude();
|
||||
break;
|
||||
case kPegasusBiochip:
|
||||
((PegasusChip *)currentBiochip)->setUpPegasusChipRude();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TimeValue AIArea::getBigInfoTime() {
|
||||
if (_middleAreaOwner == kInventorySignature) {
|
||||
InventoryItem *currentItem = g_vm->getCurrentInventoryItem();
|
||||
return currentItem->getInfoLeftTime();
|
||||
} else if (_middleAreaOwner == kBiochipSignature) {
|
||||
BiochipItem *currentBiochip = g_vm->getCurrentBiochip();
|
||||
return currentBiochip->getInfoLeftTime();
|
||||
}
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
|
||||
void AIArea::getSmallInfoSegment(TimeValue &start, TimeValue &stop) {
|
||||
if (_middleAreaOwner == kInventorySignature) {
|
||||
InventoryItem *currentItem = g_vm->getCurrentInventoryItem();
|
||||
currentItem->getInfoRightTimes(start, stop);
|
||||
} else if (_middleAreaOwner == kBiochipSignature) {
|
||||
BiochipItem *currentBiochip = g_vm->getCurrentBiochip();
|
||||
currentBiochip->getInfoRightTimes(start, stop);
|
||||
} else {
|
||||
start = 0xffffffff;
|
||||
stop = 0xffffffff;
|
||||
}
|
||||
}
|
||||
|
||||
LowerClientSignature AIArea::getMiddleAreaOwner() {
|
||||
return _middleAreaOwner;
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
171
engines/pegasus/ai/ai_area.h
Normal file
171
engines/pegasus/ai/ai_area.h
Normal file
@@ -0,0 +1,171 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_AI_AIAREA_H
|
||||
#define PEGASUS_AI_AIAREA_H
|
||||
|
||||
#include "pegasus/input.h"
|
||||
#include "pegasus/movie.h"
|
||||
#include "pegasus/timers.h"
|
||||
#include "pegasus/ai/ai_rule.h"
|
||||
|
||||
namespace Common {
|
||||
class ReadStream;
|
||||
class WriteStream;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
The AI area is the area at the bottom of the screen. There are three areas within
|
||||
the AI area:
|
||||
1) the inventory/AI help area
|
||||
2) the middle area
|
||||
3) the biochip display area
|
||||
|
||||
Area 1 is used for displaying the current inventory item. When the player changes the
|
||||
current item, either by selecting a new one in the inventory list or by picking
|
||||
up a new item, area 1 updates to show the new item.
|
||||
|
||||
If the AI decides to give a message, the AI's head temporarily takes over area 1
|
||||
for the duration of the message, then goes away, returning the area to the current
|
||||
inventory item.
|
||||
|
||||
Area 2 is used to display the current inventory item's state, the current biochip's
|
||||
state, and any extra information from the AI. The contention for this area is
|
||||
resolved as follows:
|
||||
-- If the AI needs to use the area while giving a message in area 1, it takes over
|
||||
area 2 for the duration of its message.
|
||||
*** This is not true.
|
||||
-- If the player selects a new inventory item, the inventory item's state gets
|
||||
displayed immediately.
|
||||
-- If the player selects a new biochip, the biochip's state info gets displayed
|
||||
immediately.
|
||||
-- If any auto drawing is to occur, it seizes the area as soon as the drawing is
|
||||
to occur. For example, the mapping biochip does auto drawing every time the
|
||||
player takes a step. The only exception to this rule is if the AI is presenting
|
||||
a warning. When the AI seizes areas 1 and 2, it preempts all other uses.
|
||||
Some inventory items and biochips can cause arbitrary drawing to occur in this area
|
||||
at arbitrary times. The map biochip is one example which causes drawing when the
|
||||
player takes a step. Another example is the poison gas canister, which flashes in
|
||||
this area to indicate a dangerous compound.
|
||||
|
||||
Area 3 is used to display the current biochip. When the player changes the current
|
||||
biochip, either by selecting a new one from the biochip list or by picking up a
|
||||
new one, area 3 updates to show the new item. In addition, some biochips can play
|
||||
animation in this area.
|
||||
|
||||
*/
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class AIArea : public Surface, public Idler, public InputHandler {
|
||||
public:
|
||||
AIArea(InputHandler *);
|
||||
~AIArea() override;
|
||||
|
||||
void writeAIRules(Common::WriteStream *stream);
|
||||
void readAIRules(Common::ReadStream *stream);
|
||||
|
||||
void initAIArea();
|
||||
|
||||
void saveAIState();
|
||||
void restoreAIState();
|
||||
|
||||
void handleInput(const Input &, const Hotspot *) override;
|
||||
void activateHotspots() override;
|
||||
void clickInHotspot(const Input &, const Hotspot *) override;
|
||||
|
||||
void setAIVolume(const uint16);
|
||||
|
||||
// There are only so many legal combinations of client/area.
|
||||
// Here is the list of supported pairs:
|
||||
// kInventorySignature kLeftAreaSignature
|
||||
// kInventorySignature kMiddleAreaSignature
|
||||
// kBiochipSignature kMiddleAreaSignature
|
||||
// kBiochipSignature kRightAreaSignature
|
||||
// kAISignature kLeftAreaSignature
|
||||
// Further, the kAISignature never sets a static frame time in the left area,
|
||||
// but only plays a sequence from the AI movie.
|
||||
void setAIAreaToTime(const LowerClientSignature, const LowerAreaSignature, const TimeValue);
|
||||
|
||||
// The "Play" functions play the requested sequence synchronously.
|
||||
void playAIAreaSequence(const LowerClientSignature, const LowerAreaSignature, const TimeValue, const TimeValue);
|
||||
|
||||
// For PlayAIMovie, it is assumed that the client is the AI itself.
|
||||
// This is used to play AI messages as well as Optical Memory video.
|
||||
// Returns true if the movie played all the way through, false if it was interrupted.
|
||||
bool playAIMovie(const LowerAreaSignature, const Common::Path &movieName, bool keepLastFrame, const InputBits);
|
||||
|
||||
// Loop the requested sequence indefinitely.
|
||||
void loopAIAreaSequence(const LowerClientSignature, const LowerAreaSignature, const TimeValue, const TimeValue);
|
||||
|
||||
void addAIRule(AIRule *);
|
||||
|
||||
// Remove and delete all rules.
|
||||
void removeAllRules();
|
||||
|
||||
void lockAIOut();
|
||||
void unlockAI();
|
||||
void forceAIUnlocked();
|
||||
|
||||
void checkMiddleArea();
|
||||
void checkRules();
|
||||
|
||||
LowerClientSignature getMiddleAreaOwner();
|
||||
void toggleMiddleAreaOwner();
|
||||
|
||||
TimeValue getBigInfoTime();
|
||||
void getSmallInfoSegment(TimeValue &, TimeValue &);
|
||||
|
||||
protected:
|
||||
void useIdleTime() override;
|
||||
|
||||
void setLeftMovieTime(const TimeValue);
|
||||
void setMiddleMovieTime(const LowerClientSignature, const TimeValue);
|
||||
void setRightMovieTime(const TimeValue);
|
||||
|
||||
Movie _leftAreaMovie;
|
||||
Movie _middleAreaMovie;
|
||||
Movie _rightAreaMovie;
|
||||
Movie _AIMovie;
|
||||
|
||||
LowerClientSignature _leftAreaOwner;
|
||||
LowerClientSignature _middleAreaOwner;
|
||||
LowerClientSignature _rightAreaOwner;
|
||||
|
||||
TimeValue _leftInventoryTime;
|
||||
TimeValue _middleInventoryTime;
|
||||
TimeValue _middleBiochipTime;
|
||||
TimeValue _rightBiochipTime;
|
||||
|
||||
AIRuleList _AIRules;
|
||||
|
||||
uint _lockCount;
|
||||
};
|
||||
|
||||
extern AIArea *g_AIArea;
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
289
engines/pegasus/ai/ai_condition.cpp
Normal file
289
engines/pegasus/ai/ai_condition.cpp
Normal file
@@ -0,0 +1,289 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/stream.h"
|
||||
|
||||
#include "pegasus/energymonitor.h"
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/ai/ai_condition.h"
|
||||
#include "pegasus/items/itemlist.h"
|
||||
#include "pegasus/items/biochips/biochipitem.h"
|
||||
#include "pegasus/items/inventory/inventoryitem.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
AIOneChildCondition::AIOneChildCondition(AICondition *child) {
|
||||
_child = child;
|
||||
}
|
||||
|
||||
AIOneChildCondition::~AIOneChildCondition() {
|
||||
delete _child;
|
||||
}
|
||||
|
||||
void AIOneChildCondition::writeAICondition(Common::WriteStream *stream) {
|
||||
if (_child)
|
||||
_child->writeAICondition(stream);
|
||||
}
|
||||
|
||||
void AIOneChildCondition::readAICondition(Common::ReadStream *stream) {
|
||||
if (_child)
|
||||
_child->readAICondition(stream);
|
||||
}
|
||||
|
||||
AITwoChildrenCondition::AITwoChildrenCondition(AICondition *leftChild, AICondition *rightChild) {
|
||||
_leftChild = leftChild;
|
||||
_rightChild = rightChild;
|
||||
}
|
||||
|
||||
AITwoChildrenCondition::~AITwoChildrenCondition() {
|
||||
delete _leftChild;
|
||||
delete _rightChild;
|
||||
}
|
||||
|
||||
void AITwoChildrenCondition::writeAICondition(Common::WriteStream *stream) {
|
||||
if (_leftChild)
|
||||
_leftChild->writeAICondition(stream);
|
||||
|
||||
if (_rightChild)
|
||||
_rightChild->writeAICondition(stream);
|
||||
}
|
||||
|
||||
void AITwoChildrenCondition::readAICondition(Common::ReadStream *stream) {
|
||||
if (_leftChild)
|
||||
_leftChild->readAICondition(stream);
|
||||
|
||||
if (_rightChild)
|
||||
_rightChild->readAICondition(stream);
|
||||
}
|
||||
|
||||
AINotCondition::AINotCondition(AICondition* child) : AIOneChildCondition(child) {
|
||||
}
|
||||
|
||||
bool AINotCondition::fireCondition() {
|
||||
return _child && !_child->fireCondition();
|
||||
}
|
||||
|
||||
AIAndCondition::AIAndCondition(AICondition *leftChild, AICondition *rightChild) : AITwoChildrenCondition(leftChild, rightChild) {
|
||||
}
|
||||
|
||||
bool AIAndCondition::fireCondition() {
|
||||
return _leftChild && _leftChild->fireCondition() && _rightChild && _rightChild->fireCondition();
|
||||
}
|
||||
|
||||
AIOrCondition::AIOrCondition(AICondition *leftChild, AICondition *rightChild) : AITwoChildrenCondition(leftChild, rightChild) {
|
||||
}
|
||||
|
||||
bool AIOrCondition::fireCondition() {
|
||||
return (_leftChild && _leftChild->fireCondition()) || (_rightChild && _rightChild->fireCondition());
|
||||
}
|
||||
|
||||
AITimerCondition::AITimerCondition(const TimeValue time, const TimeScale scale, const bool shouldStartTimer) {
|
||||
_timerFuse.primeFuse(time, scale);
|
||||
_timerFuse.setFunctor(new Common::Functor0Mem<void, AITimerCondition>(this, &AITimerCondition::fire));
|
||||
_fired = false;
|
||||
|
||||
if (shouldStartTimer)
|
||||
startTimer();
|
||||
}
|
||||
|
||||
void AITimerCondition::startTimer() {
|
||||
_fired = false;
|
||||
_timerFuse.lightFuse();
|
||||
}
|
||||
|
||||
void AITimerCondition::stopTimer() {
|
||||
_timerFuse.stopFuse();
|
||||
}
|
||||
|
||||
void AITimerCondition::writeAICondition(Common::WriteStream *stream) {
|
||||
stream->writeByte(_timerFuse.isFuseLit());
|
||||
stream->writeByte(_fired);
|
||||
stream->writeUint32BE(_timerFuse.getTimeRemaining());
|
||||
stream->writeUint32BE(_timerFuse.getFuseScale());
|
||||
}
|
||||
|
||||
void AITimerCondition::readAICondition(Common::ReadStream *stream) {
|
||||
bool running = stream->readByte();
|
||||
_fired = stream->readByte();
|
||||
TimeValue time = stream->readUint32BE();
|
||||
TimeScale scale = stream->readUint32BE();
|
||||
|
||||
_timerFuse.stopFuse();
|
||||
_timerFuse.primeFuse(time, scale);
|
||||
|
||||
if (running)
|
||||
_timerFuse.lightFuse();
|
||||
}
|
||||
|
||||
bool AITimerCondition::fireCondition() {
|
||||
return _fired;
|
||||
}
|
||||
|
||||
void AITimerCondition::fire() {
|
||||
_fired = true;
|
||||
}
|
||||
|
||||
AILocationCondition::AILocationCondition(uint32 maxLocations) {
|
||||
_numLocations = 0;
|
||||
_maxLocations = maxLocations;
|
||||
_locations = new RoomViewID[maxLocations];
|
||||
}
|
||||
|
||||
AILocationCondition::~AILocationCondition() {
|
||||
delete[] _locations;
|
||||
}
|
||||
|
||||
void AILocationCondition::addLocation(const RoomViewID location) {
|
||||
if (_numLocations < _maxLocations)
|
||||
_locations[_numLocations++] = location;
|
||||
}
|
||||
|
||||
bool AILocationCondition::fireCondition() {
|
||||
RoomViewID test = GameState.getCurrentRoomAndView(), *p;
|
||||
uint32 i;
|
||||
|
||||
for (i = 0, p = _locations; i < _numLocations; i++, p++) {
|
||||
if (test == *p) {
|
||||
*p = MakeRoomView(kNoRoomID, kNoDirection);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AILocationCondition::writeAICondition(Common::WriteStream *stream) {
|
||||
stream->writeUint32BE(_maxLocations);
|
||||
stream->writeUint32BE(_numLocations);
|
||||
|
||||
uint32 i;
|
||||
RoomViewID *p;
|
||||
for (i = 0, p = _locations; i < _numLocations; i++, p++)
|
||||
stream->writeUint32BE(*p);
|
||||
}
|
||||
|
||||
void AILocationCondition::readAICondition(Common::ReadStream *stream) {
|
||||
uint32 maxLocations = stream->readUint32BE();
|
||||
|
||||
if (_maxLocations != maxLocations) {
|
||||
delete[] _locations;
|
||||
_locations = new RoomViewID[maxLocations];
|
||||
_maxLocations = maxLocations;
|
||||
}
|
||||
|
||||
_numLocations = stream->readUint32BE();
|
||||
|
||||
uint32 i;
|
||||
RoomViewID *p;
|
||||
for (i = 0, p = _locations; i < _numLocations; i++, p++)
|
||||
*p = stream->readUint32BE();
|
||||
}
|
||||
|
||||
AIDoorOpenedCondition::AIDoorOpenedCondition(RoomViewID doorLocation) {
|
||||
_doorLocation = doorLocation;
|
||||
}
|
||||
|
||||
bool AIDoorOpenedCondition::fireCondition() {
|
||||
return GameState.getCurrentRoomAndView() == _doorLocation && GameState.isCurrentDoorOpen();
|
||||
}
|
||||
|
||||
AIHasItemCondition::AIHasItemCondition(const ItemID item) {
|
||||
_item = item;
|
||||
}
|
||||
|
||||
bool AIHasItemCondition::fireCondition() {
|
||||
return _item == kNoItemID || GameState.isTakenItemID(_item);
|
||||
}
|
||||
|
||||
AIDoesntHaveItemCondition::AIDoesntHaveItemCondition(const ItemID item) {
|
||||
_item = item;
|
||||
}
|
||||
|
||||
bool AIDoesntHaveItemCondition::fireCondition() {
|
||||
return _item == kNoItemID || !GameState.isTakenItemID(_item);
|
||||
}
|
||||
|
||||
AICurrentItemCondition::AICurrentItemCondition(const ItemID item) {
|
||||
_item = item;
|
||||
}
|
||||
|
||||
bool AICurrentItemCondition::fireCondition() {
|
||||
InventoryItem *item = g_vm->getCurrentInventoryItem();
|
||||
|
||||
if (_item == kNoItemID)
|
||||
return item == nullptr;
|
||||
|
||||
return item != nullptr && item->getObjectID() == _item;
|
||||
}
|
||||
|
||||
AICurrentBiochipCondition::AICurrentBiochipCondition(const ItemID biochip) {
|
||||
_biochip = biochip;
|
||||
}
|
||||
|
||||
bool AICurrentBiochipCondition::fireCondition() {
|
||||
BiochipItem *biochip = g_vm->getCurrentBiochip();
|
||||
|
||||
if (_biochip == kNoItemID)
|
||||
return biochip == nullptr;
|
||||
|
||||
return biochip != nullptr && biochip->getObjectID() == _biochip;
|
||||
}
|
||||
|
||||
AIItemStateCondition::AIItemStateCondition(const ItemID item, const ItemState state) {
|
||||
_item = item;
|
||||
_state = state;
|
||||
}
|
||||
|
||||
bool AIItemStateCondition::fireCondition() {
|
||||
Item *item = g_allItems.findItemByID(_item);
|
||||
return item != nullptr && item->getItemState() == _state;
|
||||
}
|
||||
|
||||
AIEnergyMonitorCondition::AIEnergyMonitorCondition(const int32 energyThreshold) {
|
||||
_energyThreshold = energyThreshold;
|
||||
}
|
||||
|
||||
bool AIEnergyMonitorCondition::fireCondition() {
|
||||
return g_energyMonitor != nullptr && g_energyMonitor->getCurrentEnergy() < _energyThreshold;
|
||||
}
|
||||
|
||||
AILastExtraCondition::AILastExtraCondition(const ExtraID lastExtra) {
|
||||
_lastExtra = lastExtra;
|
||||
}
|
||||
|
||||
bool AILastExtraCondition::fireCondition() {
|
||||
return g_neighborhood && (ExtraID)g_neighborhood->getLastExtra() == _lastExtra;
|
||||
}
|
||||
|
||||
AICondition *makeLocationAndDoesntHaveItemCondition(const RoomID room, const DirectionConstant direction, const ItemID item) {
|
||||
AILocationCondition *location = new AILocationCondition(1);
|
||||
location->addLocation(MakeRoomView(room, direction));
|
||||
|
||||
AIDoesntHaveItemCondition *doesntHaveItem = new AIDoesntHaveItemCondition(item);
|
||||
|
||||
return new AIAndCondition(location, doesntHaveItem);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
286
engines/pegasus/ai/ai_condition.h
Normal file
286
engines/pegasus/ai/ai_condition.h
Normal file
@@ -0,0 +1,286 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_AI_AICONDITION_H
|
||||
#define PEGASUS_AI_AICONDITION_H
|
||||
|
||||
#include "pegasus/timers.h"
|
||||
|
||||
namespace Common {
|
||||
class ReadStream;
|
||||
class WriteStream;
|
||||
}
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AICondition
|
||||
|
||||
class AICondition {
|
||||
public:
|
||||
AICondition() {}
|
||||
virtual ~AICondition() {}
|
||||
|
||||
virtual bool fireCondition() = 0;
|
||||
|
||||
// Only need these for conditions that are dynamic, like timer conditions...
|
||||
// other conditions, like item related conditions, which don't change during
|
||||
// the run of an environment, are completely initted when the environment
|
||||
// is created.
|
||||
virtual void writeAICondition(Common::WriteStream *) {}
|
||||
virtual void readAICondition(Common::ReadStream *) {}
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AIOneChildCondition
|
||||
|
||||
class AIOneChildCondition : public AICondition {
|
||||
public:
|
||||
AIOneChildCondition(AICondition *);
|
||||
~AIOneChildCondition() override;
|
||||
|
||||
void writeAICondition(Common::WriteStream *) override;
|
||||
void readAICondition(Common::ReadStream *) override;
|
||||
|
||||
protected:
|
||||
AICondition *_child;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AITwoChildrenCondition
|
||||
|
||||
class AITwoChildrenCondition : public AICondition {
|
||||
public:
|
||||
AITwoChildrenCondition(AICondition *, AICondition *);
|
||||
~AITwoChildrenCondition() override;
|
||||
|
||||
void writeAICondition(Common::WriteStream *) override;
|
||||
void readAICondition(Common::ReadStream *) override;
|
||||
|
||||
protected:
|
||||
AICondition *_leftChild, *_rightChild;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AINotCondition
|
||||
|
||||
class AINotCondition : public AIOneChildCondition {
|
||||
public:
|
||||
AINotCondition(AICondition *);
|
||||
|
||||
bool fireCondition() override;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AIAndCondition
|
||||
|
||||
class AIAndCondition : public AITwoChildrenCondition {
|
||||
public:
|
||||
AIAndCondition(AICondition *, AICondition *);
|
||||
|
||||
bool fireCondition() override;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AIOrCondition
|
||||
|
||||
class AIOrCondition : public AITwoChildrenCondition {
|
||||
public:
|
||||
AIOrCondition(AICondition *, AICondition *);
|
||||
|
||||
bool fireCondition() override;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AITimerCondition
|
||||
|
||||
class AITimerCondition : public AICondition {
|
||||
public:
|
||||
AITimerCondition(const TimeValue, const TimeScale, const bool);
|
||||
|
||||
void startTimer();
|
||||
void stopTimer();
|
||||
|
||||
bool fireCondition() override;
|
||||
|
||||
void writeAICondition(Common::WriteStream *) override;
|
||||
void readAICondition(Common::ReadStream *) override;
|
||||
|
||||
protected:
|
||||
void fire();
|
||||
|
||||
FuseFunction _timerFuse;
|
||||
bool _fired;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AILocationCondition
|
||||
|
||||
class AILocationCondition : public AICondition {
|
||||
public:
|
||||
AILocationCondition(uint32);
|
||||
~AILocationCondition() override;
|
||||
|
||||
void addLocation(RoomViewID);
|
||||
bool fireCondition() override;
|
||||
|
||||
void writeAICondition(Common::WriteStream *) override;
|
||||
void readAICondition(Common::ReadStream *) override;
|
||||
|
||||
protected:
|
||||
uint32 _numLocations, _maxLocations;
|
||||
RoomViewID *_locations;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AIDoorOpenedCondition
|
||||
|
||||
class AIDoorOpenedCondition : public AICondition {
|
||||
public:
|
||||
AIDoorOpenedCondition(RoomViewID);
|
||||
~AIDoorOpenedCondition() override {}
|
||||
|
||||
bool fireCondition() override;
|
||||
|
||||
protected:
|
||||
RoomViewID _doorLocation;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AIHasItemCondition
|
||||
|
||||
class AIHasItemCondition : public AICondition {
|
||||
public:
|
||||
AIHasItemCondition(const ItemID);
|
||||
|
||||
bool fireCondition() override;
|
||||
|
||||
protected:
|
||||
ItemID _item;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AIDoesntHaveItemCondition
|
||||
|
||||
class AIDoesntHaveItemCondition : public AICondition {
|
||||
public:
|
||||
AIDoesntHaveItemCondition(const ItemID);
|
||||
|
||||
bool fireCondition() override;
|
||||
|
||||
protected:
|
||||
ItemID _item;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AICurrentItemCondition
|
||||
|
||||
class AICurrentItemCondition : public AICondition {
|
||||
public:
|
||||
AICurrentItemCondition(const ItemID);
|
||||
|
||||
bool fireCondition() override;
|
||||
|
||||
protected:
|
||||
ItemID _item;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AICurrentBiochipCondition
|
||||
|
||||
class AICurrentBiochipCondition : public AICondition {
|
||||
public:
|
||||
AICurrentBiochipCondition(const ItemID);
|
||||
|
||||
bool fireCondition() override;
|
||||
|
||||
protected:
|
||||
ItemID _biochip;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AIItemStateCondition
|
||||
|
||||
class AIItemStateCondition : public AICondition {
|
||||
public:
|
||||
AIItemStateCondition(const ItemID, const ItemState);
|
||||
|
||||
bool fireCondition() override;
|
||||
|
||||
protected:
|
||||
ItemID _item;
|
||||
ItemState _state;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AIEnergyMonitorCondition
|
||||
|
||||
class AIEnergyMonitorCondition : public AICondition {
|
||||
public:
|
||||
AIEnergyMonitorCondition(const int32);
|
||||
|
||||
bool fireCondition() override;
|
||||
|
||||
protected:
|
||||
int32 _energyThreshold;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// AILastExtraCondition
|
||||
|
||||
class AILastExtraCondition : public AICondition {
|
||||
public:
|
||||
AILastExtraCondition(const ExtraID);
|
||||
|
||||
bool fireCondition() override;
|
||||
|
||||
protected:
|
||||
ExtraID _lastExtra;
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Helper functions
|
||||
|
||||
AICondition *makeLocationAndDoesntHaveItemCondition(const RoomID room, const DirectionConstant direction, const ItemID item);
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
77
engines/pegasus/ai/ai_rule.cpp
Normal file
77
engines/pegasus/ai/ai_rule.cpp
Normal file
@@ -0,0 +1,77 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/stream.h"
|
||||
|
||||
#include "pegasus/ai/ai_action.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/ai/ai_condition.h"
|
||||
#include "pegasus/ai/ai_rule.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
bool AIRule::fireRule() {
|
||||
if (_ruleActive && _ruleCondition && _ruleAction && _ruleCondition->fireCondition()) {
|
||||
if (g_AIArea)
|
||||
g_AIArea->lockAIOut();
|
||||
|
||||
_ruleAction->performAIAction(this);
|
||||
|
||||
if (--_ruleAction->_actionCount <= 0)
|
||||
deactivateRule();
|
||||
|
||||
if (g_AIArea)
|
||||
g_AIArea->unlockAI();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AIRule::writeAIRule(Common::WriteStream *stream) {
|
||||
stream->writeByte(_ruleActive);
|
||||
|
||||
if (_ruleCondition)
|
||||
_ruleCondition->writeAICondition(stream);
|
||||
}
|
||||
|
||||
void AIRule::readAIRule(Common::ReadStream *stream) {
|
||||
_ruleActive = stream->readByte();
|
||||
|
||||
if (_ruleCondition)
|
||||
_ruleCondition->readAICondition(stream);
|
||||
}
|
||||
|
||||
void AIRuleList::writeAIRules(Common::WriteStream *stream) {
|
||||
for (AIRuleList::iterator it = begin(); it != end(); it++)
|
||||
(*it)->writeAIRule(stream);
|
||||
}
|
||||
|
||||
void AIRuleList::readAIRules(Common::ReadStream *stream) {
|
||||
for (AIRuleList::iterator it = begin(); it != end(); it++)
|
||||
(*it)->readAIRule(stream);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
85
engines/pegasus/ai/ai_rule.h
Normal file
85
engines/pegasus/ai/ai_rule.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_AI_AIRULE_H
|
||||
#define PEGASUS_AI_AIRULE_H
|
||||
|
||||
#include "common/list.h"
|
||||
|
||||
#include "pegasus/ai/ai_action.h"
|
||||
#include "pegasus/ai/ai_condition.h"
|
||||
|
||||
namespace Common {
|
||||
class ReadStream;
|
||||
class WriteStream;
|
||||
}
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class AICondition;
|
||||
class AIAction;
|
||||
|
||||
class AIRule {
|
||||
public:
|
||||
AIRule(AICondition *condition, AIAction *rule) {
|
||||
_ruleCondition = condition;
|
||||
_ruleAction = rule;
|
||||
_ruleActive = true;
|
||||
}
|
||||
|
||||
~AIRule() {
|
||||
if (_ruleCondition)
|
||||
delete _ruleCondition;
|
||||
|
||||
if (_ruleAction)
|
||||
delete _ruleAction;
|
||||
}
|
||||
|
||||
bool fireRule();
|
||||
|
||||
void activateRule() { _ruleActive = true; }
|
||||
void deactivateRule() { _ruleActive = false; }
|
||||
bool isRuleActive() { return _ruleActive; }
|
||||
|
||||
void writeAIRule(Common::WriteStream *);
|
||||
void readAIRule(Common::ReadStream *);
|
||||
|
||||
protected:
|
||||
AICondition *_ruleCondition;
|
||||
AIAction *_ruleAction;
|
||||
bool _ruleActive;
|
||||
};
|
||||
|
||||
class AIRuleList : public Common::List<AIRule *> {
|
||||
public:
|
||||
AIRuleList() {}
|
||||
~AIRuleList() {}
|
||||
|
||||
void writeAIRules(Common::WriteStream *);
|
||||
void readAIRules(Common::ReadStream *);
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
122
engines/pegasus/chase.cpp
Normal file
122
engines/pegasus/chase.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
/* 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-2013 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/chase.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
// Notification constants.
|
||||
|
||||
static const NotificationFlags kChaseNotificationFlags = kChaseEnteredBranchZone |
|
||||
kChaseExitedBranchZone |
|
||||
kChaseFinished;
|
||||
|
||||
ChaseInteraction::ChaseInteraction(const InteractionID interactionID, Neighborhood *handler,
|
||||
const NotificationID notificationID, NotificationManager *manager) : GameInteraction(interactionID, handler),
|
||||
_chaseNotification(notificationID, manager), _steerPict(kNoDisplayElement), _directionNeeded(false),
|
||||
_turnDirection(kNoTurn) {
|
||||
|
||||
// HACK HACK HACK HACK HACK
|
||||
// TRIPLE SUPER ULTRA HACK
|
||||
// This avoids a nasty optimization bug I have been unable to track down
|
||||
// after days and days of searching. Let's just ship the game already.
|
||||
setNextHandler(nullptr);
|
||||
|
||||
_neighborhoodNotification = handler->getNeighborhoodNotification();
|
||||
}
|
||||
|
||||
void ChaseInteraction::openInteraction() {
|
||||
_steerPict.initFromPICTFile("Images/Interface/steer.pict", true);
|
||||
|
||||
_chaseNotification.notifyMe(this, kChaseNotificationFlags, kChaseNotificationFlags);
|
||||
|
||||
_neighborhoodNotification->notifyMe(this, kDelayCompletedFlag | kSpotSoundCompletedFlag,
|
||||
kDelayCompletedFlag | kSpotSoundCompletedFlag);
|
||||
}
|
||||
|
||||
void ChaseInteraction::closeInteraction() {
|
||||
_steerPict.hide();
|
||||
_steerPict.deallocateSurface();
|
||||
|
||||
_chaseNotification.cancelNotification(this);
|
||||
|
||||
_neighborhoodNotification->cancelNotification(this);
|
||||
}
|
||||
|
||||
void ChaseInteraction::receiveNotification(Notification *notification, const NotificationFlags flags) {
|
||||
if (notification == &_chaseNotification)
|
||||
switch (flags) {
|
||||
case kChaseEnteredBranchZone:
|
||||
_directionNeeded = true;
|
||||
showControlsHint();
|
||||
setUpBranch();
|
||||
break;
|
||||
case kChaseExitedBranchZone:
|
||||
switch (_turnDirection) {
|
||||
case kTurnLeft:
|
||||
branchLeft();
|
||||
break;
|
||||
case kTurnRight:
|
||||
branchRight();
|
||||
break;
|
||||
case kNoTurn:
|
||||
dontBranch();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
hideControlsHint();
|
||||
_turnDirection = kNoTurn;
|
||||
_directionNeeded = false;
|
||||
break;
|
||||
case kChaseFinished:
|
||||
_owner->requestDeleteCurrentInteraction();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ChaseInteraction::handleInput(const Input &input, const Hotspot *cursorSpot) {
|
||||
if (input.anyDirectionInput()) {
|
||||
if (_directionNeeded) {
|
||||
if (input.leftButtonAnyDown())
|
||||
_turnDirection = kTurnLeft;
|
||||
else if (input.rightButtonAnyDown())
|
||||
_turnDirection = kTurnRight;
|
||||
}
|
||||
} else {
|
||||
this->InputHandler::handleInput(input, cursorSpot);
|
||||
}
|
||||
}
|
||||
|
||||
void ChaseInteraction::showControlsHint() {
|
||||
_steerPict.show();
|
||||
}
|
||||
|
||||
void ChaseInteraction::hideControlsHint() {
|
||||
_steerPict.hide();
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
82
engines/pegasus/chase.h
Normal file
82
engines/pegasus/chase.h
Normal file
@@ -0,0 +1,82 @@
|
||||
/* 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-2013 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_CHASE_H
|
||||
#define PEGASUS_CHASE_H
|
||||
|
||||
#include "pegasus/hotspot.h"
|
||||
#include "pegasus/interaction.h"
|
||||
#include "pegasus/notification.h"
|
||||
#include "pegasus/neighborhood/neighborhood.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
// Notification constants.
|
||||
|
||||
static const NotificationFlags kChaseEnteredBranchZone = 1;
|
||||
static const NotificationFlags kChaseExitedBranchZone = kChaseEnteredBranchZone << 1;
|
||||
static const NotificationFlags kChaseFinished = kChaseExitedBranchZone << 1;
|
||||
|
||||
// Time to choose a direction.
|
||||
|
||||
static const TimeValue kDecisionTime = 600 * 2;
|
||||
|
||||
class ChaseInteraction : public GameInteraction, public NotificationReceiver {
|
||||
public:
|
||||
ChaseInteraction(const InteractionID, Neighborhood *, NotificationID, NotificationManager *);
|
||||
virtual ~ChaseInteraction() {}
|
||||
|
||||
virtual void handleInput(const Input &, const Hotspot *);
|
||||
|
||||
protected:
|
||||
|
||||
virtual void openInteraction();
|
||||
virtual void initInteraction() {}
|
||||
virtual void closeInteraction();
|
||||
|
||||
virtual void receiveNotification(Notification *, const NotificationFlags);
|
||||
|
||||
virtual void setUpBranch() {}
|
||||
virtual void branchLeft() {}
|
||||
virtual void branchRight() {}
|
||||
virtual void dontBranch() {}
|
||||
|
||||
virtual void showControlsHint();
|
||||
virtual void hideControlsHint();
|
||||
|
||||
Notification _chaseNotification;
|
||||
|
||||
Notification *_neighborhoodNotification;
|
||||
|
||||
Picture _steerPict;
|
||||
|
||||
private:
|
||||
|
||||
bool _directionNeeded;
|
||||
TurnDirection _turnDirection;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
81
engines/pegasus/compass.cpp
Normal file
81
engines/pegasus/compass.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/compass.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
Compass *g_compass = nullptr;
|
||||
|
||||
Compass::Compass() : FaderAnimation(kCompassID) {
|
||||
// Initialize it to east...
|
||||
setFaderValue(90);
|
||||
g_compass = this;
|
||||
}
|
||||
|
||||
Compass::~Compass() {
|
||||
g_compass = nullptr;
|
||||
}
|
||||
|
||||
void Compass::initCompass() {
|
||||
if (!isCompassValid()) {
|
||||
Common::Rect r;
|
||||
_compassImage.initFromPICTFile("Images/Compass/Compass");
|
||||
_compassImage.getSurfaceBounds(r);
|
||||
r.right = kCompassWidth;
|
||||
setBounds(r);
|
||||
}
|
||||
}
|
||||
|
||||
void Compass::deallocateCompass() {
|
||||
_compassImage.deallocateSurface();
|
||||
}
|
||||
|
||||
void Compass::setFaderValue(const int32 angle) {
|
||||
int16 a = angle % 360;
|
||||
|
||||
if (a < 0)
|
||||
a += 360;
|
||||
|
||||
FaderAnimation::setFaderValue(a);
|
||||
}
|
||||
|
||||
void Compass::draw(const Common::Rect &r1) {
|
||||
if (_compassImage.isSurfaceValid()) {
|
||||
Common::Rect bounds;
|
||||
getBounds(bounds);
|
||||
|
||||
Common::Rect r2;
|
||||
_compassImage.getSurfaceBounds(r2);
|
||||
|
||||
CoordType width = r2.width();
|
||||
CoordType offsetH = width / 10 - bounds.width() / 2 + (getFaderValue() * width) / 450 - bounds.left;
|
||||
CoordType offsetV = -bounds.top;
|
||||
r2 = r1;
|
||||
r2.translate(offsetH, offsetV);
|
||||
_compassImage.drawImage(r2, r1);
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
57
engines/pegasus/compass.h
Normal file
57
engines/pegasus/compass.h
Normal file
@@ -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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_COMPASS_H
|
||||
#define PEGASUS_COMPASS_H
|
||||
|
||||
#include "pegasus/fader.h"
|
||||
#include "pegasus/surface.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
// Compass is defined with 0 as north, 90 east, 180 south, 270 west.
|
||||
// Clockwise rotation increases the angle, counterclockwise rotation decreases the angle.
|
||||
|
||||
class Compass : public FaderAnimation {
|
||||
public:
|
||||
Compass();
|
||||
~Compass() override;
|
||||
|
||||
void initCompass();
|
||||
void deallocateCompass();
|
||||
bool isCompassValid() const { return _compassImage.isSurfaceValid(); }
|
||||
|
||||
void setFaderValue(const int32) override;
|
||||
|
||||
protected:
|
||||
void draw(const Common::Rect &) override;
|
||||
|
||||
Frame _compassImage;
|
||||
};
|
||||
|
||||
extern Compass *g_compass;
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
3
engines/pegasus/configure.engine
Normal file
3
engines/pegasus/configure.engine
Normal file
@@ -0,0 +1,3 @@
|
||||
# This file is included from the main "configure" script
|
||||
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] [components]
|
||||
add_engine pegasus "The Journeyman Project: Pegasus Prime" yes "" "" "16bit highres" "theoradec"
|
||||
101
engines/pegasus/console.cpp
Normal file
101
engines/pegasus/console.cpp
Normal file
@@ -0,0 +1,101 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/console.h"
|
||||
#include "pegasus/interface.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/neighborhood/neighborhood.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
PegasusConsole::PegasusConsole(PegasusEngine *vm) : GUI::Debugger(), _vm(vm) {
|
||||
registerCmd("die", WRAP_METHOD(PegasusConsole, Cmd_Die));
|
||||
|
||||
// These functions are non-demo specific
|
||||
if (!_vm->isDemo())
|
||||
registerCmd("jump", WRAP_METHOD(PegasusConsole, Cmd_Jump));
|
||||
}
|
||||
|
||||
PegasusConsole::~PegasusConsole() {
|
||||
}
|
||||
|
||||
bool PegasusConsole::Cmd_Die(int argc, const char **argv) {
|
||||
if (argc == 1) {
|
||||
debugPrintf("Usage: die <death reason>\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
int reason = atoi(argv[1]);
|
||||
|
||||
bool invalidReason = (reason == 0 || reason > kPlayerWonGame);
|
||||
|
||||
if (!invalidReason && _vm->isDemo())
|
||||
invalidReason = (reason != kDeathFallOffCliff) && (reason != kDeathEatenByDinosaur) &&
|
||||
(reason != kDeathStranded) && (reason != kPlayerWonGame);
|
||||
|
||||
|
||||
if (invalidReason) {
|
||||
debugPrintf("Invalid death reason %d\n", reason);
|
||||
return true;
|
||||
}
|
||||
|
||||
_vm->die(atoi(argv[1]));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PegasusConsole::Cmd_Jump(int argc, const char **argv) {
|
||||
if (!g_interface) {
|
||||
// TODO
|
||||
debugPrintf("Cannot jump without interface set up\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: Default room/direction for each neighborhood
|
||||
|
||||
if (argc < 4) {
|
||||
debugPrintf("Usage: jump <neighborhood> <room> <direction>\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
NeighborhoodID neighborhood = (NeighborhoodID)atoi(argv[1]);
|
||||
RoomID room = (RoomID)atoi(argv[2]);
|
||||
DirectionConstant direction = (DirectionConstant)atoi(argv[3]);
|
||||
|
||||
if ((neighborhood < kCaldoriaID || neighborhood > kNoradDeltaID || neighborhood == kFinalTSAID) &&
|
||||
neighborhood != kNoradSubChaseID) {
|
||||
debugPrintf("Invalid neighborhood %d", neighborhood);
|
||||
return true;
|
||||
}
|
||||
|
||||
// No real way to check room validity at this point
|
||||
|
||||
if (direction > kWest) {
|
||||
debugPrintf("Invalid direction %d", direction);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Here we go!
|
||||
// TODO: Can't clear menu since the engine is paused
|
||||
_vm->jumpToNewEnvironment(neighborhood, room, direction);
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
45
engines/pegasus/console.h
Normal file
45
engines/pegasus/console.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_CONSOLE_H
|
||||
#define PEGASUS_CONSOLE_H
|
||||
|
||||
#include "gui/debugger.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class PegasusEngine;
|
||||
|
||||
class PegasusConsole : public GUI::Debugger {
|
||||
public:
|
||||
PegasusConsole(PegasusEngine *vm);
|
||||
~PegasusConsole() override;
|
||||
|
||||
private:
|
||||
bool Cmd_Die(int argc, const char **argv);
|
||||
bool Cmd_Jump(int argc, const char **argv);
|
||||
|
||||
PegasusEngine *_vm;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
739
engines/pegasus/constants.h
Normal file
739
engines/pegasus/constants.h
Normal file
@@ -0,0 +1,739 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_CONSTANTS_H
|
||||
#define PEGASUS_CONSTANTS_H
|
||||
|
||||
#include "common/endian.h"
|
||||
#include "common/rect.h"
|
||||
|
||||
#include "pegasus/types.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
// TODO: Organize these
|
||||
|
||||
static const GameID kGameIDNothing = -1;
|
||||
|
||||
static const ActorID kNoActorID = kGameIDNothing;
|
||||
static const ActorID kPlayerID = 0;
|
||||
static const ItemID kNoItemID = kGameIDNothing;
|
||||
static const RoomID kNoRoomID = kGameIDNothing;
|
||||
static const ExtraID kNoExtraID = 0xFFFFFFFF;
|
||||
static const NeighborhoodID kNoNeighborhoodID = kGameIDNothing;
|
||||
static const AlternateID kNoAlternateID = 0;
|
||||
static const GameMenuCommand kMenuCmdNoCommand = 0;
|
||||
|
||||
static const HotSpotActivationID kActivateHotSpotAlways = 0;
|
||||
static const HotSpotActivationID kActivateHotSpotNever = -1;
|
||||
|
||||
static const ItemState kNoItemState = -1;
|
||||
|
||||
static const DirectionConstant kNoDirection = 0xFF;
|
||||
static const DirectionConstant kNorth = 0;
|
||||
static const DirectionConstant kSouth = 1;
|
||||
static const DirectionConstant kEast = 2;
|
||||
static const DirectionConstant kWest = 3;
|
||||
|
||||
static const TurnDirection kNoTurn = 0xFF;
|
||||
static const TurnDirection kTurnLeft = 0;
|
||||
static const TurnDirection kTurnRight = 1;
|
||||
static const TurnDirection kTurnUp = 2;
|
||||
static const TurnDirection kTurnDown = 3;
|
||||
static const TurnDirection kMaxTurns = 4;
|
||||
|
||||
static const GameMode kNoMode = -1;
|
||||
static const GameMode kModeNavigation = 0;
|
||||
static const GameMode kLastGameShellMode = kModeNavigation;
|
||||
|
||||
static const CanMoveForwardReason kCanMoveForward = 0;
|
||||
static const CanMoveForwardReason kCantMoveBlocked = kCanMoveForward + 1;
|
||||
static const CanMoveForwardReason kCantMoveDoorClosed = kCantMoveBlocked + 1;
|
||||
static const CanMoveForwardReason kCantMoveDoorLocked = kCantMoveDoorClosed + 1;
|
||||
static const CanMoveForwardReason kCantMoveLastReason = kCantMoveDoorLocked;
|
||||
|
||||
static const CanTurnReason kCanTurn = 0;
|
||||
static const CanTurnReason kCantTurnNoTurn = kCanTurn + 1;
|
||||
static const CanTurnReason kCantTurnLastReason = kCantTurnNoTurn;
|
||||
|
||||
static const CanOpenDoorReason kCanOpenDoor = 0;
|
||||
static const CanOpenDoorReason kCantOpenNoDoor = kCanOpenDoor + 1;
|
||||
static const CanOpenDoorReason kCantOpenLocked = kCantOpenNoDoor + 1;
|
||||
static const CanOpenDoorReason kCantOpenAlreadyOpen = kCantOpenLocked + 1;
|
||||
static const CanOpenDoorReason kCantOpenLastReason = kCantOpenAlreadyOpen;
|
||||
|
||||
static const DisplayElementID kNoDisplayElement = -1;
|
||||
static const DisplayElementID kHighestReservedElementID = -2;
|
||||
|
||||
static const DisplayElementID kCursorID = kHighestReservedElementID;
|
||||
static const DisplayElementID kLoadScreenID = kCursorID - 1;
|
||||
|
||||
static const DisplayOrder kMinAvailableOrder = 0;
|
||||
static const DisplayOrder kMaxAvailableOrder = 999998;
|
||||
static const DisplayOrder kLoadScreenOrder = 900000;
|
||||
static const DisplayOrder kCursorOrder = 1000000;
|
||||
|
||||
static const HotSpotID kNoHotSpotID = -1;
|
||||
static const HotSpotFlags kNoHotSpotFlags = 0;
|
||||
static const HotSpotFlags kAllHotSpotFlags = ~kNoHotSpotFlags;
|
||||
|
||||
static const NotificationFlags kNoNotificationFlags = 0;
|
||||
|
||||
static const DisplayElementID kCurrentDragSpriteID = 1000;
|
||||
|
||||
static const TimeScale kDefaultTimeScale = 600;
|
||||
|
||||
// Ticks per second.
|
||||
|
||||
static const TimeScale kOneTickPerSecond = 1;
|
||||
static const TimeScale kTwoTicksPerSecond = 2;
|
||||
static const TimeScale kFifteenTicksPerSecond = 15;
|
||||
static const TimeScale kThirtyTicksPerSecond = 30;
|
||||
static const TimeScale kSixtyTicksPerSecond = 60;
|
||||
static const TimeScale kMovieTicksPerSecond = 600;
|
||||
|
||||
// These times are in seconds.
|
||||
|
||||
static const TimeValue kOneSecond = 1;
|
||||
static const TimeValue kTwoSeconds = 2;
|
||||
static const TimeValue kThreeSeconds = 3;
|
||||
static const TimeValue kFourSeconds = 4;
|
||||
static const TimeValue kFiveSeconds = 5;
|
||||
static const TimeValue kSixSeconds = 6;
|
||||
static const TimeValue kSevenSeconds = 7;
|
||||
static const TimeValue kEightSeconds = 8;
|
||||
static const TimeValue kNineSeconds = 9;
|
||||
static const TimeValue kTenSeconds = 10;
|
||||
static const TimeValue kElevenSeconds = 11;
|
||||
static const TimeValue kTwelveSeconds = 12;
|
||||
static const TimeValue kThirteenSeconds = 13;
|
||||
static const TimeValue kFourteenSeconds = 14;
|
||||
static const TimeValue kFifteenSeconds = 15;
|
||||
static const TimeValue kSixteenSeconds = 16;
|
||||
static const TimeValue kSeventeenSeconds = 17;
|
||||
static const TimeValue kEighteenSeconds = 18;
|
||||
static const TimeValue kNineteenSeconds = 19;
|
||||
static const TimeValue kTwentySeconds = 20;
|
||||
static const TimeValue kThirtySeconds = 30;
|
||||
static const TimeValue kFortySeconds = 40;
|
||||
static const TimeValue kFiftySeconds = 50;
|
||||
static const TimeValue kSixtySeconds = 60;
|
||||
static const TimeValue kOneMinute = 60;
|
||||
static const TimeValue kTwoMinutes = kOneMinute * 2;
|
||||
static const TimeValue kThreeMinutes = kOneMinute * 3;
|
||||
static const TimeValue kFourMinutes = kOneMinute * 4;
|
||||
static const TimeValue kFiveMinutes = kOneMinute * 5;
|
||||
static const TimeValue kSixMinutes = kOneMinute * 6;
|
||||
static const TimeValue kSevenMinutes = kOneMinute * 7;
|
||||
static const TimeValue kEightMinutes = kOneMinute * 8;
|
||||
static const TimeValue kNineMinutes = kOneMinute * 9;
|
||||
static const TimeValue kTenMinutes = kOneMinute * 10;
|
||||
static const TimeValue kElevenMinutes = kOneMinute * 11;
|
||||
static const TimeValue kTwelveMinutes = kOneMinute * 12;
|
||||
static const TimeValue kThirteenMinutes = kOneMinute * 13;
|
||||
static const TimeValue kFourteenMinutes = kOneMinute * 14;
|
||||
static const TimeValue kFifteenMinutes = kOneMinute * 15;
|
||||
static const TimeValue kSixteenMinutes = kOneMinute * 16;
|
||||
static const TimeValue kSeventeenMinutes = kOneMinute * 17;
|
||||
static const TimeValue kEighteenMinutes = kOneMinute * 18;
|
||||
static const TimeValue kNineteenMinutes = kOneMinute * 19;
|
||||
static const TimeValue kTwentyMinutes = kOneMinute * 20;
|
||||
static const TimeValue kThirtyMinutes = kOneMinute * 30;
|
||||
static const TimeValue kFortyMinutes = kOneMinute * 40;
|
||||
static const TimeValue kFiftyMinutes = kOneMinute * 50;
|
||||
static const TimeValue kOneHour = kOneMinute * 60;
|
||||
static const TimeValue kTwoHours = kOneHour * 2;
|
||||
|
||||
// Common times.
|
||||
|
||||
static const TimeValue kHalfSecondPerTwoTicks = kTwoTicksPerSecond / 2;
|
||||
static const TimeValue kHalfSecondPerThirtyTicks = kThirtyTicksPerSecond / 2;
|
||||
static const TimeValue kHalfSecondPerSixtyTicks = kSixtyTicksPerSecond / 2;
|
||||
|
||||
static const TimeValue kOneSecondPerTwoTicks = kTwoTicksPerSecond;
|
||||
static const TimeValue kOneSecondPerThirtyTicks = kThirtyTicksPerSecond;
|
||||
static const TimeValue kOneSecondPerSixtyTicks = kSixtyTicksPerSecond;
|
||||
|
||||
static const TimeValue kOneMinutePerFifteenTicks = kOneMinute * kFifteenTicksPerSecond;
|
||||
static const TimeValue kFiveMinutesPerFifteenTicks = kFiveMinutes * kFifteenTicksPerSecond;
|
||||
static const TimeValue kTenMinutesPerFifteenTicks = kTenMinutes * kFifteenTicksPerSecond;
|
||||
|
||||
static const TimeValue kOneMinutePerThirtyTicks = kOneMinute * kThirtyTicksPerSecond;
|
||||
static const TimeValue kFiveMinutesPerThirtyTicks = kFiveMinutes * kThirtyTicksPerSecond;
|
||||
static const TimeValue kTenMinutesPerThirtyTicks = kTenMinutes * kThirtyTicksPerSecond;
|
||||
|
||||
static const TimeValue kOneMinutePerSixtyTicks = kOneMinute * kSixtyTicksPerSecond;
|
||||
static const TimeValue kFiveMinutesPerSixtyTicks = kFiveMinutes * kSixtyTicksPerSecond;
|
||||
static const TimeValue kTenMinutesPerSixtyTicks = kTenMinutes * kSixtyTicksPerSecond;
|
||||
|
||||
// Time in seconds you can hang around Caldoria without going to work...
|
||||
static const TimeValue kLateWarning2TimeLimit = kFiveMinutes;
|
||||
static const TimeValue kLateWarning3TimeLimit = kTenMinutes;
|
||||
|
||||
static const TimeValue kSinclairShootsTimeLimit = kThreeMinutes;
|
||||
static const TimeValue kCardBombCountDownTime = kTwelveSeconds;
|
||||
|
||||
static const TimeValue kOxyMaskFullTime = kThirtyMinutes;
|
||||
|
||||
static const TimeValue kTSAUncreatedTimeLimit = kFiveMinutes;
|
||||
static const TimeValue kRipTimeLimit = kTenMinutesPerFifteenTicks;
|
||||
static const TimeScale kRipTimeScale = kFifteenTicksPerSecond;
|
||||
|
||||
static const TimeValue kIntroTimeOut = kThirtySeconds;
|
||||
|
||||
static const TimeValue kMarsRobotPatienceLimit = kFifteenSeconds;
|
||||
static const TimeValue kLockFreezeTimeLmit = kFifteenSeconds;
|
||||
static const TimeValue kSpaceChaseTimeLimit = kTenMinutes;
|
||||
static const TimeValue kVacuumSurvivalTimeLimit = kThirtySeconds;
|
||||
static const TimeValue kColorMatchingTimeLimit = kFourMinutes;
|
||||
static const TimeScale kJunkTimeScale = kFifteenTicksPerSecond;
|
||||
static const TimeValue kJunkDropBaseTime = kFiveSeconds;
|
||||
static const TimeValue kJunkDropSlopTime = kThreeSeconds;
|
||||
static const TimeValue kJunkTravelTime = kTenSeconds * kJunkTimeScale;
|
||||
static const TimeValue kCollisionReboundTime = kOneSecond * kJunkTimeScale;
|
||||
static const TimeValue kWeaponReboundTime = kTwoSeconds * kJunkTimeScale;
|
||||
|
||||
static const TimeValue kGawkAtRobotTime = kTenSeconds;
|
||||
static const TimeValue kGawkAtRobotTime2 = kThirteenSeconds;
|
||||
static const TimeValue kPlasmaImpactTime = kTwoSeconds;
|
||||
|
||||
static const TimeValue kNoradAirMaskTimeLimit = kOneMinute + kFifteenSeconds;
|
||||
|
||||
static const NotificationID kNeighborhoodNotificationID = 1;
|
||||
static const NotificationID kLastNeighborhoodNotificationID = kNeighborhoodNotificationID;
|
||||
|
||||
static const NotificationFlags kNeighborhoodMovieCompletedFlag = 1;
|
||||
static const NotificationFlags kMoveForwardCompletedFlag = kNeighborhoodMovieCompletedFlag << 1;
|
||||
static const NotificationFlags kStrideCompletedFlag = kMoveForwardCompletedFlag << 1;
|
||||
static const NotificationFlags kTurnCompletedFlag = kStrideCompletedFlag << 1;
|
||||
static const NotificationFlags kSpotCompletedFlag = kTurnCompletedFlag << 1;
|
||||
static const NotificationFlags kDoorOpenCompletedFlag = kSpotCompletedFlag << 1;
|
||||
static const NotificationFlags kExtraCompletedFlag = kDoorOpenCompletedFlag << 1;
|
||||
static const NotificationFlags kSpotSoundCompletedFlag = kExtraCompletedFlag << 1;
|
||||
static const NotificationFlags kDelayCompletedFlag = kSpotSoundCompletedFlag << 1;
|
||||
static const NotificationFlags kActionRequestCompletedFlag = kDelayCompletedFlag << 1;
|
||||
static const NotificationFlags kDeathExtraCompletedFlag = kActionRequestCompletedFlag << 1;
|
||||
static const NotificationFlags kLastNeighborhoodNotificationFlag = kDeathExtraCompletedFlag;
|
||||
|
||||
static const NotificationFlags kNeighborhoodFlags = kNeighborhoodMovieCompletedFlag |
|
||||
kMoveForwardCompletedFlag |
|
||||
kStrideCompletedFlag |
|
||||
kTurnCompletedFlag |
|
||||
kSpotCompletedFlag |
|
||||
kDoorOpenCompletedFlag |
|
||||
kExtraCompletedFlag |
|
||||
kSpotSoundCompletedFlag |
|
||||
kDelayCompletedFlag |
|
||||
kActionRequestCompletedFlag |
|
||||
kDeathExtraCompletedFlag;
|
||||
|
||||
static const uint32 kPegasusPrimeCreator = MKTAG('J', 'P', 'P', 'P');
|
||||
static const uint32 kPegasusPrimeContinueType = MKTAG('P', 'P', 'C', 'T');
|
||||
|
||||
static const uint32 kPegasusPrimeDisk1GameType = MKTAG('P', 'P', 'G', '1');
|
||||
static const uint32 kPegasusPrimeDisk2GameType = MKTAG('P', 'P', 'G', '2');
|
||||
static const uint32 kPegasusPrimeDisk3GameType = MKTAG('P', 'P', 'G', '3');
|
||||
static const uint32 kPegasusPrimeDisk4GameType = MKTAG('P', 'P', 'G', '4');
|
||||
|
||||
// We only support one of the save versions; the rest are from betas
|
||||
// and we are not supporting them.
|
||||
static const uint32 kPegasusPrimeVersion = 0x00009019;
|
||||
|
||||
static const char kNormalSave = 0;
|
||||
static const char kContinueSave = 1;
|
||||
|
||||
// Display IDs.
|
||||
|
||||
static const DisplayElementID kNavMovieID = 1;
|
||||
static const DisplayElementID kTurnPushID = 2;
|
||||
|
||||
static const DisplayElementID kMaxGameShellDisplayID = kTurnPushID;
|
||||
|
||||
// Display ordering.
|
||||
|
||||
static const DisplayOrder kNavLayer = 10000;
|
||||
static const DisplayOrder kNavMovieOrder = kNavLayer;
|
||||
static const DisplayOrder kTurnPushOrder = kNavMovieOrder + 1;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Display IDs.
|
||||
|
||||
static const DisplayElementID kScreenDimmerID = kMaxGameShellDisplayID + 1;
|
||||
static const DisplayElementID kInterface1ID = kScreenDimmerID + 1;
|
||||
static const DisplayElementID kInterface2ID = kInterface1ID + 1;
|
||||
static const DisplayElementID kInterface3ID = kInterface2ID + 1;
|
||||
static const DisplayElementID kInterface4ID = kInterface3ID + 1;
|
||||
static const DisplayElementID kDateID = kInterface4ID + 1;
|
||||
static const DisplayElementID kCompassID = kDateID + 1;
|
||||
static const DisplayElementID kInventoryPushID = kCompassID + 1;
|
||||
static const DisplayElementID kInventoryLidID = kInventoryPushID + 1;
|
||||
static const DisplayElementID kBiochipPushID = kInventoryLidID + 1;
|
||||
static const DisplayElementID kBiochipLidID = kBiochipPushID + 1;
|
||||
static const DisplayElementID kEnergyBarID = kBiochipLidID + 1;
|
||||
static const DisplayElementID kWarningLightID = kEnergyBarID + 1;
|
||||
static const DisplayElementID kAILeftAreaID = kWarningLightID + 1;
|
||||
static const DisplayElementID kAIMiddleAreaID = kAILeftAreaID + 1;
|
||||
static const DisplayElementID kAIRightAreaID = kAIMiddleAreaID + 1;
|
||||
static const DisplayElementID kAIMovieID = kAIRightAreaID + 1;
|
||||
static const DisplayElementID kInventoryDropHighlightID = kAIMovieID + 1;
|
||||
static const DisplayElementID kBiochipDropHighlightID = kInventoryDropHighlightID + 1;
|
||||
|
||||
static const DisplayElementID kDraggingSpriteID = 1000;
|
||||
|
||||
static const DisplayElementID kCroppedMovieID = 2000;
|
||||
|
||||
static const DisplayElementID kNeighborhoodDisplayID = 3000;
|
||||
|
||||
static const DisplayElementID kItemPictureBaseID = 5000;
|
||||
|
||||
static const CoordType kNavAreaLeft = 64;
|
||||
static const CoordType kNavAreaTop = 64;
|
||||
|
||||
static const CoordType kBackground1Left = 0;
|
||||
static const CoordType kBackground1Top = 64;
|
||||
|
||||
static const CoordType kBackground2Left = 0;
|
||||
static const CoordType kBackground2Top = 0;
|
||||
|
||||
static const CoordType kBackground3Left = 576;
|
||||
static const CoordType kBackground3Top = 64;
|
||||
|
||||
static const CoordType kBackground4Left = 0;
|
||||
static const CoordType kBackground4Top = 320;
|
||||
|
||||
static const CoordType kOverviewControllerLeft = 540;
|
||||
static const CoordType kOverviewControllerTop = 348;
|
||||
|
||||
static const CoordType kSwapLeft = 194;
|
||||
static const CoordType kSwapTop = 116;
|
||||
|
||||
static const CoordType kSwapHiliteLeft = 200;
|
||||
static const CoordType kSwapHiliteTop = 206;
|
||||
|
||||
static const CoordType kDateLeft = 136;
|
||||
static const CoordType kDateTop = 44;
|
||||
|
||||
static const CoordType kCompassLeft = 222;
|
||||
static const CoordType kCompassTop = 42;
|
||||
static const CoordType kCompassWidth = 92;
|
||||
|
||||
static const CoordType kInventoryPushLeft = 74;
|
||||
static const CoordType kInventoryPushTop = 92;
|
||||
|
||||
static const CoordType kInventoryLidLeft = 74;
|
||||
static const CoordType kInventoryLidTop = 316;
|
||||
|
||||
static const CoordType kBiochipPushLeft = 362;
|
||||
static const CoordType kBiochipPushTop = 192;
|
||||
|
||||
static const CoordType kBiochipLidLeft = 362;
|
||||
static const CoordType kBiochipLidTop = 316;
|
||||
|
||||
static const CoordType kInventoryDropLeft = 0;
|
||||
static const CoordType kInventoryDropTop = 320;
|
||||
static const CoordType kInventoryDropRight = 232;
|
||||
static const CoordType kInventoryDropBottom = 480;
|
||||
|
||||
static const CoordType kBiochipDropLeft = 302;
|
||||
static const CoordType kBiochipDropTop = 320;
|
||||
static const CoordType kBiochipDropRight = 640;
|
||||
static const CoordType kBiochipDropBottom = 480;
|
||||
|
||||
static const CoordType kFinalMessageLeft = kInventoryPushLeft + 1;
|
||||
static const CoordType kFinalMessageTop = kInventoryPushTop + 24;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Notifications.
|
||||
|
||||
static const NotificationID kJMPDCShellNotificationID = kLastNeighborhoodNotificationID + 1;
|
||||
static const NotificationID kInterfaceNotificationID = kJMPDCShellNotificationID + 1;
|
||||
static const NotificationID kAINotificationID = kInterfaceNotificationID + 1;
|
||||
static const NotificationID kNoradNotificationID = kAINotificationID + 1;
|
||||
static const NotificationID kNoradECRNotificationID = kNoradNotificationID + 1;
|
||||
static const NotificationID kNoradFillingStationNotificationID = kNoradECRNotificationID + 1;
|
||||
static const NotificationID kNoradPressureNotificationID = kNoradFillingStationNotificationID + 1;
|
||||
static const NotificationID kNoradUtilityNotificationID = kNoradPressureNotificationID + 1;
|
||||
static const NotificationID kNoradElevatorNotificationID = kNoradUtilityNotificationID + 1;
|
||||
static const NotificationID kNoradSubPlatformNotificationID = kNoradElevatorNotificationID + 1;
|
||||
static const NotificationID kNoradSubChaseNotificationID = kNoradSubPlatformNotificationID + 1;
|
||||
static const NotificationID kSubControlNotificationID = kNoradSubChaseNotificationID + 1;
|
||||
static const NotificationID kNoradGreenBallNotificationID = kSubControlNotificationID + 1;
|
||||
static const NotificationID kNoradGlobeNotificationID = kNoradGreenBallNotificationID + 1;
|
||||
static const NotificationID kCaldoriaVidPhoneNotificationID = kNoradGlobeNotificationID + 1;
|
||||
static const NotificationID kCaldoriaMessagesNotificationID = kCaldoriaVidPhoneNotificationID + 1;
|
||||
static const NotificationID kCaldoriaBombTimerNotificationID = kCaldoriaMessagesNotificationID + 1;
|
||||
static const NotificationID kMarsTunnelPodNotificationID = kCaldoriaBombTimerNotificationID + 1;
|
||||
static const NotificationID kMarsCanyonChaseNotificationID = kMarsTunnelPodNotificationID + 1;
|
||||
|
||||
// Sent to the shell by fShellNotification.
|
||||
static const NotificationFlags kGameStartingFlag = 1;
|
||||
static const NotificationFlags kNeedNewJumpFlag = kGameStartingFlag << 1;
|
||||
static const NotificationFlags kPlayerDiedFlag = kNeedNewJumpFlag << 1;
|
||||
|
||||
static const NotificationFlags kJMPShellNotificationFlags = kGameStartingFlag |
|
||||
kNeedNewJumpFlag |
|
||||
kPlayerDiedFlag;
|
||||
|
||||
// Sent to the interface.
|
||||
static const NotificationFlags kInventoryLidOpenFlag = 1;
|
||||
static const NotificationFlags kInventoryLidClosedFlag = kInventoryLidOpenFlag << 1;
|
||||
static const NotificationFlags kInventoryDrawerUpFlag = kInventoryLidClosedFlag << 1;
|
||||
static const NotificationFlags kInventoryDrawerDownFlag = kInventoryDrawerUpFlag << 1;
|
||||
static const NotificationFlags kBiochipLidOpenFlag = kInventoryDrawerDownFlag << 1;
|
||||
static const NotificationFlags kBiochipLidClosedFlag = kBiochipLidOpenFlag << 1;
|
||||
static const NotificationFlags kBiochipDrawerUpFlag = kBiochipLidClosedFlag << 1;
|
||||
static const NotificationFlags kBiochipDrawerDownFlag = kBiochipDrawerUpFlag << 1;
|
||||
|
||||
static const NotificationFlags kInterfaceNotificationFlags = kInventoryLidOpenFlag |
|
||||
kInventoryLidClosedFlag |
|
||||
kInventoryDrawerUpFlag |
|
||||
kInventoryDrawerDownFlag |
|
||||
kBiochipLidOpenFlag |
|
||||
kBiochipLidClosedFlag |
|
||||
kBiochipDrawerUpFlag |
|
||||
kBiochipDrawerDownFlag;
|
||||
|
||||
// Hot spots.
|
||||
|
||||
// Neighborhood hot spots.
|
||||
|
||||
static const HotSpotID kFirstNeighborhoodSpotID = 5000;
|
||||
|
||||
// kShellSpotFlag is a flag which marks all hot spots which belong to the shell, like
|
||||
// the current item and current biochip spots.
|
||||
static const HotSpotFlags kShellSpotFlag = 1;
|
||||
// kNeighborhoodSpotFlag is a flag which marks all hot spots which belong to a
|
||||
// neighborhood, like buttons on walls and so on.
|
||||
static const HotSpotFlags kNeighborhoodSpotFlag = kShellSpotFlag << 1;
|
||||
// kZoomInSpotFlag is a flag which marks all hot spots which indicate a zoom.
|
||||
static const HotSpotFlags kZoomInSpotFlag = kNeighborhoodSpotFlag << 1;
|
||||
// kZoomOutSpotFlag is a flag which marks all hot spots which indicate a zoom.
|
||||
static const HotSpotFlags kZoomOutSpotFlag = kZoomInSpotFlag << 1;
|
||||
|
||||
static const HotSpotFlags kClickSpotFlag = kZoomOutSpotFlag << 1;
|
||||
static const HotSpotFlags kPlayExtraSpotFlag = kClickSpotFlag << 1;
|
||||
static const HotSpotFlags kPickUpItemSpotFlag = kPlayExtraSpotFlag << 1;
|
||||
static const HotSpotFlags kDropItemSpotFlag = kPickUpItemSpotFlag << 1;
|
||||
static const HotSpotFlags kOpenDoorSpotFlag = kDropItemSpotFlag << 1;
|
||||
|
||||
static const HotSpotFlags kZoomSpotFlags = kZoomInSpotFlag | kZoomOutSpotFlag;
|
||||
|
||||
static const HotSpotFlags kHighestGameShellSpotFlag = kOpenDoorSpotFlag;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Hot spots.
|
||||
|
||||
// Shell hot spots.
|
||||
// The shell reserves all hot spot IDs from 0 to 999
|
||||
|
||||
static const HotSpotID kCurrentItemSpotID = 0;
|
||||
static const HotSpotID kCurrentBiochipSpotID = kCurrentItemSpotID + 1;
|
||||
|
||||
static const HotSpotID kInventoryDropSpotID = kCurrentBiochipSpotID + 1;
|
||||
static const HotSpotID kBiochipDropSpotID = kInventoryDropSpotID + 1;
|
||||
|
||||
static const HotSpotID kInfoReturnSpotID = kBiochipDropSpotID + 1;
|
||||
|
||||
static const HotSpotID kAIHint1SpotID = kInfoReturnSpotID + 1;
|
||||
static const HotSpotID kAIHint2SpotID = kAIHint1SpotID + 1;
|
||||
static const HotSpotID kAIHint3SpotID = kAIHint2SpotID + 1;
|
||||
static const HotSpotID kAISolveSpotID = kAIHint3SpotID + 1;
|
||||
static const HotSpotID kAIBriefingSpotID = kAISolveSpotID + 1;
|
||||
static const HotSpotID kAIScanSpotID = kAIBriefingSpotID + 1;
|
||||
|
||||
static const HotSpotID kArthurWisdomSpotID = kAIScanSpotID + 1;
|
||||
static const HotSpotID kChattyArthurSpotID = kArthurWisdomSpotID + 1;
|
||||
static const HotSpotID kChattyAISpotID = kChattyArthurSpotID + 1;
|
||||
static const HotSpotID kArthurHeadSpotID = kChattyAISpotID + 1;
|
||||
|
||||
static const HotSpotID kPegasusRecallSpotID = kArthurHeadSpotID + 1;
|
||||
|
||||
static const HotSpotID kAriesSpotID = kPegasusRecallSpotID + 1;
|
||||
static const HotSpotID kMercurySpotID = kAriesSpotID + 1;
|
||||
static const HotSpotID kPoseidonSpotID = kMercurySpotID + 1;
|
||||
|
||||
static const HotSpotID kAirMaskToggleSpotID = kPoseidonSpotID + 1;
|
||||
|
||||
static const HotSpotID kShuttleEnergySpotID = kAirMaskToggleSpotID + 1;
|
||||
static const HotSpotID kShuttleGravitonSpotID = kShuttleEnergySpotID + 1;
|
||||
static const HotSpotID kShuttleTractorSpotID = kShuttleGravitonSpotID + 1;
|
||||
static const HotSpotID kShuttleViewSpotID = kShuttleTractorSpotID + 1;
|
||||
static const HotSpotID kShuttleTransportSpotID = kShuttleViewSpotID + 1;
|
||||
|
||||
// Most of these are obsolete:
|
||||
|
||||
// kInventoryDropSpotFlag is a flag which marks hot spots which are valid drop spots
|
||||
// for inventory items.
|
||||
// static const HotSpotFlags kInventoryDropSpotFlag = kHighestGameShellSpotFlag << 1;
|
||||
|
||||
// kBiochipDropSpotFlag is a flag which marks hot spots which are valid drop spots
|
||||
// for biochips.
|
||||
// static const HotSpotFlags kBiochipDropSpotFlag = kInventoryDropSpotFlag << 1;
|
||||
|
||||
// kInventorySpotFlag is a flag which marks hot spots which indicate inventory items
|
||||
// in the environment.
|
||||
// static const HotSpotFlags kInventorySpotFlag = kBiochipDropSpotFlag << 1;
|
||||
|
||||
// kBiochipSpotFlag is a flag which marks hot spots which indicate biochips
|
||||
// in the environment.
|
||||
static const HotSpotFlags kPickUpBiochipSpotFlag = kHighestGameShellSpotFlag << 1;
|
||||
static const HotSpotFlags kDropBiochipSpotFlag = kPickUpBiochipSpotFlag << 1;
|
||||
|
||||
static const HotSpotFlags kInfoReturnSpotFlag = kDropBiochipSpotFlag << 1;
|
||||
|
||||
// Biochip and inventory hot spot flags...
|
||||
|
||||
static const HotSpotFlags kAIBiochipSpotFlag = kInfoReturnSpotFlag << 1;
|
||||
static const HotSpotFlags kArthurBiochipSpotFlag = kAIBiochipSpotFlag << 1;
|
||||
static const HotSpotFlags kPegasusBiochipSpotFlag = kArthurBiochipSpotFlag << 1;
|
||||
static const HotSpotFlags kOpticalBiochipSpotFlag = kPegasusBiochipSpotFlag << 1;
|
||||
static const HotSpotFlags kAirMaskSpotFlag = kOpticalBiochipSpotFlag << 1;
|
||||
|
||||
static const HotSpotFlags kJMPClickingSpotFlags = kClickSpotFlag |
|
||||
kPlayExtraSpotFlag |
|
||||
kOpenDoorSpotFlag |
|
||||
kInfoReturnSpotFlag |
|
||||
kAIBiochipSpotFlag |
|
||||
kArthurBiochipSpotFlag |
|
||||
kPegasusBiochipSpotFlag |
|
||||
kOpticalBiochipSpotFlag |
|
||||
kAirMaskSpotFlag;
|
||||
|
||||
static const int32 kMainMenuID = 1;
|
||||
static const int32 kPauseMenuID = 2;
|
||||
static const int32 kCreditsMenuID = 3;
|
||||
static const int32 kDeathMenuID = 4;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Menu commands.
|
||||
|
||||
static const GameMenuCommand kMenuCmdOverview = kMenuCmdNoCommand + 1;
|
||||
static const GameMenuCommand kMenuCmdStartAdventure = kMenuCmdOverview + 1;
|
||||
static const GameMenuCommand kMenuCmdStartWalkthrough = kMenuCmdStartAdventure + 1;
|
||||
static const GameMenuCommand kMenuCmdRestore = kMenuCmdStartWalkthrough + 1;
|
||||
static const GameMenuCommand kMenuCmdCredits = kMenuCmdRestore + 1;
|
||||
static const GameMenuCommand kMenuCmdQuit = kMenuCmdCredits + 1;
|
||||
|
||||
static const GameMenuCommand kMenuCmdDeathContinue = kMenuCmdQuit + 1;
|
||||
|
||||
static const GameMenuCommand kMenuCmdDeathQuitDemo = kMenuCmdDeathContinue + 1;
|
||||
static const GameMenuCommand kMenuCmdDeathMainMenuDemo = kMenuCmdDeathQuitDemo + 1;
|
||||
|
||||
static const GameMenuCommand kMenuCmdDeathRestore = kMenuCmdDeathMainMenuDemo + 1;
|
||||
static const GameMenuCommand kMenuCmdDeathMainMenu = kMenuCmdDeathRestore + 1;
|
||||
|
||||
static const GameMenuCommand kMenuCmdPauseSave = kMenuCmdDeathMainMenu + 1;
|
||||
static const GameMenuCommand kMenuCmdPauseContinue = kMenuCmdPauseSave + 1;
|
||||
static const GameMenuCommand kMenuCmdPauseRestore = kMenuCmdPauseContinue + 1;
|
||||
static const GameMenuCommand kMenuCmdPauseQuit = kMenuCmdPauseRestore + 1;
|
||||
|
||||
static const GameMenuCommand kMenuCmdCreditsMainMenu = kMenuCmdPauseQuit + 1;
|
||||
|
||||
static const GameMenuCommand kMenuCmdCancelRestart = kMenuCmdCreditsMainMenu + 1;
|
||||
static const GameMenuCommand kMenuCmdEjectRestart = kMenuCmdCancelRestart + 1;
|
||||
|
||||
static const TimeValue kMenuButtonHiliteTime = 20;
|
||||
static const TimeScale kMenuButtonHiliteScale = kSixtyTicksPerSecond;
|
||||
|
||||
// PICT resources:
|
||||
|
||||
// Warning light PICTs:
|
||||
|
||||
static const ResIDType kLightOffID = 128;
|
||||
static const ResIDType kLightYellowID = 129;
|
||||
static const ResIDType kLightOrangeID = 130;
|
||||
static const ResIDType kLightRedID = 131;
|
||||
|
||||
// Date PICTs:
|
||||
|
||||
static const ResIDType kDatePrehistoricID = 138;
|
||||
static const ResIDType kDate2112ID = 139;
|
||||
static const ResIDType kDate2185ID = 140;
|
||||
static const ResIDType kDate2310ID = 141;
|
||||
static const ResIDType kDate2318ID = 142;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Display Order
|
||||
|
||||
static const DisplayOrder kCroppedMovieLayer = 11000;
|
||||
|
||||
static const DisplayOrder kMonitorLayer = 12000;
|
||||
|
||||
static const DisplayOrder kDragSpriteLayer = 15000;
|
||||
static const DisplayOrder kDragSpriteOrder = kDragSpriteLayer;
|
||||
|
||||
static const DisplayOrder kInterfaceLayer = 20000;
|
||||
static const DisplayOrder kBackground1Order = kInterfaceLayer;
|
||||
static const DisplayOrder kBackground2Order = kBackground1Order + 1;
|
||||
static const DisplayOrder kBackground3Order = kBackground2Order + 1;
|
||||
static const DisplayOrder kBackground4Order = kBackground3Order + 1;
|
||||
static const DisplayOrder kDateOrder = kBackground4Order + 1;
|
||||
static const DisplayOrder kCompassOrder = kDateOrder + 1;
|
||||
static const DisplayOrder kEnergyBarOrder = kCompassOrder + 1;
|
||||
static const DisplayOrder kEnergyLightOrder = kEnergyBarOrder + 1;
|
||||
|
||||
static const DisplayOrder kAILayer = 22000;
|
||||
static const DisplayOrder kAILeftAreaOrder = kAILayer;
|
||||
static const DisplayOrder kAIMiddleAreaOrder = kAILeftAreaOrder + 1;
|
||||
static const DisplayOrder kAIRightAreaOrder = kAIMiddleAreaOrder + 1;
|
||||
static const DisplayOrder kAIMovieOrder = kAIRightAreaOrder + 1;
|
||||
|
||||
static const DisplayOrder kHilitesLayer = 23000;
|
||||
static const DisplayOrder kInventoryHiliteOrder = kHilitesLayer;
|
||||
static const DisplayOrder kBiochipHiliteOrder = kInventoryHiliteOrder + 1;
|
||||
|
||||
static const DisplayOrder kPanelsLayer = 25000;
|
||||
static const DisplayOrder kInventoryPushOrder = kPanelsLayer;
|
||||
static const DisplayOrder kInventoryLidOrder = kInventoryPushOrder + 1;
|
||||
static const DisplayOrder kBiochipPushOrder = kInventoryLidOrder + 1;
|
||||
static const DisplayOrder kBiochipLidOrder = kBiochipPushOrder + 1;
|
||||
static const DisplayOrder kFinalMessageOrder = kBiochipLidOrder + 1;
|
||||
|
||||
static const DisplayOrder kInfoLayer = 26000;
|
||||
static const DisplayOrder kInfoBackgroundOrder = kInfoLayer;
|
||||
static const DisplayOrder kInfoSpinOrder = kInfoBackgroundOrder + 1;
|
||||
|
||||
static const DisplayOrder kScreenDimmerOrder = 30000;
|
||||
|
||||
static const DisplayOrder kPauseScreenLayer = 31000;
|
||||
static const DisplayOrder kPauseMenuOrder = kPauseScreenLayer;
|
||||
static const DisplayOrder kSaveGameOrder = kPauseMenuOrder + 1;
|
||||
static const DisplayOrder kContinueOrder = kSaveGameOrder + 1;
|
||||
static const DisplayOrder kRestoreOrder = kContinueOrder + 1;
|
||||
static const DisplayOrder kSoundFXOrder = kRestoreOrder + 1;
|
||||
static const DisplayOrder kAmbienceOrder = kSoundFXOrder + 1;
|
||||
static const DisplayOrder kWalkthruOrder = kAmbienceOrder + 1;
|
||||
static const DisplayOrder kQuitToMainMenuOrder = kWalkthruOrder + 1;
|
||||
static const DisplayOrder kPauseLargeHiliteOrder = kQuitToMainMenuOrder + 1;
|
||||
static const DisplayOrder kPauseSmallHiliteOrder = kPauseLargeHiliteOrder + 1;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Death reasons.
|
||||
enum {
|
||||
// Caldoria
|
||||
kDeathUncreatedInCaldoria = 1,
|
||||
kDeathCardBomb,
|
||||
kDeathShotBySinclair,
|
||||
kDeathSinclairShotDelegate,
|
||||
kDeathNuclearExplosion,
|
||||
|
||||
// TSA
|
||||
kDeathUncreatedInTSA,
|
||||
kDeathShotByTSARobots,
|
||||
|
||||
// Prehistoric
|
||||
kDeathFallOffCliff,
|
||||
kDeathEatenByDinosaur,
|
||||
kDeathStranded,
|
||||
|
||||
// Norad
|
||||
kDeathGassedInNorad,
|
||||
kDeathArrestedInNorad,
|
||||
kDeathWokeUpNorad,
|
||||
kDeathSubDestroyed, // Unused
|
||||
kDeathRobotThroughNoradDoor,
|
||||
kDeathRobotSubControlRoom,
|
||||
|
||||
// Mars
|
||||
kDeathWrongShuttleLock,
|
||||
kDeathArrestedInMars,
|
||||
kDeathCollidedWithPod,
|
||||
kDeathRunOverByPod,
|
||||
kDeathDidntGetOutOfWay,
|
||||
kDeathReactorBurn,
|
||||
kDeathDidntFindMarsBomb,
|
||||
kDeathDidntDisarmMarsBomb,
|
||||
kDeathNoMaskInMaze,
|
||||
kDeathNoAirInMaze,
|
||||
kDeathGroundByMazebot,
|
||||
kDeathMissedOreBucket,
|
||||
kDeathDidntLeaveBucket,
|
||||
kDeathRanIntoCanyonWall, // Unused
|
||||
kDeathRanIntoSpaceJunk,
|
||||
|
||||
// WSC
|
||||
kDeathDidntStopPoison,
|
||||
kDeathArrestedInWSC,
|
||||
kDeathHitByPlasma,
|
||||
kDeathShotOnCatwalk,
|
||||
|
||||
// Winning
|
||||
kPlayerWonGame
|
||||
};
|
||||
|
||||
static const CoordType kAILeftAreaLeft = 76;
|
||||
static const CoordType kAILeftAreaTop = 334;
|
||||
|
||||
static const CoordType kAILeftAreaWidth = 96;
|
||||
static const CoordType kAILeftAreaHeight = 96;
|
||||
|
||||
static const CoordType kAIMiddleAreaLeft = 172;
|
||||
static const CoordType kAIMiddleAreaTop = 334;
|
||||
|
||||
static const CoordType kAIMiddleAreaWidth = 192;
|
||||
static const CoordType kAIMiddleAreaHeight = 96;
|
||||
|
||||
static const CoordType kAIRightAreaLeft = 364;
|
||||
static const CoordType kAIRightAreaTop = 334;
|
||||
|
||||
static const CoordType kAIRightAreaWidth = 96;
|
||||
static const CoordType kAIRightAreaHeight = 96;
|
||||
|
||||
enum {
|
||||
kTSAPlayerNotArrived, // initial state, must be zero
|
||||
kTSAPlayerForcedReview, // Player must watch TBP before rip occurs.
|
||||
kTSAPlayerDetectedRip, // Player finished TBP, rip alarm just went off.
|
||||
kTSAPlayerNeedsHistoricalLog, // Player is instructed to get historical log
|
||||
kTSAPlayerGotHistoricalLog,
|
||||
kTSAPlayerInstalledHistoricalLog,
|
||||
kTSABossSawHistoricalLog,
|
||||
kRobotsAtCommandCenter,
|
||||
kRobotsAtFrontDoor,
|
||||
kRobotsAtReadyRoom,
|
||||
kPlayerLockedInPegasus,
|
||||
kPlayerOnWayToPrehistoric,
|
||||
kPlayerWentToPrehistoric,
|
||||
kPlayerOnWayToNorad,
|
||||
kPlayerOnWayToMars,
|
||||
kPlayerOnWayToWSC,
|
||||
kPlayerFinishedWithTSA
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Mode static constants.
|
||||
|
||||
static const GameMode kModeInventoryPick = kLastGameShellMode + 1;
|
||||
static const GameMode kModeBiochipPick = kModeInventoryPick + 1;
|
||||
static const GameMode kModeInfoScreen = kModeBiochipPick + 1;
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
3
engines/pegasus/credits.pl
Normal file
3
engines/pegasus/credits.pl
Normal file
@@ -0,0 +1,3 @@
|
||||
begin_section("Pegasus");
|
||||
add_person("Matthew Hoops", "clone2727", "(retired)");
|
||||
end_section();
|
||||
171
engines/pegasus/cursor.cpp
Normal file
171
engines/pegasus/cursor.cpp
Normal file
@@ -0,0 +1,171 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/events.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/system.h"
|
||||
#include "graphics/cursorman.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "image/cicn.h"
|
||||
#include "image/pict.h"
|
||||
|
||||
#include "pegasus/cursor.h"
|
||||
#include "pegasus/graphics.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
Cursor::Cursor() {
|
||||
_cursorObscured = false;
|
||||
_index = -1;
|
||||
startIdling();
|
||||
}
|
||||
|
||||
Cursor::~Cursor() {
|
||||
for (uint32 i = 0; i < _info.size(); i++) {
|
||||
if (_info[i].surface) {
|
||||
_info[i].surface->free();
|
||||
delete _info[i].surface;
|
||||
}
|
||||
delete[] _info[i].palette;
|
||||
}
|
||||
|
||||
stopIdling();
|
||||
}
|
||||
|
||||
void Cursor::addCursorFrames(uint16 id) {
|
||||
Common::SeekableReadStream *cursStream = g_vm->_resFork->getResource(MKTAG('C', 'u', 'r', 's'), id);
|
||||
if (!cursStream)
|
||||
error("Could not load cursor frames set %d", id);
|
||||
|
||||
uint16 frameCount = cursStream->readUint16BE();
|
||||
for (uint16 i = 0; i < frameCount; i++) {
|
||||
CursorInfo info;
|
||||
info.tag = cursStream->readUint16BE();
|
||||
info.hotspot.x = cursStream->readUint16BE();
|
||||
info.hotspot.y = cursStream->readUint16BE();
|
||||
info.surface = nullptr;
|
||||
info.palette = nullptr;
|
||||
info.colorCount = 0;
|
||||
_info.push_back(info);
|
||||
}
|
||||
|
||||
delete cursStream;
|
||||
|
||||
setCurrentFrameIndex(0);
|
||||
}
|
||||
|
||||
void Cursor::setCurrentFrameIndex(int32 index) {
|
||||
if (_index != index) {
|
||||
_index = index;
|
||||
if (index != -1) {
|
||||
loadCursorImage(_info[index]);
|
||||
|
||||
if (_info[index].surface->format.bytesPerPixel == 1) {
|
||||
CursorMan.replaceCursorPalette(_info[index].palette, 0, _info[index].colorCount);
|
||||
CursorMan.replaceCursor(*_info[index].surface, _info[index].hotspot.x, _info[index].hotspot.y, 0);
|
||||
} else {
|
||||
CursorMan.replaceCursor(*_info[index].surface, _info[index].hotspot.x, _info[index].hotspot.y, _info[index].surface->format.RGBToColor(0xFF, 0xFF, 0xFF), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int32 Cursor::getCurrentFrameIndex() const {
|
||||
return _index;
|
||||
}
|
||||
|
||||
void Cursor::show() {
|
||||
if (!isVisible())
|
||||
CursorMan.showMouse(true);
|
||||
|
||||
_cursorObscured = false;
|
||||
}
|
||||
|
||||
void Cursor::hide() {
|
||||
CursorMan.showMouse(false);
|
||||
setCurrentFrameIndex(0);
|
||||
}
|
||||
|
||||
void Cursor::hideUntilMoved() {
|
||||
if (!_cursorObscured) {
|
||||
hide();
|
||||
_cursorObscured = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Cursor::useIdleTime() {
|
||||
if (g_system->getEventManager()->getMousePos() != _cursorLocation) {
|
||||
_cursorLocation = g_system->getEventManager()->getMousePos();
|
||||
if (_index != -1 && _cursorObscured)
|
||||
show();
|
||||
}
|
||||
}
|
||||
|
||||
void Cursor::getCursorLocation(Common::Point &pt) const {
|
||||
pt = _cursorLocation;
|
||||
}
|
||||
|
||||
bool Cursor::isVisible() {
|
||||
return CursorMan.isVisible();
|
||||
}
|
||||
|
||||
void Cursor::loadCursorImage(CursorInfo &cursorInfo) {
|
||||
if (cursorInfo.surface)
|
||||
return;
|
||||
|
||||
if (g_vm->isDVD()) {
|
||||
// The DVD version has some higher color PICT images for its cursors
|
||||
Common::SeekableReadStream *pictStream = g_vm->_resFork->getResource(MKTAG('P', 'I', 'C', 'T'), cursorInfo.tag + 1000);
|
||||
|
||||
if (pictStream) {
|
||||
Image::PICTDecoder pict;
|
||||
if (!pict.loadStream(*pictStream))
|
||||
error("Failed to decode cursor PICT %d", cursorInfo.tag + 1000);
|
||||
|
||||
cursorInfo.surface = pict.getSurface()->convertTo(g_system->getScreenFormat());
|
||||
delete pictStream;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
cursorInfo.surface = new Graphics::Surface();
|
||||
|
||||
// The CD version uses (only) lower color cicn images for its cursors
|
||||
Common::SeekableReadStream *cicnStream = g_vm->_resFork->getResource(MKTAG('c', 'i', 'c', 'n'), cursorInfo.tag);
|
||||
|
||||
if (cicnStream) {
|
||||
Image::CicnDecoder cicn;
|
||||
if (!cicn.loadStream(*cicnStream))
|
||||
error("Failed to decode cursor cicn %d", cursorInfo.tag);
|
||||
|
||||
cursorInfo.surface = cicn.getSurface()->convertTo(g_system->getScreenFormat(), cicn.getPalette().data(), cicn.getPalette().size());
|
||||
delete cicnStream;
|
||||
return;
|
||||
}
|
||||
|
||||
error("Failed to find color icon %d", cursorInfo.tag);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
83
engines/pegasus/cursor.h
Normal file
83
engines/pegasus/cursor.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_CURSOR_H
|
||||
#define PEGASUS_CURSOR_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/rect.h"
|
||||
|
||||
#include "pegasus/timers.h"
|
||||
|
||||
namespace Graphics {
|
||||
struct Surface;
|
||||
}
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
// The original cursor code was in the graphics code directly,
|
||||
// unlike ScummVM where we have the cursor code separate. We're
|
||||
// going to go with CursorManager here and therefore not inherit
|
||||
// from the Sprite class.
|
||||
|
||||
class Cursor : private Idler {
|
||||
public:
|
||||
Cursor();
|
||||
~Cursor() override;
|
||||
|
||||
void addCursorFrames(uint16 id);
|
||||
|
||||
void setCurrentFrameIndex(int32 index);
|
||||
int32 getCurrentFrameIndex() const;
|
||||
|
||||
void show();
|
||||
void hide();
|
||||
void hideUntilMoved();
|
||||
bool isVisible();
|
||||
|
||||
void getCursorLocation(Common::Point &) const;
|
||||
|
||||
protected:
|
||||
void useIdleTime() override;
|
||||
|
||||
private:
|
||||
struct CursorInfo {
|
||||
uint16 tag;
|
||||
Common::Point hotspot;
|
||||
Graphics::Surface *surface;
|
||||
byte *palette;
|
||||
uint16 colorCount;
|
||||
};
|
||||
|
||||
Common::Point _cursorLocation;
|
||||
Common::Array<CursorInfo> _info;
|
||||
bool _cursorObscured;
|
||||
int _index;
|
||||
|
||||
void loadCursorImage(CursorInfo &cursorInfo);
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
165
engines/pegasus/detection.cpp
Normal file
165
engines/pegasus/detection.cpp
Normal file
@@ -0,0 +1,165 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "base/plugins.h"
|
||||
|
||||
#include "engines/advancedDetector.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/file.h"
|
||||
|
||||
#include "pegasus/detection.h"
|
||||
|
||||
static const PlainGameDescriptor pegasusGames[] = {
|
||||
{"pegasus", "The Journeyman Project: Pegasus Prime"},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
static const PegasusGameDescription gameDescriptions[] = {
|
||||
{
|
||||
{
|
||||
"pegasus",
|
||||
"",
|
||||
AD_ENTRY1s("JMP PP Resources", "d13a602d2498010d720a6534f097f88b", 2009687),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformMacintosh,
|
||||
ADGF_MACRESFORK,
|
||||
GUIO1(GUIO_NOMIDI)
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
{
|
||||
"pegasus",
|
||||
"DVD",
|
||||
AD_ENTRY1s("JMP PP Resources", "d13a602d2498010d720a6534f097f88b", 2075081),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformMacintosh,
|
||||
ADGF_MACRESFORK|ADGF_DVD,
|
||||
GUIO0()
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
{ "pegasus",
|
||||
"DVD",
|
||||
AD_ENTRY1s("JMP PP Resources", "d13a602d2498010d720a6534f097f88b", 2075081),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformWindows,
|
||||
ADGF_MACRESFORK|ADGF_DVD,
|
||||
GUIO0()
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
{
|
||||
"pegasus",
|
||||
"DVD",
|
||||
AD_ENTRY1s("JMP PP Resources", "d13a602d2498010d720a6534f097f88b", 2075081),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformLinux,
|
||||
ADGF_MACRESFORK|ADGF_DVD,
|
||||
GUIO0()
|
||||
},
|
||||
},
|
||||
|
||||
// The Next Generation Disc #31 - July 1997
|
||||
// Mac Addict #12 - August 1997
|
||||
// Publisher is Bandai Digital Entertainment Corporation
|
||||
// File modified date is Mar 29 1997 (v1.0)
|
||||
{
|
||||
{
|
||||
"pegasus",
|
||||
"v1.0 Demo",
|
||||
AD_ENTRY1s("JMP PP Resources", "d13a602d2498010d720a6534f097f88b", 365329),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformMacintosh,
|
||||
ADGF_MACRESFORK | ADGF_DEMO,
|
||||
GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)
|
||||
},
|
||||
},
|
||||
|
||||
// Official distribution from Presto website
|
||||
// http://thejourneymanproject.com/presto/journeymanprime/demos.html
|
||||
// File modified date is date is Dec 15 2011
|
||||
{
|
||||
{
|
||||
"pegasus",
|
||||
"Demo",
|
||||
AD_ENTRY1s("JMP PP Resources", "d13a602d2498010d720a6534f097f88b", 359873),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformMacintosh,
|
||||
ADGF_MACRESFORK | ADGF_DEMO,
|
||||
GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
{
|
||||
"pegasus",
|
||||
"DVD Demo",
|
||||
AD_ENTRY1s("JMP PP Resources", "r:d0fcda50dc75c7a81ae314e6a813f4d2", 93239),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformMacintosh,
|
||||
ADGF_MACRESFORK | ADGF_DEMO | ADGF_DVD,
|
||||
GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
{
|
||||
"pegasus",
|
||||
"DVD Demo",
|
||||
AD_ENTRY1s("JMP PP Resources", "r:d0fcda50dc75c7a81ae314e6a813f4d2", 93239),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformWindows,
|
||||
ADGF_MACRESFORK | ADGF_DEMO | ADGF_DVD,
|
||||
GUIO2(GUIO_NOLAUNCHLOAD, GUIO_NOMIDI)
|
||||
},
|
||||
},
|
||||
|
||||
{ AD_TABLE_END_MARKER }
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
|
||||
class PegasusMetaEngineDetection : public AdvancedMetaEngineDetection<Pegasus::PegasusGameDescription> {
|
||||
public:
|
||||
PegasusMetaEngineDetection() : AdvancedMetaEngineDetection(Pegasus::gameDescriptions, pegasusGames) {
|
||||
}
|
||||
|
||||
const char *getName() const override {
|
||||
return "pegasus";
|
||||
}
|
||||
|
||||
const char *getEngineName() const override {
|
||||
return "The Journeyman Project: Pegasus Prime";
|
||||
}
|
||||
|
||||
const char *getOriginalCopyright() const override {
|
||||
return "The Journeyman Project: Pegasus Prime (C) Presto Studios";
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_PLUGIN_STATIC(PEGASUS_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, PegasusMetaEngineDetection);
|
||||
37
engines/pegasus/detection.h
Normal file
37
engines/pegasus/detection.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_DETECTION_H
|
||||
#define PEGASUS_DETECTION_H
|
||||
|
||||
#include "engines/advancedDetector.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
struct PegasusGameDescription {
|
||||
AD_GAME_DESCRIPTION_HELPERS(desc);
|
||||
|
||||
ADGameDescription desc;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif // PEGASUS_DETECTION_H
|
||||
567
engines/pegasus/elements.cpp
Normal file
567
engines/pegasus/elements.cpp
Normal file
@@ -0,0 +1,567 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/macresman.h"
|
||||
#include "common/stream.h"
|
||||
|
||||
#include "pegasus/elements.h"
|
||||
#include "pegasus/graphics.h"
|
||||
#include "pegasus/surface.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
DisplayElement::DisplayElement(const DisplayElementID id) : IDObject(id) {
|
||||
_elementIsDisplaying = false;
|
||||
_elementIsVisible = false;
|
||||
_elementOrder = 0;
|
||||
_triggeredElement = this;
|
||||
_nextElement = nullptr;
|
||||
}
|
||||
|
||||
DisplayElement::~DisplayElement() {
|
||||
if (isDisplaying())
|
||||
g_vm->_gfx->removeDisplayElement(this);
|
||||
}
|
||||
|
||||
void DisplayElement::setDisplayOrder(const DisplayOrder order) {
|
||||
if (_elementOrder != order) {
|
||||
_elementOrder = order;
|
||||
if (isDisplaying()) {
|
||||
g_vm->_gfx->removeDisplayElement(this);
|
||||
g_vm->_gfx->addDisplayElement(this);
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayElement::startDisplaying() {
|
||||
if (!isDisplaying()) {
|
||||
g_vm->_gfx->addDisplayElement(this);
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayElement::stopDisplaying() {
|
||||
if (isDisplaying()) {
|
||||
triggerRedraw();
|
||||
g_vm->_gfx->removeDisplayElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayElement::setBounds(const CoordType left, const CoordType top, const CoordType right, const CoordType bottom) {
|
||||
setBounds(Common::Rect(left, top, right, bottom));
|
||||
}
|
||||
|
||||
void DisplayElement::getBounds(Common::Rect &r) const {
|
||||
r = _bounds;
|
||||
}
|
||||
|
||||
void DisplayElement::sizeElement(const CoordType h, const CoordType v) {
|
||||
Common::Rect newBounds = _bounds;
|
||||
newBounds.right = _bounds.left + h;
|
||||
newBounds.bottom = _bounds.top + v;
|
||||
setBounds(newBounds);
|
||||
}
|
||||
|
||||
void DisplayElement::moveElementTo(const CoordType h, const CoordType v) {
|
||||
Common::Rect newBounds = _bounds;
|
||||
newBounds.moveTo(h, v);
|
||||
setBounds(newBounds);
|
||||
}
|
||||
|
||||
void DisplayElement::moveElement(const CoordType dh, const CoordType dv) {
|
||||
Common::Rect newBounds = _bounds;
|
||||
newBounds.translate(dh, dv);
|
||||
setBounds(newBounds);
|
||||
}
|
||||
|
||||
void DisplayElement::getLocation(CoordType &h, CoordType &v) const {
|
||||
h = _bounds.left;
|
||||
v = _bounds.top;
|
||||
}
|
||||
|
||||
void DisplayElement::centerElementAt(const CoordType h, const CoordType v) {
|
||||
Common::Rect newBounds = _bounds;
|
||||
newBounds.moveTo(h - (_bounds.width() / 2), v - (_bounds.height() / 2));
|
||||
setBounds(newBounds);
|
||||
}
|
||||
|
||||
void DisplayElement::getCenter(CoordType &h, CoordType &v) const {
|
||||
h = (_bounds.left + _bounds.right) / 2;
|
||||
v = (_bounds.top + _bounds.bottom) / 2;
|
||||
}
|
||||
|
||||
void DisplayElement::setBounds(const Common::Rect &r) {
|
||||
if (r != _bounds) {
|
||||
triggerRedraw();
|
||||
_bounds = r;
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayElement::hide() {
|
||||
if (_elementIsVisible) {
|
||||
triggerRedraw();
|
||||
_elementIsVisible = false;
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayElement::show() {
|
||||
if (!_elementIsVisible) {
|
||||
_elementIsVisible = true;
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
// Only invalidates this element's bounding rectangle if all these conditions are true:
|
||||
// -- The triggered element is this element.
|
||||
// -- The element is displaying on the display list.
|
||||
// -- The element is visible.
|
||||
// -- The element is part of the active layer OR is one of the reserved items.
|
||||
void DisplayElement::triggerRedraw() {
|
||||
GraphicsManager *gfx = g_vm->_gfx;
|
||||
|
||||
if (_triggeredElement == this) {
|
||||
if (validToDraw(gfx->getBackOfActiveLayer(), gfx->getFrontOfActiveLayer()))
|
||||
gfx->invalRect(_bounds);
|
||||
} else {
|
||||
_triggeredElement->triggerRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
void DisplayElement::setTriggeredElement(DisplayElement *element) {
|
||||
if (element)
|
||||
_triggeredElement = element;
|
||||
else
|
||||
_triggeredElement = this;
|
||||
}
|
||||
|
||||
bool DisplayElement::validToDraw(DisplayOrder backLayer, DisplayOrder frontLayer) {
|
||||
return isDisplaying() && _elementIsVisible &&
|
||||
(getObjectID() <= kHighestReservedElementID ||
|
||||
(getDisplayOrder() >= backLayer &&
|
||||
getDisplayOrder() <= frontLayer));
|
||||
}
|
||||
|
||||
DropHighlight::DropHighlight(const DisplayElementID id) : DisplayElement(id) {
|
||||
_highlightColor = 0;
|
||||
_thickness = 2;
|
||||
_cornerDiameter = 0;
|
||||
}
|
||||
|
||||
void DropHighlight::draw(const Common::Rect &) {
|
||||
Graphics::Surface *screen = g_vm->_gfx->getWorkArea();
|
||||
|
||||
// Since this is only used in two different ways, I'm only
|
||||
// going to implement it in those two ways. Deal with it.
|
||||
|
||||
Common::Rect rect = _bounds;
|
||||
rect.grow(-_thickness);
|
||||
screen->frameRect(rect, _highlightColor);
|
||||
rect.grow(1);
|
||||
screen->frameRect(rect, _highlightColor);
|
||||
|
||||
if (_cornerDiameter == 8 && _thickness == 4) {
|
||||
rect.grow(1);
|
||||
screen->frameRect(rect, _highlightColor);
|
||||
screen->hLine(rect.left + 1, rect.top - 1, rect.right - 2, _highlightColor);
|
||||
screen->hLine(rect.left + 1, rect.bottom, rect.right - 2, _highlightColor);
|
||||
screen->vLine(rect.left - 1, rect.top + 1, rect.bottom - 2, _highlightColor);
|
||||
screen->vLine(rect.right, rect.top + 1, rect.bottom - 2, _highlightColor);
|
||||
}
|
||||
}
|
||||
|
||||
IdlerAnimation::IdlerAnimation(const DisplayElementID id) : Animation(id) {
|
||||
_lastTime = 0xffffffff;
|
||||
}
|
||||
|
||||
void IdlerAnimation::startDisplaying() {
|
||||
if (!isDisplaying()) {
|
||||
Animation::startDisplaying();
|
||||
startIdling();
|
||||
}
|
||||
}
|
||||
|
||||
void IdlerAnimation::stopDisplaying() {
|
||||
if (isDisplaying()) {
|
||||
Animation::stopDisplaying();
|
||||
stopIdling();
|
||||
}
|
||||
}
|
||||
|
||||
void IdlerAnimation::useIdleTime() {
|
||||
uint32 currentTime = getTime();
|
||||
|
||||
if (currentTime != _lastTime) {
|
||||
_lastTime = currentTime;
|
||||
timeChanged(_lastTime);
|
||||
}
|
||||
}
|
||||
|
||||
void IdlerAnimation::timeChanged(const TimeValue) {
|
||||
triggerRedraw();
|
||||
}
|
||||
|
||||
FrameSequence::FrameSequence(const DisplayElementID id) : IdlerAnimation(id) {
|
||||
_duration = 0;
|
||||
_currentFrameNum = 0;
|
||||
_resFork = new Common::MacResManager();
|
||||
_numFrames = 0;
|
||||
}
|
||||
|
||||
FrameSequence::~FrameSequence() {
|
||||
delete _resFork;
|
||||
}
|
||||
|
||||
void FrameSequence::useFileName(const Common::Path &fileName) {
|
||||
_resFork->open(fileName);
|
||||
}
|
||||
|
||||
void FrameSequence::openFrameSequence() {
|
||||
if (!_resFork->hasResFork())
|
||||
return;
|
||||
|
||||
Common::SeekableReadStream *res = _resFork->getResource(MKTAG('P', 'F', 'r', 'm'), 0x80);
|
||||
|
||||
if (!res)
|
||||
return;
|
||||
|
||||
uint32 scale = res->readUint32BE();
|
||||
_bounds.top = res->readUint16BE();
|
||||
_bounds.left = res->readUint16BE();
|
||||
_bounds.bottom = res->readUint16BE();
|
||||
_bounds.right = res->readUint16BE();
|
||||
_numFrames = res->readUint16BE();
|
||||
_duration = 0;
|
||||
|
||||
_frameTimes.clear();
|
||||
for (uint32 i = 0; i < _numFrames; i++) {
|
||||
TimeValue time = res->readUint32BE();
|
||||
_frameTimes.push_back(_duration);
|
||||
_duration += time;
|
||||
}
|
||||
|
||||
setScale(scale);
|
||||
setSegment(0, _duration);
|
||||
setTime(0);
|
||||
_currentFrameNum = 0;
|
||||
newFrame(_currentFrameNum);
|
||||
triggerRedraw();
|
||||
|
||||
delete res;
|
||||
}
|
||||
|
||||
void FrameSequence::closeFrameSequence() {
|
||||
stop();
|
||||
_resFork->close();
|
||||
_duration = 0;
|
||||
_numFrames = 0;
|
||||
_frameTimes.clear();
|
||||
}
|
||||
|
||||
void FrameSequence::timeChanged(const TimeValue time) {
|
||||
int16 frameNum = 0;
|
||||
for (int16 i = _numFrames - 1; i >= 0; i--) {
|
||||
if (_frameTimes[i] < time) {
|
||||
frameNum = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (frameNum != _currentFrameNum) {
|
||||
_currentFrameNum = frameNum;
|
||||
newFrame(_currentFrameNum);
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
void FrameSequence::setFrameNum(const int16 frameNum) {
|
||||
int16 f = CLIP<int>(frameNum, 0, _numFrames);
|
||||
|
||||
if (_currentFrameNum != f) {
|
||||
_currentFrameNum = f;
|
||||
setTime(_frameTimes[f]);
|
||||
newFrame(f);
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
bool FrameSequence::isSequenceOpen() const {
|
||||
return _numFrames != 0;
|
||||
}
|
||||
|
||||
Sprite::Sprite(const DisplayElementID id) : DisplayElement(id) {
|
||||
_numFrames = 0;
|
||||
_currentFrameNum = 0xffffffff;
|
||||
_currentFrame = nullptr;
|
||||
}
|
||||
|
||||
Sprite::~Sprite() {
|
||||
discardFrames();
|
||||
}
|
||||
|
||||
void Sprite::discardFrames() {
|
||||
if (!_frameArray.empty()) {
|
||||
for (uint32 i = 0; i < _numFrames; i++) {
|
||||
SpriteFrame *frame = _frameArray[i].frame;
|
||||
frame->_referenceCount--;
|
||||
if (frame->_referenceCount == 0)
|
||||
delete frame;
|
||||
}
|
||||
|
||||
_frameArray.clear();
|
||||
_numFrames = 0;
|
||||
_currentFrame = nullptr;
|
||||
_currentFrameNum = 0xffffffff;
|
||||
setBounds(0, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void Sprite::addPICTResourceFrame(const ResIDType pictID, bool transparent, const CoordType left, const CoordType top) {
|
||||
SpriteFrame *frame = new SpriteFrame();
|
||||
frame->initFromPICTResource(g_vm->_resFork, pictID, transparent);
|
||||
addFrame(frame, left, top);
|
||||
}
|
||||
|
||||
uint32 Sprite::addFrame(SpriteFrame *frame, const CoordType left, const CoordType top) {
|
||||
SpriteFrameRec frameRecord;
|
||||
frameRecord.frame = frame;
|
||||
frameRecord.frameLeft = left;
|
||||
frameRecord.frameTop = top;
|
||||
_frameArray.push_back(frameRecord);
|
||||
_numFrames++;
|
||||
frame->_referenceCount++;
|
||||
|
||||
Common::Rect frameBounds;
|
||||
frame->getSurfaceBounds(frameBounds);
|
||||
|
||||
// 9/3/96
|
||||
// BB Should this be + left or - left?
|
||||
frameBounds.moveTo(_bounds.left + left, _bounds.top + top);
|
||||
|
||||
frameBounds.extend(_bounds);
|
||||
|
||||
if (_bounds != frameBounds)
|
||||
setBounds(frameBounds);
|
||||
|
||||
return _numFrames - 1;
|
||||
}
|
||||
|
||||
void Sprite::removeFrame(const uint32 frameNum) {
|
||||
_frameArray[frameNum].frame->_referenceCount--;
|
||||
if (_frameArray[frameNum].frame->_referenceCount == 0)
|
||||
delete _frameArray[frameNum].frame;
|
||||
|
||||
// Calculate the new bounds
|
||||
Common::Rect frameBounds;
|
||||
for (uint32 i = 0; i < _numFrames; i++) {
|
||||
if (i == frameNum)
|
||||
continue;
|
||||
|
||||
Common::Rect r;
|
||||
_frameArray[i].frame->getSurfaceBounds(r);
|
||||
r.translate(_frameArray[i].frameLeft, _frameArray[i].frameTop);
|
||||
frameBounds.extend(r);
|
||||
}
|
||||
|
||||
_frameArray.remove_at(frameNum);
|
||||
|
||||
frameBounds.moveTo(_bounds.left, _bounds.top);
|
||||
setBounds(frameBounds);
|
||||
|
||||
if (_currentFrameNum == frameNum)
|
||||
triggerRedraw();
|
||||
else if (_currentFrameNum != 0xffffffff && _currentFrameNum > frameNum)
|
||||
--_currentFrameNum;
|
||||
}
|
||||
|
||||
void Sprite::setCurrentFrameIndex(const int32 frameNum) {
|
||||
if (frameNum < 0) {
|
||||
if (_currentFrameNum != 0xffffffff) {
|
||||
_currentFrameNum = 0xffffffff;
|
||||
_currentFrame = nullptr;
|
||||
triggerRedraw();
|
||||
}
|
||||
} else if (_numFrames > 0) {
|
||||
uint32 f = frameNum % _numFrames;
|
||||
if (f != _currentFrameNum) {
|
||||
_currentFrameNum = f;
|
||||
_currentFrame = &_frameArray[f];
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SpriteFrame *Sprite::getFrame(const int32 index) {
|
||||
if (index < 0 || (uint32)index >= _numFrames)
|
||||
return nullptr;
|
||||
|
||||
return _frameArray[index].frame;
|
||||
}
|
||||
|
||||
void Sprite::draw(const Common::Rect &r) {
|
||||
if (_currentFrame) {
|
||||
Common::Rect frameBounds;
|
||||
_currentFrame->frame->getSurfaceBounds(frameBounds);
|
||||
|
||||
frameBounds.translate(_bounds.left + _currentFrame->frameLeft, _bounds.top + _currentFrame->frameTop);
|
||||
Common::Rect r1 = frameBounds.findIntersectingRect(r);
|
||||
|
||||
Common::Rect r2 = frameBounds;
|
||||
r2.translate(-_bounds.left - _currentFrame->frameLeft, -_bounds.top - _currentFrame->frameTop);
|
||||
|
||||
_currentFrame->frame->drawImage(r2, r1);
|
||||
}
|
||||
}
|
||||
|
||||
SpriteSequence::SpriteSequence(const DisplayElementID id, const DisplayElementID spriteID) :
|
||||
FrameSequence(id), _sprite(spriteID), _transparent(false) {
|
||||
}
|
||||
|
||||
void SpriteSequence::openFrameSequence() {
|
||||
if (!isSequenceOpen()) {
|
||||
FrameSequence::openFrameSequence();
|
||||
|
||||
if (isSequenceOpen()) {
|
||||
uint32 numFrames = getNumFrames();
|
||||
|
||||
for (uint32 i = 0; i < numFrames; ++i) {
|
||||
SpriteFrame *frame = new SpriteFrame();
|
||||
frame->initFromPICTResource(_resFork, i + 0x80, _transparent);
|
||||
_sprite.addFrame(frame, 0, 0);
|
||||
}
|
||||
|
||||
_sprite.setBounds(_bounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteSequence::closeFrameSequence() {
|
||||
if (isSequenceOpen()) {
|
||||
FrameSequence::closeFrameSequence();
|
||||
_sprite.discardFrames();
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteSequence::setBounds(const Common::Rect &bounds) {
|
||||
FrameSequence::setBounds(bounds);
|
||||
_sprite.setBounds(_bounds);
|
||||
}
|
||||
|
||||
void SpriteSequence::draw(const Common::Rect &r) {
|
||||
_sprite.draw(r);
|
||||
}
|
||||
|
||||
void SpriteSequence::newFrame(const uint16 frame) {
|
||||
_sprite.setCurrentFrameIndex(frame);
|
||||
}
|
||||
|
||||
#define DRAW_PIXEL() \
|
||||
if (bytesPerPixel == 2) \
|
||||
*((uint16 *)dst) = black; \
|
||||
else \
|
||||
*((uint32 *)dst) = black; \
|
||||
dst += bytesPerPixel
|
||||
|
||||
#define SKIP_PIXEL() \
|
||||
dst += bytesPerPixel
|
||||
|
||||
void ScreenDimmer::draw(const Common::Rect &r) {
|
||||
// We're going to emulate QuickDraw's srcOr+gray mode here
|
||||
// In this mode, every other y column is all black (odd-columns).
|
||||
// Basically, every row does three black and then one transparent
|
||||
// repeatedly.
|
||||
|
||||
// The output is identical to the original
|
||||
|
||||
uint32 black = g_system->getScreenFormat().RGBToColor(0, 0, 0);
|
||||
Graphics::Surface *screen = g_vm->_gfx->getWorkArea();
|
||||
byte bytesPerPixel = g_system->getScreenFormat().bytesPerPixel;
|
||||
|
||||
// We're currently doing it to the whole screen to simplify the code
|
||||
|
||||
for (int y = 0; y < 480; y++) {
|
||||
byte *dst = (byte *)screen->getBasePtr(0, y);
|
||||
|
||||
for (int x = 0; x < 640; x += 4) {
|
||||
if (y & 1) {
|
||||
DRAW_PIXEL();
|
||||
DRAW_PIXEL();
|
||||
SKIP_PIXEL();
|
||||
DRAW_PIXEL();
|
||||
} else {
|
||||
SKIP_PIXEL();
|
||||
DRAW_PIXEL();
|
||||
DRAW_PIXEL();
|
||||
DRAW_PIXEL();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#undef DRAW_PIXEL
|
||||
#undef SKIP_PIXEL
|
||||
|
||||
SoundLevel::SoundLevel(const DisplayElementID id) : DisplayElement(id) {
|
||||
_soundLevel = 0;
|
||||
}
|
||||
|
||||
void SoundLevel::incrementLevel() {
|
||||
if (_soundLevel < 12) {
|
||||
_soundLevel++;
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
void SoundLevel::decrementLevel() {
|
||||
if (_soundLevel > 0) {
|
||||
_soundLevel--;
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
uint16 SoundLevel::getSoundLevel() {
|
||||
return CLIP<int>(_soundLevel * 22, 0, 256);
|
||||
}
|
||||
|
||||
void SoundLevel::setSoundLevel(uint16 level) {
|
||||
uint16 newLevel = (level + 21) / 22;
|
||||
|
||||
if (newLevel != _soundLevel) {
|
||||
_soundLevel = newLevel;
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
void SoundLevel::draw(const Common::Rect &r) {
|
||||
Common::Rect levelRect(_bounds.right + (8 * (_soundLevel - 12)), _bounds.top, _bounds.right, _bounds.bottom);
|
||||
levelRect = r.findIntersectingRect(levelRect);
|
||||
|
||||
if (!levelRect.isEmpty()) {
|
||||
Graphics::Surface *screen = g_vm->_gfx->getWorkArea();
|
||||
screen->fillRect(levelRect, g_system->getScreenFormat().RGBToColor(0, 0, 0));
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
253
engines/pegasus/elements.h
Normal file
253
engines/pegasus/elements.h
Normal file
@@ -0,0 +1,253 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ELEMENTS_H
|
||||
#define PEGASUS_ELEMENTS_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/rect.h"
|
||||
#include "common/str.h"
|
||||
#include "common/system.h"
|
||||
#include "graphics/surface.h"
|
||||
|
||||
#include "pegasus/timers.h"
|
||||
#include "pegasus/util.h"
|
||||
|
||||
namespace Common {
|
||||
class MacResManager;
|
||||
}
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class DisplayElement : public IDObject {
|
||||
friend class GraphicsManager;
|
||||
public:
|
||||
DisplayElement(const DisplayElementID);
|
||||
virtual ~DisplayElement();
|
||||
|
||||
void setDisplayOrder(const DisplayOrder);
|
||||
DisplayOrder getDisplayOrder() const { return _elementOrder; }
|
||||
|
||||
bool validToDraw(DisplayOrder, DisplayOrder);
|
||||
|
||||
virtual void draw(const Common::Rect&) {}
|
||||
bool isDisplaying() { return _elementIsDisplaying; }
|
||||
virtual void startDisplaying();
|
||||
virtual void stopDisplaying();
|
||||
|
||||
virtual void show();
|
||||
virtual void hide();
|
||||
bool isVisible() { return _elementIsVisible; }
|
||||
|
||||
// triggerRedraw only triggers a draw if the element is displaying and visible.
|
||||
void triggerRedraw();
|
||||
void setTriggeredElement(DisplayElement *);
|
||||
|
||||
virtual void setBounds(const CoordType, const CoordType, const CoordType, const CoordType);
|
||||
virtual void setBounds(const Common::Rect &);
|
||||
virtual void getBounds(Common::Rect &) const;
|
||||
virtual void sizeElement(const CoordType, const CoordType);
|
||||
virtual void moveElementTo(const CoordType, const CoordType);
|
||||
virtual void moveElement(const CoordType, const CoordType);
|
||||
virtual void getLocation(CoordType &, CoordType &) const;
|
||||
virtual void getCenter(CoordType &, CoordType &) const;
|
||||
virtual void centerElementAt(const CoordType, const CoordType);
|
||||
|
||||
protected:
|
||||
Common::Rect _bounds;
|
||||
bool _elementIsVisible;
|
||||
DisplayElement *_triggeredElement;
|
||||
|
||||
// Used only by PegasusEngine
|
||||
bool _elementIsDisplaying;
|
||||
DisplayOrder _elementOrder;
|
||||
DisplayElement *_nextElement;
|
||||
};
|
||||
|
||||
// I'm using the proper "highlight" instead of the evil
|
||||
// QuickDraw "hilite" :P (deal with it!)
|
||||
class DropHighlight : public DisplayElement {
|
||||
public:
|
||||
DropHighlight(const DisplayElementID);
|
||||
~DropHighlight() override {}
|
||||
|
||||
void setHighlightColor(const uint32 &highlight) { _highlightColor = highlight; }
|
||||
void getHighlightColor(uint32 &highlight) const { highlight = _highlightColor; }
|
||||
|
||||
void setHighlightThickness(const uint16 thickness) { _thickness = thickness; }
|
||||
uint16 getHighlightThickness() const { return _thickness; }
|
||||
|
||||
void setHighlightCornerDiameter(const uint16 diameter) { _cornerDiameter = diameter; }
|
||||
uint16 getHighlightCornerDiameter() const { return _cornerDiameter; }
|
||||
|
||||
void draw(const Common::Rect&) override;
|
||||
|
||||
protected:
|
||||
uint32 _highlightColor;
|
||||
uint16 _thickness;
|
||||
uint16 _cornerDiameter;
|
||||
};
|
||||
|
||||
class Animation : public DisplayElement, public DynamicElement {
|
||||
public:
|
||||
Animation(const DisplayElementID id) : DisplayElement(id) {}
|
||||
};
|
||||
|
||||
class IdlerAnimation : public Animation, public Idler {
|
||||
public:
|
||||
IdlerAnimation(const DisplayElementID);
|
||||
|
||||
void startDisplaying() override;
|
||||
void stopDisplaying() override;
|
||||
|
||||
TimeValue getLastTime() const { return _lastTime; }
|
||||
|
||||
protected:
|
||||
void useIdleTime() override;
|
||||
virtual void timeChanged(const TimeValue);
|
||||
|
||||
TimeValue _lastTime;
|
||||
};
|
||||
|
||||
// This class reads PICT resources and plays them like a movie.
|
||||
// Assumes there is a resource of type 'PFrm' describing the time values for each
|
||||
// PICT frame, as well as the total time in the movie.
|
||||
// Assumes that PICT frames begin at PICT 128
|
||||
|
||||
class FrameSequence : public IdlerAnimation {
|
||||
public:
|
||||
FrameSequence(const DisplayElementID);
|
||||
~FrameSequence() override;
|
||||
|
||||
void useFileName(const Common::Path &fileName);
|
||||
|
||||
virtual void openFrameSequence();
|
||||
virtual void closeFrameSequence();
|
||||
bool isSequenceOpen() const;
|
||||
|
||||
uint16 getNumFrames() const { return _numFrames; }
|
||||
virtual uint16 getFrameNum() const { return _currentFrameNum; }
|
||||
virtual void setFrameNum(const int16);
|
||||
|
||||
protected:
|
||||
void timeChanged(const TimeValue) override;
|
||||
virtual void newFrame(const uint16) {}
|
||||
|
||||
Common::MacResManager *_resFork;
|
||||
TimeValue _duration;
|
||||
|
||||
uint16 _numFrames;
|
||||
Common::Array<TimeValue> _frameTimes;
|
||||
|
||||
uint16 _currentFrameNum;
|
||||
};
|
||||
|
||||
class SpriteFrame;
|
||||
|
||||
class Sprite : public DisplayElement {
|
||||
friend class SpriteFrame;
|
||||
public:
|
||||
Sprite(const DisplayElementID);
|
||||
~Sprite() override;
|
||||
|
||||
virtual void addPICTResourceFrame(const ResIDType, const bool, const CoordType, const CoordType);
|
||||
virtual uint32 addFrame(SpriteFrame *, const CoordType, const CoordType);
|
||||
virtual void removeFrame(const uint32);
|
||||
virtual void discardFrames();
|
||||
|
||||
// Setting the current frame.
|
||||
// If the index is negative, sets the current frame to NULL and hides the sprite.
|
||||
// If the index is larger than the number of frames in the sprite, the number
|
||||
// is treated modulo the number of frames.
|
||||
virtual void setCurrentFrameIndex(const int32);
|
||||
virtual uint32 getCurrentFrameIndex() const { return _currentFrameNum; }
|
||||
|
||||
virtual SpriteFrame *getFrame(const int32);
|
||||
|
||||
void draw(const Common::Rect &) override;
|
||||
|
||||
uint32 getNumFrames() const { return _numFrames; }
|
||||
|
||||
protected:
|
||||
struct SpriteFrameRec {
|
||||
SpriteFrame *frame;
|
||||
CoordType frameLeft;
|
||||
CoordType frameTop;
|
||||
};
|
||||
|
||||
uint32 _numFrames;
|
||||
uint32 _currentFrameNum;
|
||||
SpriteFrameRec *_currentFrame;
|
||||
Common::Array<SpriteFrameRec> _frameArray;
|
||||
};
|
||||
|
||||
class SpriteSequence : public FrameSequence {
|
||||
public:
|
||||
SpriteSequence(const DisplayElementID id, const DisplayElementID spriteID);
|
||||
~SpriteSequence() override {}
|
||||
|
||||
void useTransparent(bool transparent) { _transparent = transparent; }
|
||||
|
||||
void openFrameSequence() override;
|
||||
void closeFrameSequence() override;
|
||||
|
||||
void draw(const Common::Rect &) override;
|
||||
|
||||
void setBounds(const Common::Rect &) override;
|
||||
|
||||
protected:
|
||||
void newFrame(const uint16) override;
|
||||
|
||||
bool _transparent;
|
||||
Sprite _sprite;
|
||||
};
|
||||
|
||||
class ScreenDimmer : public DisplayElement {
|
||||
public:
|
||||
ScreenDimmer() : DisplayElement(kScreenDimmerID) {}
|
||||
~ScreenDimmer() override {}
|
||||
|
||||
void draw(const Common::Rect &) override;
|
||||
};
|
||||
|
||||
class SoundLevel : public DisplayElement {
|
||||
public:
|
||||
SoundLevel(const DisplayElementID);
|
||||
~SoundLevel() override {}
|
||||
|
||||
void incrementLevel();
|
||||
void decrementLevel();
|
||||
|
||||
uint16 getSoundLevel();
|
||||
void setSoundLevel(uint16);
|
||||
|
||||
void draw(const Common::Rect &) override;
|
||||
|
||||
protected:
|
||||
uint16 _soundLevel;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
291
engines/pegasus/energymonitor.cpp
Normal file
291
engines/pegasus/energymonitor.cpp
Normal file
@@ -0,0 +1,291 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/energymonitor.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/surface.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
Blinker::Blinker() {
|
||||
_sprite = nullptr;
|
||||
_frame1 = -1;
|
||||
_frame2 = -1;
|
||||
_blinkDuration = 0;
|
||||
}
|
||||
|
||||
void Blinker::startBlinking(Sprite *sprite, int32 frame1, int32 frame2, uint32 numBlinks, TimeValue blinkDuration, TimeScale blinkScale) {
|
||||
stopBlinking();
|
||||
_sprite = sprite;
|
||||
_frame1 = frame1;
|
||||
_frame2 = frame2;
|
||||
_blinkDuration = blinkDuration;
|
||||
setScale(blinkScale);
|
||||
setSegment(0, blinkDuration * numBlinks * 2, blinkScale);
|
||||
setTime(0);
|
||||
start();
|
||||
}
|
||||
|
||||
void Blinker::stopBlinking() {
|
||||
if (_sprite) {
|
||||
_sprite->setCurrentFrameIndex(_frame2);
|
||||
_sprite = nullptr;
|
||||
stop();
|
||||
}
|
||||
}
|
||||
|
||||
void Blinker::timeChanged(const TimeValue time) {
|
||||
if (_sprite && _blinkDuration != 0) {
|
||||
if (((time / _blinkDuration) & 1) != 0 || time == getDuration()) {
|
||||
_sprite->setCurrentFrameIndex(_frame2);
|
||||
if (!isRunning())
|
||||
stopBlinking();
|
||||
} else {
|
||||
_sprite->setCurrentFrameIndex(_frame1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum {
|
||||
kEnergyExpiredFlag = 1
|
||||
};
|
||||
|
||||
EnergyMonitor *g_energyMonitor = nullptr;
|
||||
|
||||
EnergyMonitor::EnergyMonitor() : IdlerAnimation(kEnergyBarID), _energyLight(kWarningLightID) {
|
||||
_stage = kStageNoStage;
|
||||
|
||||
_calibrating = false;
|
||||
_dontFlash = false;
|
||||
|
||||
setBounds(338, 48, 434, 54);
|
||||
|
||||
setDisplayOrder(kEnergyBarOrder);
|
||||
startDisplaying();
|
||||
|
||||
SpriteFrame *frame = new SpriteFrame();
|
||||
frame->initFromPICTResource(g_vm->_resFork, kLightOffID);
|
||||
_energyLight.addFrame(frame, 0, 0);
|
||||
|
||||
frame = new SpriteFrame();
|
||||
frame->initFromPICTResource(g_vm->_resFork, kLightYellowID);
|
||||
_energyLight.addFrame(frame, 0, 0);
|
||||
|
||||
frame = new SpriteFrame();
|
||||
frame->initFromPICTResource(g_vm->_resFork, kLightOrangeID);
|
||||
_energyLight.addFrame(frame, 0, 0);
|
||||
|
||||
frame = new SpriteFrame();
|
||||
frame->initFromPICTResource(g_vm->_resFork, kLightRedID);
|
||||
_energyLight.addFrame(frame, 0, 0);
|
||||
|
||||
_energyLight.setBounds(540, 35, 600, 59);
|
||||
_energyLight.setDisplayOrder(kEnergyLightOrder);
|
||||
_energyLight.startDisplaying();
|
||||
|
||||
setScale(1);
|
||||
setSegment(0, kMaxJMPEnergy);
|
||||
|
||||
setEnergyValue(kCasualEnergy);
|
||||
|
||||
g_energyMonitor = this;
|
||||
}
|
||||
|
||||
EnergyMonitor::~EnergyMonitor() {
|
||||
g_energyMonitor = nullptr;
|
||||
}
|
||||
|
||||
void EnergyMonitor::setEnergyValue(const uint32 value) {
|
||||
if (isRunning()) {
|
||||
stop();
|
||||
setTime(getStop() - value);
|
||||
start();
|
||||
} else {
|
||||
setTime(getStop() - value);
|
||||
}
|
||||
}
|
||||
|
||||
void EnergyMonitor::startEnergyDraining() {
|
||||
if (!isRunning()) {
|
||||
_energyLight.show();
|
||||
start();
|
||||
show();
|
||||
}
|
||||
}
|
||||
|
||||
void EnergyMonitor::setEnergyDrainRate(Common::Rational rate) {
|
||||
setRate(rate);
|
||||
}
|
||||
|
||||
Common::Rational EnergyMonitor::getEnergyDrainRate() {
|
||||
return getRate();
|
||||
}
|
||||
|
||||
void EnergyMonitor::stopEnergyDraining() {
|
||||
if (isRunning()) {
|
||||
stop();
|
||||
_energyLight.hide();
|
||||
hide();
|
||||
}
|
||||
}
|
||||
|
||||
void EnergyMonitor::drainEnergy(const int32 delta) {
|
||||
setTime(getTime() + delta);
|
||||
}
|
||||
|
||||
int32 EnergyMonitor::getCurrentEnergy() {
|
||||
return kMaxJMPEnergy - getTime();
|
||||
}
|
||||
|
||||
void EnergyMonitor::timeChanged(const TimeValue currentTime) {
|
||||
if (currentTime == getStop()) {
|
||||
if (g_vm->getEnergyDeathReason() != -1)
|
||||
g_vm->die(g_vm->getEnergyDeathReason());
|
||||
} else {
|
||||
uint32 currentEnergy = kMaxJMPEnergy - currentTime;
|
||||
|
||||
EnergyStage newStage;
|
||||
if (currentEnergy > kWorriedEnergy)
|
||||
newStage = kStageCasual;
|
||||
else if (currentEnergy > kNervousEnergy)
|
||||
newStage = kStageWorried;
|
||||
else if (currentEnergy > kPanicStrickenEnergy)
|
||||
newStage = kStageNervous;
|
||||
else
|
||||
newStage = kStagePanicStricken;
|
||||
|
||||
if (_stage != newStage) {
|
||||
uint32 newFrame;
|
||||
|
||||
switch (newStage) {
|
||||
case kStageCasual:
|
||||
_barColor = g_system->getScreenFormat().RGBToColor(0x48, 0xB0, 0xD8);
|
||||
newFrame = kFrameLightOff;
|
||||
break;
|
||||
case kStageWorried:
|
||||
_barColor = g_system->getScreenFormat().RGBToColor(0xD8, 0xC0, 0x30);
|
||||
newFrame = kFrameLightYellow;
|
||||
break;
|
||||
case kStageNervous:
|
||||
_barColor = g_system->getScreenFormat().RGBToColor(0xD8, 0x78, 0x38);
|
||||
newFrame = kFrameLightOrange;
|
||||
break;
|
||||
case kStagePanicStricken:
|
||||
_barColor = g_system->getScreenFormat().RGBToColor(0xD8, 0x40, 0x38);
|
||||
newFrame = kFrameLightRed;
|
||||
break;
|
||||
default:
|
||||
error("no stage in energy monitor?");
|
||||
break;
|
||||
}
|
||||
|
||||
_stage = newStage;
|
||||
uint32 oldFrame = _energyLight.getCurrentFrameIndex();
|
||||
|
||||
if (!_calibrating) {
|
||||
if (oldFrame > newFrame || oldFrame == 0xffffffff || _dontFlash) {
|
||||
_energyLight.setCurrentFrameIndex(newFrame);
|
||||
_dontFlash = false;
|
||||
} else {
|
||||
_lightBlinker.startBlinking(&_energyLight, oldFrame, newFrame, 4, 1, 3);
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Common::Rect r;
|
||||
calcLevelRect(r);
|
||||
if (r != _levelRect) {
|
||||
_levelRect = r;
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EnergyMonitor::calcLevelRect(Common::Rect &r) {
|
||||
if (getStop() == 0) {
|
||||
r = Common::Rect();
|
||||
} else {
|
||||
getBounds(r);
|
||||
r.left = r.right - r.width() * (kMaxJMPEnergy - getTime()) / getStop();
|
||||
}
|
||||
}
|
||||
|
||||
void EnergyMonitor::draw(const Common::Rect &r) {
|
||||
Common::Rect r2 = r.findIntersectingRect(_levelRect);
|
||||
|
||||
if (!r2.isEmpty()) {
|
||||
Graphics::Surface *screen = g_vm->_gfx->getWorkArea();
|
||||
screen->fillRect(r2, _barColor);
|
||||
}
|
||||
}
|
||||
|
||||
void EnergyMonitor::calibrateEnergyBar() {
|
||||
_calibrating = true;
|
||||
|
||||
g_vm->setEnergyDeathReason(-1);
|
||||
|
||||
uint32 numFrames = _energyLight.getNumFrames();
|
||||
for (uint32 i = 1; i < numFrames; i++) {
|
||||
_energyLight.setCurrentFrameIndex(i);
|
||||
_energyLight.show();
|
||||
g_vm->delayShell(1, 3);
|
||||
_energyLight.hide();
|
||||
g_vm->delayShell(1, 3);
|
||||
}
|
||||
|
||||
_energyLight.setCurrentFrameIndex(0);
|
||||
_energyLight.hide();
|
||||
|
||||
setEnergyValue(0);
|
||||
setEnergyDrainRate(-(int32)kMaxJMPEnergy / 2);
|
||||
show();
|
||||
|
||||
// Make sure warning light is hidden...
|
||||
_energyLight.hide();
|
||||
while (getCurrentEnergy() != (int32)kMaxJMPEnergy) {
|
||||
InputDevice.pumpEvents();
|
||||
g_vm->checkCallBacks();
|
||||
g_vm->refreshDisplay();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
|
||||
g_vm->refreshDisplay();
|
||||
setEnergyDrainRate(0);
|
||||
hide();
|
||||
|
||||
_calibrating = false;
|
||||
}
|
||||
|
||||
void EnergyMonitor::restoreLastEnergyValue() {
|
||||
_dontFlash = true;
|
||||
setEnergyValue(g_vm->getSavedEnergyValue());
|
||||
g_vm->resetEnergyDeathReason();
|
||||
}
|
||||
|
||||
void EnergyMonitor::saveCurrentEnergyValue() {
|
||||
g_vm->setLastEnergyValue(getCurrentEnergy());
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
110
engines/pegasus/energymonitor.h
Normal file
110
engines/pegasus/energymonitor.h
Normal file
@@ -0,0 +1,110 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ENERGYMONITOR_H
|
||||
#define PEGASUS_ENERGYMONITOR_H
|
||||
|
||||
#include "pegasus/elements.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class Sprite;
|
||||
|
||||
class Blinker : private IdlerTimeBase {
|
||||
public:
|
||||
Blinker();
|
||||
~Blinker() override {}
|
||||
|
||||
void startBlinking(Sprite *sprite, int32 frame1, int32 frame2, uint32 numBlinks, TimeValue blinkDuration, TimeScale blinkScale);
|
||||
void stopBlinking();
|
||||
|
||||
protected:
|
||||
void timeChanged(const TimeValue) override;
|
||||
|
||||
Sprite *_sprite;
|
||||
int32 _frame1;
|
||||
int32 _frame2;
|
||||
TimeValue _blinkDuration;
|
||||
};
|
||||
|
||||
// Energy monitor constants.
|
||||
|
||||
// These are in seconds.
|
||||
// Max is two hours
|
||||
static const uint32 kMaxJMPEnergy = 7200;
|
||||
|
||||
static const uint32 kCasualEnergy = kMaxJMPEnergy * 100 / 100; // 100%
|
||||
static const uint32 kWorriedEnergy = kMaxJMPEnergy * 50 / 100; // 50%
|
||||
static const uint32 kNervousEnergy = kMaxJMPEnergy * 25 / 100; // 25%
|
||||
static const uint32 kPanicStrickenEnergy = kMaxJMPEnergy * 5 / 100; // 5%
|
||||
|
||||
static const uint32 kFullEnergy = kCasualEnergy;
|
||||
|
||||
static const uint32 kFrameLightOff = 0;
|
||||
static const uint32 kFrameLightYellow = 1;
|
||||
static const uint32 kFrameLightOrange = 2;
|
||||
static const uint32 kFrameLightRed = 3;
|
||||
|
||||
static const int kEnergyDrainNormal = 1;
|
||||
static const int kMarsReactorEnergyDrainNoShield = 6;
|
||||
static const int kMarsReactorEnergyDrainWithShield = 3;
|
||||
static const int kWSCPoisonEnergyDrainWithDart = 20;
|
||||
static const int kWSCPoisonEnergyDrainNoDart = 10;
|
||||
|
||||
class EnergyMonitor : private IdlerAnimation {
|
||||
public:
|
||||
EnergyMonitor();
|
||||
~EnergyMonitor() override;
|
||||
|
||||
void setEnergyValue(const uint32);
|
||||
void startEnergyDraining();
|
||||
void setEnergyDrainRate(Common::Rational);
|
||||
Common::Rational getEnergyDrainRate();
|
||||
void stopEnergyDraining();
|
||||
void drainEnergy(const int32);
|
||||
int32 getCurrentEnergy();
|
||||
|
||||
void restoreLastEnergyValue();
|
||||
void saveCurrentEnergyValue();
|
||||
|
||||
void calibrateEnergyBar();
|
||||
|
||||
protected:
|
||||
void timeChanged(const TimeValue) override;
|
||||
void calcLevelRect(Common::Rect &);
|
||||
void draw(const Common::Rect &) override;
|
||||
|
||||
uint32 _barColor;
|
||||
Common::Rect _levelRect;
|
||||
EnergyStage _stage;
|
||||
Sprite _energyLight;
|
||||
Blinker _lightBlinker;
|
||||
bool _calibrating, _dontFlash;
|
||||
};
|
||||
|
||||
extern EnergyMonitor *g_energyMonitor;
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
218
engines/pegasus/fader.cpp
Normal file
218
engines/pegasus/fader.cpp
Normal file
@@ -0,0 +1,218 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/fader.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/sound.h"
|
||||
#include "pegasus/util.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
Fader::Fader() {
|
||||
_currentValue = 0;
|
||||
_currentFaderMove._numKnots = 0;
|
||||
}
|
||||
|
||||
void Fader::setFaderValue(const int32 newValue) {
|
||||
_currentValue = newValue;
|
||||
}
|
||||
|
||||
bool Fader::initFaderMove(const FaderMoveSpec &spec) {
|
||||
bool faderMoves = false;
|
||||
int32 value = 0;
|
||||
|
||||
if (spec._numKnots > 0) {
|
||||
stopFader();
|
||||
value = spec._knots[0].knotValue;
|
||||
TimeValue startTime = spec._knots[0].knotTime;
|
||||
|
||||
if (startTime != 0xffffffff) {
|
||||
if (spec._numKnots > 1) {
|
||||
TimeValue stopTime = spec._knots[spec._numKnots - 1].knotTime;
|
||||
|
||||
if (spec._faderScale > 0) {
|
||||
if (stopTime > startTime) {
|
||||
for (uint32 i = 1; i < spec._numKnots; ++i) {
|
||||
if (spec._knots[i - 1].knotValue != spec._knots[i].knotValue) {
|
||||
faderMoves = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (faderMoves)
|
||||
_currentFaderMove = spec;
|
||||
} else if (spec._knots[spec._numKnots - 1].knotValue != value) {
|
||||
value = spec._knots[spec._numKnots - 1].knotValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setFaderValue(value);
|
||||
return faderMoves;
|
||||
}
|
||||
|
||||
void Fader::startFader(const FaderMoveSpec &spec) {
|
||||
if (initFaderMove(spec)) {
|
||||
setFlags(0);
|
||||
setScale(spec._faderScale);
|
||||
setSegment(spec._knots[0].knotTime, spec._knots[spec._numKnots - 1].knotTime);
|
||||
setTime(spec._knots[0].knotTime);
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
void Fader::startFaderSync(const FaderMoveSpec &spec) {
|
||||
if (initFaderMove(spec)) {
|
||||
setFlags(0);
|
||||
setScale(spec._faderScale);
|
||||
setSegment(spec._knots[0].knotTime, spec._knots[spec._numKnots - 1].knotTime);
|
||||
setTime(spec._knots[0].knotTime);
|
||||
start();
|
||||
|
||||
while (isFading()) {
|
||||
InputDevice.pumpEvents();
|
||||
g_vm->checkCallBacks();
|
||||
useIdleTime();
|
||||
}
|
||||
|
||||
// Once more, for good measure, to make sure that there are no boundary
|
||||
// condition problems.
|
||||
useIdleTime();
|
||||
stopFader();
|
||||
}
|
||||
}
|
||||
|
||||
void Fader::loopFader(const FaderMoveSpec &spec) {
|
||||
if (initFaderMove(spec)) {
|
||||
setFlags(kLoopTimeBase);
|
||||
setScale(spec._faderScale);
|
||||
setSegment(spec._knots[0].knotTime, spec._knots[spec._numKnots - 1].knotTime);
|
||||
setTime(spec._knots[0].knotTime);
|
||||
start();
|
||||
}
|
||||
}
|
||||
|
||||
void Fader::stopFader() {
|
||||
stop();
|
||||
}
|
||||
|
||||
void Fader::pauseFader() {
|
||||
stopFader();
|
||||
}
|
||||
|
||||
void Fader::continueFader() {
|
||||
if (getTime() < getStop())
|
||||
start();
|
||||
}
|
||||
|
||||
void Fader::timeChanged(const TimeValue newTime) {
|
||||
if (_currentFaderMove._numKnots != 0) {
|
||||
uint32 i;
|
||||
for (i = 0; i < _currentFaderMove._numKnots; i++)
|
||||
if (_currentFaderMove._knots[i].knotTime > newTime)
|
||||
break;
|
||||
|
||||
int32 newValue;
|
||||
if (i == 0)
|
||||
newValue = _currentFaderMove._knots[0].knotValue;
|
||||
else if (i == _currentFaderMove._numKnots)
|
||||
newValue = _currentFaderMove._knots[i - 1].knotValue;
|
||||
else
|
||||
newValue = linearInterp(_currentFaderMove._knots[i - 1].knotTime, _currentFaderMove._knots[i].knotTime, newTime, _currentFaderMove._knots[i - 1].knotValue, _currentFaderMove._knots[i].knotValue);
|
||||
|
||||
if (newValue != _currentValue)
|
||||
setFaderValue(newValue);
|
||||
}
|
||||
}
|
||||
|
||||
void FaderMoveSpec::makeOneKnotFaderSpec(const int32 knotValue) {
|
||||
_numKnots = 1;
|
||||
_knots[0].knotTime = 0;
|
||||
_knots[0].knotValue = knotValue;
|
||||
}
|
||||
|
||||
void FaderMoveSpec::makeTwoKnotFaderSpec(const TimeScale faderScale, const TimeValue time1, const int32 value1, const TimeValue time2, const int32 value2) {
|
||||
_numKnots = 2;
|
||||
_faderScale = faderScale;
|
||||
_knots[0].knotTime = time1;
|
||||
_knots[0].knotValue = value1;
|
||||
_knots[1].knotTime = time2;
|
||||
_knots[1].knotValue = value2;
|
||||
}
|
||||
|
||||
void FaderMoveSpec::insertFaderKnot(const TimeValue knotTime, const int32 knotValue) {
|
||||
if (_numKnots != kMaxFaderKnots) {
|
||||
uint32 index;
|
||||
for (index = 0; index < _numKnots; index++) {
|
||||
if (knotTime == _knots[index].knotTime) {
|
||||
_knots[index].knotValue = knotValue;
|
||||
return;
|
||||
} else if (knotTime < _knots[index].knotTime) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32 i = _numKnots; i > index; i--)
|
||||
_knots[i] = _knots[i - 1];
|
||||
|
||||
_knots[index].knotTime = knotTime;
|
||||
_knots[index].knotValue = knotValue;
|
||||
_numKnots++;
|
||||
}
|
||||
}
|
||||
|
||||
void FaderAnimation::setFaderValue(const int32 newValue) {
|
||||
if (getFaderValue() != newValue) {
|
||||
Fader::setFaderValue(newValue);
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
SoundFader::SoundFader() {
|
||||
_sound = nullptr;
|
||||
_masterVolume = 0xff;
|
||||
}
|
||||
|
||||
void SoundFader::attachSound(Sound *sound) {
|
||||
if (!sound && isFading())
|
||||
stopFader();
|
||||
|
||||
_sound = sound;
|
||||
}
|
||||
|
||||
void SoundFader::setFaderValue(const int32 newVolume) {
|
||||
if (_sound)
|
||||
_sound->setVolume((newVolume * _masterVolume) >> 8);
|
||||
|
||||
_currentValue = newVolume;
|
||||
}
|
||||
|
||||
void SoundFader::setMasterVolume(const uint16 masterVolume) {
|
||||
_masterVolume = masterVolume;
|
||||
setFaderValue(getFaderValue());
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
129
engines/pegasus/fader.h
Normal file
129
engines/pegasus/fader.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_FADER_H
|
||||
#define PEGASUS_FADER_H
|
||||
|
||||
#include "pegasus/elements.h"
|
||||
#include "pegasus/timers.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class Fader;
|
||||
|
||||
class FaderMoveSpec {
|
||||
friend class Fader;
|
||||
public:
|
||||
FaderMoveSpec() {
|
||||
_faderScale = kDefaultTimeScale;
|
||||
_numKnots = 0;
|
||||
}
|
||||
|
||||
FaderMoveSpec(const TimeScale scale) {
|
||||
_faderScale = scale;
|
||||
_numKnots = 0;
|
||||
}
|
||||
|
||||
void setFaderScale(const TimeScale scale) { _faderScale = scale; }
|
||||
TimeScale getFaderScale() const { return _faderScale; }
|
||||
|
||||
void makeOneKnotFaderSpec(const int32);
|
||||
void makeTwoKnotFaderSpec(const TimeScale, const TimeValue, const int32, const TimeValue, const int32);
|
||||
|
||||
void insertFaderKnot(const TimeValue, const int32);
|
||||
|
||||
uint32 getNumKnots() const { return _numKnots; }
|
||||
TimeValue getNthKnotTime(const uint32 index) const { return _knots[index].knotTime; }
|
||||
int32 getNthKnotValue(const uint32 index) const { return _knots[index].knotValue; }
|
||||
|
||||
protected:
|
||||
struct FaderKnot {
|
||||
TimeValue knotTime;
|
||||
int32 knotValue;
|
||||
};
|
||||
|
||||
TimeScale _faderScale;
|
||||
uint32 _numKnots;
|
||||
|
||||
static const uint32 kMaxFaderKnots = 20;
|
||||
FaderKnot _knots[kMaxFaderKnots];
|
||||
};
|
||||
|
||||
class Fader : public IdlerTimeBase {
|
||||
public:
|
||||
Fader();
|
||||
~Fader() override {}
|
||||
|
||||
virtual void setFaderValue(const int32);
|
||||
int32 getFaderValue() const { return _currentValue; }
|
||||
virtual void startFader(const FaderMoveSpec &);
|
||||
virtual void startFaderSync(const FaderMoveSpec &);
|
||||
virtual void loopFader(const FaderMoveSpec &);
|
||||
virtual void stopFader();
|
||||
virtual bool isFading() { return isRunning(); }
|
||||
|
||||
void pauseFader();
|
||||
void continueFader();
|
||||
|
||||
void getCurrentFaderMove(FaderMoveSpec &spec) { spec = _currentFaderMove; }
|
||||
|
||||
protected:
|
||||
bool initFaderMove(const FaderMoveSpec &);
|
||||
void timeChanged(const TimeValue) override;
|
||||
|
||||
int32 _currentValue;
|
||||
FaderMoveSpec _currentFaderMove;
|
||||
};
|
||||
|
||||
class FaderAnimation : public DisplayElement, public Fader {
|
||||
public:
|
||||
FaderAnimation(const DisplayElementID id) : DisplayElement(id) {}
|
||||
~FaderAnimation() override {}
|
||||
|
||||
void setFaderValue(const int32) override;
|
||||
};
|
||||
|
||||
class Sound;
|
||||
|
||||
class SoundFader : public Fader {
|
||||
friend class Sound;
|
||||
public:
|
||||
SoundFader();
|
||||
~SoundFader() override {}
|
||||
|
||||
void setFaderValue(const int32) override;
|
||||
|
||||
void setMasterVolume(const uint16);
|
||||
uint16 getMasterVolume() const { return _masterVolume; }
|
||||
|
||||
protected:
|
||||
void attachSound(Sound *);
|
||||
|
||||
Sound *_sound;
|
||||
uint16 _masterVolume;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
2358
engines/pegasus/gamestate.cpp
Normal file
2358
engines/pegasus/gamestate.cpp
Normal file
File diff suppressed because it is too large
Load Diff
885
engines/pegasus/gamestate.h
Normal file
885
engines/pegasus/gamestate.h
Normal file
@@ -0,0 +1,885 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_GAMESTATE_H
|
||||
#define PEGASUS_GAMESTATE_H
|
||||
|
||||
#include "common/singleton.h"
|
||||
#include "common/util.h"
|
||||
|
||||
#include "pegasus/types.h"
|
||||
#include "pegasus/util.h"
|
||||
#include "pegasus/items/item.h"
|
||||
|
||||
namespace Common {
|
||||
class Error;
|
||||
class ReadStream;
|
||||
class WriteStream;
|
||||
}
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
// The only things saved in here are things which get written out to a saved game file...
|
||||
|
||||
enum {
|
||||
kGlobalWalkthroughFlag,
|
||||
kGlobalShieldOnFlag,
|
||||
kGlobalEasterEggFlag,
|
||||
kGlobalBeenToWSCFlag,
|
||||
kGlobalBeenToMarsFlag,
|
||||
kGlobalBeenToNoradFlag,
|
||||
kGlobalWSCFinishedFlag,
|
||||
kGlobalMarsFinishedFlag,
|
||||
kGlobalNoradFinishedFlag,
|
||||
kNumGlobalFlags
|
||||
};
|
||||
|
||||
enum {
|
||||
kScoringSawINNFlag,
|
||||
kScoringTookShowerFlag,
|
||||
kScoringFixedHairFlag,
|
||||
kScoringGotKeyCardFlag,
|
||||
kScoringReadPaperFlag,
|
||||
kScoringLookThroughTelescopeFlag,
|
||||
kScoringSawCaldoriaKioskFlag,
|
||||
kScoringGoToTSAFlag,
|
||||
kScoringEnterTSAFlag,
|
||||
kScoringSawBust1Flag,
|
||||
kScoringSawBust2Flag,
|
||||
kScoringSawBust3Flag,
|
||||
kScoringSawBust4Flag,
|
||||
kScoringSawBust5Flag,
|
||||
kScoringSawBust6Flag,
|
||||
kScoringSawTheoryFlag,
|
||||
kScoringSawBackgroundFlag,
|
||||
kScoringSawProcedureFlag,
|
||||
kScoringGotJourneymanKeyFlag,
|
||||
kScoringGotPegasusBiochipFlag,
|
||||
kScoringGotBiosuitFlag,
|
||||
kScoringGoToPrehistoricFlag,
|
||||
kScoringPutLogInReaderFlag,
|
||||
kScoringSawCaldoriaNormalFlag,
|
||||
kScoringSawCaldoriaAlteredFlag,
|
||||
kScoringSawNoradNormalFlag,
|
||||
kScoringSawNoradAlteredFlag,
|
||||
kScoringSawMarsNormalFlag,
|
||||
kScoringSawMarsAlteredFlag,
|
||||
kScoringSawWSCNormalFlag,
|
||||
kScoringSawWSCAlteredFlag,
|
||||
kScoringWentToReadyRoom2Flag,
|
||||
kScoringWentAfterSinclairFlag,
|
||||
kScoringUsedCardBombFlag,
|
||||
kScoringShieldedCardBombFlag,
|
||||
kScoringStunnedSinclairFlag,
|
||||
kScoringDisarmedNukeFlag,
|
||||
|
||||
kScoringThrewBreakerFlag,
|
||||
kScoringExtendedBridgeFlag,
|
||||
kScoringGotHistoricalLogFlag,
|
||||
kScoringFinishedPrehistoricFlag,
|
||||
|
||||
kScoringThrownByRobotFlag,
|
||||
kScoringGotMarsCardFlag,
|
||||
kScoringSawMarsKioskFlag,
|
||||
kScoringSawTransportMapFlag,
|
||||
kScoringGotCrowBarFlag,
|
||||
kScoringTurnedOnTransportFlag,
|
||||
kScoringGotOxygenMaskFlag,
|
||||
kScoringAvoidedRobotFlag,
|
||||
kScoringActivatedPlatformFlag,
|
||||
kScoringUsedLiquidNitrogenFlag,
|
||||
kScoringUsedCrowBarFlag,
|
||||
kScoringFoundCardBombFlag,
|
||||
kScoringDisarmedCardBombFlag,
|
||||
kScoringGotCardBombFlag,
|
||||
kScoringThreadedMazeFlag,
|
||||
kScoringThreadedGearRoomFlag,
|
||||
kScoringEnteredShuttleFlag,
|
||||
kScoringEnteredLaunchTubeFlag,
|
||||
kScoringStoppedRobotsShuttleFlag,
|
||||
kScoringGotMarsOpMemChipFlag,
|
||||
kScoringFinishedMarsFlag,
|
||||
|
||||
kScoringSawSecurityMonitorFlag,
|
||||
kScoringFilledOxygenCanisterFlag,
|
||||
kScoringFilledArgonCanisterFlag,
|
||||
kScoringSawUnconsciousOperatorFlag,
|
||||
kScoringWentThroughPressureDoorFlag,
|
||||
kScoringPreppedSubFlag,
|
||||
kScoringEnteredSubFlag,
|
||||
kScoringExitedSubFlag,
|
||||
kScoringSawRobotAt54NorthFlag,
|
||||
kScoringPlayedWithClawFlag,
|
||||
kScoringUsedRetinalChipFlag,
|
||||
kScoringFinishedGlobeGameFlag,
|
||||
kScoringStoppedNoradRobotFlag,
|
||||
kScoringGotNoradOpMemChipFlag,
|
||||
kScoringFinishedNoradFlag,
|
||||
|
||||
kScoringRemovedDartFlag,
|
||||
kScoringAnalyzedDartFlag,
|
||||
kScoringBuiltAntidoteFlag,
|
||||
kScoringGotSinclairKeyFlag,
|
||||
kScoringGotArgonCanisterFlag,
|
||||
kScoringGotNitrogenCanisterFlag,
|
||||
kScoringPlayedWithMessagesFlag,
|
||||
kScoringSawMorphExperimentFlag,
|
||||
kScoringEnteredSinclairOfficeFlag,
|
||||
kScoringSawBrochureFlag,
|
||||
kScoringSawSinclairEntry1Flag,
|
||||
kScoringSawSinclairEntry2Flag,
|
||||
kScoringSawSinclairEntry3Flag,
|
||||
kScoringSawWSCDirectoryFlag,
|
||||
kScoringUsedCrowBarInWSCFlag,
|
||||
kScoringFinishedPlasmaDodgeFlag,
|
||||
kScoringOpenedCatwalkFlag,
|
||||
kScoringStoppedWSCRobotFlag,
|
||||
kScoringGotWSCOpMemChipFlag,
|
||||
kScoringFinishedWSCFlag,
|
||||
|
||||
kScoringMarsGandhiFlag,
|
||||
kScoringNoradGandhiFlag,
|
||||
kScoringWSCGandhiFlag,
|
||||
|
||||
kNumScoringFlags
|
||||
};
|
||||
|
||||
enum {
|
||||
kCaldoriaSeenPullbackFlag,
|
||||
kCaldoriaMadeOJFlag,
|
||||
kCaldoriaWokenUpFlag,
|
||||
kCaldoriaDidRecalibrationFlag,
|
||||
kCaldoriaSeenSinclairInElevatorFlag,
|
||||
kCaldoriaINNAnnouncingFlag,
|
||||
kCaldoriaSeenINNFlag,
|
||||
kCaldoriaSeenMessagesFlag,
|
||||
kCaldoriaSinclairShotFlag,
|
||||
kCaldoriaBombDisarmedFlag,
|
||||
kCaldoriaRoofDoorOpenFlag,
|
||||
kCaldoriaDoneHygieneFlag,
|
||||
kCaldoriaSawVoiceAnalysisFlag,
|
||||
kCaldoriaDoorBombedFlag,
|
||||
kCaldoriaGunAimedFlag,
|
||||
kNumCaldoriaFlags
|
||||
};
|
||||
|
||||
enum {
|
||||
kCaldoriaNoFuseRunning,
|
||||
kCaldoriaDoorBombFuseRunning,
|
||||
kCaldoriaSinclairFuseRunning
|
||||
};
|
||||
|
||||
enum {
|
||||
kTSAIDedAtDoorFlag,
|
||||
kTSA0BZoomedInFlag,
|
||||
kTSAFrontDoorUnlockedOutsideFlag,
|
||||
kTSAFrontDoorUnlockedInsideFlag,
|
||||
kTSASeenRobotGreetingFlag,
|
||||
kTSASeenTheoryFlag,
|
||||
kTSASeenBackgroundFlag,
|
||||
kTSASeenProcedureFlag,
|
||||
kTSASeenAgent3AtDoorFlag,
|
||||
kTSACommandCenterLockedFlag,
|
||||
kTSASeenCaldoriaNormalFlag,
|
||||
kTSASeenCaldoriaAlteredFlag,
|
||||
kTSASeenNoradNormalFlag,
|
||||
kTSASeenNoradAlteredFlag,
|
||||
kTSASeenMarsNormalFlag,
|
||||
kTSASeenMarsAlteredFlag,
|
||||
kTSASeenWSCNormalFlag,
|
||||
kTSASeenWSCAlteredFlag,
|
||||
kTSABiosuitOnFlag,
|
||||
kNumTSAFlags
|
||||
};
|
||||
|
||||
enum {
|
||||
kPrehistoricTriedToExtendBridgeFlag,
|
||||
kPrehistoricSeenTimeStreamFlag,
|
||||
kPrehistoricSeenFlyer1Flag,
|
||||
kPrehistoricSeenFlyer2Flag,
|
||||
kPrehistoricSeenBridgeZoomFlag,
|
||||
kPrehistoricBreakerThrownFlag,
|
||||
kNumPrehistoricFlags
|
||||
};
|
||||
|
||||
enum {
|
||||
kNoradSeenTimeStreamFlag,
|
||||
kNoradGassedFlag,
|
||||
kNoradFillingStationOnFlag,
|
||||
kNoradN22MessagePlayedFlag,
|
||||
kNoradArrivedFromSubFlag,
|
||||
kNoradWaitingForLaserFlag,
|
||||
kNoradRetScanGoodFlag,
|
||||
kNoradPlayedGlobeGameFlag,
|
||||
kNoradBeatRobotWithClawFlag,
|
||||
kNoradBeatRobotWithDoorFlag,
|
||||
kNumNoradFlags
|
||||
};
|
||||
|
||||
enum {
|
||||
kMarsSeenTimeStreamFlag,
|
||||
kMarsHeardUpperPodMessageFlag,
|
||||
kMarsRobotThrownPlayerFlag,
|
||||
kMarsHeardCheckInMessageFlag,
|
||||
kMarsPodAtUpperPlatformFlag,
|
||||
kMarsSeenThermalScanFlag,
|
||||
kMarsArrivedBelowFlag,
|
||||
kMarsSeenRobotAtReactorFlag,
|
||||
kMarsAvoidedReactorRobotFlag,
|
||||
kMarsInAirlockFlag,
|
||||
kMarsAirlockOpenFlag,
|
||||
kMarsMaskOnFillerFlag,
|
||||
kMarsLockFrozenFlag,
|
||||
kMarsLockBrokenFlag,
|
||||
kMarsMazeDoorPair1Flag,
|
||||
kMarsMazeDoorPair2Flag,
|
||||
kMarsMazeDoorPair3Flag,
|
||||
kMarsSawRobotLeaveFlag,
|
||||
kMarsSecurityDownFlag,
|
||||
kMarsHitRobotWithCannonFlag,
|
||||
kMarsReadyForShuttleTransportFlag,
|
||||
kMarsFinishedCanyonChaseFlag,
|
||||
kMarsThreadedMazeFlag,
|
||||
kNumMarsFlags
|
||||
};
|
||||
|
||||
enum {
|
||||
kWSCSeenTimeStreamFlag,
|
||||
kWSCPoisonedFlag,
|
||||
kWSCAnsweredAboutDartFlag,
|
||||
kWSCRemovedDartFlag,
|
||||
kWSCAnalyzerOnFlag,
|
||||
kWSCDartInAnalyzerFlag,
|
||||
kWSCAnalyzedDartFlag,
|
||||
kWSCSawMorphFlag,
|
||||
kWSCDesignedAntidoteFlag,
|
||||
kWSCPickedUpAntidoteFlag,
|
||||
kWSCOfficeMessagesOpenFlag,
|
||||
kWSCSeenNerdFlag,
|
||||
kWSCHeardPage1Flag,
|
||||
kWSCHeardPage2Flag,
|
||||
kWSCHeardCheckInFlag,
|
||||
kWSCDidPlasmaDodgeFlag,
|
||||
kWSCSeenSinclairLectureFlag,
|
||||
kWSCBeenAtWSC93Flag,
|
||||
kWSCCatwalkDarkFlag,
|
||||
kWSCRobotDeadFlag,
|
||||
kWSCRobotGoneFlag,
|
||||
kNumWSCFlags
|
||||
};
|
||||
|
||||
class GameStateManager : public Common::Singleton<GameStateManager> {
|
||||
public:
|
||||
GameStateManager() { resetGameState(); }
|
||||
|
||||
// Base game state
|
||||
Common::Error writeGameState(Common::WriteStream *stream);
|
||||
Common::Error readGameState(Common::ReadStream *stream);
|
||||
|
||||
void resetGameState();
|
||||
|
||||
void getCurrentLocation(NeighborhoodID &neighborhood, RoomID &room, DirectionConstant &direction);
|
||||
void setCurrentLocation(const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction);
|
||||
|
||||
NeighborhoodID getCurrentNeighborhood();
|
||||
void setCurrentNeighborhood(const NeighborhoodID neighborhood);
|
||||
RoomID getCurrentRoom();
|
||||
void setCurrentRoom(const RoomID room);
|
||||
DirectionConstant getCurrentDirection();
|
||||
void setCurrentDirection(const DirectionConstant direction);
|
||||
|
||||
RoomViewID getCurrentRoomAndView();
|
||||
|
||||
void getNextLocation(NeighborhoodID &neighborhood, RoomID &room, DirectionConstant &direction);
|
||||
void setNextLocation(const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction);
|
||||
|
||||
NeighborhoodID getNextNeighborhood();
|
||||
void setNextNeighborhood(const NeighborhoodID neighborhood);
|
||||
RoomID getNextRoom();
|
||||
void setNextRoom(const RoomID room);
|
||||
DirectionConstant getNextDirection();
|
||||
void setNextDirection(const DirectionConstant direction);
|
||||
|
||||
void getLastLocation(NeighborhoodID &neighborhood, RoomID &room, DirectionConstant &direction);
|
||||
void setLastLocation(const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction);
|
||||
|
||||
NeighborhoodID getLastNeighborhood();
|
||||
void setLastNeighborhood(const NeighborhoodID neighborhood);
|
||||
RoomID getLastRoom();
|
||||
void setLastRoom(const RoomID room);
|
||||
DirectionConstant getLastDirection();
|
||||
void setLastDirection(const DirectionConstant direction);
|
||||
|
||||
RoomViewID getLastRoomAndView();
|
||||
|
||||
void getOpenDoorLocation(RoomID &room, DirectionConstant &direction);
|
||||
void setOpenDoorLocation(const RoomID room, const DirectionConstant direction);
|
||||
RoomID getOpenDoorRoom();
|
||||
void setOpenDoorRoom(const RoomID room);
|
||||
DirectionConstant getOpenDoorDirection();
|
||||
void setOpenDoorDirection(const DirectionConstant direction);
|
||||
|
||||
RoomViewID getDoorOpenRoomAndView();
|
||||
|
||||
bool isCurrentDoorOpen();
|
||||
|
||||
// Pegasus Prime
|
||||
|
||||
// Scoring...
|
||||
// Scoring "Set" functions.
|
||||
// Caldoria/TSA scoring
|
||||
void setScoringSawINN(const bool = true);
|
||||
void setScoringTookShower(const bool = true);
|
||||
void setScoringFixedHair(const bool = true);
|
||||
void setScoringGotKeyCard(const bool = true);
|
||||
void setScoringReadPaper(const bool = true);
|
||||
void setScoringLookThroughTelescope(const bool = true);
|
||||
void setScoringSawCaldoriaKiosk(const bool = true);
|
||||
void setScoringGoToTSA(const bool = true);
|
||||
void setScoringEnterTSA(const bool = true);
|
||||
void setScoringSawBust1(const bool = true);
|
||||
void setScoringSawBust2(const bool = true);
|
||||
void setScoringSawBust3(const bool = true);
|
||||
void setScoringSawBust4(const bool = true);
|
||||
void setScoringSawBust5(const bool = true);
|
||||
void setScoringSawBust6(const bool = true);
|
||||
void setScoringSawTheory(const bool = true);
|
||||
void setScoringSawBackground(const bool = true);
|
||||
void setScoringSawProcedure(const bool = true);
|
||||
void setScoringGotJourneymanKey(const bool = true);
|
||||
void setScoringGotPegasusBiochip(const bool = true);
|
||||
void setScoringGotBiosuit(const bool = true);
|
||||
void setScoringGoToPrehistoric(const bool = true);
|
||||
void setScoringPutLogInReader(const bool = true);
|
||||
void setScoringSawCaldoriaNormal(const bool = true);
|
||||
void setScoringSawCaldoriaAltered(const bool = true);
|
||||
void setScoringSawNoradNormal(const bool = true);
|
||||
void setScoringSawNoradAltered(const bool = true);
|
||||
void setScoringSawMarsNormal(const bool = true);
|
||||
void setScoringSawMarsAltered(const bool = true);
|
||||
void setScoringSawWSCNormal(const bool = true);
|
||||
void setScoringSawWSCAltered(const bool = true);
|
||||
void setScoringWentToReadyRoom2(const bool = true);
|
||||
void setScoringWentAfterSinclair(const bool = true);
|
||||
void setScoringUsedCardBomb(const bool = true);
|
||||
void setScoringShieldedCardBomb(const bool = true);
|
||||
void setScoringStunnedSinclair(const bool = true);
|
||||
void setScoringDisarmedNuke(const bool = true);
|
||||
|
||||
// Prehistoric scoring
|
||||
void setScoringThrewBreaker(const bool = true);
|
||||
void setScoringExtendedBridge(const bool = true);
|
||||
void setScoringGotHistoricalLog(const bool = true);
|
||||
void setScoringFinishedPrehistoric(const bool = true);
|
||||
|
||||
// Mars scoring
|
||||
void setScoringThrownByRobot(const bool = true);
|
||||
void setScoringGotMarsCard(const bool = true);
|
||||
void setScoringSawMarsKiosk(const bool = true);
|
||||
void setScoringSawTransportMap(const bool = true);
|
||||
void setScoringGotCrowBar(const bool = true);
|
||||
void setScoringTurnedOnTransport(const bool = true);
|
||||
void setScoringGotOxygenMask(const bool = true);
|
||||
void setScoringAvoidedRobot(const bool = true);
|
||||
void setScoringActivatedPlatform(const bool = true);
|
||||
void setScoringUsedLiquidNitrogen(const bool = true);
|
||||
void setScoringUsedCrowBar(const bool = true);
|
||||
void setScoringFoundCardBomb(const bool = true);
|
||||
void setScoringDisarmedCardBomb(const bool = true);
|
||||
void setScoringGotCardBomb(const bool = true);
|
||||
void setScoringThreadedMaze(const bool = true);
|
||||
void setScoringThreadedGearRoom(const bool = true);
|
||||
void setScoringEnteredShuttle(const bool = true);
|
||||
void setScoringEnteredLaunchTube(const bool = true);
|
||||
void setScoringStoppedRobotsShuttle(const bool = true);
|
||||
void setScoringGotMarsOpMemChip(const bool = true);
|
||||
void setScoringFinishedMars(const bool = true);
|
||||
|
||||
// Norad scoring
|
||||
void setScoringSawSecurityMonitor(const bool = true);
|
||||
void setScoringFilledOxygenCanister(const bool = true);
|
||||
void setScoringFilledArgonCanister(const bool = true);
|
||||
void setScoringSawUnconsciousOperator(const bool = true);
|
||||
void setScoringWentThroughPressureDoor(const bool = true);
|
||||
void setScoringPreppedSub(const bool = true);
|
||||
void setScoringEnteredSub(const bool = true);
|
||||
void setScoringExitedSub(const bool = true);
|
||||
void setScoringSawRobotAt54North(const bool = true);
|
||||
void setScoringPlayedWithClaw(const bool = true);
|
||||
void setScoringUsedRetinalChip(const bool = true);
|
||||
void setScoringFinishedGlobeGame(const bool = true);
|
||||
void setScoringStoppedNoradRobot(const bool = true);
|
||||
void setScoringGotNoradOpMemChip(const bool = true);
|
||||
void setScoringFinishedNorad(const bool = true);
|
||||
|
||||
// WSC scoring
|
||||
void setScoringRemovedDart(const bool = true);
|
||||
void setScoringAnalyzedDart(const bool = true);
|
||||
void setScoringBuiltAntidote(const bool = true);
|
||||
void setScoringGotSinclairKey(const bool = true);
|
||||
void setScoringGotArgonCanister(const bool = true);
|
||||
void setScoringGotNitrogenCanister(const bool = true);
|
||||
void setScoringPlayedWithMessages(const bool = true);
|
||||
void setScoringSawMorphExperiment(const bool = true);
|
||||
void setScoringEnteredSinclairOffice(const bool = true);
|
||||
void setScoringSawBrochure(const bool = true);
|
||||
void setScoringSawSinclairEntry1(const bool = true);
|
||||
void setScoringSawSinclairEntry2(const bool = true);
|
||||
void setScoringSawSinclairEntry3(const bool = true);
|
||||
void setScoringSawWSCDirectory(const bool = true);
|
||||
void setScoringUsedCrowBarInWSC(const bool = true);
|
||||
void setScoringFinishedPlasmaDodge(const bool = true);
|
||||
void setScoringOpenedCatwalk(const bool = true);
|
||||
void setScoringStoppedWSCRobot(const bool = true);
|
||||
void setScoringGotWSCOpMemChip(const bool = true);
|
||||
void setScoringFinishedWSC(const bool = true);
|
||||
|
||||
// Gandhi scoring
|
||||
void setScoringMarsGandhi(const bool = true);
|
||||
void setScoringNoradGandhi(const bool = true);
|
||||
void setScoringWSCGandhi(const bool = true);
|
||||
|
||||
// Scoring "Get" functions.
|
||||
bool getScoringSawINN();
|
||||
bool getScoringTookShower();
|
||||
bool getScoringFixedHair();
|
||||
bool getScoringGotKeyCard();
|
||||
bool getScoringReadPaper();
|
||||
bool getScoringLookThroughTelescope();
|
||||
bool getScoringSawCaldoriaKiosk();
|
||||
bool getScoringGoToTSA();
|
||||
bool getScoringEnterTSA();
|
||||
bool getScoringSawBust1();
|
||||
bool getScoringSawBust2();
|
||||
bool getScoringSawBust3();
|
||||
bool getScoringSawBust4();
|
||||
bool getScoringSawBust5();
|
||||
bool getScoringSawBust6();
|
||||
bool getScoringSawTheory();
|
||||
bool getScoringSawBackground();
|
||||
bool getScoringSawProcedure();
|
||||
bool getScoringGotJourneymanKey();
|
||||
bool getScoringGotPegasusBiochip();
|
||||
bool getScoringGotBiosuit();
|
||||
bool getScoringGoToPrehistoric();
|
||||
bool getScoringPutLogInReader();
|
||||
bool getScoringSawCaldoriaNormal();
|
||||
bool getScoringSawCaldoriaAltered();
|
||||
bool getScoringSawNoradNormal();
|
||||
bool getScoringSawNoradAltered();
|
||||
bool getScoringSawMarsNormal();
|
||||
bool getScoringSawMarsAltered();
|
||||
bool getScoringSawWSCNormal();
|
||||
bool getScoringSawWSCAltered();
|
||||
bool getScoringWentToReadyRoom2();
|
||||
bool getScoringWentAfterSinclair();
|
||||
bool getScoringUsedCardBomb();
|
||||
bool getScoringShieldedCardBomb();
|
||||
bool getScoringStunnedSinclair();
|
||||
bool getScoringDisarmedNuke();
|
||||
bool getScoringThrewBreaker();
|
||||
bool getScoringExtendedBridge();
|
||||
bool getScoringGotHistoricalLog();
|
||||
bool getScoringFinishedPrehistoric();
|
||||
bool getScoringThrownByRobot();
|
||||
bool getScoringGotMarsCard();
|
||||
bool getScoringSawMarsKiosk();
|
||||
bool getScoringSawTransportMap();
|
||||
bool getScoringGotCrowBar();
|
||||
bool getScoringTurnedOnTransport();
|
||||
bool getScoringGotOxygenMask();
|
||||
bool getScoringAvoidedRobot();
|
||||
bool getScoringActivatedPlatform();
|
||||
bool getScoringUsedLiquidNitrogen();
|
||||
bool getScoringUsedCrowBar();
|
||||
bool getScoringFoundCardBomb();
|
||||
bool getScoringDisarmedCardBomb();
|
||||
bool getScoringGotCardBomb();
|
||||
bool getScoringThreadedMaze();
|
||||
bool getScoringThreadedGearRoom();
|
||||
bool getScoringEnteredShuttle();
|
||||
bool getScoringEnteredLaunchTube();
|
||||
bool getScoringStoppedRobotsShuttle();
|
||||
bool getScoringGotMarsOpMemChip();
|
||||
bool getScoringFinishedMars();
|
||||
bool getScoringSawSecurityMonitor();
|
||||
bool getScoringFilledOxygenCanister();
|
||||
bool getScoringFilledArgonCanister();
|
||||
bool getScoringSawUnconsciousOperator();
|
||||
bool getScoringWentThroughPressureDoor();
|
||||
bool getScoringPreppedSub();
|
||||
bool getScoringEnteredSub();
|
||||
bool getScoringExitedSub();
|
||||
bool getScoringSawRobotAt54North();
|
||||
bool getScoringPlayedWithClaw();
|
||||
bool getScoringUsedRetinalChip();
|
||||
bool getScoringFinishedGlobeGame();
|
||||
bool getScoringStoppedNoradRobot();
|
||||
bool getScoringGotNoradOpMemChip();
|
||||
bool getScoringFinishedNorad();
|
||||
bool getScoringRemovedDart();
|
||||
bool getScoringAnalyzedDart();
|
||||
bool getScoringBuiltAntidote();
|
||||
bool getScoringGotSinclairKey();
|
||||
bool getScoringGotArgonCanister();
|
||||
bool getScoringGotNitrogenCanister();
|
||||
bool getScoringPlayedWithMessages();
|
||||
bool getScoringSawMorphExperiment();
|
||||
bool getScoringEnteredSinclairOffice();
|
||||
bool getScoringSawBrochure();
|
||||
bool getScoringSawSinclairEntry1();
|
||||
bool getScoringSawSinclairEntry2();
|
||||
bool getScoringSawSinclairEntry3();
|
||||
bool getScoringSawWSCDirectory();
|
||||
bool getScoringUsedCrowBarInWSC();
|
||||
bool getScoringFinishedPlasmaDodge();
|
||||
bool getScoringOpenedCatwalk();
|
||||
bool getScoringStoppedWSCRobot();
|
||||
bool getScoringGotWSCOpMemChip();
|
||||
bool getScoringFinishedWSC();
|
||||
bool getScoringMarsGandhi();
|
||||
bool getScoringNoradGandhi();
|
||||
bool getScoringWSCGandhi();
|
||||
|
||||
GameScoreType getCaldoriaTSAScore();
|
||||
GameScoreType getPrehistoricScore();
|
||||
GameScoreType getMarsScore();
|
||||
GameScoreType getNoradScore();
|
||||
GameScoreType getWSCScore();
|
||||
GameScoreType getGandhiScore();
|
||||
GameScoreType getTotalScore();
|
||||
|
||||
void writeCaldoriaState(Common::WriteStream *stream);
|
||||
void readCaldoriaState(Common::ReadStream *stream);
|
||||
void resetCaldoriaState();
|
||||
|
||||
void writeTSAState(Common::WriteStream *stream);
|
||||
void readTSAState(Common::ReadStream *stream);
|
||||
void resetTSAState();
|
||||
|
||||
void writePrehistoricState(Common::WriteStream *stream);
|
||||
void readPrehistoricState(Common::ReadStream *stream);
|
||||
void resetPrehistoricState();
|
||||
|
||||
void writeNoradState(Common::WriteStream *stream);
|
||||
void readNoradState(Common::ReadStream *stream);
|
||||
void resetNoradState();
|
||||
|
||||
void writeMarsState(Common::WriteStream *stream);
|
||||
void readMarsState(Common::ReadStream *stream);
|
||||
void resetMarsState();
|
||||
|
||||
void writeWSCState(Common::WriteStream *stream);
|
||||
void readWSCState(Common::ReadStream *stream);
|
||||
void resetWSCState();
|
||||
|
||||
// Globals.
|
||||
void setWalkthroughMode(bool);
|
||||
bool getWalkthroughMode();
|
||||
void setShieldOn(bool);
|
||||
bool getShieldOn();
|
||||
void setEasterEgg(bool);
|
||||
bool getEasterEgg();
|
||||
void setBeenToWSC(bool value);
|
||||
bool getBeenToWSC();
|
||||
void setBeenToMars(bool value);
|
||||
bool getBeenToMars();
|
||||
void setBeenToNorad(bool value);
|
||||
bool getBeenToNorad();
|
||||
void setWSCFinished(bool);
|
||||
bool getWSCFinished();
|
||||
void setMarsFinished(bool);
|
||||
bool getMarsFinished();
|
||||
void setNoradFinished(bool);
|
||||
bool getNoradFinished();
|
||||
bool allTimeZonesFinished();
|
||||
void setTakenItemID(ItemID, bool);
|
||||
bool isTakenItemID(ItemID);
|
||||
void setTakenItem(Item *, bool);
|
||||
bool isTakenItem(Item *);
|
||||
|
||||
// Caldoria
|
||||
void setCaldoriaFuseTimeLimit(const TimeValue);
|
||||
TimeValue getCaldoriaFuseTimeLimit();
|
||||
void setCaldoriaSeenPullback(bool);
|
||||
bool getCaldoriaSeenPullback();
|
||||
void setCaldoriaMadeOJ(bool);
|
||||
bool getCaldoriaMadeOJ();
|
||||
void setCaldoriaWokenUp(bool);
|
||||
bool getCaldoriaWokenUp();
|
||||
void setCaldoriaDidRecalibration(bool);
|
||||
bool getCaldoriaDidRecalibration();
|
||||
void setCaldoriaSeenSinclairInElevator(bool);
|
||||
bool getCaldoriaSeenSinclairInElevator();
|
||||
void setCaldoriaINNAnnouncing(bool);
|
||||
bool getCaldoriaINNAnnouncing();
|
||||
void setCaldoriaSeenINN(bool);
|
||||
bool getCaldoriaSeenINN();
|
||||
void setCaldoriaSeenMessages(bool);
|
||||
bool getCaldoriaSeenMessages();
|
||||
void setCaldoriaSinclairShot(bool);
|
||||
bool getCaldoriaSinclairShot();
|
||||
void setCaldoriaBombDisarmed(bool);
|
||||
bool getCaldoriaBombDisarmed();
|
||||
void setCaldoriaRoofDoorOpen(bool);
|
||||
bool getCaldoriaRoofDoorOpen();
|
||||
void setCaldoriaDoneHygiene(bool);
|
||||
bool getCaldoriaDoneHygiene();
|
||||
void setCaldoriaSawVoiceAnalysis(bool);
|
||||
bool getCaldoriaSawVoiceAnalysis();
|
||||
void setCaldoriaDoorBombed(bool);
|
||||
bool getCaldoriaDoorBombed();
|
||||
void setCaldoriaGunAimed(bool);
|
||||
bool getCaldoriaGunAimed();
|
||||
|
||||
// TSA
|
||||
void setRipTimerTime(TimeValue);
|
||||
TimeValue getRipTimerTime();
|
||||
void setTSAFuseTimeLimit(TimeValue);
|
||||
TimeValue getTSAFuseTimeLimit();
|
||||
void setT0BMonitorMode(byte);
|
||||
byte getT0BMonitorMode();
|
||||
void setTSAState(byte);
|
||||
byte getTSAState();
|
||||
void setT0BMonitorStart(TimeValue);
|
||||
TimeValue getT0BMonitorStart();
|
||||
void setTSAIDedAtDoor(bool);
|
||||
bool getTSAIDedAtDoor();
|
||||
void setTSA0BZoomedIn(bool);
|
||||
bool getTSA0BZoomedIn();
|
||||
void setTSAFrontDoorUnlockedOutside(bool);
|
||||
bool getTSAFrontDoorUnlockedOutside();
|
||||
void setTSAFrontDoorUnlockedInside(bool);
|
||||
bool getTSAFrontDoorUnlockedInside();
|
||||
void setTSASeenRobotGreeting(bool);
|
||||
bool getTSASeenRobotGreeting();
|
||||
void setTSASeenTheory(bool);
|
||||
bool getTSASeenTheory();
|
||||
void setTSASeenBackground(bool);
|
||||
bool getTSASeenBackground();
|
||||
void setTSASeenProcedure(bool);
|
||||
bool getTSASeenProcedure();
|
||||
void setTSASeenAgent3AtDoor(bool);
|
||||
bool getTSASeenAgent3AtDoor();
|
||||
void setTSACommandCenterLocked(bool);
|
||||
bool getTSACommandCenterLocked();
|
||||
void setTSASeenCaldoriaNormal(bool);
|
||||
bool getTSASeenCaldoriaNormal();
|
||||
void setTSASeenCaldoriaAltered(bool);
|
||||
bool getTSASeenCaldoriaAltered();
|
||||
void setTSASeenNoradNormal(bool);
|
||||
bool getTSASeenNoradNormal();
|
||||
void setTSASeenNoradAltered(bool);
|
||||
bool getTSASeenNoradAltered();
|
||||
void setTSASeenMarsNormal(bool);
|
||||
bool getTSASeenMarsNormal();
|
||||
void setTSASeenMarsAltered(bool);
|
||||
bool getTSASeenMarsAltered();
|
||||
void setTSASeenWSCNormal(bool);
|
||||
bool getTSASeenWSCNormal();
|
||||
void setTSASeenWSCAltered(bool);
|
||||
bool getTSASeenWSCAltered();
|
||||
void setTSABiosuitOn(bool);
|
||||
bool getTSABiosuitOn();
|
||||
|
||||
// Prehistoric
|
||||
void setPrehistoricTriedToExtendBridge(bool);
|
||||
bool getPrehistoricTriedToExtendBridge();
|
||||
void setPrehistoricSeenTimeStream(bool);
|
||||
bool getPrehistoricSeenTimeStream();
|
||||
void setPrehistoricSeenFlyer1(bool);
|
||||
bool getPrehistoricSeenFlyer1();
|
||||
void setPrehistoricSeenFlyer2(bool);
|
||||
bool getPrehistoricSeenFlyer2();
|
||||
void setPrehistoricSeenBridgeZoom(bool);
|
||||
bool getPrehistoricSeenBridgeZoom();
|
||||
void setPrehistoricBreakerThrown(bool);
|
||||
bool getPrehistoricBreakerThrown();
|
||||
|
||||
// Norad
|
||||
void setNoradSeenTimeStream(bool);
|
||||
bool getNoradSeenTimeStream();
|
||||
void setNoradGassed(bool);
|
||||
bool getNoradGassed();
|
||||
void setNoradFillingStationOn(bool);
|
||||
bool getNoradFillingStationOn();
|
||||
void setNoradN22MessagePlayed(bool);
|
||||
bool getNoradN22MessagePlayed();
|
||||
void setNoradPlayedGlobeGame(bool);
|
||||
bool getNoradPlayedGlobeGame();
|
||||
void setNoradBeatRobotWithClaw(bool);
|
||||
bool getNoradBeatRobotWithClaw();
|
||||
void setNoradBeatRobotWithDoor(bool);
|
||||
bool getNoradBeatRobotWithDoor();
|
||||
void setNoradRetScanGood(bool);
|
||||
bool getNoradRetScanGood();
|
||||
void setNoradWaitingForLaser(bool);
|
||||
bool getNoradWaitingForLaser();
|
||||
void setNoradSubRoomPressure(uint16);
|
||||
uint16 getNoradSubRoomPressure();
|
||||
void setNoradSubPrepState(NoradSubPrepState);
|
||||
NoradSubPrepState getNoradSubPrepState();
|
||||
void setNoradArrivedFromSub(bool);
|
||||
bool getNoradArrivedFromSub();
|
||||
|
||||
// Mars
|
||||
void setMarsSeenTimeStream(bool);
|
||||
bool getMarsSeenTimeStream();
|
||||
void setMarsHeardUpperPodMessage(bool);
|
||||
bool getMarsHeardUpperPodMessage();
|
||||
void setMarsRobotThrownPlayer(bool);
|
||||
bool getMarsRobotThrownPlayer();
|
||||
void setMarsHeardCheckInMessage(bool);
|
||||
bool getMarsHeardCheckInMessage();
|
||||
void setMarsPodAtUpperPlatform(bool);
|
||||
bool getMarsPodAtUpperPlatform();
|
||||
void setMarsSeenThermalScan(bool);
|
||||
bool getMarsSeenThermalScan();
|
||||
void setMarsArrivedBelow(bool);
|
||||
bool getMarsArrivedBelow();
|
||||
void setMarsSeenRobotAtReactor(bool);
|
||||
bool getMarsSeenRobotAtReactor();
|
||||
void setMarsAvoidedReactorRobot(bool);
|
||||
bool getMarsAvoidedReactorRobot();
|
||||
void setMarsInAirlock(bool);
|
||||
bool getMarsInAirlock();
|
||||
void setMarsAirlockOpen(bool);
|
||||
bool getMarsAirlockOpen();
|
||||
void setMarsMaskOnFiller(bool);
|
||||
bool getMarsMaskOnFiller();
|
||||
void setMarsLockFrozen(bool);
|
||||
bool getMarsLockFrozen();
|
||||
void setMarsLockBroken(bool);
|
||||
bool getMarsLockBroken();
|
||||
void setMarsMazeDoorPair1(bool);
|
||||
bool getMarsMazeDoorPair1();
|
||||
void setMarsMazeDoorPair2(bool);
|
||||
bool getMarsMazeDoorPair2();
|
||||
void setMarsMazeDoorPair3(bool);
|
||||
bool getMarsMazeDoorPair3();
|
||||
void setMarsSawRobotLeave(bool);
|
||||
bool getMarsSawRobotLeave();
|
||||
void setMarsSecurityDown(bool);
|
||||
bool getMarsSecurityDown();
|
||||
void setMarsFinishedCanyonChase(bool);
|
||||
bool getMarsFinishedCanyonChase();
|
||||
void setMarsThreadedMaze(bool);
|
||||
bool getMarsThreadedMaze();
|
||||
void setMarsHitRobotWithCannon(bool);
|
||||
bool getMarsHitRobotWithCannon();
|
||||
void setMarsReadyForShuttleTransport(bool);
|
||||
bool getMarsReadyForShuttleTransport();
|
||||
|
||||
// WSC
|
||||
void setWSCSeenTimeStream(bool);
|
||||
bool getWSCSeenTimeStream();
|
||||
void setWSCPoisoned(bool);
|
||||
bool getWSCPoisoned();
|
||||
void setWSCAnsweredAboutDart(bool);
|
||||
bool getWSCAnsweredAboutDart();
|
||||
void setWSCRemovedDart(bool);
|
||||
bool getWSCRemovedDart();
|
||||
void setWSCAnalyzerOn(bool);
|
||||
bool getWSCAnalyzerOn();
|
||||
void setWSCDartInAnalyzer(bool);
|
||||
bool getWSCDartInAnalyzer();
|
||||
void setWSCAnalyzedDart(bool);
|
||||
bool getWSCAnalyzedDart();
|
||||
void setWSCSawMorph(bool);
|
||||
bool getWSCSawMorph();
|
||||
void setWSCDesignedAntidote(bool);
|
||||
bool getWSCDesignedAntidote();
|
||||
void setWSCPickedUpAntidote(bool);
|
||||
bool getWSCPickedUpAntidote();
|
||||
void setWSCOfficeMessagesOpen(bool);
|
||||
bool getWSCOfficeMessagesOpen();
|
||||
void setWSCSeenNerd(bool);
|
||||
bool getWSCSeenNerd();
|
||||
void setWSCHeardPage1(bool);
|
||||
bool getWSCHeardPage1();
|
||||
void setWSCHeardPage2(bool);
|
||||
bool getWSCHeardPage2();
|
||||
void setWSCHeardCheckIn(bool);
|
||||
bool getWSCHeardCheckIn();
|
||||
void setWSCDidPlasmaDodge(bool);
|
||||
bool getWSCDidPlasmaDodge();
|
||||
void setWSCSeenSinclairLecture(bool);
|
||||
bool getWSCSeenSinclairLecture();
|
||||
void setWSCBeenAtWSC93(bool);
|
||||
bool getWSCBeenAtWSC93();
|
||||
void setWSCCatwalkDark(bool);
|
||||
bool getWSCCatwalkDark();
|
||||
void setWSCRobotDead(bool);
|
||||
bool getWSCRobotDead();
|
||||
void setWSCRobotGone(bool);
|
||||
bool getWSCRobotGone();
|
||||
|
||||
protected:
|
||||
friend class Common::Singleton<SingletonBaseType>;
|
||||
|
||||
private:
|
||||
// Base
|
||||
NeighborhoodID _currentNeighborhood;
|
||||
RoomID _currentRoom;
|
||||
DirectionConstant _currentDirection;
|
||||
NeighborhoodID _nexNeighborhoodID;
|
||||
RoomID _nextRoomID;
|
||||
DirectionConstant _nextDirection;
|
||||
NeighborhoodID _lastNeighborhood;
|
||||
RoomID _lastRoom;
|
||||
DirectionConstant _lastDirection;
|
||||
RoomID _openDoorRoom;
|
||||
DirectionConstant _openDoorDirection;
|
||||
|
||||
// Pegasus Prime
|
||||
FlagsArray<byte, kNumGlobalFlags> _globalFlags;
|
||||
FlagsArray<byte, kNumScoringFlags> _scoringFlags;
|
||||
FlagsArray<uint32, kNumItems> _itemTakenFlags;
|
||||
|
||||
FlagsArray<byte, kNumCaldoriaFlags> _caldoriaFlags;
|
||||
TimeValue _caldoriaFuseTimeLimit;
|
||||
|
||||
TimeValue _TSARipTimerTime;
|
||||
TimeValue _TSAFuseTimeLimit;
|
||||
byte _TSAState;
|
||||
byte _T0BMonitorMode;
|
||||
TimeValue _T0BMonitorStart;
|
||||
FlagsArray<byte, kNumTSAFlags> _TSAFlags;
|
||||
|
||||
FlagsArray<byte, kNumPrehistoricFlags> _prehistoricFlags;
|
||||
|
||||
FlagsArray<byte, kNumNoradFlags> _noradFlags;
|
||||
uint16 _noradSubRoomPressure;
|
||||
NoradSubPrepState _noradSubPrepState;
|
||||
|
||||
FlagsArray<byte, kNumMarsFlags> _marsFlags;
|
||||
|
||||
FlagsArray<byte, kNumWSCFlags> _WSCFlags;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#define GameState (::Pegasus::GameStateManager::instance())
|
||||
|
||||
#endif
|
||||
287
engines/pegasus/graphics.cpp
Normal file
287
engines/pegasus/graphics.cpp
Normal file
@@ -0,0 +1,287 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/events.h"
|
||||
#include "common/file.h"
|
||||
#include "common/textconsole.h"
|
||||
#include "engines/util.h"
|
||||
|
||||
#include "pegasus/elements.h"
|
||||
#include "pegasus/graphics.h"
|
||||
#include "pegasus/transition.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
GraphicsManager::GraphicsManager(PegasusEngine *vm) : _vm(vm) {
|
||||
initGraphics(640, 480, nullptr);
|
||||
|
||||
if (_vm->_system->getScreenFormat().bytesPerPixel == 1)
|
||||
error("No true color mode available");
|
||||
|
||||
_backLayer = kMinAvailableOrder;
|
||||
_frontLayer = kMaxAvailableOrder;
|
||||
_firstDisplayElement = _lastDisplayElement = nullptr;
|
||||
_workArea.create(640, 480, _vm->_system->getScreenFormat());
|
||||
_curSurface = &_workArea;
|
||||
_erase = false;
|
||||
_updatesEnabled = true;
|
||||
_screenFader = new ScreenFader();
|
||||
}
|
||||
|
||||
GraphicsManager::~GraphicsManager() {
|
||||
_workArea.free();
|
||||
delete _screenFader;
|
||||
}
|
||||
|
||||
void GraphicsManager::invalRect(const Common::Rect &rect) {
|
||||
// We're using a simpler algorithm for dirty rect handling than the original
|
||||
// The original was way too overcomplicated for what we need here now.
|
||||
|
||||
if (_dirtyRect.width() == 0 || _dirtyRect.height() == 0) {
|
||||
// We have no dirty rect, so this is now our dirty rect
|
||||
_dirtyRect = rect;
|
||||
} else {
|
||||
// Expand our dirty rect to include rect
|
||||
_dirtyRect.extend(rect);
|
||||
}
|
||||
|
||||
// Sanity check: clip our rect to the screen
|
||||
_dirtyRect.right = MIN<int>(640, _dirtyRect.right);
|
||||
_dirtyRect.bottom = MIN<int>(480, _dirtyRect.bottom);
|
||||
}
|
||||
|
||||
void GraphicsManager::addDisplayElement(DisplayElement *newElement) {
|
||||
newElement->_elementOrder = CLIP<int>(newElement->_elementOrder, kMinAvailableOrder, kMaxAvailableOrder);
|
||||
|
||||
if (_firstDisplayElement) {
|
||||
DisplayElement *runner = _firstDisplayElement;
|
||||
DisplayElement *lastRunner = nullptr;
|
||||
|
||||
// Search for first element whose display order is greater than
|
||||
// the new element's and add the new element just before it.
|
||||
while (runner) {
|
||||
if (newElement->_elementOrder < runner->_elementOrder) {
|
||||
if (lastRunner) {
|
||||
lastRunner->_nextElement = newElement;
|
||||
newElement->_nextElement = runner;
|
||||
} else {
|
||||
newElement->_nextElement = _firstDisplayElement;
|
||||
_firstDisplayElement = newElement;
|
||||
}
|
||||
break;
|
||||
}
|
||||
lastRunner = runner;
|
||||
runner = runner->_nextElement;
|
||||
}
|
||||
|
||||
// If got here and runner == NULL, we ran through the whole list without
|
||||
// inserting, so add at the end.
|
||||
if (!runner) {
|
||||
_lastDisplayElement->_nextElement = newElement;
|
||||
_lastDisplayElement = newElement;
|
||||
}
|
||||
} else {
|
||||
_firstDisplayElement = newElement;
|
||||
_lastDisplayElement = newElement;
|
||||
}
|
||||
|
||||
newElement->_elementIsDisplaying = true;
|
||||
}
|
||||
|
||||
void GraphicsManager::removeDisplayElement(DisplayElement *oldElement) {
|
||||
if (!_firstDisplayElement)
|
||||
return;
|
||||
|
||||
if (oldElement == _firstDisplayElement) {
|
||||
if (oldElement == _lastDisplayElement) {
|
||||
_firstDisplayElement = nullptr;
|
||||
_lastDisplayElement = nullptr;
|
||||
} else {
|
||||
_firstDisplayElement = oldElement->_nextElement;
|
||||
}
|
||||
|
||||
invalRect(oldElement->_bounds);
|
||||
} else {
|
||||
// Scan list for element.
|
||||
// If we get here, we know that the list has at least one item, and it
|
||||
// is not the first item, so we can skip it.
|
||||
DisplayElement *runner = _firstDisplayElement->_nextElement;
|
||||
DisplayElement *lastRunner = _firstDisplayElement;
|
||||
|
||||
while (runner) {
|
||||
if (runner == oldElement) {
|
||||
lastRunner->_nextElement = runner->_nextElement;
|
||||
|
||||
if (oldElement == _lastDisplayElement)
|
||||
_lastDisplayElement = lastRunner;
|
||||
|
||||
invalRect(oldElement->_bounds);
|
||||
break;
|
||||
}
|
||||
|
||||
lastRunner = runner;
|
||||
runner = runner->_nextElement;
|
||||
}
|
||||
}
|
||||
|
||||
oldElement->_nextElement = nullptr;
|
||||
oldElement->_elementIsDisplaying = false;
|
||||
}
|
||||
|
||||
void GraphicsManager::updateDisplay() {
|
||||
if (!_dirtyRect.isEmpty()) {
|
||||
// Fill the dirty area with black if erase mode is enabled
|
||||
if (_erase)
|
||||
_workArea.fillRect(_dirtyRect, _workArea.format.RGBToColor(0, 0, 0));
|
||||
|
||||
for (DisplayElement *runner = _firstDisplayElement; runner != nullptr; runner = runner->_nextElement) {
|
||||
Common::Rect bounds;
|
||||
runner->getBounds(bounds);
|
||||
|
||||
// TODO: Better logic; it does a bit more work than it probably needs to
|
||||
// but it should work fine for now.
|
||||
if (bounds.intersects(_dirtyRect) && runner->validToDraw(_backLayer, _frontLayer)) {
|
||||
runner->draw(bounds);
|
||||
}
|
||||
}
|
||||
|
||||
// Copy only the dirty rect to the screen
|
||||
g_system->copyRectToScreen((byte *)_workArea.getBasePtr(_dirtyRect.left, _dirtyRect.top), _workArea.pitch, _dirtyRect.left, _dirtyRect.top, _dirtyRect.width(), _dirtyRect.height());
|
||||
|
||||
// Clear the dirty rect
|
||||
_dirtyRect = Common::Rect();
|
||||
}
|
||||
|
||||
if (_updatesEnabled)
|
||||
g_system->updateScreen();
|
||||
}
|
||||
|
||||
DisplayElement *GraphicsManager::findDisplayElement(const DisplayElementID id) {
|
||||
DisplayElement *runner = _firstDisplayElement;
|
||||
|
||||
while (runner) {
|
||||
if (runner->getObjectID() == id)
|
||||
return runner;
|
||||
runner = runner->_nextElement;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void GraphicsManager::doFadeOutSync(const TimeValue time, const TimeScale scale, bool isBlack) {
|
||||
_updatesEnabled = false;
|
||||
_screenFader->doFadeOutSync(time, scale, isBlack);
|
||||
}
|
||||
|
||||
void GraphicsManager::doFadeInSync(const TimeValue time, const TimeScale scale, bool isBlack) {
|
||||
_screenFader->doFadeInSync(time, scale, isBlack);
|
||||
_updatesEnabled = true;
|
||||
}
|
||||
|
||||
void GraphicsManager::newShakePoint(int32 index1, int32 index2, int32 maxRadius) {
|
||||
int32 index3 = (index1 + index2) >> 1;
|
||||
|
||||
if (maxRadius == 0) {
|
||||
_shakeOffsets[index3].x = ((_shakeOffsets[index1].x + _shakeOffsets[index2].x) >> 1);
|
||||
_shakeOffsets[index3].y = ((_shakeOffsets[index1].y + _shakeOffsets[index2].y) >> 1);
|
||||
} else {
|
||||
double angle = (int32)(_vm->getRandomNumber(360 - 1) * 3.1415926535 / 180);
|
||||
int32 radius = maxRadius;
|
||||
_shakeOffsets[index3].x = (int32)(((_shakeOffsets[index1].x + _shakeOffsets[index2].x) >> 1) +
|
||||
cos(angle) / 2 * radius);
|
||||
_shakeOffsets[index3].y = (int32)(((_shakeOffsets[index1].y + _shakeOffsets[index2].y) >> 1) +
|
||||
sin(angle) * radius);
|
||||
}
|
||||
|
||||
if (index1 < index3 - 1)
|
||||
newShakePoint(index1, index3, maxRadius * 2 / 3);
|
||||
|
||||
if (index3 < index2 - 1)
|
||||
newShakePoint(index3, index2, maxRadius * 2 / 3);
|
||||
}
|
||||
|
||||
void GraphicsManager::shakeTheWorld(TimeValue duration, TimeScale scale) {
|
||||
if (duration == 0 || scale == 0)
|
||||
return;
|
||||
|
||||
_shakeOffsets[0].x = 0;
|
||||
_shakeOffsets[0].y = 0;
|
||||
_shakeOffsets[(kMaxShakeOffsets - 1) / 4].x = 0;
|
||||
_shakeOffsets[(kMaxShakeOffsets - 1) / 4].y = 0;
|
||||
_shakeOffsets[(kMaxShakeOffsets - 1) / 2].x = 0;
|
||||
_shakeOffsets[(kMaxShakeOffsets - 1) / 2].y = 0;
|
||||
_shakeOffsets[(kMaxShakeOffsets - 1) * 3 / 4].x = 0;
|
||||
_shakeOffsets[(kMaxShakeOffsets - 1) * 3 / 4].y = 0;
|
||||
_shakeOffsets[kMaxShakeOffsets - 1].x = 0;
|
||||
_shakeOffsets[kMaxShakeOffsets - 1].y = 0;
|
||||
|
||||
newShakePoint(0, (kMaxShakeOffsets - 1) / 4, 8);
|
||||
newShakePoint((kMaxShakeOffsets - 1) / 4, (kMaxShakeOffsets - 1) / 2, 6);
|
||||
newShakePoint((kMaxShakeOffsets - 1) / 2, (kMaxShakeOffsets - 1) * 3 / 4, 4);
|
||||
newShakePoint((kMaxShakeOffsets - 1) * 3 / 4, kMaxShakeOffsets - 1, 3);
|
||||
|
||||
Common::Point lastOffset(0, 0);
|
||||
|
||||
// Convert to millis
|
||||
duration = duration * 1000 / scale;
|
||||
|
||||
uint32 startTime = g_system->getMillis();
|
||||
|
||||
while (g_system->getMillis() < startTime + duration) {
|
||||
Common::Point thisOffset = _shakeOffsets[(g_system->getMillis() - startTime) * (kMaxShakeOffsets - 1) / duration];
|
||||
if (thisOffset != lastOffset) {
|
||||
g_system->setShakePos(thisOffset.x, thisOffset.y);
|
||||
g_system->updateScreen();
|
||||
|
||||
lastOffset = thisOffset;
|
||||
}
|
||||
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
|
||||
if (lastOffset.x != 0 || lastOffset.y != 0) {
|
||||
g_system->setShakePos(0, 0);
|
||||
g_system->updateScreen();
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsManager::enableErase() {
|
||||
_erase = true;
|
||||
}
|
||||
|
||||
void GraphicsManager::disableErase() {
|
||||
_erase = false;
|
||||
}
|
||||
|
||||
void GraphicsManager::enableUpdates() {
|
||||
_updatesEnabled = true;
|
||||
_screenFader->setFaderValue(100);
|
||||
}
|
||||
|
||||
void GraphicsManager::disableUpdates() {
|
||||
_updatesEnabled = false;
|
||||
_screenFader->setFaderValue(0);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
90
engines/pegasus/graphics.h
Normal file
90
engines/pegasus/graphics.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_GRAPHICS_H
|
||||
#define PEGASUS_GRAPHICS_H
|
||||
|
||||
#include "common/rect.h"
|
||||
#include "common/str.h"
|
||||
#include "common/system.h"
|
||||
#include "graphics/surface.h"
|
||||
|
||||
#include "pegasus/constants.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/util.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class Cursor;
|
||||
class DisplayElement;
|
||||
class PegasusEngine;
|
||||
class ScreenFader;
|
||||
|
||||
class GraphicsManager {
|
||||
friend class Cursor;
|
||||
public:
|
||||
GraphicsManager(PegasusEngine *vm);
|
||||
~GraphicsManager();
|
||||
|
||||
void addDisplayElement(DisplayElement *element);
|
||||
void removeDisplayElement(DisplayElement *element);
|
||||
void invalRect(const Common::Rect &rect);
|
||||
DisplayOrder getBackOfActiveLayer() const { return _backLayer; }
|
||||
DisplayOrder getFrontOfActiveLayer() const { return _frontLayer; }
|
||||
void updateDisplay();
|
||||
Graphics::Surface *getCurSurface() { return _curSurface; }
|
||||
void setCurSurface(Graphics::Surface *surface) { _curSurface = surface; }
|
||||
Graphics::Surface *getWorkArea() { return &_workArea; }
|
||||
DisplayElement *findDisplayElement(const DisplayElementID id);
|
||||
void shakeTheWorld(TimeValue time, TimeScale scale);
|
||||
void enableErase();
|
||||
void disableErase();
|
||||
void enableUpdates();
|
||||
void disableUpdates();
|
||||
|
||||
// These default to black
|
||||
void doFadeOutSync(const TimeValue = kOneSecondPerThirtyTicks, const TimeScale = kThirtyTicksPerSecond, bool isBlack = true);
|
||||
void doFadeInSync(const TimeValue = kOneSecondPerThirtyTicks, const TimeScale = kThirtyTicksPerSecond, bool isBlack = true);
|
||||
|
||||
private:
|
||||
PegasusEngine *_vm;
|
||||
|
||||
bool _erase;
|
||||
Common::Rect _dirtyRect;
|
||||
DisplayOrder _backLayer, _frontLayer;
|
||||
DisplayElement *_firstDisplayElement, *_lastDisplayElement;
|
||||
Graphics::Surface _workArea, *_curSurface;
|
||||
|
||||
// Shake Shake Shake!
|
||||
static const int kMaxShakeOffsets = 17;
|
||||
Common::Point _shakeOffsets[kMaxShakeOffsets];
|
||||
void newShakePoint(int32 index1, int32 index2, int32 maxRadius);
|
||||
|
||||
bool _updatesEnabled;
|
||||
ScreenFader *_screenFader;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
324
engines/pegasus/hotspot.cpp
Normal file
324
engines/pegasus/hotspot.cpp
Normal file
@@ -0,0 +1,324 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/stream.h"
|
||||
|
||||
#include "pegasus/hotspot.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
Region::Region(Common::ReadStream *stream) {
|
||||
uint16 length = stream->readUint16BE();
|
||||
|
||||
assert(length >= 10);
|
||||
|
||||
_bounds.top = stream->readUint16BE();
|
||||
_bounds.left = stream->readUint16BE();
|
||||
_bounds.bottom = stream->readUint16BE();
|
||||
_bounds.right = stream->readUint16BE();
|
||||
|
||||
_bounds.debugPrint(0, "Bounds:");
|
||||
|
||||
if (length == 10)
|
||||
return;
|
||||
|
||||
length -= 10;
|
||||
|
||||
while (length > 0) {
|
||||
Vector v;
|
||||
v.y = stream->readUint16BE();
|
||||
length -= 2;
|
||||
|
||||
if (v.y == 0x7fff)
|
||||
break;
|
||||
|
||||
debug(0, "y: %d", v.y);
|
||||
|
||||
// Normalize y to _bounds
|
||||
v.y -= _bounds.top;
|
||||
|
||||
while (length > 0) {
|
||||
Run run;
|
||||
run.start = stream->readUint16BE();
|
||||
length -= 2;
|
||||
|
||||
if (run.start == 0x7fff)
|
||||
break;
|
||||
|
||||
run.end = stream->readUint16BE();
|
||||
length -= 2;
|
||||
|
||||
debug(0, "\t[%d, %d)", run.start, run.end);
|
||||
|
||||
// Normalize to _bounds
|
||||
run.start -= _bounds.left;
|
||||
run.end -= _bounds.left;
|
||||
|
||||
v.push_back(run);
|
||||
}
|
||||
|
||||
_vectors.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
Region::Region(const Common::Rect &rect) {
|
||||
_bounds = rect;
|
||||
}
|
||||
|
||||
bool Region::pointInRegion(const Common::Point &point) const {
|
||||
if (!_bounds.contains(point))
|
||||
return false;
|
||||
|
||||
bool pixelActive = false;
|
||||
|
||||
// Normalize the points to _bounds
|
||||
uint16 x = point.x - _bounds.left;
|
||||
uint16 y = point.y - _bounds.top;
|
||||
|
||||
for (Common::List<Vector>::const_iterator v = _vectors.begin(); v != _vectors.end(); v++) {
|
||||
if (v->y > y)
|
||||
return pixelActive;
|
||||
|
||||
for (Vector::const_iterator run = v->begin(); run != v->end(); run++) {
|
||||
if (x >= run->start && x < run->end) {
|
||||
pixelActive = !pixelActive;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the case if the region is just a rect
|
||||
return true;
|
||||
}
|
||||
|
||||
void Region::moveTo(CoordType h, CoordType v) {
|
||||
_bounds.moveTo(h, v);
|
||||
}
|
||||
|
||||
void Region::moveTo(const Common::Point &point) {
|
||||
_bounds.moveTo(point);
|
||||
}
|
||||
|
||||
void Region::translate(CoordType h, CoordType v) {
|
||||
_bounds.translate(h, v);
|
||||
}
|
||||
|
||||
void Region::translate(const Common::Point &point) {
|
||||
_bounds.translate(point.x, point.y);
|
||||
}
|
||||
|
||||
void Region::getCenter(CoordType &h, CoordType &v) const {
|
||||
h = (_bounds.left + _bounds.right) / 2;
|
||||
v = (_bounds.top + _bounds.bottom) / 2;
|
||||
}
|
||||
|
||||
void Region::getCenter(Common::Point &point) const {
|
||||
getCenter(point.x, point.y);
|
||||
}
|
||||
|
||||
Hotspot::Hotspot(const HotSpotID id) : IDObject(id) {
|
||||
_spotFlags = kNoHotSpotFlags;
|
||||
_spotActive = false;
|
||||
}
|
||||
|
||||
Hotspot::~Hotspot() {
|
||||
}
|
||||
|
||||
void Hotspot::setArea(const Common::Rect &area) {
|
||||
_spotArea = Region(area);
|
||||
}
|
||||
|
||||
void Hotspot::setArea(const CoordType left, const CoordType top, const CoordType right, const CoordType bottom) {
|
||||
_spotArea = Region(Common::Rect(left, top, right, bottom));
|
||||
}
|
||||
|
||||
void Hotspot::getBoundingBox(Common::Rect &r) const {
|
||||
r = _spotArea.getBoundingBox();
|
||||
}
|
||||
|
||||
void Hotspot::getCenter(Common::Point &pt) const {
|
||||
_spotArea.getCenter(pt);
|
||||
}
|
||||
|
||||
void Hotspot::getCenter(CoordType &h, CoordType &v) const {
|
||||
_spotArea.getCenter(h, v);
|
||||
}
|
||||
|
||||
void Hotspot::setActive() {
|
||||
_spotActive = true;
|
||||
}
|
||||
|
||||
void Hotspot::setInactive() {
|
||||
_spotActive = false;
|
||||
}
|
||||
|
||||
void Hotspot::setHotspotFlags(const HotSpotFlags flags) {
|
||||
_spotFlags = flags;
|
||||
}
|
||||
|
||||
void Hotspot::setMaskedHotspotFlags(const HotSpotFlags flags, const HotSpotFlags mask) {
|
||||
_spotFlags = (_spotFlags & ~mask) | flags;
|
||||
}
|
||||
|
||||
bool Hotspot::isSpotActive() const {
|
||||
return _spotActive;
|
||||
}
|
||||
|
||||
void Hotspot::moveSpotTo(const CoordType h, const CoordType v) {
|
||||
_spotArea.moveTo(h, v);
|
||||
}
|
||||
|
||||
void Hotspot::moveSpotTo(const Common::Point &pt) {
|
||||
_spotArea.moveTo(pt);
|
||||
}
|
||||
|
||||
void Hotspot::moveSpot(const CoordType h, const CoordType v) {
|
||||
_spotArea.translate(h, v);
|
||||
}
|
||||
|
||||
void Hotspot::moveSpot(const Common::Point &pt) {
|
||||
_spotArea.translate(pt.x, pt.y);
|
||||
}
|
||||
|
||||
bool Hotspot::pointInSpot(const Common::Point &where) const {
|
||||
return _spotActive && _spotArea.pointInRegion(where);
|
||||
}
|
||||
|
||||
HotSpotFlags Hotspot::getHotspotFlags() const {
|
||||
return _spotFlags;
|
||||
}
|
||||
|
||||
HotspotList::HotspotList() {
|
||||
}
|
||||
|
||||
HotspotList::~HotspotList() {
|
||||
// TODO: Should this call deleteHotspots()?
|
||||
}
|
||||
|
||||
void HotspotList::deleteHotspots() {
|
||||
for (HotspotIterator it = begin(); it != end(); it++)
|
||||
delete *it;
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
Hotspot *HotspotList::findHotspot(const Common::Point &where) {
|
||||
for (HotspotIterator it = begin(); it != end(); it++)
|
||||
if ((*it)->pointInSpot(where))
|
||||
return *it;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HotSpotID HotspotList::findHotspotID(const Common::Point &where) {
|
||||
Hotspot *hotspot = findHotspot(where);
|
||||
return hotspot ? hotspot->getObjectID() : kNoHotSpotID;
|
||||
}
|
||||
|
||||
Hotspot *HotspotList::findHotspotByID(const HotSpotID id) {
|
||||
for (HotspotIterator it = begin(); it != end(); it++)
|
||||
if ((*it)->getObjectID() == id)
|
||||
return *it;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Hotspot *HotspotList::findHotspotByMask(const HotSpotFlags flags) {
|
||||
for (HotspotIterator it = begin(); it != end(); it++)
|
||||
if (((*it)->getHotspotFlags() & flags) == flags)
|
||||
return *it;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void HotspotList::activateMaskedHotspots(const HotSpotFlags flags) {
|
||||
for (HotspotIterator it = begin(); it != end(); it++)
|
||||
if (flags == kNoHotSpotFlags || ((*it)->getHotspotFlags() & flags) != 0)
|
||||
(*it)->setActive();
|
||||
}
|
||||
|
||||
void HotspotList::deactivateAllHotspots() {
|
||||
for (HotspotIterator it = begin(); it != end(); it++)
|
||||
(*it)->setInactive();
|
||||
}
|
||||
|
||||
void HotspotList::deactivateMaskedHotspots(const HotSpotFlags flags) {
|
||||
for (HotspotIterator it = begin(); it != end(); it++)
|
||||
if (((*it)->getHotspotFlags() & flags) != 0)
|
||||
(*it)->setInactive();
|
||||
}
|
||||
|
||||
void HotspotList::activateOneHotspot(const HotSpotID id) {
|
||||
for (HotspotIterator it = begin(); it != end(); it++) {
|
||||
if ((*it)->getObjectID() == id) {
|
||||
(*it)->setActive();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HotspotList::deactivateOneHotspot(const HotSpotID id) {
|
||||
for (HotspotIterator it = begin(); it != end(); it++) {
|
||||
if ((*it)->getObjectID() == id) {
|
||||
(*it)->setInactive();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HotspotList::removeOneHotspot(const HotSpotID id) {
|
||||
for (HotspotIterator it = begin(); it != end(); it++) {
|
||||
if ((*it)->getObjectID() == id) {
|
||||
erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HotspotList::removeMaskedHotspots(const HotSpotFlags flags) {
|
||||
if (flags != kNoHotSpotFlags) {
|
||||
for (HotspotIterator it = begin(); it != end(); ) {
|
||||
if (((*it)->getHotspotFlags() & flags) != 0)
|
||||
it = erase(it);
|
||||
else
|
||||
it++;
|
||||
}
|
||||
} else {
|
||||
clear();
|
||||
}
|
||||
}
|
||||
|
||||
void HotspotList::setHotspotRect(const HotSpotID id, const Common::Rect &r) {
|
||||
Hotspot *hotspot = findHotspotByID(id);
|
||||
if (hotspot)
|
||||
hotspot->setArea(r);
|
||||
}
|
||||
|
||||
void HotspotList::getHotspotRect(const HotSpotID id, Common::Rect &r) {
|
||||
Hotspot *hotspot = findHotspotByID(id);
|
||||
if (hotspot)
|
||||
hotspot->getBoundingBox(r);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
151
engines/pegasus/hotspot.h
Normal file
151
engines/pegasus/hotspot.h
Normal file
@@ -0,0 +1,151 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_HOTSPOT_H
|
||||
#define PEGASUS_HOTSPOT_H
|
||||
|
||||
#include "common/list.h"
|
||||
#include "common/rect.h"
|
||||
|
||||
#include "pegasus/constants.h"
|
||||
#include "pegasus/types.h"
|
||||
#include "pegasus/util.h"
|
||||
|
||||
/*
|
||||
|
||||
Hot spots combine a pixel area, an ID value and an active flag.
|
||||
|
||||
A point is considered in a hot spot if the point is in the hot spot's pixel area and
|
||||
the active flag is set.
|
||||
|
||||
In addition, hot spots have a 32 bit word of bit flags for filtering use.
|
||||
|
||||
*/
|
||||
|
||||
namespace Common {
|
||||
class ReadStream;
|
||||
}
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
// Our implementation of QuickDraw regions
|
||||
class Region {
|
||||
public:
|
||||
Region() {}
|
||||
Region(Common::ReadStream *stream);
|
||||
Region(const Common::Rect &rect);
|
||||
|
||||
Common::Rect getBoundingBox() const { return _bounds; }
|
||||
|
||||
bool pointInRegion(const Common::Point &point) const;
|
||||
|
||||
void moveTo(CoordType h, CoordType v);
|
||||
void moveTo(const Common::Point &point);
|
||||
void translate(CoordType h, CoordType v);
|
||||
void translate(const Common::Point &point);
|
||||
void getCenter(CoordType &h, CoordType &v) const;
|
||||
void getCenter(Common::Point &point) const;
|
||||
|
||||
private:
|
||||
Common::Rect _bounds;
|
||||
|
||||
struct Run {
|
||||
uint16 start, end;
|
||||
};
|
||||
|
||||
class Vector : public Common::List<Run> {
|
||||
public:
|
||||
uint16 y;
|
||||
};
|
||||
|
||||
Common::List<Vector> _vectors;
|
||||
};
|
||||
|
||||
class Hotspot : public IDObject {
|
||||
public:
|
||||
Hotspot(const HotSpotID);
|
||||
virtual ~Hotspot();
|
||||
|
||||
void setArea(const Region ®ion) { _spotArea = region; }
|
||||
void setArea(const Common::Rect &);
|
||||
void setArea(const CoordType, const CoordType, const CoordType, const CoordType);
|
||||
void getBoundingBox(Common::Rect &) const;
|
||||
void getArea(Region &) const;
|
||||
void getCenter(Common::Point&) const;
|
||||
void getCenter(CoordType&, CoordType&) const;
|
||||
|
||||
void moveSpotTo(const CoordType, const CoordType);
|
||||
void moveSpotTo(const Common::Point &);
|
||||
void moveSpot(const CoordType, const CoordType);
|
||||
void moveSpot(const Common::Point &);
|
||||
|
||||
bool pointInSpot(const Common::Point &) const;
|
||||
|
||||
void setActive();
|
||||
void setInactive();
|
||||
bool isSpotActive() const;
|
||||
|
||||
HotSpotFlags getHotspotFlags() const;
|
||||
void setHotspotFlags(const HotSpotFlags);
|
||||
void setMaskedHotspotFlags(const HotSpotFlags flags, const HotSpotFlags mask);
|
||||
|
||||
protected:
|
||||
Region _spotArea;
|
||||
HotSpotFlags _spotFlags;
|
||||
bool _spotActive;
|
||||
};
|
||||
|
||||
class HotspotList : public Common::List<Hotspot *> {
|
||||
public:
|
||||
HotspotList();
|
||||
virtual ~HotspotList();
|
||||
|
||||
void deleteHotspots();
|
||||
|
||||
Hotspot *findHotspot(const Common::Point &);
|
||||
HotSpotID findHotspotID(const Common::Point &);
|
||||
Hotspot *findHotspotByID(const HotSpotID);
|
||||
Hotspot *findHotspotByMask(const HotSpotFlags);
|
||||
|
||||
void activateMaskedHotspots(const HotSpotFlags = kNoHotSpotFlags);
|
||||
void deactivateAllHotspots();
|
||||
void deactivateMaskedHotspots(const HotSpotFlags);
|
||||
|
||||
void activateOneHotspot(const HotSpotID);
|
||||
void deactivateOneHotspot(const HotSpotID);
|
||||
|
||||
void removeOneHotspot(const HotSpotID);
|
||||
void removeMaskedHotspots(const HotSpotFlags = kNoHotSpotFlags);
|
||||
|
||||
void setHotspotRect(const HotSpotID, const Common::Rect&);
|
||||
void getHotspotRect(const HotSpotID, Common::Rect&);
|
||||
};
|
||||
|
||||
typedef HotspotList::iterator HotspotIterator;
|
||||
|
||||
#define g_allHotspots g_vm->getAllHotspots()
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
359
engines/pegasus/input.cpp
Normal file
359
engines/pegasus/input.cpp
Normal file
@@ -0,0 +1,359 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/events.h"
|
||||
#include "common/system.h"
|
||||
|
||||
#include "gui/gui-manager.h"
|
||||
|
||||
#include "pegasus/cursor.h"
|
||||
#include "pegasus/input.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
|
||||
namespace Common {
|
||||
DECLARE_SINGLETON(Pegasus::InputDeviceManager);
|
||||
}
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
InputDeviceManager::InputDeviceManager() {
|
||||
// Set all keys to "not down"
|
||||
for (uint i = 0; i < ARRAYSIZE(_keysDown); i++) {
|
||||
_keysDown[i] = false;
|
||||
}
|
||||
|
||||
g_system->getEventManager()->getEventDispatcher()->registerObserver(this, 2, false);
|
||||
_lastRawBits = kAllUpBits;
|
||||
_AKeyWasDown = false;
|
||||
}
|
||||
|
||||
InputDeviceManager::~InputDeviceManager() {
|
||||
g_system->getEventManager()->getEventDispatcher()->unregisterObserver(this);
|
||||
}
|
||||
|
||||
void InputDeviceManager::getInput(Input &input, const InputBits filter) {
|
||||
// Poll for events, but ignore most of them!
|
||||
// We'll pick the rest up in notifyEvent()
|
||||
// We do that so that any pollEvent() call can update the variables
|
||||
// (ie. if one uses enter to access the restore menu, we never receive
|
||||
// the key up event, which leads to bad things)
|
||||
// This is to closely emulate what the GetKeys() function did on Mac OS
|
||||
InputBits currentBits = 0;
|
||||
|
||||
Common::Event event;
|
||||
while (g_system->getEventManager()->pollEvent(event))
|
||||
;
|
||||
|
||||
// Now fill in the rest of the bitfield
|
||||
if (_keysDown[kPegasusActionUp])
|
||||
currentBits |= (kRawButtonDown << kUpButtonShift);
|
||||
|
||||
if (_keysDown[kPegasusActionDown])
|
||||
currentBits |= (kRawButtonDown << kDownButtonShift);
|
||||
|
||||
if (_keysDown[kPegasusActionLeft])
|
||||
currentBits |= (kRawButtonDown << kLeftButtonShift);
|
||||
|
||||
if (_keysDown[kPegasusActionRight])
|
||||
currentBits |= (kRawButtonDown << kRightButtonShift);
|
||||
|
||||
if (_keysDown[kPegasusActionInteract])
|
||||
currentBits |= (kRawButtonDown << kTwoButtonShift);
|
||||
|
||||
if (_keysDown[kPegasusActionToggleCenterDisplay])
|
||||
currentBits |= (kRawButtonDown << kThreeButtonShift);
|
||||
|
||||
if (_keysDown[kPegasusActionShowInfoScreen])
|
||||
currentBits |= (kRawButtonDown << kFourButtonShift);
|
||||
|
||||
if (_keysDown[kPegasusActionShowPauseMenu])
|
||||
currentBits |= (kRawButtonDown << kMod3ButtonShift);
|
||||
|
||||
if (_keysDown[kPegasusActionShowInventory])
|
||||
currentBits |= (kRawButtonDown << kLeftFireButtonShift);
|
||||
|
||||
if (_keysDown[kPegasusActionShowBiochip])
|
||||
currentBits |= (kRawButtonDown << kRightFireButtonShift);
|
||||
|
||||
if (g_vm->isDVD()) {
|
||||
if (_keysDown[kPegasusActionToggleChattyAI] && !_AKeyWasDown) {
|
||||
g_vm->requestToggle();
|
||||
_AKeyWasDown = true;
|
||||
} else if (!_keysDown[kPegasusActionToggleChattyAI])
|
||||
_AKeyWasDown = false;
|
||||
}
|
||||
|
||||
// Update mouse button state
|
||||
// Note that we don't use EVENT_LBUTTONUP/EVENT_LBUTTONDOWN because
|
||||
// they do not show if the button is being held down. We're treating
|
||||
// both mouse buttons as the same for ease of use.
|
||||
if (g_system->getEventManager()->getButtonState() != 0)
|
||||
currentBits |= (kRawButtonDown << kTwoButtonShift);
|
||||
|
||||
// Update the mouse position too
|
||||
input.setInputLocation(g_system->getEventManager()->getMousePos());
|
||||
|
||||
// Set the outgoing bits
|
||||
InputBits filteredBits = currentBits & filter;
|
||||
input.setInputBits((filteredBits & kAllButtonDownBits) | (filteredBits & _lastRawBits & kAllAutoBits));
|
||||
|
||||
// Update the last bits
|
||||
_lastRawBits = currentBits;
|
||||
|
||||
// WORKAROUND: The original had this in currentBits, but then
|
||||
// pressing alt would count as an event (and mess up someone
|
||||
// trying to do alt+enter or something). Since it's only used
|
||||
// as an easter egg, I'm just going to handle it as a separate
|
||||
// bool value.
|
||||
input.setAltDown(_keysDown[kPegasusActionEnableEasterEgg]);
|
||||
}
|
||||
|
||||
// Wait until the input device stops returning input allowed by filter...
|
||||
void InputDeviceManager::waitInput(const InputBits filter) {
|
||||
if (filter != 0) {
|
||||
for (;;) {
|
||||
Input input;
|
||||
getInput(input, filter);
|
||||
if (!input.anyInput())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool InputDeviceManager::notifyEvent(const Common::Event &event) {
|
||||
if (GUI::GuiManager::instance().isActive()) {
|
||||
// For some reason, the engine hooks in the event system using an EventObserver.
|
||||
// So we need to explicitly ignore events that happen while ScummVM's GUI is open.
|
||||
return false;
|
||||
}
|
||||
|
||||
// We're mapping from ScummVM events to pegasus events, which
|
||||
// are based on pippin events.
|
||||
|
||||
switch (event.type) {
|
||||
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
|
||||
switch ((PegasusAction)event.customType) {
|
||||
case kPegasusActionSaveGameState:
|
||||
g_vm->requestSave();
|
||||
break;
|
||||
case kPegasusActionLoadGameState:
|
||||
g_vm->requestLoad();
|
||||
break;
|
||||
default:
|
||||
// Otherwise, set the action to down if we have it
|
||||
if (event.customType != kPegasusActionNone && event.customType < kPegasusActionCount)
|
||||
_keysDown[event.customType] = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Common::EVENT_CUSTOM_ENGINE_ACTION_END:
|
||||
// Set the key to up if we have it
|
||||
if (event.customType != kPegasusActionNone && event.customType < kPegasusActionCount)
|
||||
_keysDown[event.customType] = false;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void InputDeviceManager::pumpEvents() {
|
||||
bool saveAllowed = g_vm->swapSaveAllowed(false);
|
||||
bool openAllowed = g_vm->swapLoadAllowed(false);
|
||||
|
||||
// Just poll for events. notifyEvent() will pick up on them.
|
||||
Common::Event event;
|
||||
while (g_system->getEventManager()->pollEvent(event))
|
||||
;
|
||||
|
||||
g_vm->swapSaveAllowed(saveAllowed);
|
||||
g_vm->swapLoadAllowed(openAllowed);
|
||||
}
|
||||
|
||||
int operator==(const Input &arg1, const Input &arg2) {
|
||||
return arg1._inputState == arg2._inputState;
|
||||
}
|
||||
|
||||
int operator!=(const Input &arg1, const Input &arg2) {
|
||||
return !operator==(arg1, arg2);
|
||||
}
|
||||
|
||||
InputHandler *InputHandler::_inputHandler = nullptr;
|
||||
bool InputHandler::_invalHotspots = false;
|
||||
InputBits InputHandler::_lastFilter = kFilterNoInput;
|
||||
|
||||
InputHandler *InputHandler::setInputHandler(InputHandler *currentHandler) {
|
||||
InputHandler *result = nullptr;
|
||||
|
||||
if (_inputHandler != currentHandler && (!_inputHandler || _inputHandler->releaseInputFocus())) {
|
||||
result = _inputHandler;
|
||||
_inputHandler = currentHandler;
|
||||
if (_inputHandler)
|
||||
_inputHandler->grabInputFocus();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void InputHandler::pollForInput() {
|
||||
if (_inputHandler) {
|
||||
Input input;
|
||||
Hotspot *cursorSpot = nullptr;
|
||||
|
||||
InputHandler::getInput(input, cursorSpot);
|
||||
if (_inputHandler->isClickInput(input, cursorSpot))
|
||||
_inputHandler->clickInHotspot(input, cursorSpot);
|
||||
else
|
||||
_inputHandler->handleInput(input, cursorSpot);
|
||||
}
|
||||
}
|
||||
|
||||
void InputHandler::getInput(Input &input, Hotspot *&cursorSpot) {
|
||||
Cursor *cursor = g_vm->_cursor;
|
||||
|
||||
if (_inputHandler)
|
||||
_lastFilter = _inputHandler->getInputFilter();
|
||||
else
|
||||
_lastFilter = kFilterAllInput;
|
||||
|
||||
InputDevice.getInput(input, _lastFilter);
|
||||
|
||||
if (_inputHandler && _inputHandler->wantsCursor() && (_lastFilter & _inputHandler->getClickFilter()) != 0) {
|
||||
if (cursor->isVisible()) {
|
||||
g_allHotspots.deactivateAllHotspots();
|
||||
_inputHandler->activateHotspots();
|
||||
|
||||
Common::Point cursorLocation;
|
||||
cursor->getCursorLocation(cursorLocation);
|
||||
cursorSpot = g_allHotspots.findHotspot(cursorLocation);
|
||||
|
||||
if (_inputHandler)
|
||||
_inputHandler->updateCursor(cursorLocation, cursorSpot);
|
||||
} else {
|
||||
cursor->hideUntilMoved();
|
||||
}
|
||||
} else {
|
||||
cursor->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void InputHandler::readInputDevice(Input &input) {
|
||||
InputDevice.getInput(input, kFilterAllInput);
|
||||
}
|
||||
|
||||
InputHandler::InputHandler(InputHandler *nextHandler) {
|
||||
_nextHandler = nextHandler;
|
||||
allowInput(true);
|
||||
}
|
||||
|
||||
InputHandler::~InputHandler() {
|
||||
if (_inputHandler == this)
|
||||
setInputHandler(_nextHandler);
|
||||
}
|
||||
|
||||
void InputHandler::handleInput(const Input &input, const Hotspot *cursorSpot) {
|
||||
if (_nextHandler)
|
||||
_nextHandler->handleInput(input, cursorSpot);
|
||||
}
|
||||
|
||||
void InputHandler::clickInHotspot(const Input &input, const Hotspot *cursorSpot) {
|
||||
if (_nextHandler)
|
||||
_nextHandler->clickInHotspot(input, cursorSpot);
|
||||
}
|
||||
|
||||
bool InputHandler::isClickInput(const Input &input, const Hotspot *cursorSpot) {
|
||||
if (_nextHandler)
|
||||
return _nextHandler->isClickInput(input, cursorSpot);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void InputHandler::activateHotspots() {
|
||||
if (_nextHandler)
|
||||
_nextHandler->activateHotspots();
|
||||
}
|
||||
|
||||
InputBits InputHandler::getInputFilter() {
|
||||
if (_allowInput) {
|
||||
if (_nextHandler)
|
||||
return _nextHandler->getInputFilter();
|
||||
else
|
||||
return kFilterAllInput;
|
||||
}
|
||||
|
||||
return kFilterNoInput;
|
||||
}
|
||||
|
||||
InputBits InputHandler::getClickFilter() {
|
||||
if (_allowInput && _nextHandler)
|
||||
return _nextHandler->getClickFilter();
|
||||
|
||||
return kFilterNoInput;
|
||||
}
|
||||
|
||||
void InputHandler::updateCursor(const Common::Point &cursorLocation, const Hotspot *cursorSpot) {
|
||||
if (_nextHandler)
|
||||
_nextHandler->updateCursor(cursorLocation, cursorSpot);
|
||||
}
|
||||
|
||||
bool InputHandler::wantsCursor() {
|
||||
if (_allowInput) {
|
||||
if (_nextHandler)
|
||||
return _nextHandler->wantsCursor();
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Tracker *Tracker::_currentTracker = nullptr;
|
||||
|
||||
void Tracker::handleInput(const Input &input, const Hotspot *) {
|
||||
if (stopTrackingInput(input))
|
||||
stopTracking(input);
|
||||
else if (isTracking())
|
||||
continueTracking(input);
|
||||
}
|
||||
|
||||
void Tracker::startTracking(const Input &) {
|
||||
if (!isTracking()) {
|
||||
_savedHandler = InputHandler::setInputHandler(this);
|
||||
_currentTracker = this;
|
||||
}
|
||||
}
|
||||
|
||||
void Tracker::stopTracking(const Input &) {
|
||||
if (isTracking()) {
|
||||
_currentTracker = nullptr;
|
||||
InputHandler::setInputHandler(_savedHandler);
|
||||
}
|
||||
}
|
||||
|
||||
bool Tracker::isClickInput(const Input &input, const Hotspot *hotspot) {
|
||||
return !isTracking() && InputHandler::isClickInput(input, hotspot);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
516
engines/pegasus/input.h
Normal file
516
engines/pegasus/input.h
Normal file
@@ -0,0 +1,516 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_INPUT_H
|
||||
#define PEGASUS_INPUT_H
|
||||
|
||||
#include "common/events.h"
|
||||
#include "common/rect.h"
|
||||
#include "common/singleton.h"
|
||||
|
||||
#include "pegasus/constants.h"
|
||||
#include "pegasus/types.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class Hotspot;
|
||||
class Input;
|
||||
|
||||
enum PegasusAction {
|
||||
kPegasusActionNone,
|
||||
kPegasusActionUp,
|
||||
kPegasusActionDown,
|
||||
kPegasusActionLeft,
|
||||
kPegasusActionRight,
|
||||
kPegasusActionInteract,
|
||||
kPegasusActionShowInventory,
|
||||
kPegasusActionShowBiochip,
|
||||
kPegasusActionToggleCenterDisplay,
|
||||
kPegasusActionShowInfoScreen,
|
||||
kPegasusActionShowPauseMenu,
|
||||
kPegasusActionSaveGameState,
|
||||
kPegasusActionLoadGameState,
|
||||
kPegasusActionEnableEasterEgg,
|
||||
kPegasusActionToggleChattyAI,
|
||||
|
||||
kPegasusActionCount
|
||||
};
|
||||
|
||||
class InputDeviceManager : public Common::Singleton<InputDeviceManager>, public Common::EventObserver {
|
||||
public:
|
||||
InputDeviceManager();
|
||||
~InputDeviceManager() override;
|
||||
|
||||
bool notifyEvent(const Common::Event &event) override;
|
||||
|
||||
void getInput(Input &, const InputBits);
|
||||
|
||||
void waitInput(const InputBits);
|
||||
|
||||
void pumpEvents();
|
||||
|
||||
protected:
|
||||
friend class Common::Singleton<SingletonBaseType>;
|
||||
|
||||
// Keep track of which keys are down (= true) or not
|
||||
bool _keysDown[kPegasusActionCount];
|
||||
InputBits _lastRawBits;
|
||||
bool _AKeyWasDown;
|
||||
};
|
||||
|
||||
enum {
|
||||
kButtonDownBit = 0,
|
||||
kAutoButtonBit = 1,
|
||||
kBitsPerButton = 2,
|
||||
|
||||
kButtonDownMask = 1 << kButtonDownBit,
|
||||
kAutoButtonMask = 1 << kAutoButtonBit,
|
||||
|
||||
kButtonStateBits = kButtonDownMask | kAutoButtonMask,
|
||||
|
||||
kRawButtonUp = 0,
|
||||
kRawButtonDown = kButtonDownMask | kAutoButtonMask,
|
||||
|
||||
kButtonUp = 0,
|
||||
kButtonDown = kButtonDownMask,
|
||||
kButtonAutoUp = kAutoButtonMask,
|
||||
kButtonAutoDown = kButtonDownMask | kAutoButtonMask
|
||||
};
|
||||
|
||||
enum {
|
||||
kUpButtonNum = 0,
|
||||
kLeftButtonNum = 1,
|
||||
kDownButtonNum = 2,
|
||||
kRightButtonNum = 3,
|
||||
kLeftFireButtonNum = 4,
|
||||
kRightFireButtonNum = 5,
|
||||
kOneButtonNum = 6,
|
||||
kTwoButtonNum = 7,
|
||||
kThreeButtonNum = 8,
|
||||
kFourButtonNum = 9,
|
||||
kMod1ButtonNum = 10,
|
||||
kMod2ButtonNum = 11,
|
||||
kMod3ButtonNum = 12
|
||||
};
|
||||
|
||||
enum {
|
||||
kUpButtonShift = kUpButtonNum * kBitsPerButton,
|
||||
kLeftButtonShift = kLeftButtonNum * kBitsPerButton,
|
||||
kDownButtonShift = kDownButtonNum * kBitsPerButton,
|
||||
kRightButtonShift = kRightButtonNum * kBitsPerButton,
|
||||
kLeftFireButtonShift = kLeftFireButtonNum * kBitsPerButton,
|
||||
kRightFireButtonShift = kRightFireButtonNum * kBitsPerButton,
|
||||
kOneButtonShift = kOneButtonNum * kBitsPerButton,
|
||||
kTwoButtonShift = kTwoButtonNum * kBitsPerButton,
|
||||
kThreeButtonShift = kThreeButtonNum * kBitsPerButton,
|
||||
kFourButtonShift = kFourButtonNum * kBitsPerButton,
|
||||
kMod1ButtonShift = kMod1ButtonNum * kBitsPerButton,
|
||||
kMod2ButtonShift = kMod2ButtonNum * kBitsPerButton,
|
||||
kMod3ButtonShift = kMod3ButtonNum * kBitsPerButton
|
||||
};
|
||||
|
||||
enum {
|
||||
kAllUpBits = (kButtonUp << kUpButtonShift) |
|
||||
(kButtonUp << kLeftButtonShift) |
|
||||
(kButtonUp << kDownButtonShift) |
|
||||
(kButtonUp << kRightButtonShift) |
|
||||
(kButtonUp << kLeftFireButtonShift) |
|
||||
(kButtonUp << kRightFireButtonShift) |
|
||||
(kButtonUp << kOneButtonShift) |
|
||||
(kButtonUp << kTwoButtonShift) |
|
||||
(kButtonUp << kThreeButtonShift) |
|
||||
(kButtonUp << kFourButtonShift) |
|
||||
(kButtonUp << kMod1ButtonShift) |
|
||||
(kButtonUp << kMod2ButtonShift) |
|
||||
(kButtonUp << kMod3ButtonShift),
|
||||
kDirectionBits = (kButtonDownMask << kUpButtonShift) |
|
||||
(kButtonDownMask << kLeftButtonShift) |
|
||||
(kButtonDownMask << kDownButtonShift) |
|
||||
(kButtonDownMask << kRightButtonShift),
|
||||
kButtonBits = (kButtonDownMask << kLeftFireButtonShift) |
|
||||
(kButtonDownMask << kRightFireButtonShift) |
|
||||
(kButtonDownMask << kOneButtonShift) |
|
||||
(kButtonDownMask << kTwoButtonShift) |
|
||||
(kButtonDownMask << kThreeButtonShift) |
|
||||
(kButtonDownMask << kFourButtonShift) |
|
||||
(kButtonDownMask << kMod1ButtonShift) |
|
||||
(kButtonDownMask << kMod2ButtonShift) |
|
||||
(kButtonDownMask << kMod3ButtonShift),
|
||||
kAllButtonDownBits = kDirectionBits | kButtonBits,
|
||||
kAllAutoBits = (kAutoButtonMask << kUpButtonShift) |
|
||||
(kAutoButtonMask << kLeftButtonShift) |
|
||||
(kAutoButtonMask << kDownButtonShift) |
|
||||
(kAutoButtonMask << kRightButtonShift) |
|
||||
(kAutoButtonMask << kLeftFireButtonShift) |
|
||||
(kAutoButtonMask << kRightFireButtonShift) |
|
||||
(kAutoButtonMask << kOneButtonShift) |
|
||||
(kAutoButtonMask << kTwoButtonShift) |
|
||||
(kAutoButtonMask << kThreeButtonShift) |
|
||||
(kAutoButtonMask << kFourButtonShift) |
|
||||
(kAutoButtonMask << kMod1ButtonShift) |
|
||||
(kAutoButtonMask << kMod2ButtonShift) |
|
||||
(kAutoButtonMask << kMod3ButtonShift),
|
||||
|
||||
kFilterUpButton = kButtonDownMask << kUpButtonShift,
|
||||
kFilterUpAuto = kAutoButtonMask << kUpButtonShift,
|
||||
kFilterUpButtonAny = kFilterUpButton | kFilterUpAuto,
|
||||
kFilterLeftButton = kButtonDownMask << kLeftButtonShift,
|
||||
kFilterLeftAuto = kAutoButtonMask << kLeftButtonShift,
|
||||
kFilterLeftButtonAny = kFilterLeftButton | kFilterLeftAuto,
|
||||
kFilterDownButton = kButtonDownMask << kDownButtonShift,
|
||||
kFilterDownAuto = kAutoButtonMask << kDownButtonShift,
|
||||
kFilterDownButtonAny = kFilterDownButton | kFilterDownAuto,
|
||||
kFilterRightButton = kButtonDownMask << kRightButtonShift,
|
||||
kFilterRightAuto = kAutoButtonMask << kRightButtonShift,
|
||||
kFilterRightButtonAny = kFilterRightButton | kFilterRightAuto,
|
||||
kFilterLeftFireButton = kButtonDownMask << kLeftFireButtonShift,
|
||||
kFilterLeftFireAuto = kAutoButtonMask << kLeftFireButtonShift,
|
||||
kFilterLeftFireButtonAny = kFilterLeftFireButton | kFilterLeftFireAuto,
|
||||
kFilterRightFireButton = kButtonDownMask << kRightFireButtonShift,
|
||||
kFilterRightFireAuto = kAutoButtonMask << kRightFireButtonShift,
|
||||
kFilterRightFireButtonAny = kFilterRightFireButton | kFilterRightFireAuto,
|
||||
kFilterOneButton = kButtonDownMask << kOneButtonShift,
|
||||
kFilterOneAuto = kAutoButtonMask << kOneButtonShift,
|
||||
kFilterOneButtonAny = kFilterOneButton | kFilterOneAuto,
|
||||
kFilterTwoButton = kButtonDownMask << kTwoButtonShift,
|
||||
kFilterTwoAuto = kAutoButtonMask << kTwoButtonShift,
|
||||
kFilterTwoButtonAny = kFilterTwoButton | kFilterTwoAuto,
|
||||
kFilterThreeButton = kButtonDownMask << kThreeButtonShift,
|
||||
kFilterThreeAuto = kAutoButtonMask << kThreeButtonShift,
|
||||
kFilterThreeButtonAny = kFilterThreeButton | kFilterThreeAuto,
|
||||
kFilterFourButton = kButtonDownMask << kFourButtonShift,
|
||||
kFilterFourAuto = kAutoButtonMask << kFourButtonShift,
|
||||
kFilterFourButtonAny = kFilterFourButton | kFilterFourAuto,
|
||||
kFilterMod1Button = kButtonDownMask << kMod1ButtonShift,
|
||||
kFilterMod1Auto = kAutoButtonMask << kMod1ButtonShift,
|
||||
kFilterMod1ButtonAny = kFilterMod1Button | kFilterMod1Auto,
|
||||
kFilterMod2Button = kButtonDownMask << kMod2ButtonShift,
|
||||
kFilterMod2Auto = kAutoButtonMask << kMod2ButtonShift,
|
||||
kFilterMod2ButtonAny = kFilterMod2Button | kFilterMod2Auto,
|
||||
kFilterMod3Button = kButtonDownMask << kMod3ButtonShift,
|
||||
kFilterMod3Auto = kAutoButtonMask << kMod3ButtonShift,
|
||||
kFilterMod3ButtonAny = kFilterMod3Button | kFilterMod3Auto,
|
||||
|
||||
kFilterNoInput = 0,
|
||||
kFilterAllInput = kFilterUpButton |
|
||||
kFilterUpAuto |
|
||||
kFilterLeftButton |
|
||||
kFilterLeftAuto |
|
||||
kFilterDownButton |
|
||||
kFilterDownAuto |
|
||||
kFilterRightButton |
|
||||
kFilterRightAuto |
|
||||
kFilterLeftFireButton |
|
||||
kFilterLeftFireAuto |
|
||||
kFilterRightFireButton |
|
||||
kFilterRightFireAuto |
|
||||
kFilterOneButton |
|
||||
kFilterOneAuto |
|
||||
kFilterTwoButton |
|
||||
kFilterTwoAuto |
|
||||
kFilterThreeButton |
|
||||
kFilterThreeAuto |
|
||||
kFilterFourButton |
|
||||
kFilterFourAuto |
|
||||
kFilterMod1Button |
|
||||
kFilterMod1Auto |
|
||||
kFilterMod2Button |
|
||||
kFilterMod2Auto |
|
||||
kFilterMod3Button |
|
||||
kFilterMod3Auto,
|
||||
|
||||
kFilterAllDirections = kFilterUpButton |
|
||||
kFilterUpAuto |
|
||||
kFilterLeftButton |
|
||||
kFilterLeftAuto |
|
||||
kFilterDownButton |
|
||||
kFilterDownAuto |
|
||||
kFilterRightButton |
|
||||
kFilterRightAuto,
|
||||
|
||||
kFilterButtons = kFilterOneButton |
|
||||
kFilterOneAuto |
|
||||
kFilterTwoButton |
|
||||
kFilterTwoAuto |
|
||||
kFilterThreeButton |
|
||||
kFilterThreeAuto |
|
||||
kFilterFourButton |
|
||||
kFilterFourAuto,
|
||||
|
||||
kFilterFireButtons = kFilterLeftFireButton |
|
||||
kFilterLeftFireAuto |
|
||||
kFilterRightFireButton |
|
||||
kFilterRightFireAuto,
|
||||
|
||||
kFilterAllButtons = kFilterLeftFireButton |
|
||||
kFilterLeftFireAuto |
|
||||
kFilterRightFireButton |
|
||||
kFilterRightFireAuto |
|
||||
kFilterOneButton |
|
||||
kFilterOneAuto |
|
||||
kFilterTwoButton |
|
||||
kFilterTwoAuto |
|
||||
kFilterThreeButton |
|
||||
kFilterThreeAuto |
|
||||
kFilterFourButton |
|
||||
kFilterFourAuto |
|
||||
kFilterMod1Button |
|
||||
kFilterMod1Auto |
|
||||
kFilterMod2Button |
|
||||
kFilterMod2Auto |
|
||||
kFilterMod3Button |
|
||||
kFilterMod3Auto,
|
||||
|
||||
kFilterAllInputNoAuto = kFilterUpButton |
|
||||
kFilterLeftButton |
|
||||
kFilterDownButton |
|
||||
kFilterRightButton |
|
||||
kFilterLeftFireButton |
|
||||
kFilterRightFireButton |
|
||||
kFilterOneButton |
|
||||
kFilterTwoButton |
|
||||
kFilterThreeButton |
|
||||
kFilterFourButton |
|
||||
kFilterMod1Button |
|
||||
kFilterMod2Button |
|
||||
kFilterMod3Button
|
||||
};
|
||||
|
||||
static const InputBits kHintInterruption = kFilterAllInputNoAuto;
|
||||
static const InputBits kWarningInterruption = kFilterAllInputNoAuto;
|
||||
static const InputBits kOpticalInterruption = kFilterAllInputNoAuto;
|
||||
|
||||
/*
|
||||
|
||||
Buttons are defined as:
|
||||
up, left, down, right direction buttons.
|
||||
fireLeft, fireRight: fire buttons.
|
||||
mod1, mod2, mod3: modifier buttons, similar to shift, control, etc.
|
||||
a, b, c, d: general purpose buttons.
|
||||
|
||||
button state is held as bits in a long word, two bits per button.
|
||||
|
||||
Filter bits:
|
||||
for each button, two bits are assigned for filtering. If bit 0 is set, the
|
||||
corresponding button is available for "button down" input. If bit 1 is set,
|
||||
the corresponding button is available for "auto down" input. Note that bit
|
||||
1 is meaningful only if bit 0 is set.
|
||||
|
||||
*/
|
||||
|
||||
class Input {
|
||||
friend int operator==(const Input &, const Input &);
|
||||
friend int operator!=(const Input &, const Input &);
|
||||
friend class InputDeviceManager;
|
||||
|
||||
public:
|
||||
Input() { clearInput(); }
|
||||
|
||||
bool upButtonDown() const { return (_inputState & (kButtonStateBits << kUpButtonShift)) == (kButtonDown << kUpButtonShift); }
|
||||
bool upButtonAutoDown() const { return (_inputState & (kButtonStateBits << kUpButtonShift)) == (kButtonAutoDown << kUpButtonShift); }
|
||||
bool upButtonAnyDown() const { return (_inputState & (kButtonAutoDown << kUpButtonShift)) != 0; }
|
||||
|
||||
bool leftButtonDown() const { return (_inputState & (kButtonStateBits << kLeftButtonShift)) == (kButtonDown << kLeftButtonShift); }
|
||||
bool leftButtonAutoDown() const { return (_inputState & (kButtonStateBits << kLeftButtonShift)) == (kButtonAutoDown << kLeftButtonShift); }
|
||||
bool leftButtonAnyDown() const { return (_inputState & (kButtonAutoDown << kLeftButtonShift)) != 0; }
|
||||
|
||||
bool downButtonDown() const { return (_inputState & (kButtonStateBits << kDownButtonShift)) == (kButtonDown << kDownButtonShift); }
|
||||
bool downButtonAutoDown() const { return (_inputState & (kButtonStateBits << kDownButtonShift)) == (kButtonAutoDown << kDownButtonShift); }
|
||||
bool downButtonAnyDown() const { return (_inputState & (kButtonAutoDown << kDownButtonShift)) != 0; }
|
||||
|
||||
bool rightButtonDown() const { return (_inputState & (kButtonStateBits << kRightButtonShift)) == (kButtonDown << kRightButtonShift); }
|
||||
bool rightButtonAutoDown() const { return (_inputState & (kButtonStateBits << kRightButtonShift)) == (kButtonAutoDown << kRightButtonShift); }
|
||||
bool rightButtonAnyDown() const { return (_inputState & (kButtonAutoDown << kRightButtonShift)) != 0; }
|
||||
|
||||
bool leftFireButtonDown() const { return (_inputState & (kButtonStateBits << kLeftFireButtonShift)) == (kButtonDown << kLeftFireButtonShift); }
|
||||
bool leftFireButtonAutoDown() const { return (_inputState & (kButtonStateBits << kLeftFireButtonShift)) == (kButtonAutoDown << kLeftFireButtonShift); }
|
||||
bool leftFireButtonAnyDown() const { return (_inputState & (kButtonAutoDown << kLeftFireButtonShift)) != 0; }
|
||||
|
||||
bool rightFireButtonDown() const { return (_inputState & (kButtonStateBits << kRightFireButtonShift)) == (kButtonDown << kRightFireButtonShift); }
|
||||
bool rightFireButtonAutoDown() const { return (_inputState & (kButtonStateBits << kRightFireButtonShift)) == (kButtonAutoDown << kRightFireButtonShift); }
|
||||
bool rightFireButtonAnyDown() const { return (_inputState & (kButtonAutoDown << kRightFireButtonShift)) != 0; }
|
||||
|
||||
bool oneButtonDown() const { return (_inputState & (kButtonStateBits << kOneButtonShift)) == (kButtonDown << kOneButtonShift); }
|
||||
bool oneButtonAutoDown() const { return (_inputState & (kButtonStateBits << kOneButtonShift)) == (kButtonAutoDown << kOneButtonShift); }
|
||||
bool oneButtonAnyDown() const { return (_inputState & (kButtonAutoDown << kOneButtonShift)) != 0; }
|
||||
|
||||
bool twoButtonDown() const { return (_inputState & (kButtonStateBits << kTwoButtonShift)) == (kButtonDown << kTwoButtonShift); }
|
||||
bool twoButtonAutoDown() const { return (_inputState & (kButtonStateBits << kTwoButtonShift)) == (kButtonAutoDown << kTwoButtonShift); }
|
||||
bool twoButtonAnyDown() const { return (_inputState & (kButtonAutoDown << kTwoButtonShift)) != 0; }
|
||||
|
||||
bool threeButtonDown() const { return (_inputState & (kButtonStateBits << kThreeButtonShift)) == (kButtonDown << kThreeButtonShift); }
|
||||
bool threeButtonAutoDown() const { return (_inputState & (kButtonStateBits << kThreeButtonShift)) == (kButtonAutoDown << kThreeButtonShift); }
|
||||
bool threeButtonAnyDown() const { return (_inputState & (kButtonAutoDown << kThreeButtonShift)) != 0; }
|
||||
|
||||
bool fourButtonDown() const { return (_inputState & (kButtonStateBits << kFourButtonShift)) == (kButtonDown << kFourButtonShift); }
|
||||
bool fourButtonAutoDown() const { return (_inputState & (kButtonStateBits << kFourButtonShift)) == (kButtonAutoDown << kFourButtonShift); }
|
||||
bool fourButtonAnyDown() const { return (_inputState & (kButtonAutoDown << kFourButtonShift)) != 0; }
|
||||
|
||||
bool mod1ButtonDown() const { return (_inputState & (kButtonStateBits << kMod1ButtonShift)) == (kButtonDown << kMod1ButtonShift); }
|
||||
bool mod1ButtonAutoDown() const { return (_inputState & (kButtonStateBits << kMod1ButtonShift)) == (kButtonAutoDown << kMod1ButtonShift); }
|
||||
bool mod1ButtonAnyDown() const { return (_inputState & (kButtonAutoDown << kMod1ButtonShift)) != 0; }
|
||||
|
||||
bool mod2ButtonDown() const { return (_inputState & (kButtonStateBits << kMod2ButtonShift)) == (kButtonDown << kMod2ButtonShift); }
|
||||
bool mod2ButtonAutoDown() const { return (_inputState & (kButtonStateBits << kMod2ButtonShift)) == (kButtonAutoDown << kMod2ButtonShift); }
|
||||
bool mod2ButtonAnyDown() const { return (_inputState & (kButtonAutoDown << kMod2ButtonShift)) != 0; }
|
||||
|
||||
bool mod3ButtonDown() const { return (_inputState & (kButtonStateBits << kMod3ButtonShift)) == (kButtonDown << kMod3ButtonShift); }
|
||||
bool mod3ButtonAutoDown() const { return (_inputState & (kButtonStateBits << kMod3ButtonShift)) == (kButtonAutoDown << kMod3ButtonShift); }
|
||||
bool mod3ButtonAnyDown() const { return (_inputState & (kButtonAutoDown << kMod3ButtonShift)) != 0; }
|
||||
|
||||
bool allAutoInput() const { return (_inputState & kAllAutoBits) != 0; }
|
||||
bool anyDirectionInput() const { return (_inputState & kDirectionBits) != 0; }
|
||||
bool anyButtonInput() const { return (_inputState & kButtonBits) != 0; }
|
||||
bool anyInput() const { return _inputState != 0; }
|
||||
|
||||
void getInputLocation(Common::Point &where) const { where = _inputLocation; }
|
||||
|
||||
bool anyInputBitSet(const InputBits bits) const { return (_inputState & bits) != 0; }
|
||||
|
||||
bool isAltDown() const { return _altDown; }
|
||||
|
||||
void clearInput() {
|
||||
_inputState = kAllUpBits;
|
||||
_inputLocation.x = 0;
|
||||
_inputLocation.y = 0;
|
||||
_altDown = false;
|
||||
}
|
||||
|
||||
protected:
|
||||
void setInputBits(const InputBits state) { _inputState = state; }
|
||||
void setInputLocation(const Common::Point &where) { _inputLocation = where; }
|
||||
void setAltDown(bool altDown) { _altDown = altDown; }
|
||||
|
||||
InputBits _inputState;
|
||||
Common::Point _inputLocation;
|
||||
bool _altDown;
|
||||
};
|
||||
|
||||
class InputHandler {
|
||||
public:
|
||||
static InputHandler *setInputHandler(InputHandler*);
|
||||
static InputHandler *getCurrentHandler() { return _inputHandler; }
|
||||
static void pollForInput();
|
||||
static void getInput(Input&, Hotspot*&);
|
||||
static void readInputDevice(Input&);
|
||||
static void invalHotspots() { _invalHotspots = true; }
|
||||
static InputBits getCurrentFilter() { return _lastFilter; }
|
||||
|
||||
InputHandler(InputHandler*);
|
||||
virtual ~InputHandler();
|
||||
|
||||
virtual void setNextHandler(InputHandler *nextHandler) { _nextHandler = nextHandler; }
|
||||
virtual InputHandler *getNextHandler() { return _nextHandler; }
|
||||
|
||||
virtual void handleInput(const Input &, const Hotspot *);
|
||||
virtual void clickInHotspot(const Input &, const Hotspot *);
|
||||
|
||||
virtual void activateHotspots();
|
||||
virtual void updateCursor(const Common::Point &, const Hotspot *);
|
||||
virtual bool isClickInput(const Input &, const Hotspot *);
|
||||
virtual bool wantsCursor();
|
||||
|
||||
virtual bool releaseInputFocus() { return true; }
|
||||
virtual void grabInputFocus() {}
|
||||
|
||||
// This returns bits set for what kinds of input to accept.
|
||||
virtual InputBits getInputFilter();
|
||||
|
||||
// This returns bits defining what input constitutes a "click."
|
||||
virtual InputBits getClickFilter();
|
||||
|
||||
virtual void allowInput(const bool allow) { _allowInput = allow; }
|
||||
|
||||
protected:
|
||||
static InputHandler *_inputHandler;
|
||||
static bool _invalHotspots;
|
||||
static InputBits _lastFilter;
|
||||
|
||||
InputHandler *_nextHandler;
|
||||
bool _allowInput;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Tracker implements "dragging". A Tracker can receive a startTracking message,
|
||||
which causes it to be the current tracker, as well as setting it up as the current
|
||||
input handler. In addition, only one tracker can be tracking at a time, and no
|
||||
other handler can be set up as the current handler until the track finishes. By
|
||||
default, there is no next input handler for a Tracker, but this behavior can be
|
||||
overridden if desired.
|
||||
|
||||
*/
|
||||
|
||||
class Tracker : public InputHandler {
|
||||
public:
|
||||
Tracker() : InputHandler(0), _savedHandler(nullptr) {}
|
||||
~Tracker() override {}
|
||||
|
||||
void handleInput(const Input &, const Hotspot *) override;
|
||||
virtual bool stopTrackingInput(const Input &) { return false; }
|
||||
|
||||
virtual void startTracking(const Input &);
|
||||
virtual void stopTracking(const Input &);
|
||||
virtual void continueTracking(const Input &) {}
|
||||
|
||||
bool isTracking() { return this == _currentTracker; }
|
||||
bool isClickInput(const Input &, const Hotspot *) override;
|
||||
|
||||
bool releaseInputFocus() override { return !isTracking(); }
|
||||
|
||||
protected:
|
||||
static Tracker *_currentTracker;
|
||||
|
||||
InputHandler *_savedHandler;
|
||||
};
|
||||
|
||||
class JMPPPInput {
|
||||
public:
|
||||
static bool isMenuButtonPressInput(const Input &input) { return input.twoButtonDown(); }
|
||||
|
||||
static InputBits getClickInputFilter() { return kFilterTwoButton; }
|
||||
static bool isClickInput(const Input &input) { return input.twoButtonDown(); }
|
||||
static bool isDraggingInput(const Input &input) { return input.twoButtonAnyDown(); }
|
||||
static bool isPressingInput(const Input &input) { return input.twoButtonAnyDown(); }
|
||||
|
||||
static bool isRaiseInventoryInput(const Input &input) { return input.leftFireButtonDown(); }
|
||||
static bool isRaiseBiochipsInput(const Input &input) { return input.rightFireButtonDown(); }
|
||||
static InputBits getItemPanelsInputFilter() { return kFilterFourButton | kFilterLeftFireButton | kFilterRightFireButton; }
|
||||
|
||||
static bool isToggleAIMiddleInput(const Input &input) { return input.threeButtonDown(); }
|
||||
|
||||
static bool isToggleInfoInput(const Input &input) { return input.fourButtonDown(); }
|
||||
|
||||
// Hmmmmm....
|
||||
static bool isEasterEggModifierInput(const Input &input) { return input.isAltDown(); }
|
||||
|
||||
static bool isTogglePauseInput(const Input &input) { return input.mod3ButtonDown(); }
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#define InputDevice (::Pegasus::InputDeviceManager::instance())
|
||||
|
||||
#endif
|
||||
36
engines/pegasus/interaction.cpp
Normal file
36
engines/pegasus/interaction.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/interaction.h"
|
||||
#include "pegasus/neighborhood/neighborhood.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
GameInteraction::GameInteraction(const InteractionID id, Neighborhood *nextHandler) : IDObject(id), InputHandler(nextHandler) {
|
||||
_isInteracting = false;
|
||||
_savedHandler = nullptr;
|
||||
_owner = nextHandler;
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
105
engines/pegasus/interaction.h
Normal file
105
engines/pegasus/interaction.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_INTERACTION_H
|
||||
#define PEGASUS_INTERACTION_H
|
||||
|
||||
#include "pegasus/input.h"
|
||||
#include "pegasus/util.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
static const InteractionID kNoInteractionID = -1;
|
||||
|
||||
class Neighborhood;
|
||||
|
||||
class GameInteraction : public IDObject, public InputHandler {
|
||||
public:
|
||||
GameInteraction(const InteractionID id, Neighborhood *nextHandler);
|
||||
|
||||
// If the interaction is open (_isInteracting == true), it's too late to do anything
|
||||
// about it here.
|
||||
~GameInteraction() override {}
|
||||
|
||||
// startInteraction and stopInteraction are called by the outside world to
|
||||
// start and stop the interaction sequence.
|
||||
// isInteracting returns a bool indicating whether or not the interaction
|
||||
// is going.
|
||||
void startInteraction() {
|
||||
if (!isInteracting()) {
|
||||
openInteraction();
|
||||
initInteraction();
|
||||
_isInteracting = true;
|
||||
_savedHandler = InputHandler::setInputHandler(this);
|
||||
}
|
||||
}
|
||||
void stopInteraction() {
|
||||
if (isInteracting()) {
|
||||
closeInteraction();
|
||||
_isInteracting = false;
|
||||
if (InputHandler::_inputHandler == this)
|
||||
InputHandler::setInputHandler(_savedHandler);
|
||||
}
|
||||
}
|
||||
void startOverInteraction() {
|
||||
if (isInteracting())
|
||||
resetInteraction();
|
||||
}
|
||||
bool isInteracting() const { return _isInteracting; }
|
||||
Neighborhood *getOwner() const { return _owner; }
|
||||
|
||||
virtual Common::Path getBriefingMovie() { return Common::Path(); }
|
||||
virtual Common::Path getEnvScanMovie() { return Common::Path(); }
|
||||
virtual long getNumHints() { return 0; }
|
||||
virtual Common::Path getHintMovie(uint) { return Common::Path(); }
|
||||
virtual bool canSolve() { return false; }
|
||||
|
||||
virtual void setSoundFXLevel(const uint16) {}
|
||||
virtual void setAmbienceLevel(const uint16) {}
|
||||
|
||||
virtual void doSolve() {}
|
||||
|
||||
protected:
|
||||
// Subclasses override openInteraction and closeInteraction to perform
|
||||
// specific initialization and cleanup. Override resetInteraction to
|
||||
// "start the interaction over." resetInteraction is called only when
|
||||
// the interaction is already open.
|
||||
// These functions are only called in pairs, never two opens or closes
|
||||
// in a row.
|
||||
virtual void openInteraction() {}
|
||||
virtual void initInteraction() {}
|
||||
virtual void closeInteraction() {}
|
||||
virtual void resetInteraction() {}
|
||||
|
||||
InputHandler *_savedHandler;
|
||||
Neighborhood *_owner;
|
||||
|
||||
private:
|
||||
// Private so that only StartInteraction and StopInteraction can touch it.
|
||||
bool _isInteracting;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
709
engines/pegasus/interface.cpp
Normal file
709
engines/pegasus/interface.cpp
Normal file
@@ -0,0 +1,709 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/compass.h"
|
||||
#include "pegasus/energymonitor.h"
|
||||
#include "pegasus/interface.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/items/biochips/biochipitem.h"
|
||||
#include "pegasus/items/inventory/inventoryitem.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
Interface *g_interface = nullptr;
|
||||
|
||||
Interface::Interface() : InputHandler(nullptr), _interfaceNotification(kInterfaceNotificationID, (NotificationManager *)g_vm),
|
||||
_currentItemSpot(kCurrentItemSpotID), _currentBiochipSpot(kCurrentBiochipSpotID),
|
||||
_background1(kInterface1ID), _background2(kInterface2ID), _background3(kInterface3ID),
|
||||
_background4(kInterface4ID), _datePicture(kDateID), _inventoryPush(kInventoryPushID),
|
||||
_inventoryLid(kInventoryLidID, kNoDisplayElement),
|
||||
_inventoryPanel(kNoDisplayElement, (InputHandler *)g_vm, (g_vm)->getItemsInventory()),
|
||||
_biochipPush(kBiochipPushID), _biochipLid(kBiochipLidID, kNoDisplayElement),
|
||||
_biochipPanel(kNoDisplayElement, (InputHandler *)g_vm, (g_vm)->getBiochipsInventory()) {
|
||||
g_energyMonitor = nullptr;
|
||||
_previousHandler = nullptr;
|
||||
_inventoryRaised = false;
|
||||
_biochipRaised = false;
|
||||
_playingEndMessage = false;
|
||||
g_interface = this;
|
||||
}
|
||||
|
||||
Interface::~Interface() {
|
||||
throwAwayInterface();
|
||||
g_interface = nullptr;
|
||||
}
|
||||
|
||||
void Interface::throwAwayInterface() {
|
||||
g_allHotspots.removeOneHotspot(kCurrentItemSpotID);
|
||||
g_allHotspots.removeOneHotspot(kCurrentBiochipSpotID);
|
||||
|
||||
throwAwayBackground();
|
||||
throwAwayDateMonitor();
|
||||
throwAwayEnergyMonitor();
|
||||
throwAwayAIArea();
|
||||
throwAwayCompass();
|
||||
throwAwayNotifications();
|
||||
throwAwayInventoryPanel();
|
||||
throwAwayBiochipPanel();
|
||||
}
|
||||
|
||||
void Interface::validateBackground() {
|
||||
if (!_background1.isSurfaceValid()) {
|
||||
_background1.initFromPICTFile("Images/Interface/3DInterface Left");
|
||||
_background2.initFromPICTFile("Images/Interface/3DInterface Top");
|
||||
_background3.initFromPICTFile("Images/Interface/3DInterface Right");
|
||||
_background4.initFromPICTFile("Images/Interface/3DInterface Bottom");
|
||||
|
||||
_background1.setDisplayOrder(kBackground1Order);
|
||||
_background1.startDisplaying();
|
||||
_background1.moveElementTo(kBackground1Left, kBackground1Top);
|
||||
|
||||
_background2.setDisplayOrder(kBackground2Order);
|
||||
_background2.startDisplaying();
|
||||
_background2.moveElementTo(kBackground2Left, kBackground2Top);
|
||||
|
||||
_background3.setDisplayOrder(kBackground2Order);
|
||||
_background3.startDisplaying();
|
||||
_background3.moveElementTo(kBackground3Left, kBackground3Top);
|
||||
|
||||
_background4.setDisplayOrder(kBackground4Order);
|
||||
_background4.startDisplaying();
|
||||
_background4.moveElementTo(kBackground4Left, kBackground4Top);
|
||||
|
||||
_background1.show();
|
||||
_background2.show();
|
||||
_background3.show();
|
||||
_background4.show();
|
||||
}
|
||||
}
|
||||
|
||||
void Interface::throwAwayBackground() {
|
||||
_background1.stopDisplaying();
|
||||
_background1.deallocateSurface();
|
||||
_background2.stopDisplaying();
|
||||
_background2.deallocateSurface();
|
||||
_background3.stopDisplaying();
|
||||
_background3.deallocateSurface();
|
||||
_background4.stopDisplaying();
|
||||
_background4.deallocateSurface();
|
||||
}
|
||||
|
||||
void Interface::validateDateMonitor() {
|
||||
if (!_datePicture.isSurfaceValid()) {
|
||||
_datePicture.setDisplayOrder(kDateOrder);
|
||||
_datePicture.startDisplaying();
|
||||
_datePicture.moveElementTo(kDateLeft, kDateTop);
|
||||
_datePicture.show();
|
||||
}
|
||||
}
|
||||
|
||||
void Interface::throwAwayDateMonitor() {
|
||||
_datePicture.stopDisplaying();
|
||||
_datePicture.deallocateSurface();
|
||||
}
|
||||
|
||||
void Interface::setDate(const uint16 dateResID) {
|
||||
validateDateMonitor();
|
||||
_datePicture.initFromPICTResource(g_vm->_resFork, dateResID);
|
||||
_datePicture.triggerRedraw();
|
||||
}
|
||||
|
||||
void Interface::validateCompass() {
|
||||
if (!g_compass) {
|
||||
new Compass();
|
||||
g_compass->initCompass();
|
||||
g_compass->setDisplayOrder(kCompassOrder);
|
||||
g_compass->startDisplaying();
|
||||
g_compass->moveElementTo(kCompassLeft, kCompassTop);
|
||||
g_compass->show();
|
||||
}
|
||||
}
|
||||
|
||||
void Interface::throwAwayCompass() {
|
||||
delete g_compass;
|
||||
}
|
||||
|
||||
void Interface::validateNotifications() {
|
||||
_interfaceNotification.notifyMe(this, kInterfaceNotificationFlags, kInterfaceNotificationFlags);
|
||||
_inventoryLidCallBack.setNotification(&_interfaceNotification);
|
||||
_inventoryPushCallBack.setNotification(&_interfaceNotification);
|
||||
_biochipLidCallBack.setNotification(&_interfaceNotification);
|
||||
_biochipPushCallBack.setNotification(&_interfaceNotification);
|
||||
}
|
||||
|
||||
void Interface::throwAwayNotifications() {
|
||||
_interfaceNotification.cancelNotification(this);
|
||||
}
|
||||
|
||||
void Interface::validateAIArea() {
|
||||
if (!g_AIArea) {
|
||||
new AIArea((InputHandler *)g_vm);
|
||||
if (g_AIArea)
|
||||
g_AIArea->initAIArea();
|
||||
}
|
||||
}
|
||||
|
||||
void Interface::throwAwayAIArea() {
|
||||
delete g_AIArea;
|
||||
}
|
||||
|
||||
void Interface::validateInventoryPanel() {
|
||||
if (!_inventoryPanel.isSurfaceValid()) {
|
||||
_inventoryPanel.initInventoryImage(&_inventoryPush);
|
||||
_inventoryPanel.moveElementTo(kInventoryPushLeft, kInventoryPushTop);
|
||||
_inventoryPush.setSlideDirection(kSlideUpMask);
|
||||
_inventoryPush.setInAndOutElements(&_inventoryPanel, nullptr);
|
||||
_inventoryPush.setDisplayOrder(kInventoryPushOrder);
|
||||
_inventoryPush.startDisplaying();
|
||||
|
||||
_inventoryLid.useFileName("Images/Lids/Inventory Lid Sequence");
|
||||
_inventoryLid.useTransparent(true);
|
||||
_inventoryLid.openFrameSequence();
|
||||
_inventoryLid.moveElementTo(kInventoryLidLeft, kInventoryLidTop);
|
||||
_inventoryLid.setDisplayOrder(kInventoryLidOrder);
|
||||
_inventoryLid.startDisplaying();
|
||||
|
||||
if (g_vm->isDVD()) {
|
||||
_inventoryOpenSound.initFromAIFFFile("Sounds/Items/Inventory Panel Open.aif");
|
||||
_inventoryCloseSound.initFromAIFFFile("Sounds/Items/Inventory Panel Close.aif");
|
||||
}
|
||||
|
||||
_inventoryPushCallBack.initCallBack(&_inventoryPush, kCallBackAtExtremes);
|
||||
_inventoryLidCallBack.initCallBack(&_inventoryLid, kCallBackAtExtremes);
|
||||
|
||||
_inventoryUp = false;
|
||||
_inventoryRaised = false;
|
||||
|
||||
Item *item = getCurrentInventoryItem();
|
||||
if (item)
|
||||
item->select();
|
||||
}
|
||||
}
|
||||
|
||||
void Interface::throwAwayInventoryPanel() {
|
||||
_inventoryPanel.stopDisplaying();
|
||||
_inventoryPanel.throwAwayInventoryImage();
|
||||
_inventoryPush.stopDisplaying();
|
||||
_inventoryLid.stopDisplaying();
|
||||
_inventoryLid.closeFrameSequence();
|
||||
_inventoryPushCallBack.releaseCallBack();
|
||||
_inventoryLidCallBack.releaseCallBack();
|
||||
|
||||
Item *item = getCurrentInventoryItem();
|
||||
if (item)
|
||||
item->deselect();
|
||||
|
||||
_inventoryUp = false;
|
||||
_inventoryRaised = false;
|
||||
}
|
||||
|
||||
void Interface::validateBiochipPanel() {
|
||||
if (!_biochipPanel.isSurfaceValid()) {
|
||||
_biochipPanel.initInventoryImage(&_biochipPush);
|
||||
_biochipPanel.moveElementTo(kBiochipPushLeft, kBiochipPushTop);
|
||||
_biochipPush.setSlideDirection(kSlideUpMask);
|
||||
_biochipPush.setInAndOutElements(&_biochipPanel, nullptr);
|
||||
_biochipPush.setDisplayOrder(kBiochipPushOrder);
|
||||
_biochipPush.startDisplaying();
|
||||
|
||||
_biochipLid.useFileName("Images/Lids/Biochip Lid Sequence");
|
||||
_biochipLid.useTransparent(true);
|
||||
_biochipLid.openFrameSequence();
|
||||
_biochipLid.moveElementTo(kBiochipLidLeft, kBiochipLidTop);
|
||||
_biochipLid.setDisplayOrder(kBiochipLidOrder);
|
||||
_biochipLid.startDisplaying();
|
||||
|
||||
if (g_vm->isDVD()) {
|
||||
_biochipOpenSound.initFromAIFFFile("Sounds/Items/Biochip Panel Open.aif");
|
||||
_biochipCloseSound.initFromAIFFFile("Sounds/Items/Biochip Panel Close.aif");
|
||||
}
|
||||
|
||||
_biochipPushCallBack.initCallBack(&_biochipPush, kCallBackAtExtremes);
|
||||
_biochipLidCallBack.initCallBack(&_biochipLid, kCallBackAtExtremes);
|
||||
|
||||
_biochipUp = false;
|
||||
_biochipRaised = false;
|
||||
|
||||
Item *item = getCurrentBiochip();
|
||||
if (item)
|
||||
item->select();
|
||||
}
|
||||
}
|
||||
|
||||
void Interface::throwAwayBiochipPanel() {
|
||||
_biochipPanel.stopDisplaying();
|
||||
_biochipPanel.throwAwayInventoryImage();
|
||||
_biochipPush.stopDisplaying();
|
||||
_biochipLid.stopDisplaying();
|
||||
_biochipLid.closeFrameSequence();
|
||||
_biochipPushCallBack.releaseCallBack();
|
||||
_biochipLidCallBack.releaseCallBack();
|
||||
|
||||
Item *item = getCurrentBiochip();
|
||||
if (item)
|
||||
item->deselect();
|
||||
|
||||
_biochipUp = false;
|
||||
_biochipRaised = false;
|
||||
}
|
||||
|
||||
void Interface::validateEnergyMonitor() {
|
||||
if (!g_energyMonitor)
|
||||
new EnergyMonitor();
|
||||
}
|
||||
|
||||
void Interface::throwAwayEnergyMonitor() {
|
||||
delete g_energyMonitor;
|
||||
}
|
||||
|
||||
void Interface::createInterface() {
|
||||
validateBackground();
|
||||
validateDateMonitor();
|
||||
validateCompass();
|
||||
validateNotifications();
|
||||
validateAIArea();
|
||||
validateBiochipPanel();
|
||||
validateInventoryPanel();
|
||||
validateEnergyMonitor();
|
||||
|
||||
if (!g_allHotspots.findHotspotByID(kCurrentItemSpotID)) {
|
||||
_currentItemSpot.setArea(Common::Rect(76, 334, 172, 430));
|
||||
_currentItemSpot.setHotspotFlags(kShellSpotFlag);
|
||||
_currentItemSpot.setActive();
|
||||
g_allHotspots.push_back(&_currentItemSpot);
|
||||
}
|
||||
|
||||
if (!g_allHotspots.findHotspotByID(kCurrentBiochipSpotID)) {
|
||||
_currentBiochipSpot.setArea(Common::Rect(364, 334, 460, 430));
|
||||
_currentBiochipSpot.setHotspotFlags(kShellSpotFlag);
|
||||
_currentBiochipSpot.setActive();
|
||||
g_allHotspots.push_back(&_currentBiochipSpot);
|
||||
}
|
||||
}
|
||||
|
||||
InventoryResult Interface::addInventoryItem(InventoryItem *item) {
|
||||
return _inventoryPanel.addInventoryItem(item);
|
||||
}
|
||||
|
||||
InventoryResult Interface::removeInventoryItem(InventoryItem *item) {
|
||||
return _inventoryPanel.removeInventoryItem(item);
|
||||
}
|
||||
|
||||
void Interface::removeAllItemsFromInventory() {
|
||||
_inventoryPanel.removeAllItems();
|
||||
}
|
||||
|
||||
InventoryItem *Interface::getCurrentInventoryItem() {
|
||||
return (InventoryItem *)_inventoryPanel.getCurrentItem();
|
||||
}
|
||||
|
||||
void Interface::setCurrentInventoryItem(InventoryItem *item) {
|
||||
setCurrentInventoryItemID(item->getObjectID());
|
||||
}
|
||||
|
||||
void Interface::setCurrentInventoryItemID(ItemID id) {
|
||||
_inventoryPanel.setCurrentItemID(id);
|
||||
}
|
||||
|
||||
InventoryResult Interface::addBiochip(BiochipItem *item) {
|
||||
return _biochipPanel.addInventoryItem(item);
|
||||
}
|
||||
|
||||
void Interface::removeAllItemsFromBiochips() {
|
||||
_biochipPanel.removeAllItems();
|
||||
}
|
||||
|
||||
BiochipItem *Interface::getCurrentBiochip() {
|
||||
return (BiochipItem *)_biochipPanel.getCurrentItem();
|
||||
}
|
||||
|
||||
void Interface::setCurrentBiochip(BiochipItem *item) {
|
||||
setCurrentBiochipID(item->getObjectID());
|
||||
}
|
||||
|
||||
void Interface::setCurrentBiochipID(ItemID id) {
|
||||
_biochipPanel.setCurrentItemID(id);
|
||||
}
|
||||
|
||||
void Interface::receiveNotification(Notification *notification, const NotificationFlags flags) {
|
||||
if (notification == &_interfaceNotification) {
|
||||
switch (flags) {
|
||||
case kInventoryLidOpenFlag:
|
||||
inventoryLidOpen(true);
|
||||
break;
|
||||
case kInventoryLidClosedFlag:
|
||||
inventoryLidClosed();
|
||||
break;
|
||||
case kInventoryDrawerUpFlag:
|
||||
inventoryDrawerUp();
|
||||
break;
|
||||
case kInventoryDrawerDownFlag:
|
||||
inventoryDrawerDown(true);
|
||||
break;
|
||||
case kBiochipLidOpenFlag:
|
||||
biochipLidOpen(true);
|
||||
break;
|
||||
case kBiochipLidClosedFlag:
|
||||
biochipLidClosed();
|
||||
break;
|
||||
case kBiochipDrawerUpFlag:
|
||||
biochipDrawerUp();
|
||||
break;
|
||||
case kBiochipDrawerDownFlag:
|
||||
biochipDrawerDown(true);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Interface::raiseInventoryDrawer(const bool doCallBacks) {
|
||||
if (!_biochipUp)
|
||||
_previousHandler = InputHandler::getCurrentHandler();
|
||||
|
||||
InputHandler::setInputHandler(&_inventoryPanel);
|
||||
_inventoryUp = true;
|
||||
_inventoryPanel.activateInventoryPicture();
|
||||
|
||||
if (doCallBacks) {
|
||||
_inventoryLidCallBack.setCallBackFlag(kInventoryLidOpenFlag);
|
||||
_inventoryLidCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
}
|
||||
|
||||
_inventoryLid.show();
|
||||
_inventoryPush.show();
|
||||
_inventoryLid.start();
|
||||
|
||||
if (g_vm->isDVD()) {
|
||||
_inventoryCloseSound.stopSound();
|
||||
_inventoryOpenSound.setVolume(g_vm->getSoundFXLevel());
|
||||
_inventoryOpenSound.playSound();
|
||||
}
|
||||
}
|
||||
|
||||
void Interface::playEndMessage() {
|
||||
raiseInventoryDrawerForMessage();
|
||||
_playingEndMessage = true;
|
||||
_inventoryPanel.playEndMessage(&_inventoryPush);
|
||||
lowerInventoryDrawerForMessage();
|
||||
_playingEndMessage = false;
|
||||
}
|
||||
|
||||
void Interface::raiseInventoryDrawerForMessage() {
|
||||
_inventoryPanel.disableLooping();
|
||||
|
||||
// The DVD version has a different image for the inventory
|
||||
// for the end message.
|
||||
if (g_vm->isDVD()) {
|
||||
_inventoryPanel.setCommPicture();
|
||||
_inventoryPanel.throwAwayInventoryImage();
|
||||
_inventoryPanel.initInventoryImage(&_inventoryPush);
|
||||
}
|
||||
|
||||
raiseInventoryDrawerSync();
|
||||
}
|
||||
|
||||
void Interface::lowerInventoryDrawerForMessage() {
|
||||
lowerInventoryDrawerSync();
|
||||
}
|
||||
|
||||
void Interface::inventoryLidOpen(const bool doCallBacks) {
|
||||
_inventoryLid.stop();
|
||||
|
||||
if (doCallBacks) {
|
||||
_inventoryPushCallBack.setCallBackFlag(kInventoryDrawerUpFlag);
|
||||
_inventoryPushCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
}
|
||||
|
||||
FaderMoveSpec moveSpec;
|
||||
moveSpec.makeTwoKnotFaderSpec(60, 0, 0, 15, 1000);
|
||||
_inventoryPush.startFader(moveSpec);
|
||||
}
|
||||
|
||||
void Interface::inventoryDrawerUp() {
|
||||
_inventoryPush.stopFader();
|
||||
_inventoryPanel.panelUp();
|
||||
_inventoryRaised = true;
|
||||
}
|
||||
|
||||
bool Interface::isInventoryUp() {
|
||||
return _inventoryRaised;
|
||||
}
|
||||
|
||||
bool Interface::isInventoryDown() {
|
||||
return !_inventoryUp;
|
||||
}
|
||||
|
||||
void Interface::lowerInventoryDrawer(const bool doCallBacks) {
|
||||
if (_inventoryRaised) {
|
||||
_inventoryRaised = false;
|
||||
|
||||
if (!_playingEndMessage)
|
||||
_inventoryPanel.deactivateInventoryPicture();
|
||||
|
||||
if (doCallBacks) {
|
||||
_inventoryPushCallBack.setCallBackFlag(kInventoryDrawerDownFlag);
|
||||
_inventoryPushCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
}
|
||||
|
||||
FaderMoveSpec moveSpec;
|
||||
moveSpec.makeTwoKnotFaderSpec(60, 0, 1000, 15, 0);
|
||||
_inventoryPush.startFader(moveSpec);
|
||||
|
||||
if (g_vm->isDVD()) {
|
||||
_inventoryOpenSound.stopSound();
|
||||
_inventoryCloseSound.setVolume(g_vm->getSoundFXLevel());
|
||||
_inventoryCloseSound.playSound();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Interface::inventoryDrawerDown(const bool doCallBacks) {
|
||||
_inventoryPush.stopFader();
|
||||
|
||||
if (doCallBacks) {
|
||||
_inventoryLidCallBack.setCallBackFlag(kInventoryLidClosedFlag);
|
||||
_inventoryLidCallBack.scheduleCallBack(kTriggerAtStart, 0, 0);
|
||||
}
|
||||
|
||||
_inventoryLid.setRate(-1);
|
||||
}
|
||||
|
||||
void Interface::inventoryLidClosed() {
|
||||
_inventoryLid.stop();
|
||||
|
||||
if (!_biochipUp)
|
||||
InputHandler::setInputHandler(_previousHandler);
|
||||
|
||||
_inventoryLid.hide();
|
||||
_inventoryPush.hide();
|
||||
_inventoryUp = false;
|
||||
}
|
||||
|
||||
void Interface::raiseBiochipDrawer(const bool doCallBacks) {
|
||||
if (!_inventoryUp)
|
||||
_previousHandler = InputHandler::getCurrentHandler();
|
||||
|
||||
InputHandler::setInputHandler(&_biochipPanel);
|
||||
_biochipUp = true;
|
||||
_biochipPanel.activateInventoryPicture();
|
||||
|
||||
if (doCallBacks) {
|
||||
_biochipLidCallBack.setCallBackFlag(kBiochipLidOpenFlag);
|
||||
_biochipLidCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
}
|
||||
|
||||
_biochipLid.show();
|
||||
_biochipPush.show();
|
||||
_biochipLid.start();
|
||||
|
||||
if (g_vm->isDVD()) {
|
||||
_biochipCloseSound.stopSound();
|
||||
_biochipOpenSound.setVolume(g_vm->getSoundFXLevel());
|
||||
_biochipOpenSound.playSound();
|
||||
}
|
||||
}
|
||||
|
||||
void Interface::biochipLidOpen(const bool doCallBacks) {
|
||||
_biochipLid.stop();
|
||||
|
||||
if (doCallBacks) {
|
||||
_biochipPushCallBack.setCallBackFlag(kBiochipDrawerUpFlag);
|
||||
_biochipPushCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
}
|
||||
|
||||
FaderMoveSpec moveSpec;
|
||||
moveSpec.makeTwoKnotFaderSpec(60, 0, 0, 9, 1000);
|
||||
_biochipPush.startFader(moveSpec);
|
||||
}
|
||||
|
||||
void Interface::biochipDrawerUp() {
|
||||
_biochipPush.stopFader();
|
||||
_biochipPanel.panelUp();
|
||||
_biochipRaised = true;
|
||||
}
|
||||
|
||||
void Interface::lowerBiochipDrawer(const bool doCallBacks) {
|
||||
if (_biochipRaised) {
|
||||
_biochipRaised = false;
|
||||
_biochipPanel.deactivateInventoryPicture();
|
||||
|
||||
if (doCallBacks) {
|
||||
_biochipPushCallBack.setCallBackFlag(kBiochipDrawerDownFlag);
|
||||
_biochipPushCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
}
|
||||
|
||||
FaderMoveSpec moveSpec;
|
||||
moveSpec.makeTwoKnotFaderSpec(60, 0, 1000, 9, 0);
|
||||
_biochipPush.startFader(moveSpec);
|
||||
|
||||
if (g_vm->isDVD()) {
|
||||
_biochipOpenSound.stopSound();
|
||||
_biochipCloseSound.setVolume(g_vm->getSoundFXLevel());
|
||||
_biochipCloseSound.playSound();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Interface::biochipDrawerDown(const bool doCallBacks) {
|
||||
_biochipPush.stopFader();
|
||||
|
||||
if (doCallBacks) {
|
||||
_biochipLidCallBack.setCallBackFlag(kBiochipLidClosedFlag);
|
||||
_biochipLidCallBack.scheduleCallBack(kTriggerAtStart, 0, 0);
|
||||
}
|
||||
|
||||
_biochipLid.setRate(-1);
|
||||
}
|
||||
|
||||
void Interface::biochipLidClosed() {
|
||||
_biochipLid.stop();
|
||||
|
||||
if (!_inventoryUp)
|
||||
InputHandler::setInputHandler(_previousHandler);
|
||||
|
||||
_biochipLid.hide();
|
||||
_biochipPush.hide();
|
||||
_biochipUp = false;
|
||||
}
|
||||
|
||||
void Interface::calibrateCompass() {
|
||||
uint32 currentValue = g_compass->getFaderValue();
|
||||
FaderMoveSpec compassMove;
|
||||
compassMove.makeTwoKnotFaderSpec(15, 0, currentValue, 30, currentValue + 360);
|
||||
|
||||
g_compass->startFader(compassMove);
|
||||
|
||||
while (g_compass->isFading()) {
|
||||
g_vm->refreshDisplay();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
|
||||
g_vm->refreshDisplay();
|
||||
g_compass->setFaderValue(currentValue);
|
||||
}
|
||||
|
||||
void Interface::calibrateEnergyBar() {
|
||||
g_energyMonitor->calibrateEnergyBar();
|
||||
}
|
||||
|
||||
void Interface::raiseInventoryDrawerSync() {
|
||||
raiseInventoryDrawer(false);
|
||||
|
||||
while (_inventoryLid.isRunning()) {
|
||||
InputDevice.pumpEvents();
|
||||
g_vm->checkCallBacks();
|
||||
g_vm->refreshDisplay();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
|
||||
g_vm->refreshDisplay();
|
||||
inventoryLidOpen(false);
|
||||
|
||||
while (_inventoryPush.isFading()) {
|
||||
InputDevice.pumpEvents();
|
||||
g_vm->checkCallBacks();
|
||||
g_vm->refreshDisplay();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
|
||||
g_vm->refreshDisplay();
|
||||
inventoryDrawerUp();
|
||||
}
|
||||
|
||||
void Interface::lowerInventoryDrawerSync() {
|
||||
lowerInventoryDrawer(false);
|
||||
|
||||
while (_inventoryPush.isFading()) {
|
||||
InputDevice.pumpEvents();
|
||||
g_vm->checkCallBacks();
|
||||
g_vm->refreshDisplay();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
|
||||
g_vm->refreshDisplay();
|
||||
inventoryDrawerDown(false);
|
||||
|
||||
while (_inventoryLid.isRunning()) {
|
||||
InputDevice.pumpEvents();
|
||||
g_vm->checkCallBacks();
|
||||
g_vm->refreshDisplay();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
|
||||
g_vm->refreshDisplay();
|
||||
inventoryLidClosed();
|
||||
}
|
||||
|
||||
void Interface::raiseBiochipDrawerSync() {
|
||||
raiseBiochipDrawer(false);
|
||||
|
||||
while (_biochipLid.isRunning()) {
|
||||
InputDevice.pumpEvents();
|
||||
g_vm->checkCallBacks();
|
||||
g_vm->refreshDisplay();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
|
||||
g_vm->refreshDisplay();
|
||||
biochipLidOpen(false);
|
||||
|
||||
while (_biochipPush.isFading()) {
|
||||
InputDevice.pumpEvents();
|
||||
g_vm->checkCallBacks();
|
||||
g_vm->refreshDisplay();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
|
||||
g_vm->refreshDisplay();
|
||||
biochipDrawerUp();
|
||||
}
|
||||
|
||||
void Interface::lowerBiochipDrawerSync() {
|
||||
lowerBiochipDrawer(false);
|
||||
|
||||
while (_biochipPush.isFading()) {
|
||||
InputDevice.pumpEvents();
|
||||
g_vm->checkCallBacks();
|
||||
g_vm->refreshDisplay();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
|
||||
g_vm->refreshDisplay();
|
||||
biochipDrawerDown(false);
|
||||
|
||||
while (_biochipLid.isRunning()) {
|
||||
InputDevice.pumpEvents();
|
||||
g_vm->checkCallBacks();
|
||||
g_vm->refreshDisplay();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
|
||||
g_vm->refreshDisplay();
|
||||
biochipLidClosed();
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
150
engines/pegasus/interface.h
Normal file
150
engines/pegasus/interface.h
Normal file
@@ -0,0 +1,150 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_INTERFACE_H
|
||||
#define PEGASUS_INTERFACE_H
|
||||
|
||||
#include "pegasus/hotspot.h"
|
||||
#include "pegasus/input.h"
|
||||
#include "pegasus/notification.h"
|
||||
#include "pegasus/sound.h"
|
||||
#include "pegasus/surface.h"
|
||||
#include "pegasus/transition.h"
|
||||
#include "pegasus/items/inventorypicture.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class BiochipItem;
|
||||
class InventoryItem;
|
||||
|
||||
class Interface : public InputHandler, public NotificationReceiver {
|
||||
public:
|
||||
Interface();
|
||||
~Interface() override;
|
||||
|
||||
void createInterface();
|
||||
|
||||
// Recalibration functions...
|
||||
void calibrateCompass();
|
||||
void calibrateEnergyBar();
|
||||
void raiseInventoryDrawerSync();
|
||||
void lowerInventoryDrawerSync();
|
||||
void raiseBiochipDrawerSync();
|
||||
void lowerBiochipDrawerSync();
|
||||
|
||||
void raiseInventoryDrawer(const bool doCallBacks = true);
|
||||
void raiseBiochipDrawer(const bool doCallBacks = true);
|
||||
void lowerInventoryDrawer(const bool doCallBacks = true);
|
||||
void lowerBiochipDrawer(const bool doCallBacks = true);
|
||||
|
||||
void raiseInventoryDrawerForMessage();
|
||||
void lowerInventoryDrawerForMessage();
|
||||
bool isInventoryUp();
|
||||
bool isInventoryDown();
|
||||
|
||||
InventoryResult addInventoryItem(InventoryItem *);
|
||||
InventoryResult removeInventoryItem(InventoryItem *);
|
||||
void removeAllItemsFromInventory();
|
||||
InventoryItem *getCurrentInventoryItem();
|
||||
void setCurrentInventoryItem(InventoryItem *);
|
||||
void setCurrentInventoryItemID(ItemID);
|
||||
InventoryResult addBiochip(BiochipItem *);
|
||||
void removeAllItemsFromBiochips();
|
||||
BiochipItem *getCurrentBiochip();
|
||||
void setCurrentBiochip(BiochipItem *);
|
||||
void setCurrentBiochipID(ItemID);
|
||||
|
||||
void setDate(const uint16);
|
||||
|
||||
void playEndMessage();
|
||||
|
||||
void throwAwayInterface();
|
||||
|
||||
protected:
|
||||
void validateBackground();
|
||||
void validateDateMonitor();
|
||||
void validateCompass();
|
||||
void validateNotifications();
|
||||
void validateAIArea();
|
||||
void validateInventoryPanel();
|
||||
void validateBiochipPanel();
|
||||
void validateEnergyMonitor();
|
||||
|
||||
void throwAwayBackground();
|
||||
void throwAwayDateMonitor();
|
||||
void throwAwayCompass();
|
||||
void throwAwayNotifications();
|
||||
void throwAwayAIArea();
|
||||
void throwAwayInventoryPanel();
|
||||
void throwAwayBiochipPanel();
|
||||
void throwAwayEnergyMonitor();
|
||||
|
||||
void receiveNotification(Notification *, const NotificationFlags) override;
|
||||
void inventoryLidOpen(const bool doCallBacks);
|
||||
void inventoryLidClosed();
|
||||
void inventoryDrawerUp();
|
||||
void inventoryDrawerDown(const bool doCallBacks);
|
||||
void biochipLidOpen(const bool doCallBacks);
|
||||
void biochipLidClosed();
|
||||
void biochipDrawerUp();
|
||||
void biochipDrawerDown(const bool doCallBacks);
|
||||
|
||||
Picture _background1;
|
||||
Picture _background2;
|
||||
Picture _background3;
|
||||
Picture _background4;
|
||||
|
||||
Picture _datePicture;
|
||||
|
||||
InputHandler *_previousHandler;
|
||||
|
||||
Push _inventoryPush;
|
||||
SpriteSequence _inventoryLid;
|
||||
NotificationCallBack _inventoryPushCallBack;
|
||||
NotificationCallBack _inventoryLidCallBack;
|
||||
InventoryItemsPicture _inventoryPanel;
|
||||
bool _inventoryUp, _inventoryRaised;
|
||||
Sound _inventoryOpenSound, _inventoryCloseSound;
|
||||
|
||||
Push _biochipPush;
|
||||
SpriteSequence _biochipLid;
|
||||
NotificationCallBack _biochipPushCallBack;
|
||||
NotificationCallBack _biochipLidCallBack;
|
||||
BiochipPicture _biochipPanel;
|
||||
bool _biochipUp, _biochipRaised;
|
||||
Sound _biochipOpenSound, _biochipCloseSound;
|
||||
|
||||
Hotspot _currentItemSpot;
|
||||
Hotspot _currentBiochipSpot;
|
||||
|
||||
Notification _interfaceNotification;
|
||||
|
||||
bool _playingEndMessage;
|
||||
};
|
||||
|
||||
extern Interface *g_interface;
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
90
engines/pegasus/items/autodragger.cpp
Normal file
90
engines/pegasus/items/autodragger.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/elements.h"
|
||||
#include "pegasus/items/autodragger.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
AutoDragger::AutoDragger() {
|
||||
_draggingElement = nullptr;
|
||||
_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 = nullptr;
|
||||
_startLocation = Common::Point();
|
||||
_stopLocation = Common::Point();
|
||||
_lastTime = 0;
|
||||
_done = true;
|
||||
}
|
||||
|
||||
bool AutoDragger::isDragging() {
|
||||
return isIdling();
|
||||
}
|
||||
|
||||
void AutoDragger::useIdleTime() {
|
||||
TimeValue thisTime = getTime();
|
||||
|
||||
if (thisTime != _lastTime) {
|
||||
int32 offsetX = (_stopLocation.x - _startLocation.x) * (int32)thisTime / (int32)getDuration();
|
||||
int32 offsetY = (_stopLocation.y - _startLocation.y) * (int32)thisTime / (int32)getDuration();
|
||||
_draggingElement->moveElementTo(_startLocation.x + offsetX, _startLocation.y + offsetY);
|
||||
_lastTime = thisTime;
|
||||
}
|
||||
|
||||
if (_done)
|
||||
stopDragging();
|
||||
}
|
||||
|
||||
void AutoDragger::callBack() {
|
||||
if (isIdling())
|
||||
_done = true;
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
55
engines/pegasus/items/autodragger.h
Normal file
55
engines/pegasus/items/autodragger.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#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();
|
||||
~AutoDragger() override {}
|
||||
|
||||
void autoDrag(DisplayElement *, const Common::Point &, const Common::Point &, TimeValue, TimeScale);
|
||||
bool isDragging();
|
||||
void stopDragging();
|
||||
|
||||
protected:
|
||||
void useIdleTime() override;
|
||||
void callBack() override;
|
||||
|
||||
DisplayElement *_draggingElement;
|
||||
Common::Point _startLocation, _stopLocation;
|
||||
TimeValue _lastTime;
|
||||
bool _done;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
271
engines/pegasus/items/biochips/aichip.cpp
Normal file
271
engines/pegasus/items/biochips/aichip.cpp
Normal file
@@ -0,0 +1,271 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/energymonitor.h"
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/items/biochips/aichip.h"
|
||||
#include "pegasus/neighborhood/neighborhood.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
// indexed by [number of hints][number of solves (0, 1, or 2)][which button to highlight]
|
||||
static const ItemState s_highlightState[4][3][7] = {
|
||||
{
|
||||
{kAI000, -1, -1, -1, -1, kAI005, kAI006},
|
||||
{kAI010, -1, -1, -1, -1, kAI015, kAI016},
|
||||
{kAI020, -1, -1, -1, kAI024, -1, -1}
|
||||
},
|
||||
{
|
||||
{kAI100, kAI101, -1, -1, -1, kAI105, kAI106},
|
||||
{kAI110, kAI111, -1, -1, -1, kAI115, kAI116},
|
||||
{kAI120, kAI121, -1, -1, kAI124, kAI125, kAI126}
|
||||
},
|
||||
{
|
||||
{kAI200, kAI201, kAI202, -1, -1, kAI205, kAI206},
|
||||
{kAI210, kAI211, kAI212, -1, -1, kAI215, kAI216},
|
||||
{kAI220, kAI221, kAI222, -1, kAI224, kAI225, kAI226}
|
||||
},
|
||||
{
|
||||
{kAI300, kAI301, kAI302, kAI303, -1, kAI305, kAI306},
|
||||
{kAI310, kAI311, kAI312, kAI313, -1, kAI315, kAI316},
|
||||
{kAI320, kAI321, kAI322, kAI323, kAI324, kAI325, kAI326}
|
||||
}
|
||||
};
|
||||
|
||||
AIChip *g_AIChip = nullptr;
|
||||
|
||||
AIChip::AIChip(const ItemID id, const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction) :
|
||||
BiochipItem(id, neighborhood, room, direction), _briefingSpot(kAIBriefingSpotID), _scanSpot(kAIScanSpotID),
|
||||
_hint1Spot(kAIHint1SpotID), _hint2Spot(kAIHint2SpotID), _hint3Spot(kAIHint3SpotID), _solveSpot(kAISolveSpotID) {
|
||||
_briefingSpot.setArea(Common::Rect(kAIMiddleAreaLeft + 10, kAIMiddleAreaTop + 27, kAIMiddleAreaLeft + 10 + 81, kAIMiddleAreaTop + 27 + 31));
|
||||
_briefingSpot.setHotspotFlags(kAIBiochipSpotFlag);
|
||||
g_allHotspots.push_back(&_briefingSpot);
|
||||
|
||||
_scanSpot.setArea(Common::Rect(kAIMiddleAreaLeft + 100, kAIMiddleAreaTop + 27, kAIMiddleAreaLeft + 100 + 81, kAIMiddleAreaTop + 27 + 31));
|
||||
_scanSpot.setHotspotFlags(kAIBiochipSpotFlag);
|
||||
g_allHotspots.push_back(&_scanSpot);
|
||||
|
||||
_hint1Spot.setArea(Common::Rect(kAIMiddleAreaLeft + 70, kAIMiddleAreaTop + 67, kAIMiddleAreaLeft + 70 + 21, kAIMiddleAreaTop + 67 + 21));
|
||||
_hint1Spot.setHotspotFlags(kAIBiochipSpotFlag);
|
||||
g_allHotspots.push_back(&_hint1Spot);
|
||||
|
||||
_hint2Spot.setArea(Common::Rect(kAIMiddleAreaLeft + 91, kAIMiddleAreaTop + 67, kAIMiddleAreaLeft + 91 + 20, kAIMiddleAreaTop + 67 + 21));
|
||||
_hint2Spot.setHotspotFlags(kAIBiochipSpotFlag);
|
||||
g_allHotspots.push_back(&_hint2Spot);
|
||||
|
||||
_hint3Spot.setArea(Common::Rect(kAIMiddleAreaLeft + 111, kAIMiddleAreaTop + 67, kAIMiddleAreaLeft + 111 + 20, kAIMiddleAreaTop + 67 + 21));
|
||||
_hint3Spot.setHotspotFlags(kAIBiochipSpotFlag);
|
||||
g_allHotspots.push_back(&_hint3Spot);
|
||||
|
||||
_solveSpot.setArea(Common::Rect(kAIMiddleAreaLeft + 131, kAIMiddleAreaTop + 67, kAIMiddleAreaLeft + 131 + 50, kAIMiddleAreaTop + 67 + 21));
|
||||
_solveSpot.setHotspotFlags(kAIBiochipSpotFlag);
|
||||
g_allHotspots.push_back(&_solveSpot);
|
||||
|
||||
_playingMovie = false;
|
||||
setItemState(kAI000);
|
||||
|
||||
g_AIChip = this;
|
||||
}
|
||||
|
||||
AIChip::~AIChip() {
|
||||
g_AIChip = nullptr;
|
||||
|
||||
g_allHotspots.removeOneHotspot(kAIBriefingSpotID);
|
||||
g_allHotspots.removeOneHotspot(kAIScanSpotID);
|
||||
g_allHotspots.removeOneHotspot(kAIHint1SpotID);
|
||||
g_allHotspots.removeOneHotspot(kAIHint2SpotID);
|
||||
g_allHotspots.removeOneHotspot(kAIHint3SpotID);
|
||||
g_allHotspots.removeOneHotspot(kAISolveSpotID);
|
||||
}
|
||||
|
||||
void AIChip::select() {
|
||||
BiochipItem::select();
|
||||
setUpAIChip();
|
||||
}
|
||||
|
||||
void AIChip::takeSharedArea() {
|
||||
setUpAIChip();
|
||||
}
|
||||
|
||||
void AIChip::setUpAIChip() {
|
||||
if (!_playingMovie) {
|
||||
uint numSolves;
|
||||
if (GameState.getWalkthroughMode()) {
|
||||
if (g_vm->canSolve())
|
||||
numSolves = 2;
|
||||
else
|
||||
numSolves = 1;
|
||||
} else {
|
||||
numSolves = 0;
|
||||
}
|
||||
|
||||
setItemState(s_highlightState[g_vm->getNumHints()][numSolves][0]);
|
||||
}
|
||||
}
|
||||
|
||||
// Only does something when there are hints or solves available.
|
||||
void AIChip::setUpAIChipRude() {
|
||||
if (!_playingMovie) {
|
||||
uint numSolves;
|
||||
if (GameState.getWalkthroughMode()) {
|
||||
if (g_vm->canSolve())
|
||||
numSolves = 2;
|
||||
else
|
||||
numSolves = 1;
|
||||
} else {
|
||||
numSolves = 0;
|
||||
}
|
||||
|
||||
uint numHints = g_vm->getNumHints();
|
||||
if (numSolves == 2 || numHints != 0)
|
||||
setItemState(s_highlightState[numHints][numSolves][0]);
|
||||
}
|
||||
}
|
||||
|
||||
void AIChip::activateAIHotspots() {
|
||||
_briefingSpot.setActive();
|
||||
_scanSpot.setActive();
|
||||
|
||||
switch (g_vm->getNumHints()) {
|
||||
case 3:
|
||||
_hint3Spot.setActive();
|
||||
// fall through
|
||||
case 2:
|
||||
_hint2Spot.setActive();
|
||||
// fall through
|
||||
case 1:
|
||||
_hint1Spot.setActive();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (GameState.getWalkthroughMode() && g_vm->canSolve())
|
||||
_solveSpot.setActive();
|
||||
}
|
||||
|
||||
void AIChip::showBriefingClicked() {
|
||||
_playingMovie = true;
|
||||
|
||||
uint numSolves;
|
||||
if (GameState.getWalkthroughMode()) {
|
||||
if (g_vm->canSolve())
|
||||
numSolves = 2;
|
||||
else
|
||||
numSolves = 1;
|
||||
} else {
|
||||
numSolves = 0;
|
||||
}
|
||||
|
||||
ItemState newState = s_highlightState[g_vm->getNumHints()][numSolves][kAIBriefingSpotID - kAIHint1SpotID + 1];
|
||||
if (newState != -1)
|
||||
setItemState(newState);
|
||||
}
|
||||
|
||||
void AIChip::showEnvScanClicked() {
|
||||
_playingMovie = true;
|
||||
|
||||
uint numSolves;
|
||||
if (GameState.getWalkthroughMode()) {
|
||||
if (g_vm->canSolve())
|
||||
numSolves = 2;
|
||||
else
|
||||
numSolves = 1;
|
||||
} else {
|
||||
numSolves = 0;
|
||||
}
|
||||
|
||||
ItemState newState = s_highlightState[g_vm->getNumHints()][numSolves][kAIScanSpotID - kAIHint1SpotID + 1];
|
||||
|
||||
if (newState != -1)
|
||||
setItemState(newState);
|
||||
}
|
||||
|
||||
void AIChip::clearClicked() {
|
||||
_playingMovie = false;
|
||||
setUpAIChip();
|
||||
}
|
||||
|
||||
void AIChip::clickInAIHotspot(HotSpotID id) {
|
||||
Common::Path movieName;
|
||||
|
||||
switch (id) {
|
||||
case kAIBriefingSpotID:
|
||||
movieName = g_vm->getBriefingMovie();
|
||||
break;
|
||||
case kAIScanSpotID:
|
||||
movieName = g_vm->getEnvScanMovie();
|
||||
break;
|
||||
case kAIHint1SpotID:
|
||||
movieName = g_vm->getHintMovie(1);
|
||||
break;
|
||||
case kAIHint2SpotID:
|
||||
movieName = g_vm->getHintMovie(2);
|
||||
break;
|
||||
case kAIHint3SpotID:
|
||||
movieName = g_vm->getHintMovie(3);
|
||||
break;
|
||||
case kAISolveSpotID:
|
||||
g_neighborhood->doSolve();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ItemState state = getItemState();
|
||||
|
||||
if (!movieName.empty()) {
|
||||
_playingMovie = true;
|
||||
|
||||
uint numSolves;
|
||||
if (GameState.getWalkthroughMode()) {
|
||||
if (g_vm->canSolve())
|
||||
numSolves = 2;
|
||||
else
|
||||
numSolves = 1;
|
||||
} else {
|
||||
numSolves = 0;
|
||||
}
|
||||
|
||||
ItemState newState = s_highlightState[g_vm->getNumHints()][numSolves][id - kAIHint1SpotID + 1];
|
||||
|
||||
if (newState != -1)
|
||||
setItemState(newState);
|
||||
|
||||
if (g_AIArea) {
|
||||
g_vm->prepareForAIHint(movieName);
|
||||
g_AIArea->playAIMovie(kRightAreaSignature, movieName, false, kHintInterruption);
|
||||
g_vm->cleanUpAfterAIHint(movieName);
|
||||
}
|
||||
|
||||
if (newState != -1)
|
||||
setItemState(state);
|
||||
|
||||
_playingMovie = false;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
68
engines/pegasus/items/biochips/aichip.h
Normal file
68
engines/pegasus/items/biochips/aichip.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_BIOCHIPS_AICHIP_H
|
||||
#define PEGASUS_ITEMS_BIOCHIPS_AICHIP_H
|
||||
|
||||
#include "pegasus/hotspot.h"
|
||||
#include "pegasus/items/biochips/biochipitem.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class AIChip : public BiochipItem {
|
||||
public:
|
||||
AIChip(const ItemID, const NeighborhoodID, const RoomID, const DirectionConstant);
|
||||
~AIChip() override;
|
||||
|
||||
void select() override;
|
||||
|
||||
void setUpAIChip();
|
||||
|
||||
// Called to set up the AI chip when the AI chip is the current chip but does not
|
||||
// own the center area.
|
||||
void setUpAIChipRude();
|
||||
void activateAIHotspots();
|
||||
void clickInAIHotspot(HotSpotID);
|
||||
|
||||
void takeSharedArea() override;
|
||||
|
||||
void showBriefingClicked();
|
||||
void showEnvScanClicked();
|
||||
void clearClicked();
|
||||
|
||||
protected:
|
||||
Hotspot _briefingSpot;
|
||||
Hotspot _scanSpot;
|
||||
Hotspot _hint1Spot;
|
||||
Hotspot _hint2Spot;
|
||||
Hotspot _hint3Spot;
|
||||
Hotspot _solveSpot;
|
||||
bool _playingMovie;
|
||||
};
|
||||
|
||||
extern AIChip *g_AIChip;
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
270
engines/pegasus/items/biochips/arthurchip.cpp
Normal file
270
engines/pegasus/items/biochips/arthurchip.cpp
Normal file
@@ -0,0 +1,270 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/items/biochips/arthurchip.h"
|
||||
|
||||
namespace Common {
|
||||
DECLARE_SINGLETON(Pegasus::ArthurManager);
|
||||
}
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
static const char *kArthurWisdomMovies[] = {
|
||||
"Images/AI/Globals/XGLOBA01",
|
||||
"Images/AI/Globals/XGLOBA03",
|
||||
"Images/AI/Globals/XGLOBA06",
|
||||
"Images/AI/Globals/XGLOBA07",
|
||||
"Images/AI/Globals/XGLOBA09",
|
||||
"Images/AI/Globals/XGLOBA17",
|
||||
"Images/AI/Globals/XGLOBA18",
|
||||
"Images/AI/Globals/XGLOBA25",
|
||||
"Images/AI/Globals/XGLOBA26",
|
||||
"Images/AI/Globals/XGLOBA27",
|
||||
"Images/AI/Globals/XGLOBA28",
|
||||
"Images/AI/Globals/XGLOBA30",
|
||||
"Images/AI/Globals/XGLOBA34",
|
||||
"Images/AI/Globals/XGLOBA35",
|
||||
"Images/AI/Globals/XGLOBA43",
|
||||
"Images/AI/Globals/XGLOBA50",
|
||||
"Images/AI/Globals/XGLOBA56",
|
||||
"Images/AI/Globals/XGLOBA59",
|
||||
"Images/AI/Globals/XGLOBA63",
|
||||
"Images/AI/Globals/XGLOBB10",
|
||||
"Images/AI/Globals/XGLOBB11",
|
||||
"Images/AI/Globals/XGLOBB12",
|
||||
"Images/AI/Globals/XGLOBB13",
|
||||
"Images/AI/Globals/XGLOBB14",
|
||||
"Images/AI/Globals/XGLOBB15",
|
||||
"Images/AI/Globals/XGLOBB16",
|
||||
"Images/AI/Globals/XGLOBB17",
|
||||
"Images/AI/Globals/XGLOBB18",
|
||||
"Images/AI/Globals/XGLOBB19",
|
||||
"Images/AI/Globals/XGLOBB20",
|
||||
"Images/AI/Globals/XGLOBB21",
|
||||
"Images/AI/Globals/XGLOBB22",
|
||||
"Images/AI/Globals/XGLOBB23",
|
||||
"Images/AI/Globals/XGLOBB24",
|
||||
"Images/AI/Globals/XGLOBB25",
|
||||
"Images/AI/Globals/XGLOBB26",
|
||||
"Images/AI/Globals/XGLOBB27",
|
||||
"Images/AI/Globals/XGLOBB28",
|
||||
"Images/AI/Globals/XGLOBB29",
|
||||
"Images/AI/Globals/XGLOBB30",
|
||||
"Images/AI/Globals/XGLOBB31",
|
||||
"Images/AI/Globals/XGLOBB32",
|
||||
"Images/AI/Globals/XGLOBB33",
|
||||
"Images/AI/Globals/XGLOBB34",
|
||||
"Images/AI/Globals/XGLOBB35",
|
||||
"Images/AI/Globals/XGLOBB36",
|
||||
"Images/AI/Globals/XGLOBB37",
|
||||
"Images/AI/Globals/XGLOBB38",
|
||||
"Images/AI/Globals/XGLOBB39",
|
||||
"Images/AI/Globals/XGLOBB43",
|
||||
"Images/AI/Globals/XGLOBB44",
|
||||
"Images/AI/Globals/XGLOBA62"
|
||||
};
|
||||
|
||||
ArthurChip *g_arthurChip = nullptr;
|
||||
|
||||
ArthurChip::ArthurChip(const ItemID id, const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction) :
|
||||
BiochipItem(id, neighborhood, room, direction), _arthurWisdomHotspot(kArthurWisdomSpotID),
|
||||
_chattyArthurHotspot(kChattyArthurSpotID), _chattyAIHotspot(kChattyAISpotID),
|
||||
_arthurHeadHotspot(kArthurHeadSpotID) {
|
||||
_lastArthurMovie = "";
|
||||
|
||||
_arthurWisdomHotspot.setArea(Common::Rect(kAIMiddleAreaLeft + 20, kAIMiddleAreaTop + 27, kAIMiddleAreaLeft + 20 + 161, kAIMiddleAreaTop + 27 + 30));
|
||||
_arthurWisdomHotspot.setHotspotFlags(kArthurBiochipSpotFlag);
|
||||
g_allHotspots.push_back(&_arthurWisdomHotspot);
|
||||
|
||||
_chattyArthurHotspot.setArea(Common::Rect(kAIMiddleAreaLeft + 100, kAIMiddleAreaTop + 67, kAIMiddleAreaLeft + 100 + 20, kAIMiddleAreaTop + 67 + 20));
|
||||
_chattyArthurHotspot.setHotspotFlags(kArthurBiochipSpotFlag);
|
||||
g_allHotspots.push_back(&_chattyArthurHotspot);
|
||||
|
||||
_chattyAIHotspot.setArea(Common::Rect(kAIMiddleAreaLeft + 130, kAIMiddleAreaTop + 67, kAIMiddleAreaLeft + 130 + 20, kAIMiddleAreaTop + 67 + 20));
|
||||
_chattyAIHotspot.setHotspotFlags(kArthurBiochipSpotFlag);
|
||||
g_allHotspots.push_back(&_chattyAIHotspot);
|
||||
|
||||
_arthurHeadHotspot.setArea(Common::Rect(kAIRightAreaLeft, kAIRightAreaTop, kAIRightAreaLeft + kAIRightAreaWidth, kAIRightAreaTop + kAIRightAreaHeight));
|
||||
_arthurHeadHotspot.setHotspotFlags(kArthurBiochipSpotFlag);
|
||||
g_allHotspots.push_back(&_arthurHeadHotspot);
|
||||
|
||||
setItemState(kArthur000);
|
||||
|
||||
g_arthurChip = this;
|
||||
}
|
||||
|
||||
ArthurChip::~ArthurChip() {
|
||||
g_arthurChip = nullptr;
|
||||
|
||||
g_allHotspots.removeOneHotspot(kArthurWisdomSpotID);
|
||||
g_allHotspots.removeOneHotspot(kChattyArthurSpotID);
|
||||
g_allHotspots.removeOneHotspot(kChattyAISpotID);
|
||||
g_allHotspots.removeOneHotspot(kArthurHeadSpotID);
|
||||
}
|
||||
|
||||
void ArthurChip::select() {
|
||||
BiochipItem::select();
|
||||
setUpArthurChip();
|
||||
}
|
||||
|
||||
void ArthurChip::setUpArthurChip() {
|
||||
ItemState state = getItemState();
|
||||
|
||||
if (g_vm->isChattyArthur()) {
|
||||
if (g_AIArea && g_vm->isChattyAI()) {
|
||||
if (state != kArthur002)
|
||||
setItemState(kArthur000);
|
||||
} else if (state != kArthur102) {
|
||||
setItemState(kArthur100);
|
||||
}
|
||||
} else {
|
||||
if (g_AIArea && g_vm->isChattyAI()) {
|
||||
if (state != kArthur012)
|
||||
setItemState(kArthur010);
|
||||
} else if (state != kArthur112) {
|
||||
setItemState(kArthur110);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ArthurChip::activateArthurHotspots() {
|
||||
_arthurWisdomHotspot.setActive();
|
||||
_chattyArthurHotspot.setActive();
|
||||
_chattyAIHotspot.setActive();
|
||||
_arthurHeadHotspot.setActive();
|
||||
}
|
||||
|
||||
void ArthurChip::clickInArthurHotspot(HotSpotID id) {
|
||||
ItemState state, newState;
|
||||
|
||||
if (id == kArthurHeadSpotID) {
|
||||
if (_lastArthurMovie != "")
|
||||
playArthurMovie(_lastArthurMovie);
|
||||
return;
|
||||
}
|
||||
|
||||
newState = state = getItemState();
|
||||
switch (state) {
|
||||
case kArthur000:
|
||||
switch (id) {
|
||||
case kArthurWisdomSpotID:
|
||||
newState = kArthur002;
|
||||
break;
|
||||
case kChattyArthurSpotID:
|
||||
newState = kArthur010;
|
||||
break;
|
||||
case kChattyAISpotID:
|
||||
newState = kArthur100;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case kArthur010:
|
||||
switch (id) {
|
||||
case kArthurWisdomSpotID:
|
||||
newState = kArthur012;
|
||||
break;
|
||||
case kChattyArthurSpotID:
|
||||
newState = kArthur000;
|
||||
break;
|
||||
case kChattyAISpotID:
|
||||
newState = kArthur110;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case kArthur100:
|
||||
switch (id) {
|
||||
case kArthurWisdomSpotID:
|
||||
newState = kArthur102;
|
||||
break;
|
||||
case kChattyArthurSpotID:
|
||||
newState = kArthur110;
|
||||
break;
|
||||
case kChattyAISpotID:
|
||||
newState = kArthur010;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case kArthur110:
|
||||
switch (id) {
|
||||
case kArthurWisdomSpotID:
|
||||
newState = kArthur112;
|
||||
break;
|
||||
case kChattyArthurSpotID:
|
||||
newState = kArthur100;
|
||||
break;
|
||||
case kChattyAISpotID:
|
||||
newState = kArthur010;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
setItemState(newState);
|
||||
switch (id) {
|
||||
case kArthurWisdomSpotID:
|
||||
playArthurMovie(kArthurWisdomMovies[g_vm->getRandomNumber((
|
||||
sizeof(kArthurWisdomMovies) / sizeof(const char *)) - 1)]);
|
||||
break;
|
||||
case kChattyArthurSpotID:
|
||||
g_vm->setChattyArthur(!g_vm->isChattyArthur());
|
||||
break;
|
||||
case kChattyAISpotID:
|
||||
g_vm->setChattyAI(!g_vm->isChattyAI());
|
||||
break;
|
||||
}
|
||||
|
||||
setItemState(state);
|
||||
}
|
||||
|
||||
void ArthurChip::playArthurMovie(const Common::Path &movieName) {
|
||||
if (g_AIArea) {
|
||||
g_AIArea->playAIMovie(kRightAreaSignature, movieName, false, kHintInterruption);
|
||||
if (movieName != "Images/AI/Globals/XGLOB00" &&
|
||||
movieName != "Images/AI/Globals/XGLOB01" &&
|
||||
movieName != "Images/AI/Globals/XGLOBAA0" &&
|
||||
movieName != "Images/AI/Globals/XGLOBAA1" &&
|
||||
movieName != "Images/AI/Globals/XGLOBAA2")
|
||||
_lastArthurMovie = movieName;
|
||||
}
|
||||
}
|
||||
|
||||
bool ArthurChip::playArthurMovieForEvent(const Common::Path &movieName, ArthurEvent event) {
|
||||
if (g_vm->isDVD() && g_vm->playerHasItemID(kArthurBiochip) &&
|
||||
g_vm->isChattyArthur() && !Arthur._arthurFlags.getFlag(event)) {
|
||||
Arthur._arthurFlags.setFlag(event, true);
|
||||
playArthurMovie(movieName);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ArthurManager::resetArthurState() {
|
||||
bool savedGameFlag = _arthurFlags.getFlag(kArthurLoadedSavedGame);
|
||||
_arthurFlags.clearAllFlags();
|
||||
_arthurFlags.setFlag(kArthurLoadedSavedGame, savedGameFlag);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
221
engines/pegasus/items/biochips/arthurchip.h
Normal file
221
engines/pegasus/items/biochips/arthurchip.h
Normal file
@@ -0,0 +1,221 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_BIOCHIPS_ARTHURCHIP_H
|
||||
#define PEGASUS_ITEMS_BIOCHIPS_ARTHURCHIP_H
|
||||
|
||||
#include "pegasus/hotspot.h"
|
||||
#include "pegasus/util.h"
|
||||
#include "pegasus/items/biochips/biochipitem.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
enum ArthurEvent {
|
||||
kArthurLoadedSavedGame,
|
||||
kArthurAttemptedLockedDoor,
|
||||
kArthurAttemptedLockedDoorAgain,
|
||||
kArthurDestroyedInventoryItem,
|
||||
kArthurDisabledAI,
|
||||
|
||||
kArthurCaldoriaFinishedJoyride,
|
||||
kArthurCaldoriaSelectedStickyBuns,
|
||||
kArthurCaldoriaCreatedCornbread,
|
||||
kArthurCaldoriaDrankOJ,
|
||||
kArthurCaldoriaZoomedToLaundry,
|
||||
kArthurCaldoriaReachedToilet,
|
||||
kArthurCaldoriaReadPaper,
|
||||
kArthurCaldoriaChoseAgencyHairStyle,
|
||||
kArthurCaldoriaSawVacantApartment,
|
||||
kArthurCaldoriaLookThroughTelescope,
|
||||
kArthurCaldoriaRoofDoor,
|
||||
kArthurCaldoriaUsedCardBomb,
|
||||
kArthurCaldoriaBlownDoor,
|
||||
kArthurCaldoriaSawVoiceAnalysis,
|
||||
kArthurCaldoriaStunningSinclair,
|
||||
kArthurCaldoriaSeeRoofBomb,
|
||||
kArthurCaldoriaDisarmedNuke,
|
||||
|
||||
kArthurTSAEnteredCave,
|
||||
kArthurTSASawAgent3,
|
||||
kArthurTSASawBust,
|
||||
kArthurTSAReachedJunction,
|
||||
kArthurTSAClickedRobot1,
|
||||
kArthurTSAClickedRobot2,
|
||||
kArthurTSAOpenTBPMonitor,
|
||||
kArthurTSASawJourneymanKey,
|
||||
kArthurTSASawBiochips,
|
||||
kArthurTSAUsedPegasus,
|
||||
kArthurTSAConfinedByBaldwin,
|
||||
kArthurTSARedirectedRobots,
|
||||
kArthurTSAUsedTurbolift,
|
||||
kArthurTSASawFirstOpMemMovie,
|
||||
kArthurTSAInPegasusNoVideo,
|
||||
kArthurTSASawBaldwinSayGo,
|
||||
kArthurTSALeaving,
|
||||
|
||||
kArthurGoToPrehistoric,
|
||||
|
||||
kArthurPrehistoricReachedJunction,
|
||||
kArthurPrehistoricSawBreaker,
|
||||
kArthurPrehistoricBreakerThrown,
|
||||
kArthurPrehistoricAtCliffEdge,
|
||||
kArthurPrehistoricSawEggs,
|
||||
kArthurPrehistoricZoomedToVault,
|
||||
kArthurPrehistoricAttemptedBridge,
|
||||
kArthurPrehistoricExtendedBridge,
|
||||
kArthurPrehistoricCrossedBridge,
|
||||
kArthurPrehistoricUnlockedVault,
|
||||
|
||||
kArthurMarsReadyForKiosk,
|
||||
kArthurMarsLookedAtGuards,
|
||||
kArthurMarsZoomedToKeyCard,
|
||||
kArthurMarsTurnedOnTransport,
|
||||
kArthurMarsCantFillMask,
|
||||
kArthurMarsSawWelcomeVideos,
|
||||
kArthurMarsRobotThrownPlayerWithMask,
|
||||
kArthurMarsLeftPodNoCrowBar,
|
||||
kArthurMarsLookAtEmptyTracks,
|
||||
kArthurMarsEnteredReactor,
|
||||
kArthurMarsSawLockedPanel,
|
||||
kArthurMarsSawLockedPanelNoNitrogen,
|
||||
kArthurMarsUsedLiquidNitrogen,
|
||||
kArthurMarsFoundCardBomb,
|
||||
kArthurMarsSolvedReactorGame,
|
||||
kArthurMarsDeactivatedCardBomb,
|
||||
kArthurMarsExitedReactorWithCardBomb,
|
||||
kArthurMarsInAirlockNoOxygen,
|
||||
kArthurMarsMazeReachedJunction,
|
||||
kArthurMarsOxygen50Warning,
|
||||
kArthurMarsOxygen25Warning,
|
||||
kArthurMarsOxygen5Warning,
|
||||
kArthurMarsFoundBuckets,
|
||||
kArthurMarsApproachedBuckets,
|
||||
kArthurMarsEnteredGearRoom,
|
||||
kArthurMarsLookAtGears,
|
||||
kArthurMarsExitedGearRoom,
|
||||
kArthurMarsFoundNoShuttlePresent,
|
||||
kArthurMarsEnteredShuttle,
|
||||
kArthurMarsFoundDeadRobot,
|
||||
kArthurMarsRobotHeadOpen,
|
||||
|
||||
kArthurWSCRemovedDart,
|
||||
kArthurWSCPoisonedDuringGame,
|
||||
kArthurWSCFailedMolecule,
|
||||
kArthurWSCDesignedAntidote,
|
||||
kArthurWSCSawAresHologram,
|
||||
kArthurWSCLookAtMorphExperiment,
|
||||
kArthurWSCStartMorphExperiment,
|
||||
kArthurWSCSawMorphExperiment,
|
||||
kArthurWSCLeftLabNoKeyOrCanisters,
|
||||
kArthurWSCAtOppositeDoor,
|
||||
kArthurWSCReadyForMap,
|
||||
kArthurWSCAttemptedLockedDoor,
|
||||
kArthurWSCSawSinclairDoor,
|
||||
kArthurWSCSawSinclairDoorNoKey,
|
||||
kArthurWSCAttemptedSinclairDoorNoKey,
|
||||
kArthurWSCZoomedToSnake,
|
||||
kArthurWSCActivatedComputer,
|
||||
kArthurWSCZoomedToSinclairMessages,
|
||||
kArthurWSCPlayedEasterEggMessage,
|
||||
kArthurWSCGotMachineGun,
|
||||
kArthurWSCSeenNerd,
|
||||
kArthurWSCSawBrokenDoor,
|
||||
kArthurWSCSawBrokenDoorNoCrowBar,
|
||||
kArthurWSCUsedCrowBar,
|
||||
kArthurWSCDidPlasmaDodge,
|
||||
kArthurWSCEnteredAuditorium,
|
||||
kArthurWSCSawSinclairLecture,
|
||||
kArthurWSCEnteredPassage,
|
||||
kArthurWSCInPassage,
|
||||
kArthurWSCExitedPassage,
|
||||
kArthurWSCSawCatwalkDoor,
|
||||
kArthurWSCRobotHeadOpen,
|
||||
|
||||
kArthurNoradAtSecurityMonitor,
|
||||
kArthurNoradSawFillingStation,
|
||||
kArthurNoradSawIntakeWarning,
|
||||
kArthurNoradDidntFillCanisters,
|
||||
kArthurNoradSawUnconsciousOperator,
|
||||
kArthurNoradAttemptedLockedDoor,
|
||||
kArthurNoradAttemptedLockedDoorAgain,
|
||||
kArthurNoradReachedPressureDoor,
|
||||
kArthurNoradSawSubMessage,
|
||||
kArthurNoradSawClawMonitor,
|
||||
kArthurNoradPlayedWithClaw,
|
||||
kArthurNoradEnteredSub,
|
||||
kArthurNoradExitedSub,
|
||||
kArthurNoradApproachedDamagedDoor,
|
||||
kArthurNoradAtRetScanNoBiochip,
|
||||
kArthurNoradStartGlobeGame,
|
||||
kArthurNoradSelectedIncorrectSilo,
|
||||
kArthurNoradFinishedGlobeGame,
|
||||
kArthurNoradThreatenedByRobot,
|
||||
kArthurNoradBeatRobotWithClaw,
|
||||
kArthurNoradRobotHeadOpen,
|
||||
|
||||
kNumArthurFlags
|
||||
};
|
||||
|
||||
class ArthurChip : public BiochipItem {
|
||||
public:
|
||||
ArthurChip(const ItemID, const NeighborhoodID, const RoomID, const DirectionConstant);
|
||||
virtual ~ArthurChip();
|
||||
|
||||
void select();
|
||||
|
||||
void setUpArthurChip();
|
||||
void activateArthurHotspots();
|
||||
void clickInArthurHotspot(HotSpotID);
|
||||
void playArthurMovie(const Common::Path &);
|
||||
bool playArthurMovieForEvent(const Common::Path &, ArthurEvent event);
|
||||
|
||||
protected:
|
||||
Hotspot _arthurWisdomHotspot;
|
||||
Hotspot _chattyArthurHotspot;
|
||||
Hotspot _chattyAIHotspot;
|
||||
Hotspot _arthurHeadHotspot;
|
||||
Common::Path _lastArthurMovie;
|
||||
};
|
||||
|
||||
class ArthurManager : public Common::Singleton<ArthurManager> {
|
||||
public:
|
||||
ArthurManager() { resetArthurState(); }
|
||||
|
||||
void resetArthurState();
|
||||
|
||||
protected:
|
||||
friend class Common::Singleton<SingletonBaseType>;
|
||||
friend class ArthurChip;
|
||||
|
||||
private:
|
||||
FlagsArray<byte, kNumArthurFlags> _arthurFlags;
|
||||
};
|
||||
|
||||
extern ArthurChip *g_arthurChip;
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#define Arthur (::Pegasus::ArthurManager::instance())
|
||||
|
||||
#endif
|
||||
92
engines/pegasus/items/biochips/biochipitem.cpp
Normal file
92
engines/pegasus/items/biochips/biochipitem.cpp
Normal file
@@ -0,0 +1,92 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "common/stream.h"
|
||||
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/items/biochips/biochipitem.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
BiochipItem::BiochipItem(const ItemID id, const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction) :
|
||||
Item(id, neighborhood, room, direction) {
|
||||
|
||||
Common::SeekableReadStream *biochipInfo = g_vm->_resFork->getResource(MKTAG('B', 'i', 'o', 'I'), kItemBaseResID + id);
|
||||
if (biochipInfo) {
|
||||
_biochipInfoPanelTime = biochipInfo->readUint32BE();
|
||||
delete biochipInfo;
|
||||
} else {
|
||||
_biochipInfoPanelTime = 0;
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *rightInfo = g_vm->_resFork->getResource(MKTAG('R', 'g', 'h', 't'), kItemBaseResID + id);
|
||||
if (!rightInfo)
|
||||
error("Could not find right info for biochip %d", id);
|
||||
|
||||
_rightAreaInfo = readItemState(rightInfo);
|
||||
delete rightInfo;
|
||||
|
||||
setItemState(kNormalItem);
|
||||
}
|
||||
|
||||
BiochipItem::~BiochipItem() {
|
||||
delete[] _rightAreaInfo.entries;
|
||||
}
|
||||
|
||||
ItemType BiochipItem::getItemType() {
|
||||
return kBiochipItemType;
|
||||
}
|
||||
|
||||
TimeValue BiochipItem::getRightAreaTime() const {
|
||||
if (!_rightAreaInfo.entries)
|
||||
return 0xffffffff;
|
||||
|
||||
TimeValue time;
|
||||
ItemState state;
|
||||
|
||||
findItemStateEntryByState(_rightAreaInfo, _itemState, time);
|
||||
if (time == 0xffffffff)
|
||||
getItemStateEntry(_rightAreaInfo, 0, state, time);
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
// Must affect images in right area.
|
||||
void BiochipItem::select() {
|
||||
Item::select();
|
||||
|
||||
if (g_AIArea)
|
||||
g_AIArea->setAIAreaToTime(kBiochipSignature, kRightAreaSignature, getRightAreaTime());
|
||||
}
|
||||
|
||||
void BiochipItem::deselect() {
|
||||
Item::deselect();
|
||||
|
||||
if (g_AIArea)
|
||||
g_AIArea->setAIAreaToTime(kBiochipSignature, kRightAreaSignature, 0xffffffff);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
53
engines/pegasus/items/biochips/biochipitem.h
Normal file
53
engines/pegasus/items/biochips/biochipitem.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_BIOCHIPS_BIOCHIPITEM_H
|
||||
#define PEGASUS_ITEMS_BIOCHIPS_BIOCHIPITEM_H
|
||||
|
||||
#include "pegasus/items/item.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class BiochipItem : public Item {
|
||||
public:
|
||||
BiochipItem(const ItemID, const NeighborhoodID, const RoomID, const DirectionConstant);
|
||||
~BiochipItem() override;
|
||||
|
||||
ItemType getItemType() override;
|
||||
|
||||
TimeValue getPanelTime() const { return _biochipInfoPanelTime; }
|
||||
TimeValue getRightAreaTime() const;
|
||||
|
||||
// Must affect images in right area.
|
||||
void select() override;
|
||||
void deselect() override;
|
||||
|
||||
protected:
|
||||
TimeValue _biochipInfoPanelTime;
|
||||
ItemStateInfo _rightAreaInfo;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
105
engines/pegasus/items/biochips/mapchip.cpp
Normal file
105
engines/pegasus/items/biochips/mapchip.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/items/biochips/mapchip.h"
|
||||
#include "pegasus/neighborhood/neighborhood.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
MapChip *g_map = nullptr;
|
||||
|
||||
MapChip::MapChip(const ItemID id, const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction) :
|
||||
BiochipItem(id, neighborhood, room, direction) {
|
||||
g_map = this;
|
||||
setItemState(kMapUnavailable);
|
||||
}
|
||||
|
||||
MapChip::~MapChip() {
|
||||
g_map = nullptr;
|
||||
}
|
||||
|
||||
void MapChip::writeToStream(Common::WriteStream *stream) {
|
||||
return _image.writeToStream(stream);
|
||||
}
|
||||
|
||||
void MapChip::readFromStream(Common::ReadStream *stream) {
|
||||
return _image.readFromStream(stream);
|
||||
}
|
||||
|
||||
void MapChip::select() {
|
||||
BiochipItem::select();
|
||||
moveToMapLocation(GameState.getCurrentNeighborhood(), GameState.getCurrentRoom(), GameState.getCurrentDirection());
|
||||
_image.show();
|
||||
}
|
||||
|
||||
void MapChip::takeSharedArea() {
|
||||
_image.show();
|
||||
}
|
||||
|
||||
void MapChip::giveUpSharedArea() {
|
||||
_image.hide();
|
||||
}
|
||||
|
||||
void MapChip::deselect() {
|
||||
BiochipItem::deselect();
|
||||
_image.unloadImage();
|
||||
}
|
||||
|
||||
void MapChip::moveToMapLocation(const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant dir) {
|
||||
AirQuality airQuality;
|
||||
|
||||
if (g_neighborhood)
|
||||
airQuality = g_neighborhood->getAirQuality(room);
|
||||
else
|
||||
airQuality = kAirQualityGood;
|
||||
|
||||
switch (neighborhood) {
|
||||
case kMarsID:
|
||||
if (airQuality == kAirQualityVacuum) {
|
||||
if (room >= kMars35 && room <= kMars39) {
|
||||
setItemState(kMapEngaged);
|
||||
if (isSelected() && g_AIArea && g_AIArea->getMiddleAreaOwner() == kBiochipSignature)
|
||||
_image.loadGearRoomIfNecessary();
|
||||
} else {
|
||||
setItemState(kMapEngaged);
|
||||
if (isSelected() && g_AIArea && g_AIArea->getMiddleAreaOwner() == kBiochipSignature)
|
||||
_image.loadMazeIfNecessary();
|
||||
}
|
||||
|
||||
_image.moveToMapLocation(neighborhood, room, dir);
|
||||
} else {
|
||||
_image.unloadImage();
|
||||
setItemState(kMapUnavailable);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
_image.unloadImage();
|
||||
setItemState(kMapUnavailable);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
63
engines/pegasus/items/biochips/mapchip.h
Normal file
63
engines/pegasus/items/biochips/mapchip.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_BIOCHIPS_MAPCHIP_H
|
||||
#define PEGASUS_ITEMS_BIOCHIPS_MAPCHIP_H
|
||||
|
||||
#include "pegasus/items/biochips/biochipitem.h"
|
||||
#include "pegasus/items/biochips/mapimage.h"
|
||||
|
||||
namespace Common {
|
||||
class ReadStream;
|
||||
class WriteStream;
|
||||
}
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class MapChip : public BiochipItem {
|
||||
public:
|
||||
MapChip(const ItemID, const NeighborhoodID, const RoomID, const DirectionConstant);
|
||||
~MapChip() override;
|
||||
|
||||
void select() override;
|
||||
void deselect() override;
|
||||
void takeSharedArea() override;
|
||||
void giveUpSharedArea() override;
|
||||
|
||||
void moveToMapLocation(const NeighborhoodID, const RoomID, const DirectionConstant);
|
||||
|
||||
void writeToStream(Common::WriteStream *) override;
|
||||
void readFromStream(Common::ReadStream *) override;
|
||||
|
||||
bool beenToMaze() { return _image.anyFlagSet(); }
|
||||
|
||||
protected:
|
||||
MapImage _image;
|
||||
};
|
||||
|
||||
extern MapChip *g_map;
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
444
engines/pegasus/items/biochips/mapimage.cpp
Normal file
444
engines/pegasus/items/biochips/mapimage.cpp
Normal file
@@ -0,0 +1,444 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/items/biochips/mapimage.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
#define FLAG_TO_INDEX(flag) ((flag) >> 2)
|
||||
#define INDEX_TO_FLAG(index) ((index) << 2)
|
||||
|
||||
#define ROOM_TO_INDEX(room) \
|
||||
(((room) >= kMars35 && (room) <= kMars39) ? ((room) - kMars35) : \
|
||||
(((room) == kMars60) ? (kMars39 - kMars35 + 1) : \
|
||||
((room) - kMarsMaze004 + kMars39 - kMars35 + 2)))
|
||||
|
||||
#define INDEX_TO_ROOM(index) \
|
||||
(((index) <= ROOM_TO_INDEX(kMars39)) ? \
|
||||
(((index) - ROOM_TO_INDEX(kMars35)) + kMars35) : \
|
||||
((index) <= ROOM_TO_INDEX(kMars60,)) ? kMars60 : \
|
||||
((((index) - ROOM_TO_INDEX(kMarsMaze004))) + kMarsMaze004))
|
||||
|
||||
#define ROOM_TO_FLAG(room, dir) (INDEX_TO_FLAG(ROOM_TO_INDEX(room)) | (dir))
|
||||
|
||||
#define FLAG_TO_ROOM(flag) (INDEX_TO_ROOM(FLAG_TO_INDEX(flag)))
|
||||
|
||||
#define FLAG_TO_DIRECTION(flag) ((flag) & 3)
|
||||
|
||||
static const int kGearRoomFlagLow = ROOM_TO_FLAG(kMars35, kNorth);
|
||||
static const int kGearRoomFlagHigh = ROOM_TO_FLAG(kMars39, kWest);
|
||||
|
||||
static const int kMazeFlagLow = ROOM_TO_FLAG(kMars60, kNorth);
|
||||
static const int kMazeFlagHigh = ROOM_TO_FLAG(kMarsMaze200, kWest);
|
||||
|
||||
static const CoordType kGearRoomScreenOffsetX = 49;
|
||||
static const CoordType kGearRoomScreenOffsetY = 47;
|
||||
|
||||
static const CoordType kGearRoomGridOriginX = 1;
|
||||
static const CoordType kGearRoomGridOriginY = 4;
|
||||
|
||||
static const CoordType kMazeScreenOffsetX = 16;
|
||||
static const CoordType kMazeScreenOffsetY = 20;
|
||||
|
||||
static const CoordType kMazeGridOriginX = 6;
|
||||
static const CoordType kMazeGridOriginY = 1;
|
||||
|
||||
static const CoordType kGridWidth = 4;
|
||||
static const CoordType kGridHeight = 4;
|
||||
|
||||
static const uint16 kMapOfMazePICTID = 906;
|
||||
static const uint16 kMapOfGearRoomPICTID = 907;
|
||||
|
||||
static const int s_mapCoords[MapImage::kNumMappingRooms][2] = {
|
||||
/* kMars35 */ { 0, 0 },
|
||||
/* kMars36 */ { 1, 0 },
|
||||
/* kMars37 */ { 2, 0 },
|
||||
/* kMars38 */ { 3, 0 },
|
||||
/* kMars39 */ { 4, 0 },
|
||||
/* kMars60 */ { 19, 9 },
|
||||
/* kMarsMaze004 */ { 18, 9 },
|
||||
/* kMarsMaze005 */ { 18, 10 },
|
||||
/* kMarsMaze006 */ { 17, 10 },
|
||||
/* kMarsMaze007 */ { 16, 10 },
|
||||
/* kMarsMaze008 */ { 15, 10 },
|
||||
/* kMarsMaze009 */ { 14, 10 },
|
||||
/* kMarsMaze010 */ { 14, 9 },
|
||||
/* kMarsMaze011 */ { 14, 8 },
|
||||
/* kMarsMaze012 */ { 14, 7 },
|
||||
/* kMarsMaze015 */ { 16, 7 },
|
||||
/* kMarsMaze016 */ { 14, 11 },
|
||||
/* kMarsMaze017 */ { 14, 12 },
|
||||
/* kMarsMaze018 */ { 15, 12 },
|
||||
/* kMarsMaze019 */ { 16, 12 },
|
||||
/* kMarsMaze020 */ { 16, 13 },
|
||||
/* kMarsMaze021 */ { 16, 14 },
|
||||
/* kMarsMaze022 */ { 16, 15 },
|
||||
/* kMarsMaze023 */ { 17, 15 },
|
||||
/* kMarsMaze024 */ { 18, 15 },
|
||||
/* kMarsMaze025 */ { 18, 14 },
|
||||
/* kMarsMaze026 */ { 18, 13 },
|
||||
/* kMarsMaze027 */ { 18, 12 },
|
||||
/* kMarsMaze028 */ { 18, 11 },
|
||||
/* kMarsMaze031 */ { 19, 14 },
|
||||
/* kMarsMaze032 */ { 20, 14 },
|
||||
/* kMarsMaze033 */ { 20, 13 },
|
||||
/* kMarsMaze034 */ { 20, 12 },
|
||||
/* kMarsMaze035 */ { 20, 11 },
|
||||
/* kMarsMaze036 */ { 21, 11 },
|
||||
/* kMarsMaze037 */ { 15, 15 },
|
||||
/* kMarsMaze038 */ { 14, 15 },
|
||||
/* kMarsMaze039 */ { 13, 15 },
|
||||
/* kMarsMaze042 */ { 10, 15 },
|
||||
/* kMarsMaze043 */ { 9, 15 },
|
||||
/* kMarsMaze044 */ { 8, 15 },
|
||||
/* kMarsMaze045 */ { 7, 15 },
|
||||
/* kMarsMaze046 */ { 6, 15 },
|
||||
/* kMarsMaze047 */ { 5, 15 },
|
||||
/* kMarsMaze049 */ { 13, 14 },
|
||||
/* kMarsMaze050 */ { 12, 14 },
|
||||
/* kMarsMaze051 */ { 11, 14 },
|
||||
/* kMarsMaze052 */ { 10, 14 },
|
||||
/* kMarsMaze053 */ { 10, 13 },
|
||||
/* kMarsMaze054 */ { 9, 13 },
|
||||
/* kMarsMaze055 */ { 8, 13 },
|
||||
/* kMarsMaze056 */ { 8, 12 },
|
||||
/* kMarsMaze057 */ { 7, 12 },
|
||||
/* kMarsMaze058 */ { 12, 13 },
|
||||
/* kMarsMaze059 */ { 12, 12 },
|
||||
/* kMarsMaze060 */ { 12, 11 },
|
||||
/* kMarsMaze061 */ { 12, 10 },
|
||||
/* kMarsMaze063 */ { 12, 9 },
|
||||
/* kMarsMaze064 */ { 12, 8 },
|
||||
/* kMarsMaze065 */ { 12, 7 },
|
||||
/* kMarsMaze066 */ { 13, 7 },
|
||||
/* kMarsMaze067 */ { 15, 7 },
|
||||
/* kMarsMaze068 */ { 17, 7 },
|
||||
/* kMarsMaze069 */ { 18, 7 },
|
||||
/* kMarsMaze070 */ { 19, 7 },
|
||||
/* kMarsMaze071 */ { 20, 7 },
|
||||
/* kMarsMaze072 */ { 20, 6 },
|
||||
/* kMarsMaze074 */ { 20, 5 },
|
||||
/* kMarsMaze076 */ { 20, 4 },
|
||||
/* kMarsMaze078 */ { 20, 3 },
|
||||
/* kMarsMaze079 */ { 20, 2 },
|
||||
/* kMarsMaze081 */ { 20, 2 },
|
||||
/* kMarsMaze083 */ { 20, 0 },
|
||||
/* kMarsMaze084 */ { 19, 0 },
|
||||
/* kMarsMaze085 */ { 18, 0 },
|
||||
/* kMarsMaze086 */ { 17, 0 },
|
||||
/* kMarsMaze087 */ { 16, 0 },
|
||||
/* kMarsMaze088 */ { 15, 0 },
|
||||
/* kMarsMaze089 */ { 14, 0 },
|
||||
/* kMarsMaze090 */ { 13, 0 },
|
||||
/* kMarsMaze091 */ { 12, 0 },
|
||||
/* kMarsMaze092 */ { 11, 0 },
|
||||
/* kMarsMaze093 */ { 10, 0 },
|
||||
/* kMarsMaze098 */ { 10, 1 },
|
||||
/* kMarsMaze099 */ { 8, 2 },
|
||||
/* kMarsMaze100 */ { 9, 2 },
|
||||
/* kMarsMaze101 */ { 10, 2 },
|
||||
/* kMarsMaze104 */ { 13, 2 },
|
||||
/* kMarsMaze105 */ { 13, 3 },
|
||||
/* kMarsMaze106 */ { 13, 4 },
|
||||
/* kMarsMaze107 */ { 13, 5 },
|
||||
/* kMarsMaze108 */ { 14, 5 },
|
||||
/* kMarsMaze111 */ { 15, 5 },
|
||||
/* kMarsMaze113 */ { 16, 5 },
|
||||
/* kMarsMaze114 */ { 17, 5 },
|
||||
/* kMarsMaze115 */ { 18, 5 },
|
||||
/* kMarsMaze116 */ { 18, 4 },
|
||||
/* kMarsMaze117 */ { 18, 3 },
|
||||
/* kMarsMaze118 */ { 19, 3 },
|
||||
/* kMarsMaze119 */ { 18, 2 },
|
||||
/* kMarsMaze120 */ { 17, 2 },
|
||||
/* kMarsMaze121 */ { 16, 2 },
|
||||
/* kMarsMaze122 */ { 15, 2 },
|
||||
/* kMarsMaze123 */ { 15, 1 },
|
||||
/* kMarsMaze124 */ { 12, 4 },
|
||||
/* kMarsMaze125 */ { 11, 4 },
|
||||
/* kMarsMaze126 */ { 10, 4 },
|
||||
/* kMarsMaze127 */ { 10, 5 },
|
||||
/* kMarsMaze128 */ { 10, 6 },
|
||||
/* kMarsMaze129 */ { 9, 6 },
|
||||
/* kMarsMaze130 */ { 8, 6 },
|
||||
/* kMarsMaze131 */ { 7, 6 },
|
||||
/* kMarsMaze132 */ { 7, 7 },
|
||||
/* kMarsMaze133 */ { 7, 8 },
|
||||
/* kMarsMaze136 */ { 7, 11 },
|
||||
/* kMarsMaze137 */ { 6, 11 },
|
||||
/* kMarsMaze138 */ { 5, 11 },
|
||||
/* kMarsMaze139 */ { 5, 12 },
|
||||
/* kMarsMaze140 */ { 4, 12 },
|
||||
/* kMarsMaze141 */ { 5, 13 },
|
||||
/* kMarsMaze142 */ { 5, 14 },
|
||||
/* kMarsMaze143 */ { 4, 14 },
|
||||
/* kMarsMaze144 */ { 3, 14 },
|
||||
/* kMarsMaze145 */ { 3, 13 },
|
||||
/* kMarsMaze146 */ { 2, 13 },
|
||||
/* kMarsMaze147 */ { 1, 13 },
|
||||
/* kMarsMaze148 */ { 1, 14 },
|
||||
/* kMarsMaze149 */ { 1, 15 },
|
||||
/* kMarsMaze152 */ { 1, 12 },
|
||||
/* kMarsMaze153 */ { 1, 11 },
|
||||
/* kMarsMaze154 */ { 1, 10 },
|
||||
/* kMarsMaze155 */ { 1, 9 },
|
||||
/* kMarsMaze156 */ { 1, 8 },
|
||||
/* kMarsMaze157 */ { 2, 10 },
|
||||
/* kMarsMaze159 */ { 2, 8 },
|
||||
/* kMarsMaze160 */ { 2, 7 },
|
||||
/* kMarsMaze161 */ { 2, 6 },
|
||||
/* kMarsMaze162 */ { 3, 10 },
|
||||
/* kMarsMaze163 */ { 3, 9 },
|
||||
/* kMarsMaze164 */ { 3, 8 },
|
||||
/* kMarsMaze165 */ { 4, 8 },
|
||||
/* kMarsMaze166 */ { 5, 8 },
|
||||
/* kMarsMaze167 */ { 6, 8 },
|
||||
/* kMarsMaze168 */ { 3, 6 },
|
||||
/* kMarsMaze169 */ { 4, 6 },
|
||||
/* kMarsMaze170 */ { 5, 6 },
|
||||
/* kMarsMaze171 */ { 5, 5 },
|
||||
/* kMarsMaze172 */ { 5, 4 },
|
||||
/* kMarsMaze173 */ { 4, 4 },
|
||||
/* kMarsMaze174 */ { 3, 4 },
|
||||
/* kMarsMaze175 */ { 3, 5 },
|
||||
/* kMarsMaze177 */ { 8, 4 },
|
||||
/* kMarsMaze178 */ { 8, 3 },
|
||||
/* kMarsMaze179 */ { 7, 4 },
|
||||
/* kMarsMaze180 */ { 6, 4 },
|
||||
/* kMarsMaze181 */ { 6, 3 },
|
||||
/* kMarsMaze182 */ { 6, 2 },
|
||||
/* kMarsMaze183 */ { 6, 1 },
|
||||
/* kMarsMaze184 */ { 6, 0 },
|
||||
/* kMarsMaze187 */ { 3, 0 },
|
||||
/* kMarsMaze188 */ { 2, 0 },
|
||||
/* kMarsMaze189 */ { 1, 0 },
|
||||
/* kMarsMaze190 */ { 1, 1 },
|
||||
/* kMarsMaze191 */ { 1, 2 },
|
||||
/* kMarsMaze192 */ { 5, 2 },
|
||||
/* kMarsMaze193 */ { 4, 2 },
|
||||
/* kMarsMaze194 */ { 3, 2 },
|
||||
/* kMarsMaze195 */ { 3, 1 },
|
||||
/* kMarsMaze198 */ { 1, 3 },
|
||||
/* kMarsMaze199 */ { 1, 4 },
|
||||
/* kMarsMaze200 */ { 0, 4 }
|
||||
};
|
||||
|
||||
MapImage::MapImage() : DisplayElement(kNoDisplayElement) {
|
||||
_whichArea = kMapNoArea;
|
||||
setBounds(kAIMiddleAreaLeft, kAIMiddleAreaTop, kAIMiddleAreaLeft + kAIMiddleAreaWidth, kAIMiddleAreaTop + kAIMiddleAreaHeight);
|
||||
setDisplayOrder(kAIMiddleAreaOrder + 10);
|
||||
startDisplaying();
|
||||
|
||||
_darkGreen = g_system->getScreenFormat().RGBToColor(64, 150, 10);
|
||||
_lightGreen = g_system->getScreenFormat().RGBToColor(102, 239, 0);
|
||||
}
|
||||
|
||||
void MapImage::writeToStream(Common::WriteStream *stream) {
|
||||
_mappedRooms.writeToStream(stream);
|
||||
}
|
||||
|
||||
void MapImage::readFromStream(Common::ReadStream *stream) {
|
||||
_mappedRooms.readFromStream(stream);
|
||||
}
|
||||
|
||||
void MapImage::loadGearRoomIfNecessary() {
|
||||
if (_whichArea != kMapGearRoom) {
|
||||
_mapImage.getImageFromPICTResource(g_vm->_resFork, kMapOfGearRoomPICTID);
|
||||
|
||||
Common::Rect bounds;
|
||||
_mapImage.getSurfaceBounds(bounds);
|
||||
_mapMask.allocateSurface(bounds);
|
||||
_whichArea = kMapGearRoom;
|
||||
|
||||
GraphicsManager *gfx = g_vm->_gfx;
|
||||
gfx->setCurSurface(_mapMask.getSurface());
|
||||
|
||||
gfx->getCurSurface()->fillRect(bounds, g_system->getScreenFormat().RGBToColor(0xff, 0xff, 0xff));
|
||||
|
||||
for (int i = kGearRoomFlagLow; i <= kGearRoomFlagHigh; i++)
|
||||
if (_mappedRooms.getFlag(i))
|
||||
addFlagToMask(i);
|
||||
|
||||
gfx->setCurSurface(gfx->getWorkArea());
|
||||
show();
|
||||
}
|
||||
}
|
||||
|
||||
void MapImage::loadMazeIfNecessary() {
|
||||
if (_whichArea != kMapMaze) {
|
||||
_mapImage.getImageFromPICTResource(g_vm->_resFork, kMapOfMazePICTID);
|
||||
|
||||
Common::Rect bounds;
|
||||
_mapImage.getSurfaceBounds(bounds);
|
||||
_mapMask.allocateSurface(bounds);
|
||||
_whichArea = kMapMaze;
|
||||
|
||||
GraphicsManager *gfx = g_vm->_gfx;
|
||||
gfx->setCurSurface(_mapMask.getSurface());
|
||||
|
||||
gfx->getCurSurface()->fillRect(bounds, g_system->getScreenFormat().RGBToColor(0xff, 0xff, 0xff));
|
||||
|
||||
for (int i = kMazeFlagLow; i <= kMazeFlagHigh; i++)
|
||||
if (_mappedRooms.getFlag(i))
|
||||
addFlagToMask(i);
|
||||
|
||||
gfx->setCurSurface(gfx->getWorkArea());
|
||||
show();
|
||||
}
|
||||
}
|
||||
|
||||
void MapImage::unloadImage() {
|
||||
_mapImage.deallocateSurface();
|
||||
_mapMask.deallocateSurface();
|
||||
hide();
|
||||
_whichArea = kMapNoArea;
|
||||
}
|
||||
|
||||
void MapImage::moveToMapLocation(const NeighborhoodID, const RoomID room, const DirectionConstant dir) {
|
||||
GraphicsManager *gfx = g_vm->_gfx;
|
||||
|
||||
int flag = ROOM_TO_FLAG(room, dir);
|
||||
|
||||
if (!_mappedRooms.getFlag(flag)) {
|
||||
_mappedRooms.setFlag(flag, true);
|
||||
|
||||
if (_mapMask.isSurfaceValid()) {
|
||||
gfx->setCurSurface(_mapMask.getSurface());
|
||||
addFlagToMask(flag);
|
||||
gfx->setCurSurface(gfx->getWorkArea());
|
||||
}
|
||||
}
|
||||
|
||||
if (isDisplaying())
|
||||
triggerRedraw();
|
||||
}
|
||||
|
||||
void MapImage::addFlagToMask(const int flag) {
|
||||
Common::Rect r1;
|
||||
getRevealedRects(flag, r1);
|
||||
g_vm->_gfx->getCurSurface()->fillRect(r1, g_system->getScreenFormat().RGBToColor(0, 0, 0));
|
||||
}
|
||||
|
||||
// This function can even be sensitive to open doors.
|
||||
// clone2727 notices that it's not, though
|
||||
void MapImage::getRevealedRects(const uint32 flag, Common::Rect &r1) {
|
||||
CoordType gridX, gridY;
|
||||
|
||||
switch (_whichArea) {
|
||||
case kMapMaze:
|
||||
gridX = kMazeGridOriginX;
|
||||
gridY = kMazeGridOriginY;
|
||||
break;
|
||||
case kMapGearRoom:
|
||||
gridX = kGearRoomGridOriginX;
|
||||
gridY = kGearRoomGridOriginY;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
int index = FLAG_TO_INDEX(flag);
|
||||
gridX += s_mapCoords[index][0] * kGridWidth;
|
||||
gridY += s_mapCoords[index][1] * kGridHeight;
|
||||
|
||||
r1 = Common::Rect(gridX - 1, gridY - 1, gridX + kGridWidth + 1, gridY + kGridHeight + 1);
|
||||
}
|
||||
|
||||
void MapImage::drawPlayer() {
|
||||
Graphics::Surface *screen = g_vm->_gfx->getCurSurface();
|
||||
|
||||
CoordType gridX, gridY;
|
||||
|
||||
switch (_whichArea) {
|
||||
case kMapMaze:
|
||||
gridX = _bounds.left + kMazeScreenOffsetX + kMazeGridOriginX;
|
||||
gridY = _bounds.top + kMazeScreenOffsetY + kMazeGridOriginY;
|
||||
break;
|
||||
case kMapGearRoom:
|
||||
gridX = _bounds.left + kGearRoomScreenOffsetX + kGearRoomGridOriginX;
|
||||
gridY = _bounds.top + kGearRoomScreenOffsetY + kGearRoomGridOriginY;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
int index = ROOM_TO_INDEX(GameState.getCurrentRoom());
|
||||
gridX += s_mapCoords[index][0] * kGridWidth;
|
||||
gridY += s_mapCoords[index][1] * kGridHeight;
|
||||
|
||||
// This was intended to make little arrows
|
||||
switch (GameState.getCurrentDirection()) {
|
||||
case kNorth:
|
||||
screen->drawLine(gridX + 1, gridY, gridX + 2, gridY, _darkGreen);
|
||||
screen->drawLine(gridX, gridY + 1, gridX + 3, gridY + 1, _darkGreen);
|
||||
screen->drawLine(gridX + 1, gridY + 1, gridX + 2, gridY + 1, _lightGreen);
|
||||
screen->drawLine(gridX, gridY + 2, gridX + 3, gridY + 2, _lightGreen);
|
||||
break;
|
||||
case kSouth:
|
||||
screen->drawLine(gridX + 1, gridY + 3, gridX + 2, gridY + 3, _darkGreen);
|
||||
screen->drawLine(gridX, gridY + 2, gridX + 3, gridY + 2, _darkGreen);
|
||||
screen->drawLine(gridX + 1, gridY + 2, gridX + 2, gridY + 2, _lightGreen);
|
||||
screen->drawLine(gridX, gridY + 1, gridX + 3, gridY + 1, _lightGreen);
|
||||
break;
|
||||
case kEast:
|
||||
screen->drawLine(gridX + 3, gridY + 1, gridX + 3, gridY + 2, _darkGreen);
|
||||
screen->drawLine(gridX + 2, gridY, gridX + 2, gridY + 3, _darkGreen);
|
||||
screen->drawLine(gridX + 2, gridY + 1, gridX + 2, gridY + 2, _lightGreen);
|
||||
screen->drawLine(gridX + 1, gridY, gridX + 1, gridY + 3, _lightGreen);
|
||||
break;
|
||||
case kWest:
|
||||
screen->drawLine(gridX, gridY + 1, gridX, gridY + 2, _darkGreen);
|
||||
screen->drawLine(gridX + 1, gridY, gridX + 1, gridY + 3, _darkGreen);
|
||||
screen->drawLine(gridX + 1, gridY + 1, gridX + 1, gridY + 2, _lightGreen);
|
||||
screen->drawLine(gridX + 2, gridY, gridX + 2, gridY + 3, _lightGreen);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void MapImage::draw(const Common::Rect &) {
|
||||
Common::Rect r1;
|
||||
_mapImage.getSurfaceBounds(r1);
|
||||
|
||||
Common::Rect r2 = r1;
|
||||
switch (_whichArea) {
|
||||
case kMapMaze:
|
||||
r2.moveTo(_bounds.left + kMazeScreenOffsetX, _bounds.top + kMazeScreenOffsetY);
|
||||
break;
|
||||
case kMapGearRoom:
|
||||
r2.moveTo(_bounds.left + kGearRoomScreenOffsetX, _bounds.top + kGearRoomScreenOffsetY);
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
_mapImage.copyToCurrentPortMasked(r1, r2, &_mapMask);
|
||||
|
||||
drawPlayer();
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
83
engines/pegasus/items/biochips/mapimage.h
Normal file
83
engines/pegasus/items/biochips/mapimage.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_BIOCHIPS_MAPIMAGE_H
|
||||
#define PEGASUS_ITEMS_BIOCHIPS_MAPIMAGE_H
|
||||
|
||||
#include "pegasus/elements.h"
|
||||
#include "pegasus/surface.h"
|
||||
#include "pegasus/util.h"
|
||||
#include "pegasus/neighborhood/mars/constants.h"
|
||||
|
||||
namespace Common {
|
||||
class ReadStream;
|
||||
class WriteStream;
|
||||
}
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class MapImage : public DisplayElement {
|
||||
public:
|
||||
MapImage();
|
||||
~MapImage() override {}
|
||||
|
||||
void writeToStream(Common::WriteStream *);
|
||||
void readFromStream(Common::ReadStream *);
|
||||
|
||||
void loadGearRoomIfNecessary();
|
||||
void loadMazeIfNecessary();
|
||||
void unloadImage();
|
||||
void moveToMapLocation(const NeighborhoodID, const RoomID, const DirectionConstant);
|
||||
|
||||
void draw(const Common::Rect &) override;
|
||||
|
||||
bool anyFlagSet() { return _mappedRooms.anyFlagSet(); }
|
||||
|
||||
static const uint32 kNumMappingRooms = (kMars39 - kMars35 + 1) + (kMars60 - kMars60 + 1) +
|
||||
(kMarsMaze200 - kMarsMaze004 + 1);
|
||||
static const uint32 kNumMappingFlags = kNumMappingRooms * 4;
|
||||
|
||||
protected:
|
||||
enum MapArea {
|
||||
kMapNoArea,
|
||||
kMapMaze,
|
||||
kMapGearRoom
|
||||
};
|
||||
|
||||
void addFlagToMask(const int flag);
|
||||
void getRevealedRects(const uint32, Common::Rect &);
|
||||
void drawPlayer();
|
||||
|
||||
MapArea _whichArea;
|
||||
|
||||
FlagsArray<byte, kNumMappingFlags> _mappedRooms;
|
||||
|
||||
uint32 _darkGreen, _lightGreen;
|
||||
|
||||
Surface _mapImage, _mapMask;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
200
engines/pegasus/items/biochips/opticalchip.cpp
Normal file
200
engines/pegasus/items/biochips/opticalchip.cpp
Normal file
@@ -0,0 +1,200 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/items/biochips/opticalchip.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
OpticalChip *g_opticalChip = nullptr;
|
||||
|
||||
OpticalChip::OpticalChip(const ItemID id, const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction) :
|
||||
BiochipItem(id, neighborhood, room, direction), _ariesHotspot(kAriesSpotID), _mercuryHotspot(kMercurySpotID),
|
||||
_poseidonHotspot(kPoseidonSpotID) {
|
||||
_ariesHotspot.setArea(Common::Rect(kAIMiddleAreaLeft + 60, kAIMiddleAreaTop + 27, kAIMiddleAreaLeft + 60 + 121, kAIMiddleAreaTop + 27 + 20));
|
||||
_ariesHotspot.setHotspotFlags(kOpticalBiochipSpotFlag);
|
||||
g_allHotspots.push_back(&_ariesHotspot);
|
||||
|
||||
_mercuryHotspot.setArea(Common::Rect(kAIMiddleAreaLeft + 60, kAIMiddleAreaTop + 47, kAIMiddleAreaLeft + 60 + 121, kAIMiddleAreaTop + 47 + 20));
|
||||
_mercuryHotspot.setHotspotFlags(kOpticalBiochipSpotFlag);
|
||||
g_allHotspots.push_back(&_mercuryHotspot);
|
||||
|
||||
_poseidonHotspot.setArea(Common::Rect(kAIMiddleAreaLeft + 60, kAIMiddleAreaTop + 67, kAIMiddleAreaLeft + 60 + 121, kAIMiddleAreaTop + 67 + 20));
|
||||
_poseidonHotspot.setHotspotFlags(kOpticalBiochipSpotFlag);
|
||||
g_allHotspots.push_back(&_poseidonHotspot);
|
||||
|
||||
setItemState(kOptical000);
|
||||
|
||||
g_opticalChip = this;
|
||||
}
|
||||
|
||||
OpticalChip::~OpticalChip() {
|
||||
g_allHotspots.removeOneHotspot(kAriesSpotID);
|
||||
g_allHotspots.removeOneHotspot(kMercurySpotID);
|
||||
g_allHotspots.removeOneHotspot(kPoseidonSpotID);
|
||||
}
|
||||
|
||||
void OpticalChip::writeToStream(Common::WriteStream *stream) {
|
||||
BiochipItem::writeToStream(stream);
|
||||
_opticalFlags.writeToStream(stream);
|
||||
}
|
||||
|
||||
void OpticalChip::readFromStream(Common::ReadStream *stream) {
|
||||
BiochipItem::readFromStream(stream);
|
||||
_opticalFlags.readFromStream(stream);
|
||||
}
|
||||
|
||||
void OpticalChip::addAries() {
|
||||
_opticalFlags.setFlag(kOpticalAriesExposed, true);
|
||||
setUpOpticalChip();
|
||||
}
|
||||
|
||||
void OpticalChip::addMercury() {
|
||||
_opticalFlags.setFlag(kOpticalMercuryExposed, true);
|
||||
setUpOpticalChip();
|
||||
}
|
||||
|
||||
void OpticalChip::addPoseidon() {
|
||||
_opticalFlags.setFlag(kOpticalPoseidonExposed, true);
|
||||
setUpOpticalChip();
|
||||
}
|
||||
|
||||
void OpticalChip::setUpOpticalChip() {
|
||||
if (_opticalFlags.getFlag(kOpticalAriesExposed)) {
|
||||
if (_opticalFlags.getFlag(kOpticalMercuryExposed)) {
|
||||
if (_opticalFlags.getFlag(kOpticalPoseidonExposed))
|
||||
setItemState(kOptical111);
|
||||
else
|
||||
setItemState(kOptical011);
|
||||
} else {
|
||||
if (_opticalFlags.getFlag(kOpticalPoseidonExposed))
|
||||
setItemState(kOptical101);
|
||||
else
|
||||
setItemState(kOptical001);
|
||||
}
|
||||
} else {
|
||||
if (_opticalFlags.getFlag(kOpticalMercuryExposed)) {
|
||||
if (_opticalFlags.getFlag(kOpticalPoseidonExposed))
|
||||
setItemState(kOptical110);
|
||||
else
|
||||
setItemState(kOptical010);
|
||||
} else {
|
||||
if (_opticalFlags.getFlag(kOpticalPoseidonExposed))
|
||||
setItemState(kOptical100);
|
||||
else
|
||||
setItemState(kOptical000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OpticalChip::activateOpticalHotspots() {
|
||||
if (_opticalFlags.getFlag(kOpticalAriesExposed))
|
||||
_ariesHotspot.setActive();
|
||||
if (_opticalFlags.getFlag(kOpticalMercuryExposed))
|
||||
_mercuryHotspot.setActive();
|
||||
if (_opticalFlags.getFlag(kOpticalPoseidonExposed))
|
||||
_poseidonHotspot.setActive();
|
||||
}
|
||||
|
||||
void OpticalChip::clickInOpticalHotspot(HotSpotID id) {
|
||||
playOpMemMovie(id);
|
||||
}
|
||||
|
||||
void OpticalChip::playOpMemMovie(HotSpotID id) {
|
||||
Common::Path movieName;
|
||||
switch (id) {
|
||||
case kAriesSpotID:
|
||||
// WORKAROUND: The original CD release played the ares video even
|
||||
// when you destroyed the shuttle. For the DVD release, we have
|
||||
// some new videos that can be played instead to workaround a plot
|
||||
// loophole.
|
||||
if (!g_vm->isDVD() || _opticalFlags.getFlag(kOpticalAriesExposed))
|
||||
movieName = "Images/AI/Globals/OMAI";
|
||||
else if (_itemOwnerID == kPlayerID)
|
||||
movieName = "Images/AI/Globals/OMN1";
|
||||
else
|
||||
movieName = "Images/AI/Globals/OMN0";
|
||||
break;
|
||||
case kMercurySpotID:
|
||||
movieName = "Images/AI/Globals/OMMI";
|
||||
break;
|
||||
case kPoseidonSpotID:
|
||||
movieName = "Images/AI/Globals/OMPI";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ItemState state = getItemState(), newState;
|
||||
switch (state) {
|
||||
case kOptical001:
|
||||
newState = kOptical002;
|
||||
break;
|
||||
case kOptical010:
|
||||
newState = kOptical020;
|
||||
break;
|
||||
case kOptical011:
|
||||
if (id == kAriesSpotID)
|
||||
newState = kOptical012;
|
||||
else
|
||||
newState = kOptical021;
|
||||
break;
|
||||
case kOptical100:
|
||||
newState = kOptical200;
|
||||
break;
|
||||
case kOptical101:
|
||||
if (id == kAriesSpotID)
|
||||
newState = kOptical102;
|
||||
else
|
||||
newState = kOptical201;
|
||||
break;
|
||||
case kOptical110:
|
||||
if (id == kMercurySpotID)
|
||||
newState = kOptical120;
|
||||
else
|
||||
newState = kOptical210;
|
||||
break;
|
||||
case kOptical111:
|
||||
if (id == kAriesSpotID)
|
||||
newState = kOptical112;
|
||||
else if (id == kMercurySpotID)
|
||||
newState = kOptical121;
|
||||
else
|
||||
newState = kOptical211;
|
||||
break;
|
||||
case kOptical000: // Can never happen.
|
||||
default:
|
||||
error("Invalid optical chip state");
|
||||
}
|
||||
|
||||
setItemState(newState);
|
||||
|
||||
if (g_AIArea)
|
||||
g_AIArea->playAIMovie(kRightAreaSignature, movieName, false, kOpticalInterruption);
|
||||
|
||||
setItemState(state);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
70
engines/pegasus/items/biochips/opticalchip.h
Normal file
70
engines/pegasus/items/biochips/opticalchip.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_BIOCHIPS_OPTICALCHIP_H
|
||||
#define PEGASUS_ITEMS_BIOCHIPS_OPTICALCHIP_H
|
||||
|
||||
#include "pegasus/hotspot.h"
|
||||
#include "pegasus/util.h"
|
||||
#include "pegasus/items/biochips/biochipitem.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class OpticalChip : public BiochipItem {
|
||||
public:
|
||||
OpticalChip(const ItemID, const NeighborhoodID, const RoomID, const DirectionConstant);
|
||||
~OpticalChip() override;
|
||||
|
||||
void writeToStream(Common::WriteStream *) override;
|
||||
void readFromStream(Common::ReadStream *) override;
|
||||
|
||||
void addAries();
|
||||
void addMercury();
|
||||
void addPoseidon();
|
||||
|
||||
void activateOpticalHotspots();
|
||||
void clickInOpticalHotspot(HotSpotID);
|
||||
void playOpMemMovie(HotSpotID);
|
||||
|
||||
protected:
|
||||
enum {
|
||||
kOpticalAriesExposed,
|
||||
kOpticalMercuryExposed,
|
||||
kOpticalPoseidonExposed,
|
||||
kNumOpticalChipFlags
|
||||
};
|
||||
|
||||
void setUpOpticalChip();
|
||||
|
||||
FlagsArray<byte, kNumOpticalChipFlags> _opticalFlags;
|
||||
Hotspot _ariesHotspot;
|
||||
Hotspot _mercuryHotspot;
|
||||
Hotspot _poseidonHotspot;
|
||||
};
|
||||
|
||||
extern OpticalChip *g_opticalChip;
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
206
engines/pegasus/items/biochips/pegasuschip.cpp
Normal file
206
engines/pegasus/items/biochips/pegasuschip.cpp
Normal file
@@ -0,0 +1,206 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/energymonitor.h"
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/items/biochips/pegasuschip.h"
|
||||
#include "pegasus/neighborhood/tsa/fulltsa.h"
|
||||
#include "pegasus/neighborhood/tsa/tinytsa.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
PegasusChip::PegasusChip(const ItemID id, const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction) :
|
||||
BiochipItem(id, neighborhood, room, direction), _recallSpot(kPegasusRecallSpotID) {
|
||||
_recallSpot.setArea(Common::Rect(kAIMiddleAreaLeft + 116, kAIMiddleAreaTop + 63, kAIMiddleAreaLeft + 184, kAIMiddleAreaTop + 91));
|
||||
_recallSpot.setHotspotFlags(kPegasusBiochipSpotFlag);
|
||||
g_allHotspots.push_back(&_recallSpot);
|
||||
setItemState(kPegasusTSA00);
|
||||
}
|
||||
|
||||
PegasusChip::~PegasusChip() {
|
||||
g_allHotspots.removeOneHotspot(kPegasusRecallSpotID);
|
||||
}
|
||||
|
||||
void PegasusChip::select() {
|
||||
BiochipItem::select();
|
||||
setUpPegasusChip();
|
||||
}
|
||||
|
||||
void PegasusChip::takeSharedArea() {
|
||||
BiochipItem::takeSharedArea();
|
||||
setUpPegasusChip();
|
||||
}
|
||||
|
||||
void PegasusChip::setUpPegasusChip() {
|
||||
switch (GameState.getCurrentNeighborhood()) {
|
||||
case kCaldoriaID:
|
||||
setItemState(kPegasusCaldoria);
|
||||
break;
|
||||
case kFullTSAID:
|
||||
case kFinalTSAID:
|
||||
case kTinyTSAID:
|
||||
setItemState(kPegasusTSA10);
|
||||
break;
|
||||
case kPrehistoricID:
|
||||
if (g_vm->playerHasItemID(kHistoricalLog))
|
||||
setItemState(kPegasusPrehistoric00);
|
||||
else
|
||||
setItemState(kPegasusPrehistoric10);
|
||||
break;
|
||||
case kMarsID:
|
||||
if (GameState.getMarsFinished())
|
||||
setItemState(kPegasusMars00);
|
||||
else
|
||||
setItemState(kPegasusMars10);
|
||||
break;
|
||||
case kWSCID:
|
||||
if (GameState.getWSCFinished())
|
||||
setItemState(kPegasusWSC00);
|
||||
else
|
||||
setItemState(kPegasusWSC10);
|
||||
break;
|
||||
case kNoradAlphaID:
|
||||
case kNoradDeltaID:
|
||||
if (GameState.getNoradFinished())
|
||||
setItemState(kPegasusNorad00);
|
||||
else
|
||||
setItemState(kPegasusNorad10);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Only does something if the chip should be announcing that the time zone is finished...
|
||||
void PegasusChip::setUpPegasusChipRude() {
|
||||
switch (GameState.getCurrentNeighborhood()) {
|
||||
case kPrehistoricID:
|
||||
if (g_vm->playerHasItemID(kHistoricalLog))
|
||||
setItemState(kPegasusPrehistoric00);
|
||||
break;
|
||||
case kMarsID:
|
||||
if (GameState.getMarsFinished())
|
||||
setItemState(kPegasusMars00);
|
||||
break;
|
||||
case kWSCID:
|
||||
if (GameState.getWSCFinished())
|
||||
setItemState(kPegasusWSC00);
|
||||
break;
|
||||
case kNoradAlphaID:
|
||||
case kNoradDeltaID:
|
||||
if (GameState.getNoradFinished())
|
||||
setItemState(kPegasusNorad00);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PegasusChip::activatePegasusHotspots() {
|
||||
switch (GameState.getCurrentNeighborhood()) {
|
||||
case kPrehistoricID:
|
||||
// WORKAROUND: Don't allow the player to recall if they don't have
|
||||
// the historical log. Otherwise, gameplay is broken when returning
|
||||
// to the TSA.
|
||||
if (!g_vm->playerHasItemID(kHistoricalLog))
|
||||
return;
|
||||
// fall through
|
||||
case kMarsID:
|
||||
case kWSCID:
|
||||
case kNoradAlphaID:
|
||||
case kNoradDeltaID:
|
||||
_recallSpot.setActive();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PegasusChip::clickInPegasusHotspot() {
|
||||
ItemState thisState = getItemState();
|
||||
ItemState hiliteState;
|
||||
|
||||
switch (thisState) {
|
||||
case kPegasusPrehistoric00:
|
||||
hiliteState = kPegasusPrehistoric01;
|
||||
break;
|
||||
case kPegasusPrehistoric10:
|
||||
hiliteState = kPegasusPrehistoric11;
|
||||
break;
|
||||
case kPegasusMars00:
|
||||
hiliteState = kPegasusMars01;
|
||||
break;
|
||||
case kPegasusMars10:
|
||||
hiliteState = kPegasusMars11;
|
||||
break;
|
||||
case kPegasusNorad00:
|
||||
hiliteState = kPegasusNorad01;
|
||||
break;
|
||||
case kPegasusNorad10:
|
||||
hiliteState = kPegasusNorad11;
|
||||
break;
|
||||
case kPegasusWSC00:
|
||||
hiliteState = kPegasusWSC01;
|
||||
break;
|
||||
case kPegasusWSC10:
|
||||
hiliteState = kPegasusWSC11;
|
||||
break;
|
||||
default:
|
||||
error("Invalid pegasus chip state");
|
||||
}
|
||||
|
||||
// WORKAROUND: The original called setItemState() here. However,
|
||||
// since we're overriding select() to call setUpPegasusChip(),
|
||||
// the highlighted frame is never displayed! So, we're manually
|
||||
// setting the state and selecting the item. Also of note is that
|
||||
// setItemState() for this class is effectively useless since it
|
||||
// always gets overriden in the select() function. The only reason
|
||||
// that this doesn't end in infinite recursion is because setItemState()
|
||||
// has a check against the current state to make sure you don't call
|
||||
// select() again. </rant>
|
||||
_itemState = hiliteState;
|
||||
BiochipItem::select();
|
||||
|
||||
uint32 time = g_system->getMillis();
|
||||
while (g_system->getMillis() < time + 500) {
|
||||
g_vm->refreshDisplay();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
|
||||
setItemState(thisState);
|
||||
|
||||
if (!((Neighborhood *)g_neighborhood)->okayToJump())
|
||||
return;
|
||||
|
||||
if (g_energyMonitor)
|
||||
g_energyMonitor->stopEnergyDraining();
|
||||
|
||||
if (GameState.getTSAState() == kPlayerWentToPrehistoric || GameState.allTimeZonesFinished())
|
||||
g_vm->jumpToNewEnvironment(kFullTSAID, kTSA37, kNorth);
|
||||
else
|
||||
g_vm->jumpToNewEnvironment(kTinyTSAID, kTinyTSA37, kNorth);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
56
engines/pegasus/items/biochips/pegasuschip.h
Normal file
56
engines/pegasus/items/biochips/pegasuschip.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_BIOCHIPS_PEGASUSCHIP_H
|
||||
#define PEGASUS_ITEMS_BIOCHIPS_PEGASUSCHIP_H
|
||||
|
||||
#include "pegasus/hotspot.h"
|
||||
#include "pegasus/items/biochips/biochipitem.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class PegasusChip : public BiochipItem {
|
||||
public:
|
||||
PegasusChip(const ItemID, const NeighborhoodID, const RoomID, const DirectionConstant);
|
||||
~PegasusChip() override;
|
||||
|
||||
void select() override;
|
||||
|
||||
void takeSharedArea() override;
|
||||
|
||||
void setUpPegasusChip();
|
||||
|
||||
// Called to set up the Pegasus chip when the Pegasus chip is the current chip but does not
|
||||
// own the center area.
|
||||
void setUpPegasusChipRude();
|
||||
void activatePegasusHotspots();
|
||||
void clickInPegasusHotspot();
|
||||
|
||||
protected:
|
||||
Hotspot _recallSpot;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
48
engines/pegasus/items/biochips/retscanchip.cpp
Normal file
48
engines/pegasus/items/biochips/retscanchip.cpp
Normal file
@@ -0,0 +1,48 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/items/biochips/retscanchip.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
RetScanChip::RetScanChip(const ItemID id, const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction) :
|
||||
BiochipItem(id, neighborhood, room, direction) {
|
||||
}
|
||||
|
||||
void RetScanChip::searchForLaser() {
|
||||
ItemExtraEntry entry;
|
||||
findItemExtra(kRetinalScanSearching, entry);
|
||||
|
||||
if (g_AIArea)
|
||||
g_AIArea->playAIAreaSequence(kBiochipSignature, kMiddleAreaSignature, entry.extraStart, entry.extraStop);
|
||||
|
||||
findItemExtra(kRetinalScanActivated, entry);
|
||||
if (g_AIArea)
|
||||
g_AIArea->playAIAreaSequence(kBiochipSignature, kRightAreaSignature, entry.extraStart, entry.extraStop);
|
||||
|
||||
setItemState(kRetinalSimulating);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
42
engines/pegasus/items/biochips/retscanchip.h
Normal file
42
engines/pegasus/items/biochips/retscanchip.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_BIOCHIPS_RETSCANCHIP_H
|
||||
#define PEGASUS_ITEMS_BIOCHIPS_RETSCANCHIP_H
|
||||
|
||||
#include "pegasus/items/biochips/biochipitem.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class RetScanChip : public BiochipItem {
|
||||
public:
|
||||
RetScanChip(const ItemID, const NeighborhoodID, const RoomID, const DirectionConstant);
|
||||
~RetScanChip() override {}
|
||||
|
||||
void searchForLaser();
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
52
engines/pegasus/items/biochips/shieldchip.cpp
Normal file
52
engines/pegasus/items/biochips/shieldchip.cpp
Normal file
@@ -0,0 +1,52 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/items/biochips/shieldchip.h"
|
||||
#include "pegasus/neighborhood/neighborhood.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
ShieldChip *g_shield = nullptr;
|
||||
|
||||
ShieldChip::ShieldChip(const ItemID id, const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction) :
|
||||
BiochipItem(id, neighborhood, room, direction) {
|
||||
g_shield = this;
|
||||
}
|
||||
|
||||
void ShieldChip::select() {
|
||||
BiochipItem::select();
|
||||
GameState.setShieldOn(true);
|
||||
if (g_neighborhood)
|
||||
g_neighborhood->shieldOn();
|
||||
}
|
||||
|
||||
void ShieldChip::deselect() {
|
||||
BiochipItem::deselect();
|
||||
GameState.setShieldOn(false);
|
||||
if (g_neighborhood)
|
||||
g_neighborhood->shieldOff();
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
45
engines/pegasus/items/biochips/shieldchip.h
Normal file
45
engines/pegasus/items/biochips/shieldchip.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_BIOCHIPS_SHIELDCHIP_H
|
||||
#define PEGASUS_ITEMS_BIOCHIPS_SHIELDCHIP_H
|
||||
|
||||
#include "pegasus/items/biochips/biochipitem.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class ShieldChip : public BiochipItem {
|
||||
public:
|
||||
ShieldChip(const ItemID, const NeighborhoodID, const RoomID, const DirectionConstant);
|
||||
~ShieldChip() override {}
|
||||
|
||||
void select() override;
|
||||
void deselect() override;
|
||||
};
|
||||
|
||||
extern ShieldChip *g_shield;
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
174
engines/pegasus/items/inventory.cpp
Normal file
174
engines/pegasus/items/inventory.cpp
Normal file
@@ -0,0 +1,174 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/constants.h"
|
||||
#include "pegasus/items/item.h"
|
||||
#include "pegasus/items/inventory.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
Inventory::Inventory() {
|
||||
_weightLimit = 100;
|
||||
_ownerID = kNoActorID;
|
||||
_referenceCount = 0;
|
||||
}
|
||||
|
||||
Inventory::~Inventory() {
|
||||
}
|
||||
|
||||
void Inventory::setWeightLimit(WeightType limit) {
|
||||
_weightLimit = limit;
|
||||
// *** What to do if the new weight limit is greater than the current weight?
|
||||
}
|
||||
|
||||
WeightType Inventory::getWeight() {
|
||||
WeightType result = 0;
|
||||
|
||||
for (ItemIterator it = _inventoryList.begin(); it != _inventoryList.end(); it++)
|
||||
result += (*it)->getItemWeight();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// If the item already belongs, just return kInventoryOK.
|
||||
InventoryResult Inventory::addItem(Item *item) {
|
||||
if (itemInInventory(item))
|
||||
return kInventoryOK;
|
||||
|
||||
if (getWeight() + item->getItemWeight() > _weightLimit)
|
||||
return kTooMuchWeight;
|
||||
|
||||
_inventoryList.push_back(item);
|
||||
item->setItemOwner(_ownerID);
|
||||
|
||||
++_referenceCount;
|
||||
return kInventoryOK;
|
||||
}
|
||||
|
||||
InventoryResult Inventory::removeItem(Item *item) {
|
||||
for (ItemIterator it = _inventoryList.begin(); it != _inventoryList.end(); it++) {
|
||||
if (*it == item) {
|
||||
_inventoryList.erase(it);
|
||||
item->setItemOwner(kNoActorID);
|
||||
|
||||
++_referenceCount;
|
||||
return kInventoryOK;
|
||||
}
|
||||
}
|
||||
|
||||
return kItemNotInInventory;
|
||||
}
|
||||
|
||||
InventoryResult Inventory::removeItem(ItemID id) {
|
||||
Item *item = findItemByID(id);
|
||||
|
||||
if (item) {
|
||||
_inventoryList.remove(item);
|
||||
item->setItemOwner(kNoActorID);
|
||||
|
||||
++_referenceCount;
|
||||
return kInventoryOK;
|
||||
}
|
||||
|
||||
return kItemNotInInventory;
|
||||
}
|
||||
|
||||
void Inventory::removeAllItems() {
|
||||
_inventoryList.clear();
|
||||
++_referenceCount;
|
||||
}
|
||||
|
||||
bool Inventory::itemInInventory(Item *item) {
|
||||
for (ItemIterator it = _inventoryList.begin(); it != _inventoryList.end(); it++)
|
||||
if (*it == item)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Inventory::itemInInventory(ItemID id) {
|
||||
return findItemByID(id) != nullptr;
|
||||
}
|
||||
|
||||
Item *Inventory::getItemAt(int32 index) {
|
||||
int32 i = 0;
|
||||
for (ItemIterator it = _inventoryList.begin(); it != _inventoryList.end(); it++, i++)
|
||||
if (i == index)
|
||||
return *it;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ItemID Inventory::getItemIDAt(int32 index) {
|
||||
Item *item = getItemAt(index);
|
||||
|
||||
if (item)
|
||||
return item->getObjectID();
|
||||
|
||||
return kNoItemID;
|
||||
}
|
||||
|
||||
Item *Inventory::findItemByID(ItemID id) {
|
||||
return _inventoryList.findItemByID(id);
|
||||
}
|
||||
|
||||
// Return -1 if not found.
|
||||
|
||||
int32 Inventory::findIndexOf(Item *item) {
|
||||
uint32 i = 0;
|
||||
for (ItemIterator it = _inventoryList.begin(); it != _inventoryList.end(); it++, i++)
|
||||
if (*it == item)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Return -1 if not found.
|
||||
|
||||
int32 Inventory::findIndexOf(ItemID id) {
|
||||
uint32 i = 0;
|
||||
for (ItemIterator it = _inventoryList.begin(); it != _inventoryList.end(); it++, i++)
|
||||
if ((*it)->getObjectID() == id)
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
WeightType Inventory::getWeightLimit() {
|
||||
return _weightLimit;
|
||||
}
|
||||
|
||||
int32 Inventory::getNumItems() {
|
||||
return _inventoryList.size();
|
||||
}
|
||||
|
||||
void Inventory::setOwnerID(const ActorID id) {
|
||||
_ownerID = id;
|
||||
}
|
||||
|
||||
ActorID Inventory::getOwnerID() const {
|
||||
return _ownerID;
|
||||
}
|
||||
|
||||
} // End of namespae Pegasus
|
||||
79
engines/pegasus/items/inventory.h
Normal file
79
engines/pegasus/items/inventory.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_INVENTORY_H
|
||||
#define PEGASUS_ITEMS_INVENTORY_H
|
||||
|
||||
#include "pegasus/types.h"
|
||||
#include "pegasus/items/itemlist.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class Item;
|
||||
|
||||
// Inventories have a "current item". This item is the default item the player can
|
||||
// use. In a text adventure system, the current item would be "it", as in
|
||||
// "Hit the troll with it," where "it" would refer to some weapon which is the current
|
||||
// item. In a graphic adventure, the current item would be the item the user selects
|
||||
// to use with the mouse or other pointing device.
|
||||
|
||||
class Inventory {
|
||||
public:
|
||||
Inventory();
|
||||
virtual ~Inventory();
|
||||
|
||||
WeightType getWeightLimit();
|
||||
void setWeightLimit(WeightType limit);
|
||||
WeightType getWeight();
|
||||
|
||||
virtual InventoryResult addItem(Item *item);
|
||||
virtual InventoryResult removeItem(Item *item);
|
||||
virtual InventoryResult removeItem(ItemID id);
|
||||
virtual bool itemInInventory(Item *item);
|
||||
virtual bool itemInInventory(ItemID id);
|
||||
virtual Item *getItemAt(int32 index);
|
||||
virtual ItemID getItemIDAt(int32 index);
|
||||
virtual Item *findItemByID(ItemID id);
|
||||
virtual int32 findIndexOf(Item *item);
|
||||
virtual int32 findIndexOf(ItemID id);
|
||||
int32 getNumItems();
|
||||
virtual void removeAllItems();
|
||||
|
||||
void setOwnerID(const ActorID id);
|
||||
ActorID getOwnerID() const;
|
||||
|
||||
uint32 getReferenceCount() { return _referenceCount; }
|
||||
|
||||
protected:
|
||||
WeightType _weightLimit;
|
||||
ActorID _ownerID;
|
||||
ItemList _inventoryList;
|
||||
|
||||
private:
|
||||
uint32 _referenceCount;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
250
engines/pegasus/items/inventory/airmask.cpp
Normal file
250
engines/pegasus/items/inventory/airmask.cpp
Normal file
@@ -0,0 +1,250 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/items/inventory/airmask.h"
|
||||
#include "pegasus/neighborhood/neighborhood.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
AirMask *g_airMask = nullptr;
|
||||
|
||||
// Based on full == 100, which is scale used by GetAirLeft().
|
||||
static const TimeValue kOxygenLowThreshold = 25;
|
||||
|
||||
void AirMask::airMaskTimerExpired() {
|
||||
if (g_neighborhood)
|
||||
g_neighborhood->checkAirMask();
|
||||
}
|
||||
|
||||
AirMask::AirMask(const ItemID id, const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction) :
|
||||
InventoryItem(id, neighborhood, room, direction), _toggleSpot(kAirMaskToggleSpotID) {
|
||||
g_airMask = this;
|
||||
_toggleSpot.setArea(Common::Rect(kAIMiddleAreaLeft + 10, kAIMiddleAreaTop + 17, kAIMiddleAreaLeft + 110, kAIMiddleAreaTop + 57));
|
||||
_toggleSpot.setHotspotFlags(kAirMaskSpotFlag);
|
||||
g_allHotspots.push_back(&_toggleSpot);
|
||||
setItemState(kAirMaskEmptyOff);
|
||||
_oxygenTimer.primeFuse(0);
|
||||
_oxygenTimer.setFunctor(new Common::Functor0Mem<void, AirMask>(this, &AirMask::airMaskTimerExpired));
|
||||
}
|
||||
|
||||
AirMask::~AirMask() {
|
||||
g_allHotspots.removeOneHotspot(kAirMaskToggleSpotID);
|
||||
g_airMask = nullptr;
|
||||
}
|
||||
|
||||
void AirMask::writeToStream(Common::WriteStream *stream) {
|
||||
InventoryItem::writeToStream(stream);
|
||||
stream->writeUint32BE(_oxygenTimer.getTimeRemaining());
|
||||
}
|
||||
|
||||
void AirMask::readFromStream(Common::ReadStream *stream) {
|
||||
_oxygenTimer.stopFuse();
|
||||
InventoryItem::readFromStream(stream);
|
||||
_oxygenTimer.primeFuse(stream->readUint32BE());
|
||||
}
|
||||
|
||||
void AirMask::putMaskOn() {
|
||||
AirQuality airQuality;
|
||||
|
||||
if (g_neighborhood)
|
||||
airQuality = g_neighborhood->getAirQuality(GameState.getCurrentRoom());
|
||||
else
|
||||
airQuality = kAirQualityGood;
|
||||
|
||||
uint airLevel = getAirLeft();
|
||||
ItemState newState = getItemState();
|
||||
ItemState oldState = newState;
|
||||
|
||||
if (airLevel == 0) {
|
||||
newState = kAirMaskEmptyFilter;
|
||||
} else if (airLevel <= kOxygenLowThreshold) {
|
||||
if (airQuality == kAirQualityVacuum)
|
||||
newState = kAirMaskLowOn;
|
||||
else
|
||||
newState = kAirMaskLowFilter;
|
||||
} else {
|
||||
if (airQuality == kAirQualityVacuum)
|
||||
newState = kAirMaskFullOn;
|
||||
else
|
||||
newState = kAirMaskFullFilter;
|
||||
}
|
||||
|
||||
if (newState != oldState)
|
||||
setItemState(newState);
|
||||
}
|
||||
|
||||
void AirMask::takeMaskOff() {
|
||||
uint airLevel = getAirLeft();
|
||||
ItemState newState = getItemState();
|
||||
ItemState oldState = newState;
|
||||
|
||||
if (airLevel == 0)
|
||||
newState = kAirMaskEmptyOff;
|
||||
else if (airLevel <= kOxygenLowThreshold)
|
||||
newState = kAirMaskLowOff;
|
||||
else
|
||||
newState = kAirMaskFullOff;
|
||||
|
||||
if (newState != oldState)
|
||||
setItemState(newState);
|
||||
}
|
||||
|
||||
void AirMask::toggleItemState() {
|
||||
if (isAirMaskInUse())
|
||||
takeMaskOff();
|
||||
else
|
||||
putMaskOn();
|
||||
}
|
||||
|
||||
void AirMask::airQualityChanged() {
|
||||
if (isAirMaskInUse())
|
||||
putMaskOn();
|
||||
else
|
||||
takeMaskOff();
|
||||
}
|
||||
|
||||
void AirMask::setItemState(const ItemState newState) {
|
||||
if (newState != getItemState()) {
|
||||
InventoryItem::setItemState(newState);
|
||||
|
||||
switch (newState) {
|
||||
case kAirMaskFullOn:
|
||||
case kAirMaskLowOn:
|
||||
if (!_oxygenTimer.isFuseLit()) {
|
||||
_oxygenTimer.lightFuse();
|
||||
startIdling();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (_oxygenTimer.isFuseLit()) {
|
||||
_oxygenTimer.stopFuse();
|
||||
stopIdling();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (g_neighborhood)
|
||||
g_neighborhood->checkAirMask();
|
||||
|
||||
g_AIArea->checkMiddleArea();
|
||||
}
|
||||
}
|
||||
|
||||
void AirMask::useIdleTime() {
|
||||
if (getAirLeft() == 0)
|
||||
setItemState(kAirMaskEmptyOff);
|
||||
else if (getAirLeft() <= kOxygenLowThreshold)
|
||||
setItemState(kAirMaskLowOn);
|
||||
}
|
||||
|
||||
void AirMask::refillAirMask() {
|
||||
switch (getItemState()) {
|
||||
case kAirMaskEmptyOff:
|
||||
case kAirMaskLowOff:
|
||||
setItemState(kAirMaskFullOff);
|
||||
break;
|
||||
case kAirMaskEmptyFilter:
|
||||
case kAirMaskLowFilter:
|
||||
setItemState(kAirMaskFullFilter);
|
||||
break;
|
||||
case kAirMaskLowOn:
|
||||
setItemState(kAirMaskFullOn);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (_oxygenTimer.isFuseLit()) {
|
||||
_oxygenTimer.stopFuse();
|
||||
_oxygenTimer.primeFuse(kOxyMaskFullTime);
|
||||
_oxygenTimer.lightFuse();
|
||||
} else {
|
||||
_oxygenTimer.primeFuse(kOxyMaskFullTime);
|
||||
}
|
||||
}
|
||||
|
||||
// Doesn't return 0 until the timer is actually at 0.
|
||||
uint AirMask::getAirLeft() {
|
||||
return CLIP<int>(((_oxygenTimer.getTimeRemaining() * 100) + kOxyMaskFullTime - 1) / kOxyMaskFullTime, 0, 100);
|
||||
}
|
||||
|
||||
bool AirMask::isAirMaskInUse() {
|
||||
switch (getItemState()) {
|
||||
case kAirMaskEmptyOff:
|
||||
case kAirMaskLowOff:
|
||||
case kAirMaskFullOff:
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool AirMask::isAirMaskOn() {
|
||||
switch (getItemState()) {
|
||||
case kAirMaskLowOn:
|
||||
case kAirMaskFullOn:
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool AirMask::isAirFilterOn() {
|
||||
switch (getItemState()) {
|
||||
case kAirMaskEmptyFilter:
|
||||
case kAirMaskLowFilter:
|
||||
case kAirMaskFullFilter:
|
||||
return true;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void AirMask::addedToInventory() {
|
||||
GameState.setMarsMaskOnFiller(false);
|
||||
}
|
||||
|
||||
void AirMask::removedFromInventory() {
|
||||
if (isAirMaskInUse())
|
||||
toggleItemState();
|
||||
}
|
||||
|
||||
void AirMask::activateAirMaskHotspots() {
|
||||
_toggleSpot.setActive();
|
||||
}
|
||||
|
||||
void AirMask::clickInAirMaskHotspot() {
|
||||
toggleItemState();
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
75
engines/pegasus/items/inventory/airmask.h
Normal file
75
engines/pegasus/items/inventory/airmask.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_INVENTORY_AIRMASK_H
|
||||
#define PEGASUS_ITEMS_INVENTORY_AIRMASK_H
|
||||
|
||||
#include "pegasus/hotspot.h"
|
||||
#include "pegasus/timers.h"
|
||||
#include "pegasus/items/inventory/inventoryitem.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class AirMask : public InventoryItem, private Idler {
|
||||
public:
|
||||
AirMask(const ItemID, const NeighborhoodID, const RoomID, const DirectionConstant);
|
||||
~AirMask() override;
|
||||
|
||||
void writeToStream(Common::WriteStream *) override;
|
||||
void readFromStream(Common::ReadStream *) override;
|
||||
|
||||
void setItemState(const ItemState) override;
|
||||
void putMaskOn();
|
||||
void takeMaskOff();
|
||||
void toggleItemState() override;
|
||||
void airQualityChanged();
|
||||
|
||||
bool isAirMaskInUse();
|
||||
bool isAirMaskOn();
|
||||
bool isAirFilterOn();
|
||||
|
||||
void refillAirMask();
|
||||
|
||||
// Returns a percentage
|
||||
uint getAirLeft();
|
||||
|
||||
void activateAirMaskHotspots();
|
||||
void clickInAirMaskHotspot();
|
||||
|
||||
protected:
|
||||
void airMaskTimerExpired();
|
||||
|
||||
void removedFromInventory() override;
|
||||
void addedToInventory() override;
|
||||
void useIdleTime() override;
|
||||
|
||||
Hotspot _toggleSpot;
|
||||
FuseFunction _oxygenTimer;
|
||||
};
|
||||
|
||||
extern AirMask *g_airMask;
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
45
engines/pegasus/items/inventory/gascanister.cpp
Normal file
45
engines/pegasus/items/inventory/gascanister.cpp
Normal file
@@ -0,0 +1,45 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/items/inventory/gascanister.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
GasCanister::GasCanister(const ItemID id, const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction) :
|
||||
InventoryItem(id, neighborhood, room, direction) {
|
||||
}
|
||||
|
||||
void GasCanister::select() {
|
||||
InventoryItem::select();
|
||||
takeSharedArea();
|
||||
}
|
||||
|
||||
void GasCanister::takeSharedArea() {
|
||||
ItemExtraEntry entry;
|
||||
findItemExtra(kGasCanLoop, entry);
|
||||
g_AIArea->loopAIAreaSequence(kInventorySignature, kMiddleAreaSignature, entry.extraStart, entry.extraStop);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
43
engines/pegasus/items/inventory/gascanister.h
Normal file
43
engines/pegasus/items/inventory/gascanister.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_INVENTORY_GASCANISTER_H
|
||||
#define PEGASUS_ITEMS_INVENTORY_GASCANISTER_H
|
||||
|
||||
#include "pegasus/items/inventory/inventoryitem.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class GasCanister : public InventoryItem {
|
||||
public:
|
||||
GasCanister(const ItemID, const NeighborhoodID, const RoomID, const DirectionConstant);
|
||||
~GasCanister() override {}
|
||||
|
||||
void select() override;
|
||||
void takeSharedArea() override;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
107
engines/pegasus/items/inventory/inventoryitem.cpp
Normal file
107
engines/pegasus/items/inventory/inventoryitem.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/stream.h"
|
||||
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/items/inventory/inventoryitem.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
InventoryItem::InventoryItem(const ItemID id, const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction) :
|
||||
Item(id, neighborhood, room, direction) {
|
||||
|
||||
Common::SeekableReadStream *leftInfo = g_vm->_resFork->getResource(MKTAG('L', 'e', 'f', 't'), kItemBaseResID + id);
|
||||
if (leftInfo) {
|
||||
_leftAreaInfo = readItemState(leftInfo);
|
||||
delete leftInfo;
|
||||
} else {
|
||||
_leftAreaInfo.numEntries = 0;
|
||||
_leftAreaInfo.entries = nullptr;
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *inventoryInfo = g_vm->_resFork->getResource(MKTAG('I', 'n', 'v', 'I'), kItemBaseResID + id);
|
||||
if (inventoryInfo) {
|
||||
_inventoryInfo.panelStart = inventoryInfo->readUint32BE();
|
||||
_inventoryInfo.panelStop = inventoryInfo->readUint32BE();
|
||||
delete inventoryInfo;
|
||||
} else {
|
||||
_inventoryInfo.panelStart = _inventoryInfo.panelStop = 0;
|
||||
}
|
||||
|
||||
_itemAnimationTime = 0;
|
||||
}
|
||||
|
||||
InventoryItem::~InventoryItem() {
|
||||
delete[] _leftAreaInfo.entries;
|
||||
}
|
||||
|
||||
ItemType InventoryItem::getItemType() {
|
||||
return kInventoryItemType;
|
||||
}
|
||||
|
||||
TimeValue InventoryItem::getLeftAreaTime() const {
|
||||
if (!_leftAreaInfo.entries)
|
||||
return 0xffffffff;
|
||||
|
||||
TimeValue time;
|
||||
ItemState state;
|
||||
|
||||
findItemStateEntryByState(_leftAreaInfo, _itemState, time);
|
||||
if (time == 0xffffffff)
|
||||
getItemStateEntry(_leftAreaInfo, 0, state, time);
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
void InventoryItem::setAnimationTime(const TimeValue time) {
|
||||
_itemAnimationTime = time;
|
||||
}
|
||||
|
||||
TimeValue InventoryItem::getAnimationTime() const {
|
||||
return _itemAnimationTime;
|
||||
}
|
||||
|
||||
// Must affect images in left area.
|
||||
void InventoryItem::select() {
|
||||
Item::select();
|
||||
|
||||
if (g_AIArea)
|
||||
g_AIArea->setAIAreaToTime(kInventorySignature, kLeftAreaSignature, getLeftAreaTime());
|
||||
}
|
||||
|
||||
void InventoryItem::deselect() {
|
||||
Item::deselect();
|
||||
|
||||
if (g_AIArea)
|
||||
g_AIArea->setAIAreaToTime(kInventorySignature, kLeftAreaSignature, 0xffffffff);
|
||||
}
|
||||
|
||||
void InventoryItem::getPanelTimes(TimeValue &start, TimeValue &stop) const {
|
||||
start = _inventoryInfo.panelStart;
|
||||
stop = _inventoryInfo.panelStop;
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
66
engines/pegasus/items/inventory/inventoryitem.h
Normal file
66
engines/pegasus/items/inventory/inventoryitem.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_INVENTORY_INVENTORYITEM_H
|
||||
#define PEGASUS_ITEMS_INVENTORY_INVENTORYITEM_H
|
||||
|
||||
#include "pegasus/items/item.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
// JMPInventoryInfo contains the resource data used by InventoryItems.
|
||||
|
||||
struct JMPInventoryInfo {
|
||||
TimeValue panelStart;
|
||||
TimeValue panelStop;
|
||||
};
|
||||
|
||||
class InventoryItem : public Item {
|
||||
public:
|
||||
InventoryItem(const ItemID, const NeighborhoodID, const RoomID, const DirectionConstant);
|
||||
~InventoryItem() override;
|
||||
|
||||
ItemType getItemType() override;
|
||||
|
||||
void getPanelTimes(TimeValue &, TimeValue &) const;
|
||||
TimeValue getLeftAreaTime() const;
|
||||
|
||||
void setAnimationTime(const TimeValue);
|
||||
TimeValue getAnimationTime() const;
|
||||
|
||||
virtual void toggleItemState() {}
|
||||
|
||||
// Must affect images in left area.
|
||||
void select() override;
|
||||
void deselect() override;
|
||||
|
||||
protected:
|
||||
JMPInventoryInfo _inventoryInfo;
|
||||
ItemStateInfo _leftAreaInfo;
|
||||
TimeValue _itemAnimationTime;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
58
engines/pegasus/items/inventory/keycard.cpp
Normal file
58
engines/pegasus/items/inventory/keycard.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/items/inventory/keycard.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
KeyCard::KeyCard(const ItemID id, const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction) :
|
||||
InventoryItem(id, neighborhood, room, direction) {
|
||||
setItemState(kFlashlightOff);
|
||||
}
|
||||
|
||||
void KeyCard::toggleItemState() {
|
||||
if (getItemState() == kFlashlightOff)
|
||||
setItemState(kFlashlightOn);
|
||||
else
|
||||
setItemState(kFlashlightOff);
|
||||
}
|
||||
|
||||
void KeyCard::setItemState(const ItemState newState) {
|
||||
if (newState != getItemState()) {
|
||||
InventoryItem::setItemState(newState);
|
||||
g_vm->checkFlashlight();
|
||||
}
|
||||
}
|
||||
|
||||
bool KeyCard::isFlashlightOn() {
|
||||
return getItemState() == kFlashlightOn;
|
||||
}
|
||||
|
||||
void KeyCard::removedFromInventory() {
|
||||
if (isFlashlightOn())
|
||||
setItemState(kFlashlightOff);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
47
engines/pegasus/items/inventory/keycard.h
Normal file
47
engines/pegasus/items/inventory/keycard.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_INVENTORY_KEYCARD_H
|
||||
#define PEGASUS_ITEMS_INVENTORY_KEYCARD_H
|
||||
|
||||
#include "pegasus/items/inventory/inventoryitem.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class KeyCard : public InventoryItem {
|
||||
public:
|
||||
KeyCard(const ItemID, const NeighborhoodID, const RoomID, const DirectionConstant);
|
||||
~KeyCard() override {}
|
||||
|
||||
void toggleItemState() override;
|
||||
void setItemState(const ItemState) override;
|
||||
bool isFlashlightOn();
|
||||
|
||||
protected:
|
||||
void removedFromInventory() override;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
373
engines/pegasus/items/inventorypicture.cpp
Normal file
373
engines/pegasus/items/inventorypicture.cpp
Normal file
@@ -0,0 +1,373 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/transition.h"
|
||||
#include "pegasus/items/inventorypicture.h"
|
||||
#include "pegasus/items/biochips/biochipitem.h"
|
||||
#include "pegasus/items/inventory/inventoryitem.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
InventoryPicture::InventoryPicture(const DisplayElementID id, InputHandler *nextHandler, Inventory *inventory) :
|
||||
InputHandler(nextHandler), Picture(id), _panelMovie(kNoDisplayElement){
|
||||
_inventory = inventory;
|
||||
_lastReferenceCount = 0xffffffff;
|
||||
|
||||
if (_inventory->getNumItems() > 0) {
|
||||
_currentItemIndex = 0;
|
||||
_currentItem = (Item *)_inventory->getItemAt(0);
|
||||
} else {
|
||||
_currentItemIndex = -1;
|
||||
_currentItem = nullptr;
|
||||
}
|
||||
|
||||
_active = false;
|
||||
_shouldDrawHighlight = true;
|
||||
_itemsPerRow = 1;
|
||||
_numberOfRows = 1;
|
||||
_itemWidth = 0;
|
||||
_itemHeight = 0;
|
||||
_itemX = 0;
|
||||
_itemY = 0;
|
||||
}
|
||||
|
||||
void InventoryPicture::initInventoryImage(Transition *transition) {
|
||||
initFromPICTFile(_pictName, true);
|
||||
_panelMovie.shareSurface(this);
|
||||
_panelMovie.initFromMovieFile(_movieName);
|
||||
_panelMovie.getBounds(_highlightBounds);
|
||||
_panelMovie.setTriggeredElement(transition);
|
||||
_highlightImage.initFromPICTFile(_highlightName, true);
|
||||
}
|
||||
|
||||
void InventoryPicture::throwAwayInventoryImage() {
|
||||
if (isSurfaceValid()) {
|
||||
_panelMovie.releaseMovie();
|
||||
_highlightImage.deallocateSurface();
|
||||
deallocateSurface();
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryPicture::getItemXY(uint32 index, CoordType &x, CoordType &y) {
|
||||
x = (index % _itemsPerRow) * _itemWidth + _itemX;
|
||||
y = (index / _itemsPerRow) * _itemHeight + _itemY;
|
||||
}
|
||||
|
||||
void InventoryPicture::drawItemHighlight(const Common::Rect &r) {
|
||||
if (_highlightImage.isSurfaceValid()) {
|
||||
Common::Rect r2 = _highlightBounds;
|
||||
Common::Rect bounds;
|
||||
getBounds(bounds);
|
||||
|
||||
r2.translate(bounds.left, bounds.top);
|
||||
r2 = r2.findIntersectingRect(r);
|
||||
if (!r2.isEmpty()) {
|
||||
Common::Rect r1 = r2;
|
||||
r1.translate(-bounds.left - _highlightBounds.left, -bounds.top - _highlightBounds.top);
|
||||
_highlightImage.drawImage(r1, r2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryPicture::draw(const Common::Rect &r) {
|
||||
Picture::draw(r);
|
||||
if (_inventory->getNumItems() != 0 && _shouldDrawHighlight)
|
||||
drawItemHighlight(r);
|
||||
}
|
||||
|
||||
// Assumes index >= 0.
|
||||
void InventoryPicture::setCurrentItemIndex(int32 index) {
|
||||
if (index >= _inventory->getNumItems())
|
||||
index = _inventory->getNumItems() - 1;
|
||||
|
||||
Item *currentItem = nullptr;
|
||||
if (index >= 0)
|
||||
currentItem = (Item *)_inventory->getItemAt(index);
|
||||
|
||||
if (currentItem != _currentItem) {
|
||||
if (_currentItem) {
|
||||
if (_currentItem->isSelected())
|
||||
_currentItem->deselect();
|
||||
|
||||
if (_active)
|
||||
unhighlightCurrentItem();
|
||||
}
|
||||
|
||||
_currentItemIndex = index;
|
||||
_currentItem = currentItem;
|
||||
if (_currentItem) {
|
||||
_currentItem->select();
|
||||
|
||||
if (_active)
|
||||
highlightCurrentItem();
|
||||
}
|
||||
|
||||
if (_active)
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryPicture::setCurrentItemID(ItemID id) {
|
||||
int32 index = _inventory->findIndexOf(id);
|
||||
if (index >= 0)
|
||||
setCurrentItemIndex(index);
|
||||
}
|
||||
|
||||
InventoryResult InventoryPicture::addInventoryItem(Item *item) {
|
||||
InventoryResult result = _inventory->addItem(item);
|
||||
|
||||
if (result == kInventoryOK)
|
||||
setCurrentItemIndex(_inventory->findIndexOf(item));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
InventoryResult InventoryPicture::removeInventoryItem(Item *item) {
|
||||
InventoryResult result = _inventory->removeItem(item);
|
||||
|
||||
if (result == kInventoryOK)
|
||||
setCurrentItemIndex(getCurrentItemIndex());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void InventoryPicture::removeAllItems() {
|
||||
_inventory->removeAllItems();
|
||||
setCurrentItemIndex(0);
|
||||
}
|
||||
|
||||
bool InventoryPicture::itemInInventory(Item *item) {
|
||||
return _inventory->itemInInventory(item);
|
||||
}
|
||||
|
||||
bool InventoryPicture::itemInInventory(const ItemID id) {
|
||||
return _inventory->itemInInventory(id);
|
||||
}
|
||||
|
||||
void InventoryPicture::panelUp() {
|
||||
allowInput(true);
|
||||
}
|
||||
|
||||
// Must ensure that the picture matches the _inventory member variable.
|
||||
void InventoryPicture::activateInventoryPicture() {
|
||||
if (_active)
|
||||
return;
|
||||
|
||||
allowInput(false);
|
||||
|
||||
if (_lastReferenceCount != _inventory->getReferenceCount()) {
|
||||
uint32 numItems = _inventory->getNumItems();
|
||||
|
||||
CoordType x, y;
|
||||
getItemXY(0, x, y);
|
||||
_panelMovie.moveMovieBoxTo(x, y);
|
||||
_panelMovie.show();
|
||||
|
||||
for (uint32 i = 0; i < numItems; i++) {
|
||||
Item *item = (Item *)_inventory->getItemAt(i);
|
||||
if (item == _currentItem)
|
||||
item->select();
|
||||
|
||||
getItemXY(i, x, y);
|
||||
_panelMovie.moveMovieBoxTo(x, y);
|
||||
_panelMovie.setTime(getItemPanelTime(item));
|
||||
_panelMovie.redrawMovieWorld();
|
||||
}
|
||||
|
||||
uint32 numSlots = _itemsPerRow * _numberOfRows;
|
||||
|
||||
for (uint32 i = numItems; i < numSlots; i++) {
|
||||
getItemXY(i, x, y);
|
||||
_panelMovie.moveMovieBoxTo(x, y);
|
||||
_panelMovie.setTime(0);
|
||||
_panelMovie.redrawMovieWorld();
|
||||
}
|
||||
|
||||
_lastReferenceCount = _inventory->getReferenceCount();
|
||||
}
|
||||
|
||||
show(); // *** Do we really need this?
|
||||
if (_currentItem)
|
||||
highlightCurrentItem();
|
||||
|
||||
_active = true;
|
||||
}
|
||||
|
||||
void InventoryPicture::deactivateInventoryPicture() {
|
||||
if (!_active)
|
||||
return;
|
||||
|
||||
_active = false;
|
||||
allowInput(false);
|
||||
_panelMovie.hide();
|
||||
hide();
|
||||
|
||||
if (_inventory->getNumItems() != 0)
|
||||
if (!_currentItem->isActive())
|
||||
_currentItem->activate();
|
||||
}
|
||||
|
||||
void InventoryPicture::handleInput(const Input &input, const Hotspot *cursorSpot) {
|
||||
if (_active) {
|
||||
if (input.upButtonDown()) {
|
||||
if (_currentItemIndex - _itemsPerRow >= 0)
|
||||
setCurrentItemIndex(_currentItemIndex - _itemsPerRow);
|
||||
} else if (input.downButtonDown()) {
|
||||
if (_currentItemIndex + _itemsPerRow < _inventory->getNumItems())
|
||||
setCurrentItemIndex(_currentItemIndex + _itemsPerRow);
|
||||
} else if (input.leftButtonDown()) {
|
||||
if ((_currentItemIndex % _itemsPerRow) != 0)
|
||||
setCurrentItemIndex(_currentItemIndex - 1);
|
||||
} else if (input.rightButtonDown()) {
|
||||
if (((_currentItemIndex + 1) % _itemsPerRow) != 0 && _currentItemIndex + 1 < _inventory->getNumItems())
|
||||
setCurrentItemIndex(_currentItemIndex + 1);
|
||||
}
|
||||
}
|
||||
|
||||
InputHandler::handleInput(input, cursorSpot);
|
||||
}
|
||||
|
||||
void InventoryPicture::highlightCurrentItem() {
|
||||
CoordType x, y;
|
||||
getItemXY(_currentItemIndex, x, y);
|
||||
_highlightBounds.moveTo(x, y);
|
||||
}
|
||||
|
||||
InventoryItemsPicture::InventoryItemsPicture(const DisplayElementID id, InputHandler *nextHandler, Inventory *inventory) :
|
||||
InventoryPicture(id, nextHandler, inventory) {
|
||||
_pictName = "Images/Items/Inventory/Inventory Panel";
|
||||
_movieName = "Images/Items/Inventory/Inventory Panel Movie";
|
||||
_highlightName = "Images/Items/Inventory/Inventory Hilite";
|
||||
|
||||
_itemsPerRow = 3;
|
||||
_numberOfRows = 3;
|
||||
_itemWidth = 88;
|
||||
_itemHeight = 64;
|
||||
_itemX = 8;
|
||||
_itemY = 26;
|
||||
_isLooping = true;
|
||||
}
|
||||
|
||||
void InventoryItemsPicture::loopCurrentItem() {
|
||||
if (_isLooping) {
|
||||
CoordType x, y;
|
||||
getItemXY(_currentItemIndex, x, y);
|
||||
_panelMovie.moveMovieBoxTo(x, y);
|
||||
_highlightBounds.moveTo(x, y);
|
||||
|
||||
TimeValue start, stop;
|
||||
((InventoryItem *)_currentItem)->getPanelTimes(start, stop);
|
||||
_panelMovie.stop();
|
||||
_panelMovie.setFlags(0);
|
||||
_panelMovie.setSegment(start, stop);
|
||||
_panelMovie.setFlags(kLoopTimeBase);
|
||||
_panelMovie.setTime(((InventoryItem *)_currentItem)->getAnimationTime());
|
||||
_panelMovie.start();
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryItemsPicture::highlightCurrentItem() {
|
||||
InventoryPicture::highlightCurrentItem();
|
||||
loopCurrentItem();
|
||||
}
|
||||
|
||||
void InventoryItemsPicture::unhighlightCurrentItem() {
|
||||
InventoryPicture::unhighlightCurrentItem();
|
||||
_panelMovie.stop();
|
||||
_panelMovie.setFlags(0);
|
||||
((InventoryItem *)_currentItem)->setAnimationTime(_panelMovie.getTime());
|
||||
}
|
||||
|
||||
TimeValue InventoryItemsPicture::getItemPanelTime(Item *item) {
|
||||
TimeValue start, stop;
|
||||
((InventoryItem *)item)->getPanelTimes(start, stop);
|
||||
((InventoryItem *)item)->setAnimationTime(start);
|
||||
return start;
|
||||
}
|
||||
|
||||
void InventoryItemsPicture::deactivateInventoryPicture() {
|
||||
if (_active) {
|
||||
InventoryPicture::deactivateInventoryPicture();
|
||||
_panelMovie.stop();
|
||||
_panelMovie.setFlags(0);
|
||||
_panelMovie.setSegment(0, _panelMovie.getDuration());
|
||||
_isLooping = true;
|
||||
}
|
||||
}
|
||||
|
||||
void InventoryItemsPicture::setCommPicture() {
|
||||
_pictName = "Images/Items/Inventory/Comm Panel";
|
||||
}
|
||||
|
||||
void InventoryItemsPicture::playEndMessage(DisplayElement *pushElement) {
|
||||
Movie endMessage(0);
|
||||
|
||||
_shouldDrawHighlight = false;
|
||||
endMessage.shareSurface(this);
|
||||
endMessage.initFromMovieFile("Images/Caldoria/A56 Congrats");
|
||||
endMessage.setVolume(g_vm->getSoundFXLevel());
|
||||
endMessage.moveMovieBoxTo(kFinalMessageLeft - kInventoryPushLeft, kFinalMessageTop - kInventoryPushTop);
|
||||
endMessage.setTriggeredElement(pushElement);
|
||||
endMessage.start();
|
||||
|
||||
while (endMessage.isRunning()) {
|
||||
InputDevice.pumpEvents();
|
||||
g_vm->checkCallBacks();
|
||||
g_vm->refreshDisplay();
|
||||
g_system->delayMillis(10);
|
||||
}
|
||||
|
||||
endMessage.stop();
|
||||
}
|
||||
|
||||
BiochipPicture::BiochipPicture(const DisplayElementID id, InputHandler *nextHandler, Inventory *inventory) :
|
||||
InventoryPicture(id, nextHandler, inventory) {
|
||||
_pictName = "Images/Items/Biochips/Biochip Panel";
|
||||
_movieName = "Images/Items/Biochips/Biochip Panel Movie";
|
||||
_highlightName = "Images/Items/Biochips/BioChip Hilite";
|
||||
|
||||
_itemsPerRow = 4;
|
||||
_numberOfRows = 2;
|
||||
_itemWidth = 46;
|
||||
_itemHeight = 46;
|
||||
_itemX = 4;
|
||||
_itemY = 24;
|
||||
}
|
||||
|
||||
void BiochipPicture::unhighlightCurrentItem() {
|
||||
InventoryPicture::unhighlightCurrentItem();
|
||||
CoordType x, y;
|
||||
getItemXY(_currentItemIndex, x, y);
|
||||
_panelMovie.show();
|
||||
_panelMovie.moveMovieBoxTo(x, y);
|
||||
_panelMovie.setTime(getItemPanelTime(_currentItem));
|
||||
_panelMovie.redrawMovieWorld();
|
||||
}
|
||||
|
||||
TimeValue BiochipPicture::getItemPanelTime(Item *item) {
|
||||
return ((BiochipItem *)item)->getPanelTime();
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
124
engines/pegasus/items/inventorypicture.h
Normal file
124
engines/pegasus/items/inventorypicture.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_INVENTORYPICTURE_H
|
||||
#define PEGASUS_ITEMS_INVENTORYPICTURE_H
|
||||
|
||||
#include "pegasus/input.h"
|
||||
#include "pegasus/movie.h"
|
||||
#include "pegasus/surface.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class Inventory;
|
||||
class Item;
|
||||
class Input;
|
||||
class Transition;
|
||||
|
||||
class InventoryPicture : public InputHandler, public Picture {
|
||||
public:
|
||||
InventoryPicture(const DisplayElementID, InputHandler *, Inventory *);
|
||||
~InventoryPicture() override {}
|
||||
|
||||
void initInventoryImage(Transition *);
|
||||
void throwAwayInventoryImage();
|
||||
|
||||
void panelUp();
|
||||
void activateInventoryPicture();
|
||||
void deactivateInventoryPicture();
|
||||
void handleInput(const Input &, const Hotspot *) override;
|
||||
bool wantsCursor() override { return false; }
|
||||
|
||||
InventoryResult addInventoryItem(Item *);
|
||||
InventoryResult removeInventoryItem(Item *);
|
||||
void removeAllItems();
|
||||
Item *getCurrentItem() { return _currentItem; }
|
||||
void setCurrentItemIndex(int32);
|
||||
void setCurrentItemID(ItemID);
|
||||
int32 getCurrentItemIndex() { return _currentItemIndex; }
|
||||
bool itemInInventory(Item *);
|
||||
bool itemInInventory(const ItemID);
|
||||
|
||||
protected:
|
||||
void getItemXY(uint32, CoordType &, CoordType &);
|
||||
void draw(const Common::Rect &) override;
|
||||
void drawItemHighlight(const Common::Rect &);
|
||||
virtual void highlightCurrentItem();
|
||||
virtual void unhighlightCurrentItem() {}
|
||||
virtual TimeValue getItemPanelTime(Item *) = 0;
|
||||
|
||||
Inventory *_inventory;
|
||||
uint32 _lastReferenceCount;
|
||||
Frame _highlightImage;
|
||||
Movie _panelMovie;
|
||||
int32 _currentItemIndex;
|
||||
Item *_currentItem;
|
||||
Common::Rect _highlightBounds;
|
||||
bool _active, _shouldDrawHighlight;
|
||||
|
||||
Common::Path _pictName;
|
||||
Common::Path _movieName;
|
||||
Common::Path _highlightName;
|
||||
uint16 _itemsPerRow;
|
||||
uint16 _numberOfRows;
|
||||
uint16 _itemWidth;
|
||||
uint16 _itemHeight;
|
||||
uint16 _itemX;
|
||||
uint16 _itemY;
|
||||
};
|
||||
|
||||
class InventoryItemsPicture : public InventoryPicture {
|
||||
public:
|
||||
InventoryItemsPicture(const DisplayElementID, InputHandler *, Inventory *);
|
||||
~InventoryItemsPicture() override {}
|
||||
|
||||
void deactivateInventoryPicture();
|
||||
|
||||
void disableLooping() { _isLooping = false; }
|
||||
|
||||
void setCommPicture();
|
||||
void playEndMessage(DisplayElement *);
|
||||
|
||||
protected:
|
||||
void highlightCurrentItem() override;
|
||||
void unhighlightCurrentItem() override;
|
||||
TimeValue getItemPanelTime(Item *) override;
|
||||
void loopCurrentItem();
|
||||
|
||||
bool _isLooping;
|
||||
};
|
||||
|
||||
class BiochipPicture : public InventoryPicture {
|
||||
public:
|
||||
BiochipPicture(const DisplayElementID, InputHandler *, Inventory *);
|
||||
~BiochipPicture() override {}
|
||||
|
||||
protected:
|
||||
void unhighlightCurrentItem() override;
|
||||
TimeValue getItemPanelTime(Item *) override;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
320
engines/pegasus/items/item.cpp
Normal file
320
engines/pegasus/items/item.cpp
Normal file
@@ -0,0 +1,320 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/error.h"
|
||||
#include "common/stream.h"
|
||||
|
||||
#include "pegasus/constants.h"
|
||||
#include "pegasus/elements.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/surface.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/items/item.h"
|
||||
#include "pegasus/items/itemlist.h"
|
||||
#include "pegasus/items/biochips/biochipitem.h"
|
||||
#include "pegasus/items/inventory/inventoryitem.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
Item::Item(const ItemID id, const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction) : IDObject(id) {
|
||||
_originalNeighborhood = _itemNeighborhood = neighborhood;
|
||||
_originalRoom = _itemRoom = room;
|
||||
_originalDirection = _itemDirection = direction;
|
||||
_itemWeight = 1;
|
||||
_itemOwnerID = kNoActorID;
|
||||
_itemState = 0;
|
||||
|
||||
Common::SeekableReadStream *info = g_vm->_resFork->getResource(kItemInfoResType, kItemBaseResID + id);
|
||||
if (info) {
|
||||
_itemInfo.infoLeftTime = info->readUint32BE();
|
||||
_itemInfo.infoRightStart = info->readUint32BE();
|
||||
_itemInfo.infoRightStop = info->readUint32BE();
|
||||
_itemInfo.dragSpriteNormalID = info->readUint16BE();
|
||||
_itemInfo.dragSpriteUsedID = info->readUint16BE();
|
||||
|
||||
if (g_vm->isDemo()) {
|
||||
// Adjust info right times to account for the stuff that was chopped out of the
|
||||
// info right movies.
|
||||
// Assumes time scale of 600.
|
||||
|
||||
// Gap times in seconds
|
||||
static const TimeValue kGap1 = 24;
|
||||
static const TimeValue kGap2 = 34;
|
||||
static const TimeValue kGap3 = 4;
|
||||
static const TimeValue kGap4 = 4;
|
||||
|
||||
static const TimeValue kGapForGroup1 = kGap1;
|
||||
static const TimeValue kGapForGroup2 = kGapForGroup1 + kGap2;
|
||||
static const TimeValue kGapForGroup3 = kGapForGroup2 + kGap3;
|
||||
static const TimeValue kGapForGroup4 = kGapForGroup3 + kGap4;
|
||||
|
||||
switch (id) {
|
||||
case kHistoricalLog:
|
||||
case kJourneymanKey:
|
||||
case kKeyCard:
|
||||
_itemInfo.infoRightStart -= 600 * kGapForGroup1;
|
||||
_itemInfo.infoRightStop -= 600 * kGapForGroup1;
|
||||
break;
|
||||
case kAIBiochip:
|
||||
_itemInfo.infoRightStart -= 600 * kGapForGroup2;
|
||||
_itemInfo.infoRightStop -= 600 * kGapForGroup2;
|
||||
break;
|
||||
case kMapBiochip:
|
||||
_itemInfo.infoRightStart -= 600 * kGapForGroup3;
|
||||
_itemInfo.infoRightStop -= 600 * kGapForGroup3;
|
||||
break;
|
||||
case kPegasusBiochip:
|
||||
_itemInfo.infoRightStart -= 600 * kGapForGroup4;
|
||||
_itemInfo.infoRightStop -= 600 * kGapForGroup4;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete info;
|
||||
} else {
|
||||
memset(&_itemInfo, 0, sizeof(_itemInfo));
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *middleAreaInfo = g_vm->_resFork->getResource(kMiddleAreaInfoResType, kItemBaseResID + id);
|
||||
if (middleAreaInfo) {
|
||||
_sharedAreaInfo = readItemState(middleAreaInfo);
|
||||
delete middleAreaInfo;
|
||||
} else {
|
||||
// Only kArgonPickup does not have this
|
||||
memset(&_sharedAreaInfo, 0, sizeof(_sharedAreaInfo));
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *extraInfo = g_vm->_resFork->getResource(kItemExtraInfoResType, kItemBaseResID + id);
|
||||
if (!extraInfo)
|
||||
error("Extra info not found for item %d", id);
|
||||
|
||||
_itemExtras.numEntries = extraInfo->readUint16BE();
|
||||
_itemExtras.entries = new ItemExtraEntry[_itemExtras.numEntries];
|
||||
for (uint16 i = 0; i < _itemExtras.numEntries; i++) {
|
||||
_itemExtras.entries[i].extraID = extraInfo->readUint32BE();
|
||||
_itemExtras.entries[i].extraArea = extraInfo->readUint16BE();
|
||||
_itemExtras.entries[i].extraStart = extraInfo->readUint32BE();
|
||||
_itemExtras.entries[i].extraStop = extraInfo->readUint32BE();
|
||||
}
|
||||
|
||||
delete extraInfo;
|
||||
|
||||
g_allItems.push_back(this);
|
||||
}
|
||||
|
||||
Item::~Item() {
|
||||
delete[] _sharedAreaInfo.entries;
|
||||
delete[] _itemExtras.entries;
|
||||
}
|
||||
|
||||
void Item::reset() {
|
||||
_itemNeighborhood = _originalNeighborhood;
|
||||
_itemRoom = _originalRoom;
|
||||
_itemDirection = _originalDirection;
|
||||
_itemOwnerID = kNoActorID;
|
||||
_itemState = 0;
|
||||
}
|
||||
|
||||
void Item::writeToStream(Common::WriteStream *stream) {
|
||||
stream->writeUint16BE(_itemNeighborhood);
|
||||
stream->writeUint16BE(_itemRoom);
|
||||
stream->writeByte(_itemDirection);
|
||||
stream->writeUint16BE(_itemOwnerID);
|
||||
stream->writeUint16BE(_itemState);
|
||||
}
|
||||
|
||||
void Item::readFromStream(Common::ReadStream *stream) {
|
||||
_itemNeighborhood = stream->readUint16BE();
|
||||
_itemRoom = stream->readUint16BE();
|
||||
_itemDirection = stream->readByte();
|
||||
_itemOwnerID = stream->readUint16BE();
|
||||
_itemState = stream->readUint16BE();
|
||||
}
|
||||
|
||||
ActorID Item::getItemOwner() const {
|
||||
return _itemOwnerID;
|
||||
}
|
||||
|
||||
void Item::setItemOwner(const ActorID owner) {
|
||||
_itemOwnerID = owner;
|
||||
|
||||
if (owner == kNoActorID) {
|
||||
if (isSelected())
|
||||
deselect();
|
||||
removedFromInventory();
|
||||
} else {
|
||||
addedToInventory();
|
||||
}
|
||||
}
|
||||
|
||||
WeightType Item::getItemWeight() {
|
||||
return _itemWeight;
|
||||
}
|
||||
|
||||
ItemState Item::getItemState() const {
|
||||
return _itemState;
|
||||
}
|
||||
|
||||
void Item::setItemState(const ItemState state) {
|
||||
if (state != _itemState) {
|
||||
_itemState = state;
|
||||
|
||||
if (getItemType() == kInventoryItemType && g_vm->getCurrentInventoryItem() == (InventoryItem *)this)
|
||||
select();
|
||||
else if (getItemType() == kBiochipItemType && g_vm->getCurrentBiochip() == (BiochipItem *)this)
|
||||
select();
|
||||
}
|
||||
}
|
||||
|
||||
void Item::getItemRoom(NeighborhoodID &neighborhood, RoomID &room, DirectionConstant &direction) const {
|
||||
neighborhood = _itemNeighborhood;
|
||||
room = _itemRoom;
|
||||
direction = _itemDirection;
|
||||
}
|
||||
|
||||
void Item::setItemRoom(const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction) {
|
||||
_itemNeighborhood = neighborhood;
|
||||
_itemRoom = room;
|
||||
_itemDirection = direction;
|
||||
|
||||
if (neighborhood == kNoNeighborhoodID)
|
||||
pickedUp();
|
||||
else
|
||||
dropped();
|
||||
}
|
||||
|
||||
NeighborhoodID Item::getItemNeighborhood() const {
|
||||
return _itemNeighborhood;
|
||||
}
|
||||
|
||||
TimeValue Item::getSharedAreaTime() const {
|
||||
if (!_sharedAreaInfo.entries)
|
||||
return 0xffffffff;
|
||||
|
||||
TimeValue time;
|
||||
ItemState state;
|
||||
|
||||
findItemStateEntryByState(_sharedAreaInfo, _itemState, time);
|
||||
if (time == 0xffffffff)
|
||||
getItemStateEntry(_sharedAreaInfo, 0, state, time);
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
// Must affect images in shared area.
|
||||
void Item::select() {
|
||||
_isSelected = true;
|
||||
|
||||
if (g_AIArea) {
|
||||
if (getItemType() == kInventoryItemType)
|
||||
g_AIArea->setAIAreaToTime(kInventorySignature, kMiddleAreaSignature, getSharedAreaTime());
|
||||
else
|
||||
g_AIArea->setAIAreaToTime(kBiochipSignature, kMiddleAreaSignature, getSharedAreaTime());
|
||||
}
|
||||
}
|
||||
|
||||
void Item::deselect() {
|
||||
_isActive = false;
|
||||
_isSelected = false;
|
||||
|
||||
if (g_AIArea) {
|
||||
if (getItemType() == kInventoryItemType)
|
||||
g_AIArea->setAIAreaToTime(kInventorySignature, kMiddleAreaSignature, 0xffffffff);
|
||||
else
|
||||
g_AIArea->setAIAreaToTime(kBiochipSignature, kMiddleAreaSignature, 0xffffffff);
|
||||
}
|
||||
}
|
||||
|
||||
void Item::getItemStateEntry(ItemStateInfo info, uint32 index, ItemState &state, TimeValue &time) {
|
||||
if (index < info.numEntries) {
|
||||
state = info.entries[index].itemState;
|
||||
time = info.entries[index].itemTime;
|
||||
} else {
|
||||
state = kNoItemState;
|
||||
time = 0xffffffff;
|
||||
}
|
||||
}
|
||||
|
||||
void Item::findItemStateEntryByState(ItemStateInfo info, ItemState state, TimeValue &time) {
|
||||
for (uint16 i = 0; i < info.numEntries; i++) {
|
||||
if (info.entries[i].itemState == state) {
|
||||
time = info.entries[i].itemTime;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
time = 0xffffffff;
|
||||
}
|
||||
|
||||
ItemStateInfo Item::readItemState(Common::SeekableReadStream *stream) {
|
||||
ItemStateInfo info;
|
||||
|
||||
info.numEntries = stream->readUint16BE();
|
||||
info.entries = new ItemStateEntry[info.numEntries];
|
||||
for (uint16 i = 0; i < info.numEntries; i++) {
|
||||
info.entries[i].itemState = stream->readSint16BE();
|
||||
info.entries[i].itemTime = stream->readUint32BE();
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
Sprite *Item::getDragSprite(const DisplayElementID id) const {
|
||||
Sprite *result = new Sprite(id);
|
||||
SpriteFrame *frame = new SpriteFrame();
|
||||
|
||||
frame->initFromPICTResource(g_vm->_resFork, _itemInfo.dragSpriteNormalID, true);
|
||||
result->addFrame(frame, 0, 0);
|
||||
|
||||
if (_itemInfo.dragSpriteNormalID != _itemInfo.dragSpriteUsedID) {
|
||||
frame = new SpriteFrame();
|
||||
frame->initFromPICTResource(g_vm->_resFork, _itemInfo.dragSpriteUsedID, true);
|
||||
}
|
||||
|
||||
result->addFrame(frame, 0, 0);
|
||||
result->setCurrentFrameIndex(0);
|
||||
return result;
|
||||
}
|
||||
|
||||
TimeValue Item::getInfoLeftTime() const {
|
||||
return _itemInfo.infoLeftTime;
|
||||
}
|
||||
|
||||
void Item::getInfoRightTimes(TimeValue &start, TimeValue &stop) const {
|
||||
start = _itemInfo.infoRightStart;
|
||||
stop = _itemInfo.infoRightStop;
|
||||
}
|
||||
|
||||
void Item::findItemExtra(const uint32 extraID, ItemExtraEntry &entry) {
|
||||
for (uint32 i = 0; i < _itemExtras.numEntries; i++) {
|
||||
if (_itemExtras.entries[i].extraID == extraID) {
|
||||
entry = _itemExtras.entries[i];
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
378
engines/pegasus/items/item.h
Normal file
378
engines/pegasus/items/item.h
Normal file
@@ -0,0 +1,378 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_ITEM_H
|
||||
#define PEGASUS_ITEMS_ITEM_H
|
||||
|
||||
#include "common/endian.h"
|
||||
|
||||
#include "pegasus/types.h"
|
||||
#include "pegasus/util.h"
|
||||
|
||||
namespace Common {
|
||||
class Error;
|
||||
class ReadStream;
|
||||
class WriteStream;
|
||||
class SeekableReadStream;
|
||||
}
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
// JMPItemInfo contains resource data used by all Items.
|
||||
|
||||
struct JMPItemInfo {
|
||||
TimeValue infoLeftTime;
|
||||
TimeValue infoRightStart;
|
||||
TimeValue infoRightStop;
|
||||
uint32 dragSpriteNormalID;
|
||||
uint32 dragSpriteUsedID;
|
||||
};
|
||||
|
||||
// ItemStateEntry contains a single state/TimeValue pair. The TimeValue is
|
||||
// the time value to set the shared area movie that corresponds with the given
|
||||
// state of an inventory item.
|
||||
|
||||
struct ItemStateEntry {
|
||||
ItemState itemState;
|
||||
TimeValue itemTime;
|
||||
};
|
||||
|
||||
struct ItemStateInfo {
|
||||
uint16 numEntries; // For easy ResEdit access
|
||||
ItemStateEntry *entries;
|
||||
};
|
||||
|
||||
// ItemExtraEntry
|
||||
|
||||
static const short kLeftAreaExtra = 0;
|
||||
static const short kMiddleAreaExtra = 1;
|
||||
static const short kRightAreaExtra = 2;
|
||||
|
||||
struct ItemExtraEntry {
|
||||
uint32 extraID;
|
||||
uint16 extraArea;
|
||||
TimeValue extraStart;
|
||||
TimeValue extraStop;
|
||||
};
|
||||
|
||||
struct ItemExtraInfo {
|
||||
uint16 numEntries; // For easy ResEdit access
|
||||
ItemExtraEntry *entries;
|
||||
};
|
||||
|
||||
// Inventory info resource type and ID:
|
||||
// Individual inventory items are stored in these resource types.
|
||||
// Resource ID is item ID + kItemBaseResID.
|
||||
|
||||
static const uint32 kItemInfoResType = MKTAG('I', 't', 'e', 'm'); // JMPItemInfoHandle
|
||||
static const uint32 kLeftAreaInfoResType = MKTAG('L', 'e', 'f', 't'); // ItemStateInfoHandle
|
||||
static const uint32 kMiddleAreaInfoResType = MKTAG('M', 'i', 'd', 'l'); // ItemStateInfoHandle
|
||||
static const uint32 kRightAreaInfoResType = MKTAG('R', 'g', 'h', 't'); // ItemStateInfoHandle
|
||||
static const uint32 kItemExtraInfoResType = MKTAG('I', 'X', 't', 'r'); // ItemExtraInfoHandle
|
||||
|
||||
static const uint16 kItemBaseResID = 128;
|
||||
|
||||
// Item IDs.
|
||||
|
||||
static const ItemID kAirMask = 7;
|
||||
static const ItemID kAntidote = 8;
|
||||
static const ItemID kArgonCanister = 9;
|
||||
static const ItemID kCardBomb = 10;
|
||||
static const ItemID kCrowbar = 11;
|
||||
static const ItemID kGasCanister = 12;
|
||||
static const ItemID kHistoricalLog = 13;
|
||||
static const ItemID kJourneymanKey = 14;
|
||||
static const ItemID kKeyCard = 15;
|
||||
static const ItemID kMachineGun = 16;
|
||||
static const ItemID kMarsCard = 17;
|
||||
static const ItemID kNitrogenCanister = 18;
|
||||
static const ItemID kOrangeJuiceGlassFull = 19;
|
||||
static const ItemID kOrangeJuiceGlassEmpty = 20;
|
||||
static const ItemID kPoisonDart = 21;
|
||||
static const ItemID kSinclairKey = 22;
|
||||
static const ItemID kStunGun = 23;
|
||||
static const ItemID kArgonPickup = 24;
|
||||
|
||||
// Biochips.
|
||||
|
||||
static const ItemID kAIBiochip = 0;
|
||||
static const ItemID kArthurBiochip = 1;
|
||||
static const ItemID kInterfaceBiochip = 1;
|
||||
static const ItemID kMapBiochip = 2;
|
||||
static const ItemID kOpticalBiochip = 3;
|
||||
static const ItemID kPegasusBiochip = 4;
|
||||
static const ItemID kRetinalScanBiochip = 5;
|
||||
static const ItemID kShieldBiochip = 6;
|
||||
|
||||
static const ItemID kNumItems = 25;
|
||||
|
||||
// Item States.
|
||||
|
||||
static const ItemState kAI000 = 0;
|
||||
static const ItemState kAI005 = 1;
|
||||
static const ItemState kAI006 = 2;
|
||||
static const ItemState kAI010 = 3;
|
||||
static const ItemState kAI015 = 4;
|
||||
static const ItemState kAI016 = 5;
|
||||
static const ItemState kAI020 = 6;
|
||||
static const ItemState kAI024 = 7;
|
||||
static const ItemState kAI100 = 8;
|
||||
static const ItemState kAI101 = 9;
|
||||
static const ItemState kAI105 = 10;
|
||||
static const ItemState kAI106 = 11;
|
||||
static const ItemState kAI110 = 12;
|
||||
static const ItemState kAI111 = 13;
|
||||
static const ItemState kAI115 = 14;
|
||||
static const ItemState kAI116 = 15;
|
||||
static const ItemState kAI120 = 16;
|
||||
static const ItemState kAI121 = 17;
|
||||
static const ItemState kAI124 = 18;
|
||||
static const ItemState kAI125 = 19;
|
||||
static const ItemState kAI126 = 20;
|
||||
static const ItemState kAI200 = 21;
|
||||
static const ItemState kAI201 = 22;
|
||||
static const ItemState kAI202 = 23;
|
||||
static const ItemState kAI205 = 24;
|
||||
static const ItemState kAI206 = 25;
|
||||
static const ItemState kAI210 = 26;
|
||||
static const ItemState kAI211 = 27;
|
||||
static const ItemState kAI212 = 28;
|
||||
static const ItemState kAI215 = 29;
|
||||
static const ItemState kAI216 = 30;
|
||||
static const ItemState kAI220 = 31;
|
||||
static const ItemState kAI221 = 32;
|
||||
static const ItemState kAI222 = 33;
|
||||
static const ItemState kAI224 = 34;
|
||||
static const ItemState kAI225 = 35;
|
||||
static const ItemState kAI226 = 36;
|
||||
static const ItemState kAI300 = 37;
|
||||
static const ItemState kAI301 = 38;
|
||||
static const ItemState kAI302 = 39;
|
||||
static const ItemState kAI303 = 40;
|
||||
static const ItemState kAI305 = 41;
|
||||
static const ItemState kAI306 = 42;
|
||||
static const ItemState kAI310 = 43;
|
||||
static const ItemState kAI311 = 44;
|
||||
static const ItemState kAI312 = 45;
|
||||
static const ItemState kAI313 = 46;
|
||||
static const ItemState kAI315 = 47;
|
||||
static const ItemState kAI316 = 48;
|
||||
static const ItemState kAI320 = 49;
|
||||
static const ItemState kAI321 = 50;
|
||||
static const ItemState kAI322 = 51;
|
||||
static const ItemState kAI323 = 52;
|
||||
static const ItemState kAI324 = 53;
|
||||
static const ItemState kAI325 = 54;
|
||||
static const ItemState kAI326 = 55;
|
||||
static const ItemState kNormalItem = 56;
|
||||
static const ItemState kMapUnavailable = 57;
|
||||
static const ItemState kMapEngaged = 58;
|
||||
static const ItemState kOptical000 = 59;
|
||||
static const ItemState kOptical001 = 60;
|
||||
static const ItemState kOptical002 = 61;
|
||||
static const ItemState kOptical010 = 62;
|
||||
static const ItemState kOptical011 = 63;
|
||||
static const ItemState kOptical012 = 64;
|
||||
static const ItemState kOptical020 = 65;
|
||||
static const ItemState kOptical021 = 66;
|
||||
static const ItemState kOptical100 = 67;
|
||||
static const ItemState kOptical101 = 68;
|
||||
static const ItemState kOptical102 = 69;
|
||||
static const ItemState kOptical110 = 70;
|
||||
static const ItemState kOptical111 = 71;
|
||||
static const ItemState kOptical112 = 72;
|
||||
static const ItemState kOptical120 = 73;
|
||||
static const ItemState kOptical121 = 74;
|
||||
static const ItemState kOptical200 = 75;
|
||||
static const ItemState kOptical201 = 76;
|
||||
static const ItemState kOptical210 = 77;
|
||||
static const ItemState kOptical211 = 78;
|
||||
static const ItemState kPegasusTSA00 = 79;
|
||||
static const ItemState kPegasusTSA10 = 80;
|
||||
static const ItemState kPegasusPrehistoric00 = 81;
|
||||
static const ItemState kPegasusPrehistoric01 = 82;
|
||||
static const ItemState kPegasusPrehistoric10 = 83;
|
||||
static const ItemState kPegasusPrehistoric11 = 84;
|
||||
static const ItemState kPegasusMars00 = 85;
|
||||
static const ItemState kPegasusMars01 = 86;
|
||||
static const ItemState kPegasusMars10 = 87;
|
||||
static const ItemState kPegasusMars11 = 88;
|
||||
static const ItemState kPegasusNorad00 = 89;
|
||||
static const ItemState kPegasusNorad01 = 90;
|
||||
static const ItemState kPegasusNorad10 = 91;
|
||||
static const ItemState kPegasusNorad11 = 92;
|
||||
static const ItemState kPegasusWSC00 = 93;
|
||||
static const ItemState kPegasusWSC01 = 94;
|
||||
static const ItemState kPegasusWSC10 = 95;
|
||||
static const ItemState kPegasusWSC11 = 96;
|
||||
static const ItemState kPegasusCaldoria = 97;
|
||||
static const ItemState kRetinalSimulating = 98;
|
||||
static const ItemState kShieldNormal = 99;
|
||||
static const ItemState kShieldRadiation = 100;
|
||||
static const ItemState kShieldPlasma = 101;
|
||||
static const ItemState kShieldCardBomb = 102;
|
||||
static const ItemState kShieldDraining = 103;
|
||||
static const ItemState kAirMaskEmptyOff = 104;
|
||||
static const ItemState kAirMaskEmptyFilter = 105;
|
||||
static const ItemState kAirMaskLowOff = 106;
|
||||
static const ItemState kAirMaskLowFilter = 107;
|
||||
static const ItemState kAirMaskLowOn = 108;
|
||||
static const ItemState kAirMaskFullOff = 109;
|
||||
static const ItemState kAirMaskFullFilter = 110;
|
||||
static const ItemState kAirMaskFullOn = 111;
|
||||
static const ItemState kArgonEmpty = 112;
|
||||
static const ItemState kArgonFull = 113;
|
||||
static const ItemState kFlashlightOff = 114;
|
||||
static const ItemState kFlashlightOn = 115;
|
||||
static const ItemState kNitrogenEmpty = 116;
|
||||
static const ItemState kNitrogenFull = 117;
|
||||
static const ItemState kFullGlass = 118;
|
||||
static const ItemState kArthur000 = 119;
|
||||
static const ItemState kArthur002 = 120;
|
||||
static const ItemState kArthur010 = 121;
|
||||
static const ItemState kArthur012 = 122;
|
||||
static const ItemState kArthur100 = 123;
|
||||
static const ItemState kArthur102 = 124;
|
||||
static const ItemState kArthur110 = 125;
|
||||
static const ItemState kArthur112 = 126;
|
||||
|
||||
// Extra IDs.
|
||||
|
||||
static const uint32 kRetinalScanSearching = 0;
|
||||
static const uint32 kRetinalScanActivated = 1;
|
||||
static const uint32 kShieldIntro = 2;
|
||||
static const uint32 kRemoveAirMask = 3;
|
||||
static const uint32 kRemoveArgon = 4;
|
||||
static const uint32 kRemoveCrowbar = 5;
|
||||
static const uint32 kGasCanLoop = 6;
|
||||
static const uint32 kRemoveJourneymanKey = 7;
|
||||
static const uint32 kRemoveMarsCard = 8;
|
||||
static const uint32 kRemoveNitrogen = 9;
|
||||
static const uint32 kRemoveGlass = 10;
|
||||
static const uint32 kRemoveDart = 11;
|
||||
static const uint32 kRemoveSinclairKey = 12;
|
||||
|
||||
enum ItemType {
|
||||
kInventoryItemType,
|
||||
kBiochipItemType
|
||||
};
|
||||
|
||||
class Sprite;
|
||||
|
||||
/*
|
||||
|
||||
Item is an object which can be picked up and carried around.
|
||||
Items have
|
||||
a location
|
||||
an ID.
|
||||
weight
|
||||
an owner (kNoActorID if no one is carrying the Item)
|
||||
|
||||
*/
|
||||
|
||||
class Item : public IDObject {
|
||||
public:
|
||||
Item(const ItemID id, const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction);
|
||||
virtual ~Item();
|
||||
|
||||
// WriteToStream writes everything EXCEPT the item's ID.
|
||||
// It is assumed that the calling function will write and read the ID.
|
||||
virtual void writeToStream(Common::WriteStream *stream);
|
||||
virtual void readFromStream(Common::ReadStream *stream);
|
||||
|
||||
virtual ActorID getItemOwner() const;
|
||||
virtual void setItemOwner(const ActorID owner);
|
||||
|
||||
void getItemRoom(NeighborhoodID &neighborhood, RoomID &room, DirectionConstant &direction) const;
|
||||
void setItemRoom(const NeighborhoodID neighborhood, const RoomID room, const DirectionConstant direction);
|
||||
NeighborhoodID getItemNeighborhood() const;
|
||||
|
||||
virtual WeightType getItemWeight();
|
||||
|
||||
virtual void setItemState(const ItemState state);
|
||||
virtual ItemState getItemState() const;
|
||||
|
||||
virtual ItemType getItemType() = 0;
|
||||
|
||||
TimeValue getInfoLeftTime() const;
|
||||
void getInfoRightTimes(TimeValue &, TimeValue &) const;
|
||||
TimeValue getSharedAreaTime() const;
|
||||
|
||||
Sprite *getDragSprite(const DisplayElementID) const;
|
||||
|
||||
/*
|
||||
select -- called when this item becomes current. Also called when the inventory
|
||||
panel holding this item is raised and this is the current item.
|
||||
deselect -- called when this item is no longer current.
|
||||
activate -- called on the current item when the panel is closed.
|
||||
*/
|
||||
// In an override of these three member functions, you must call the inherited
|
||||
// member functions.
|
||||
virtual void select();
|
||||
virtual void deselect();
|
||||
virtual bool isSelected() { return _isSelected; }
|
||||
|
||||
virtual void activate() { _isActive = true; }
|
||||
virtual bool isActive() { return _isActive; }
|
||||
virtual void pickedUp() {}
|
||||
virtual void addedToInventory() {}
|
||||
virtual void removedFromInventory() {}
|
||||
virtual void dropped() {}
|
||||
|
||||
// Called when the shared area is taken by another item, but this item is still
|
||||
// selected.
|
||||
virtual void giveUpSharedArea() {}
|
||||
virtual void takeSharedArea() {}
|
||||
|
||||
void findItemExtra(const uint32 extraID, ItemExtraEntry &entry);
|
||||
|
||||
// Reset to its original state at the beginning of the game
|
||||
void reset();
|
||||
|
||||
protected:
|
||||
NeighborhoodID _itemNeighborhood;
|
||||
RoomID _itemRoom;
|
||||
DirectionConstant _itemDirection;
|
||||
ActorID _itemOwnerID;
|
||||
WeightType _itemWeight;
|
||||
ItemState _itemState;
|
||||
|
||||
NeighborhoodID _originalNeighborhood;
|
||||
RoomID _originalRoom;
|
||||
DirectionConstant _originalDirection;
|
||||
|
||||
JMPItemInfo _itemInfo;
|
||||
ItemStateInfo _sharedAreaInfo;
|
||||
ItemExtraInfo _itemExtras;
|
||||
bool _isActive;
|
||||
bool _isSelected;
|
||||
|
||||
static void getItemStateEntry(ItemStateInfo, uint32, ItemState &, TimeValue &);
|
||||
static void findItemStateEntryByState(ItemStateInfo, ItemState, TimeValue &);
|
||||
static ItemStateInfo readItemState(Common::SeekableReadStream *stream);
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
192
engines/pegasus/items/itemdragger.cpp
Normal file
192
engines/pegasus/items/itemdragger.cpp
Normal file
@@ -0,0 +1,192 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/elements.h"
|
||||
#include "pegasus/hotspot.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/items/itemdragger.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
SpriteDragger::SpriteDragger() {
|
||||
_draggingSprite = nullptr;
|
||||
_limitRect = Common::Rect(-30000, -30000, 30000, 30000);
|
||||
_slopRect = Common::Rect(-30000, -30000, 30000, 30000);
|
||||
_dragOffset.x = 0;
|
||||
_dragOffset.y = 0;
|
||||
_lastHotspot = nullptr;
|
||||
}
|
||||
|
||||
void SpriteDragger::setDragSprite(Sprite *newSprite) {
|
||||
if (!isTracking())
|
||||
_draggingSprite = newSprite;
|
||||
}
|
||||
|
||||
void SpriteDragger::setDragConstraints(const Common::Rect &limitRect, const Common::Rect &slopRect) {
|
||||
if (!isTracking()) {
|
||||
_rawLimitRect = limitRect;
|
||||
_slopRect = slopRect;
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteDragger::getDragConstraints(Common::Rect &limitRect, Common::Rect &slopRect) const {
|
||||
limitRect = _rawLimitRect;
|
||||
slopRect = _slopRect;
|
||||
}
|
||||
|
||||
void SpriteDragger::startTracking(const Input &input) {
|
||||
if (_draggingSprite) {
|
||||
Tracker::startTracking(input);
|
||||
|
||||
if (isTracking()) {
|
||||
input.getInputLocation(_startPoint);
|
||||
_lastRawPoint = _startRawPoint = _startPoint;
|
||||
|
||||
Common::Rect r;
|
||||
_draggingSprite->getBounds(r);
|
||||
_dragOffset.x = _startPoint.x - r.left;
|
||||
_dragOffset.y = _startPoint.y - r.top;
|
||||
|
||||
_limitRect = _rawLimitRect;
|
||||
_limitRect.left += _dragOffset.x;
|
||||
_limitRect.top += _dragOffset.y;
|
||||
_limitRect.right -= r.width() - _dragOffset.x;
|
||||
_limitRect.bottom -= r.height() - _dragOffset.y;
|
||||
pinPointInRect(_limitRect, _startPoint);
|
||||
|
||||
_lastPoint = _startPoint;
|
||||
if (_startPoint != _startRawPoint) {
|
||||
Common::Point pt = _startPoint - _dragOffset;
|
||||
_draggingSprite->moveElementTo(pt.x, pt.y);
|
||||
}
|
||||
|
||||
_lastHotspot = g_allHotspots.findHotspot(_lastRawPoint);
|
||||
if (_lastHotspot)
|
||||
enterHotspot(_lastHotspot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteDragger::continueTracking(const Input &input) {
|
||||
if (_draggingSprite) {
|
||||
Common::Point rawPoint;
|
||||
input.getInputLocation(rawPoint);
|
||||
|
||||
if (!_slopRect.contains(rawPoint))
|
||||
rawPoint = _startRawPoint;
|
||||
|
||||
if (rawPoint != _lastRawPoint) {
|
||||
Common::Point newPoint = rawPoint;
|
||||
pinPointInRect(_limitRect, newPoint);
|
||||
newPoint -= _dragOffset;
|
||||
|
||||
if (newPoint != _lastPoint) {
|
||||
_draggingSprite->moveElementTo(newPoint.x, newPoint.y);
|
||||
_lastPoint = newPoint;
|
||||
}
|
||||
|
||||
Hotspot *newHotspot = g_allHotspots.findHotspot(rawPoint);
|
||||
if (newHotspot != _lastHotspot) {
|
||||
if (_lastHotspot)
|
||||
exitHotspot(_lastHotspot);
|
||||
if (newHotspot)
|
||||
enterHotspot(newHotspot);
|
||||
_lastHotspot = newHotspot;
|
||||
}
|
||||
|
||||
_lastRawPoint = rawPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteDragger::pinPointInRect(const Common::Rect &r, Common::Point &pt) {
|
||||
pt.x = CLIP<int>(pt.x, r.left, r.right - 1);
|
||||
pt.y = CLIP<int>(pt.y, r.top, r.bottom - 1);
|
||||
}
|
||||
|
||||
ItemDragger::ItemDragger(PegasusEngine *owner) : _inventoryDropSpot(kInventoryDropSpotID), _biochipDropSpot(kBiochipDropSpotID),
|
||||
_inventoryHighlight(kInventoryDropHighlightID), _biochipHighlight(kBiochipDropHighlightID) {
|
||||
_owner = owner;
|
||||
|
||||
Common::Rect r(kInventoryDropLeft, kInventoryDropTop, kInventoryDropRight, kInventoryDropBottom);
|
||||
_inventoryDropSpot.setArea(r);
|
||||
_inventoryDropSpot.setHotspotFlags(kDropItemSpotFlag);
|
||||
owner->getAllHotspots().push_back(&_inventoryDropSpot);
|
||||
|
||||
r = Common::Rect(kBiochipDropLeft, kBiochipDropTop, kBiochipDropRight, kBiochipDropBottom);
|
||||
_biochipDropSpot.setArea(r);
|
||||
_biochipDropSpot.setHotspotFlags(kDropBiochipSpotFlag);
|
||||
owner->getAllHotspots().push_back(&_biochipDropSpot);
|
||||
}
|
||||
|
||||
void ItemDragger::startTracking(const Input &input) {
|
||||
_inventoryHighlight.setDisplayOrder(kInventoryHiliteOrder);
|
||||
_inventoryHighlight.startDisplaying();
|
||||
|
||||
_biochipHighlight.setDisplayOrder(kBiochipHiliteOrder);
|
||||
_biochipHighlight.startDisplaying();
|
||||
|
||||
SpriteDragger::startTracking(input);
|
||||
}
|
||||
|
||||
void ItemDragger::stopTracking(const Input &input) {
|
||||
SpriteDragger::stopTracking(input);
|
||||
_inventoryHighlight.hide();
|
||||
_biochipHighlight.hide();
|
||||
_inventoryHighlight.stopDisplaying();
|
||||
_biochipHighlight.stopDisplaying();
|
||||
_owner->dragTerminated(input);
|
||||
}
|
||||
|
||||
bool ItemDragger::stopTrackingInput(const Input &input) {
|
||||
return !JMPPPInput::isDraggingInput(input);
|
||||
}
|
||||
|
||||
void ItemDragger::enterHotspot(Hotspot *spot) {
|
||||
if (spot->getObjectID() == kInventoryDropSpotID)
|
||||
_inventoryHighlight.show();
|
||||
else if (spot->getObjectID() == kBiochipDropSpotID)
|
||||
_biochipHighlight.show();
|
||||
else if ((spot->getHotspotFlags() & kDropItemSpotFlag) != 0)
|
||||
_draggingSprite->setCurrentFrameIndex(1);
|
||||
}
|
||||
|
||||
void ItemDragger::exitHotspot(Hotspot *spot) {
|
||||
if (spot->getObjectID() == kInventoryDropSpotID)
|
||||
_inventoryHighlight.hide();
|
||||
else if (spot->getObjectID() == kBiochipDropSpotID)
|
||||
_biochipHighlight.hide();
|
||||
else if ((spot->getHotspotFlags() & kDropItemSpotFlag) != 0)
|
||||
_draggingSprite->setCurrentFrameIndex(0);
|
||||
}
|
||||
|
||||
void ItemDragger::setHighlightBounds() {
|
||||
uint32 color = g_system->getScreenFormat().RGBToColor(0x48, 0x80, 0xD8);
|
||||
_inventoryHighlight.setBounds(Common::Rect(76, 334, 172, 430));
|
||||
_inventoryHighlight.setHighlightColor(color);
|
||||
_biochipHighlight.setBounds(Common::Rect(364, 334, 460, 430));
|
||||
_biochipHighlight.setHighlightColor(color);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
95
engines/pegasus/items/itemdragger.h
Normal file
95
engines/pegasus/items/itemdragger.h
Normal file
@@ -0,0 +1,95 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_ITEMDRAGGER_H
|
||||
#define PEGASUS_ITEMS_ITEMDRAGGER_H
|
||||
|
||||
#include "pegasus/elements.h"
|
||||
#include "pegasus/input.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
// TODO: Merge SpriteDragger and ItemDragger
|
||||
|
||||
class Hotspot;
|
||||
class Sprite;
|
||||
|
||||
class SpriteDragger : public Tracker {
|
||||
public:
|
||||
SpriteDragger();
|
||||
~SpriteDragger() override {}
|
||||
|
||||
void setDragSprite(Sprite *);
|
||||
Sprite *getDragSprite() { return _draggingSprite; }
|
||||
|
||||
void setDragConstraints(const Common::Rect &, const Common::Rect &);
|
||||
void getDragConstraints(Common::Rect &, Common::Rect &) const;
|
||||
|
||||
void startTracking(const Input &) override;
|
||||
void continueTracking(const Input&) override;
|
||||
|
||||
Hotspot *getLastHotspot() const { return _lastHotspot; }
|
||||
|
||||
protected:
|
||||
virtual void enterHotspot(Hotspot *) {}
|
||||
virtual void exitHotspot(Hotspot *) {}
|
||||
|
||||
Sprite *_draggingSprite;
|
||||
Common::Point _startPoint, _lastPoint, _dragOffset;
|
||||
Common::Point _startRawPoint, _lastRawPoint;
|
||||
Common::Rect _rawLimitRect;
|
||||
Common::Rect _limitRect;
|
||||
Common::Rect _slopRect;
|
||||
Hotspot *_lastHotspot;
|
||||
|
||||
// This is a replica of QuickDraw's PinPointInRect function
|
||||
void pinPointInRect(const Common::Rect &, Common::Point &);
|
||||
};
|
||||
|
||||
class PegasusEngine;
|
||||
|
||||
class ItemDragger : public SpriteDragger {
|
||||
public:
|
||||
ItemDragger(PegasusEngine *);
|
||||
~ItemDragger() override {}
|
||||
|
||||
void setHighlightBounds();
|
||||
void startTracking(const Input &) override;
|
||||
void stopTracking(const Input &) override;
|
||||
bool stopTrackingInput(const Input &) override;
|
||||
|
||||
protected:
|
||||
void enterHotspot(Hotspot *) override;
|
||||
void exitHotspot(Hotspot *) override;
|
||||
|
||||
PegasusEngine *_owner;
|
||||
DropHighlight _inventoryHighlight;
|
||||
Hotspot _inventoryDropSpot;
|
||||
DropHighlight _biochipHighlight;
|
||||
Hotspot _biochipDropSpot;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
71
engines/pegasus/items/itemlist.cpp
Normal file
71
engines/pegasus/items/itemlist.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/error.h"
|
||||
#include "common/stream.h"
|
||||
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/items/item.h"
|
||||
#include "pegasus/items/itemlist.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
ItemList::ItemList() {
|
||||
}
|
||||
|
||||
ItemList::~ItemList() {
|
||||
}
|
||||
|
||||
void ItemList::writeToStream(Common::WriteStream *stream) {
|
||||
stream->writeUint32BE(size());
|
||||
|
||||
for (ItemIterator it = begin(); it != end(); it++) {
|
||||
stream->writeUint16BE((*it)->getObjectID());
|
||||
(*it)->writeToStream(stream);
|
||||
}
|
||||
}
|
||||
|
||||
void ItemList::readFromStream(Common::ReadStream *stream) {
|
||||
uint32 itemCount = stream->readUint32BE();
|
||||
|
||||
for (uint32 i = 0; i < itemCount; i++) {
|
||||
ItemID itemID = stream->readUint16BE();
|
||||
g_allItems.findItemByID(itemID)->readFromStream(stream);
|
||||
}
|
||||
}
|
||||
|
||||
Item *ItemList::findItemByID(const ItemID id) {
|
||||
for (ItemIterator it = begin(); it != end(); it++)
|
||||
if ((*it)->getObjectID() == id)
|
||||
return *it;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ItemList::resetAllItems() {
|
||||
for (ItemIterator it = begin(); it != end(); it++)
|
||||
(*it)->reset();
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
59
engines/pegasus/items/itemlist.h
Normal file
59
engines/pegasus/items/itemlist.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_ITEMS_ITEMLIST_H
|
||||
#define PEGASUS_ITEMS_ITEMLIST_H
|
||||
|
||||
#include "common/list.h"
|
||||
|
||||
#include "pegasus/types.h"
|
||||
|
||||
namespace Common {
|
||||
class ReadStream;
|
||||
class WriteStream;
|
||||
}
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class Item;
|
||||
|
||||
class ItemList : public Common::List<Item *> {
|
||||
public:
|
||||
ItemList();
|
||||
virtual ~ItemList();
|
||||
|
||||
virtual void writeToStream(Common::WriteStream *stream);
|
||||
virtual void readFromStream(Common::ReadStream *stream);
|
||||
|
||||
Item *findItemByID(const ItemID id);
|
||||
void resetAllItems();
|
||||
};
|
||||
|
||||
typedef ItemList::iterator ItemIterator;
|
||||
|
||||
#define g_allItems g_vm->getAllItems()
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
1299
engines/pegasus/menu.cpp
Normal file
1299
engines/pegasus/menu.cpp
Normal file
File diff suppressed because it is too large
Load Diff
175
engines/pegasus/menu.h
Normal file
175
engines/pegasus/menu.h
Normal file
@@ -0,0 +1,175 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_MENU_H
|
||||
#define PEGASUS_MENU_H
|
||||
|
||||
#include "pegasus/constants.h"
|
||||
#include "pegasus/fader.h"
|
||||
#include "pegasus/input.h"
|
||||
#include "pegasus/movie.h"
|
||||
#include "pegasus/sound.h"
|
||||
#include "pegasus/surface.h"
|
||||
#include "pegasus/util.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class GameMenu : public IDObject, public InputHandler {
|
||||
public:
|
||||
GameMenu(const uint32);
|
||||
~GameMenu() override {}
|
||||
|
||||
virtual void becomeCurrentHandler();
|
||||
virtual void restorePreviousHandler();
|
||||
|
||||
GameMenuCommand getLastCommand() { return _lastCommand; }
|
||||
void clearLastCommand() { _lastCommand = kMenuCmdNoCommand; }
|
||||
|
||||
protected:
|
||||
void setLastCommand(const GameMenuCommand command) { _lastCommand = command; }
|
||||
|
||||
InputHandler *_previousHandler;
|
||||
GameMenuCommand _lastCommand;
|
||||
|
||||
void drawScore(GameScoreType, GameScoreType, const Common::Rect &, Surface *);
|
||||
|
||||
private:
|
||||
void drawNumber(GameScoreType, CoordType &, CoordType, Surface *);
|
||||
};
|
||||
|
||||
class Hotspot;
|
||||
|
||||
class MainMenu : public GameMenu {
|
||||
public:
|
||||
MainMenu();
|
||||
~MainMenu() override;
|
||||
|
||||
void handleInput(const Input &input, const Hotspot *) override;
|
||||
void startMainMenuLoop();
|
||||
void stopMainMenuLoop();
|
||||
|
||||
protected:
|
||||
void updateDisplay();
|
||||
|
||||
uint32 _menuSelection;
|
||||
|
||||
// Full and Demo
|
||||
Picture _menuBackground;
|
||||
Picture _startButton;
|
||||
Picture _creditsButton;
|
||||
Picture _quitButton;
|
||||
Picture _largeSelect;
|
||||
Picture _smallSelect;
|
||||
|
||||
// Full only
|
||||
bool _adventureMode;
|
||||
Picture _overviewButton;
|
||||
Picture _restoreButton;
|
||||
Picture _adventureButton;
|
||||
Picture _walkthroughButton;
|
||||
|
||||
Sound _menuLoop;
|
||||
SoundFader _menuFader;
|
||||
};
|
||||
|
||||
class CreditsMenu : public GameMenu {
|
||||
public:
|
||||
CreditsMenu();
|
||||
~CreditsMenu() override;
|
||||
|
||||
void handleInput(const Input &input, const Hotspot *) override;
|
||||
void startCreditsMenuLoop();
|
||||
void stopCreditsMenuLoop();
|
||||
|
||||
protected:
|
||||
void newMenuSelection(const int);
|
||||
void newMovieTime(const TimeValue);
|
||||
|
||||
int _menuSelection;
|
||||
Picture _menuBackground;
|
||||
Movie _creditsMovie;
|
||||
Picture _mainMenuButton;
|
||||
Picture _largeSelect;
|
||||
Picture _smallSelect;
|
||||
|
||||
Sound _menuLoop;
|
||||
SoundFader _menuFader;
|
||||
};
|
||||
|
||||
class DeathMenu : public GameMenu {
|
||||
public:
|
||||
DeathMenu(const DeathReason);
|
||||
~DeathMenu() override {}
|
||||
|
||||
void handleInput(const Input &input, const Hotspot *) override;
|
||||
|
||||
bool playerWon() { return _playerWon; }
|
||||
|
||||
protected:
|
||||
void drawAllScores();
|
||||
|
||||
void updateDisplay();
|
||||
|
||||
bool _playerWon;
|
||||
int _menuSelection;
|
||||
DeathReason _deathReason;
|
||||
|
||||
Picture _deathBackground;
|
||||
Picture _continueButton;
|
||||
Picture _restoreButton;
|
||||
Picture _mainMenuButton;
|
||||
Picture _quitButton;
|
||||
|
||||
Picture _largeSelect;
|
||||
Picture _smallSelect;
|
||||
|
||||
Sound _triumphSound;
|
||||
};
|
||||
|
||||
class PauseMenu : public GameMenu {
|
||||
public:
|
||||
PauseMenu();
|
||||
~PauseMenu() override {}
|
||||
|
||||
void handleInput(const Input &input, const Hotspot *) override;
|
||||
|
||||
protected:
|
||||
void updateDisplay();
|
||||
|
||||
uint32 _menuSelection;
|
||||
Picture _pauseBackground;
|
||||
Picture _saveButton;
|
||||
Picture _restoreButton;
|
||||
Picture _walkthroughButton;
|
||||
Picture _continueButton;
|
||||
SoundLevel _soundFXLevel;
|
||||
SoundLevel _ambienceLevel;
|
||||
Picture _quitButton;
|
||||
Picture _largeSelect;
|
||||
Picture _smallSelect;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
139
engines/pegasus/metaengine.cpp
Normal file
139
engines/pegasus/metaengine.cpp
Normal file
@@ -0,0 +1,139 @@
|
||||
/* 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.
|
||||
*
|
||||
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "base/plugins.h"
|
||||
|
||||
#include "engines/advancedDetector.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/file.h"
|
||||
#include "common/savefile.h"
|
||||
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/detection.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
bool PegasusEngine::hasFeature(EngineFeature f) const {
|
||||
return
|
||||
(f == kSupportsReturnToLauncher)
|
||||
|| (f == kSupportsLoadingDuringRuntime)
|
||||
|| (f == kSupportsSavingDuringRuntime);
|
||||
}
|
||||
|
||||
bool PegasusEngine::isDemo() const {
|
||||
return (_gameDescription->desc.flags & ADGF_DEMO) != 0;
|
||||
}
|
||||
|
||||
bool PegasusEngine::isDVD() const {
|
||||
return (_gameDescription->desc.flags & ADGF_DVD) != 0;
|
||||
}
|
||||
|
||||
bool PegasusEngine::isDVDDemo() const {
|
||||
return isDemo() && isDVD();
|
||||
}
|
||||
|
||||
bool PegasusEngine::isOldDemo() const {
|
||||
return isDemo() && !isDVD();
|
||||
}
|
||||
|
||||
bool PegasusEngine::isWindows() const {
|
||||
return _gameDescription->desc.platform == Common::kPlatformWindows;
|
||||
}
|
||||
|
||||
bool PegasusEngine::isLinux() const {
|
||||
return _gameDescription->desc.platform == Common::kPlatformLinux;
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
class PegasusMetaEngine : public AdvancedMetaEngine<Pegasus::PegasusGameDescription> {
|
||||
public:
|
||||
const char *getName() const override {
|
||||
return "pegasus";
|
||||
}
|
||||
|
||||
bool hasFeature(MetaEngineFeature f) const override;
|
||||
Common::Error createInstance(OSystem *syst, Engine **engine, const Pegasus::PegasusGameDescription *desc) const override;
|
||||
|
||||
SaveStateList listSaves(const char *target) const override;
|
||||
int getMaximumSaveSlot() const override { return 999; }
|
||||
bool removeSaveState(const char *target, int slot) const override;
|
||||
Common::KeymapArray initKeymaps(const char *target) const override;
|
||||
Common::String getSavegameFile(int saveGameIdx, const char *target) const override {
|
||||
if (saveGameIdx == kSavegameFilePattern)
|
||||
return Common::String::format("pegasus-*.sav");
|
||||
Common::StringArray fileNames = Pegasus::PegasusEngine::listSaveFiles();
|
||||
if (saveGameIdx < (int)fileNames.size())
|
||||
return fileNames[saveGameIdx];
|
||||
if (fileNames.empty())
|
||||
return Common::String("pegasus-1.sav");
|
||||
Common::String name = fileNames.back();
|
||||
name.insertString("_last", name.size() - 4);
|
||||
return name;
|
||||
}
|
||||
};
|
||||
|
||||
bool PegasusMetaEngine::hasFeature(MetaEngineFeature f) const {
|
||||
return
|
||||
(f == kSupportsListSaves)
|
||||
|| (f == kSupportsLoadingDuringStartup)
|
||||
|| (f == kSupportsDeleteSave);
|
||||
}
|
||||
|
||||
SaveStateList PegasusMetaEngine::listSaves(const char *target) const {
|
||||
// The original had no pattern, so the user must rename theirs
|
||||
// Note that we ignore the target because saves are compatible between
|
||||
// all versions
|
||||
Common::StringArray fileNames = Pegasus::PegasusEngine::listSaveFiles();
|
||||
|
||||
SaveStateList saveList;
|
||||
for (uint32 i = 0; i < fileNames.size(); i++) {
|
||||
// Isolate the description from the file name
|
||||
Common::String desc = fileNames[i].c_str() + 8;
|
||||
for (int j = 0; j < 4; j++)
|
||||
desc.deleteLastChar();
|
||||
|
||||
saveList.push_back(SaveStateDescriptor(this, i, desc));
|
||||
}
|
||||
|
||||
return saveList;
|
||||
}
|
||||
|
||||
bool PegasusMetaEngine::removeSaveState(const char *target, int slot) const {
|
||||
// See listSaves() for info on the pattern
|
||||
Common::StringArray fileNames = Pegasus::PegasusEngine::listSaveFiles();
|
||||
return g_system->getSavefileManager()->removeSavefile(fileNames[slot].c_str());
|
||||
}
|
||||
|
||||
Common::KeymapArray PegasusMetaEngine::initKeymaps(const char *target) const {
|
||||
return Pegasus::PegasusEngine::initKeymaps();
|
||||
}
|
||||
|
||||
Common::Error PegasusMetaEngine::createInstance(OSystem *syst, Engine **engine, const Pegasus::PegasusGameDescription *desc) const {
|
||||
*engine = new Pegasus::PegasusEngine(syst,desc);
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
#if PLUGIN_ENABLED_DYNAMIC(PEGASUS)
|
||||
REGISTER_PLUGIN_DYNAMIC(PEGASUS, PLUGIN_TYPE_ENGINE, PegasusMetaEngine);
|
||||
#else
|
||||
REGISTER_PLUGIN_STATIC(PEGASUS, PLUGIN_TYPE_ENGINE, PegasusMetaEngine);
|
||||
#endif
|
||||
109
engines/pegasus/module.mk
Normal file
109
engines/pegasus/module.mk
Normal file
@@ -0,0 +1,109 @@
|
||||
MODULE := engines/pegasus
|
||||
|
||||
MODULE_OBJS = \
|
||||
chase.o \
|
||||
compass.o \
|
||||
console.o \
|
||||
cursor.o \
|
||||
elements.o \
|
||||
energymonitor.o \
|
||||
fader.o \
|
||||
gamestate.o \
|
||||
graphics.o \
|
||||
hotspot.o \
|
||||
input.o \
|
||||
interaction.o \
|
||||
interface.o \
|
||||
menu.o \
|
||||
metaengine.o \
|
||||
movie.o \
|
||||
notification.o \
|
||||
pegasus.o \
|
||||
sound.o \
|
||||
surface.o \
|
||||
timers.o \
|
||||
transition.o \
|
||||
util.o \
|
||||
ai/ai_action.o \
|
||||
ai/ai_area.o \
|
||||
ai/ai_condition.o \
|
||||
ai/ai_rule.o \
|
||||
items/autodragger.o \
|
||||
items/inventory.o \
|
||||
items/inventorypicture.o \
|
||||
items/item.o \
|
||||
items/itemdragger.o \
|
||||
items/itemlist.o \
|
||||
items/biochips/aichip.o \
|
||||
items/biochips/arthurchip.o \
|
||||
items/biochips/biochipitem.o \
|
||||
items/biochips/mapchip.o \
|
||||
items/biochips/mapimage.o \
|
||||
items/biochips/opticalchip.o \
|
||||
items/biochips/pegasuschip.o \
|
||||
items/biochips/retscanchip.o \
|
||||
items/biochips/shieldchip.o \
|
||||
items/inventory/airmask.o \
|
||||
items/inventory/gascanister.o \
|
||||
items/inventory/inventoryitem.o \
|
||||
items/inventory/keycard.o \
|
||||
neighborhood/door.o \
|
||||
neighborhood/exit.o \
|
||||
neighborhood/extra.o \
|
||||
neighborhood/hotspotinfo.o \
|
||||
neighborhood/neighborhood.o \
|
||||
neighborhood/spot.o \
|
||||
neighborhood/turn.o \
|
||||
neighborhood/view.o \
|
||||
neighborhood/zoom.o \
|
||||
neighborhood/caldoria/caldoria.o \
|
||||
neighborhood/caldoria/caldoria4dsystem.o \
|
||||
neighborhood/caldoria/caldoriabomb.o \
|
||||
neighborhood/caldoria/caldoriamessages.o \
|
||||
neighborhood/caldoria/caldoriamirror.o \
|
||||
neighborhood/mars/canyonchase.o \
|
||||
neighborhood/mars/energybeam.o \
|
||||
neighborhood/mars/gravitoncannon.o \
|
||||
neighborhood/mars/hermite.o \
|
||||
neighborhood/mars/mars.o \
|
||||
neighborhood/mars/planetmover.o \
|
||||
neighborhood/mars/reactor.o \
|
||||
neighborhood/mars/robotship.o \
|
||||
neighborhood/mars/shuttleenergymeter.o \
|
||||
neighborhood/mars/shuttlehud.o \
|
||||
neighborhood/mars/shuttleweapon.o \
|
||||
neighborhood/mars/spacechase3d.o \
|
||||
neighborhood/mars/spacejunk.o \
|
||||
neighborhood/mars/tractorbeam.o \
|
||||
neighborhood/mars/tunnelpod.o \
|
||||
neighborhood/norad/norad.o \
|
||||
neighborhood/norad/noradelevator.o \
|
||||
neighborhood/norad/pressuredoor.o \
|
||||
neighborhood/norad/pressuretracker.o \
|
||||
neighborhood/norad/subcontrolroom.o \
|
||||
neighborhood/norad/subplatform.o \
|
||||
neighborhood/norad/alpha/ecrmonitor.o \
|
||||
neighborhood/norad/alpha/fillingstation.o \
|
||||
neighborhood/norad/alpha/noradalpha.o \
|
||||
neighborhood/norad/alpha/panorama.o \
|
||||
neighborhood/norad/alpha/panoramascroll.o \
|
||||
neighborhood/norad/alpha/subchase.o \
|
||||
neighborhood/norad/delta/globegame.o \
|
||||
neighborhood/norad/delta/noraddelta.o \
|
||||
neighborhood/prehistoric/prehistoric.o \
|
||||
neighborhood/tsa/fulltsa.o \
|
||||
neighborhood/tsa/tinytsa.o \
|
||||
neighborhood/wsc/moleculebin.o \
|
||||
neighborhood/wsc/wsc.o
|
||||
|
||||
|
||||
# This module can be built as a plugin
|
||||
ifeq ($(ENABLE_PEGASUS), DYNAMIC_PLUGIN)
|
||||
PLUGIN := 1
|
||||
endif
|
||||
|
||||
# Include common rules
|
||||
include $(srcdir)/rules.mk
|
||||
|
||||
# Detection objects
|
||||
DETECT_OBJS += $(MODULE)/detection.o
|
||||
283
engines/pegasus/movie.cpp
Normal file
283
engines/pegasus/movie.cpp
Normal file
@@ -0,0 +1,283 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/system.h"
|
||||
#include "graphics/surface.h"
|
||||
#include "video/qt_decoder.h"
|
||||
#include "video/video_decoder.h"
|
||||
|
||||
#include "pegasus/movie.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
Movie::Movie(const DisplayElementID id) : Animation(id) {
|
||||
_video = nullptr;
|
||||
setScale(600);
|
||||
}
|
||||
|
||||
Movie::~Movie() {
|
||||
releaseMovie();
|
||||
}
|
||||
|
||||
// *** Make sure this will stop displaying the movie.
|
||||
|
||||
void Movie::releaseMovie() {
|
||||
if (_video) {
|
||||
delete _video;
|
||||
_video = nullptr;
|
||||
disposeAllCallBacks();
|
||||
deallocateSurface();
|
||||
}
|
||||
|
||||
setBounds(Common::Rect(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
void Movie::initFromMovieFile(const Common::Path &fileName, bool transparent) {
|
||||
_transparent = transparent;
|
||||
|
||||
releaseMovie();
|
||||
_video = new Video::QuickTimeDecoder();
|
||||
// enableEditListBoundsCheckQuirk(true) fixes bug #14855
|
||||
// At least one video file (Images/AI/Caldoria/XAE1) requires this fix
|
||||
_video->enableEditListBoundsCheckQuirk(true);
|
||||
if (!_video->loadFile(fileName)) {
|
||||
// Replace any colon with an underscore, since only macOS
|
||||
// supports that. See PegasusEngine::detectOpeningClosingDirectory()
|
||||
// for more info.
|
||||
Common::String newName(fileName.toString('/'));
|
||||
if (newName.contains(':'))
|
||||
for (uint i = 0; i < newName.size(); i++)
|
||||
if (newName[i] == ':')
|
||||
newName.setChar('_', i);
|
||||
|
||||
if (!_video->loadFile(Common::Path(newName)))
|
||||
error("Could not load video '%s'", fileName.toString().c_str());
|
||||
}
|
||||
|
||||
Common::Rect bounds(0, 0, _video->getWidth(), _video->getHeight());
|
||||
sizeElement(_video->getWidth(), _video->getHeight());
|
||||
_movieBox = bounds;
|
||||
|
||||
if (!isSurfaceValid())
|
||||
allocateSurface(bounds);
|
||||
|
||||
setStart(0, getScale());
|
||||
TimeBase::setStop(_video->getDuration().convertToFramerate(getScale()).totalNumberOfFrames(), getScale());
|
||||
}
|
||||
|
||||
void Movie::redrawMovieWorld() {
|
||||
if (_video && _video->needsUpdate()) {
|
||||
const Graphics::Surface *frame = _video->decodeNextFrame();
|
||||
|
||||
if (!frame)
|
||||
return;
|
||||
|
||||
// Make sure we have a surface in the current pixel format
|
||||
Graphics::Surface *convertedFrame = nullptr;
|
||||
|
||||
if (frame->format != g_system->getScreenFormat()) {
|
||||
convertedFrame = frame->convertTo(g_system->getScreenFormat());
|
||||
frame = convertedFrame;
|
||||
}
|
||||
|
||||
// Copy to the surface using _movieBox
|
||||
uint16 width = MIN<int>(frame->w, _movieBox.width());
|
||||
uint16 height = MIN<int>(frame->h, _movieBox.height());
|
||||
|
||||
for (uint16 y = 0; y < height; y++)
|
||||
memcpy((byte *)_surface->getBasePtr(_movieBox.left, _movieBox.top + y), (const byte *)frame->getBasePtr(0, y), width * frame->format.bytesPerPixel);
|
||||
|
||||
if (convertedFrame) {
|
||||
convertedFrame->free();
|
||||
delete convertedFrame;
|
||||
}
|
||||
|
||||
triggerRedraw();
|
||||
}
|
||||
}
|
||||
|
||||
void Movie::draw(const Common::Rect &r) {
|
||||
Common::Rect worldBounds = _movieBox;
|
||||
Common::Rect elementBounds;
|
||||
getBounds(elementBounds);
|
||||
|
||||
worldBounds.moveTo(elementBounds.left, elementBounds.top);
|
||||
Common::Rect r1 = r.findIntersectingRect(worldBounds);
|
||||
|
||||
Common::Rect r2 = r1;
|
||||
r2.translate(_movieBox.left - elementBounds.left, _movieBox.top - elementBounds.top);
|
||||
drawImage(r2, r1);
|
||||
}
|
||||
|
||||
void Movie::moveMovieBoxTo(const CoordType h, const CoordType v) {
|
||||
_movieBox.moveTo(h, v);
|
||||
}
|
||||
|
||||
void Movie::setStop(const TimeValue stopTime, const TimeScale scale) {
|
||||
TimeBase::setStop(stopTime, scale);
|
||||
|
||||
if (_video)
|
||||
_video->setEndTime(Audio::Timestamp(0, _stopTime, _stopScale));
|
||||
}
|
||||
|
||||
void Movie::setVolume(uint16 volume) {
|
||||
if (_video)
|
||||
_video->setVolume(MIN<uint>(volume, 0xFF));
|
||||
}
|
||||
|
||||
void Movie::setTime(const TimeValue time, const TimeScale scale) {
|
||||
if (_video) {
|
||||
// Don't go past the ends of the movie
|
||||
Common::Rational timeFrac = Common::Rational(time, ((scale == 0) ? getScale() : scale));
|
||||
|
||||
if (timeFrac < Common::Rational(_startTime, _startScale))
|
||||
timeFrac = Common::Rational(_startTime, _startScale);
|
||||
else if (timeFrac >= Common::Rational(_stopTime, _stopScale))
|
||||
return;
|
||||
|
||||
_video->seek(Audio::Timestamp(0, timeFrac.getNumerator(), timeFrac.getDenominator()));
|
||||
_time = timeFrac;
|
||||
_lastMillis = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Movie::setRate(const Common::Rational &rate) {
|
||||
if (_video) {
|
||||
_video->setRate(rate);
|
||||
|
||||
TimeBase::setRate(_video->getRate());
|
||||
return;
|
||||
}
|
||||
|
||||
TimeBase::setRate(rate);
|
||||
}
|
||||
|
||||
void Movie::start() {
|
||||
if (_video)
|
||||
_video->start();
|
||||
|
||||
TimeBase::start();
|
||||
}
|
||||
|
||||
void Movie::stop() {
|
||||
if (_video)
|
||||
_video->stop();
|
||||
|
||||
TimeBase::stop();
|
||||
}
|
||||
|
||||
void Movie::resume() {
|
||||
if (_paused) {
|
||||
if (_video)
|
||||
_video->pauseVideo(false);
|
||||
|
||||
_paused = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Movie::pause() {
|
||||
if (isRunning() && !_paused) {
|
||||
if (_video)
|
||||
_video->pauseVideo(true);
|
||||
|
||||
_paused = true;
|
||||
_pauseStart = g_system->getMillis();
|
||||
}
|
||||
}
|
||||
|
||||
TimeValue Movie::getDuration(const TimeScale scale) const {
|
||||
// Unlike TimeBase::getDuration(), this returns the whole duration of the movie
|
||||
// The original source has a TODO to make this behave like TimeBase::getDuration(),
|
||||
// but the problem is that too much code requires this function to behave this way...
|
||||
|
||||
if (_video)
|
||||
return _video->getDuration().convertToFramerate(((scale == 0) ? getScale() : scale)).totalNumberOfFrames();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Movie::updateTime() {
|
||||
// The reason why we overrode TimeBase's updateTime():
|
||||
// Again, avoiding timers and handling it here
|
||||
if (_video && _video->isPlaying() && !_video->isPaused()) {
|
||||
redrawMovieWorld();
|
||||
|
||||
uint32 startTime = _startTime * getScale() / _startScale;
|
||||
uint32 stopTime = _stopTime * getScale() / _stopScale;
|
||||
uint32 actualTime = CLIP<int>(_video->getTime() * getScale() / 1000, startTime, stopTime);
|
||||
|
||||
// HACK: Due to the inaccuracy of the time, we won't actually allow us to hit
|
||||
// the stop time unless we've actually reached the end of the segment.
|
||||
if (actualTime == stopTime && !_video->endOfVideo())
|
||||
actualTime--;
|
||||
|
||||
_time = Common::Rational(actualTime, getScale());
|
||||
}
|
||||
}
|
||||
|
||||
GlowingMovie::GlowingMovie(const DisplayElementID id) : Movie(id) {
|
||||
_glowing = false;
|
||||
}
|
||||
|
||||
void GlowingMovie::draw(const Common::Rect &r) {
|
||||
// Make sure the rectangles are clipped properly, OR guarantee that _bounds will
|
||||
// never fall off the screen.
|
||||
if (_glowing) {
|
||||
Common::Rect bounds;
|
||||
getBounds(bounds);
|
||||
|
||||
copyToCurrentPortTransparentGlow(_movieBox, bounds);
|
||||
} else {
|
||||
Movie::draw(r);
|
||||
}
|
||||
}
|
||||
|
||||
void GlowingMovie::setBounds(const Common::Rect &r) {
|
||||
Common::Rect bounds;
|
||||
getBounds(bounds);
|
||||
|
||||
if (r != bounds) {
|
||||
// Avoid Movie::setBounds.
|
||||
// clone2727 asks why, but goes along with it
|
||||
Animation::setBounds(r);
|
||||
}
|
||||
}
|
||||
|
||||
ScalingMovie::ScalingMovie(const DisplayElementID id) : GlowingMovie(id) {
|
||||
}
|
||||
|
||||
void ScalingMovie::draw(const Common::Rect &) {
|
||||
// Make sure the rectangles are clipped properly, OR guarantee that _bounds will
|
||||
// never fall off the screen.
|
||||
|
||||
Common::Rect bounds;
|
||||
getBounds(bounds);
|
||||
|
||||
if (_glowing)
|
||||
scaleTransparentCopyGlow(_movieBox, bounds);
|
||||
else
|
||||
scaleTransparentCopy(_movieBox, bounds);
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
105
engines/pegasus/movie.h
Normal file
105
engines/pegasus/movie.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_MOVIE_H
|
||||
#define PEGASUS_MOVIE_H
|
||||
|
||||
#include "common/str.h"
|
||||
|
||||
#include "pegasus/elements.h"
|
||||
#include "pegasus/surface.h"
|
||||
#include "video/qt_decoder.h"
|
||||
|
||||
namespace Video {
|
||||
class VideoDecoder;
|
||||
}
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class Movie : public Animation, public PixelImage {
|
||||
public:
|
||||
Movie(const DisplayElementID);
|
||||
~Movie() override;
|
||||
|
||||
virtual void initFromMovieFile(const Common::Path &fileName, bool transparent = false);
|
||||
|
||||
bool isMovieValid() { return _video != 0; }
|
||||
|
||||
virtual void releaseMovie();
|
||||
|
||||
void draw(const Common::Rect &) override;
|
||||
virtual void redrawMovieWorld();
|
||||
|
||||
void setTime(const TimeValue, const TimeScale = 0) override;
|
||||
|
||||
void setRate(const Common::Rational &) override;
|
||||
|
||||
void start() override;
|
||||
void stop() override;
|
||||
void resume() override;
|
||||
void pause() override;
|
||||
|
||||
virtual void moveMovieBoxTo(const CoordType, const CoordType);
|
||||
|
||||
void setStop(const TimeValue, const TimeScale = 0) override;
|
||||
|
||||
TimeValue getDuration(const TimeScale = 0) const override;
|
||||
|
||||
// *** HACK ALERT
|
||||
Video::VideoDecoder *getMovie() { return _video; }
|
||||
void setVolume(uint16);
|
||||
|
||||
protected:
|
||||
void updateTime() override;
|
||||
|
||||
Video::QuickTimeDecoder *_video;
|
||||
Common::Rect _movieBox;
|
||||
};
|
||||
|
||||
class GlowingMovie : public Movie {
|
||||
public:
|
||||
GlowingMovie(DisplayElementID);
|
||||
~GlowingMovie() override {}
|
||||
|
||||
void draw(const Common::Rect &) override;
|
||||
|
||||
void setBounds(const Common::Rect &) override;
|
||||
|
||||
void setGlowing(const bool glowing) { _glowing = glowing; }
|
||||
|
||||
protected:
|
||||
bool _glowing;
|
||||
};
|
||||
|
||||
class ScalingMovie : public GlowingMovie {
|
||||
public:
|
||||
ScalingMovie(DisplayElementID);
|
||||
~ScalingMovie() override {}
|
||||
|
||||
void draw(const Common::Rect &) override;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
2662
engines/pegasus/neighborhood/caldoria/caldoria.cpp
Normal file
2662
engines/pegasus/neighborhood/caldoria/caldoria.cpp
Normal file
File diff suppressed because it is too large
Load Diff
544
engines/pegasus/neighborhood/caldoria/caldoria.h
Normal file
544
engines/pegasus/neighborhood/caldoria/caldoria.h
Normal file
@@ -0,0 +1,544 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_CALDORIA_CALDORIA_H
|
||||
#define PEGASUS_NEIGHBORHOOD_CALDORIA_CALDORIA_H
|
||||
|
||||
#include "pegasus/neighborhood/neighborhood.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
static const TimeScale kCaldoriaMovieScale = 600;
|
||||
static const TimeScale kCaldoriaFramesPerSecond = 15;
|
||||
static const TimeScale kCaldoriaFrameDuration = 40;
|
||||
|
||||
// Alternate IDs.
|
||||
|
||||
static const AlternateID kAltCaldoriaNormal = 0;
|
||||
static const AlternateID kAltCaldoriaRoofDoorBlown = 2;
|
||||
static const AlternateID kAltCaldoriaSinclairDown = 3;
|
||||
|
||||
// Room IDs.
|
||||
|
||||
static const RoomID kCaldoria00 = 1;
|
||||
static const RoomID kCaldoria01 = 2;
|
||||
static const RoomID kCaldoria02 = 3;
|
||||
static const RoomID kCaldoria03 = 4;
|
||||
static const RoomID kCaldoria04 = 5;
|
||||
static const RoomID kCaldoria05 = 6;
|
||||
static const RoomID kCaldoria06 = 7;
|
||||
static const RoomID kCaldoria07 = 8;
|
||||
static const RoomID kCaldoria08 = 9;
|
||||
static const RoomID kCaldoria09 = 10;
|
||||
static const RoomID kCaldoria10 = 11;
|
||||
static const RoomID kCaldoriaToilet = 12;
|
||||
static const RoomID kCaldoria11 = 13;
|
||||
static const RoomID kCaldoria12 = 14;
|
||||
static const RoomID kCaldoriaVidPhone = 15;
|
||||
static const RoomID kCaldoriaReplicator = 16;
|
||||
static const RoomID kCaldoriaDrawers = 17;
|
||||
static const RoomID kCaldoria13 = 18;
|
||||
static const RoomID kCaldoria14 = 19;
|
||||
static const RoomID kCaldoria15 = 20;
|
||||
static const RoomID kCaldoria16 = 21;
|
||||
static const RoomID kCaldoria17 = 22;
|
||||
static const RoomID kCaldoria18 = 23;
|
||||
static const RoomID kCaldoria19 = 24;
|
||||
static const RoomID kCaldoria20 = 25;
|
||||
static const RoomID kCaldoria21 = 26;
|
||||
static const RoomID kCaldoria22 = 27;
|
||||
static const RoomID kCaldoria23 = 28;
|
||||
static const RoomID kCaldoria24 = 29;
|
||||
static const RoomID kCaldoria25 = 30;
|
||||
static const RoomID kCaldoria26 = 31;
|
||||
static const RoomID kCaldoria27 = 32;
|
||||
static const RoomID kCaldoria28 = 33;
|
||||
static const RoomID kCaldoria29 = 34;
|
||||
static const RoomID kCaldoria30 = 35;
|
||||
static const RoomID kCaldoria31 = 36;
|
||||
static const RoomID kCaldoria32 = 37;
|
||||
static const RoomID kCaldoria33 = 38;
|
||||
static const RoomID kCaldoria34 = 39;
|
||||
static const RoomID kCaldoria35 = 40;
|
||||
static const RoomID kCaldoria36 = 41;
|
||||
static const RoomID kCaldoria37 = 42;
|
||||
static const RoomID kCaldoria38 = 43;
|
||||
static const RoomID kCaldoria39 = 44;
|
||||
static const RoomID kCaldoria40 = 45;
|
||||
static const RoomID kCaldoria41 = 46;
|
||||
static const RoomID kCaldoriaBinoculars = 47;
|
||||
static const RoomID kCaldoria42 = 48;
|
||||
static const RoomID kCaldoriaKiosk = 49;
|
||||
static const RoomID kCaldoria44 = 50;
|
||||
static const RoomID kCaldoria45 = 51;
|
||||
static const RoomID kCaldoria46 = 52;
|
||||
static const RoomID kCaldoria47 = 53;
|
||||
static const RoomID kCaldoria48 = 54;
|
||||
static const RoomID kCaldoria49 = 55;
|
||||
static const RoomID kCaldoria50 = 56;
|
||||
static const RoomID kCaldoria51 = 57;
|
||||
static const RoomID kCaldoria52 = 58;
|
||||
static const RoomID kCaldoria53 = 59;
|
||||
static const RoomID kCaldoria54 = 60;
|
||||
static const RoomID kCaldoria55 = 61;
|
||||
static const RoomID kCaldoria56 = 62;
|
||||
static const RoomID kCaldoriaDeathRoom = 0;
|
||||
|
||||
// Hot Spot Activation IDs.
|
||||
|
||||
static const HotSpotActivationID kActivate4DClosed = 1;
|
||||
static const HotSpotActivationID kActivate4DOpen = 2;
|
||||
static const HotSpotActivationID kActivateMirrorReady = 3;
|
||||
static const HotSpotActivationID kActivateStylistReady = 4;
|
||||
static const HotSpotActivationID kActivateReplicatorReady = 5;
|
||||
static const HotSpotActivationID kActivateOJOnThePad = 6;
|
||||
static const HotSpotActivationID kActivateDrawersClosed = 7;
|
||||
static const HotSpotActivationID kActivateRightOpen = 8;
|
||||
static const HotSpotActivationID kActivateLeftOpen = 9;
|
||||
static const HotSpotActivationID kActivateFocusedOnShip = 10;
|
||||
static const HotSpotActivationID kActivateNotFocusedOnShip = 11;
|
||||
static const HotSpotActivationID kActivateReadyForCard = 12;
|
||||
static const HotSpotActivationID kActivateReadyToTransport = 13;
|
||||
static const HotSpotActivationID kActivateRoofSlotEmpty = 14;
|
||||
static const HotSpotActivationID kActivateZoomedOnSinclair = 15;
|
||||
|
||||
// Hot Spot IDs.
|
||||
|
||||
static const HotSpotID kCa4DEnvironOpenSpotID = 5000;
|
||||
static const HotSpotID kCa4DEnvironCloseSpotID = 5001;
|
||||
static const HotSpotID kCa4DVisualSpotID = 5002;
|
||||
static const HotSpotID kCa4DAudioSpotID = 5003;
|
||||
static const HotSpotID kCa4DChoice1SpotID = 5004;
|
||||
static const HotSpotID kCa4DChoice2SpotID = 5005;
|
||||
static const HotSpotID kCa4DChoice3SpotID = 5006;
|
||||
static const HotSpotID kCa4DChoice4SpotID = 5007;
|
||||
static const HotSpotID kCaBathroomMirrorSpotID = 5008;
|
||||
static const HotSpotID kCaHairStyle1SpotID = 5009;
|
||||
static const HotSpotID kCaHairStyle2SpotID = 5010;
|
||||
static const HotSpotID kCaHairStyle3SpotID = 5011;
|
||||
static const HotSpotID kCaShowerSpotID = 5012;
|
||||
static const HotSpotID kCaBathroomToiletSpotID = 5013;
|
||||
static const HotSpotID kCaldoriaVidPhoneSpotID = 5014;
|
||||
static const HotSpotID kCaldoriaReplicatorSpotID = 5015;
|
||||
static const HotSpotID kCaldoriaDrawersSpotID = 5016;
|
||||
static const HotSpotID kCaldoriaVidPhoneOutSpotID = 5017;
|
||||
static const HotSpotID kCaBedroomVidPhoneActivationSpotID = 5018;
|
||||
static const HotSpotID kCaldoriaReplicatorOutSpotID = 5019;
|
||||
static const HotSpotID kCaldoriaMakeOJSpotID = 5020;
|
||||
static const HotSpotID kCaldoriaMakeStickyBunsSpotID = 5021;
|
||||
static const HotSpotID kCaldoriaOrangeJuiceSpotID = 5022;
|
||||
static const HotSpotID kCaldoriaOrangeJuiceDropSpotID = 5023;
|
||||
static const HotSpotID kCaldoriaDrawersOutSpotID = 5024;
|
||||
static const HotSpotID kCaldoriaLeftDrawerOpenSpotID = 5025;
|
||||
static const HotSpotID kCaldoriaRightDrawerOpenSpotID = 5026;
|
||||
static const HotSpotID kCaldoriaKeyCardSpotID = 5027;
|
||||
static const HotSpotID kCaldoriaLeftDrawerCloseSpotID = 5028;
|
||||
static const HotSpotID kCaldoriaRightDrawerWithKeysCloseSpotID = 5029;
|
||||
static const HotSpotID kCaldoriaRightDrawerNoKeysCloseSpotID = 5030;
|
||||
static const HotSpotID kCaldoriaFourthFloorElevatorSpotID = 5031;
|
||||
static const HotSpotID kCaldoria20DoorbellSpotID = 5032;
|
||||
static const HotSpotID kCaldoria21DoorbellSpotID = 5033;
|
||||
static const HotSpotID kCaldoria26DoorbellSpotID = 5034;
|
||||
static const HotSpotID kCaldoriaFourthFloorElevator1 = 5035;
|
||||
static const HotSpotID kCaldoriaFourthFloorElevator2 = 5036;
|
||||
static const HotSpotID kCaldoriaFourthFloorElevator3 = 5037;
|
||||
static const HotSpotID kCaldoriaFourthFloorElevator4 = 5038;
|
||||
static const HotSpotID kCaldoriaFourthFloorElevator5 = 5039;
|
||||
static const HotSpotID kCaldoriaGroundElevator1 = 5040;
|
||||
static const HotSpotID kCaldoriaGroundElevator2 = 5041;
|
||||
static const HotSpotID kCaldoriaGroundElevator3 = 5042;
|
||||
static const HotSpotID kCaldoriaGroundElevator4 = 5043;
|
||||
static const HotSpotID kCaldoriaGroundElevator5 = 5044;
|
||||
static const HotSpotID kCaldoria29DoorbellSpotID = 5045;
|
||||
static const HotSpotID kCaldoria34DoorbellSpotID = 5046;
|
||||
static const HotSpotID kCaldoria35DoorbellSpotID = 5047;
|
||||
static const HotSpotID kCaldoriaGroundElevatorSpotID = 5048;
|
||||
static const HotSpotID kCaldoriaBinocularZoomInSpotID = 5049;
|
||||
static const HotSpotID kCaldoriaBinocularsOutSpotID = 5050;
|
||||
static const HotSpotID kCaldoriaZoomInOnShipSpotID = 5051;
|
||||
static const HotSpotID kCaldoriaKioskSpotID = 5052;
|
||||
static const HotSpotID kCaldoriaKioskOutSpotID = 5053;
|
||||
static const HotSpotID kCaldoriaKioskInfoSpotID = 5054;
|
||||
static const HotSpotID kCaldoriaGTCardDropSpotID = 5055;
|
||||
static const HotSpotID kCaldoriaGTTokyoSpotID = 5056;
|
||||
static const HotSpotID kCaldoriaGTTSASpotID = 5057;
|
||||
static const HotSpotID kCaldoriaGTBeachSpotID = 5058;
|
||||
static const HotSpotID kCaldoriaGTOtherSpotID = 5059;
|
||||
static const HotSpotID kCaldoriaRoofElevator1 = 5060;
|
||||
static const HotSpotID kCaldoriaRoofElevator2 = 5061;
|
||||
static const HotSpotID kCaldoriaRoofElevator3 = 5062;
|
||||
static const HotSpotID kCaldoriaRoofElevator4 = 5063;
|
||||
static const HotSpotID kCaldoriaRoofElevator5 = 5064;
|
||||
static const HotSpotID kCaldoriaRoofElevatorSpotID = 5065;
|
||||
static const HotSpotID kCaldoriaRoofDoorSpotID = 5066;
|
||||
static const HotSpotID kCaldoriaRoofCardDropSpotID = 5067;
|
||||
static const HotSpotID kCaldoria53EastSinclairTargetSpotID = 5068;
|
||||
static const HotSpotID kCaldoriaCornbread = 5069;
|
||||
|
||||
// Extra sequence IDs.
|
||||
|
||||
static const ExtraID kCaldoriaWakeUpView1 = 0;
|
||||
static const ExtraID kCaldoria00WakeUp1 = 1;
|
||||
static const ExtraID kCaldoria00WakeUp2 = 2;
|
||||
static const ExtraID kCaldoria00SitDown = 3;
|
||||
static const ExtraID k4DEnvironOpenToINN = 4;
|
||||
static const ExtraID k4DINNInterruption = 5;
|
||||
static const ExtraID k4DINNIntro = 6;
|
||||
static const ExtraID k4DINNMarkJohnson = 7;
|
||||
static const ExtraID k4DINNMeganLove = 8;
|
||||
static const ExtraID k4DINNFadeOut = 9;
|
||||
static const ExtraID k4DEnvironOpenFromINN = 10;
|
||||
static const ExtraID k4DEnvironOpen = 11;
|
||||
static const ExtraID k4DEnvironOpenView = 12;
|
||||
static const ExtraID k4DEnvironClose = 13;
|
||||
static const ExtraID k4DIslandLoop = 14;
|
||||
static const ExtraID k4DDesertLoop = 15;
|
||||
static const ExtraID k4DMountainLoop = 16;
|
||||
static const ExtraID k4DIsland1ToIsland0 = 17;
|
||||
static const ExtraID k4DIsland2ToIsland0 = 18;
|
||||
static const ExtraID k4DIsland0ToDesert0 = 19;
|
||||
static const ExtraID k4DIsland1ToDesert0 = 20;
|
||||
static const ExtraID k4DIsland2ToDesert0 = 21;
|
||||
static const ExtraID k4DIsland0ToMountain0 = 22;
|
||||
static const ExtraID k4DIsland1ToMountain0 = 23;
|
||||
static const ExtraID k4DIsland2ToMountain0 = 24;
|
||||
static const ExtraID k4DDesert0ToIsland0 = 25;
|
||||
static const ExtraID k4DDesert1ToIsland0 = 26;
|
||||
static const ExtraID k4DDesert2ToIsland0 = 27;
|
||||
static const ExtraID k4DDesert0ToMountain0 = 28;
|
||||
static const ExtraID k4DDesert1ToMountain0 = 29;
|
||||
static const ExtraID k4DDesert2ToMountain0 = 30;
|
||||
static const ExtraID k4DMountain0ToIsland0 = 31;
|
||||
static const ExtraID k4DMountain1ToIsland0 = 32;
|
||||
static const ExtraID k4DMountain2ToIsland0 = 33;
|
||||
static const ExtraID k4DMountain0ToDesert0 = 34;
|
||||
static const ExtraID k4DMountain1ToDesert0 = 35;
|
||||
static const ExtraID k4DMountain2ToDesert0 = 36;
|
||||
static const ExtraID kCaBathroomGreeting = 37;
|
||||
static const ExtraID kCaBathroomBodyFat = 38;
|
||||
static const ExtraID kCaBathroomStylistIntro = 39;
|
||||
static const ExtraID kCaBathroomRetrothrash = 40;
|
||||
static const ExtraID kCaBathroomRetrothrashReturn = 41;
|
||||
static const ExtraID kCaBathroomGeoWave = 42;
|
||||
static const ExtraID kCaBathroomGeoWaveReturn = 43;
|
||||
static const ExtraID kCaBathroomAgencyStandard = 44;
|
||||
static const ExtraID kCaldoriaShowerTitle = 45;
|
||||
static const ExtraID kCaldoriaShowerButton = 46;
|
||||
static const ExtraID kCaldoriaShowerDown = 47;
|
||||
static const ExtraID kCaldoriaShowerUp = 48;
|
||||
static const ExtraID kCaBedroomVidPhone = 49;
|
||||
static const ExtraID kCaBedroomMessage1 = 50;
|
||||
static const ExtraID kCaBedroomMessage2 = 51;
|
||||
static const ExtraID kCreateOrangeJuice = 52;
|
||||
static const ExtraID kDisposeOrangeJuice = 53;
|
||||
static const ExtraID kReplicatorNorthViewWithOJ = 54;
|
||||
static const ExtraID kLeftDrawerOpen = 55;
|
||||
static const ExtraID kLeftDrawerClose = 56;
|
||||
static const ExtraID kRightDrawerOpenWithKeys = 57;
|
||||
static const ExtraID kRightDrawerCloseWithKeys = 58;
|
||||
static const ExtraID kRightDrawerOpenNoKeys = 59;
|
||||
static const ExtraID kRightDrawerCloseNoKeys = 60;
|
||||
static const ExtraID kRightDrawerOpenViewWithKeys = 61;
|
||||
static const ExtraID kRightDrawerOpenViewNoKeys = 62;
|
||||
static const ExtraID kCaldoria16ElevatorUp = 63;
|
||||
static const ExtraID kCaldoria16ElevatorDown = 64;
|
||||
static const ExtraID kCaldoria16SouthViewWithElevator = 65;
|
||||
static const ExtraID kCaldoria20Doorbell = 66;
|
||||
static const ExtraID kCaldoria21Doorbell = 67;
|
||||
static const ExtraID kCaldoria26Doorbell = 68;
|
||||
static const ExtraID kCaldoriaFourthToGround = 69;
|
||||
static const ExtraID kCaldoriaRoofToFourth = 70;
|
||||
static const ExtraID kCaldoriaRoofToGround = 71;
|
||||
static const ExtraID kCaldoriaGroundToFourth = 72;
|
||||
static const ExtraID kCaldoriaGroundToRoof = 73;
|
||||
static const ExtraID kCaldoriaFourthToRoof = 74;
|
||||
static const ExtraID kCaldoria29Doorbell = 75;
|
||||
static const ExtraID kCaldoria34Doorbell = 76;
|
||||
static const ExtraID kCaldoria35Doorbell = 77;
|
||||
static const ExtraID kBinocularsZoomInOnShip = 78;
|
||||
static const ExtraID kCaldoriaKioskVideo = 79;
|
||||
static const ExtraID kCaldoriaTransporterArrowLoop = 80;
|
||||
static const ExtraID kArriveAtCaldoriaFromTSA = 81;
|
||||
static const ExtraID kCaGTOtherChoice = 82;
|
||||
static const ExtraID kCaGTCardSwipe = 83;
|
||||
static const ExtraID kCaGTSelectTSA = 84;
|
||||
static const ExtraID kCaGTFryTheFly = 85;
|
||||
static const ExtraID kCaGTGoToTSA = 86;
|
||||
static const ExtraID kCaGTSelectBeach = 87;
|
||||
static const ExtraID kCaGTGoToBeach = 88;
|
||||
static const ExtraID kCaGTArriveAtBeach = 89;
|
||||
static const ExtraID kCaGTSelectTokyo = 90;
|
||||
static const ExtraID kCaGTGoToTokyo = 91;
|
||||
static const ExtraID kCaGTArriveAtTokyo = 92;
|
||||
static const ExtraID kCa48NorthRooftopClosed = 93;
|
||||
static const ExtraID kCa48NorthExplosion = 94;
|
||||
static const ExtraID kCa48NorthExplosionDeath = 95;
|
||||
static const ExtraID kCa49NorthVoiceAnalysis = 96;
|
||||
static const ExtraID kCa50SinclairShoots = 97;
|
||||
static const ExtraID kCa53EastZoomToSinclair = 98;
|
||||
static const ExtraID kCa53EastDeath2 = 99;
|
||||
static const ExtraID kCa53EastShootSinclair = 100;
|
||||
static const ExtraID kCa53EastZoomOutFromSinclair = 101;
|
||||
static const ExtraID kCa54SouthDeath = 102;
|
||||
static const ExtraID kCaldoria56BombStage1 = 103;
|
||||
static const ExtraID kCaldoria56BombStage2 = 104;
|
||||
static const ExtraID kCaldoria56BombStage3 = 105;
|
||||
static const ExtraID kCaldoria56BombStage4 = 106;
|
||||
static const ExtraID kCaldoria56BombStage5 = 107;
|
||||
static const ExtraID kCaldoria56BombStage6 = 108;
|
||||
static const ExtraID kCaldoria56BombStage7 = 109;
|
||||
static const ExtraID kCaldoria56BombExplodes = 110;
|
||||
|
||||
// Caldoria interactions.
|
||||
|
||||
static const InteractionID kCaldoria4DInteractionID = 0;
|
||||
static const InteractionID kCaldoriaBombInteractionID = 1;
|
||||
static const InteractionID kCaldoriaMessagesInteractionID = 2;
|
||||
static const InteractionID kCaldoriaMirrorInteractionID = 3;
|
||||
|
||||
// Caldoria:
|
||||
|
||||
static const DisplayOrder kVidPhoneOrder = kMonitorLayer;
|
||||
static const DisplayOrder k4DSpritesOrder = kMonitorLayer;
|
||||
static const DisplayOrder kCaldoriaMessagesOrder = kMonitorLayer;
|
||||
static const DisplayOrder kCaldoriaElevatorOrder = kMonitorLayer;
|
||||
static const DisplayOrder kCaldoriaA05LightLoopOrder = kMonitorLayer;
|
||||
static const DisplayOrder kCaldoriaA07LightLoopOrder = kMonitorLayer;
|
||||
static const DisplayOrder kCaldoriaBombGridOrder = kMonitorLayer;
|
||||
static const DisplayOrder kCaldoriaBombTimerOrder = kCaldoriaBombGridOrder + 1;
|
||||
|
||||
/////////////////////////////////////////////
|
||||
//
|
||||
// Caldoria
|
||||
|
||||
static const CoordType kCaldoriaVidPhoneLeft = kNavAreaLeft + 105;
|
||||
static const CoordType kCaldoriaVidPhoneTop = kNavAreaTop + 28;
|
||||
|
||||
static const CoordType kCaldoria4DSpritesLeft = kNavAreaLeft + 10;
|
||||
static const CoordType kCaldoria4DSpritesTop = kNavAreaTop + 142;
|
||||
|
||||
static const CoordType kCaldoriaMessageLeft = kNavAreaLeft + 202;
|
||||
static const CoordType kCaldoriaMessageTop = kNavAreaTop + 26;
|
||||
|
||||
static const CoordType kCaldoriaElevatorLeft = kNavAreaLeft + 407;
|
||||
static const CoordType kCaldoriaElevatorTop = kNavAreaTop + 138;
|
||||
|
||||
static const CoordType kCaldoriaA05LightLoopLeft = kNavAreaLeft + 213;
|
||||
static const CoordType kCaldoriaA05LightLoopTop = kNavAreaTop + 215;
|
||||
|
||||
static const CoordType kCaldoriaA07LightLoopLeft = kNavAreaLeft + 414;
|
||||
static const CoordType kCaldoriaA07LightLoopTop = kNavAreaTop + 215;
|
||||
|
||||
static const CoordType kCaldoriaGunSpriteLeft = kNavAreaLeft + 276;
|
||||
static const CoordType kCaldoriaGunSpriteTop = kNavAreaTop + 115;
|
||||
|
||||
static const CoordType kCaldoria11MessageLoopLeft = kNavAreaLeft + 135;
|
||||
static const CoordType kCaldoria11MessageLoopTop = kNavAreaTop + 214;
|
||||
|
||||
static const CoordType kCaldoria12MessageLoopLeft = kNavAreaLeft + 209;
|
||||
static const CoordType kCaldoria12MessageLoopTop = kNavAreaTop + 170;
|
||||
|
||||
static const CoordType kCaldoria13MessageLoopLeft = kNavAreaLeft + 480;
|
||||
static const CoordType kCaldoria13MessageLoopTop = kNavAreaTop + 191;
|
||||
|
||||
static const CoordType kCaldoria14MessageLoopLeft = kNavAreaLeft + 248;
|
||||
static const CoordType kCaldoria14MessageLoopTop = kNavAreaTop + 191;
|
||||
|
||||
static const CoordType kCaldoria48CardBombLoopLeft = kNavAreaLeft + 337;
|
||||
static const CoordType kCaldoria48CardBombLoopTop = kNavAreaTop + 205;
|
||||
|
||||
static const CoordType kCaldoriaBombGridLeft = kNavAreaLeft + 290;
|
||||
static const CoordType kCaldoriaBombGridTop = kNavAreaTop + 58;
|
||||
|
||||
static const CoordType kCaldoriaBombTimerLeft = kNavAreaLeft + 58;
|
||||
static const CoordType kCaldoriaBombTimerTop = kNavAreaTop + 204;
|
||||
|
||||
// Caldoria display IDs.
|
||||
|
||||
static const DisplayElementID kCaldoriaVidPhoneID = kNeighborhoodDisplayID;
|
||||
static const DisplayElementID kCaldoria4DSpritesID = kCaldoriaVidPhoneID + 1;
|
||||
static const DisplayElementID kCaldoriaMessagesID = kCaldoria4DSpritesID + 1;
|
||||
static const DisplayElementID kCaldoriaUtilityID = kCaldoriaMessagesID + 1;
|
||||
static const DisplayElementID kCaldoriaBombGridID = kCaldoriaUtilityID + 1;
|
||||
static const DisplayElementID kCaldoriaBombTimerID = kCaldoriaBombGridID + 1;
|
||||
|
||||
static const TimeValue kCaldoria4DInstructionsIn = 28013;
|
||||
static const TimeValue kCaldoria4DInstructionsOut = 29730;
|
||||
|
||||
static const TimeValue kCaldoria4DBlankChoiceIn = 29730;
|
||||
static const TimeValue kCaldoria4DBlankChoiceOut = 33910;
|
||||
|
||||
class Caldoria;
|
||||
|
||||
class SinclairCallBack : public TimeBaseCallBack {
|
||||
public:
|
||||
SinclairCallBack(Caldoria *);
|
||||
~SinclairCallBack() override {}
|
||||
|
||||
protected:
|
||||
void callBack() override;
|
||||
|
||||
Caldoria *_caldoria;
|
||||
};
|
||||
|
||||
class Caldoria : public Neighborhood {
|
||||
friend class SinclairCallBack;
|
||||
|
||||
public:
|
||||
Caldoria(InputHandler *, PegasusEngine *);
|
||||
~Caldoria() override;
|
||||
|
||||
uint16 getDateResID() const override;
|
||||
|
||||
void pickedUpItem(Item *) override;
|
||||
|
||||
GameInteraction *makeInteraction(const InteractionID) override;
|
||||
|
||||
Common::Path getBriefingMovie() override;
|
||||
Common::Path getEnvScanMovie() override;
|
||||
uint getNumHints() override;
|
||||
Common::Path getHintMovie(uint) override;
|
||||
void loadAmbientLoops() override;
|
||||
bool wantsCursor() override;
|
||||
void flushGameState() override;
|
||||
|
||||
void checkContinuePoint(const RoomID, const DirectionConstant) override;
|
||||
|
||||
void setSoundFXLevel(const uint16) override;
|
||||
|
||||
protected:
|
||||
enum {
|
||||
kCaldoriaPrivate4DSystemOpenFlag,
|
||||
kCaloriaPrivateLeftDrawerOpenFlag,
|
||||
kCaldoriaPrivateRightDrawerOpenFlag,
|
||||
kCaldoriaPrivateReadyToShootFlag,
|
||||
kCaldoriaPrivateZoomingToBombFlag,
|
||||
kCaldoriaPrivateCanOpenElevatorDoorFlag,
|
||||
kCaldoriaPrivateSinclairTimerExpiredFlag,
|
||||
kCaldoriaPrivateSeen13CarFlag,
|
||||
kCaldoriaPrivateSeen14CarFlag,
|
||||
kCaldoriaPrivateSeen18CarFlag,
|
||||
kCaldoriaPrivateSeen23CarFlag,
|
||||
kCaldoriaPrivateSeen33CarFlag,
|
||||
kCaldoriaPrivateSeen36CarFlag,
|
||||
kCaldoriaPrivateSeen41NorthCarFlag,
|
||||
kCaldoriaPrivateSeen41EastCarFlag,
|
||||
kCaldoriaPrivateSeen41WestCarFlag,
|
||||
kNumCaldoriaPrivateFlags
|
||||
};
|
||||
|
||||
void init() override;
|
||||
void start() override;
|
||||
void throwAwayInterface() override;
|
||||
|
||||
void setUpRoofTop();
|
||||
|
||||
void setUpAIRules() override;
|
||||
void doAIRecalibration();
|
||||
TimeValue getViewTime(const RoomID, const DirectionConstant) override;
|
||||
void findSpotEntry(const RoomID, const DirectionConstant, SpotFlags, SpotTable::Entry &) override;
|
||||
void startSpotOnceOnly(TimeValue, TimeValue) override;
|
||||
void startExitMovie(const ExitTable::Entry &) override;
|
||||
void startZoomMovie(const ZoomTable::Entry &) override;
|
||||
void startDoorOpenMovie(const TimeValue, const TimeValue) override;
|
||||
void startTurnPush(const TurnDirection, const TimeValue, const DirectionConstant) override;
|
||||
void bumpIntoWall() override;
|
||||
int16 getStaticCompassAngle(const RoomID, const DirectionConstant) override;
|
||||
void getExitCompassMove(const ExitTable::Entry &, FaderMoveSpec &) override;
|
||||
void getZoomCompassMove(const ZoomTable::Entry &, FaderMoveSpec &) override;
|
||||
void getExtraCompassMove(const ExtraTable::Entry &, FaderMoveSpec &) override;
|
||||
void spotCompleted() override;
|
||||
void arriveAt(const RoomID, const DirectionConstant) override;
|
||||
void arriveAtCaldoria00();
|
||||
void arriveAtCaldoriaToilet();
|
||||
void arriveAtCaldoria44();
|
||||
void arriveAtCaldoria49();
|
||||
void arriveAtCaldoria56();
|
||||
void arriveAtCaldoriaDeath();
|
||||
void turnTo(const DirectionConstant) override;
|
||||
void zoomTo(const Hotspot *) override;
|
||||
void leftButton(const Input &) override;
|
||||
void rightButton(const Input &) override;
|
||||
void downButton(const Input &) override;
|
||||
void startExtraSequence(const ExtraID, const NotificationFlags, const InputBits) override;
|
||||
void receiveNotification(Notification *, const NotificationFlags) override;
|
||||
InputBits getInputFilter() override;
|
||||
void activateHotspots() override;
|
||||
void clickInHotspot(const Input &, const Hotspot *) override;
|
||||
void newInteraction(const InteractionID) override;
|
||||
|
||||
void clickOnDoorbell(const HotSpotID);
|
||||
|
||||
Hotspot *getItemScreenSpot(Item *, DisplayElement *) override;
|
||||
void dropItemIntoRoom(Item *, Hotspot *) override;
|
||||
void playMissingFloorSound();
|
||||
void takeElevator(uint, uint);
|
||||
void updateElevatorMovie();
|
||||
void openElevatorMovie();
|
||||
void emptyOJGlass();
|
||||
void closeDoorOffScreen(const RoomID, const DirectionConstant) override;
|
||||
void doorBombTimerExpired();
|
||||
void sinclairTimerExpired();
|
||||
void checkSinclairShootsOS();
|
||||
void setUpSinclairLoops();
|
||||
void zoomToSinclair();
|
||||
void playEndMessage();
|
||||
void checkInterruptSinclair();
|
||||
void doArthurJoyride();
|
||||
|
||||
void cantMoveThatWay(CanMoveForwardReason) override;
|
||||
CanOpenDoorReason canOpenDoor(DoorTable::Entry &) override;
|
||||
void doorOpened() override;
|
||||
|
||||
void updateCursor(const Common::Point &, const Hotspot *) override;
|
||||
|
||||
FlagsArray<uint16, kNumCaldoriaPrivateFlags> _privateFlags;
|
||||
|
||||
const Hotspot *_zoomOutSpot;
|
||||
|
||||
Hotspot _laundryZoomInSpot;
|
||||
Hotspot _laundryZoomOutSpot;
|
||||
Hotspot _cornbreadSpot;
|
||||
|
||||
Movie _extraMovie;
|
||||
NotificationCallBack _extraMovieCallBack;
|
||||
|
||||
bool _lookingAtLaundry;
|
||||
|
||||
FuseFunction _utilityFuse;
|
||||
|
||||
long _sinclairLoopCount;
|
||||
long _numSinclairLoops;
|
||||
|
||||
Sprite *_gunSprite;
|
||||
|
||||
SinclairCallBack _sinclairInterrupt;
|
||||
|
||||
Common::Path getSoundSpotsName() override;
|
||||
Common::Path getNavMovieName() override;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
391
engines/pegasus/neighborhood/caldoria/caldoria4dsystem.cpp
Normal file
391
engines/pegasus/neighborhood/caldoria/caldoria4dsystem.cpp
Normal file
@@ -0,0 +1,391 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/ai/ai_area.h"
|
||||
#include "pegasus/neighborhood/caldoria/caldoria.h"
|
||||
#include "pegasus/neighborhood/caldoria/caldoria4dsystem.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
enum {
|
||||
kSwitchableSlop = 3 * kCaldoriaFrameDuration,
|
||||
// Two seconds - some slop
|
||||
kSwitchableDuration = kCaldoriaMovieScale * 2 - kSwitchableSlop,
|
||||
// Twelve frames + some slop
|
||||
kNonswitchableDuration = kCaldoriaFrameDuration * 12 + kSwitchableSlop,
|
||||
|
||||
kSwitchable1Start = 0,
|
||||
kSwitchable1Stop = kSwitchable1Start + kSwitchableDuration,
|
||||
|
||||
kSwitchable2Start = kSwitchable1Stop + kNonswitchableDuration,
|
||||
kSwitchable2Stop = kSwitchable2Start + kSwitchableDuration,
|
||||
|
||||
kSwitchable3Start = kSwitchable2Stop + kNonswitchableDuration,
|
||||
kSwitchable3Stop = kSwitchable3Start + kSwitchableDuration,
|
||||
|
||||
kVidPhoneDoneFlag = 1,
|
||||
|
||||
kRockMusicLoopIn = 0,
|
||||
kRockMusicLoopOut = 2088,
|
||||
|
||||
kOrchestralMusicLoopIn = 2088,
|
||||
kOrchestralMusicLoopOut = 4985,
|
||||
|
||||
kRhythmsMusicLoopIn = 4985,
|
||||
kRhythmsMusicLoopOut = 6824,
|
||||
|
||||
kAcousticMusicLoopIn = 6824,
|
||||
kAcousticMusicLoopOut = 9387
|
||||
};
|
||||
|
||||
enum {
|
||||
k4DVideoMenu,
|
||||
k4DAudioMenu,
|
||||
k4DShuttingDown,
|
||||
|
||||
// These constants are the exact frame numbers of the sprite movie.
|
||||
k4DRockChoice = 0,
|
||||
k4DOrchestralChoice,
|
||||
k4DRhythmsChoice,
|
||||
k4DAcousticChoice,
|
||||
k4DIslandChoice,
|
||||
k4DDesertChoice,
|
||||
k4DMountainChoice,
|
||||
|
||||
k4DFirstVideoChoice = k4DIslandChoice
|
||||
};
|
||||
|
||||
static const ExtraID s_transitionExtras0[3][3] = {
|
||||
{ 0xffffffff, k4DIsland0ToDesert0, k4DIsland0ToMountain0 },
|
||||
{ k4DDesert0ToIsland0, 0xffffffff, k4DDesert0ToMountain0 },
|
||||
{ k4DMountain0ToIsland0, k4DMountain0ToDesert0, 0xffffffff }
|
||||
};
|
||||
|
||||
static const ExtraID s_transitionExtras1[3][3] = {
|
||||
{ 0xffffffff, k4DIsland1ToDesert0, k4DIsland1ToMountain0 },
|
||||
{ k4DDesert1ToIsland0, 0xffffffff, k4DDesert1ToMountain0 },
|
||||
{ k4DMountain1ToIsland0, k4DMountain1ToDesert0, 0xffffffff }
|
||||
};
|
||||
|
||||
static const ExtraID s_transitionExtras2[3][3] = {
|
||||
{ 0xffffffff, k4DIsland2ToDesert0, k4DIsland2ToMountain0 },
|
||||
{ k4DDesert2ToIsland0, 0xffffffff, k4DDesert2ToMountain0 },
|
||||
{ k4DMountain2ToIsland0, k4DMountain2ToDesert0, 0xffffffff }
|
||||
};
|
||||
|
||||
static const ExtraID s_shutDownExtras[3][3] = {
|
||||
{ 0xffffffff, k4DIsland1ToIsland0, k4DIsland2ToIsland0 },
|
||||
{ k4DDesert0ToIsland0, k4DDesert1ToIsland0, k4DDesert2ToIsland0 },
|
||||
{ k4DMountain0ToIsland0, k4DMountain1ToIsland0, k4DMountain2ToIsland0 }
|
||||
};
|
||||
|
||||
Caldoria4DSystem::Caldoria4DSystem(Neighborhood *owner) : GameInteraction(kCaldoria4DInteractionID, owner),
|
||||
_4DSpritesMovie(kCaldoria4DSpritesID) {
|
||||
_4DSpritesScale = 0;
|
||||
_whichMenu = k4DVideoMenu;
|
||||
_videoChoice = k4DIslandChoice;
|
||||
_audioChoice = k4DRockChoice;
|
||||
_neighborhoodNotification = nullptr;
|
||||
_loopStart = 0;
|
||||
_clickedHotspotID = kNoHotSpotID;
|
||||
|
||||
g_AIArea->lockAIOut();
|
||||
}
|
||||
|
||||
Caldoria4DSystem::~Caldoria4DSystem() {
|
||||
g_AIArea->unlockAI();
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::openInteraction() {
|
||||
_whichMenu = k4DVideoMenu;
|
||||
_videoChoice = k4DIslandChoice;
|
||||
_audioChoice = k4DRockChoice;
|
||||
_clickedHotspotID = kNoHotSpotID;
|
||||
|
||||
_4DSpritesMovie.initFromMovieFile("Images/Caldoria/4D Sprites", true);
|
||||
_4DSpritesMovie.moveElementTo(kCaldoria4DSpritesLeft, kCaldoria4DSpritesTop);
|
||||
_4DSpritesMovie.setDisplayOrder(k4DSpritesOrder);
|
||||
_4DSpritesMovie.startDisplaying();
|
||||
_4DSpritesMovie.show();
|
||||
|
||||
_4DSpritesScale = _4DSpritesMovie.getScale();
|
||||
|
||||
_neighborhoodNotification = _owner->getNeighborhoodNotification();
|
||||
_neighborhoodNotification->notifyMe(this, kExtraCompletedFlag, kExtraCompletedFlag);
|
||||
|
||||
startIdling();
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::loopExtra(const ExtraID extraID) {
|
||||
ExtraTable::Entry extraEntry;
|
||||
|
||||
_owner->getExtraEntry(extraID, extraEntry);
|
||||
_loopStart = extraEntry.movieStart;
|
||||
_owner->loopExtraSequence(extraID);
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::useIdleTime() {
|
||||
if (_whichMenu == k4DShuttingDown) {
|
||||
TimeValue movieTime = _owner->getNavMovie()->getTime() - _loopStart;
|
||||
ExtraID extraID;
|
||||
|
||||
if (movieTime < kSwitchable1Stop)
|
||||
extraID = s_shutDownExtras[_videoChoice - k4DFirstVideoChoice][0];
|
||||
else if (movieTime >= kSwitchable2Start && movieTime < kSwitchable2Stop)
|
||||
extraID = s_shutDownExtras[_videoChoice - k4DFirstVideoChoice][1];
|
||||
else if (movieTime >= kSwitchable3Start && movieTime < kSwitchable3Stop)
|
||||
extraID = s_shutDownExtras[_videoChoice - k4DFirstVideoChoice][2];
|
||||
else
|
||||
extraID = 0xffffffff;
|
||||
|
||||
if (extraID != 0xffffffff) {
|
||||
setSpritesMovie();
|
||||
_loopStart = 0;
|
||||
_owner->startExtraSequence(extraID, kExtraCompletedFlag, kFilterNoInput);
|
||||
}
|
||||
} else if (_clickedHotspotID != kNoHotSpotID) {
|
||||
TimeValue movieTime = _owner->getNavMovie()->getTime() - _loopStart;
|
||||
ExtraID extraID;
|
||||
|
||||
if (movieTime < kSwitchable1Stop) {
|
||||
extraID = s_transitionExtras0[_videoChoice - k4DFirstVideoChoice][_clickedHotspotID - kCa4DChoice1SpotID];
|
||||
_clickedHotspotID = kNoHotSpotID;
|
||||
} else if (movieTime >= kSwitchable2Start && movieTime < kSwitchable2Stop) {
|
||||
extraID = s_transitionExtras1[_videoChoice - k4DFirstVideoChoice][_clickedHotspotID - kCa4DChoice1SpotID];
|
||||
_clickedHotspotID = kNoHotSpotID;
|
||||
} else if (movieTime >= kSwitchable3Start && movieTime < kSwitchable3Stop) {
|
||||
extraID = s_transitionExtras2[_videoChoice - k4DFirstVideoChoice][_clickedHotspotID - kCa4DChoice1SpotID];
|
||||
_clickedHotspotID = kNoHotSpotID;
|
||||
} else
|
||||
extraID = 0xffffffff;
|
||||
|
||||
if (extraID != 0xffffffff) {
|
||||
switch (extraID) {
|
||||
case k4DDesert0ToIsland0:
|
||||
case k4DMountain0ToIsland0:
|
||||
case k4DDesert1ToIsland0:
|
||||
case k4DMountain1ToIsland0:
|
||||
case k4DDesert2ToIsland0:
|
||||
case k4DMountain2ToIsland0:
|
||||
_videoChoice = k4DIslandChoice;
|
||||
break;
|
||||
case k4DIsland0ToDesert0:
|
||||
case k4DMountain0ToDesert0:
|
||||
case k4DIsland1ToDesert0:
|
||||
case k4DMountain1ToDesert0:
|
||||
case k4DIsland2ToDesert0:
|
||||
case k4DMountain2ToDesert0:
|
||||
_videoChoice = k4DDesertChoice;
|
||||
break;
|
||||
case k4DDesert0ToMountain0:
|
||||
case k4DIsland0ToMountain0:
|
||||
case k4DIsland1ToMountain0:
|
||||
case k4DDesert1ToMountain0:
|
||||
case k4DIsland2ToMountain0:
|
||||
case k4DDesert2ToMountain0:
|
||||
_videoChoice = k4DMountainChoice;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
setSpritesMovie();
|
||||
_loopStart = 0;
|
||||
_owner->startExtraSequence(extraID, kExtraCompletedFlag, kFilterNoInput);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::initInteraction() {
|
||||
setSpritesMovie();
|
||||
|
||||
playSound("Rock");
|
||||
_owner->playSpotSoundSync(kCaldoria4DInstructionsIn, kCaldoria4DInstructionsOut);
|
||||
loopExtra(k4DIslandLoop);
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::closeInteraction() {
|
||||
stopIdling();
|
||||
_neighborhoodNotification->cancelNotification(this);
|
||||
_4DSpritesMovie.releaseMovie();
|
||||
_owner->loadAmbientLoops();
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::setSpritesMovie() {
|
||||
if (_whichMenu == k4DShuttingDown)
|
||||
_4DSpritesMovie.setTime(_4DSpritesScale * k4DIslandChoice);
|
||||
else if (_whichMenu == k4DVideoMenu)
|
||||
_4DSpritesMovie.setTime(_4DSpritesScale * _videoChoice);
|
||||
else if (_whichMenu == k4DAudioMenu)
|
||||
_4DSpritesMovie.setTime(_4DSpritesScale * _audioChoice);
|
||||
|
||||
_4DSpritesMovie.redrawMovieWorld();
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::handleInput(const Input &input, const Hotspot *cursorSpot) {
|
||||
if (input.downButtonAnyDown())
|
||||
return;
|
||||
if (input.anyDirectionInput())
|
||||
shutDown4DSystem();
|
||||
else
|
||||
GameInteraction::handleInput(input, cursorSpot);
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::activateHotspots() {
|
||||
GameInteraction::activateHotspots();
|
||||
g_allHotspots.activateOneHotspot(kCa4DChoice4SpotID);
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::clickInHotspot(const Input &input, const Hotspot *spot) {
|
||||
switch (spot->getObjectID()) {
|
||||
case kCa4DVisualSpotID:
|
||||
if (_whichMenu == k4DAudioMenu) {
|
||||
_whichMenu = k4DVideoMenu;
|
||||
setSpritesMovie();
|
||||
}
|
||||
break;
|
||||
case kCa4DAudioSpotID:
|
||||
if (_whichMenu == k4DVideoMenu) {
|
||||
_whichMenu = k4DAudioMenu;
|
||||
setSpritesMovie();
|
||||
}
|
||||
break;
|
||||
case kCa4DChoice1SpotID:
|
||||
if (_whichMenu == k4DVideoMenu)
|
||||
makeIslandChoice();
|
||||
else if (_whichMenu == k4DAudioMenu)
|
||||
makeRockChoice();
|
||||
break;
|
||||
case kCa4DChoice2SpotID:
|
||||
if (_whichMenu == k4DVideoMenu)
|
||||
makeDesertChoice();
|
||||
else if (_whichMenu == k4DAudioMenu)
|
||||
makeOrchestralChoice();
|
||||
break;
|
||||
case kCa4DChoice3SpotID:
|
||||
if (_whichMenu == k4DVideoMenu)
|
||||
makeMountainChoice();
|
||||
else if (_whichMenu == k4DAudioMenu)
|
||||
makeRhythmsChoice();
|
||||
break;
|
||||
case kCa4DChoice4SpotID:
|
||||
if (_whichMenu == k4DAudioMenu)
|
||||
makeAcousticChoice();
|
||||
else
|
||||
_owner->playSpotSoundSync(kCaldoria4DBlankChoiceIn, kCaldoria4DBlankChoiceOut);
|
||||
break;
|
||||
default:
|
||||
GameInteraction::clickInHotspot(input, spot);
|
||||
}
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::receiveNotification(Notification *, const NotificationFlags) {
|
||||
if (_whichMenu == k4DShuttingDown) {
|
||||
_owner->requestDeleteCurrentInteraction();
|
||||
} else {
|
||||
uint32 extraID;
|
||||
|
||||
switch (_videoChoice) {
|
||||
case k4DIslandChoice:
|
||||
extraID = k4DIslandLoop;
|
||||
break;
|
||||
case k4DDesertChoice:
|
||||
extraID = k4DDesertLoop;
|
||||
break;
|
||||
case k4DMountainChoice:
|
||||
extraID = k4DMountainLoop;
|
||||
break;
|
||||
default:
|
||||
extraID = 0xffffffff;
|
||||
break;
|
||||
}
|
||||
|
||||
if (extraID != 0xffffffff)
|
||||
loopExtra(extraID);
|
||||
}
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::makeIslandChoice() {
|
||||
if (_videoChoice != k4DIslandChoice && _clickedHotspotID == kNoHotSpotID)
|
||||
_clickedHotspotID = kCa4DChoice1SpotID;
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::makeDesertChoice() {
|
||||
if (_videoChoice != k4DDesertChoice && _clickedHotspotID == kNoHotSpotID)
|
||||
_clickedHotspotID = kCa4DChoice2SpotID;
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::makeMountainChoice() {
|
||||
if (_videoChoice != k4DMountainChoice && _clickedHotspotID == kNoHotSpotID)
|
||||
_clickedHotspotID = kCa4DChoice3SpotID;
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::makeRockChoice() {
|
||||
if (_audioChoice != k4DRockChoice) {
|
||||
_audioChoice = k4DRockChoice;
|
||||
setSpritesMovie();
|
||||
playSound("Rock");
|
||||
}
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::makeOrchestralChoice() {
|
||||
if (_audioChoice != k4DOrchestralChoice) {
|
||||
_audioChoice = k4DOrchestralChoice;
|
||||
setSpritesMovie();
|
||||
playSound("Orchestral");
|
||||
}
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::makeRhythmsChoice() {
|
||||
if (_audioChoice != k4DRhythmsChoice) {
|
||||
_audioChoice = k4DRhythmsChoice;
|
||||
setSpritesMovie();
|
||||
playSound("Rhythms");
|
||||
}
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::makeAcousticChoice() {
|
||||
if (_audioChoice != k4DAcousticChoice) {
|
||||
_audioChoice = k4DAcousticChoice;
|
||||
setSpritesMovie();
|
||||
playSound("Acoustic");
|
||||
}
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::shutDown4DSystem() {
|
||||
_whichMenu = k4DShuttingDown;
|
||||
}
|
||||
|
||||
void Caldoria4DSystem::playSound(const Common::String &baseFileName) {
|
||||
Common::String fileName = "Sounds/Caldoria/" + baseFileName;
|
||||
|
||||
// Updated DVD files
|
||||
if (g_vm->isDVD())
|
||||
fileName += ".44K";
|
||||
|
||||
_owner->loadLoopSound1(Common::Path(fileName + ".aiff"));
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
79
engines/pegasus/neighborhood/caldoria/caldoria4dsystem.h
Normal file
79
engines/pegasus/neighborhood/caldoria/caldoria4dsystem.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_CALDORIA_CALDORIA4DSYSTEM_H
|
||||
#define PEGASUS_NEIGHBORHOOD_CALDORIA_CALDORIA4DSYSTEM_H
|
||||
|
||||
#include "pegasus/interaction.h"
|
||||
#include "pegasus/movie.h"
|
||||
#include "pegasus/notification.h"
|
||||
#include "pegasus/timers.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class Neighborhood;
|
||||
|
||||
class Caldoria4DSystem : public GameInteraction, private Idler, public NotificationReceiver {
|
||||
public:
|
||||
Caldoria4DSystem(Neighborhood *);
|
||||
~Caldoria4DSystem() override;
|
||||
|
||||
void shutDown4DSystem();
|
||||
|
||||
protected:
|
||||
void openInteraction() override;
|
||||
void initInteraction() override;
|
||||
void closeInteraction() override;
|
||||
|
||||
void handleInput(const Input &, const Hotspot *) override;
|
||||
void activateHotspots() override;
|
||||
void clickInHotspot(const Input &, const Hotspot *) override;
|
||||
void receiveNotification(Notification *, const NotificationFlags) override;
|
||||
void setSpritesMovie();
|
||||
void makeIslandChoice();
|
||||
void makeRockChoice();
|
||||
void makeMountainChoice();
|
||||
void makeOrchestralChoice();
|
||||
void makeDesertChoice();
|
||||
void makeRhythmsChoice();
|
||||
void makeAcousticChoice();
|
||||
|
||||
void useIdleTime() override;
|
||||
void loopExtra(const ExtraID);
|
||||
|
||||
void playSound(const Common::String &baseFileName);
|
||||
|
||||
Movie _4DSpritesMovie;
|
||||
TimeScale _4DSpritesScale;
|
||||
uint _whichMenu;
|
||||
uint _videoChoice;
|
||||
uint _audioChoice;
|
||||
Notification *_neighborhoodNotification;
|
||||
TimeValue _loopStart;
|
||||
HotSpotID _clickedHotspotID;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
1473
engines/pegasus/neighborhood/caldoria/caldoriabomb.cpp
Normal file
1473
engines/pegasus/neighborhood/caldoria/caldoriabomb.cpp
Normal file
File diff suppressed because it is too large
Load Diff
158
engines/pegasus/neighborhood/caldoria/caldoriabomb.h
Normal file
158
engines/pegasus/neighborhood/caldoria/caldoriabomb.h
Normal file
@@ -0,0 +1,158 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_CALDORIA_CALDORIABOMB_H
|
||||
#define PEGASUS_NEIGHBORHOOD_CALDORIA_CALDORIABOMB_H
|
||||
|
||||
#include "pegasus/interaction.h"
|
||||
#include "pegasus/notification.h"
|
||||
#include "pegasus/surface.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
/*
|
||||
Edge list is arranged as follows:
|
||||
|
||||
all values in the edge list are bytes.
|
||||
|
||||
all vertices are numbers between 0 and 24. x coordinate of vertex is vertex % 5,
|
||||
and y coordinate is vertex / 5.
|
||||
|
||||
an edge is
|
||||
a direction code
|
||||
a number of vertices in the edge
|
||||
an array of vertices -- all vertices along the edge, whether or not they're
|
||||
clickable.
|
||||
an array of bools (bytes) indicating that a portion of the edge is
|
||||
traversed (and should be drawn). the number of bools is one less than
|
||||
the number of vertices.
|
||||
|
||||
an edge list is
|
||||
an array of 25 bools indicating which vertex is clickable.
|
||||
an array of 25 bools indicating which vertex is used (drawn).
|
||||
a number of edges
|
||||
an array of edges.
|
||||
|
||||
a hot vertex list is
|
||||
a number of vertices
|
||||
an array of 25 vertices
|
||||
|
||||
*/
|
||||
|
||||
typedef int8 VertexType;
|
||||
typedef VertexType *BombEdgeList;
|
||||
|
||||
static const VertexType kEdgeOneSixteenth = 0;
|
||||
static const VertexType kEdgeOneEighth = 1;
|
||||
static const VertexType kEdgeThreeSixteenths = 2;
|
||||
static const VertexType kEdgeOneFourth = 3;
|
||||
static const VertexType kEdgeFiveSixteenths = 4;
|
||||
static const VertexType kEdgeThreeEighths = 5;
|
||||
static const VertexType kEdgeSevenSixteenths = 6;
|
||||
static const VertexType kEdgeOneHalf = 7;
|
||||
|
||||
class BombTimer : public IdlerAnimation {
|
||||
public:
|
||||
BombTimer(const DisplayElementID);
|
||||
~BombTimer() override {}
|
||||
|
||||
void draw(const Common::Rect &) override;
|
||||
|
||||
protected:
|
||||
void timeChanged(const TimeValue) override;
|
||||
|
||||
int _middle;
|
||||
Surface _leftImage, _rightImage;
|
||||
};
|
||||
|
||||
class BombGrid : public Picture {
|
||||
public:
|
||||
BombGrid(const DisplayElementID);
|
||||
~BombGrid() override {}
|
||||
|
||||
void drawEdges(BombEdgeList);
|
||||
|
||||
protected:
|
||||
Frame _yellowDot;
|
||||
Frame _yellowOneSixteenth;
|
||||
Frame _yellowOneEighth;
|
||||
Frame _yellowThreeSixteenths;
|
||||
Frame _yellowOneFourth;
|
||||
Frame _yellowFiveSixteenths;
|
||||
Frame _yellowThreeEighths;
|
||||
Frame _yellowSevenSixteenths;
|
||||
Frame _yellowOneHalf;
|
||||
Frame _redDot;
|
||||
Frame _redOneSixteenth;
|
||||
Frame _redOneEighth;
|
||||
Frame _redThreeSixteenths;
|
||||
Frame _redOneFourth;
|
||||
Frame _redFiveSixteenths;
|
||||
Frame _redThreeEighths;
|
||||
Frame _redSevenSixteenths;
|
||||
Frame _redOneHalf;
|
||||
};
|
||||
|
||||
class Hotspot;
|
||||
|
||||
class CaldoriaBomb : public GameInteraction, public NotificationReceiver {
|
||||
public:
|
||||
CaldoriaBomb(Neighborhood *, NotificationManager *);
|
||||
~CaldoriaBomb() override;
|
||||
|
||||
void setSoundFXLevel(const uint16) override;
|
||||
void setAmbienceLevel(const uint16) override;
|
||||
|
||||
long getNumHints() override;
|
||||
Common::Path getHintMovie(uint) override;
|
||||
void doSolve() override;
|
||||
bool canSolve() override;
|
||||
|
||||
protected:
|
||||
void openInteraction() override;
|
||||
void initInteraction() override;
|
||||
void closeInteraction() override;
|
||||
void receiveNotification(Notification *, const NotificationFlags) override;
|
||||
void activateHotspots() override;
|
||||
void clickInHotspot(const Input &, const Hotspot *) override;
|
||||
void handleInput(const Input &, const Hotspot *) override;
|
||||
InputBits getInputFilter() override;
|
||||
void startBombAmbient(const Common::Path &);
|
||||
|
||||
Notification *_neighborhoodNotification;
|
||||
BombGrid _grid;
|
||||
BombTimer _timer;
|
||||
BombEdgeList _bombLevel[6];
|
||||
int _currentLevel, _flashTime;
|
||||
Hotspot *_vertexHotspot[25];
|
||||
VertexType _lastVertex;
|
||||
Notification _timerNotification;
|
||||
NotificationCallBack _timerCallBack;
|
||||
|
||||
TimeValue _readTime;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
124
engines/pegasus/neighborhood/caldoria/caldoriamessages.cpp
Normal file
124
engines/pegasus/neighborhood/caldoria/caldoriamessages.cpp
Normal file
@@ -0,0 +1,124 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/neighborhood/neighborhood.h"
|
||||
#include "pegasus/neighborhood/caldoria/caldoria.h"
|
||||
#include "pegasus/neighborhood/caldoria/caldoriamessages.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
static const NotificationFlags kMessageDoneFlag = 1;
|
||||
|
||||
CaldoriaMessages::CaldoriaMessages(Neighborhood *owner, const NotificationID id, NotificationManager *manager) :
|
||||
GameInteraction(kCaldoriaMessagesInteractionID, owner), Notification(id, manager), _messageMovie(kCaldoriaMessagesID) {
|
||||
_neighborhoodNotification = nullptr;
|
||||
_messageNumber = 0;
|
||||
}
|
||||
|
||||
void CaldoriaMessages::openInteraction() {
|
||||
_neighborhoodNotification = GameInteraction::_owner->getNeighborhoodNotification();
|
||||
_neighborhoodNotification->notifyMe(this, kExtraCompletedFlag, kExtraCompletedFlag);
|
||||
_messageCallBack.setNotification(this);
|
||||
notifyMe(this, kMessageDoneFlag, kMessageDoneFlag);
|
||||
_messageCallBack.setCallBackFlag(kMessageDoneFlag);
|
||||
_messageNumber = 1;
|
||||
}
|
||||
|
||||
void CaldoriaMessages::setSoundFXLevel(const uint16 fxLevel) {
|
||||
_messageMovie.setVolume(fxLevel);
|
||||
}
|
||||
|
||||
void CaldoriaMessages::initInteraction() {
|
||||
GameInteraction::_owner->startExtraSequence(kCaBedroomVidPhone, kExtraCompletedFlag, kFilterNoInput);
|
||||
}
|
||||
|
||||
void CaldoriaMessages::closeInteraction() {
|
||||
cancelNotification(this);
|
||||
_neighborhoodNotification->cancelNotification(this);
|
||||
}
|
||||
|
||||
void CaldoriaMessages::receiveNotification(Notification *notification, const NotificationFlags) {
|
||||
if (notification == _neighborhoodNotification) {
|
||||
switch (GameInteraction::_owner->getLastExtra()) {
|
||||
case kCaBedroomVidPhone:
|
||||
GameInteraction::_owner->showExtraView(kCaBedroomMessage1);
|
||||
break;
|
||||
case kCaBedroomMessage1:
|
||||
play1Message(1);
|
||||
break;
|
||||
case kCaBedroomMessage2:
|
||||
play1Message(2);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
_messageCallBack.releaseCallBack();
|
||||
_messageMovie.releaseMovie();
|
||||
|
||||
uint32 extraID = (_messageNumber == 1) ? kCaBedroomMessage1 : kCaBedroomMessage2;
|
||||
GameInteraction::_owner->showExtraView(extraID);
|
||||
allowInput(true);
|
||||
}
|
||||
}
|
||||
|
||||
void CaldoriaMessages::clickInHotspot(const Input &input, const Hotspot *spot) {
|
||||
uint32 extraID;
|
||||
|
||||
switch (spot->getObjectID()) {
|
||||
case kCaBedroomVidPhoneActivationSpotID:
|
||||
extraID = (_messageNumber == 1) ? kCaBedroomMessage1 : kCaBedroomMessage2;
|
||||
GameInteraction::_owner->startExtraSequence(extraID, kExtraCompletedFlag, kFilterNoInput);
|
||||
break;
|
||||
default:
|
||||
GameInteraction::clickInHotspot(input, spot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CaldoriaMessages::play1Message(uint messageNumber) {
|
||||
if (messageNumber == 1) {
|
||||
_messageMovie.initFromMovieFile("Images/Caldoria/A12NVA.movie");
|
||||
_messageNumber = 2;
|
||||
} else {
|
||||
_messageMovie.initFromMovieFile("Images/Caldoria/A12NVB.movie");
|
||||
_messageNumber = 1;
|
||||
GameState.setCaldoriaSeenMessages(true);
|
||||
}
|
||||
|
||||
_messageMovie.setVolume(g_vm->getSoundFXLevel());
|
||||
_messageMovie.moveElementTo(kCaldoriaMessageLeft, kCaldoriaMessageTop);
|
||||
_messageMovie.setDisplayOrder(kCaldoriaMessagesOrder);
|
||||
_messageMovie.startDisplaying();
|
||||
_messageCallBack.initCallBack(&_messageMovie, kCallBackAtExtremes);
|
||||
_messageCallBack.scheduleCallBack(kTriggerAtStop, 0, 0);
|
||||
allowInput(false);
|
||||
_messageMovie.show();
|
||||
_messageMovie.redrawMovieWorld();
|
||||
_messageMovie.start();
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
61
engines/pegasus/neighborhood/caldoria/caldoriamessages.h
Normal file
61
engines/pegasus/neighborhood/caldoria/caldoriamessages.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_CALDORIA_CALDORIAMESSAGES_H
|
||||
#define PEGASUS_NEIGHBORHOOD_CALDORIA_CALDORIAMESSAGES_H
|
||||
|
||||
#include "pegasus/input.h"
|
||||
#include "pegasus/interaction.h"
|
||||
#include "pegasus/movie.h"
|
||||
#include "pegasus/notification.h"
|
||||
#include "pegasus/timers.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class Neighborhood;
|
||||
|
||||
class CaldoriaMessages : public GameInteraction, public Notification, public NotificationReceiver {
|
||||
public:
|
||||
CaldoriaMessages(Neighborhood *, const NotificationID, NotificationManager *);
|
||||
~CaldoriaMessages() override {}
|
||||
|
||||
void setSoundFXLevel(const uint16) override;
|
||||
|
||||
protected:
|
||||
void openInteraction() override;
|
||||
void initInteraction() override;
|
||||
void closeInteraction() override;
|
||||
void receiveNotification(Notification *, const NotificationFlags) override;
|
||||
void clickInHotspot(const Input &, const Hotspot *) override;
|
||||
void play1Message(uint);
|
||||
|
||||
Movie _messageMovie;
|
||||
NotificationCallBack _messageCallBack;
|
||||
Notification *_neighborhoodNotification;
|
||||
uint _messageNumber;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
133
engines/pegasus/neighborhood/caldoria/caldoriamirror.cpp
Normal file
133
engines/pegasus/neighborhood/caldoria/caldoriamirror.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "pegasus/gamestate.h"
|
||||
#include "pegasus/pegasus.h"
|
||||
#include "pegasus/items/biochips/arthurchip.h"
|
||||
#include "pegasus/neighborhood/neighborhood.h"
|
||||
#include "pegasus/neighborhood/caldoria/caldoria.h"
|
||||
#include "pegasus/neighborhood/caldoria/caldoriamirror.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
CaldoriaMirror::CaldoriaMirror(Neighborhood *owner) : GameInteraction(kCaldoriaMirrorInteractionID, owner) {
|
||||
_neighborhoodNotification = nullptr;
|
||||
}
|
||||
|
||||
void CaldoriaMirror::openInteraction() {
|
||||
_neighborhoodNotification = _owner->getNeighborhoodNotification();
|
||||
_neighborhoodNotification->notifyMe(this, kExtraCompletedFlag, kExtraCompletedFlag);
|
||||
}
|
||||
|
||||
void CaldoriaMirror::initInteraction() {
|
||||
_owner->setCurrentActivation(kActivateMirrorReady);
|
||||
_owner->startExtraSequence(kCaBathroomGreeting, kExtraCompletedFlag, kFilterNoInput);
|
||||
// The original made the player click to start each of the following sequences,
|
||||
// which was unnecessary, so it is automated here.
|
||||
_owner->startExtraSequenceSync(kCaBathroomGreeting, kFilterNoInput);
|
||||
_owner->startExtraSequenceSync(kCaBathroomBodyFat, kFilterNoInput);
|
||||
_owner->startExtraSequence(kCaBathroomStylistIntro, kExtraCompletedFlag, kFilterNoInput);
|
||||
}
|
||||
|
||||
void CaldoriaMirror::closeInteraction() {
|
||||
_neighborhoodNotification->cancelNotification(this);
|
||||
}
|
||||
|
||||
void CaldoriaMirror::handleInput(const Input &input, const Hotspot *cursorSpot) {
|
||||
if (_owner->getLastExtra() == (uint32)kCaBathroomAgencyStandard || !input.anyDirectionInput())
|
||||
GameInteraction::handleInput(input, cursorSpot);
|
||||
}
|
||||
|
||||
void CaldoriaMirror::activateHotspots() {
|
||||
GameInteraction::activateHotspots();
|
||||
|
||||
switch (_owner->getLastExtra()) {
|
||||
case kCaBathroomGreeting:
|
||||
case kCaBathroomBodyFat:
|
||||
case kCaBathroomRetrothrash:
|
||||
case kCaBathroomGeoWave:
|
||||
g_allHotspots.activateOneHotspot(kCaBathroomMirrorSpotID);
|
||||
g_allHotspots.deactivateOneHotspot(kCaHairStyle1SpotID);
|
||||
g_allHotspots.deactivateOneHotspot(kCaHairStyle2SpotID);
|
||||
g_allHotspots.deactivateOneHotspot(kCaHairStyle3SpotID);
|
||||
break;
|
||||
case kCaBathroomStylistIntro:
|
||||
case kCaBathroomRetrothrashReturn:
|
||||
case kCaBathroomGeoWaveReturn:
|
||||
g_allHotspots.activateOneHotspot(kCaHairStyle1SpotID);
|
||||
g_allHotspots.activateOneHotspot(kCaHairStyle2SpotID);
|
||||
g_allHotspots.activateOneHotspot(kCaHairStyle3SpotID);
|
||||
g_allHotspots.deactivateOneHotspot(kCaBathroomMirrorSpotID);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CaldoriaMirror::clickInHotspot(const Input &input, const Hotspot *spot) {
|
||||
switch (spot->getObjectID()) {
|
||||
// The original made the player click through several interstitial screens before
|
||||
// reaching the hairstyle menu, which was unnecessary, so it's skipped here.
|
||||
case kCaHairStyle1SpotID:
|
||||
_owner->startExtraSequenceSync(kCaBathroomRetrothrash, kFilterNoInput);
|
||||
_owner->startExtraSequence(kCaBathroomRetrothrashReturn, kExtraCompletedFlag, kFilterNoInput);
|
||||
break;
|
||||
case kCaHairStyle2SpotID:
|
||||
_owner->startExtraSequence(kCaBathroomAgencyStandard, kExtraCompletedFlag, kFilterNoInput);
|
||||
break;
|
||||
case kCaHairStyle3SpotID:
|
||||
_owner->startExtraSequenceSync(kCaBathroomGeoWave, kFilterNoInput);
|
||||
_owner->startExtraSequence(kCaBathroomGeoWaveReturn, kExtraCompletedFlag, kFilterNoInput);
|
||||
break;
|
||||
default:
|
||||
GameInteraction::clickInHotspot(input, spot);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CaldoriaMirror::receiveNotification(Notification *, const NotificationFlags) {
|
||||
switch (_owner->getLastExtra()) {
|
||||
case kCaBathroomRetrothrash:
|
||||
case kCaBathroomGeoWave:
|
||||
_owner->setCurrentActivation(kActivateMirrorReady);
|
||||
break;
|
||||
case kCaBathroomStylistIntro:
|
||||
case kCaBathroomRetrothrashReturn:
|
||||
case kCaBathroomGeoWaveReturn:
|
||||
_owner->setCurrentActivation(kActivateStylistReady);
|
||||
break;
|
||||
case kCaBathroomAgencyStandard:
|
||||
_owner->setCurrentActivation(kActivateHotSpotAlways);
|
||||
_owner->requestDeleteCurrentInteraction();
|
||||
GameState.setScoringFixedHair(true);
|
||||
GameState.setCaldoriaDoneHygiene(true);
|
||||
if (g_arthurChip)
|
||||
g_arthurChip->playArthurMovieForEvent("Images/AI/Globals/XGLOBA43", kArthurCaldoriaChoseAgencyHairStyle);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
53
engines/pegasus/neighborhood/caldoria/caldoriamirror.h
Normal file
53
engines/pegasus/neighborhood/caldoria/caldoriamirror.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_CALDORIA_CALDORIAMIRROR_H
|
||||
#define PEGASUS_NEIGHBORHOOD_CALDORIA_CALDORIAMIRROR_H
|
||||
|
||||
#include "pegasus/interaction.h"
|
||||
#include "pegasus/notification.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class CaldoriaMirror : public GameInteraction, public NotificationReceiver {
|
||||
public:
|
||||
CaldoriaMirror(Neighborhood *);
|
||||
~CaldoriaMirror() override {}
|
||||
|
||||
protected:
|
||||
void openInteraction() override;
|
||||
void initInteraction() override;
|
||||
void closeInteraction() override;
|
||||
|
||||
void handleInput(const Input &, const Hotspot *) override;
|
||||
void activateHotspots() override;
|
||||
void clickInHotspot(const Input &, const Hotspot *) override;
|
||||
void receiveNotification(Notification *, const NotificationFlags) override;
|
||||
|
||||
Notification *_neighborhoodNotification;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
63
engines/pegasus/neighborhood/door.cpp
Normal file
63
engines/pegasus/neighborhood/door.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
#include "pegasus/neighborhood/door.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
void DoorTable::loadFromStream(Common::SeekableReadStream *stream) {
|
||||
uint32 count = stream->readUint32BE();
|
||||
_entries.resize(count);
|
||||
|
||||
for (uint32 i = 0; i < count; i++) {
|
||||
_entries[i].room = stream->readUint16BE();
|
||||
_entries[i].direction = stream->readByte();
|
||||
_entries[i].altCode = stream->readByte();
|
||||
_entries[i].movieStart = stream->readUint32BE();
|
||||
_entries[i].movieEnd = stream->readUint32BE();
|
||||
_entries[i].flags = stream->readByte();
|
||||
stream->readByte(); // alignment
|
||||
debug(0, "Door[%d]: %d %d %d %d %d %d", i, _entries[i].room, _entries[i].direction,
|
||||
_entries[i].altCode, _entries[i].movieStart, _entries[i].movieEnd,
|
||||
_entries[i].flags);
|
||||
}
|
||||
}
|
||||
|
||||
void DoorTable::clear() {
|
||||
_entries.clear();
|
||||
}
|
||||
|
||||
DoorTable::Entry DoorTable::findEntry(RoomID room, DirectionConstant direction, AlternateID altCode) {
|
||||
for (uint32 i = 0; i < _entries.size(); i++)
|
||||
if (_entries[i].room == room && _entries[i].direction == direction && _entries[i].altCode == altCode)
|
||||
return _entries[i];
|
||||
|
||||
return Entry();
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
88
engines/pegasus/neighborhood/door.h
Normal file
88
engines/pegasus/neighborhood/door.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_DOOR_H
|
||||
#define PEGASUS_NEIGHBORHOOD_DOOR_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/endian.h"
|
||||
|
||||
#include "pegasus/constants.h"
|
||||
|
||||
namespace Common {
|
||||
class SeekableReadStream;
|
||||
}
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
typedef byte DoorFlags;
|
||||
|
||||
enum {
|
||||
kDoorPresentBit, // Bit set if there is a door here.
|
||||
kDoorLockedBit // Bit set if door is locked, clear if unlocked.
|
||||
};
|
||||
|
||||
static const DoorFlags kNoDoorFlags = 0;
|
||||
static const DoorFlags kDoorPresentMask = 1 << kDoorPresentBit;
|
||||
static const DoorFlags kDoorLockedMask = 1 << kDoorLockedBit;
|
||||
|
||||
class DoorTable {
|
||||
public:
|
||||
DoorTable() {}
|
||||
~DoorTable() {}
|
||||
|
||||
static uint32 getResTag() { return MKTAG('D', 'o', 'o', 'r'); }
|
||||
|
||||
void loadFromStream(Common::SeekableReadStream *stream);
|
||||
void clear();
|
||||
|
||||
struct Entry {
|
||||
Entry() { clear(); }
|
||||
bool isEmpty() { return movieStart == 0xffffffff; }
|
||||
void clear() {
|
||||
room = kNoRoomID;
|
||||
direction = kNoDirection;
|
||||
altCode = kNoAlternateID;
|
||||
movieStart = 0xffffffff;
|
||||
movieEnd = 0xffffffff;
|
||||
flags = kNoDoorFlags;
|
||||
}
|
||||
|
||||
RoomID room;
|
||||
DirectionConstant direction;
|
||||
AlternateID altCode;
|
||||
TimeValue movieStart;
|
||||
TimeValue movieEnd;
|
||||
DoorFlags flags;
|
||||
};
|
||||
|
||||
Entry findEntry(RoomID room, DirectionConstant direction, AlternateID altCode);
|
||||
|
||||
private:
|
||||
Common::Array<Entry> _entries;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
69
engines/pegasus/neighborhood/exit.cpp
Normal file
69
engines/pegasus/neighborhood/exit.cpp
Normal file
@@ -0,0 +1,69 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
#include "pegasus/neighborhood/exit.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
void ExitTable::loadFromStream(Common::SeekableReadStream *stream) {
|
||||
uint32 count = stream->readUint32BE();
|
||||
_entries.resize(count);
|
||||
|
||||
for (uint32 i = 0; i < count; i++) {
|
||||
_entries[i].room = stream->readUint16BE();
|
||||
_entries[i].direction = stream->readByte();
|
||||
_entries[i].altCode = stream->readByte();
|
||||
_entries[i].movieStart = stream->readUint32BE();
|
||||
_entries[i].movieEnd = stream->readUint32BE();
|
||||
_entries[i].exitEnd = stream->readUint32BE();
|
||||
_entries[i].exitLoop = stream->readUint32BE();
|
||||
_entries[i].exitRoom = stream->readUint16BE();
|
||||
_entries[i].exitDirection = stream->readByte();
|
||||
stream->readByte(); // alignment
|
||||
|
||||
_entries[i].originalEnd = _entries[i].exitEnd;
|
||||
|
||||
debug(0, "Exit[%d]: %d %d %d %d %d %d %d %d %d", i, _entries[i].room, _entries[i].direction,
|
||||
_entries[i].altCode, _entries[i].movieStart, _entries[i].movieEnd, _entries[i].exitEnd,
|
||||
_entries[i].exitLoop, _entries[i].exitRoom, _entries[i].exitDirection);
|
||||
}
|
||||
}
|
||||
|
||||
void ExitTable::clear() {
|
||||
_entries.clear();
|
||||
}
|
||||
|
||||
ExitTable::Entry ExitTable::findEntry(RoomID room, DirectionConstant direction, AlternateID altCode) {
|
||||
for (uint32 i = 0; i < _entries.size(); i++)
|
||||
if (_entries[i].room == room && _entries[i].direction == direction && _entries[i].altCode == altCode)
|
||||
return _entries[i];
|
||||
|
||||
return Entry();
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
92
engines/pegasus/neighborhood/exit.h
Normal file
92
engines/pegasus/neighborhood/exit.h
Normal file
@@ -0,0 +1,92 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_EXIT_H
|
||||
#define PEGASUS_NEIGHBORHOOD_EXIT_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/endian.h"
|
||||
|
||||
#include "pegasus/constants.h"
|
||||
|
||||
namespace Common {
|
||||
class SeekableReadStream;
|
||||
}
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class ExitTable {
|
||||
public:
|
||||
ExitTable() {}
|
||||
~ExitTable() {}
|
||||
|
||||
static uint32 getResTag() { return MKTAG('E', 'x', 'i', 't'); }
|
||||
|
||||
void loadFromStream(Common::SeekableReadStream *stream);
|
||||
void clear();
|
||||
|
||||
struct Entry {
|
||||
Entry() { clear(); }
|
||||
bool isEmpty() { return movieStart == 0xffffffff; }
|
||||
void clear() {
|
||||
room = kNoRoomID;
|
||||
direction = kNoDirection;
|
||||
altCode = kNoAlternateID;
|
||||
movieStart = 0xffffffff;
|
||||
movieEnd = 0xffffffff;
|
||||
exitEnd = 0xffffffff;
|
||||
originalEnd = 0xffffffff;
|
||||
exitLoop = 0xffffffff;
|
||||
exitRoom = kNoRoomID;
|
||||
exitDirection = kNoDirection;
|
||||
}
|
||||
|
||||
RoomID room;
|
||||
DirectionConstant direction;
|
||||
AlternateID altCode;
|
||||
TimeValue movieStart;
|
||||
TimeValue movieEnd;
|
||||
// exitEnd is the end of the optimized run of walks.
|
||||
TimeValue exitEnd;
|
||||
TimeValue originalEnd;
|
||||
// exitLoop is the loop start time of the optimized run of walks if the run
|
||||
// loops back on itself (so far, only in TSA).
|
||||
TimeValue exitLoop;
|
||||
RoomID exitRoom;
|
||||
DirectionConstant exitDirection;
|
||||
};
|
||||
|
||||
Entry findEntry(RoomID room, DirectionConstant direction, AlternateID altCode);
|
||||
|
||||
typedef Common::Array<Entry>::iterator iterator;
|
||||
iterator begin() { return _entries.begin(); }
|
||||
iterator end() { return _entries.end(); }
|
||||
|
||||
private:
|
||||
Common::Array<Entry> _entries;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
57
engines/pegasus/neighborhood/extra.cpp
Normal file
57
engines/pegasus/neighborhood/extra.cpp
Normal file
@@ -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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/stream.h"
|
||||
#include "common/textconsole.h"
|
||||
|
||||
#include "pegasus/neighborhood/extra.h"
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
void ExtraTable::loadFromStream(Common::SeekableReadStream *stream) {
|
||||
uint32 count = stream->readUint32BE();
|
||||
_entries.resize(count);
|
||||
|
||||
for (uint32 i = 0; i < count; i++) {
|
||||
_entries[i].extra = stream->readUint32BE();
|
||||
_entries[i].movieStart = stream->readUint32BE();
|
||||
_entries[i].movieEnd = stream->readUint32BE();
|
||||
debug(0, "Extra[%d]: %d %d %d", i, _entries[i].extra, _entries[i].movieStart, _entries[i].movieEnd);
|
||||
}
|
||||
}
|
||||
|
||||
void ExtraTable::clear() {
|
||||
_entries.clear();
|
||||
}
|
||||
|
||||
ExtraTable::Entry ExtraTable::findEntry(ExtraID extra) {
|
||||
for (uint32 i = 0; i < _entries.size(); i++)
|
||||
if (_entries[i].extra == extra)
|
||||
return _entries[i];
|
||||
|
||||
return Entry();
|
||||
}
|
||||
|
||||
} // End of namespace Pegasus
|
||||
66
engines/pegasus/neighborhood/extra.h
Normal file
66
engines/pegasus/neighborhood/extra.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/* 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 3 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, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PEGASUS_NEIGHBORHOOD_EXTRA_H
|
||||
#define PEGASUS_NEIGHBORHOOD_EXTRA_H
|
||||
|
||||
#include "common/array.h"
|
||||
#include "common/endian.h"
|
||||
|
||||
#include "pegasus/constants.h"
|
||||
|
||||
namespace Common {
|
||||
class SeekableReadStream;
|
||||
}
|
||||
|
||||
namespace Pegasus {
|
||||
|
||||
class ExtraTable {
|
||||
public:
|
||||
ExtraTable() {}
|
||||
~ExtraTable() {}
|
||||
|
||||
static uint32 getResTag() { return MKTAG('X', 't', 'r', 'a'); }
|
||||
|
||||
void loadFromStream(Common::SeekableReadStream *stream);
|
||||
void clear();
|
||||
|
||||
struct Entry {
|
||||
Entry() { movieStart = 0xffffffff; }
|
||||
bool isEmpty() { return movieStart == 0xffffffff; }
|
||||
|
||||
ExtraID extra;
|
||||
TimeValue movieStart;
|
||||
TimeValue movieEnd;
|
||||
};
|
||||
|
||||
Entry findEntry(ExtraID extra);
|
||||
|
||||
private:
|
||||
Common::Array<Entry> _entries;
|
||||
};
|
||||
|
||||
} // End of namespace Pegasus
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user