PEGASUS: Add the WSC neighborhood

Seems to be working fine, minus the molecule sprites (though the minigame is completable and the antidote can be found).
This commit is contained in:
Matthew Hoops 2011-10-13 20:59:20 -04:00
parent 13fef21fed
commit 753006ae1a
14 changed files with 2946 additions and 21 deletions

View File

@ -745,7 +745,6 @@ const tRoomID kMars39 = 42;
const tRoomID kMars60 = 58;
const tRoomID kMarsMaze004 = 60;
const tRoomID kMarsMaze200 = 224;
static const tRoomID kWSC01 = 0;
} // End of namespace Pegasus

View File

@ -44,6 +44,7 @@ void InputDevice::getInput(Input &input, const tInputBits filter) {
tInputBits currentBits = 0;
bool consoleRequested = false;
bool altDown = false;
Common::Event event;
while (g_system->getEventManager()->pollEvent(event)) {
@ -104,13 +105,13 @@ void InputDevice::getInput(Input &input, const tInputBits filter) {
break;
}
#if 0
// FIXME: This is disabled for now because it interferes with
// the ScummVM alt combinations. It's only used for one easter egg
// anyway, so I'll come up with something when I get around to that.
// WORKAROUND: The original had a specific key for this, but
// 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.
if (event.kbd.flags & Common::KBD_ALT)
currentBits |= (kRawButtonDown << kMod2ButtonShift);
#endif
altDown = true;
}
}
@ -133,6 +134,9 @@ void InputDevice::getInput(Input &input, const tInputBits filter) {
// Set the console to be requested or not
input.setConsoleRequested(consoleRequested);
// Same for alt
input.setAltDown(altDown);
}
// Wait until the input device stops returning input allowed by filter...

View File

@ -358,6 +358,7 @@ public:
bool anyInputBitSet(const tInputBits bits) const { return (_inputState & bits) != 0; }
bool isAltDown() const { return _altDown; }
bool isConsoleRequested() const { return _consoleRequested; }
void clearInput() {
@ -365,16 +366,19 @@ public:
_inputLocation.x = 0;
_inputLocation.y = 0;
_consoleRequested = false;
_altDown = false;
}
protected:
void setInputBits(const tInputBits state) { _inputState = state; }
void setInputLocation(const Common::Point &where) { _inputLocation = where; }
void setConsoleRequested(bool consoleRequested) { _consoleRequested = consoleRequested; }
void setAltDown(bool altDown) { _altDown = altDown; }
tInputBits _inputState;
Common::Point _inputLocation;
bool _consoleRequested;
bool _altDown;
};
class InputHandler {
@ -476,7 +480,7 @@ public:
static bool isToggleInfoInput(const Input &input) { return input.fourButtonDown(); }
// Hmmmmm....
static bool isEasterEggModifierInput(const Input &input) { return input.mod2ButtonAnyDown(); }
static bool isEasterEggModifierInput(const Input &input) { return input.isAltDown(); }
static bool isTogglePauseInput(const Input &input) { return input.mod3ButtonDown(); }
};

View File

@ -59,7 +59,9 @@ MODULE_OBJS = \
neighborhood/caldoria/caldoriamirror.o \
neighborhood/prehistoric/prehistoric.o \
neighborhood/tsa/fulltsa.o \
neighborhood/tsa/tinytsa.o
neighborhood/tsa/tinytsa.o \
neighborhood/wsc/moleculebin.o \
neighborhood/wsc/wsc.o
# This module can be built as a plugin

View File

@ -33,6 +33,7 @@
#include "pegasus/neighborhood/caldoria/caldoria.h"
#include "pegasus/neighborhood/prehistoric/prehistoric.h"
#include "pegasus/neighborhood/tsa/fulltsa.h"
#include "pegasus/neighborhood/wsc/wsc.h"
namespace Pegasus {

View File

@ -30,6 +30,7 @@
#include "pegasus/items/biochips/aichip.h"
#include "pegasus/items/biochips/opticalchip.h"
#include "pegasus/neighborhood/tsa/tinytsa.h"
#include "pegasus/neighborhood/wsc/wsc.h"
namespace Pegasus {

View File

@ -0,0 +1,127 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* Additional copyright for this file:
* Copyright (C) 1995-1997 Presto Studios, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "pegasus/graphics.h"
#include "pegasus/neighborhood/wsc/moleculebin.h"
#include "pegasus/neighborhood/wsc/wsc.h"
namespace Pegasus {
static const tCoordType kMoleculeBinWidth = 138;
static const tCoordType kMoleculeBinHeight = 128;
static const tCoordType kMoleculeWidth = 66;
static const tCoordType kMoleculeHeight = 40;
static const tCoordType kMoleculeBinLeft = kNavAreaLeft + 286;
static const tCoordType kMoleculeBinTop = kNavAreaLeft + 96;
// Layouts:
MoleculeBin::MoleculeBin() : DisplayElement(kNoDisplayElement) {
_highlightColor = g_system->getScreenFormat().RGBToColor(0xff, 0xff, 102);
_selectedMolecule = -1;
}
void MoleculeBin::initMoleculeBin() {
if (!isDisplaying()) {
for (int i = 0; i < 6; i++)
_binLayout[i] = i;
resetBin();
_binImages.getImageFromPICTFile("Images/World Science Center/Molecules");
setDisplayOrder(kWSCMoleculeBinOrder);
setBounds(kMoleculeBinLeft, kMoleculeBinTop, kMoleculeBinLeft + kMoleculeBinWidth,
kMoleculeBinTop + kMoleculeBinHeight);
startDisplaying();
show();
}
}
void MoleculeBin::cleanUpMoleculeBin() {
if (isDisplaying()) {
stopDisplaying();
_binImages.deallocateSurface();
}
}
void MoleculeBin::setBinLayout(const uint32 *layout) {
for (int i = 0; i < 6; i++)
_binLayout[i] = layout[i];
}
void MoleculeBin::highlightMolecule(const uint32 whichMolecule) {
if (!_moleculeFlags.getFlag(whichMolecule)) {
_moleculeFlags.setFlag(whichMolecule, true);
triggerRedraw();
}
}
bool MoleculeBin::isMoleculeHighlighted(uint32 whichMolecule) {
return _moleculeFlags.getFlag(whichMolecule);
}
void MoleculeBin::selectMolecule(const int whichMolecule) {
if (_selectedMolecule != whichMolecule) {
_selectedMolecule = whichMolecule;
triggerRedraw();
}
}
void MoleculeBin::resetBin() {
_moleculeFlags.clearAllFlags();
_selectedMolecule = -1;
triggerRedraw();
}
void MoleculeBin::draw(const Common::Rect &) {
Common::Rect r1(0, 0, kMoleculeWidth, kMoleculeHeight);
Common::Rect r2 = r1;
for (int i = 0; i < 6; i++) {
r1.moveTo(i * (kMoleculeWidth * 2), 0);
if (_moleculeFlags.getFlag(_binLayout[i]))
r1.translate(kMoleculeWidth, 0);
r1.moveTo((_binLayout[i] & 1) * (kMoleculeWidth + 2) + _bounds.left + 2,
(_binLayout[i] >> 1) * (kMoleculeHeight + 2) + _bounds.top + 2);
_binImages.copyToCurrentPort(r1, r2);
}
if (_selectedMolecule >= 0) {
r2.moveTo((_selectedMolecule & 1) * (kMoleculeWidth + 2) + _bounds.left + 2,
(_selectedMolecule >> 1) * (kMoleculeHeight + 2) + _bounds.top + 2);
Graphics::Surface *screen = ((PegasusEngine *)g_engine)->_gfx->getWorkArea();
screen->frameRect(r2, _highlightColor);
r2.grow(1);
screen->frameRect(r2, _highlightColor);
}
}
} // End of namespace Pegasus

View File

@ -0,0 +1,72 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* Additional copyright for this file:
* Copyright (C) 1995-1997 Presto Studios, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_WSC_MOLECULEBIN_H
#define PEGASUS_NEIGHBORHOOD_WSC_MOLECULEBIN_H
#include "pegasus/elements.h"
#include "pegasus/surface.h"
#include "pegasus/util.h"
namespace Pegasus {
enum {
kMolecule1,
kMolecule2,
kMolecule3,
kMolecule4,
kMolecule5,
kMolecule6
};
class MoleculeBin : public DisplayElement {
public:
MoleculeBin();
virtual ~MoleculeBin() {}
void initMoleculeBin();
void cleanUpMoleculeBin();
void setBinLayout(const uint32 *);
void highlightMolecule(const uint32 whichMolecule);
void selectMolecule(const int whichMolecule);
void resetBin();
bool isMoleculeHighlighted(uint32);
protected:
void draw(const Common::Rect &);
Surface _binImages;
FlagsArray<byte, kMolecule6 + 1> _moleculeFlags;
int _selectedMolecule;
uint32 _binLayout[6];
uint32 _highlightColor;
};
} // End of namespace Pegasus
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,163 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* Additional copyright for this file:
* Copyright (C) 1995-1997 Presto Studios, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#ifndef PEGASUS_NEIGHBORHOOD_WSC_WSC_H
#define PEGASUS_NEIGHBORHOOD_WSC_WSC_H
#include "pegasus/neighborhood/neighborhood.h"
#include "pegasus/neighborhood/wsc/moleculebin.h"
namespace Pegasus {
const tDisplayOrder kWSCMoleculeBinOrder = kMonitorLayer;
const tDisplayOrder kWSCMoleculesMovieOrder = kWSCMoleculeBinOrder + 1;
const tRoomID kWSC01 = 0;
class WSC : public Neighborhood {
public:
WSC(InputHandler *, PegasusEngine *);
virtual ~WSC() {}
void flushGameState();
virtual uint16 getDateResID() const;
bool okayToJump();
void checkContinuePoint(const tRoomID, const tDirectionConstant);
bool inSynthesizerGame();
bool canSolve();
void doSolve();
virtual void prepareForAIHint(const Common::String &);
virtual void cleanUpAfterAIHint(const Common::String &);
void init();
void start();
protected:
enum {
kWSCDraggingAntidoteFlag,
kWSCPrivateLabMessagesOpenFlag,
kWSCPrivateInterruptedMorphFlag,
kWSCPrivateInMoleculeGameFlag,
kWSCPrivateSinclairOfficeOpenFlag,
kWSCPrivateOfficeLogOpenFlag,
kWSCPrivate58SouthOpenFlag,
kWSCPrivateClickedCatwalkCableFlag,
kWSCPrivateRobotHeadOpenFlag,
kWSCPrivateSeenPeopleAt17WestFlag,
kWSCPrivateSeenPeopleAt19NorthFlag,
kWSCPrivateSeenPeopleAt21SouthFlag,
kWSCPrivateSeenPeopleAt24SouthFlag,
kWSCPrivateSeenPeopleAt34EastFlag,
kWSCPrivateSeenPeopleAt36WestFlag,
kWSCPrivateSeenPeopleAt38NorthFlag,
kWSCPrivateSeenPeopleAt46SouthFlag,
kWSCPrivateSeenPeopleAt49NorthFlag,
kWSCPrivateSeenPeopleAt73WestFlag,
kWSCPrivateNeedPeopleAt17WestFlag,
kWSCPrivateNeedPeopleAt21SouthFlag,
kWSCPrivateNeedPeopleAt24SouthFlag,
kWSCPrivateNeedPeopleAt34EastFlag,
kWSCPrivateNeedPeopleAt36WestFlag,
kWSCPrivateNeedPeopleAt38NorthFlag,
kWSCPrivateNeedPeopleAt46SouthFlag,
kWSCPrivateNeedPeopleAt49NorthFlag,
kWSCPrivateNeedPeopleAt73WestFlag,
kWSCPrivateGotRetScanChipFlag,
kWSCPrivateGotMapChipFlag,
kWSCPrivateGotOpticalChipFlag,
kNumWSCPrivateFlags
};
void arriveAt(const tRoomID, const tDirectionConstant);
void turnTo(const tDirectionConstant);
void receiveNotification(Notification *, const tNotificationFlags);
void dropItemIntoRoom(Item *, Hotspot *);
void clickInHotspot(const Input &, const Hotspot *);
TimeValue getViewTime(const tRoomID, const tDirectionConstant);
void getZoomEntry(const tHotSpotID, ZoomTable::Entry &);
tCanMoveForwardReason canMoveForward(ExitTable::Entry &entry);
void cantMoveThatWay(tCanMoveForwardReason reason);
tCanTurnReason canTurn(tTurnDirection turn, tDirectionConstant &nextDir);
void zoomTo(const Hotspot *hotspot);
void activateOneHotspot(HotspotInfoTable::Entry &, Hotspot *);
void setUpMoleculeGame();
void nextMoleculeGameLevel();
void startMoleculeGameLevel();
void moleculeGameClick(const tHotSpotID);
void loadAmbientLoops();
tCanOpenDoorReason canOpenDoor(DoorTable::Entry &);
void cantOpenDoor(tCanOpenDoorReason);
void pickedUpItem(Item *);
void doorOpened();
void startExtraSequence(const tExtraID, const tNotificationFlags, const tInputBits);
void getExtraEntry(const uint32, ExtraTable::Entry &);
void takeItemFromRoom(Item *item);
void checkPeopleCrossing();
void turnLeft();
void turnRight();
void moveForward();
Hotspot *getItemScreenSpot(Item *, DisplayElement *);
int16 getStaticCompassAngle(const tRoomID, const tDirectionConstant);
void getExitCompassMove(const ExitTable::Entry &exitEntry, FaderMoveSpec &compassMove);
void getExtraCompassMove(const ExtraTable::Entry &entry, FaderMoveSpec &compassMove);
void bumpIntoWall();
void activateHotspots();
void setUpAIRules();
Common::String getBriefingMovie();
Common::String getEnvScanMovie();
uint getNumHints();
Common::String getHintMovie(uint);
void closeDoorOffScreen(const tRoomID, const tDirectionConstant);
void setUpPoison();
void findSpotEntry(const tRoomID, const tDirectionConstant, tSpotFlags, SpotTable::Entry &);
void timerExpired(const uint32);
Common::String getSoundSpotsName();
Common::String getNavMovieName();
FlagsArray<byte, kNumWSCPrivateFlags> _privateFlags;
const Hotspot *_cachedZoomSpot;
MoleculeBin _moleculeBin;
int32 _moleculeGameLevel, _numCorrect;
Movie _moleculesMovie;
uint32 _levelArray[6];
Common::Rational _energyDrainRate;
Sprite *_argonSprite;
};
} // End of namespace Pegasus
#endif

View File

@ -65,6 +65,7 @@
#include "pegasus/neighborhood/prehistoric/prehistoric.h"
#include "pegasus/neighborhood/tsa/fulltsa.h"
#include "pegasus/neighborhood/tsa/tinytsa.h"
#include "pegasus/neighborhood/wsc/wsc.h"
namespace Pegasus {
@ -1356,6 +1357,9 @@ void PegasusEngine::makeNeighborhood(tNeighborhoodID neighborhoodID, Neighborhoo
case kTinyTSAID:
neighborhood = new TinyTSA(g_AIArea, this);
break;
case kWSCID:
neighborhood = new WSC(g_AIArea, this);
break;
default:
error("Unhandled neighborhood %d", neighborhoodID);
}
@ -1857,6 +1861,20 @@ uint PegasusEngine::getRandomBit() {
return _rnd->getRandomBit();
}
uint PegasusEngine::getRandomNumber(uint max) {
return _rnd->getRandomNumber(max);
}
void PegasusEngine::shuffleArray(int32 *arr, int32 count) {
if (count > 1) {
for (int32 i = 1; i < count; ++i) {
int32 j = _rnd->getRandomNumber(i);
if (j != i)
SWAP(arr[i], arr[j]);
}
}
}
void PegasusEngine::playEndMessage() {
if (g_interface) {
allowInput(false);

View File

@ -107,6 +107,8 @@ public:
void setGameMode(const tGameMode);
tGameMode getGameMode() const { return _gameMode; }
uint getRandomBit();
uint getRandomNumber(uint max);
void shuffleArray(int32 *arr, int32 count);
// Energy
void setLastEnergyValue(const int32 value) { _savedEnergyValue = value; }

View File

@ -87,14 +87,4 @@ int32 linearInterp(const int32 start1, const int32 stop1, const int32 current1,
return start2 + pegasusRound((current1 - start1) * (stop2 - start2), (stop1 - start1));
}
void shuffleArray(int32 *arr, int32 count, Common::RandomSource &random) {
if (count > 1) {
for (int32 i = 1; i < count; ++i) {
int32 j = random.getRandomNumber(i);
if (j != i)
SWAP(arr[i], arr[j]);
}
}
}
} // End of namespace Pegasus

View File

@ -126,8 +126,6 @@ private:
int32 linearInterp(const int32 start1, const int32 stop1, const int32 current1, const int32 start2, const int32 stop2);
void shuffleArray(int32 *arr, int32 count, Common::RandomSource &random);
int32 pegasusRound(const int32 a, const int32 b);
} // End of namespace Pegasus