Skip to content

Commit

Permalink
PEGASUS: Implement some more neighborhood code
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthew Hoops committed Sep 1, 2011
1 parent 8263f5a commit 3239002
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 49 deletions.
2 changes: 1 addition & 1 deletion engines/pegasus/module.mk
Expand Up @@ -24,7 +24,7 @@ MODULE_OBJS = \
neighborhood/door.o \
neighborhood/exit.o \
neighborhood/extra.o \
neighborhood/hotspot.o \
neighborhood/hotspotinfo.o \
neighborhood/neighborhood.o \
neighborhood/spot.o \
neighborhood/turn.o \
Expand Down
Expand Up @@ -27,11 +27,11 @@
#include "common/stream.h"
#include "common/textconsole.h"

#include "pegasus/neighborhood/hotspot.h"
#include "pegasus/neighborhood/hotspotinfo.h"

namespace Pegasus {

void HotspotTable::loadFromStream(Common::SeekableReadStream *stream) {
void HotspotInfoTable::loadFromStream(Common::SeekableReadStream *stream) {
uint32 count = stream->readUint32BE();
_entries.resize(count);

Expand All @@ -50,11 +50,11 @@ void HotspotTable::loadFromStream(Common::SeekableReadStream *stream) {
}
}

void HotspotTable::clear() {
void HotspotInfoTable::clear() {
_entries.clear();
}

HotspotTable::Entry HotspotTable::findEntry(tHotSpotID hotspot) {
HotspotInfoTable::Entry HotspotInfoTable::findEntry(tHotSpotID hotspot) {
for (uint32 i = 0; i < _entries.size(); i++)
if (_entries[i].hotspot == hotspot)
return _entries[i];
Expand Down
Expand Up @@ -23,8 +23,8 @@
*
*/

#ifndef PEGASUS_NEIGHBORHOOD_HOTSPOT_H
#define PEGASUS_NEIGHBORHOOD_HOTSPOT_H
#ifndef PEGASUS_NEIGHBORHOOD_HOTSPOTINFO_H
#define PEGASUS_NEIGHBORHOOD_HOTSPOTINFO_H

#include "common/array.h"
#include "common/endian.h"
Expand All @@ -37,10 +37,10 @@ namespace Common {

namespace Pegasus {

class HotspotTable {
class HotspotInfoTable {
public:
HotspotTable() {}
~HotspotTable() {}
HotspotInfoTable() {}
~HotspotInfoTable() {}

static const uint32 getResTag() { return MKTAG('H', 'S', 'I', 'n'); }

Expand Down
140 changes: 136 additions & 4 deletions engines/pegasus/neighborhood/neighborhood.cpp
Expand Up @@ -27,11 +27,14 @@
#include "common/stream.h"

#include "pegasus/pegasus.h"
#include "pegasus/game_shell/CGameState.h"
#include "pegasus/neighborhood/neighborhood.h"

namespace Pegasus {

Neighborhood::Neighborhood(PegasusEngine *vm, const Common::String &resName) : _vm(vm), _resName(resName) {
Neighborhood::Neighborhood(PegasusEngine *vm, const Common::String &resName, tNeighborhoodID id) : _vm(vm), _resName(resName) {
CGameState::SetOpenDoorLocation(kNoRoomID, kNoDirection);
_currentAlternate = 0;
}

Neighborhood::~Neighborhood() {
Expand All @@ -58,10 +61,10 @@ void Neighborhood::init() {
_extraTable.loadFromStream(stream);
delete stream;

stream = _vm->_resFork->getResource(_hotspotTable.getResTag(), _resName);
stream = _vm->_resFork->getResource(_hotspotInfoTable.getResTag(), _resName);
if (!stream)
error("Failed to load hotspots");
_hotspotTable.loadFromStream(stream);
error("Failed to load hotspot info");
_hotspotInfoTable.loadFromStream(stream);
delete stream;

stream = _vm->_resFork->getResource(_spotTable.getResTag(), _resName);
Expand Down Expand Up @@ -91,4 +94,133 @@ void Neighborhood::init() {
// TODO: AI, movies, notifications, buncha other stuff
}

void Neighborhood::start() {
CGameState::SetCurrentRoom(CGameState::GetLastRoom());
CGameState::SetCurrentDirection(CGameState::GetLastDirection());
arriveAt(CGameState::GetNextRoom(), CGameState::GetNextDirection());
}

void Neighborhood::arriveAt(tRoomID room, tDirectionConstant direction) {
// TODO
}

// These functions can be overridden to tweak the exact frames used.

void Neighborhood::getExitEntry(const tRoomID room, const tDirectionConstant direction, ExitTable::Entry &entry) {
entry = _exitTable.findEntry(room, direction, _currentAlternate);

if (entry.isEmpty())
entry = _exitTable.findEntry(room, direction, kNoAlternateID);
}

TimeValue Neighborhood::getViewTime(const tRoomID room, const tDirectionConstant direction) {
if (CGameState::GetOpenDoorRoom() == room && CGameState::GetOpenDoorDirection() == direction) {
// If we get here, the door entry for this location must exist.
DoorTable::Entry doorEntry = _doorTable.findEntry(room, direction, _currentAlternate);

if (doorEntry.isEmpty())
doorEntry = _doorTable.findEntry(room, direction, kNoAlternateID);

return doorEntry.movieEnd - 1;
}

ViewTable::Entry viewEntry = _viewTable.findEntry(room, direction, _currentAlternate);

if (viewEntry.isEmpty())
viewEntry = _viewTable.findEntry(room, direction, kNoAlternateID);

return viewEntry.time;
}

void Neighborhood::getDoorEntry(const tRoomID room, const tDirectionConstant direction, DoorTable::Entry &doorEntry) {
doorEntry = _doorTable.findEntry(room, direction, _currentAlternate);

if (doorEntry.isEmpty())
doorEntry = _doorTable.findEntry(room, direction, kNoAlternateID);
}

tDirectionConstant Neighborhood::getTurnEntry(const tRoomID room, const tDirectionConstant direction, const tTurnDirection turn) {
TurnTable::Entry turnEntry = _turnTable.findEntry(room, direction, turn, _currentAlternate);

if (turnEntry.isEmpty())
turnEntry = _turnTable.findEntry(room, direction, turn, kNoAlternateID);

return turnEntry.turnDirection;
}

void Neighborhood::findSpotEntry(const tRoomID room, const tDirectionConstant direction, tSpotFlags flags, SpotTable::Entry &spotEntry) {
spotEntry = _spotTable.findEntry(room, direction, flags, _currentAlternate);

if (spotEntry.isEmpty())
spotEntry = _spotTable.findEntry(room, direction, flags, kNoAlternateID);
}

void Neighborhood::getZoomEntry(const tHotSpotID id, ZoomTable::Entry &zoomEntry) {
zoomEntry = _zoomTable.findEntry(id);
}

void Neighborhood::getHotspotEntry(const tHotSpotID id, HotspotInfoTable::Entry &hotspotEntry) {
hotspotEntry = _hotspotInfoTable.findEntry(id);
}

void Neighborhood::getExtraEntry(const uint32 id, ExtraTable::Entry &extraEntry) {
extraEntry = _extraTable.findEntry(id);
}

/////////////////////////////////////////////
//
// "Can" functions: Called to see whether or not a user is allowed to do something

tCanMoveForwardReason Neighborhood::canMoveForward(ExitTable::Entry &entry) {
DoorTable::Entry door;

getExitEntry(CGameState::GetCurrentRoom(), CGameState::GetCurrentDirection(), entry);
getDoorEntry(CGameState::GetCurrentRoom(), CGameState::GetCurrentDirection(), door);

// Fixed this so that doors that don't lead anywhere can be opened, but not walked
// through.
if (door.flags & kDoorPresentMask) {
if (CGameState::IsCurrentDoorOpen()) {
if (entry.exitRoom == kNoRoomID)
return kCantMoveBlocked;
else
return kCanMoveForward;
} else if (door.flags & kDoorLockedMask) {
return kCantMoveDoorLocked;
} else {
return kCantMoveDoorClosed;
}
} else if (entry.exitRoom == kNoRoomID) {
return kCantMoveBlocked;
}

return kCanMoveForward;
}

tCanTurnReason Neighborhood::canTurn(tTurnDirection turn, tDirectionConstant &nextDir) {
nextDir = getTurnEntry(CGameState::GetCurrentRoom(), CGameState::GetCurrentDirection(), turn);

if (nextDir == kNoDirection)
return kCantTurnNoTurn;

return kCanTurn;
}

tCanOpenDoorReason Neighborhood::canOpenDoor(DoorTable::Entry &entry) {
getDoorEntry(CGameState::GetCurrentRoom(), CGameState::GetCurrentDirection(), entry);

if (entry.flags & kDoorPresentMask) {
if (CGameState::IsCurrentDoorOpen())
return kCantOpenAlreadyOpen;

if (entry.flags & kDoorLockedMask)
return kCantOpenLocked;

return kCanOpenDoor;
}

return kCantOpenNoDoor;
}


} // End of namespace Pegasus
41 changes: 37 additions & 4 deletions engines/pegasus/neighborhood/neighborhood.h
Expand Up @@ -31,7 +31,7 @@
#include "pegasus/neighborhood/door.h"
#include "pegasus/neighborhood/exit.h"
#include "pegasus/neighborhood/extra.h"
#include "pegasus/neighborhood/hotspot.h"
#include "pegasus/neighborhood/hotspotinfo.h"
#include "pegasus/neighborhood/spot.h"
#include "pegasus/neighborhood/turn.h"
#include "pegasus/neighborhood/view.h"
Expand All @@ -41,25 +41,58 @@ namespace Pegasus {

class PegasusEngine;

// Pegasus Prime neighborhood id's
const tNeighborhoodID kCaldoriaID = 0;
const tNeighborhoodID kFullTSAID = 1;
const tNeighborhoodID kFinalTSAID = 2;
const tNeighborhoodID kTinyTSAID = 3;
const tNeighborhoodID kPrehistoricID = 4;
const tNeighborhoodID kMarsID = 5;
const tNeighborhoodID kWSCID = 6;
const tNeighborhoodID kNoradAlphaID = 7;
const tNeighborhoodID kNoradDeltaID = 8;
// The sub chase is not really a neighborhood, but we define a constant that is used
// to allow an easy transition out of Norad Alpha.
const tNeighborhoodID kNoradSubChaseID = 1000;

class Neighborhood {
public:
Neighborhood(PegasusEngine *vm, const Common::String &resName);
Neighborhood(PegasusEngine *vm, const Common::String &resName, tNeighborhoodID id);
virtual ~Neighborhood();

virtual void init();
void start();

void arriveAt(tRoomID room, tDirectionConstant direction);

virtual void getExitEntry(const tRoomID room, const tDirectionConstant direction, ExitTable::Entry &entry);
virtual TimeValue getViewTime(const tRoomID room, const tDirectionConstant direction);
virtual void getDoorEntry(const tRoomID room, const tDirectionConstant direction, DoorTable::Entry &doorEntry);
virtual tDirectionConstant getTurnEntry(const tRoomID room, const tDirectionConstant direction, const tTurnDirection turn);
virtual void findSpotEntry(const tRoomID room, const tDirectionConstant direction, tSpotFlags flags, SpotTable::Entry &spotEntry);
virtual void getZoomEntry(const tHotSpotID id, ZoomTable::Entry &zoomEntry);
virtual void getHotspotEntry(const tHotSpotID id, HotspotInfoTable::Entry &hotspotEntry);
virtual void getExtraEntry(const uint32 id, ExtraTable::Entry &extraEntry);

private:
tCanMoveForwardReason canMoveForward(ExitTable::Entry &entry);
tCanTurnReason canTurn(tTurnDirection turn, tDirectionConstant &nextDir);
tCanOpenDoorReason canOpenDoor(DoorTable::Entry &entry);

protected:
PegasusEngine *_vm;
Common::String _resName;
tNeighborhoodID _neighborhoodID;

DoorTable _doorTable;
ExitTable _exitTable;
ExtraTable _extraTable;
HotspotTable _hotspotTable;
HotspotInfoTable _hotspotInfoTable;
SpotTable _spotTable;
TurnTable _turnTable;
ViewTable _viewTable;
ZoomTable _zoomTable;

tAlternateID _currentAlternate;
};

} // End of namespace Pegasus
Expand Down
30 changes: 14 additions & 16 deletions engines/pegasus/pegasus.cpp
Expand Up @@ -141,10 +141,8 @@ Common::Error PegasusEngine::run() {
runMainMenu();
break;
case kMainGameMode:
if (isDemo())
changeLocation(kLocPrehistoric);
else
changeLocation(kLocCaldoria);
// NOTE: Prehistoric will be our testing location
changeLocation(kPrehistoricID);
mainGameLoop();
break;
case kQuitMode:
Expand Down Expand Up @@ -233,19 +231,19 @@ void PegasusEngine::mainGameLoop() {
_video->playMovieCentered("Images/Caldoria/Pullback.movie");
drawInterface();

Common::String navMovie = Common::String::format("Images/%s/%s.movie", getTimeZoneFolder(_timeZone).c_str(), getTimeZoneDesc(_timeZone).c_str());
Common::String navMovie = Common::String::format("Images/%s/%s.movie", getTimeZoneFolder(_neighborhood).c_str(), getTimeZoneDesc(_neighborhood).c_str());
_video->playMovie(navMovie, kViewScreenOffset, kViewScreenOffset);

_gameMode = kQuitMode;
}

void PegasusEngine::changeLocation(TimeZone timeZone) {
_timeZone = timeZone;
void PegasusEngine::changeLocation(tNeighborhoodID neighborhood) {
_neighborhood = neighborhood;

// Just a test...
Neighborhood *neighborhood = new Neighborhood(this, getTimeZoneDesc(_timeZone));
neighborhood->init();
delete neighborhood;
Neighborhood *neighborhoodPtr = new Neighborhood(this, getTimeZoneDesc(_neighborhood), _neighborhood);
neighborhoodPtr->init();
delete neighborhoodPtr;
}

void PegasusEngine::showLoadDialog() {
Expand All @@ -267,16 +265,16 @@ void PegasusEngine::showLoadDialog() {
slc.close();
}

Common::String PegasusEngine::getTimeZoneDesc(TimeZone timeZone) {
static const char *names[] = { "Prehistoric", "Mars", "WSC", "Tiny TSA", "Full TSA", "Norad Alpha", "Caldoria", "Norad Delta" };
return names[timeZone];
Common::String PegasusEngine::getTimeZoneDesc(tNeighborhoodID neighborhood) {
static const char *names[] = { "Caldoria", "Full TSA", "Full TSA", "Tiny TSA", "Prehistoric", "Mars", "WSC", "Norad Alpha", "Norad Delta" };
return names[neighborhood];
}

Common::String PegasusEngine::getTimeZoneFolder(TimeZone timeZone) {
if (timeZone == kLocFullTSA || timeZone == kLocTinyTSA)
Common::String PegasusEngine::getTimeZoneFolder(tNeighborhoodID neighborhood) {
if (neighborhood == kFullTSAID || neighborhood == kTinyTSAID || neighborhood == kFinalTSAID)
return "TSA";

return getTimeZoneDesc(timeZone);
return getTimeZoneDesc(neighborhood);
}

GUI::Debugger *PegasusEngine::getDebugger() {
Expand Down

0 comments on commit 3239002

Please sign in to comment.