Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

2
engines/pink/POTFILES Normal file
View File

@@ -0,0 +1,2 @@
engines/pink/gui.cpp
engines/pink/metaengine.cpp

316
engines/pink/archive.cpp Normal file
View File

@@ -0,0 +1,316 @@
/* 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 "common/debug.h"
#include "common/file.h"
#include "pink/objects/condition.h"
#include "pink/objects/module.h"
#include "pink/objects/side_effect.h"
#include "pink/objects/actions/action_hide.h"
#include "pink/objects/actions/action_play_with_sfx.h"
#include "pink/objects/actions/action_sound.h"
#include "pink/objects/actions/action_talk.h"
#include "pink/objects/actions/action_text.h"
#include "pink/objects/actions/walk_action.h"
#include "pink/objects/actors/audio_info_pda_button.h"
#include "pink/objects/actors/cursor_actor.h"
#include "pink/objects/actors/inventory_actor.h"
#include "pink/objects/actors/lead_actor.h"
#include "pink/objects/actors/pda_button_actor.h"
#include "pink/objects/actors/supporting_actor.h"
#include "pink/objects/handlers/handler.h"
#include "pink/objects/pages/game_page.h"
#include "pink/objects/sequences/seq_timer.h"
#include "pink/objects/sequences/sequence.h"
#include "pink/objects/walk/walk_location.h"
namespace Pink {
static const struct RuntimeClass {
const char *name;
int id;
} classMap[] = {
{"ActionHide", kActionHide},
{"ActionLoop", kActionLoop},
{"ActionPlay", kActionPlay},
{"ActionPlayWithSfx", kActionPlayWithSfx},
{"ActionSfx", kActionSfx},
{"ActionSound", kActionSound},
{"ActionStill", kActionStill},
{"ActionTalk", kActionTalk},
{"ActionText", kActionText},
{"Actor", kActor},
{"AudioInfoPDAButton", kAudioInfoPDAButton},
{"ConditionGameVariable", kConditionGameVariable},
{"ConditionInventoryItemOwner", kConditionInventoryItemOwner},
{"ConditionModuleVariable", kConditionModuleVariable},
{"ConditionNotInventoryItemOwner", kConditionNotInventoryItemOwner},
{"ConditionNotModuleVariable", kConditionNotModuleVariable},
{"ConditionNotPageVariable", kConditionNotPageVariable},
{"ConditionPageVariable", kConditionPageVariable},
{"CursorActor", kCursorActor},
{"GamePage", kGamePage},
{"HandlerLeftClick", kHandlerLeftClick},
{"HandlerStartPage", kHandlerStartPage},
{"HandlerTimer", kHandlerTimer},
{"HandlerTimerActions", kHandlerTimerActions},
{"HandlerTimerSequences", kHandlerTimerSequences},
{"HandlerUseClick", kHandlerUseClick},
{"InventoryActor", kInventoryActor},
{"InventoryItem", kInventoryItem},
{"LeadActor", kLeadActor},
{"ModuleProxy", kModuleProxy},
{"PDAButtonActor", kPDAButtonActor},
{"ParlSqPink", kParlSqPink},
{"PubPink", kPubPink},
{"SeqTimer", kSeqTimer},
{"Sequence", kSequence},
{"SequenceAudio", kSequenceAudio},
{"SequenceItem", kSequenceItem},
{"SequenceItemDefaultAction", kSequenceItemDefaultAction},
{"SequenceItemLeader", kSequenceItemLeader},
{"SequenceItemLeaderAudio", kSequenceItemLeaderAudio},
{"SideEffectExit", kSideEffectExit},
{"SideEffectGameVariable", kSideEffectGameVariable},
{"SideEffectInventoryItemOwner", kSideEffectInventoryItemOwner},
{"SideEffectLocation", kSideEffectLocation},
{"SideEffectModuleVariable", kSideEffectModuleVariable},
{"SideEffectPageVariable", kSideEffectPageVariable},
{"SideEffectRandomPageVariable", kSideEffectRandomPageVariable},
{"SupportingActor", kSupportingActor},
{"WalkAction", kWalkAction},
{"WalkLocation", kWalkLocation}
};
static Object *createObject(int objectId) {
switch (objectId) {
case kActionHide:
return new ActionHide;
case kActionLoop:
return new ActionLoop;
case kActionPlay:
return new ActionPlay;
case kActionPlayWithSfx:
return new ActionPlayWithSfx;
case kActionSfx:
return new ActionSfx;
case kActionSound:
return new ActionSound;
case kActionStill:
return new ActionStill;
case kActionTalk:
return new ActionTalk;
case kActionText:
return new ActionText;
case kActor:
return new Actor;
case kAudioInfoPDAButton:
return new AudioInfoPDAButton;
case kConditionGameVariable:
return new ConditionGameVariable;
case kConditionInventoryItemOwner:
return new ConditionInventoryItemOwner;
case kConditionModuleVariable:
return new ConditionModuleVariable;
case kConditionNotInventoryItemOwner:
return new ConditionNotInventoryItemOwner;
case kConditionNotModuleVariable:
return new ConditionNotModuleVariable;
case kConditionNotPageVariable:
return new ConditionNotPageVariable;
case kConditionPageVariable:
return new ConditionPageVariable;
case kCursorActor:
return new CursorActor;
case kGamePage:
return new GamePage;
case kHandlerLeftClick:
return new HandlerLeftClick;
case kHandlerStartPage:
return new HandlerStartPage;
case kHandlerTimer:
case kHandlerTimerActions:
return new HandlerTimerActions; // hack for Peril, but behavior is correct
case kHandlerTimerSequences:
return new HandlerTimerSequences;
case kHandlerUseClick:
return new HandlerUseClick;
case kInventoryActor:
return new InventoryActor;
case kInventoryItem:
return new InventoryItem;
case kLeadActor:
return new LeadActor;
case kModuleProxy:
return new ModuleProxy;
case kPDAButtonActor:
return new PDAButtonActor;
case kParlSqPink:
return new ParlSqPink;
case kPubPink:
return new PubPink;
case kSeqTimer:
return new SeqTimer;
case kSequence:
return new Sequence;
case kSequenceAudio:
return new SequenceAudio;
case kSequenceItem:
return new SequenceItem;
case kSequenceItemDefaultAction:
return new SequenceItemDefaultAction;
case kSequenceItemLeader:
return new SequenceItemLeader;
case kSequenceItemLeaderAudio:
return new SequenceItemLeaderAudio;
case kSideEffectExit:
return new SideEffectExit;
case kSideEffectGameVariable:
return new SideEffectGameVariable;
case kSideEffectInventoryItemOwner:
return new SideEffectInventoryItemOwner;
case kSideEffectLocation:
return new SideEffectLocation;
case kSideEffectModuleVariable:
return new SideEffectModuleVariable;
case kSideEffectPageVariable:
return new SideEffectPageVariable;
case kSideEffectRandomPageVariable:
return new SideEffectRandomPageVariable;
case kSupportingActor:
return new SupportingActor;
case kWalkAction:
return new WalkAction;
case kWalkLocation:
return new WalkLocation;
default:
error("Unknown object id");
return nullptr;
}
}
Archive::Archive(Common::SeekableReadStream *stream)
: _readStream(stream), _writeStream(nullptr) {
_objectMap.push_back(0);
_objectIdMap.push_back(kNullObject);
}
Archive::Archive(Common::WriteStream *stream)
: _writeStream(stream), _readStream(nullptr) {
_objectMap.push_back(0);
_objectIdMap.push_back(kNullObject);
}
void Archive::mapObject(Object *obj) {
_objectMap.push_back(obj);
_objectIdMap.push_back(0);
}
Object *Archive::readObject() {
bool isCopyReturned;
Object *res = parseObject(isCopyReturned);
if (res && !isCopyReturned)
res->deserialize(*this);
return res;
}
Object *Archive::parseObject(bool &isCopyReturned) {
char className[kMaxClassLength];
int objectId = 0;
Object *res = nullptr;
uint obTag = _readStream->readUint16LE();
if (obTag == 0x0000) {
return nullptr;
} else if (obTag == 0xffff) {
/* int schema = */_readStream->readUint16LE();
int size = _readStream->readUint16LE();
_readStream->read(className, size);
className[size] = '\0';
objectId = findObjectId(className + 1);
res = createObject(objectId);
if (!res) error("Class %s is not implemented", className);
_objectMap.push_back(res);
_objectIdMap.push_back(objectId);
_objectMap.push_back(res); // Basically a hack, but behavior is all correct. MFC uses one array for pointers and ids
_objectIdMap.push_back(objectId);
isCopyReturned = false;
} else if ((obTag & 0x8000) == 0) {
res = _objectMap[obTag];
isCopyReturned = true;
} else {
obTag &= ~0x8000;
objectId = _objectIdMap[obTag];
res = createObject(objectId);
_objectMap.push_back(res);
_objectIdMap.push_back(objectId);
isCopyReturned = false;
}
return res;
}
static int runtimeClassCmp(const void *key, const void *elem) {
return strcmp((const char *)key, *(const char * const *)elem);
}
uint Archive::findObjectId(const char *name) {
RuntimeClass *found = (RuntimeClass *)bsearch(name, classMap, sizeof(classMap) / sizeof(RuntimeClass), sizeof(RuntimeClass), runtimeClassCmp);
if (!found)
error("Class %s is not in class Map", name);
return found->id;
}
Common::String Archive::readString() {
char buffer[kMaxStringLength];
byte len = _readStream->readByte();
assert(len <= kMaxStringLength);
_readStream->read(buffer, len);
return Common::String(buffer, len);
}
void Archive::skipString() {
byte len = _readStream->readByte();
_readStream->skip(len);
}
void Archive::writeString(const Common::String &string) {
_writeStream->writeByte(string.size());
_writeStream->write(string.c_str(), string.size());
}
} // End of namespace Pink

75
engines/pink/archive.h Normal file
View 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.
*
* 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 PINK_ARCHIVE_H
#define PINK_ARCHIVE_H
#include "common/hash-str.h"
#include "common/str-array.h"
#include "common/stream.h"
namespace Common {
class File;
}
namespace Pink {
class Object;
class Archive {
public:
Archive(Common::SeekableReadStream *stream);
Archive(Common::WriteStream *stream);
void mapObject(Object *obj);
byte readByte() { return _readStream->readByte(); }
uint32 readDWORD() { return _readStream->readUint32LE(); }
uint16 readWORD() { return _readStream->readUint16LE(); }
Common::String readString();
void skipString();
Object *readObject();
void write(const void *dataPtr, uint32 dataSize) { _writeStream->write(dataPtr, dataSize); }
void writeByte(byte val) { _writeStream->writeByte(val); }
void writeDWORD(uint32 val) { _writeStream->writeUint32LE(val); }
void writeWORD(uint16 val) { _writeStream->writeUint16LE(val); }
void writeString(const Common::String &string);
private:
uint findObjectId(const char *name);
Object *parseObject(bool &isCopyReturned);
Common::Array<Object *> _objectMap;
Common::Array<uint> _objectIdMap;
Common::SeekableReadStream *_readStream;
Common::WriteStream *_writeStream;
};
} // End of namespace Pink
#endif

View 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.
*
* 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 "pink/audio_info_mgr.h"
#include "pink/archive.h"
#include "pink/constants.h"
#include "pink/objects/actors/lead_actor.h"
namespace Pink {
AudioInfoMgr::AudioInfoMgr(LeadActor *lead)
: _lead(lead) {}
void AudioInfoMgr::loadState(Archive &archive) {
_aboutWhom = archive.readString();
}
void AudioInfoMgr::saveState(Archive &archive) {
archive.writeString(_aboutWhom);
}
void AudioInfoMgr::start(Actor *actor) {
if (!actor->getPDALink().empty()) {
_aboutWhom = actor->getName();
playAudio();
showPDAButton();
} else
stop();
}
void AudioInfoMgr::stop() {
if (!_aboutWhom.empty()) {
stopAudio();
hidePDAButton();
_aboutWhom.clear();
}
}
void AudioInfoMgr::onLeftClick() {
Actor *actor = _lead->findActor(_aboutWhom);
assert(actor);
_lead->loadPDA(actor->getPDALink());
stopAudio();
}
void AudioInfoMgr::playAudio() {
Actor *audioInfo = _lead->findActor(kAudioInfoActor);
assert(audioInfo);
audioInfo->setAction(_aboutWhom);
}
void AudioInfoMgr::stopAudio() {
Actor *audioInfo = _lead->findActor(kAudioInfoActor);
assert(audioInfo);
audioInfo->setAction(kIdleAction);
}
void AudioInfoMgr::showPDAButton() {
Actor *pdaButton = _lead->findActor(kPdaButtonActor);
assert(pdaButton);
pdaButton->setAction(kShowAction);
}
void AudioInfoMgr::hidePDAButton() {
Actor *pdaButton = _lead->findActor(kPdaButtonActor);
assert(pdaButton);
pdaButton->setAction(kHideAction);
}
} // End of namespace Pink

View File

@@ -0,0 +1,60 @@
/* 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 PINK_AUDIO_INFO_MGR_H
#define PINK_AUDIO_INFO_MGR_H
#include "common/str.h"
namespace Pink {
class Actor;
class LeadActor;
class Archive;
class AudioInfoMgr {
public:
AudioInfoMgr(LeadActor *lead);
void loadState(Archive &archive);
void saveState(Archive &archive);
void start(Actor *actor);
void stop();
void onLeftClick();
private:
void playAudio();
void stopAudio();
void showPDAButton();
void hidePDAButton();
private:
Common::String _aboutWhom;
LeadActor *_lead;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,229 @@
/* 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 "common/stream.h"
#include "graphics/surface.h"
#include "pink/cel_decoder.h"
namespace Pink {
bool CelDecoder::loadStream(Common::SeekableReadStream *stream) {
close();
/* uint32 frameSize = */ stream->readUint32LE();
uint16 frameType = stream->readUint16LE();
// Check FLC magic number
if (frameType != 0xAF12) {
warning("FlicDecoder::loadStream(): attempted to load non-FLC data (type = 0x%04X)", frameType);
return false;
}
uint16 frameCount = stream->readUint16LE();
uint16 width = stream->readUint16LE();
uint16 height = stream->readUint16LE();
uint16 colorDepth = stream->readUint16LE();
if (colorDepth != 8) {
warning("FlicDecoder::loadStream(): attempted to load an FLC with a palette of color depth %d. Only 8-bit color palettes are supported", colorDepth);
return false;
}
addTrack(new CelVideoTrack(stream, frameCount, width, height));
return true;
}
uint16 CelDecoder::getTransparentColourIndex() const {
const CelVideoTrack *track = (const CelVideoTrack *)getTrack(0);
if (!track)
return 0;
return track->getTransparentColourIndex();
}
const Graphics::Surface *CelDecoder::getCurrentFrame() const {
const CelVideoTrack *track = (const CelVideoTrack *)getTrack(0);
if (!track)
return nullptr;
return track->getCurrentFrame();
}
Common::Point CelDecoder::getCenter() const {
const CelVideoTrack *track = (const CelVideoTrack *)getTrack(0);
if (!track)
return Common::Point(0, 0);
return track->getCenter();
}
void CelDecoder::skipFrame() {
CelVideoTrack *track = (CelVideoTrack *)getTrack(0);
track->skipFrame();
}
void CelDecoder::setEndOfTrack() {
CelVideoTrack *track = (CelVideoTrack *)getTrack(0);
track->setEndOfTrack();
}
CelDecoder::CelVideoTrack::CelVideoTrack(Common::SeekableReadStream *stream, uint16 frameCount, uint16 width, uint16 height, bool skipHeader)
: FlicVideoTrack(stream, frameCount, width, height, 1), _center(0, 0), _transparentColourIndex(0) {
readHeader();
}
#define PREFIX_TYPE 0xF100
#define CEL_DATA 3
void CelDecoder::CelVideoTrack::readPrefixChunk() {
_fileStream->seek(0x80);
/* uint32 chunkSize = */_fileStream->readUint32LE();
uint16 chunkType = _fileStream->readUint16LE();
if (chunkType != PREFIX_TYPE)
return;
//uint32 offset = 6;
uint32 subchunkSize = _fileStream->readUint32LE();
uint16 subchunkType = _fileStream->readUint16LE();
switch (subchunkType) {
case CEL_DATA:
_fileStream->readUint16LE();
_center.x = _fileStream->readUint16LE();
_center.y = _fileStream->readUint16LE();
break;
default:
error("Unknown subchunk type");
_fileStream->skip(subchunkSize - 6);
break;
}
}
#undef PREFIX_TYPE
#undef CEL_DATA
void CelDecoder::CelVideoTrack::readHeader() {
_fileStream->readUint16LE();
_frameDelay = _startFrameDelay = _fileStream->readUint32LE();
_fileStream->seek(80);
_offsetFrame1 = _fileStream->readUint32LE();
_offsetFrame2 = _fileStream->readUint32LE();
if (_offsetFrame1 > 0x80)
readPrefixChunk();
_fileStream->seek(_offsetFrame1);
}
uint16 CelDecoder::CelVideoTrack::getTransparentColourIndex() const {
return _transparentColourIndex;
}
const Graphics::Surface *CelDecoder::CelVideoTrack::getCurrentFrame() const {
return _surface;
}
Common::Point CelDecoder::CelVideoTrack::getCenter() const {
return _center;
}
#define FRAME_TYPE 0xF1FA
void CelDecoder::CelVideoTrack::skipFrame() {
// Read chunk
/*uint32 frameSize = */ _fileStream->readUint32LE();
uint16 frameType = _fileStream->readUint16LE();
switch (frameType) {
case FRAME_TYPE:
handleFrame();
break;
default:
error("FlicDecoder::decodeFrame(): unknown main chunk type (type = 0x%02X)", frameType);
break;
}
_curFrame++;
//_nextFrameStartTime += _frameDelay;
if (_atRingFrame) {
// If we decoded the ring frame, seek to the second frame
_atRingFrame = false;
_fileStream->seek(_offsetFrame2);
}
if (_curFrame == 0)
_transparentColourIndex = *(byte *)_surface->getBasePtr(0, 0);
}
const Graphics::Surface *CelDecoder::CelVideoTrack::decodeNextFrame() {
// Read chunk
/*uint32 frameSize = */ _fileStream->readUint32LE();
uint16 frameType = _fileStream->readUint16LE();
switch (frameType) {
case FRAME_TYPE:
handleFrame();
break;
default:
error("FlicDecoder::decodeFrame(): unknown main chunk type (type = 0x%02X)", frameType);
break;
}
_curFrame++;
_nextFrameStartTime += _frameDelay;
if (_atRingFrame) {
// If we decoded the ring frame, seek to the second frame
_atRingFrame = false;
if (_frameCount == 1) {
_fileStream->seek(_offsetFrame1);
} else
_fileStream->seek(_offsetFrame2);
}
if (_curFrame == 0)
_transparentColourIndex = *(byte *)_surface->getBasePtr(0, 0);
return _surface;
}
#undef FRAME_TYPE
bool CelDecoder::CelVideoTrack::rewind() {
// this method is overriden for 2 reasons:
// 1) bug in Flic rewind(curFrame)
// 2) I changed behaviour of endOfTrack
_nextFrameStartTime = 0;
if (_curFrame >= (int)_frameCount - 1 && _fileStream->pos() < _fileStream->size())
_atRingFrame = true;
else
_fileStream->seek(_offsetFrame1);
_curFrame = -1;
_frameDelay = _startFrameDelay;
return true;
}
} // End of namepsace Pink

View 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.
*
* 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 PINK_CEL_DECODER_H
#define PINK_CEL_DECODER_H
#include "video/flic_decoder.h"
namespace Pink {
class CelDecoder : public Video::FlicDecoder {
public:
bool loadStream(Common::SeekableReadStream *stream) override;
uint16 getTransparentColourIndex() const;
Common::Point getCenter() const;
const Graphics::Surface *getCurrentFrame() const;
void skipFrame();
void setEndOfTrack();
protected:
class CelVideoTrack : public FlicVideoTrack {
public:
CelVideoTrack(Common::SeekableReadStream *stream, uint16 frameCount, uint16 width, uint16 height, bool skipHeader = false);
void readHeader() override;
uint16 getTransparentColourIndex() const;
// Hack. Pink needs so that Track needed an update after lastFrame delay ends
void setEndOfTrack() { _curFrame = _frameCount; }
bool endOfTrack() const override { return getCurFrame() >= getFrameCount(); }
Common::Point getCenter() const;
const Graphics::Surface *getCurrentFrame() const;
void skipFrame();
bool rewind() override;
private:
const Graphics::Surface *decodeNextFrame() override;
void readPrefixChunk();
Common::Point _center;
byte _transparentColourIndex;
};
};
}
#endif

View 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 pink "Pink Panther" yes "" "" "highres"

173
engines/pink/console.cpp Normal file
View File

@@ -0,0 +1,173 @@
/* 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 "pink/console.h"
#include "pink/pink.h"
#include "pink/objects/module.h"
#include "pink/objects/pages/game_page.h"
#include "pink/objects/actors/lead_actor.h"
namespace Pink {
Console::Console(PinkEngine *vm)
: _vm(vm) {
registerCmd("listModules", WRAP_METHOD(Console, Cmd_ListModules));
registerCmd("goToModule", WRAP_METHOD(Console, Cmd_GoToModule));
registerCmd("listPages", WRAP_METHOD(Console, Cmd_ListPages));
registerCmd("goToPage", WRAP_METHOD(Console, Cmd_GoToPage));
registerCmd("listGameVars", WRAP_METHOD(Console, Cmd_ListGameVars));
registerCmd("setGameVar", WRAP_METHOD(Console, Cmd_SetGameVar));
registerCmd("listModuleVars", WRAP_METHOD(Console, Cmd_ListModuleVars));
registerCmd("setModuleVar", WRAP_METHOD(Console, Cmd_SetModuleVar));
registerCmd("listPageVars", WRAP_METHOD(Console, Cmd_ListPageVars));
registerCmd("setPageVar", WRAP_METHOD(Console, Cmd_SetPageVar));
registerCmd("listItems", WRAP_METHOD(Console, Cmd_ListItems));
registerCmd("addItem", WRAP_METHOD(Console, Cmd_addItem));
}
bool Console::Cmd_ListModules(int argc, const char **argv) {
const Array<NamedObject *> modules = _vm->_modules;
for (uint i = 0; i < modules.size(); ++i) {
debugPrintf("%d.%s\n", i, modules[i]->getName().c_str());
}
return true;
}
bool Console::Cmd_GoToModule(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Usage: %s moduleName\n", argv[0]);
debugPrintf("Module may not work properly because of Game vars\n");
return true;
}
const Array<NamedObject *> modules = _vm->_modules;
for (uint i = 0; i < modules.size(); ++i) {
if (modules[i]->getName() == argv[1]) {
_vm->initModule(argv[1], "", nullptr);
return true;
}
}
debugPrintf("Module %s doesn't exist\n", argv[1]);
return true;
}
bool Console::Cmd_ListPages(int argc, const char **argv) {
const Array<GamePage*> pages = _vm->_module->_pages;
for (uint i = 0; i < pages.size(); ++i) {
debugPrintf("%d.%s\n", i, pages[i]->getName().c_str());
}
return true;
}
bool Console::Cmd_GoToPage(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Usage: %s pageName\n", argv[0]);
debugPrintf("Page may not work properly because of vars\n");
return true;
}
const Array<GamePage*> pages = _vm->_module->_pages;
for (uint i = 0; i < pages.size(); ++i) {
if (pages[i]->getName() == argv[1]) {
_vm->setNextExecutors("", pages[i]->getName());
_vm->changeScene();
return true;
}
}
debugPrintf("Page %s doesn't exist\n", argv[1]);
return true;
}
bool Console::Cmd_ListGameVars(int argc, const char **argv) {
const StringMap &vars = _vm->_variables;
for (StringMap::const_iterator it = vars.begin(); it != vars.end() ; ++it) {
debugPrintf("%s %s \n", it->_key.c_str(), it->_value.c_str());
}
return true;
}
bool Console::Cmd_SetGameVar(int argc, const char **argv) {
if (argc != 3) {
debugPrintf("Usage: %s varName value\n", argv[0]);
return true;
}
_vm->_variables[argv[1]] = argv[2];
return true;
}
bool Console::Cmd_ListModuleVars(int argc, const char **argv) {
const StringMap &vars = _vm->_module->_variables;
for (StringMap::const_iterator it = vars.begin(); it != vars.end() ; ++it) {
debugPrintf("%s %s \n", it->_key.c_str(), it->_value.c_str());
}
return true;
}
bool Console::Cmd_SetModuleVar(int argc, const char **argv) {
if (argc != 3) {
debugPrintf("Usage: %s varName value\n", argv[0]);
return true;
}
_vm->_module->_variables[argv[1]] = argv[2];
return true;
}
bool Console::Cmd_ListPageVars(int argc, const char **argv) {
const StringMap &vars = _vm->_module->_page->_variables;
for (StringMap::const_iterator it = vars.begin(); it != vars.end() ; ++it) {
debugPrintf("%s %s \n", it->_key.c_str(), it->_value.c_str());
}
return true;
}
bool Console::Cmd_SetPageVar(int argc, const char **argv) {
if (argc != 3) {
debugPrintf("Usage: %s varName value\n", argv[0]);
return true;
}
_vm->_module->_page->_variables[argv[1]] = argv[2];
return true;
}
bool Console::Cmd_ListItems(int argc, const char **argv) {
const Common::Array<InventoryItem *> &items = _vm->_module->_invMgr._items;
for (uint i = 0; i < items.size(); ++i) {
debugPrintf("%s\n", items[i]->getName().c_str());
}
return true;
}
bool Console::Cmd_addItem(int argc, const char **argv) {
if (argc != 2) {
debugPrintf("Usage: %s item\n", argv[0]);
return true;
}
InventoryMgr *inv = &_vm->_module->_invMgr;
LeadActor *actor = _vm->_actor;
inv->setItemOwner(actor->getName(), inv->findInventoryItem(argv[1]));
return true;
}
} // End of namespace Pink

62
engines/pink/console.h Normal file
View File

@@ -0,0 +1,62 @@
/* 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 PINK_CONSOLE_H
#define PINK_CONSOLE_H
#include "gui/debugger.h"
namespace Pink {
class PinkEngine;
class Console : public GUI::Debugger {
public:
Console(PinkEngine *vm);
~Console(void) override {}
private:
bool Cmd_ListModules(int argc, const char **argv);
bool Cmd_GoToModule(int argc, const char **argv);
bool Cmd_ListPages(int argc, const char **argv);
bool Cmd_GoToPage(int argc, const char **argv);
bool Cmd_ListGameVars(int argc, const char **argv);
bool Cmd_SetGameVar(int argc, const char **argv);
bool Cmd_ListModuleVars(int argc, const char **argv);
bool Cmd_SetModuleVar(int argc, const char **argv);
bool Cmd_ListPageVars(int argc, const char **argv);
bool Cmd_SetPageVar(int argc, const char **argv);
bool Cmd_ListItems(int argc, const char **argv);
bool Cmd_addItem(int argc, const char **argv);
private:
PinkEngine *_vm;
};
} // End of namespace Pink
#endif

215
engines/pink/constants.h Normal file
View File

@@ -0,0 +1,215 @@
/* 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 PINK_CONSTANTS_H
#define PINK_CONSTANTS_H
namespace Pink {
enum {
kMaxClassLength = 32,
kMaxStringLength = 128,
kNullObject = 0
};
enum {
kActionHide,
kActionLoop,
kActionPlay,
kActionPlayWithSfx,
kActionSfx,
kActionSound,
kActionStill,
kActionTalk,
kActionText,
kActor,
kAudioInfoPDAButton,
kConditionGameVariable,
kConditionInventoryItemOwner,
kConditionModuleVariable,
kConditionNotInventoryItemOwner,
kConditionNotModuleVariable,
kConditionNotPageVariable,
kConditionPageVariable,
kCursorActor,
kGamePage,
kHandlerLeftClick,
kHandlerStartPage,
kHandlerTimer,
kHandlerTimerActions,
kHandlerTimerSequences,
kHandlerUseClick,
kInventoryActor,
kInventoryItem,
kLeadActor,
kModuleProxy,
kPDAButtonActor,
kParlSqPink,
kPubPink,
kSeqTimer,
kSequence,
kSequenceAudio,
kSequenceItem,
kSequenceItemDefaultAction,
kSequenceItemLeader,
kSequenceItemLeaderAudio,
kSideEffectExit,
kSideEffectGameVariable,
kSideEffectInventoryItemOwner,
kSideEffectLocation,
kSideEffectModuleVariable,
kSideEffectPageVariable,
kSideEffectRandomPageVariable,
kSupportingActor,
kWalkAction,
kWalkLocation
};
enum {
kCursorsCount = 13
};
enum {
kLoadingCursor = 0,
kDefaultCursor = 1,
kClickableFirstFrameCursor = 2,
kClickableSecondFrameCursor = 3,
kNotClickableCursor = 4,
kHoldingItemCursor = 5,
kPDADefaultCursor = 6,
kPDAClickableFirstFrameCursor = 7,
kPDAClickableSecondFrameCursor = 8,
kExitLeftCursor = 9,
kExitRightCursor = 10,
kExitForwardCursor = 11,
kExitDownCursor = 12 // only in Hokus Pokus
};
// values are from Hokus Pokus
enum {
kPokusLoadingCursorID = 135,
kPokusExitForwardCursorID = 138,
kPokusExitDownCursorID = 139,
kPokusExitLeftCursorID = 133,
kPokusExitRightCursorID = 134,
kPokusClickableFirstCursorID = 137,
kPokusClickableSecondCursorID = 136,
kPokusClickableThirdCursorID = 145,
kPokusNotClickableCursorID = 140,
kPokusHoldingItemCursorID = 147,
kPokusPDADefaultCursorID = 141,
kPokusPDAClickableFirstFrameCursorID = 144,
kPokusPDAClickableSecondFrameCursorID = 146
};
// from Peril
// it contains cursors whose ids differ
enum {
kPerilClickableThirdCursorID = 140,
kPerilNotClickableCursorID = 139,
kPerilHoldingItemCursorID = 101,
kPerilPDAClickableFirstFrameCursorID = 142,
kPerilPDAClickableSecondFrameCursorID = 143
};
enum {
kOrbMajorVersion = 2,
kOrbMinorVersion = 0,
kBroMajorVersion = 1,
kBroMinorVersion = 0
};
enum {
kTimersUpdateTime = 100,
kCursorsUpdateTime = 200
};
enum {
kSampleRate = 22050
};
static const char * const kPinkGame = "PinkGame";
static const char * const kPeril = "peril";
static const char * const kCloseAction = "Close";
static const char * const kIdleAction = "Idle";
static const char * const kOpenAction = "Open";
static const char * const kShowAction = "Show";
static const char * const kHideAction = "Hide";
static const char * const kInactiveAction = "Inactive";
static const char * const kInventoryWindowActor = "InventoryWindow";
static const char * const kInventoryItemActor = "InventoryItem";
static const char * const kInventoryRightArrowActor = "InventoryRightArrow";
static const char * const kInventoryLeftArrowActor = "InventoryLeftArrow";
static const char * const kAudioInfoActor = "AudioInfo";
static const char * const kPdaButtonActor = "PDAButton";
static const char * const kCursorNameExit = "Exit";
static const char * const kCursorNameExitUp = "ExitUp";
static const char * const kCursorNameExitLeft = "ExitLeft";
static const char * const kCursorNameExitRight = "ExitRight";
static const char * const kCursorNameExitForward = "ExitForward";
static const char * const kCursorNameExitBackWards = "ExitBackwards";
static const char * const kClickable = "Clickable";
static const char * const kCursor = "Cursor";
static const char * const kFoodPuzzle = "FoodPuzzle";
static const char * const kJackson = "Jackson";
static const char * const kBolted = "Bolted";
static const char * const kDrunkLocation = "DrunkLocation";
static const char * const kDrunk = "Drunk";
static const char * const kBoy = "Boy";
static const char * const kSirBaldley = "SirBaldley";
static const char * const kBoyBlocked = "BoyBlocked";
static const char * const kUndefinedValue = "UNDEFINED";
static const char * const kTrueValue = "TRUE";
static const char * const kCountryWheel = "CountryWheel";
static const char * const kDomainWheel = "DomainWheel";
static const char * const kLocator = "Locator";
static const char * const kPreviousPageButton = "PreviousPageButton";
static const char * const kDomainButton = "DomainButton";
static const char * const kNavigatorButton = "NavigatorButton";
static const char * const kNavigatePage = "NAVIGATE";
static const char * const kSfx = "SFX";
static const char * const kRightHand = "RightHand";
static const char * const kLeftHand = "LeftHand";
static const char * const kLeft1Name = "Left1";
static const char * const kLeft2Name = "Left2";
static const char * const kLeft3Name = "Left3";
static const char * const kLeft4Name = "Left4";
} // End of namespace Pink
#endif

4
engines/pink/credits.pl Normal file
View File

@@ -0,0 +1,4 @@
begin_section("Pink");
add_person("Andrei Prykhodko", "Voltya", "");
add_person("Eugene Sandulenko", "sev", "");
end_section();

107
engines/pink/cursor_mgr.cpp Normal file
View 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.
*
* 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 "pink/cursor_mgr.h"
#include "pink/pink.h"
#include "pink/objects/pages/page.h"
#include "pink/objects/actors/cursor_actor.h"
namespace Pink {
CursorMgr::CursorMgr(PinkEngine *game, Page *page)
: _actor(nullptr), _page(page), _game(game),
_time(0), _isPlayingAnimation(false),
_isSecondFrame(false), _firstFrameIndex(0) {}
void CursorMgr::setCursor(byte index, Common::Point point, const Common::String &itemName) {
switch (index) {
case kClickableFirstFrameCursor:
// fall through
case kPDAClickableFirstFrameCursor:
startAnimation(index);
hideItem();
break;
case kHoldingItemCursor:
_game->setCursor(index);
_isPlayingAnimation = false;
showItem(itemName, point);
break;
default:
_game->setCursor(index);
_isPlayingAnimation = false;
hideItem();
break;
}
}
void CursorMgr::update() {
if (!_isPlayingAnimation)
return;
uint newTime = _game->getTotalPlayTime();
if (newTime - _time > kCursorsUpdateTime) {
_time = newTime;
_isSecondFrame = !_isSecondFrame;
_game->setCursor(_firstFrameIndex + _isSecondFrame);
}
}
void CursorMgr::setCursor(const Common::String &cursorName, Common::Point point) {
byte index;
if (cursorName == kCursorNameExitLeft)
index = kExitLeftCursor;
else if (cursorName == kCursorNameExitRight)
index = kExitRightCursor;
else if (cursorName == kCursorNameExitForward || cursorName == kCursorNameExitUp || cursorName == kCursorNameExit)
index = kExitForwardCursor;
else if (cursorName == kCursorNameExitBackWards)
index = kExitDownCursor;
else {
warning("%s UNKNOWN CURSOR", cursorName.c_str());
index = kExitForwardCursor;
}
setCursor(index, point, "");
}
void CursorMgr::hideItem() {
if (_actor)
_actor->setAction(kHideAction);
}
void CursorMgr::startAnimation(byte index) {
if (_isPlayingAnimation)
return;
_game->setCursor(index);
_time = _game->getTotalPlayTime();
_firstFrameIndex = index;
_isPlayingAnimation = true;
_isSecondFrame = false;
}
void CursorMgr::showItem(const Common::String &itemName, Common::Point point) {
if (!_actor)
_actor = static_cast<CursorActor *>(_page->findActor(kCursor));
_actor->setCursorItem(itemName, point);
}
} // End of namespace Pink

63
engines/pink/cursor_mgr.h Normal file
View 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.
*
* 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 PINK_CURSOR_MGR_H
#define PINK_CURSOR_MGR_H
#include "common/rect.h"
#include "pink/objects/object.h"
namespace Pink {
class CursorActor;
class Page;
class PinkEngine;
class CursorMgr : public Object {
public:
CursorMgr(PinkEngine *game, Page *page);
void update();
void setCursor(byte index, Common::Point point, const Common::String &itemName);
void setCursor(const Common::String &cursorName, Common::Point point);
void setPage(Page *page) { _page = page; }
private:
void startAnimation(byte index);
void showItem(const Common::String &itemName, Common::Point point);
void hideItem();
private:
Page *_page;
PinkEngine *_game;
CursorActor *_actor;
uint _time;
byte _firstFrameIndex;
bool _isPlayingAnimation;
bool _isSecondFrame;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,76 @@
/* 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 "common/system.h"
#include "engines/advancedDetector.h"
#include "pink/pink.h"
static const PlainGameDescriptor pinkGames[] = {
{"peril", "The Pink Panther: Passport to Peril"},
{"pokus", "The Pink Panther: Hokus Pokus Pink"},
{nullptr, nullptr}
};
#include "pink/detection_tables.h"
static const char *const directoryGlobs[] = {
"install",
nullptr
};
static const DebugChannelDef debugFlagList[] = {
{Pink::kPinkDebugGeneral, "general", "General issues"},
{Pink::kPinkDebugLoadingResources, "loading_resources", "Loading resources data"},
{Pink::kPinkDebugLoadingObjects, "loading_objects", "Serializing objects from Orb"},
{Pink::kPinkDebugScripts, "scripts", "Sequences"},
{Pink::kPinkDebugActions, "actions", "Actions"},
DEBUG_CHANNEL_END
};
class PinkMetaEngineDetection : public AdvancedMetaEngineDetection<ADGameDescription> {
public:
PinkMetaEngineDetection() : AdvancedMetaEngineDetection(Pink::gameDescriptions, pinkGames) {
_gameIds = pinkGames;
_maxScanDepth = 2;
_directoryGlobs = directoryGlobs;
}
const char *getName() const override {
return "pink";
}
const char *getEngineName() const override {
return "Pink Panther";
}
const char *getOriginalCopyright() const override {
return "Pink Panther (C) Wanderlust Interactive";
}
const DebugChannelDef *getDebugChannels() const override {
return debugFlagList;
}
};
REGISTER_PLUGIN_STATIC(PINK_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, PinkMetaEngineDetection);

View File

@@ -0,0 +1,379 @@
/* 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 PINK_DETECTION_TABLES_H
#define PINK_DETECTION_TABLES_H
namespace Pink {
static const ADGameDescription gameDescriptions[] = {
// Danish, Version 1.0
{
"peril",
0,
AD_ENTRY1s("PPTP.ORB", "eae050c09d7f6bfbb3166d2c39957e31", 608976918),
Common::DA_DNK,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Dutch
{
"peril",
0,
AD_ENTRY1s("PPTP.ORB", "4ae829fb3988ad783409ce8311f95ddc", 613211963),
Common::NL_NLD,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// English
{
"peril",
0,
AD_ENTRY1s("PPTP.ORB", "223d0114d443904d8949263d512859da", 618203600),
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// English Great Britain
// Supplied by jp438-2 Bugreport #10956
{
"peril",
0,
AD_ENTRY1s("PPTP.ORB", "1ee65e570adb37d446a3be657e4b2e9a", 619145676),
Common::EN_GRB,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Finnish
{
"peril",
0,
AD_ENTRY1s("PPTP.ORB", "32c31829bf7e74a64968dd05f3224ce9", 612549215),
Common::FI_FIN,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// French
{
"peril",
0,
AD_ENTRY1s("PPTP.ORB", "fd641b5735fbe41d14db698ece29d2b1", 607185037),
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// German
{
"peril",
0,
AD_ENTRY1s("PPTP.ORB", "4ee8514f7303dea1949d7fc72ff65d8c", 609695309),
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Hebrew
{
"peril",
0,
AD_ENTRY1s("PPTP.ORB", "52e2aba46d6cc47225bd5345775eeb59", 616292424),
Common::HE_ISR,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Italian
{
"peril",
0,
AD_ENTRY1s("PPTP.ORB", "d03e38348aa33d8d25315b1acb687f66", 622766069),
Common::IT_ITA,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Norwegian
{
"peril",
0,
AD_ENTRY1s("PPTP.ORB", "5f4db7a9c8dab9c871f571c75120de72", 612644330),
Common::NB_NOR,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Polish
{
"peril",
0,
AD_ENTRY1s("PPTP.ORB", "3b987bb529e131b92c3eb912871dedbd", 644839372),
Common::PL_POL,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Polish Original CD layout
{
"peril",
"Compressed",
AD_ENTRY2s("PPTP.ORB", "3b987bb529e131b92c3eb912871dedbd", 644839372,
"Data1.cab", "a2d2dd8f68f6e3cc335b566fbfcea0b2", 3699395),
Common::PL_POL,
Common::kPlatformWindows,
ADGF_DROPPLATFORM | GF_COMPRESSED,
GUIO1(GUIO_NOMIDI)
},
// Portuguese
{
"peril",
0,
AD_ENTRY1s("PPTP.ORB", "88a498256c4609550cf59497a372b7a3", 642216577),
Common::PT_BRA,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Russian
{
"peril",
0,
AD_ENTRY1s("PPTP.ORB", "4802bace9cd89a73eb915a075b230646", 635322616),
Common::RU_RUS,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Spanish (older) - reported in TRAC #14490
{
"peril",
0,
AD_ENTRY1s("PPTP.ORB", "e9bc2eca6526c1b2f0047dc3f1c815d2", 634841166),
Common::ES_ESP,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Spanish
{
"peril",
0,
AD_ENTRY1s("PPTP.ORB", "1225f76fe3a60d2ed2321ac92e2c1e79", 633626567),
Common::ES_ESP,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Swedish
{
"peril",
0,
AD_ENTRY1s("PPTP.ORB", "eadbc52f4c43b85edb7cc493b4149ba0", 633843917),
Common::SV_SWE,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// German demo
{
"peril",
"Demo",
AD_ENTRY1s("PPTP.ORB", "6ab19c3fba0fd3894758236831001456", 89851874),
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_DROPPLATFORM | ADGF_DEMO,
GUIO1(GUIO_NOMIDI)
},
// Dutch, Version 1.0
{
"pokus",
"v1.0",
AD_ENTRY1s("HPP.orb", "b769855e2fc94b9180763211c349a9ed", 509498007),
Common::NL_NLD,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Dutch, Version 2.0
{
"pokus",
"v2.0",
AD_ENTRY1s("HPP.orb", "993b0491d507efee0010e4f1c000ab8b", 509498617),
Common::NL_NLD,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// English
{
"pokus",
0,
AD_ENTRY1s("HPP.orb", "f480597a78ab70c2021b4141fe44a512", 503443586),
Common::EN_ANY,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// French
{
"pokus",
0,
AD_ENTRY1s("HPP.orb", "d5af74262276f0ffef6605ea0db861d2", 492220293),
Common::FR_FRA,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// German
{
"pokus",
0,
AD_ENTRY1s("HPP.orb", "a396a310e9d42ff43798ffdee2589a1a", 543000636),
Common::DE_DEU,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Hebrew
{
"pokus",
0,
AD_ENTRY1s("HPP.orb", "518453b73021c31566f084b3e4b8bdbf", 502988485),
Common::HE_ISR,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Italian
{
"pokus",
0,
AD_ENTRY1s("HPP.orb", "86fb890be3beaadb36d5daceae52a176", 504320381),
Common::IT_ITA,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Polish
{
"pokus",
0,
AD_ENTRY1s("HPP.orb", "51fb70412a6a5a6590dcaee842a940ab", 539274161),
Common::PL_POL,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Portuguese
{
"pokus",
0,
AD_ENTRY1s("HPP.orb", "149661ec6c35488a300293776a74b460", 526755539),
Common::PT_BRA,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Russian
{
"pokus",
0,
AD_ENTRY1s("HPP.orb", "1e5155c2219b3baea599563e02596ce5", 526369062),
Common::RU_RUS,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Spanish
{
"pokus",
0,
AD_ENTRY1s("HPP.orb", "68040543f153e494e42efe9fab47b850", 508716126),
Common::ES_ESP,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Swedish
{
"pokus",
0,
AD_ENTRY1s("HPP.orb", "7b7909414d93f847ff0c023a06ae1f7e", 500103742),
Common::SV_SWE,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
// Danish
// Version 1.0
// Contributed by sauravisus in Trac#10919
{
"pokus",
0,
AD_ENTRY1s("HPP.orb", "3428dda98c21c4b6cd798750016796ab", 513518023),
Common::DA_DNK,
Common::kPlatformWindows,
ADGF_DROPPLATFORM,
GUIO1(GUIO_NOMIDI)
},
AD_TABLE_END_MARKER
};
} // End of namespace Pink
#endif

139
engines/pink/file.cpp Normal file
View 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 "pink/pink.h"
namespace Pink {
void ObjectDescription::load(Common::File &file) {
file.read(name, sizeof(name));
objectsOffset = file.readUint32LE();
/* objectsCount = */ file.readUint32LE();
resourcesOffset = file.readUint32LE();
resourcesCount = file.readUint32LE();
}
void ResourceDescription::load(Common::File &file) {
file.read(name, sizeof(name));
offset = file.readUint32LE();
size = file.readUint32LE();
inBro = (bool)file.readUint16LE();
}
OrbFile::OrbFile()
: File(), _timestamp(0),
_tableSize(0),
_table(nullptr) {}
OrbFile::~OrbFile() {
delete[] _table;
}
bool OrbFile::open(const Common::Path &name) {
if (!File::open(name) || readUint32BE() != MKTAG('O', 'R', 'B', '\0'))
return false;
uint16 minor = readUint16LE();
uint16 major = readUint16LE();
if (major != kOrbMajorVersion || minor != kOrbMinorVersion)
return false;
if (!(_timestamp = readUint32LE()))
return false;
uint32 tableOffset = readUint32LE();
_tableSize = readUint32LE();
_table = new ObjectDescription[_tableSize];
seek(tableOffset);
for (uint i = 0; i < _tableSize; ++i) {
_table[i].load(*this);
}
return true;
}
void OrbFile::loadGame(PinkEngine *game) {
seekToObject(kPinkGame);
Archive archive(this);
archive.mapObject(reinterpret_cast<Object *>(game)); // hack
game->load(archive);
}
void OrbFile::loadObject(Object *obj, const Common::String &name) {
seekToObject(name.c_str());
Archive archive(this);
obj->load(archive);
}
void OrbFile::loadObject(Object *obj, ObjectDescription *objDesc) {
seek(objDesc->objectsOffset);
Archive archive(this);
obj->load(archive);
}
static int objDescComp(const void *a, const void *b) {
return scumm_stricmp((const char *)a, (const char *)b);
}
ObjectDescription *OrbFile::getObjDesc(const char *name) {
ObjectDescription *desc = (ObjectDescription *)bsearch(name, _table, _tableSize, sizeof(ObjectDescription), objDescComp);
assert(desc != nullptr);
return desc;
}
ResourceDescription *OrbFile::createResDescTable(ObjectDescription *objDesc) {
ResourceDescription *table = new ResourceDescription[objDesc->resourcesCount];
seek(objDesc->resourcesOffset);
for (uint i = 0; i < objDesc->resourcesCount; ++i) {
table[i].load(*this);
}
return table;
}
void OrbFile::seekToObject(const char *name) {
ObjectDescription *desc = getObjDesc(name);
seek(desc->objectsOffset);
}
bool BroFile::open(const Common::Path &name) {
if (!File::open(name) || readUint32BE() != MKTAG('B', 'R', 'O', '\0'))
return false;
uint16 minor = readUint16LE();
uint16 major = readUint16LE();
if (major != kBroMajorVersion || minor != kBroMinorVersion)
return false;
_timestamp = readUint32LE();
return true;
}
} // End of namespace Pink

88
engines/pink/file.h Normal file
View 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.
*
* 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 PINK_FILE_H
#define PINK_FILE_H
#include "common/file.h"
namespace Pink {
struct ObjectDescription {
void load(Common::File &file);
char name[16];
uint32 objectsOffset;
//uint32 objectsCount; never used
uint32 resourcesOffset;
uint32 resourcesCount;
};
struct ResourceDescription {
void load(Common::File &file);
char name[16];
uint32 offset;
uint32 size;
bool inBro;
};
class PinkEngine;
class Object;
class OrbFile : public Common::File {
public:
OrbFile();
~OrbFile() override;
bool open(const Common::Path &name) override;
public:
void loadGame(PinkEngine *game);
void loadObject(Object *obj, const Common::String &name);
void loadObject(Object *obj, ObjectDescription *objDesc);
ResourceDescription *createResDescTable(ObjectDescription *objDesc);
ObjectDescription *getObjDesc(const char *name);
uint32 getTimestamp() { return _timestamp; }
private:
void seekToObject(const char *name);
private:
ObjectDescription *_table;
uint32 _tableSize;
uint32 _timestamp;
};
class BroFile : public Common::File {
public:
BroFile() : _timestamp(0) {}
bool open(const Common::Path &name) override;
uint32 getTimestamp() { return _timestamp; }
private:
uint32 _timestamp;
};
} // End of namespace Pink
#endif

324
engines/pink/gui.cpp Normal file
View 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.
*
* 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/config-manager.h"
#include "common/translation.h"
#include "engines/metaengine.h"
#include "graphics/macgui/macwindowmanager.h"
#include "graphics/macgui/macmenu.h"
#include "gui/message.h"
#include "pink/pink.h"
#include "pink/screen.h"
#include "pink/objects/actors/lead_actor.h"
namespace Pink {
enum {
kNewGameAction = 57600,
kLoadSave = 57601,
kSaveAction = 57603,
kSaveAsAction = 57604,
kSongsAction = 32865,
kSoundSettingsAction = 32772,
kLastSavesAction = 57616,
kPauseAction = 32854,
kExitAction = 57665
};
enum {
kShowContent = 32771,
kShowGreece = 32866,
kShowIndonesia = 32867,
kShowIsrael = 32868,
kShowKenya = 32869,
kShowRussia = 32870
};
enum {
kShowPDAAction = 32793,
kShowAustraliaArt = 32796,
kShowAustraliaCloth = 32797,
kShowAustraliaFood = 32798,
kShowAustraliaHistory = 32799,
kShowAustraliaNature = 32800,
kShowAustraliaPeople = 32801,
kShowAustraliaPlaces = 32802,
kShowAustraliaReligion = 32803,
kShowBhutanArt = 32804,
kShowBhutanCloth = 32805,
kShowBhutanFood = 32806,
kShowBhutanHistory = 32807,
kShowBhutanNature = 32808,
kShowBhutanPeople = 32809,
kShowBhutanPlaces = 32810,
kShowBhutanReligion = 32811,
kShowChinaArt = 32812,
kShowChinaCloth = 32813,
kShowChinaFood = 32814,
kShowChinaHistory = 32815,
kShowChinaNature = 32816,
kShowChinaPeople = 32817,
kShowChinaPlaces = 32818,
kShowChinaReligion = 32819,
kShowEnglandArt = 32820,
kShowEnglandCloth = 32821,
kShowEnglandFood = 32822,
kShowEnglandHistory = 32823,
kShowEnglandNature = 32824,
kShowEnglandPeople = 32825,
kShowEnglandPlaces = 32826,
kShowEnglandReligion = 32827,
kShowEgyptArt = 32828,
kShowEgyptCloth = 32829,
kShowEgyptFood = 32830,
kShowEgyptHistory = 32831,
kShowEgyptNature = 32832,
kShowEgyptPeople = 32833,
kShowEgyptPlaces = 32834,
kShowEgyptReligion = 32835,
kShowIndiaArt = 32836,
kShowIndiaCloth = 32837,
kShowIndiaFood = 32838,
kShowIndiaHistory = 32839,
kShowIndiaNature = 32840,
kShowIndiaPeople = 32841,
kShowIndiaPlaces = 32842,
kShowIndiaReligion = 32843
};
enum {
kShowGameWebPage = 32844,
kShowTechSupport = 32778,
kShowOnlineHints = 32777,
kShowWanderLustWebPage = 32775,
kShowHelp = 32846,
kShowHints = 32847,
kShowWinnnerPage = 32779,
kShowWanderlustInteractive = 32849,
kShowMGM = 32848,
kShowDiagnostics = 32850,
kShowAbout = 57664
};
enum {
kRecentSaveId = 9,
kRecentSavesOffset = 400000
};
static const int kMaxSaves = 10;
static void menuCommandsCallback(int action, Common::U32String &, void *data) {
PinkEngine *engine = (PinkEngine *)data;
engine->executeMenuCommand(action);
}
struct SaveStateDescriptorTimeComparator {
bool operator()(const SaveStateDescriptor &x, const SaveStateDescriptor &y) const {
return x.getSaveDate() == y.getSaveDate() ? x.getSaveTime() > y.getSaveTime() : x.getSaveDate() > y.getSaveDate();
}
};
SaveStateList PinkEngine::listSaves() const {
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
Common::String pattern = getMetaEngine()->getSavegameFile(kSavegameFilePattern, _targetName.c_str());
Common::StringArray filenames = saveFileMan->listSavefiles(pattern);
SaveStateList saveList;
for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
// Obtain the last 2 digits of the filename, since they correspond to the save slot
int slotNum = atoi(file->c_str() + file->size() - 2);
Common::ScopedPtr<Common::InSaveFile> in(saveFileMan->openForLoading(*file));
if (in) {
SaveStateDescriptor desc;
desc.setSaveSlot(slotNum);
if (Pink::readSaveHeader(*in.get(), desc))
saveList.push_back(desc);
}
}
// Sort saves based on save time.
Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorTimeComparator());
return saveList;
}
void PinkEngine::initMenu() {
_screen->getWndManager().setEngine(this);
_menu = Graphics::MacMenu::createMenuFromPEexe(_exeResources, &_screen->getWndManager());
if (getLanguage() == Common::HE_ISR) {
_menu->setAlignment(Graphics::kTextAlignRight);
}
Graphics::MacMenuSubMenu *subMenu = _menu->getSubmenu(nullptr, 0);
if (subMenu) {
if (isPerilDemo()) {
// From the first submenu ("Game"), disable the (zero indexed) item 5 ("Songs").
// Use setEnabled() rather than removeMenuItem() since the latter removes the item
// out of the list changing the index for the items that follow.
// The effect is that "Songs" will be greyed out for the demo, since it's not available for it.
// The original demo does not have the "Songs" item in the menu at all.
_menu->setEnabled( _menu->getSubMenuItem(_menu->getMenuItem(0), 5), false);
}
SaveStateList saves = listSaves();
if (!saves.empty()) {
_menu->removeMenuItem(subMenu, kRecentSaveId);
int maxSaves = saves.size() > kMaxSaves ? kMaxSaves : saves.size();
for (int i = 0; i < maxSaves; ++i) {
_menu->insertMenuItem(subMenu, Common::U32String::format("%i. %S", i + 1, saves[i].getDescription().c_str()),
kRecentSaveId + i, saves[i].getSaveSlot() + kRecentSavesOffset);
}
}
}
_menu->calcDimensions();
_menu->setCommandsCallback(&menuCommandsCallback, this);
}
void PinkEngine::executeMenuCommand(uint id) {
if (executePageChangeCommand(id))
return;
if (id >= kRecentSavesOffset) {
int slotNum = id - kRecentSavesOffset;
Common::Error loadError = loadGameState(slotNum);
if (loadError.getCode() != Common::kNoError) {
GUI::MessageDialog errorDialog(loadError.getDesc());
errorDialog.runModal();
}
return;
}
switch (id) {
case kNewGameAction: {
initModule(_modules[0]->getName(), "", nullptr);
break;
}
case kLoadSave:
loadGameDialog();
break;
case kSaveAction:
case kSaveAsAction:
saveGameDialog();
break;
case kSoundSettingsAction:
case kLastSavesAction:
case kPauseAction:
case kExitAction:
openMainMenuDialog();
break;
case kSongsAction:
initModule("Muzik", "", nullptr);
break;
case kShowPDAAction:
_actor->loadPDA(kNavigatePage);
break;
// Cases kShowAustraliaArt - kShowIndiaReligion are handled in executePageChangeCommand()
case kShowContent:
_actor->loadPDA("TOC");
break;
case kShowGreece:
_actor->loadPDA("GREOVER");
break;
case kShowIndonesia:
_actor->loadPDA("INDOVER");
break;
case kShowIsrael:
_actor->loadPDA("ISROVER");
break;
case kShowKenya:
_actor->loadPDA("KENOVER");
break;
case kShowRussia:
_actor->loadPDA("SIBOVER");
break;
case kShowGameWebPage:
openLocalWebPage("PINK.HTM");
break;
case kShowTechSupport:
openLocalWebPage("SUPPORT.HTM");
break;
case kShowWinnnerPage:
openLocalWebPage("WINNER.HTM");
break;
case kShowWanderLustWebPage:
openLocalWebPage("LUST.HTM");
break;
case kShowOnlineHints:
openLocalWebPage("HINTS.HTM");
break;
default:
{
GUI::MessageDialog dialog(_("This menu item is not yet implemented"));
dialog.runModal();
warning("Unprocessed command id %d", id);
}
break;
}
}
// Australia, Bhutan, China, Britain, Egypt, India
static const char *pageChangePrefixes[] = { "AUS", "BHU", "CHI", "BRI", "EGY", "IND" };
// Art, Cloth, Food, History, Nature, People, Places, Religion
static const char *pageChangeSuffixes[] = { "ART", "CLO", "FOO", "HIS", "NAT", "PEO", "PLA", "REL" };
bool PinkEngine::executePageChangeCommand(uint id) {
if (id >= kShowAustraliaArt && id <= kShowIndiaReligion) {
Common::String prefix = pageChangePrefixes[(id - kShowAustraliaArt) / 8];
Common::String suffix = pageChangeSuffixes[(id - kShowAustraliaArt) % 8];
_actor->loadPDA(prefix + suffix);
return true;
}
return false;
}
void PinkEngine::openLocalWebPage(const Common::String &pageName) const {
Common::FSNode gameFolder = Common::FSNode(ConfMan.getPath("path"));
Common::FSNode filePath = gameFolder.getChild("INSTALL").getChild(pageName);
if (filePath.exists()) {
Common::String fullUrl = Common::String::format("file:///%s", filePath.getPath().toString('/').c_str());
_system->openUrl(fullUrl);
}
}
} // End of namespace Pink

187
engines/pink/metaengine.cpp Normal file
View File

@@ -0,0 +1,187 @@
/* 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 "common/system.h"
#include "engines/advancedDetector.h"
#include "pink/pink.h"
#include "common/translation.h"
#include "backends/keymapper/action.h"
#include "backends/keymapper/keymapper.h"
#include "backends/keymapper/standard-actions.h"
namespace Pink {
Common::Language PinkEngine::getLanguage() const {
return _desc->language;
}
} // End of Namespace Pink
class PinkMetaEngine : public AdvancedMetaEngine<ADGameDescription> {
public:
const char *getName() const override {
return "pink";
}
bool hasFeature(MetaEngineFeature f) const override;
int getMaximumSaveSlot() const override { return 99; }
SaveStateList listSaves(const char *target) const override;
bool removeSaveState(const char *target, int slot) const override;
SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const override;
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
Common::KeymapArray initKeymaps(const char *target) const override;
};
bool PinkMetaEngine::hasFeature(MetaEngineFeature f) const {
return
(f == kSupportsListSaves) ||
(f == kSupportsDeleteSave) ||
(f == kSavesSupportMetaInfo) ||
(f == kSavesSupportThumbnail) ||
(f == kSavesSupportCreationDate) ||
(f == kSavesSupportPlayTime) ||
(f == kSupportsLoadingDuringStartup);
}
SaveStateList PinkMetaEngine::listSaves(const char *target) const {
Common::SaveFileManager *saveFileMan = g_system->getSavefileManager();
Common::String pattern = Common::String::format("%s.s##", target);
Common::StringArray filenames = saveFileMan->listSavefiles(pattern);
SaveStateList saveList;
for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) {
// Obtain the last 2 digits of the filename, since they correspond to the save slot
int slotNum = atoi(file->c_str() + file->size() - 2);
if (slotNum >= 0 && slotNum <= getMaximumSaveSlot()) {
Common::ScopedPtr<Common::InSaveFile> in(saveFileMan->openForLoading(*file));
if (in) {
SaveStateDescriptor desc;
desc.setSaveSlot(slotNum);
if (Pink::readSaveHeader(*in.get(), desc))
saveList.push_back(desc);
}
}
}
// Sort saves based on slot number.
Common::sort(saveList.begin(), saveList.end(), SaveStateDescriptorSlotComparator());
return saveList;
}
bool PinkMetaEngine::removeSaveState(const char *target, int slot) const {
return g_system->getSavefileManager()->removeSavefile(Pink::generateSaveName(slot, target));
}
SaveStateDescriptor PinkMetaEngine::querySaveMetaInfos(const char *target, int slot) const {
Common::ScopedPtr<Common::InSaveFile> f(g_system->getSavefileManager()->openForLoading(Pink::generateSaveName(slot, target)));
if (f) {
SaveStateDescriptor desc;
if (!Pink::readSaveHeader(*f.get(), desc, false))
return SaveStateDescriptor();
return desc;
}
return SaveStateDescriptor();
}
Common::Error PinkMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
*engine = new Pink::PinkEngine(syst, desc);
return Common::kNoError;
}
Common::KeymapArray PinkMetaEngine::initKeymaps(const char *target) const {
using namespace Common;
using namespace Pink;
Keymap *engineKeyMap = new Keymap(Keymap::kKeymapTypeGame, "pink-default", "Default keymappings");
Action *act;
String gameId = ConfMan.get("gameid", target);
act = new Action(kStandardActionLeftClick, _("Interact / Select"));
act->setLeftClickEvent();
act->addDefaultInputMapping("MOUSE_LEFT");
act->addDefaultInputMapping("JOY_A");
engineKeyMap->addAction(act);
if (gameId == "peril") {
// I18N: (Game Name: Pink Panther) The player normally clicks on a target (character/object) to move toward it and interact (talk,use etc.) with it. This action makes the player still walk to the target but not start interacting when they arrive.
act = new Action(kStandardActionRightClick, _("Cancel interaction"));
act->setRightClickEvent();
act->addDefaultInputMapping("MOUSE_RIGHT");
act->addDefaultInputMapping("JOY_B");
engineKeyMap->addAction(act);
}
// I18N: (Game Name: Pink Panther) The player normally clicks on a target (character/object) to move toward it and interact (talk,use etc.) with it. This action skips the walking animation and immediately start interacting.
act = new Action("SKIPWALK", _("Skip walk"));
act->setCustomEngineActionEvent(kActionSkipWalk);
act->addDefaultInputMapping("SPACE");
act->addDefaultInputMapping("JOY_X");
engineKeyMap->addAction(act);
// I18N: (Game Name: Pink Panther) The player normally clicks on a target (character/object) to move toward it and interact (talk,use etc.) with it. This action skips the walking animation and also prevents the interaction, instead instantly placing the player next to the target.
act = new Action("SKIPWALKANDCANCEL", _("Skip walk and cancel interaction"));
act->setCustomEngineActionEvent(kActionSkipWalkAndCancelInteraction);
act->addDefaultInputMapping("ESCAPE");
act->addDefaultInputMapping("JOY_Y");
engineKeyMap->addAction(act);
// I18N: (Game Name: Pink Panther) This action fully skips the current running sequence (cutscene, dialog, interaction, etc).
act = new Action("SKIPSEQUENCE", _("Skip sequence"));
act->setCustomEngineActionEvent(kActionSkipSequence);
act->addDefaultInputMapping("ESCAPE");
act->addDefaultInputMapping("JOY_UP");
engineKeyMap->addAction(act);
// I18N: (Game Name: Pink Panther) This action skips part of the current running sequence (cutscene, dialog, interaction, etc).
act = new Action("SKIPSUBSEQUENCE", _("Skip sub-sequence"));
act->setCustomEngineActionEvent(kActionSkipSubSequence);
act->addDefaultInputMapping("SPACE");
act->addDefaultInputMapping("RIGHT");
act->addDefaultInputMapping("JOY_RIGHT");
engineKeyMap->addAction(act);
// I18N: (Game Name: Pink Panther) This action restarts the current running sequence (cutscene, dialog, interaction, etc).
act = new Action("RESTARTSEQUENCE", _("Restart sequence"));
act->setCustomEngineActionEvent(kActionRestartSequence);
act->addDefaultInputMapping("LEFT");
act->addDefaultInputMapping("JOY_LEFT");
engineKeyMap->addAction(act);
return Keymap::arrayOf(engineKeyMap);
}
#if PLUGIN_ENABLED_DYNAMIC(PINK)
REGISTER_PLUGIN_DYNAMIC(PINK, PLUGIN_TYPE_ENGINE, PinkMetaEngine);
#else
REGISTER_PLUGIN_STATIC(PINK, PLUGIN_TYPE_ENGINE, PinkMetaEngine);
#endif

62
engines/pink/module.mk Normal file
View File

@@ -0,0 +1,62 @@
MODULE := engines/pink
MODULE_OBJS = \
archive.o \
audio_info_mgr.o \
cel_decoder.o \
console.o \
cursor_mgr.o \
screen.o \
file.o \
gui.o \
metaengine.o \
pda_mgr.o \
pink.o \
resource_mgr.o \
saveload.o \
sound.o \
objects/object.o \
objects/module.o \
objects/inventory.o \
objects/side_effect.o \
objects/condition.o \
objects/actions/action.o \
objects/actions/action_cel.o \
objects/actions/action_hide.o \
objects/actions/action_loop.o \
objects/actions/action_play.o \
objects/actions/action_play_with_sfx.o \
objects/actions/action_sound.o \
objects/actions/action_still.o \
objects/actions/action_talk.o \
objects/actions/action_text.o \
objects/actions/walk_action.o \
objects/actors/actor.o \
objects/actors/audio_info_pda_button.o \
objects/actors/lead_actor.o \
objects/actors/pda_button_actor.o \
objects/actors/supporting_actor.o \
objects/handlers/handler.o \
objects/handlers/handler_mgr.o \
objects/pages/game_page.o \
objects/pages/page.o \
objects/pages/pda_page.o \
objects/sequences/seq_timer.o \
objects/sequences/sequence.o \
objects/sequences/sequence_context.o \
objects/sequences/sequence_item.o \
objects/sequences/sequencer.o \
objects/walk/walk_mgr.o \
objects/walk/walk_location.o \
objects/walk/walk_shortest_path.o
# This module can be built as a plugin
ifeq ($(ENABLE_PINK), DYNAMIC_PLUGIN)
PLUGIN := 1
endif
# Include common rules
include $(srcdir)/rules.mk
# Detection objects
DETECT_OBJS += $(MODULE)/detection.o

View File

@@ -0,0 +1,44 @@
/* 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 "pink/archive.h"
#include "pink/objects/actions/action.h"
#include "pink/objects/actors/actor.h"
namespace Pink {
void Action::deserialize(Archive &archive) {
NamedObject::deserialize(archive);
_actor = static_cast<Actor *>(archive.readObject());
}
bool Action::initPalette(Screen *screen) {
return false;
}
void Action::pause(bool paused) {}
Coordinates Action::getCoordinates() {
return Coordinates();
}
} // End of namespace Pink

View 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.
*
* 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 PINK_ACTION_H
#define PINK_ACTION_H
#include "pink/objects/object.h"
#include "pink/objects/walk/walk_mgr.h"
namespace Pink {
class Actor;
class Screen;
class Action : public NamedObject {
public:
void deserialize(Archive &archive) override;
virtual bool initPalette(Screen *screen);
virtual void start() = 0;
virtual void end() = 0;
virtual void pause(bool paused);
virtual Coordinates getCoordinates();
Actor *getActor() const { return _actor; }
protected:
Actor *_actor;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,111 @@
/* 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 "common/debug.h"
#include "common/substream.h"
#include "pink/archive.h"
#include "pink/cel_decoder.h"
#include "pink/screen.h"
#include "pink/pink.h"
#include "pink/objects/actions/action_cel.h"
#include "pink/objects/actors/actor.h"
#include "pink/objects/pages/game_page.h"
namespace Pink {
ActionCEL::~ActionCEL() {
end();
}
void ActionCEL::deserialize(Archive &archive) {
Action::deserialize(archive);
_fileName = archive.readString();
_z = archive.readDWORD();
}
bool ActionCEL::initPalette(Screen *screen) {
loadDecoder();
if (_decoder.getCurFrame() == -1) {
_decoder.decodeNextFrame();
_decoder.rewind();
}
screen->setPalette(_decoder.getPalette());
return true;
}
void ActionCEL::start() {
loadDecoder();
_decoder.start();
this->onStart();
_actor->getPage()->getGame()->getScreen()->addSprite(this);
}
void ActionCEL::end() {
_actor->getPage()->getGame()->getScreen()->removeSprite(this);
_decoder.close();
}
void ActionCEL::pause(bool paused) {
_decoder.pauseVideo(paused);
}
Coordinates ActionCEL::getCoordinates() {
loadDecoder();
Coordinates coords;
coords.point = _decoder.getCenter();
coords.z = getZ();
return coords;
}
void ActionCEL::loadDecoder() {
if (!_decoder.isVideoLoaded()) {
_decoder.loadStream(_actor->getPage()->getResourceStream(_fileName));
Common::Point point = _decoder.getCenter();
_bounds = Common::Rect::center(point.x, point.y, _decoder.getWidth(), _decoder.getHeight());
}
}
void ActionCEL::setFrame(uint frame) {
_decoder.rewind();
for (uint i = 0; i < frame; ++i) {
_decoder.skipFrame();
}
_decoder.clearDirtyRects();
_actor->getPage()->getGame()->getScreen()->addDirtyRect(_bounds);
}
void ActionCEL::decodeNext() {
_decoder.decodeNextFrame();
_actor->getPage()->getGame()->getScreen()->addDirtyRects(this);
}
void ActionCEL::setCenter(Common::Point center) {
_actor->getPage()->getGame()->getScreen()->addDirtyRect(_bounds);
_bounds = Common::Rect::center(center.x, center.y, _decoder.getWidth(), _decoder.getHeight());
_actor->getPage()->getGame()->getScreen()->addDirtyRect(_bounds);
}
} // End of namespace Pink

View File

@@ -0,0 +1,73 @@
/* 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 PINK_ACTION_CEL_H
#define PINK_ACTION_CEL_H
#include "pink/cel_decoder.h"
#include "pink/objects/actions/action.h"
namespace Pink {
class CelDecoder;
class ActionCEL : public Action {
public:
~ActionCEL() override;
void deserialize(Archive &archive) override;
bool initPalette(Screen *screen) override;
void start() override;
void end() override;
bool needsUpdate() { return _decoder.needsUpdate(); }
virtual void update() {};
void pause(bool paused) override;
Coordinates getCoordinates() override;
const Common::Rect &getBounds() const { return _bounds; }
uint32 getZ() { return _z; }
CelDecoder *getDecoder() { return &_decoder; }
void setCenter(Common::Point center);
void loadDecoder();
protected:
virtual void onStart() = 0;
void decodeNext();
void setFrame(uint frame);
CelDecoder _decoder;
Common::String _fileName;
Common::Rect _bounds;
uint32 _z;
};
} // End of namespace Pink
#endif

View 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.
*
* 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 "pink/archive.h"
#include "pink/pink.h"
#include "pink/objects/actions/action_hide.h"
#include "pink/objects/actors/actor.h"
namespace Pink {
void ActionHide::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\tActionHide: _name = %s", _name.c_str());
}
void ActionHide::start() {
debugC(6, kPinkDebugActions, "Actor %s has now ActionHide %s", _actor->getName().c_str(), _name.c_str());
_actor->endAction();
}
void ActionHide::end() {
debugC(6, kPinkDebugActions, "ActionHide %s of Actor %s is ended", _name.c_str(), _actor->getName().c_str());
}
} //End of namespace Pink

View File

@@ -0,0 +1,39 @@
/* 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 PINK_ACTION_HIDE_H
#define PINK_ACTION_HIDE_H
#include "pink/objects/actions/action.h"
namespace Pink {
class ActionHide : public Action {
public:
void toConsole() const override;
void start() override;
void end() override;
};
} //End of namespace Pink
#endif

View 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.
*
* 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/random.h"
#include "pink/pink.h"
#include "pink/cel_decoder.h"
#include "pink/objects/actions/action_loop.h"
#include "pink/objects/actors/actor.h"
#include "pink/objects/pages/page.h"
namespace Pink {
void ActionLoop::deserialize(Archive &archive) {
ActionPlay::deserialize(archive);
uint16 style;
_intro = archive.readDWORD();
style = archive.readWORD();
switch (style) {
case kPingPong:
_style = kPingPong;
break;
case kRandom:
_style = kRandom;
break;
default:
_style = kForward;
break;
}
}
void ActionLoop::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\tActionLoop: _name = %s, _fileName = %s, z = %u, _startFrame = %u,"
" _endFrame = %d, _intro = %u, _style = %u",
_name.c_str(), _fileName.c_str(), _z, _startFrame, _stopFrame, _intro, _style);
}
void ActionLoop::update() {
int32 frame = _decoder.getCurFrame();
if (!_inLoop) {
if (frame < (int32)_startFrame) {
decodeNext();
return;
} else
_inLoop = true;
}
switch (_style) {
case kPingPong:
if (_forward) {
if (frame < _stopFrame) {
decodeNext();
} else {
_forward = false;
ActionCEL::setFrame(_stopFrame - 1);
decodeNext();
}
} else {
if (frame > (int32)_startFrame) {
ActionCEL::setFrame(frame - 1);
} else {
_forward = true;
}
decodeNext();
}
break;
case kRandom: {
Common::RandomSource &rnd = _actor->getPage()->getGame()->getRnd();
ActionCEL::setFrame(rnd.getRandomNumberRng(_startFrame, _stopFrame));
decodeNext();
break;
}
case kForward:
if (frame == _stopFrame) {
ActionCEL::setFrame(_startFrame);
}
decodeNext();
break;
default:
break;
}
}
void ActionLoop::onStart() {
if (_intro) {
uint startFrame = _startFrame;
_startFrame = 0;
ActionPlay::onStart();
_startFrame = startFrame;
_inLoop = false;
} else {
ActionPlay::onStart();
_inLoop = true;
}
if (!isTalk())
_actor->endAction();
_forward = true;
}
void ActionLoop::end() {
ActionCEL::end();
debugC(6, kPinkDebugActions, "ActionLoop %s of Actor %s is ended", _name.c_str(), _actor->getName().c_str());
}
} // End of namespace Pink

View 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.
*
* 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 PINK_ACTION_LOOP_H
#define PINK_ACTION_LOOP_H
#include "pink/objects/actions/action_play.h"
namespace Pink {
class ActionLoop : public ActionPlay {
public:
void deserialize(Archive &archive) override;
void toConsole() const override;
void update() override;
void end() override;
protected:
void onStart() override;
virtual bool isTalk() { return false; }
enum Style {
kPingPong = 2,
kRandom = 3,
kForward = 4
};
Style _style;
bool _intro;
bool _inLoop;
bool _forward;
};
} // End of namespace Pink
#endif

View 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.
*
* 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 "pink/archive.h"
#include "pink/cel_decoder.h"
#include "pink/pink.h"
#include "pink/objects/actions/action_play.h"
#include "pink/objects/actors/actor.h"
namespace Pink {
void ActionPlay::deserialize(Archive &archive) {
ActionStill::deserialize(archive);
_stopFrame = archive.readDWORD();
}
void ActionPlay::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\tActionPlay: _name = %s, _fileName = %s, z = %u, _startFrame = %u,"
" _endFrame = %d", _name.c_str(), _fileName.c_str(), _z, _startFrame, _stopFrame);
}
void ActionPlay::end() {
ActionCEL::end();
debugC(6, kPinkDebugActions, "ActionPlay %s of Actor %s is ended", _name.c_str(), _actor->getName().c_str());
}
void ActionPlay::update() {
ActionCEL::update();
if (_decoder.getCurFrame() >= _stopFrame) {
_decoder.setEndOfTrack();
assert(!_decoder.needsUpdate());
_actor->endAction();
} else
decodeNext();
}
void ActionPlay::pause(bool paused) {
ActionCEL::pause(paused);
}
void ActionPlay::onStart() {
debugC(6, kPinkDebugActions, "Actor %s has now ActionPlay %s", _actor->getName().c_str(), _name.c_str());
int32 frameCount = _decoder.getFrameCount();
if ((int32)_startFrame >= frameCount) {
_startFrame = 0;
}
if (_stopFrame == -1 || _stopFrame >= frameCount) {
_stopFrame = frameCount - 1;
}
ActionCEL::setFrame(_startFrame);
// doesn't need to decode startFrame here. Update method will decode
}
} // End of namespace Pink

View File

@@ -0,0 +1,49 @@
/* 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 PINK_ACTION_PLAY_H
#define PINK_ACTION_PLAY_H
#include "pink/objects/actions/action_still.h"
namespace Pink {
class ActionPlay : public ActionStill {
public:
void deserialize(Archive &archive) override;
void toConsole() const override;
void end() override;
void update() override;
void pause(bool paused) override;
protected:
void onStart() override;
int32 _stopFrame;
};
} // End of namespace Pink
#endif

View 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.
*
* 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 "pink/cel_decoder.h"
#include "pink/sound.h"
#include "pink/pink.h"
#include "pink/objects/actors/actor.h"
#include "pink/objects/actions/action_play_with_sfx.h"
#include "pink/objects/pages/game_page.h"
#include "pink/objects/sequences/sequencer.h"
namespace Pink {
ActionPlayWithSfx::~ActionPlayWithSfx() {
ActionPlay::end();
for (uint i = 0; i < _sfxArray.size(); ++i) {
delete _sfxArray[i];
}
}
void ActionPlayWithSfx::deserialize(Pink::Archive &archive) {
ActionPlay::deserialize(archive);
_isLoop = archive.readDWORD();
_sfxArray.deserialize(archive);
}
void ActionPlayWithSfx::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\tActionPlayWithSfx: _name = %s, _fileName = %s, z = %u, _startFrame = %u,"
" _endFrame = %d, _isLoop = %u", _name.c_str(), _fileName.c_str(), _z, _startFrame, _stopFrame, _isLoop);
for (uint i = 0; i < _sfxArray.size(); ++i) {
_sfxArray[i]->toConsole();
}
}
void ActionPlayWithSfx::update() {
int currFrame = _decoder.getCurFrame();
if (_isLoop && currFrame == _stopFrame) {
ActionCEL::setFrame(_startFrame);
decodeNext();
} else
ActionPlay::update();
currFrame++;
for (uint i = 0; i < _sfxArray.size(); ++i) {
if (_sfxArray[i]->getFrame() == currFrame)
_sfxArray[i]->play();
}
}
void ActionPlayWithSfx::onStart() {
ActionPlay::onStart();
if (_isLoop)
_actor->endAction();
}
void ActionPlayWithSfx::end() {
ActionCEL::end();
debugC(6, kPinkDebugActions, "ActionPlayWithSfx %s of Actor %s is ended", _name.c_str(), _actor->getName().c_str());
// original bug fix
if (_actor->getPage()->getSequencer() && _actor->getPage()->getSequencer()->isSkipping()) {
for (uint i = 0; i < _sfxArray.size(); ++i) {
_sfxArray[i]->end();
}
}
}
void ActionSfx::deserialize(Pink::Archive &archive) {
_frame = archive.readDWORD();
_volume = archive.readDWORD();
assert(_volume <= 100);
_sfxName = archive.readString();
_sprite = (ActionPlayWithSfx *)archive.readObject();
}
void ActionSfx::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\tActionSfx: _sfx = %s, _volume = %u, _frame = %u", _sfxName.c_str(), _volume, _frame);
}
void ActionSfx::play() {
Page *page = _sprite->getActor()->getPage();
if (!_sound.isPlaying()) {
debugC(kPinkDebugActions, "ActionSfx %s of %s is now playing", _sfxName.c_str(), _sprite->getName().c_str());
int8 balance = (_sprite->getDecoder()->getCenter().x * 396875 / 1000000) - 127;
_sound.play(page->getResourceStream(_sfxName), Audio::Mixer::kSFXSoundType, _volume, balance);
}
}
void ActionSfx::end() {
_sound.stop();
}
} // End of namespace Pink

View 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.
*
* 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 PINK_ACTION_PLAY_WITH_SFX_H
#define PINK_ACTION_PLAY_WITH_SFX_H
#include "pink/objects/actions/action_play.h"
#include "pink/sound.h"
namespace Pink {
class ActionSfx;
class ActionPlayWithSfx : public ActionPlay {
public:
ActionPlayWithSfx()
: _isLoop(false) {}
~ActionPlayWithSfx() override;
void deserialize(Archive &archive) override;
void toConsole() const override;
void update() override;
void end() override;
protected:
void onStart() override;
private:
Array<ActionSfx *> _sfxArray;
bool _isLoop;
};
class Page;
class ActionSfx : public Object {
public:
void deserialize(Archive &archive) override;
void toConsole() const override;
void play();
void end();
int32 getFrame() { return _frame; }
private:
ActionPlayWithSfx *_sprite;
Common::String _sfxName;
Sound _sound;
byte _volume;
int32 _frame;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,86 @@
/* 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 "common/debug.h"
#include "pink/archive.h"
#include "pink/pink.h"
#include "pink/screen.h"
#include "pink/sound.h"
#include "pink/objects/actions/action_sound.h"
#include "pink/objects/actors/actor.h"
#include "pink/objects/pages/game_page.h"
namespace Pink {
ActionSound::~ActionSound() {
end();
}
void ActionSound::deserialize(Archive &archive) {
Action::deserialize(archive);
_fileName = archive.readString();
_volume = archive.readDWORD();
assert(_volume <= 100);
_isLoop = (bool)archive.readDWORD();
_isBackground = (bool)archive.readDWORD();
}
void ActionSound::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\tActionSound: _name = %s, _fileName = %s, _volume = %u, _isLoop = %u,"
" _isBackground = %u", _name.c_str(), _fileName.c_str(), _volume, _isLoop, _isBackground);
}
void ActionSound::start() {
Audio::Mixer::SoundType soundType = _isBackground ? Audio::Mixer::kMusicSoundType : Audio::Mixer::kSFXSoundType;
Page *page = _actor->getPage();
if (!_isLoop) {
Screen *screen = page->getGame()->getScreen();
screen->addSound(this);
} else
_actor->endAction();
_sound.play(page->getResourceStream(_fileName), soundType, _volume, 0, _isLoop);
debugC(6, kPinkDebugActions, "Actor %s has now ActionSound %s", _actor->getName().c_str(), _name.c_str());
}
void ActionSound::end() {
_sound.stop();
if (!_isLoop) {
Screen *screen = _actor->getPage()->getGame()->getScreen();
screen->removeSound(this);
}
debugC(6, kPinkDebugActions, "ActionSound %s of Actor %s is ended", _name.c_str(), _actor->getName().c_str());
}
void ActionSound::update() {
if (!_sound.isPlaying())
_actor->endAction();
}
void ActionSound::pause(bool paused) {
_sound.pause(paused);
}
} // End of namespace Pink

View File

@@ -0,0 +1,54 @@
/* 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 PINK_ACTION_SOUND_H
#define PINK_ACTION_SOUND_H
#include "pink/objects/actions/action.h"
#include "pink/sound.h"
namespace Pink {
class ActionSound : public Action {
public:
~ActionSound() override;
void deserialize(Archive &archive) override;
void toConsole() const override;
void start() override;
void end() override;
void update();
void pause(bool paused) override;
private:
Common::String _fileName;
Sound _sound;
byte _volume;
bool _isLoop;
bool _isBackground;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,74 @@
/* 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 "common/debug.h"
#include "pink/archive.h"
#include "pink/cel_decoder.h"
#include "pink/pink.h"
#include "pink/objects/actions/action_still.h"
#include "pink/objects/actors/actor.h"
namespace Pink {
void ActionStill::deserialize(Archive &archive) {
ActionCEL::deserialize(archive);
_startFrame = archive.readDWORD();
}
void ActionStill::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\tActionStill: _name = %s, _fileName = %s, _z =%u _startFrame = %u",
_name.c_str(), _fileName.c_str(), _z, _startFrame);
}
void ActionStill::end() {
ActionCEL::end();
debugC(6, kPinkDebugActions, "ActionStill %s of Actor %s is ended", _name.c_str(), _actor->getName().c_str());
}
void ActionStill::pause(bool paused) {}
void ActionStill::onStart() {
debugC(6, kPinkDebugActions, "Actor %s has now ActionStill %s", _actor->getName().c_str(), _name.c_str());
if (_startFrame >= _decoder.getFrameCount())
_startFrame = 0;
setFrame(_startFrame);
_decoder.setEndOfTrack();
assert(!_decoder.needsUpdate());
_actor->endAction();
}
void ActionStill::setFrame(uint frame) {
ActionCEL::setFrame(frame);
decodeNext();
}
void ActionStill::nextFrameLooped() {
if (_decoder.getFrameCount() != 0) {
setFrame((_decoder.getCurFrame() + 1) % _decoder.getFrameCount());
}
}
} // End of namespace Pink

View File

@@ -0,0 +1,51 @@
/* 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 PINK_ACTION_STILL_H
#define PINK_ACTION_STILL_H
#include "pink/objects/actions/action_cel.h"
namespace Pink {
class ActionStill : public ActionCEL {
public:
void deserialize(Archive &archive) override;
void toConsole() const override;
void end() override;
void pause(bool paused) override;
void setFrame(uint frame);
void nextFrameLooped();
protected:
void onStart() override;
uint32 _startFrame;
};
} // End of namespace Pink
#endif

View 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.
*
* 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 "pink/archive.h"
#include "pink/cel_decoder.h"
#include "pink/pink.h"
#include "pink/sound.h"
#include "pink/objects/actions/action_talk.h"
#include "pink/objects/actors/actor.h"
#include "pink/objects/pages/game_page.h"
namespace Pink {
void ActionTalk::deserialize(Archive &archive) {
ActionLoop::deserialize(archive);
_vox = archive.readString();
}
void ActionTalk::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\tActionTalk: _name = %s, _fileName = %s, z = %u, _startFrame = %u,"
" _endFrame = %d, _intro = %u, _style = %u, _vox = %s",
_name.c_str(), _fileName.c_str(), _z, _startFrame, _stopFrame, _intro, _style, _vox.c_str());
}
void ActionTalk::update() {
ActionLoop::update();
if (!_sound.isPlaying()) {
_decoder.setEndOfTrack();
assert(!_decoder.needsUpdate());
_actor->endAction();
}
}
void ActionTalk::end() {
ActionPlay::end();
_sound.stop();
}
void ActionTalk::pause(bool paused) {
ActionCEL::pause(paused);
_sound.pause(paused);
}
void ActionTalk::onStart() {
ActionLoop::onStart();
int8 balance = (_decoder.getCenter().x * 51 - 16160) / 320;
_sound.play(_actor->getPage()->getResourceStream(_vox), Audio::Mixer::kSpeechSoundType, 100, balance);
}
} // End of namespace Pink

View File

@@ -0,0 +1,54 @@
/* 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 PINK_ACTION_TALK_H
#define PINK_ACTION_TALK_H
#include "pink/objects/actions/action_loop.h"
namespace Pink {
class Sound;
class ActionTalk : public ActionLoop {
public:
void deserialize(Archive &archive) override;
void toConsole() const override;
void update() override;
void end() override;
void pause(bool paused) override;
protected:
void onStart() override;
bool isTalk() override { return true; }
private:
Common::String _vox;
Sound _sound;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,219 @@
/* 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 "common/debug.h"
#include "common/substream.h"
#include "common/unicode-bidi.h"
#include "graphics/paletteman.h"
#include "pink/archive.h"
#include "pink/screen.h"
#include "pink/pink.h"
#include "pink/objects/actors/actor.h"
#include "pink/objects/actions/action_text.h"
#include "pink/objects/pages/page.h"
namespace Pink {
ActionText::ActionText() {
_txtWnd = nullptr;
_macText = nullptr;
_xLeft = _xRight = 0;
_yTop = _yBottom = 0;
_centered = 0;
_scrollBar = 0;
_textRGB = 0;
_backgroundRGB = 0;
_textColorIndex = 0;
_backgroundColorIndex = 0;
}
ActionText::~ActionText() {
end();
}
void ActionText::deserialize(Archive &archive) {
Action::deserialize(archive);
_fileName = archive.readString();
_xLeft = archive.readDWORD();
_yTop = archive.readDWORD();
_xRight = archive.readDWORD();
_yBottom = archive.readDWORD();
_centered = archive.readDWORD();
_scrollBar = archive.readDWORD();
byte r = archive.readByte();
byte g = archive.readByte();
byte b = archive.readByte();
(void)archive.readByte(); // skip Alpha
_textRGB = r << 16 | g << 8 | b;
r = archive.readByte();
g = archive.readByte();
b = archive.readByte();
(void)archive.readByte(); // skip Alpha
_backgroundRGB = r << 16 | g << 8 | b;
}
void ActionText::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\tActionText: _name = %s, _fileName = %s, "
"_xLeft = %u, _yTop = %u, _xRight = %u, _yBottom = %u _centered = %u, _scrollBar = %u, _textColor = %u _backgroundColor = %u",
_name.c_str(), _fileName.c_str(), _xLeft, _yTop, _xRight, _yBottom, _centered, _scrollBar, _textRGB, _backgroundRGB);
}
void ActionText::start() {
findColorsInPalette();
Screen *screen = _actor->getPage()->getGame()->getScreen();
Graphics::TextAlign align = _centered ? Graphics::kTextAlignCenter : Graphics::kTextAlignLeft;
Common::SeekableReadStream *stream = _actor->getPage()->getResourceStream(_fileName);
char *str = new char[stream->size()];
stream->read(str, stream->size());
delete stream;
Common::Language language = _actor->getPage()->getGame()->getLanguage();
screen->getWndManager()._language = language;
switch(language) {
case Common::DA_DNK:
// fall through
case Common::ES_ESP:
// fall through
case Common::FR_FRA:
// fall through
case Common::PT_BRA:
// fall through
case Common::DE_DEU:
// fall through
case Common::IT_ITA:
// fall through
case Common::NL_NLD:
_text = Common::String(str).decode(Common::kWindows1252);
break;
case Common::FI_FIN:
// fall through
case Common::SV_SWE:
_text = Common::String(str).decode(Common::kWindows1257);
break;
case Common::HE_ISR:
_text = Common::String(str).decode(Common::kWindows1255);
if (!_centered) {
align = Graphics::kTextAlignRight;
}
break;
case Common::PL_POL:
_text = Common::String(str).decode(Common::kWindows1250);
break;
case Common::RU_RUS:
_text = Common::String(str).decode(Common::kWindows1251);
break;
case Common::EN_GRB:
// fall through
case Common::EN_ANY:
// fall through
default:
_text = Common::String(str);
break;
}
_text.trim();
delete[] str;
while ( _text.size() > 0 && (_text[ _text.size() - 1 ] == '\n' || _text[ _text.size() - 1 ] == '\r') )
_text.deleteLastChar();
if (_scrollBar) {
_txtWnd = screen->getWndManager().addTextWindow(screen->getTextFont(), _textColorIndex, _backgroundColorIndex,
_xRight - _xLeft, align, nullptr);
_txtWnd->setTextColorRGB(_textRGB);
_txtWnd->enableScrollbar(true);
// it will hide the scrollbar when the text height is smaller than the window height
_txtWnd->setMode(Graphics::kWindowModeDynamicScrollbar);
_txtWnd->move(_xLeft, _yTop);
_txtWnd->resize(_xRight - _xLeft, _yBottom - _yTop);
_txtWnd->setEditable(false);
_txtWnd->setSelectable(false);
_txtWnd->appendText(_text);
screen->addTextWindow(_txtWnd);
} else {
screen->addTextAction(this);
_macText = new Graphics::MacText(_text, &screen->getWndManager(), screen->getTextFont(), _textColorIndex, _backgroundColorIndex, _xRight - _xLeft, align);
}
}
Common::Rect ActionText::getBound() {
return Common::Rect(_xLeft, _yTop, _xRight, _yBottom);
}
void ActionText::end() {
Screen *screen = _actor->getPage()->getGame()->getScreen();
screen->addDirtyRect(this->getBound());
if (_scrollBar && _txtWnd) {
screen->getWndManager().removeWindow(_txtWnd);
screen->removeTextWindow(_txtWnd);
_txtWnd = nullptr;
} else {
screen->removeTextAction(this);
delete _macText;
}
}
void ActionText::draw(Graphics::ManagedSurface *surface) {
int yOffset = 0;
// we need to first fill this area with backgroundColor, in order to wash away the previous text
surface->fillRect(Common::Rect(_xLeft, _yTop, _xRight, _yBottom), _backgroundColorIndex);
if (_centered) {
yOffset = (_yBottom - _yTop) / 2 - _macText->getTextHeight() / 2;
}
_macText->drawToPoint(surface, Common::Rect(0, 0, _xRight - _xLeft, _yBottom - _yTop), Common::Point(_xLeft, _yTop + yOffset));
}
#define BLUE(rgb) ((rgb) & 0xFF)
#define GREEN(rgb) (((rgb) >> 8) & 0xFF)
#define RED(rgb) (((rgb) >> 16) & 0xFF)
void ActionText::findColorsInPalette() {
byte palette[256 * 3];
g_system->getPaletteManager()->grabPalette(palette, 0, 256);
g_paletteLookup->setPalette(palette, 256);
debug(2, "textcolorindex: %06x", _textRGB);
_textColorIndex = g_paletteLookup->findBestColor(RED(_textRGB), GREEN(_textRGB), BLUE(_textRGB));
debug(2, "backgroundColorIndex: %06x", _backgroundRGB);
_backgroundColorIndex = g_paletteLookup->findBestColor(RED(_backgroundRGB), GREEN(_backgroundRGB), BLUE(_backgroundRGB));
}
} // End of namespace Pink

View 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.
*
* 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 PINK_ACTION_TEXT_H
#define PINK_ACTION_TEXT_H
#include "common/events.h"
#include "graphics/macgui/macwindow.h"
#include "graphics/macgui/macmenu.h"
#include "graphics/macgui/mactextwindow.h"
#include "pink/objects/actions/action.h"
namespace Pink {
class ActionText : public Action {
public:
ActionText();
~ActionText() override;
void deserialize(Archive &archive) override;
void toConsole() const override;
void start() override;
void end() override;
void draw(Graphics::ManagedSurface *surface); // only for non-scrollable text
Common::Rect getBound();
private:
void findColorsInPalette();
void loadBorder(Graphics::MacWindow *target, Common::String filename, uint32 flags);
private:
Common::String _fileName;
Common::U32String _text;
Graphics::MacTextWindow *_txtWnd;
Graphics::MacText *_macText;
uint32 _xLeft;
uint32 _yTop;
uint32 _xRight;
uint32 _yBottom;
uint32 _centered;
uint32 _scrollBar;
uint32 _textRGB;
uint32 _backgroundRGB;
byte _textColorIndex;
byte _backgroundColorIndex;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,93 @@
/* 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 "pink/archive.h"
#include "pink/cel_decoder.h"
#include "pink/pink.h"
#include "pink/objects/actions/walk_action.h"
#include "pink/objects/actors/actor.h"
namespace Pink {
void WalkAction::deserialize(Archive &archive) {
ActionCEL::deserialize(archive);
uint32 calcFramePositions = archive.readDWORD();
_toCalcFramePositions = calcFramePositions;
}
void WalkAction::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\tWalkAction: _name = %s, _fileName = %s, _calcFramePositions = %u",
_name.c_str(), _fileName.c_str(), _toCalcFramePositions);
}
void WalkAction::onStart() {
if (_toCalcFramePositions) {
_start = _mgr->getStartCoords().point;
_end = _mgr->getEndCoords().point;
if (!_horizontal) {
_end.y = getCoordinates().point.y;
_start.y = _end.y;
_frameCount = _decoder.getFrameCount();
}
else {
_frameCount = (uint)abs(3 * (_start.x - _end.x) / (int)_z);
if (!_frameCount)
_frameCount = 1;
}
setCenter(_start);
_curFrame = 0;
}
}
void WalkAction::update() {
if (_toCalcFramePositions) {
if (_curFrame < _frameCount)
_curFrame++;
const double k = _curFrame / (double) _frameCount;
Common::Point newCenter;
newCenter.x = (_end.x - _start.x) * k + _start.x;
if (_horizontal) {
newCenter.y = (_end.y - _start.y) * k + _start.y;
} else {
newCenter.y = getCoordinates().point.y;
}
if (_decoder.getCurFrame() < (int)_decoder.getFrameCount() - 1)
decodeNext();
else {
setFrame(0);
}
setCenter(newCenter);
if (_curFrame >= _frameCount - 1) {
_decoder.setEndOfTrack();
_actor->endAction();
}
} else {
if (_decoder.getCurFrame() < (int)_decoder.getFrameCount() - 1)
decodeNext();
else {
_decoder.setEndOfTrack();
_actor->endAction();
}
}
}
} // End of namespace Pink

View 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.
*
* 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 PINK_WALK_ACTION_H
#define PINK_WALK_ACTION_H
#include "pink/objects/actions/action_cel.h"
namespace Pink {
class WalkAction : public ActionCEL {
public:
void deserialize(Archive &archive) override;
void toConsole() const override;
void update() override;
void setWalkMgr(WalkMgr *mgr) { _mgr = mgr; }
void setType(bool horizontal) { _horizontal = horizontal; }
protected:
void onStart() override;
private:
WalkMgr *_mgr;
Common::Point _start;
Common::Point _end;
uint _curFrame;
uint _frameCount;
bool _horizontal;
bool _toCalcFramePositions;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,143 @@
/* 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 "pink/constants.h"
#include "pink/cursor_mgr.h"
#include "pink/pink.h"
#include "pink/objects/actions/action_cel.h"
#include "pink/objects/actors/actor.h"
#include "pink/objects/actors/lead_actor.h"
#include "pink/objects/pages/game_page.h"
namespace Pink {
Actor::Actor()
: _page(nullptr), _action(nullptr),
_isActionEnded(true) {}
Actor::~Actor() {
for (uint i = 0; i < _actions.size(); ++i) {
delete _actions[i];
}
}
void Actor::deserialize(Archive &archive) {
NamedObject::deserialize(archive);
_page = static_cast<Page *>(archive.readObject());
_actions.deserialize(archive);
}
void Actor::loadState(Archive &archive) {
_action = findAction(archive.readString());
}
void Actor::saveState(Archive &archive) {
Common::String actionName;
if (_action)
actionName = _action->getName();
archive.writeString(actionName);
}
void Actor::init(bool paused) {
if (!_action)
_action = findAction(kIdleAction);
if (!_action) {
_isActionEnded = true;
} else {
_isActionEnded = false;
_action->start();
_action->pause(paused);
}
}
bool Actor::initPalette(Screen *screen) {
for (uint i = 0; i < _actions.size(); ++i) {
if (_actions[i]->initPalette(screen))
return true;
}
return false;
}
void Actor::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "Actor: _name = %s", _name.c_str());
for (uint i = 0; i < _actions.size(); ++i) {
_actions[i]->toConsole();
}
}
void Actor::pause(bool paused) {
if (_action)
_action->pause(paused);
}
void Actor::onMouseOver(Common::Point point, CursorMgr *mgr) {
mgr->setCursor(kDefaultCursor, point, Common::String());
}
void Actor::onMouseOverWithItem(Common::Point point, const Common::String &itemName, CursorMgr *cursorMgr) {
cursorMgr->setCursor(kHoldingItemCursor, point, itemName);
}
Action *Actor::findAction(const Common::String &name) {
for (uint i = 0; i < _actions.size(); ++i) {
if (_actions[i]->getName() == name)
return _actions[i];
}
return nullptr;
}
Common::String Actor::getLocation() const {
return Common::String();
}
void Actor::setAction(Action *newAction) {
if (_action) {
_isActionEnded = true;
_action->end();
}
_action = newAction;
if (newAction) {
_isActionEnded = false;
_action->start();
}
}
void Actor::setAction(Action *newAction, bool loadingSave) {
if (loadingSave) {
_isActionEnded = true;
_action = newAction;
} else {
setAction(newAction);
}
}
InventoryMgr *Actor::getInventoryMgr() const {
return _page->getModule()->getInventoryMgr();
}
Common::String Actor::getPDALink() const {
return Common::String();
}
} // End of namespace Pink

View File

@@ -0,0 +1,100 @@
/* 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 PINK_ACTOR_H
#define PINK_ACTOR_H
#include "common/rect.h"
#include "pink/utils.h"
namespace Pink {
class Page;
class Action;
class Sequencer;
class Screen;
class CursorMgr;
class InventoryItem;
class InventoryMgr;
class Actor : public NamedObject {
public:
Actor();
~Actor() override;
void deserialize(Archive &archive) override;
void loadState(Archive &archive);
void saveState(Archive &archive);
virtual void init(bool paused);
bool initPalette(Screen *screen);
void toConsole() const override;
bool isPlaying() const { return !_isActionEnded; }
virtual void pause(bool paused);
void endAction() { _isActionEnded = true; }
virtual bool isSupporting() const { return false; }
virtual bool isCursor() const { return false; }
virtual bool isLeftClickHandlers() const { return false; }
virtual bool isUseClickHandlers(InventoryItem *item) const { return false; }
virtual void onMouseOver(Common::Point point, CursorMgr *mgr);
virtual void onMouseOverWithItem(Common::Point point, const Common::String &itemName, CursorMgr *cursorMgr);
virtual void onTimerMessage() {}
virtual void onLeftClickMessage() {}
virtual void onUseClickMessage(InventoryItem *item, InventoryMgr *mgr) {}
Action *findAction(const Common::String &name);
Action *getAction() { return _action; }
const Action *getAction() const { return _action; }
Page *getPage() { return _page; }
const Page *getPage() const { return _page; }
InventoryMgr *getInventoryMgr() const;
virtual Common::String getPDALink() const;
virtual Common::String getLocation() const;
void setAction(const Common::String &name) { setAction(findAction(name)); }
void setAction(Action *newAction);
void setAction(Action *newAction, bool loadingSave);
protected:
Page *_page;
Action *_action;
Array<Action *> _actions;
bool _isActionEnded;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,49 @@
/* 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 "pink/pink.h"
#include "pink/objects/actors/audio_info_pda_button.h"
#include "pink/objects/actors/lead_actor.h"
#include "pink/objects/pages/page.h"
namespace Pink {
void AudioInfoPDAButton::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "AudioInfoPDAButton: _name = %s", _name.c_str());
for (uint i = 0; i < _actions.size(); ++i) {
_actions[i]->toConsole();
}
}
void AudioInfoPDAButton::onMouseOver(Common::Point point, CursorMgr *mgr) {
mgr->setCursor(kClickableFirstFrameCursor, point, Common::String());
}
void AudioInfoPDAButton::onMouseOverWithItem(Common::Point point, const Common::String &itemName, CursorMgr *cursorMgr) {
onMouseOver(point, cursorMgr);
}
void AudioInfoPDAButton::onLeftClickMessage() {
AudioInfoMgr *audioInfoMgr = _page->getLeadActor()->getAudioInfoMgr();
audioInfoMgr->onLeftClick();
}
} // End of namespace Pink

View File

@@ -0,0 +1,46 @@
/* 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 PINK_AUDIO_INFO_PDA_BUTTON_H
#define PINK_AUDIO_INFO_PDA_BUTTON_H
#include "common/debug.h"
#include "pink/constants.h"
#include "pink/cursor_mgr.h"
#include "pink/objects/actions/action.h"
#include "pink/objects/actors/actor.h"
namespace Pink {
class AudioInfoPDAButton : public Actor {
public:
void toConsole() const override;
void onMouseOver(Common::Point point, CursorMgr *mgr) override;
void onMouseOverWithItem(Common::Point point, const Common::String &itemName, CursorMgr *cursorMgr) override;
void onLeftClickMessage() override;
};
} // End of namespace Pink
#endif

View 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.
*
* 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 PINK_CURSOR_ACTOR_H
#define PINK_CURSOR_ACTOR_H
#include "common/debug.h"
#include "pink/pink.h"
#include "pink/objects/actions/action_cel.h"
#include "pink/objects/actors/actor.h"
namespace Pink {
class CursorActor : public Actor {
public:
void toConsole() const override {
debugC(6, kPinkDebugLoadingObjects, "CursorActor: _name = %s", _name.c_str());
for (uint i = 0; i < _actions.size(); ++i) {
_actions[i]->toConsole();
}
}
bool isCursor() const override {
return true;
}
void setCursorItem(const Common::String &name, Common::Point point) {
if (!_action || _action->getName() != name)
setAction(name);
static_cast<ActionCEL*>(_action)->setCenter(point);
}
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,50 @@
/* 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 PINK_INVENTORY_ACTOR_H
#define PINK_INVENTORY_ACTOR_H
#include "common/debug.h"
#include "pink/objects/actions/action.h"
#include "pink/objects/actors/actor.h"
namespace Pink {
class InventoryActor : public Actor {
public:
void toConsole() const override {
debugC(6, kPinkDebugLoadingObjects, "InventoryActor: _name = %s", _name.c_str());
for (uint i = 0; i < _actions.size(); ++i) {
_actions[i]->toConsole();
}
}
void pause(bool paused) override {}
void init(bool paused) override {
Actor::init(false);
}
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,507 @@
/* 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 "pink/archive.h"
#include "pink/cursor_mgr.h"
#include "pink/pink.h"
#include "pink/screen.h"
#include "pink/objects/actions/action.h"
#include "pink/objects/actors/supporting_actor.h"
#include "pink/objects/actors/lead_actor.h"
#include "pink/objects/pages/game_page.h"
#include "pink/objects/sequences/sequence_context.h"
#include "pink/objects/sequences/sequencer.h"
namespace Pink {
LeadActor::LeadActor()
: _state(kReady), _nextState(kUndefined), _stateBeforeInventory(kUndefined),
_stateBeforePDA(kUndefined), _isHaveItem(false), _recipient(nullptr),
_cursorMgr(nullptr), _walkMgr(nullptr), _sequencer(nullptr),
_audioInfoMgr(this) {}
void LeadActor::deserialize(Archive &archive) {
_state = kReady;
Actor::deserialize(archive);
_cursorMgr = static_cast<CursorMgr *>(archive.readObject());
_walkMgr = static_cast<WalkMgr *>(archive.readObject());
_sequencer = static_cast<Sequencer *>(archive.readObject());
}
void LeadActor::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "LeadActor: _name = %s", _name.c_str());
for (uint i = 0; i < _actions.size(); ++i) {
_actions[i]->toConsole();
}
}
void LeadActor::loadState(Archive &archive) {
_state = (State)archive.readByte();
_nextState = (State)archive.readByte();
_stateBeforeInventory = (State)archive.readByte();
_stateBeforePDA = (State)archive.readByte();
_isHaveItem = archive.readByte();
Common::String recipient = archive.readString();
if (!recipient.empty())
_recipient = _page->findActor(recipient);
else
_recipient = nullptr;
_sequencer->loadState(archive);
_walkMgr->loadState(archive);
_page->getGame()->getPdaMgr().loadState(archive);
_audioInfoMgr.loadState(archive);
}
void LeadActor::saveState(Archive &archive) {
archive.writeByte(_state);
archive.writeByte(_nextState);
archive.writeByte(_stateBeforeInventory);
archive.writeByte(_stateBeforePDA);
archive.writeByte(_isHaveItem);
if (_recipient)
archive.writeString(_recipient->getName());
else
archive.writeString(Common::String());
_sequencer->saveState(archive);
_walkMgr->saveState(archive);
_page->getGame()->getPdaMgr().saveState(archive);
_audioInfoMgr.saveState(archive);
}
void LeadActor::init(bool paused) {
if (_state == kUndefined)
_state = kReady;
getInventoryMgr()->setLeadActor(this);
_page->getGame()->setLeadActor(this);
Actor::init(paused);
}
void LeadActor::start(bool isHandler) {
if (isHandler && _state != kPlayingExitSequence) {
_state = kPlayingSequence;
_nextState = kReady;
}
switch (_state) {
case kInventory:
startInventory(1);
break;
case kPDA:
if (_stateBeforePDA == kInventory)
startInventory(1);
_page->getGame()->getScreen()->saveStage();
loadPDA(_page->getGame()->getPdaMgr().getSavedPageName());
break;
default:
forceUpdateCursor();
break;
}
}
void LeadActor::update() {
switch (_state) {
case kMoving:
_walkMgr->update();
// fall through
case kReady:
_sequencer->update();
_cursorMgr->update();
break;
case kPlayingSequence:
_sequencer->update();
if (!_sequencer->isPlaying()) {
_state = _nextState;
_nextState = kUndefined;
forceUpdateCursor();
}
break;
case kInventory:
getInventoryMgr()->update();
break;
case kPDA:
getPage()->getGame()->getPdaMgr().update();
break;
case kPlayingExitSequence:
_sequencer->update();
if (!_sequencer->isPlaying()) {
_state = kUndefined;
_page->getGame()->changeScene();
}
break;
default:
break;
}
}
void LeadActor::loadPDA(const Common::String &pageName) {
if (_state != kPDA) {
if (_state == kMoving)
cancelInteraction();
if (_state != kInventory && !_page->getGame()->getScreen()->isMenuActive())
_page->pause(true);
_stateBeforePDA = _state;
_state = kPDA;
_page->getGame()->getScreen()->saveStage();
}
_page->getGame()->getPdaMgr().setLead(this);
_page->getGame()->getPdaMgr().goToPage(pageName);
}
void LeadActor::onActionClick(Common::CustomEventType action) {
switch (_state) {
case kMoving:
switch (action) {
case kActionSkipWalkAndCancelInteraction:
cancelInteraction();
// fall through
case kActionSkipWalk:
_walkMgr->skip();
break;
default:
break;
}
break;
case kPlayingSequence:
case kPlayingExitSequence:
switch (action) {
case kActionSkipSubSequence:
_sequencer->skipSubSequence();
break;
case kActionSkipSequence:
_sequencer->skipSequence();
break;
case kActionRestartSequence:
_sequencer->restartSequence();
break;
default:
break;
}
break;
default:
break;
}
}
void LeadActor::onLeftButtonClick(Common::Point point) {
switch (_state) {
case kReady:
case kMoving: {
Actor *clickedActor = getActorByPoint(point);
if (!clickedActor)
return;
if (this == clickedActor) {
_audioInfoMgr.stop();
onLeftClickMessage();
} else if (clickedActor->isSupporting()) {
if (isInteractingWith(clickedActor)) {
_recipient = clickedActor;
_audioInfoMgr.stop();
if (!startWalk()) {
if (_isHaveItem)
sendUseClickMessage(clickedActor);
else
sendLeftClickMessage(clickedActor);
}
}
} else
clickedActor->onLeftClickMessage();
break;
}
case kPDA:
_page->getGame()->getPdaMgr().onLeftButtonClick(point);
break;
case kInventory:
getInventoryMgr()->onClick(point);
break;
default:
break;
}
}
void LeadActor::onLeftButtonUp() {
if (_state == kPDA)
_page->getGame()->getPdaMgr().onLeftButtonUp();
}
void LeadActor::onRightButtonClick(Common::Point point) {
if (_state == kReady || _state == kMoving) {
Actor *clickedActor = getActorByPoint(point);
if (clickedActor && isInteractingWith(clickedActor)) {
_audioInfoMgr.start(clickedActor);
}
if (_state == kMoving)
cancelInteraction();
}
}
void LeadActor::onMouseMove(Common::Point point) {
if (_state != kPDA)
updateCursor(point);
else
_page->getGame()->getPdaMgr().onMouseMove(point);
}
void LeadActor::onMouseOverWithItem(Common::Point point, const Common::String &itemName, CursorMgr *cursorMgr) {
_cursorMgr->setCursor(kHoldingItemCursor, point, itemName + kClickable);
}
void LeadActor::onMouseOver(Common::Point point, CursorMgr *mgr) {
if (getInventoryMgr()->isPinkOwnsAnyItems())
_cursorMgr->setCursor(kClickableFirstFrameCursor, point, Common::String());
else
Actor::onMouseOver(point, mgr);
}
void LeadActor::onLeftClickMessage() {
if (_isHaveItem) {
_isHaveItem = false;
_nextState = _state != kMoving ? kUndefined : kReady;
forceUpdateCursor();
} else {
if (_state == kMoving)
cancelInteraction();
startInventory(0);
}
}
void LeadActor::onInventoryClosed(bool isItemClicked) {
_isHaveItem = isItemClicked;
_state = _stateBeforeInventory;
_stateBeforeInventory = kUndefined;
_page->pause(false);
forceUpdateCursor();
}
void LeadActor::onWalkEnd(const Common::String &stopName) {
State oldNextState = _nextState;
_state = kReady;
_nextState = kUndefined;
if (_recipient && oldNextState == kPlayingSequence) {
if (_isHaveItem)
sendUseClickMessage(_recipient);
else
sendLeftClickMessage(_recipient);
} else { // on ESC button
Action *action = findAction(stopName);
assert(action);
setAction(action);
}
}
void LeadActor::onPDAClose() {
_page->initPalette();
_page->getGame()->getScreen()->loadStage();
_state = _stateBeforePDA;
_stateBeforePDA = kUndefined;
if (_state != kInventory)
_page->pause(false);
}
bool LeadActor::isInteractingWith(const Actor *actor) const {
if (!_isHaveItem)
return actor->isLeftClickHandlers();
return actor->isUseClickHandlers(getInventoryMgr()->getCurrentItem());
}
void LeadActor::setNextExecutors(const Common::String &nextModule, const Common::String &nextPage) {
if (_state == kReady || _state == kMoving || _state == kPlayingSequence || _state == kInventory || _state == kPDA) {
_state = kPlayingExitSequence;
_page->getGame()->setNextExecutors(nextModule, nextPage);
}
}
void LeadActor::forceUpdateCursor() {
PinkEngine *vm =_page->getGame();
vm->getScreen()->update(); // we have actions, that should be drawn to properly update cursor
Common::Point point = vm->getEventManager()->getMousePos();
updateCursor(point);
}
void LeadActor::updateCursor(Common::Point point) {
switch (_state) {
case kReady:
case kMoving: {
Actor *actor = getActorByPoint(point);
InventoryItem *item = getInventoryMgr()->getCurrentItem();
if (_isHaveItem) {
if (actor) {
actor->onMouseOverWithItem(point, item->getName(), _cursorMgr);
} else
_cursorMgr->setCursor(kHoldingItemCursor, point, item->getName());
} else if (actor)
actor->onMouseOver(point, _cursorMgr);
else
_cursorMgr->setCursor(kDefaultCursor, point, Common::String());
break;
}
case kPlayingSequence:
case kPlayingExitSequence:
_cursorMgr->setCursor(kNotClickableCursor, point, Common::String());
break;
case kPDA:
case kInventory:
_cursorMgr->setCursor(kDefaultCursor, point, Common::String());
break;
default:
break;
}
}
void LeadActor::sendUseClickMessage(Actor *actor) {
InventoryMgr *mgr = getInventoryMgr();
assert(_state != kPlayingExitSequence);
_nextState = kReady;
_state = kPlayingSequence;
InventoryItem *item = mgr->getCurrentItem();
actor->onUseClickMessage(mgr->getCurrentItem(), mgr);
if (item->getCurrentOwner() != this->_name)
_isHaveItem = false;
forceUpdateCursor();
}
void LeadActor::sendLeftClickMessage(Actor *actor) {
assert(_state != kPlayingExitSequence);
_nextState = kReady;
_state = kPlayingSequence;
actor->onLeftClickMessage();
forceUpdateCursor();
}
WalkLocation *LeadActor::getWalkDestination() {
return _walkMgr->findLocation(_recipient->getLocation());
}
Actor *LeadActor::getActorByPoint(Common::Point point) {
return _page->getGame()->getScreen()->getActorByPoint(point);
}
void LeadActor::startInventory(bool paused) {
if (!getInventoryMgr()->start(paused))
return;
if (!paused) {
_isHaveItem = false;
_stateBeforeInventory = _state;
_state = kInventory;
forceUpdateCursor();
}
_page->pause(true);
}
bool LeadActor::startWalk() {
WalkLocation *location = getWalkDestination();
if (location) {
_state = kMoving;
_nextState = kPlayingSequence;
_walkMgr->start(location);
return true;
}
return false;
}
void LeadActor::cancelInteraction() {
_recipient = nullptr;
_nextState = kReady;
}
Actor *LeadActor::findActor(const Common::String &name) {
return _page->findActor(name);
}
void ParlSqPink::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "ParlSqPink: _name = %s", _name.c_str());
for (uint i = 0; i < _actions.size(); ++i) {
_actions[i]->toConsole();
}
}
WalkLocation *ParlSqPink::getWalkDestination() {
if (_recipient->getName() == kBoy && _page->checkValueOfVariable(kBoyBlocked, kUndefinedValue))
return _walkMgr->findLocation(kSirBaldley);
return LeadActor::getWalkDestination();
}
void PubPink::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "PubPink: _name = %s", _name.c_str());
for (uint i = 0; i < _actions.size(); ++i) {
_actions[i]->toConsole();
}
}
void PubPink::onLeftClickMessage() {
if (!playingMiniGame())
LeadActor::onLeftClickMessage();
}
void PubPink::onVariableSet() {
if (playingMiniGame())
_isHaveItem = true;
}
void PubPink::updateCursor(Common::Point point) {
if (playingMiniGame()) {
Actor *actor = getActorByPoint(point);
assert(actor);
if (_state == kReady && actor->isUseClickHandlers(getInventoryMgr()->getCurrentItem())) {
_cursorMgr->setCursor(kClickableFirstFrameCursor, point, Common::String());
} else
_cursorMgr->setCursor(kDefaultCursor, point, Common::String());
} else {
LeadActor::updateCursor(point);
}
}
void PubPink::sendUseClickMessage(Actor *actor) {
LeadActor::sendUseClickMessage(actor);
if (playingMiniGame())
_isHaveItem = true;
}
WalkLocation *PubPink::getWalkDestination() {
if (playingMiniGame())
return nullptr;
if (_recipient->getName() == kJackson && !_page->checkValueOfVariable(kDrunkLocation, kBolted))
return _walkMgr->findLocation(_page->findActor(kDrunk)->getName());
return LeadActor::getWalkDestination();
}
bool PubPink::playingMiniGame() {
return !(_page->checkValueOfVariable(kFoodPuzzle, kTrueValue) ||
_page->checkValueOfVariable(kFoodPuzzle, kUndefinedValue));
}
void PubPink::onRightButtonClick(Common::Point point) {
if (!playingMiniGame())
LeadActor::onRightButtonClick(point);
}
} // End of namespace Pink

View File

@@ -0,0 +1,162 @@
/* 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 PINK_LEAD_ACTOR_H
#define PINK_LEAD_ACTOR_H
#include "common/events.h"
#include "common/rect.h"
#include "common/keyboard.h"
#include "pink/objects/actors/actor.h"
#include "pink/audio_info_mgr.h"
namespace Pink {
class CursorMgr;
class WalkMgr;
class WalkLocation;
class Sequencer;
class SupportingActor;
class InventoryItem;
class LeadActor : public Actor {
public:
LeadActor();
enum State {
kReady = 0,
kMoving = 1,
kPlayingSequence = 2,
kInventory = 3,
kPDA = 4,
kPlayingExitSequence = 6,
kUndefined = 7
};
void deserialize(Archive &archive) override;
void toConsole() const override;
void loadState(Archive &archive);
void saveState(Archive &archive);
void init(bool paused) override;
void start(bool isHandler);
void update();
void loadPDA(const Common::String &pageName);
void onActionClick(Common::CustomEventType action);
void onLeftButtonClick(Common::Point point);
void onLeftButtonUp();
virtual void onRightButtonClick(Common::Point point);
void onMouseMove(Common::Point point);
void onMouseOverWithItem(Common::Point point, const Common::String &itemName, Pink::CursorMgr *cursorMgr) override;
void onMouseOver(Common::Point point, CursorMgr *mgr) override;
void onLeftClickMessage() override;
virtual void onVariableSet() {}
void onInventoryClosed(bool isItemClicked);
void onWalkEnd(const Common::String &stopName);
void onPDAClose();
bool isInteractingWith(const Actor *actor) const;
void setNextExecutors(const Common::String &nextModule, const Common::String &nextPage);
State getState() const { return _state; }
AudioInfoMgr *getAudioInfoMgr() { return &_audioInfoMgr; }
Actor *getActorByPoint(Common::Point point);
Actor *findActor(const Common::String &name);
protected:
void forceUpdateCursor();
virtual void updateCursor(Common::Point point);
virtual void sendUseClickMessage(Actor *actor);
void sendLeftClickMessage(Actor *actor);
virtual WalkLocation *getWalkDestination();
void startInventory(bool paused);
bool startWalk();
void cancelInteraction();
Actor *_recipient;
CursorMgr *_cursorMgr;
WalkMgr *_walkMgr;
Sequencer *_sequencer;
AudioInfoMgr _audioInfoMgr;
State _state;
State _nextState;
State _stateBeforeInventory;
State _stateBeforePDA;
bool _isHaveItem;
};
class ParlSqPink : public LeadActor {
public:
void toConsole() const override;
protected:
WalkLocation *getWalkDestination() override;
};
class PubPink : public LeadActor {
public:
void toConsole() const override;
void onRightButtonClick(Common::Point point) override;
void onLeftClickMessage() override;
void onVariableSet() override;
protected:
void updateCursor(Common::Point point) override;
void sendUseClickMessage(Actor *actor) override;
WalkLocation *getWalkDestination() override;
private:
bool playingMiniGame();
};
} // End of namespace Pink
#endif

View 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.
*
* 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 "pink/constants.h"
#include "pink/cursor_mgr.h"
#include "pink/pink.h"
#include "pink/objects/pages/page.h"
#include "pink/objects/actors/pda_button_actor.h"
#include "pink/objects/actions/action_cel.h"
namespace Pink {
void PDAButtonActor::deserialize(Archive &archive) {
Actor::deserialize(archive);
_x = archive.readDWORD();
_y = archive.readDWORD();
_hideOnStop = (bool)archive.readDWORD();
_opaque = (bool)archive.readDWORD();
int type = archive.readDWORD();
assert(type != 0 && type != Command::kIncrementFrame && type != Command::kDecrementFrame);
if (_page->getGame()->isPeril()) {
_command.type = (Command::CommandType) type;
} else {
switch (type) {
case 1:
_command.type = Command::kGoToPage;
break;
case 2:
_command.type = Command::kClose;
break;
default:
_command.type = Command::kNull;
break;
}
}
_command.arg = archive.readString();
}
void PDAButtonActor::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "PDAButtonActor: _name = %s, _x = %u _y = %u _hideOnStop = %u, _opaque = %u, _commandType = %u, _arg = %s",
_name.c_str(), _x, _y, _hideOnStop, _opaque, (int)_command.type, _command.arg.c_str());
}
void PDAButtonActor::onLeftClickMessage() {
if (isActive()) {
_page->getGame()->getPdaMgr().execute(_command);
}
}
void PDAButtonActor::onMouseOver(Common::Point point, CursorMgr *mgr) {
if (_command.type == Command::kNull || !isActive())
mgr->setCursor(kPDADefaultCursor, point, Common::String());
else
mgr->setCursor(kPDAClickableFirstFrameCursor, point, Common::String());
}
bool PDAButtonActor::isActive() const {
return _action && _action->getName() != "Inactive";
}
void PDAButtonActor::init(bool paused) {
if (_x != -1 && _y != -1) {
for (uint i = 0; i < _actions.size(); ++i) {
ActionCEL *action = dynamic_cast<ActionCEL*>(_actions[i]);
assert(action);
action->loadDecoder();
Common::Point center;
center.x = _x + action->getDecoder()->getWidth() / 2;
center.y = _y + action->getDecoder()->getHeight() / 2;
action->setCenter(center);
}
}
Actor::init(paused);
}
} // End of namespace Pink

View File

@@ -0,0 +1,76 @@
/* 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 PINK_PDA_BUTTON_ACTOR_H
#define PINK_PDA_BUTTON_ACTOR_H
#include "pink/objects/actors/actor.h"
namespace Pink {
struct Command {
enum CommandType {
kGoToPage = 1,
kGoToPreviousPage,
kGoToDomain,
kGoToHelp, // won't be supported
kNavigateToDomain,
kIncrementCountry,
kDecrementCountry,
kIncrementDomain,
kDecrementDomain,
kClose,
kIncrementFrame, // not used
kDecrementFrame, // not used
kNull
};
CommandType type;
Common::String arg;
};
class PDAButtonActor : public Actor {
public:
void deserialize(Archive &archive) override;
void toConsole() const override;
void init(bool paused) override;
void onMouseOver(Common::Point point, CursorMgr *mgr) override;
void onLeftClickMessage() override;
private:
bool isActive() const;
Command _command;
int16 _x;
int16 _y;
bool _hideOnStop;
bool _opaque;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,94 @@
/* 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 "pink/pink.h"
#include "pink/utils.h"
#include "pink/constants.h"
#include "pink/cursor_mgr.h"
#include "pink/objects/inventory.h"
#include "pink/objects/actions/action.h"
#include "pink/objects/actors/supporting_actor.h"
namespace Pink {
void SupportingActor::deserialize(Archive &archive) {
Actor::deserialize(archive);
_location = archive.readString();
_pdaLink = archive.readString();
_cursor = archive.readString();
_handlerMgr.deserialize(archive);
}
void SupportingActor::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "SupportingActor: _name = %s, _location=%s, _pdaLink=%s, _cursor=%s",
_name.c_str(), _location.c_str(), _pdaLink.c_str(), _cursor.c_str());
for (uint i = 0; i < _actions.size(); ++i) {
_actions[i]->toConsole();
}
_handlerMgr.toConsole();
}
bool SupportingActor::isLeftClickHandlers() const {
return _handlerMgr.findSuitableHandlerLeftClick(this);
}
bool SupportingActor::isUseClickHandlers(InventoryItem *item) const {
return _handlerMgr.findSuitableHandlerUseClick(this, item->getName());
}
void SupportingActor::onMouseOver(Common::Point point, CursorMgr *mgr) {
if (isLeftClickHandlers()) {
if (!_cursor.empty())
mgr->setCursor(_cursor, point);
else
mgr->setCursor(kClickableFirstFrameCursor, point, Common::String());
} else
Actor::onMouseOver(point, mgr);
}
void SupportingActor::onMouseOverWithItem(Common::Point point, const Common::String &itemName, CursorMgr *cursorMgr) {
Common::String item = itemName;
if (_handlerMgr.findSuitableHandlerUseClick(this, itemName))
item += kClickable;
cursorMgr->setCursor(kHoldingItemCursor, point, item);
}
void SupportingActor::onTimerMessage() {
_handlerMgr.onTimerMessage(this);
}
void SupportingActor::onLeftClickMessage() {
_handlerMgr.onLeftClickMessage(this);
}
void SupportingActor::onUseClickMessage(InventoryItem *item, InventoryMgr *mgr) {
_handlerMgr.onUseClickMessage(this, item, mgr);
}
Common::String SupportingActor::getLocation() const {
return _location;
}
Common::String SupportingActor::getPDALink() const {
return _pdaLink;
}
} // End of namespace Pink

View File

@@ -0,0 +1,64 @@
/* 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 PINK_SUPPORTING_ACTOR_H
#define PINK_SUPPORTING_ACTOR_H
#include "pink/objects/actors/actor.h"
#include "pink/objects/handlers/handler_mgr.h"
namespace Pink {
class InventoryItem;
class InventoryMgr;
class SupportingActor : public Actor {
public:
void deserialize(Archive &archive) override;
void toConsole() const override;
bool isSupporting() const override { return true; }
bool isLeftClickHandlers() const override;
bool isUseClickHandlers(InventoryItem *item) const override;
void onMouseOver(Common::Point point, CursorMgr *mgr) override;
void onMouseOverWithItem(Common::Point point, const Common::String &itemName, CursorMgr *cursorMgr) override;
void onTimerMessage() override;
void onLeftClickMessage() override;
void onUseClickMessage(InventoryItem *item, InventoryMgr *mgr) override;
Common::String getPDALink() const override;
Common::String getLocation() const override;
private:
HandlerMgr _handlerMgr;
Common::String _location;
Common::String _pdaLink;
Common::String _cursor;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,100 @@
/* 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 "pink/archive.h"
#include "pink/pink.h"
#include "pink/objects/condition.h"
#include "pink/objects/actors/lead_actor.h"
#include "pink/objects/pages/game_page.h"
namespace Pink {
void ConditionVariable::deserialize(Archive &archive) {
_name = archive.readString();
_value = archive.readString();
}
bool ConditionGameVariable::evaluate(const Actor *actor) const {
return actor->getPage()->getModule()->getGame()->checkValueOfVariable(_name, _value);
}
void ConditionGameVariable::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\tConditionGameVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str());
}
bool ConditionModuleVariable::evaluate(const Actor *actor) const {
return actor->getPage()->getModule()->checkValueOfVariable(_name, _value);
}
void ConditionModuleVariable::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\tConditionModuleVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str());
}
bool ConditionNotModuleVariable::evaluate(const Actor *actor) const {
return !ConditionModuleVariable::evaluate(actor);
}
void ConditionNotModuleVariable::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\tConditionNotModuleVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str());
}
bool ConditionPageVariable::evaluate(const Actor *actor) const {
return actor->getPage()->checkValueOfVariable(_name, _value);
}
void ConditionPageVariable::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\tConditionPageVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str());
}
bool ConditionNotPageVariable::evaluate(const Actor *actor) const {
return !ConditionPageVariable::evaluate(actor);
}
void ConditionNotPageVariable::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\tConditionNotPageVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str());
}
void ConditionInventoryItemOwner::deserialize(Archive &archive) {
_item = archive.readString();
_owner = archive.readString();
}
bool ConditionInventoryItemOwner::evaluate(const Actor *actor) const {
InventoryMgr *mgr = actor->getInventoryMgr();
InventoryItem *item = mgr->findInventoryItem(_item);
if (item)
return item->getCurrentOwner() == _owner;
return false;
}
void ConditionInventoryItemOwner::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\tConditionInventoryItemOwner: _item=%s, _owner=%s", _item.c_str(), _owner.c_str());
}
bool ConditionNotInventoryItemOwner::evaluate(const Actor *actor) const {
return !ConditionInventoryItemOwner::evaluate(actor);
}
void ConditionNotInventoryItemOwner::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\tConditionNotInventoryItemOwner: _item=%s, _owner=%s", _item.c_str(), _owner.c_str());
}
} // End of namespace Pink

View File

@@ -0,0 +1,104 @@
/* 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 PINK_CONDITION_H
#define PINK_CONDITION_H
#include "pink/objects/object.h"
namespace Pink {
class Actor;
class Condition : public Object {
public:
void deserialize(Archive &archive) override = 0;
virtual bool evaluate(const Actor *actor) const = 0;
};
class ConditionVariable : public Condition {
public:
void deserialize(Archive &archive) override;
bool evaluate(const Actor *actor) const override = 0;
protected:
Common::String _name;
Common::String _value;
};
class ConditionGameVariable : public ConditionVariable {
public:
void toConsole() const override;
bool evaluate(const Actor *actor) const override;
};
/*
* It is not used in games and has evaluate method with infinity recursion
class ConditionNotGameVariable : public ConditionGameVariable {
virtual bool evaluate(LeadActor *leadActor);
};
*/
class ConditionModuleVariable : public ConditionVariable {
public:
void toConsole() const override;
bool evaluate(const Actor *actor) const override;
};
class ConditionNotModuleVariable : public ConditionModuleVariable {
public:
void toConsole() const override;
bool evaluate(const Actor *actor) const override;
};
class ConditionPageVariable : public ConditionVariable {
public:
void toConsole() const override;
bool evaluate(const Actor *actor) const override;
};
class ConditionNotPageVariable : public ConditionPageVariable {
public:
void toConsole() const override;
bool evaluate(const Actor *actor) const override;
};
class ConditionInventoryItemOwner : public Condition {
public:
void toConsole() const override;
void deserialize(Archive &archive) override;
bool evaluate(const Actor *actor) const override;
protected:
Common::String _item;
Common::String _owner;
};
class ConditionNotInventoryItemOwner : public ConditionInventoryItemOwner {
public:
void toConsole() const override;
bool evaluate(const Actor *actor) const override;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,178 @@
/* 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 "pink/archive.h"
#include "pink/pink.h"
#include "pink/objects/side_effect.h"
#include "pink/objects/condition.h"
#include "pink/objects/actors/actor.h"
#include "pink/objects/handlers/handler.h"
#include "pink/objects/pages/game_page.h"
#include "pink/objects/sequences/sequencer.h"
#include "pink/objects/sequences/sequence.h"
namespace Pink {
void Handler::deserialize(Archive &archive) {
_conditions.deserialize(archive);
_sideEffects.deserialize(archive);
}
bool Handler::isSuitable(const Actor *actor) const {
for (uint i = 0; i < _conditions.size(); ++i) {
if (!_conditions[i]->evaluate(actor))
return false;
}
return true;
}
void Handler::executeSideEffects(Actor *actor) {
for (uint i = 0; i < _sideEffects.size(); ++i) {
_sideEffects[i]->execute(actor);
}
}
void Handler::handle(Actor *actor) {
executeSideEffects(actor);
}
Handler::~Handler() {
for (uint i = 0; i < _sideEffects.size(); ++i) {
delete _sideEffects[i];
}
for (uint i = 0; i < _conditions.size(); ++i) {
delete _conditions[i];
}
}
void HandlerSequences::deserialize(Archive &archive) {
Handler::deserialize(archive);
_sequences.deserialize(archive);
}
void HandlerSequences::handle(Actor *actor) {
Handler::handle(actor);
Sequencer *sequencer = actor->getPage()->getSequencer();
assert(!_sequences.empty());
Common::RandomSource &rnd = actor->getPage()->getGame()->getRnd();
uint index = rnd.getRandomNumber(_sequences.size() - 1);
Sequence *sequence = sequencer->findSequence(_sequences[index]);
assert(sequence);
authorSequence(sequencer, sequence);
}
void HandlerSequences::authorSequence(Sequencer *sequencer, Sequence *sequence) {
sequencer->authorSequence(sequence, false);
}
void HandlerLeftClick::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "HandlerLeftClick:");
debugC(6, kPinkDebugLoadingObjects, "\tSideEffects:");
for (uint i = 0; i < _sideEffects.size(); ++i) {
_sideEffects[i]->toConsole();
}
debugC(6, kPinkDebugLoadingObjects, "\tConditions:");
for (uint i = 0; i < _conditions.size(); ++i) {
_conditions[i]->toConsole();
}
debugC(6, kPinkDebugLoadingObjects, "\tSequences:");
for (uint i = 0; i < _sequences.size(); ++i) {
debugC(6, kPinkDebugLoadingObjects, "\t\t%s", _sequences[i].c_str());
}
}
void HandlerUseClick::deserialize(Archive &archive) {
HandlerSequences::deserialize(archive);
_inventoryItem = archive.readString();
_recipient = archive.readString();
}
void HandlerUseClick::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "HandlerUseClick: _inventoryItem=%s, _recipient=%s", _inventoryItem.c_str(), _recipient.c_str());
debugC(6, kPinkDebugLoadingObjects, "\tSideEffects:");
for (uint i = 0; i < _sideEffects.size(); ++i) {
_sideEffects[i]->toConsole();
}
debugC(6, kPinkDebugLoadingObjects, "\tConditions:");
for (uint i = 0; i < _conditions.size(); ++i) {
_conditions[i]->toConsole();
}
debugC(6, kPinkDebugLoadingObjects, "\tSequences:");
for (uint i = 0; i < _sequences.size(); ++i) {
debugC(6, kPinkDebugLoadingObjects, "\t\t%s", _sequences[i].c_str());
}
}
void HandlerTimerActions::deserialize(Archive &archive) {
Handler::deserialize(archive);
_actions.deserialize(archive);
}
void HandlerTimerActions::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "HandlerTimerActions:");
debugC(6, kPinkDebugLoadingObjects, "\tSideEffects:");
for (uint i = 0; i < _sideEffects.size(); ++i) {
_sideEffects[i]->toConsole();
}
debugC(6, kPinkDebugLoadingObjects, "\tConditions:");
for (uint i = 0; i < _conditions.size(); ++i) {
_conditions[i]->toConsole();
}
debugC(6, kPinkDebugLoadingObjects, "\tActions:");
for (uint i = 0; i < _actions.size(); ++i) {
debugC(6, kPinkDebugLoadingObjects, "\t\t%s", _actions[i].c_str());
}
}
void HandlerTimerActions::handle(Actor *actor) {
Handler::handle(actor);
if (!actor->isPlaying() && !_actions.empty()) {
Common::RandomSource &rnd = actor->getPage()->getGame()->getRnd();
uint index = rnd.getRandomNumber(_actions.size() - 1);
Action *action = actor->findAction(_actions[index]);
assert(action);
actor->setAction(action);
}
}
void HandlerStartPage::authorSequence(Sequencer *sequencer, Sequence *sequence) {
HandlerSequences::authorSequence(sequencer, sequence);
sequence->allowSkipping();
}
void HandlerTimerSequences::authorSequence(Sequencer *sequencer, Sequence *sequence) {
sequencer->authorParallelSequence(sequence, false);
}
} // End of namespace Pink

View File

@@ -0,0 +1,103 @@
/* 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 PINK_HANDLER_H
#define PINK_HANDLER_H
#include "common/str-array.h"
#include "pink/objects/object.h"
namespace Pink {
class Condition;
class SideEffect;
class LeadActor;
class Actor;
class Handler : public Object {
public:
~Handler() override;
void deserialize(Archive &archive) override;
virtual void handle(Actor *actor);
bool isSuitable(const Actor *actor) const;
protected:
void executeSideEffects(Actor *actor);
Array<Condition *> _conditions;
Array<SideEffect *> _sideEffects;
};
class Sequence;
class Sequencer;
class HandlerSequences : public Handler {
public:
void deserialize(Archive &archive) override;
void handle(Actor *actor) override;
protected:
virtual void authorSequence(Sequencer *sequencer, Sequence *sequence);
protected:
StringArray _sequences;
};
class HandlerStartPage : public HandlerSequences {
void authorSequence(Sequencer *sequencer, Sequence *sequence) override;
};
class HandlerLeftClick : public HandlerSequences {
public:
void toConsole() const override;
};
class HandlerUseClick : public HandlerSequences {
public:
void deserialize(Archive &archive) override;
void toConsole() const override;
const Common::String &getInventoryItem() const { return _inventoryItem; }
const Common::String &getRecipient() const { return _recipient; }
private:
Common::String _inventoryItem;
Common::String _recipient;
};
class HandlerTimerActions : public Handler {
public:
void toConsole() const override;
void deserialize(Archive &archive) override;
void handle(Actor *actor) override;
private:
StringArray _actions;
};
class HandlerTimerSequences : public HandlerSequences {
void authorSequence(Sequencer *sequencer, Sequence *sequence) override;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,108 @@
/* 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 "pink/archive.h"
#include "pink/pink.h"
#include "pink/objects/inventory.h"
#include "pink/objects/handlers/handler.h"
#include "pink/objects/handlers/handler_mgr.h"
namespace Pink {
void HandlerMgr::deserialize(Archive &archive) {
_leftClickHandlers.deserialize(archive);
_useClickHandlers.deserialize(archive);
_timerHandlers.deserialize(archive);
}
void HandlerMgr::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "HandlerMgr:");
for (uint i = 0; i < _leftClickHandlers.size(); ++i) {
_leftClickHandlers[i]->toConsole();
}
for (uint i = 0; i < _useClickHandlers.size(); ++i) {
_useClickHandlers[i]->toConsole();
}
for (uint i = 0; i < _timerHandlers.size(); ++i) {
_timerHandlers[i]->toConsole();
}
}
void HandlerMgr::onTimerMessage(Actor *actor) {
Handler *handler = findSuitableHandlerTimer(actor);
if (handler)
handler->handle(actor);
}
void HandlerMgr::onLeftClickMessage(Actor *actor) {
Handler *handler = findSuitableHandlerLeftClick(actor);
assert(handler);
handler->handle(actor);
}
void HandlerMgr::onUseClickMessage(Actor *actor, InventoryItem *item, InventoryMgr *mgr) {
HandlerUseClick *handler = findSuitableHandlerUseClick(actor, item->getName());
assert(handler);
if (!handler->getRecipient().empty())
mgr->setItemOwner(handler->getRecipient(), item);
handler->handle(actor);
}
Handler *HandlerMgr::findSuitableHandlerTimer(const Actor *actor) {
for (uint i = 0; i < _timerHandlers.size(); ++i) {
if (_timerHandlers[i]->isSuitable(actor))
return _timerHandlers[i];
}
return nullptr;
}
HandlerLeftClick *HandlerMgr::findSuitableHandlerLeftClick(const Actor *actor) const {
for (uint i = 0; i < _leftClickHandlers.size(); ++i) {
if (_leftClickHandlers[i]->isSuitable(actor))
return _leftClickHandlers[i];
}
return nullptr;
}
HandlerUseClick *HandlerMgr::findSuitableHandlerUseClick(const Actor *actor, const Common::String &itemName) const {
for (uint i = 0; i < _useClickHandlers.size(); ++i) {
if (itemName == _useClickHandlers[i]->getInventoryItem() && _useClickHandlers[i]->isSuitable(actor))
return _useClickHandlers[i];
}
return nullptr;
}
HandlerMgr::~HandlerMgr() {
for (uint i = 0; i < _leftClickHandlers.size(); ++i) {
delete _leftClickHandlers[i];
}
for (uint j = 0; j < _useClickHandlers.size(); ++j) {
delete _useClickHandlers[j];
}
for (uint k = 0; k < _timerHandlers.size(); ++k) {
delete _timerHandlers[k];
}
}
} // End of namespace Pink

View 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.
*
* 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 PINK_HANDLER_MGR_H
#define PINK_HANDLER_MGR_H
#include "pink/objects/object.h"
namespace Pink {
class InventoryItem;
class InventoryMgr;
class Handler;
class HandlerLeftClick;
class HandlerUseClick;
class HandlerTimer;
class Actor;
class HandlerMgr : public Object {
public:
~HandlerMgr() override;
void deserialize(Archive &archive) override;
void toConsole() const override;
HandlerUseClick *findSuitableHandlerUseClick(const Actor *actor, const Common::String &itemName) const;
HandlerLeftClick *findSuitableHandlerLeftClick(const Actor *actor) const;
void onTimerMessage(Actor *actor);
void onLeftClickMessage(Actor *actor);
void onUseClickMessage(Actor *actor, InventoryItem *item, InventoryMgr *mgr);
private:
Handler *findSuitableHandlerTimer(const Actor *actor);
Array<HandlerLeftClick *> _leftClickHandlers;
Array<HandlerUseClick *> _useClickHandlers;
Array<Handler *> _timerHandlers;
};
}
#endif

View File

@@ -0,0 +1,222 @@
/* 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 "common/debug.h"
#include "pink/screen.h"
#include "pink/pink.h"
#include "pink/objects/inventory.h"
#include "pink/objects/actions/action.h"
#include "pink/objects/actors/lead_actor.h"
#include "pink/objects/pages/game_page.h"
namespace Pink {
InventoryMgr::InventoryMgr()
: _lead(nullptr), _window(nullptr), _itemActor(nullptr),
_rightArrow(nullptr), _leftArrow(nullptr), _currentItem(nullptr),
_state(kIdle), _isClickedOnItem(false) {}
void InventoryItem::deserialize(Archive &archive) {
NamedObject::deserialize(archive);
_initialOwner = archive.readString();
_currentOwner = _initialOwner;
}
void InventoryItem::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\tInventoryItem: _initialOwner=%s _currentOwner=%s", _initialOwner.c_str(), _currentOwner.c_str());
}
InventoryMgr::~InventoryMgr() {
for (uint i = 0; i < _items.size(); ++i) {
delete _items[i];
}
}
void InventoryMgr::deserialize(Archive &archive) {
_items.deserialize(archive);
}
InventoryItem *InventoryMgr::findInventoryItem(const Common::String &name) {
for (uint i = 0; i < _items.size(); ++i) {
if (_items[i]->getName() == name) {
return _items[i];
}
}
return nullptr;
}
void InventoryMgr::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "InventoryMgr:");
for (uint i = 0; i < _items.size(); ++i) {
_items[i]->toConsole();
}
}
bool InventoryMgr::isPinkOwnsAnyItems() {
if (_currentItem)
return true;
for (uint i = 0; i < _items.size(); ++i) {
if (_items[i]->getCurrentOwner() == _lead->getName()) {
_currentItem = _items[i];
return true;
}
}
return false;
}
void InventoryMgr::setItemOwner(const Common::String &owner, InventoryItem *item) {
if (owner == item->getCurrentOwner())
return;
if (item == _currentItem && _lead->getName() != owner)
_currentItem = nullptr;
else if (_lead->getName() == owner)
_currentItem = item;
item->_currentOwner = owner;
}
bool InventoryMgr::start(bool paused) {
if (!isPinkOwnsAnyItems())
return false;
_window = _lead->getPage()->findActor(kInventoryWindowActor);
_itemActor = _lead->getPage()->findActor(kInventoryItemActor);
_rightArrow = _lead->getPage()->findActor(kInventoryRightArrowActor);
_leftArrow = _lead->getPage()->findActor(kInventoryLeftArrowActor);
if (!paused) {
_window->setAction(kOpenAction);
_state = kOpening;
}
return true;
}
void InventoryMgr::update() {
if (_window->isPlaying())
return;
switch (_state) {
case kOpening:
_state = kReady;
_itemActor->setAction(_currentItem->getName());
_window->setAction(kShowAction);
_leftArrow->setAction(kShowAction);
_rightArrow->setAction(kShowAction);
break;
case kClosing:
_window->setAction(kIdleAction);
_lead->onInventoryClosed(_isClickedOnItem);
_state = kIdle;
_window = nullptr;
_itemActor = nullptr;
_isClickedOnItem = false;
break;
default:
break;
}
}
void InventoryMgr::onClick(Common::Point point) {
if (_state != kReady)
return;
Actor *actor = _lead->getActorByPoint(point);
if (actor == _itemActor || actor == _window) {
if (_itemActor->getAction()->getName() == "WBook") {
_lead->loadPDA("TOC");
return;
}
_isClickedOnItem = true;
close();
} else if (actor == _leftArrow) {
showNextItem(kLeft);
} else if (actor == _rightArrow) {
showNextItem(kRight);
} else
close();
}
void InventoryMgr::close() {
_state = kClosing;
_window->setAction(kCloseAction);
_itemActor->setAction(kIdleAction);
_leftArrow->setAction(kIdleAction);
_rightArrow->setAction(kIdleAction);
}
void InventoryMgr::showNextItem(bool direction) {
int index = 0;
for (uint i = 0; i < _items.size(); ++i) {
if (_currentItem == _items[i]) {
index = i + _items.size();
break;
}
}
for (uint i = 0; i < _items.size(); ++i) {
index = (direction == kLeft) ? index - 1 : index + 1;
if (_items[index % _items.size()]->getCurrentOwner() == _currentItem->getCurrentOwner()) {
_currentItem = _items[index % _items.size()];
_itemActor->setAction(_currentItem->getName());
break;
}
}
}
void InventoryMgr::loadState(Archive &archive) {
_state = (State)archive.readByte();
_isClickedOnItem = archive.readByte();
for (uint i = 0; i < _items.size(); ++i) {
_items[i]->_currentOwner = archive.readString();
}
const Common::String currItemName = archive.readString();
if (currItemName.empty()) {
_currentItem = nullptr;
_isClickedOnItem = 0;
} else {
_currentItem = findInventoryItem(currItemName);
}
}
void InventoryMgr::saveState(Archive &archive) {
archive.writeByte(_state);
archive.writeByte(_isClickedOnItem);
for (uint i = 0; i < _items.size(); ++i) {
archive.writeString(_items[i]->_currentOwner);
}
if (_currentItem)
archive.writeString(_currentItem->getName());
else
archive.writeString(Common::String());
}
} // End of namespace Pink

View 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/>.
*
*/
#ifndef PINK_INVENTORY_H
#define PINK_INVENTORY_H
#include "common/rect.h"
#include "pink/utils.h"
namespace Pink {
class InventoryItem : public NamedObject {
public:
void deserialize(Archive &archive) override;
void toConsole() const override;
const Common::String &getCurrentOwner() const { return _currentOwner; }
friend class InventoryMgr;
private:
Common::String _initialOwner;
Common::String _currentOwner;
};
class LeadActor;
class Actor;
class InventoryMgr : public Object {
public:
InventoryMgr();
~InventoryMgr() override;
void deserialize(Archive &archive) override;
void toConsole() const override;
void loadState(Archive &archive);
void saveState(Archive &archive);
void update();
void onClick(Common::Point point);
bool start(bool paused);
void setLeadActor(LeadActor *lead) { _lead = lead; }
InventoryItem *findInventoryItem(const Common::String &name);
bool isPinkOwnsAnyItems();
void setItemOwner(const Common::String &owner, InventoryItem *item);
InventoryItem *getCurrentItem() { return _currentItem; }
friend class Console;
private:
void close();
enum Direction {
kLeft = 0,
kRight = 1
};
void showNextItem(bool direction);
LeadActor *_lead;
Actor *_window;
Actor *_itemActor;
Actor *_rightArrow;
Actor *_leftArrow;
InventoryItem *_currentItem;
Array<InventoryItem *> _items;
enum State {
kIdle = 0,
kOpening = 1,
kReady = 2,
kClosing = 3
} _state;
bool _isClickedOnItem;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,111 @@
/* 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 "pink/pink.h"
#include "pink/objects/module.h"
#include "pink/objects/pages/game_page.h"
#include "pink/objects/actors/lead_actor.h"
namespace Pink {
ModuleProxy::ModuleProxy(const Common::String &name)
: NamedObject(name) {}
ModuleProxy::ModuleProxy() {}
Module::Module(PinkEngine *game, const Common::String &name)
: NamedObject(name), _game(game), _page(nullptr) {}
Module::~Module() {
for (uint i = 0; i < _pages.size(); ++i) {
delete _pages[i];
}
}
void Module::load(Archive &archive) {
archive.mapObject(this);
NamedObject::deserialize(archive);
archive.skipString(); // skip directory
_invMgr.deserialize(archive);
_pages.deserialize(archive);
}
void Module::init(bool isLoadingSave, const Common::String &pageName) {
// 0 0 - new game
// 0 1 - module changed
// 1 0 - from save
if (!pageName.empty())
_page = findPage(pageName);
if (!_page)
_page = _pages[0];
_page->init(isLoadingSave);
}
void Module::changePage(const Common::String &pageName) {
_page->unload();
_page = findPage(pageName);
_page->init(false);
}
GamePage *Module::findPage(const Common::String &pageName) const {
for (uint i = 0; i < _pages.size(); ++i) {
if (_pages[i]->getName() == pageName)
return _pages[i];
}
return nullptr;
}
bool Module::checkValueOfVariable(const Common::String &variable, const Common::String &value) const {
if (!_variables.contains(variable))
return value == kUndefinedValue;
return _variables[variable] == value;
}
void Module::loadState(Archive &archive) {
_invMgr.loadState(archive);
_variables.deserialize(archive);
for (uint i = 0; i < _pages.size(); ++i) {
_pages[i]->loadState(archive);
}
_page = findPage(archive.readString());
_page->loadManagers();
_page->getLeadActor()->loadState(archive);
}
void Module::saveState(Archive &archive) {
_invMgr.saveState(archive);
_variables.serialize(archive);
for (uint i = 0; i < _pages.size(); ++i) {
_pages[i]->saveState(archive);
}
archive.writeString(_page->getName());
_page->getLeadActor()->saveState(archive);
}
} // End of namespace Pink

View File

@@ -0,0 +1,80 @@
/* 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 PINK_MODULE_H
#define PINK_MODULE_H
#include "common/debug.h"
#include "common/hash-str.h"
#include "pink/archive.h"
#include "pink/objects/object.h"
#include "pink/objects/inventory.h"
namespace Pink {
class ModuleProxy : public NamedObject {
public:
ModuleProxy();
ModuleProxy(const Common::String &name);
};
class PinkEngine;
class GamePage;
class Module : public NamedObject {
public:
Module(PinkEngine *game, const Common::String &name);
~Module() override;
void loadState(Archive &archive);
void saveState(Archive &archive);
void load(Archive &archive) override;
void init(bool isLoadingSave, const Common::String &pageName);
void changePage(const Common::String &pageName);
PinkEngine *getGame() const { return _game; }
InventoryMgr *getInventoryMgr() { return &_invMgr; }
const InventoryMgr *getInventoryMgr() const { return &_invMgr; }
bool checkValueOfVariable(const Common::String &variable, const Common::String &value) const;
void setVariable(Common::String &variable, Common::String &value) { _variables[variable] = value; }
GamePage *getPage() { return _page; }
const GamePage *getPage() const { return _page; }
friend class Console;
private:
GamePage *findPage(const Common::String &pageName) const;
PinkEngine *_game;
GamePage *_page;
Array<GamePage *> _pages;
InventoryMgr _invMgr;
StringMap _variables;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,32 @@
/* 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 "pink/objects/object.h"
namespace Pink {
void Object::load(Archive &) {}
void Object::deserialize(Archive &) {}
void Object::toConsole() const {}
} // End of namespace Pink

View 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.
*
* 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 PINK_OBJECT_H
#define PINK_OBJECT_H
#include "common/str.h"
#include "pink/archive.h"
namespace Pink {
class Object {
public:
virtual ~Object() {};
virtual void load(Archive &);
virtual void deserialize(Archive &);
virtual void toConsole() const;
};
class NamedObject : public Object {
public:
NamedObject() {}
NamedObject(const Common::String &name)
: _name(name) {}
void deserialize(Archive &archive) override { _name = archive.readString(); }
const Common::String &getName() const { return _name; }
protected:
Common::String _name;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,201 @@
/* 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 "pink/cursor_mgr.h"
#include "pink/pink.h"
#include "pink/objects/actors/lead_actor.h"
#include "pink/objects/handlers/handler.h"
#include "pink/objects/pages/game_page.h"
#include "pink/objects/sequences/sequencer.h"
#include "pink/objects/walk/walk_mgr.h"
namespace Pink {
GamePage::GamePage()
: _module(nullptr), _cursorMgr(nullptr), _walkMgr(nullptr),
_sequencer(nullptr), _isLoaded(false), _memFile(nullptr) {}
GamePage::~GamePage() {
clear();
delete _memFile;
}
void GamePage::toConsole() const {
Page::toConsole();
_walkMgr->toConsole();
_sequencer->toConsole();
for (uint i = 0; i < _handlers.size(); ++i) {
_handlers[i]->toConsole();
}
}
void GamePage::deserialize(Archive &archive) {
Page::deserialize(archive);
_module = static_cast<Module *>(archive.readObject());
assert(dynamic_cast<Module *>(_module) != nullptr);
}
void GamePage::load(Archive &archive) {
debugC(6, kPinkDebugLoadingObjects, "GamePage load");
archive.mapObject(_cursorMgr);
archive.mapObject(_walkMgr);
archive.mapObject(_sequencer);
Page::load(archive);
_leadActor = static_cast<LeadActor *>(archive.readObject());
_walkMgr->deserialize(archive);
_sequencer->deserialize(archive);
_handlers.deserialize(archive);
}
void GamePage::init(bool isLoadingSave) {
if (!_isLoaded)
loadManagers();
toConsole();
initPalette();
LeadActor::State state = _leadActor->getState();
bool paused = (state == LeadActor::kInventory || state == LeadActor::kPDA);
for (uint i = 0; i < _actors.size(); ++i) {
_actors[i]->init(paused);
}
bool isHandler = false;
if (!isLoadingSave)
isHandler = initHandler();
_leadActor->start(isHandler);
}
bool GamePage::initHandler() {
for (uint i = 0; i < _handlers.size(); ++i) {
if (_handlers[i]->isSuitable(_leadActor)) {
_handlers[i]->handle(_leadActor);
return true;
}
}
return false;
}
void GamePage::loadManagers() {
_isLoaded = true;
_cursorMgr = new CursorMgr(_module->getGame(), this);
_walkMgr = new WalkMgr;
_sequencer = new Sequencer(this);
debugC(6, kPinkDebugGeneral, "ResMgr init");
_resMgr.init(_module->getGame(), this);
if (_memFile != nullptr) {
loadStateFromMem();
delete _memFile;
_memFile = nullptr;
}
}
bool GamePage::checkValueOfVariable(const Common::String &variable, const Common::String &value) const {
if (!_variables.contains(variable))
return value == kUndefinedValue;
return _variables[variable] == value;
}
void GamePage::setVariable(Common::String &variable, Common::String &value) {
_variables[variable] = value;
_leadActor->onVariableSet();
}
void GamePage::loadStateFromMem() {
Archive archive(static_cast<Common::SeekableReadStream *>(_memFile));
_variables.deserialize(archive);
for (uint i = 0; i < _actors.size(); ++i) {
_actors[i]->loadState(archive);
}
}
void GamePage::saveStateToMem() {
_memFile = new Common::MemoryReadWriteStream(DisposeAfterUse::YES);
Archive archive(static_cast<Common::WriteStream *>(_memFile));
_variables.serialize(archive);
for (uint i = 0; i < _actors.size(); ++i) {
_actors[i]->saveState(archive);
}
}
void GamePage::loadState(Archive &archive) {
uint size = archive.readDWORD();
if (size) {
_memFile = new Common::MemoryReadWriteStream(DisposeAfterUse::YES);
for (uint i = 0; i < size; ++i) {
_memFile->writeByte(archive.readByte());
}
}
}
void GamePage::saveState(Archive &archive) {
if (this == _module->getPage()) {
saveStateToMem();
archive.writeDWORD(_memFile->size());
archive.write(_memFile->getData(), _memFile->size());
delete _memFile;
_memFile = nullptr;
} else {
if (_memFile != nullptr) {
archive.writeDWORD(_memFile->size());
archive.write(_memFile->getData(), _memFile->size());
} else {
archive.writeDWORD(0);
}
}
}
void GamePage::unload() {
_leadActor->setAction(_leadActor->findAction(kIdleAction));
saveStateToMem();
clear();
_isLoaded = false;
}
void GamePage::clear() {
Page::clear();
_variables.clear(true);
for (uint i = 0; i < _handlers.size(); ++i) {
delete _handlers[i];
}
_handlers.clear();
delete _cursorMgr; _cursorMgr = nullptr;
delete _sequencer; _sequencer = nullptr;
delete _walkMgr; _walkMgr = nullptr;
}
} // End of namespace Pink

View 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.
*
* 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 PINK_GAME_PAGE_H
#define PINK_GAME_PAGE_H
#include "common/memstream.h"
#include "pink/objects/pages/page.h"
namespace Pink {
class CursorMgr;
class HandlerSequences;
class GamePage : public Page {
public:
GamePage();
~GamePage() override;
void toConsole() const override;
void deserialize(Archive &archive) override;
void loadState(Archive &archive);
void saveState(Archive &archive);
void load(Archive &archive) override;
void unload();
void loadManagers();
void init(bool isLoadingSave);
Sequencer *getSequencer() override { return _sequencer; }
WalkMgr *getWalkMgr() override { return _walkMgr; }
Module *getModule() override { return _module; }
const Module *getModule() const override { return _module; }
bool checkValueOfVariable(const Common::String &variable, const Common::String &value) const override;
void setVariable(Common::String &variable, Common::String &value) override;
void clear() override;
friend class Console;
private:
bool initHandler();
void loadStateFromMem();
void saveStateToMem();
bool _isLoaded;
Common::MemoryReadWriteStream *_memFile;
Module *_module;
CursorMgr *_cursorMgr;
WalkMgr *_walkMgr;
Sequencer *_sequencer;
Array<HandlerSequences *> _handlers;
StringMap _variables;
};
}
#endif

View File

@@ -0,0 +1,84 @@
/* 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 "pink/screen.h"
#include "pink/pink.h"
#include "pink/objects/actors/lead_actor.h"
#include "pink/objects/pages/page.h"
namespace Pink {
Page::~Page() {
clear();
}
void Page::load(Archive &archive) {
debugC(6, kPinkDebugLoadingObjects, "Page load");
archive.mapObject(this);
NamedObject::deserialize(archive);
archive.skipString(); //skip directory
_actors.deserialize(archive);
}
Actor *Page::findActor(const Common::String &name) {
for (uint i = 0; i < _actors.size(); ++i) {
if (_actors[i]->getName() == name) {
return _actors[i];
}
}
return nullptr;
}
void Page::toConsole() const {
for (uint i = 0; i < _actors.size(); ++i) {
_actors[i]->toConsole();
}
}
void Page::init() {
initPalette();
for (uint i = 0; i < _actors.size(); ++i) {
_actors[i]->init(false);
}
}
void Page::initPalette() {
for (uint i = 0; i < _actors.size(); ++i) {
if (_actors[i]->initPalette(getGame()->getScreen()))
break;
}
}
void Page::clear() {
for (uint i = 0; i < _actors.size(); ++i) {
delete _actors[i];
}
_actors.clear();
_resMgr.clear();
}
void Page::pause(bool paused) {
for (uint i = 0; i < _actors.size(); ++i) {
_actors[i]->pause(paused);
}
}
} // End of namespace Pink

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.
*
* 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 PINK_PAGE_H
#define PINK_PAGE_H
#include "pink/resource_mgr.h"
#include "pink/objects/module.h"
namespace Pink {
class Archive;
class Actor;
class LeadActor;
class WalkMgr;
class Sequencer;
class Page : public NamedObject {
public:
~Page() override;
void toConsole() const override;
void load(Archive &archive) override;
void init();
void initPalette();
Actor *findActor(const Common::String &name);
LeadActor *getLeadActor() { return _leadActor; }
Common::SeekableReadStream *getResourceStream(const Common::String &fileName) { return _resMgr.getResourceStream(fileName); }
virtual void clear();
void pause(bool paused);
PinkEngine *getGame() { return _resMgr.getGame(); }
virtual Sequencer *getSequencer() { return nullptr; }
virtual WalkMgr *getWalkMgr() { return nullptr; }
virtual Module *getModule() { return nullptr; }
virtual const Module *getModule() const { return nullptr; }
virtual bool checkValueOfVariable(const Common::String &variable, const Common::String &value) const { return 0; }
virtual void setVariable(Common::String &variable, Common::String &value) {}
protected:
Array<Actor *> _actors;
ResourceMgr _resMgr;
LeadActor *_leadActor;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,35 @@
/* 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 "pink/pda_mgr.h"
#include "pink/objects/actors/actor.h"
#include "pink/objects/pages/pda_page.h"
#include "pink/pink.h"
namespace Pink {
PDAPage::PDAPage(const Common::String& name, PinkEngine *vm) {
_name = name;
_resMgr.init(vm, this);
init();
}
} // End of namespace Pink

View File

@@ -0,0 +1,38 @@
/* 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 PINK_PDA_PAGE_H
#define PINK_PDA_PAGE_H
#include "pink/objects/pages/page.h"
namespace Pink {
class PDAMgr;
class PDAPage : public Page {
public:
PDAPage(const Common::String& name, PinkEngine* vm);
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,62 @@
/* 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 "common/debug.h"
#include "pink/archive.h"
#include "pink/pink.h"
#include "pink/objects/actors/supporting_actor.h"
#include "pink/objects/pages/game_page.h"
#include "pink/objects/sequences/seq_timer.h"
#include "pink/objects/sequences/sequencer.h"
namespace Pink {
SeqTimer::SeqTimer()
: _sequencer(nullptr), _updatesToMessage(0), _period(0),
_range(0) {}
void SeqTimer::deserialize(Archive &archive) {
_actor = archive.readString();
_period = archive.readDWORD();
_range = archive.readDWORD();
_sequencer = static_cast<Sequencer *>(archive.readObject());
}
void SeqTimer::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\tSeqTimer: _actor=%s _period=%u _range=%u", _actor.c_str(), _period, _range);
}
void SeqTimer::update() {
Page *page = _sequencer->getPage();
Common::RandomSource &rnd = page->getGame()->getRnd();
if (_updatesToMessage--)
return;
_updatesToMessage = _range ? _period + rnd.getRandomNumber(_range) : _period;
Actor *actor = page->findActor(_actor);
if (actor && !_sequencer->findState(_actor)) {
actor->onTimerMessage();
}
}
} // End of namespace Pink

View File

@@ -0,0 +1,50 @@
/* 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 PINK_SEQ_TIMER_H
#define PINK_SEQ_TIMER_H
#include "pink/objects/object.h"
namespace Pink {
class Sequencer;
class SeqTimer : public Object {
public:
SeqTimer();
void deserialize(Archive &archive) override;
void toConsole() const override;
void update();
private:
Common::String _actor;
Sequencer *_sequencer;
int _period;
int _range;
int _updatesToMessage;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,180 @@
/* 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 "common/debug.h"
#include "pink/archive.h"
#include "pink/pink.h"
#include "pink/sound.h"
#include "pink/objects/actors/actor.h"
#include "pink/objects/pages/game_page.h"
#include "pink/objects/sequences/sequence.h"
#include "pink/objects/sequences/sequence_context.h"
#include "pink/objects/sequences/sequencer.h"
namespace Pink {
Sequence::Sequence()
: _canBeSkipped(false), _context(nullptr),
_sequencer(nullptr) {}
Sequence::~Sequence() {
for (uint i = 0; i < _items.size(); ++i) {
delete _items[i];
}
}
void Sequence::deserialize(Archive &archive) {
NamedObject::deserialize(archive);
_sequencer = static_cast<Sequencer *>(archive.readObject());
_items.deserialize(archive);
}
void Sequence::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\tSequence %s", _name.c_str());
debugC(6, kPinkDebugLoadingObjects, "\t\t\tItems:");
for (uint i = 0; i < _items.size(); ++i) {
_items[i]->toConsole();
}
}
void Sequence::start(bool loadingSave) {
uint nextItemIndex = _context->getNextItemIndex();
if (nextItemIndex >= _items.size() ||
!_items[nextItemIndex]->execute(_context->getSegment(), this, loadingSave)) {
debugC(6, kPinkDebugScripts, "Sequence %s ended", _name.c_str());
end();
return;
}
uint i = nextItemIndex + 1;
while (i < _items.size()) {
if (_items[i]->isLeader()) {
break;
}
_items[i++]->execute(_context->getSegment(), this, loadingSave);
}
_context->execute(i, loadingSave);
}
void Sequence::update() {
if (!_context->getActor()->isPlaying()) {
debugC(6, kPinkDebugScripts, "SubSequence of %s Sequence ended", _name.c_str());
start(0);
}
}
void Sequence::end() {
_context->setActor(nullptr);
_canBeSkipped = 1;
_sequencer->removeContext(_context);
}
void Sequence::restart() {
_context->setNextItemIndex(0);
_context->clearDefaultActions();
start(0);
}
void Sequence::skip() {
if (_context->getNextItemIndex() >= _items.size())
return;
for (int i = _items.size() - 1; i >= 0; --i) {
if (_items[i]->isLeader()) {
_context->setNextItemIndex(i);
_context->clearDefaultActions();
for (int j = 0; j < i; ++j) {
_items[j]->skip(this);
}
start(0);
break;
}
}
}
void Sequence::skipSubSequence() {
if (_context->getNextItemIndex() < _items.size())
this->start(0);
}
void Sequence::forceEnd() {
skip();
end();
}
void Sequence::init(bool loadingSave) {
start(loadingSave);
}
void SequenceAudio::deserialize(Archive &archive) {
Sequence::deserialize(archive);
_soundName = archive.readString();
}
void SequenceAudio::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\tSequenceAudio %s : _sound = %s", _name.c_str(), _soundName.c_str());
debugC(6, kPinkDebugLoadingObjects, "\t\t\tItems:");
for (uint i = 0; i < _items.size(); ++i) {
_items[i]->toConsole();
}
}
void SequenceAudio::start(bool loadingSave) {
Sequence::start(loadingSave);
uint index = _context->getNextItemIndex();
if (index < _items.size()) {
_leader = (SequenceItemLeaderAudio *)_items[index];
} else {
_leader = nullptr;
}
}
void SequenceAudio::end() {
_sound.stop();
Sequence::end();
}
void SequenceAudio::update() {
if (!_sound.isPlaying())
end();
else if (_leader && _leader->getSample() <= _sound.getCurrentSample())
start(0);
}
void SequenceAudio::init(bool loadingSave) {
_leader = nullptr;
_sound.play(_sequencer->getPage()->getResourceStream(_soundName), Audio::Mixer::kMusicSoundType);
start(loadingSave);
}
void SequenceAudio::restart() {
_leader = nullptr;
_sound.play(_sequencer->getPage()->getResourceStream(_soundName), Audio::Mixer::kMusicSoundType);
Sequence::restart();
}
void SequenceAudio::skip() {
end();
}
} // End of namespace Pink

View File

@@ -0,0 +1,98 @@
/* 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 PINK_SEQUENCE_H
#define PINK_SEQUENCE_H
#include "pink/sound.h"
#include "pink/objects/sequences/sequence_item.h"
namespace Pink {
class Sequencer;
class SequenceItem;
class SequenceContext;
class Sequence : public NamedObject {
public:
Sequence();
~Sequence() override;
void deserialize(Archive &archive) override ;
void toConsole() const override;
public:
virtual void init(bool loadingSave);
virtual void start(bool loadingSave);
virtual void end();
virtual void restart();
void forceEnd();
virtual void update();
virtual void skipSubSequence();
virtual void skip();
void allowSkipping() { _canBeSkipped = true; }
bool isSkippingAllowed() { return _canBeSkipped; }
SequenceContext *getContext() const { return _context; }
Sequencer *getSequencer() const { return _sequencer; }
Common::Array<SequenceItem *> &getItems() { return _items; }
void setContext(SequenceContext *context) { _context = context; }
protected:
SequenceContext *_context;
Sequencer *_sequencer;
Array<SequenceItem *> _items;
bool _canBeSkipped;
};
class SequenceAudio : public Sequence {
public:
SequenceAudio()
: _leader(nullptr) {}
void deserialize(Archive &archive) override;
void toConsole() const override;
void init(bool loadingSave) override;
void start(bool loadingSave) override;
void end() override;
void update() override;
void restart() override;
void skipSubSequence() override {}
void skip() override;
private:
SequenceItemLeaderAudio *_leader;
Common::String _soundName;
Sound _sound;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,97 @@
/* 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 "common/debug.h"
#include "pink/pink.h"
#include "pink/objects/actors/actor.h"
#include "pink/objects/pages/game_page.h"
#include "pink/objects/sequences/sequence.h"
#include "pink/objects/sequences/sequence_context.h"
#include "pink/objects/sequences/sequencer.h"
namespace Pink {
void SequenceActorState::execute(uint segment, Sequence *sequence, bool loadingSave) const {
Actor *actor = sequence->getSequencer()->getPage()->findActor(this->actorName);
if (actor && _segment != segment && !defaultActionName.empty()) {
Action *action = actor->findAction(defaultActionName);
if (action && actor->getAction() != action) {
actor->setAction(action, loadingSave);
}
}
}
SequenceContext::SequenceContext(Sequence *sequence)
: _sequence(sequence), _nextItemIndex(0),
_segment(1), _actor(nullptr) {
sequence->setContext(this);
Common::Array<SequenceItem *> &items = sequence->getItems();
debug(kPinkDebugScripts, "SequenceContext for %s", _sequence->getName().c_str());
for (uint i = 0; i < items.size(); ++i) {
bool found = 0;
for (uint j = 0; j < _states.size(); ++j) {
if (items[i]->getActor() == _states[j].actorName) {
found = 1;
break;
}
}
if (!found) {
debug(kPinkDebugScripts, "%s", items[i]->getActor().c_str());
_states.push_back(SequenceActorState(items[i]->getActor()));
}
}
}
void SequenceContext::execute(uint nextItemIndex, bool loadingSave) {
for (uint j = 0; j < _states.size(); ++j) {
_states[j].execute(_segment, _sequence, loadingSave);
}
_nextItemIndex = nextItemIndex;
_segment++;
}
void SequenceContext::clearDefaultActions() {
for (uint i = 0; i < _states.size(); ++i) {
_states[i].defaultActionName.clear();
}
}
SequenceActorState *SequenceContext::findState(const Common::String &actor) {
for (uint i = 0; i < _states.size(); ++i) {
if (_states[i].actorName == actor)
return &_states[i];
}
return nullptr;
}
bool SequenceContext::isConflictingWith(SequenceContext *context) {
for (uint i = 0; i < _states.size(); ++i) {
if (context->findState(_states[i].actorName))
return true;
}
return false;
}
} // End of namespace Pink

View 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.
*
* 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 PINK_SEQUENCE_CONTEXT_H
#define PINK_SEQUENCE_CONTEXT_H
#include "common/array.h"
namespace Pink {
class Sequence;
class Sequencer;
struct SequenceActorState {
SequenceActorState(const Common::String &actor)
: actorName(actor), _segment(0) {}
void execute(uint segment, Sequence *sequence, bool loadingSave) const;
Common::String actorName;
Common::String defaultActionName;
uint _segment;
};
class Actor;
class SequenceContext {
public:
SequenceContext(Sequence *sequence);
void execute(uint nextItemIndex, bool loadingSave);
bool isConflictingWith(SequenceContext *context);
void clearDefaultActions();
SequenceActorState *findState(const Common::String &actor);
Sequence *getSequence() const { return _sequence; }
Actor *getActor() const { return _actor; }
uint getNextItemIndex() const { return _nextItemIndex; }
uint getSegment() const { return _segment; }
void setActor(Actor *actor) { _actor = actor; }
void setNextItemIndex(uint index) { _nextItemIndex = index; }
private:
Sequence *_sequence;
Actor *_actor;
Common::Array<SequenceActorState> _states;
uint _nextItemIndex;
uint _segment;
};
}
#endif

View File

@@ -0,0 +1,99 @@
/* 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 "common/debug.h"
#include "pink/archive.h"
#include "pink/pink.h"
#include "pink/objects/actions/action.h"
#include "pink/objects/actors/actor.h"
#include "pink/objects/pages/game_page.h"
#include "pink/objects/sequences/sequence_item.h"
#include "pink/objects/sequences/sequence.h"
#include "pink/objects/sequences/sequencer.h"
#include "pink/objects/sequences/sequence_context.h"
namespace Pink {
void SequenceItem::deserialize(Archive &archive) {
_actor = archive.readString();
_action = archive.readString();
}
void SequenceItem::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\t\t\tSequenceItem: _actor=%s, _action=%s", _actor.c_str(), _action.c_str());
}
bool SequenceItem::execute(uint segment, Sequence *sequence, bool loadingSave) {
Actor *actor = sequence->getSequencer()->getPage()->findActor(_actor);
Action *action;
if (!actor || !(action = actor->findAction(_action)))
return false;
actor->setAction(action, loadingSave);
SequenceContext *context = sequence->getContext();
SequenceActorState *state = context->findState(_actor);
if (state)
state->_segment = segment;
if (isLeader())
context->setActor(actor);
return true;
}
bool SequenceItem::isLeader() {
return false;
}
bool SequenceItemLeader::isLeader() {
return true;
}
void SequenceItemLeader::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\t\t\tSequenceItemLeader: _actor=%s, _action=%s", _actor.c_str(), _action.c_str());
}
void SequenceItemLeaderAudio::deserialize(Archive &archive) {
SequenceItem::deserialize(archive);
_sample = archive.readDWORD();
}
void SequenceItemLeaderAudio::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\t\t\tSequenceItemLeaderAudio: _actor=%s, _action=%s _sample=%d", _actor.c_str(), _action.c_str(), _sample);
}
bool SequenceItemDefaultAction::execute(uint segment, Sequence *sequence, bool loadingSave) {
SequenceActorState *state = sequence->getContext()->findState(_actor);
if (state)
state->defaultActionName = _action;
return true;
}
void SequenceItemDefaultAction::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\t\t\tSequenceItemDefaultAction: _actor=%s, _action=%s", _actor.c_str(), _action.c_str());
}
void SequenceItemDefaultAction::skip(Sequence *sequence) {
execute(0, sequence, 1);
}
} // End of namespace Pink

View 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.
*
* 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 PINK_SEQUENCE_ITEM_H
#define PINK_SEQUENCE_ITEM_H
#include "pink/objects/object.h"
namespace Pink {
class Sequence;
class SequenceItem : public Object {
public:
void deserialize(Archive &archive) override;
void toConsole() const override;
virtual bool execute(uint segment, Sequence *sequence, bool loadingSave);
virtual bool isLeader();
virtual void skip(Sequence *sequence) {};
const Common::String &getActor() const { return _actor; }
protected:
Common::String _actor;
Common::String _action;
};
class SequenceItemLeader : public SequenceItem {
public:
void toConsole() const override;
bool isLeader() override;
};
class SequenceItemLeaderAudio : public SequenceItemLeader {
public:
SequenceItemLeaderAudio()
: _sample(0) {}
void deserialize(Archive &archive) override;
void toConsole() const override;
uint32 getSample() { return _sample; }
private:
uint32 _sample;
};
class SequenceItemDefaultAction : public SequenceItem {
public:
void toConsole() const override;
bool execute(uint segment, Sequence *sequence, bool loadingSave) override;
void skip(Sequence *sequence) override;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,215 @@
/* 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 "common/debug.h"
#include "pink/archive.h"
#include "pink/pink.h"
#include "pink/objects/actors/lead_actor.h"
#include "pink/objects/pages/game_page.h"
#include "pink/objects/sequences/sequencer.h"
#include "pink/objects/sequences/sequence.h"
#include "pink/objects/sequences/sequence_context.h"
#include "pink/objects/sequences/seq_timer.h"
namespace Pink {
Sequencer::Sequencer(GamePage *page)
: _context(nullptr), _page(page), _time(0), _isSkipping(false) {}
Sequencer::~Sequencer() {
for (uint i = 0; i < _sequences.size(); ++i) {
delete _sequences[i];
}
for (uint i = 0; i < _timers.size(); ++i) {
delete _timers[i];
}
delete _context;
for (uint i = 0; i < _parallelContexts.size(); ++i) {
delete _parallelContexts[i];
}
}
void Sequencer::deserialize(Archive &archive) {
_sequences.deserialize(archive);
_timers.deserialize(archive);
}
Sequence *Sequencer::findSequence(const Common::String &name) {
for (uint i = 0; i < _sequences.size(); ++i) {
if (_sequences[i]->getName() == name)
return _sequences[i];
}
return nullptr;
}
void Sequencer::authorSequence(Sequence *sequence, bool loadingSave) {
if (_context)
_context->getSequence()->forceEnd();
if (sequence) {
SequenceContext *context = new SequenceContext(sequence);
SequenceContext *conflict;
while ((conflict = findConflictingContextWith(context)) != nullptr) {
conflict->getSequence()->forceEnd();
}
_context = context;
sequence->init(loadingSave);
debugC(5, kPinkDebugScripts, "Main Sequence %s started", sequence->getName().c_str());
}
}
void Sequencer::authorParallelSequence(Sequence *sequence, bool loadingSave) {
if (_context && _context->getSequence() == sequence)
return;
for (uint i = 0; i < _parallelContexts.size(); ++i) {
if (_parallelContexts[i]->getSequence() == sequence)
return;
}
const Common::String leadName = _page->getLeadActor()->getName();
SequenceContext *context = new SequenceContext(sequence);
if (!context->findState(leadName) && !findConflictingContextWith(context)) {
_parallelContexts.push_back(context);
sequence->init(loadingSave);
debugC(6, kPinkDebugScripts, "Parallel Sequence %s started", sequence->getName().c_str());
} else
delete context;
}
void Sequencer::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "Sequencer:");
for (uint i = 0; i < _sequences.size(); ++i) {
_sequences[i]->toConsole();
}
for (uint i = 0; i < _timers.size(); ++i) {
_timers[i]->toConsole();
}
}
void Sequencer::update() {
if (_context)
_context->getSequence()->update();
for (uint i = 0; i < _parallelContexts.size(); ++i) {
_parallelContexts[i]->getSequence()->update();
}
uint time = _page->getGame()->getTotalPlayTime();
if (time - _time > kTimersUpdateTime) {
_time = time;
for (uint i = 0; i < _timers.size(); ++i) {
_timers[i]->update();
}
}
}
void Sequencer::removeContext(SequenceContext *context) {
if (context == _context) {
delete _context;
_context = nullptr;
return;
}
for (uint i = 0; i < _parallelContexts.size(); ++i) {
if (context == _parallelContexts[i]) {
delete _parallelContexts[i];
_parallelContexts.remove_at(i);
break;
}
}
}
void Sequencer::skipSubSequence() {
if (_context) {
_isSkipping = true;
_context->getSequence()->skipSubSequence();
_isSkipping = false;
}
}
void Sequencer::restartSequence() {
if (_context) {
_isSkipping = true;
_context->getSequence()->restart();
_isSkipping = false;
}
}
void Sequencer::skipSequence() {
if (_context && _context->getSequence()->isSkippingAllowed()) {
_isSkipping = true;
_context->getSequence()->skip();
_isSkipping = false;
}
}
void Sequencer::loadState(Archive &archive) {
Sequence *sequence = findSequence(archive.readString());
authorSequence(sequence, 1);
uint size = archive.readWORD();
for (uint i = 0; i < size; ++i) {
sequence = findSequence(archive.readString());
authorParallelSequence(sequence, 1);
}
}
void Sequencer::saveState(Archive &archive) {
Common::String sequenceName;
if (_context)
sequenceName = _context->getSequence()->getName();
archive.writeString(sequenceName);
archive.writeWORD(_parallelContexts.size());
for (uint i = 0; i < _parallelContexts.size(); ++i) {
archive.writeString(_parallelContexts[i]->getSequence()->getName());
}
}
SequenceContext *Sequencer::findConflictingContextWith(SequenceContext *context) {
if (_context && _context->isConflictingWith(context)) {
return _context;
}
for (uint i = 0; i < _parallelContexts.size(); ++i) {
if (_parallelContexts[i]->isConflictingWith(context))
return _parallelContexts[i];
}
return nullptr;
}
SequenceActorState *Sequencer::findState(const Common::String &name) {
SequenceActorState *state = nullptr;
if (_context && (state = _context->findState(name)))
return state;
for (uint i = 0; i < _parallelContexts.size(); ++i) {
state = _parallelContexts[i]->findState(name);
if (state)
break;
}
return state;
}
} // End of namespace Pink

View File

@@ -0,0 +1,80 @@
/* 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 PINK_SEQUENCER_H
#define PINK_SEQUENCER_H
#include "pink/objects/object.h"
namespace Pink {
class Sequence;
class SequenceContext;
class GamePage;
class SeqTimer;
struct SequenceActorState;
class Sequencer : public Object {
public:
Sequencer(GamePage *page);
~Sequencer() override;
void toConsole() const override;
void deserialize(Archive &archive) override;
public:
void loadState(Archive &archive);
void saveState(Archive &archive);
bool isPlaying() { return _context != nullptr; }
bool isSkipping() { return _isSkipping; }
void update();
void authorSequence(Sequence *sequence, bool loadingSave);
void authorParallelSequence(Sequence *sequence, bool loadingSave);
void skipSubSequence();
void restartSequence();
void skipSequence();
void removeContext(SequenceContext *context);
SequenceContext *findConflictingContextWith(SequenceContext *context);
Sequence *findSequence(const Common::String &name);
SequenceActorState *findState(const Common::String &name);
GamePage *getPage() const { return _page; }
private:
SequenceContext *_context;
GamePage *_page;
Common::Array<SequenceContext *> _parallelContexts;
Array<Sequence *> _sequences;
Array<SeqTimer *> _timers;
uint _time;
bool _isSkipping;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,130 @@
/* 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 "common/hash-str.h"
#include "pink/archive.h"
#include "pink/pink.h"
#include "pink/objects/side_effect.h"
#include "pink/objects/actors/lead_actor.h"
#include "pink/objects/pages/game_page.h"
#include "pink/objects/walk/walk_location.h"
#include "pink/objects/walk/walk_mgr.h"
namespace Pink {
void SideEffectExit::deserialize(Archive &archive) {
_nextModule = archive.readString();
_nextPage = archive.readString();
}
void SideEffectExit::execute(Actor *actor) {
actor->getPage()->getLeadActor()->setNextExecutors(_nextModule, _nextPage);
}
void SideEffectExit::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\tSideEffectExit: _nextModule=%s, _nextPage=%s", _nextModule.c_str(), _nextPage.c_str());
}
void SideEffectLocation::deserialize(Archive &archive) {
_location = archive.readString();
}
void SideEffectLocation::execute(Actor *actor) {
WalkMgr *mgr = actor->getPage()->getWalkMgr();
WalkLocation *location = mgr->findLocation(_location);
if (location)
mgr->setCurrentWayPoint(location);
}
void SideEffectLocation::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\tSideEffectLocation: _location=%s", _location.c_str());
}
void SideEffectInventoryItemOwner::deserialize(Archive &archive) {
_item = archive.readString();
_owner = archive.readString();
}
void SideEffectInventoryItemOwner::execute(Actor *actor) {
InventoryMgr *mgr = actor->getInventoryMgr();
InventoryItem *item = mgr->findInventoryItem(_item);
mgr->setItemOwner(_owner, item);
}
void SideEffectInventoryItemOwner::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\tSideEffectInventoryItemOwner: _item=%s, _owner=%s", _item.c_str(), _owner.c_str());
}
void SideEffectVariable::deserialize(Pink::Archive &archive) {
_name = archive.readString();
_value = archive.readString();
}
void SideEffectGameVariable::execute(Actor *actor) {
actor->getPage()->getGame()->setVariable(_name, _value);
}
void SideEffectGameVariable::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\tSideEffectGameVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str());
}
void SideEffectModuleVariable::execute(Actor *actor) {
actor->getPage()->getModule()->setVariable(_name, _value);
}
void SideEffectModuleVariable::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\tSideEffectModuleVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str());
}
void SideEffectPageVariable::execute(Actor *actor) {
actor->getPage()->setVariable(_name, _value);
}
void SideEffectPageVariable::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\t\tSideEffectPageVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str());
}
void SideEffectRandomPageVariable::deserialize(Archive &archive) {
_name = archive.readString();
_values.deserialize(archive);
}
void SideEffectRandomPageVariable::execute(Actor *actor) {
assert(!_values.empty());
Common::RandomSource &rnd = actor->getPage()->getGame()->getRnd();
uint index = rnd.getRandomNumber(_values.size() - 1);
actor->getPage()->setVariable(_name, _values[index]);
}
void SideEffectRandomPageVariable::toConsole() const {
Common::String values("{");
for (uint i = 0; i < _values.size(); ++i) {
values += _values[i];
values += ',';
}
values += '}';
debugC(6, kPinkDebugLoadingObjects, "\t\tSideEffectRandomPageVariable: _name=%s, _values=%s", _name.c_str(), values.c_str());
}
} // End of namespace Pink

View File

@@ -0,0 +1,111 @@
/* 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 PINK_SIDE_EFFECT_H
#define PINK_SIDE_EFFECT_H
#include "pink/utils.h"
#include "pink/objects/object.h"
namespace Pink {
class Actor;
class SideEffect : public Object {
public:
void deserialize(Archive &archive) override = 0;
virtual void execute(Actor *actor) = 0;
};
class SideEffectExit : public SideEffect {
public:
void deserialize(Archive &archive) override;
void toConsole() const override;
void execute(Actor *actor) override;
private:
Common::String _nextModule;
Common::String _nextPage;
};
class SideEffectLocation : public SideEffect {
public:
void deserialize(Archive &archive) override;
void execute(Actor *actor) override;
void toConsole() const override;
private:
Common::String _location;
};
class SideEffectInventoryItemOwner : public SideEffect {
public:
void deserialize(Archive &archive) override;
void execute(Actor *actor) override;
void toConsole() const override;
private:
Common::String _item;
Common::String _owner;
};
class SideEffectVariable : public SideEffect {
public:
void deserialize(Archive &archive) override;
void execute(Actor *actor) override = 0;
protected:
Common::String _name;
Common::String _value;
};
class SideEffectGameVariable : public SideEffectVariable {
public:
void toConsole() const override;
void execute(Actor *actor) override;
};
class SideEffectModuleVariable : public SideEffectVariable {
public:
void toConsole() const override;
void execute(Actor *actor) override;
};
class SideEffectPageVariable : public SideEffectVariable {
public:
void toConsole() const override;
void execute(Actor *actor) override;
};
class SideEffectRandomPageVariable : public SideEffect {
public:
void deserialize(Archive &archive) override;
void toConsole() const override;
void execute(Actor *actor) override;
private:
Common::String _name;
StringArray _values;
};
} // End of namespace Pink
#endif

View 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.
*
* 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 "pink/archive.h"
#include "pink/pink.h"
#include "pink/objects/walk/walk_location.h"
namespace Pink {
void WalkLocation::deserialize(Pink::Archive &archive) {
NamedObject::deserialize(archive);
_neighbors.deserialize(archive);
}
void WalkLocation::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "\tWalkLocation: _name =%s", _name.c_str());
debugC(6, kPinkDebugLoadingObjects, "\tNeighbors:");
for (uint i = 0; i < _neighbors.size(); ++i) {
debugC(6, kPinkDebugLoadingObjects, "\t\t%s", _neighbors[i].c_str());
}
}
} // End of namespace Pink

View File

@@ -0,0 +1,40 @@
/* 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 PINK_WALK_LOCATION_H
#define PINK_WALK_LOCATION_H
#include "pink/utils.h"
namespace Pink {
class WalkLocation : public NamedObject {
public:
void deserialize(Archive &archive) override;
void toConsole() const override;
Common::StringArray &getNeigbors() { return _neighbors;}
private:
StringArray _neighbors;
};
} // End of namespace Pink
#endif

View 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.
*
* 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 "math/utils.h"
#include "pink/archive.h"
#include "pink/cel_decoder.h"
#include "pink/pink.h"
#include "pink/objects/actions/walk_action.h"
#include "pink/objects/actors/lead_actor.h"
#include "pink/objects/walk/walk_location.h"
namespace Pink {
WalkMgr::WalkMgr()
: _isWalking(false), _leadActor(nullptr),
_destination(nullptr) {}
WalkMgr::~WalkMgr() {
for (uint i = 0; i < _locations.size(); ++i) {
delete _locations[i];
}
}
void WalkMgr::deserialize(Pink::Archive &archive) {
_leadActor = static_cast<LeadActor *>(archive.readObject());
_locations.deserialize(archive);
}
WalkLocation *WalkMgr::findLocation(const Common::String &name) {
for (uint i = 0; i < _locations.size(); ++i) {
if (_locations[i]->getName() == name)
return _locations[i];
}
return nullptr;
}
void WalkMgr::toConsole() const {
debugC(6, kPinkDebugLoadingObjects, "WalkMgr:");
for (uint i = 0; i < _locations.size(); ++i) {
_locations[i]->toConsole();
}
}
void WalkMgr::start(WalkLocation *destination) {
if (_current.name.empty()) {
_current.name = _locations[0]->getName();
_current.coords = getLocationCoordinates(_locations[0]->getName());
}
_destination = destination;
if (_isWalking)
return;
if (_current.name == _destination->getName()) {
end();
} else {
_isWalking = true;
WalkLocation *currentLocation = findLocation(_current.name);
WalkShortestPath path(this);
WalkLocation *nextLocation = path.next(currentLocation, _destination);
initNextWayPoint(nextLocation);
_leadActor->setAction(getWalkAction());
}
}
void WalkMgr::initNextWayPoint(WalkLocation *location) {
_next.name = location->getName();
_next.coords = getLocationCoordinates(location->getName());
}
WalkAction *WalkMgr::getWalkAction() {
Common::String walkActionName;
bool horizontal = false;
if (_current.coords.z == _next.coords.z) {
if (_next.coords.point.x > _current.coords.point.x) {
walkActionName = Common::String::format("%dRight", _current.coords.z);
} else
walkActionName = Common::String::format("%dLeft", _next.coords.z);
horizontal = true;
} else
walkActionName = Common::String::format("%dTo%d", _current.coords.z, _next.coords.z);
WalkAction *action = (WalkAction *)_leadActor->findAction(walkActionName);
if (action) {
action->setWalkMgr(this);
action->setType(horizontal);
}
return action;
}
double WalkMgr::getLengthBetweenLocations(WalkLocation *first, WalkLocation *second) {
Coordinates firstCoord = getLocationCoordinates(first->getName());
Coordinates secondCoord = getLocationCoordinates(second->getName());
return Math::hypotenuse(secondCoord.point.x - firstCoord.point.x, secondCoord.point.y - firstCoord.point.y);
}
Coordinates WalkMgr::getLocationCoordinates(const Common::String &locationName) {
Action *action = _leadActor->findAction(locationName);
return action->getCoordinates();
}
void WalkMgr::setCurrentWayPoint(WalkLocation *location) {
_current.name = location->getName();
_current.coords = getLocationCoordinates(_current.name);
}
void WalkMgr::update() {
if (_leadActor->isPlaying())
return;
WalkShortestPath path(this);
_current = _next;
WalkLocation *next = path.next(findLocation(_current.name), _destination);
if (next) {
initNextWayPoint(next);
_leadActor->setAction(getWalkAction());
} else
end();
}
void WalkMgr::end() {
_isWalking = false;
_leadActor->onWalkEnd(_destination->getName());
}
void WalkMgr::loadState(Archive &archive) {
_isWalking = archive.readByte();
_current.name = archive.readString();
if (!_current.name.empty()) {
_current.coords = getLocationCoordinates(_current.name);
}
if (_isWalking) {
_next.name = archive.readString();
_destination = findLocation(archive.readString());
_next.coords = getLocationCoordinates(_next.name);
}
}
void WalkMgr::saveState(Archive &archive) {
archive.writeByte(_isWalking);
archive.writeString(_current.name);
if (_isWalking) {
archive.writeString(_next.name);
archive.writeString(_destination->getName());
}
}
void WalkMgr::skip() {
initNextWayPoint(_destination);
_current = _next;
end();
}
} // End of namespace Pink

View 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.
*
* 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 PINK_WALK_MGR_H
#define PINK_WALK_MGR_H
#include "common/rect.h"
#include "pink/objects/object.h"
#include "pink/objects/walk/walk_shortest_path.h"
#include "pink/utils.h"
namespace Pink {
class WalkLocation;
class LeadActor;
class WalkAction;
struct Coordinates {
Common::Point point;
int z;
};
class WalkMgr : public Object {
public:
WalkMgr();
~WalkMgr() override;
void deserialize(Archive &archive) override;
void toConsole() const override;
WalkLocation *findLocation(const Common::String &name);
void start(WalkLocation *destination);
void update();
double getLengthBetweenLocations(WalkLocation *first, WalkLocation *second);
void setCurrentWayPoint(WalkLocation *location);
void loadState(Archive &archive);
void saveState(Archive &archive);
void skip();
const Coordinates &getStartCoords() { return _current.coords; }
const Coordinates &getEndCoords() { return _next.coords; }
private:
struct WayPoint {
Common::String name;
Coordinates coords;
};
Coordinates getLocationCoordinates(const Common::String &locationName);
void end();
void initNextWayPoint(WalkLocation *location);
WalkAction *getWalkAction();
LeadActor *_leadActor;
WalkLocation *_destination;
Array<WalkLocation *> _locations;
WayPoint _current;
WayPoint _next;
bool _isWalking;
};
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,157 @@
/* 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 "pink/objects/walk/walk_location.h"
#include "pink/objects/walk/walk_mgr.h"
namespace Pink {
WalkShortestPath::WalkShortestPath(WalkMgr *manager)
: _manager(manager)
{}
WalkLocation *WalkShortestPath::next(WalkLocation *start, WalkLocation *destination) {
if (start == destination)
return nullptr;
add(start, 0.0, nullptr);
while (build() != destination) {}
return getNearestNeighbor(destination);
}
void WalkShortestPath::add(WalkLocation *wl, double val, WalkLocation *nearest) {
_locations.push_back(wl);
_visited.push_back(wl);
_weight.push_back(val);
_nearestNeigbor.push_back(nearest);
}
WalkLocation *WalkShortestPath::build() {
WalkLocation *nearest = nullptr;
WalkLocation *location = nullptr;
double len = -1.0;
addLocationsToVisit();
for (uint i = 0; i < _toVisit.size(); ++i) {
double curLen = getLengthToNearestNeigbor(_toVisit[i]);
if (curLen < 0) {
remove(_toVisit[i]);
continue;
}
curLen += getWeight(_toVisit[i]);
if (len < 0.0 || len > curLen) {
len = curLen;
location = _toVisit[i];
nearest = getNearestNeighbor(_toVisit[i]);
if (!nearest)
nearest = findNearestNeighbor(_toVisit[i]);
}
}
WalkLocation *neighbor = findNearestNeighbor(location);
if (neighbor)
add(neighbor, len, nearest);
return neighbor;
}
WalkLocation *WalkShortestPath::getNearestNeighbor(WalkLocation *location) {
for(uint i = 0; i < _visited.size(); ++i) {
if (_visited[i] == location)
return _nearestNeigbor[i];
}
return nullptr;
}
void WalkShortestPath::addLocationsToVisit() {
_toVisit.resize(_locations.size());
for (uint i = 0; i < _locations.size(); ++i) {
_toVisit[i] = _locations[i];
}
}
double WalkShortestPath::getLengthToNearestNeigbor(WalkLocation *location) {
double minLength = -1.0;
Common::StringArray &neighbors = location->getNeigbors();
for (uint i = 0; i < neighbors.size(); ++i) {
WalkLocation *neighbor = _manager->findLocation(neighbors[i]);
if (!isLocationVisited(neighbor)) {
double length = _manager->getLengthBetweenLocations(location, neighbor);
if (minLength >= 0.0) {
if (length < minLength)
minLength = length;
} else
minLength = length;
}
}
return minLength;
}
WalkLocation *WalkShortestPath::findNearestNeighbor(WalkLocation *location) {
double minLength = -1.0;
WalkLocation *nearest = nullptr;
Common::StringArray &neighbors = location->getNeigbors();
for (uint i = 0; i < neighbors.size(); ++i) {
WalkLocation *neighbor = _manager->findLocation(neighbors[i]);
if (!isLocationVisited(neighbor)) {
double length = _manager->getLengthBetweenLocations(location, neighbor);
if (minLength >= 0.0) {
if (length < minLength) {
nearest = neighbor;
minLength = length;
}
} else {
nearest = neighbor;
minLength = length;
}
}
}
return nearest;
}
double WalkShortestPath::getWeight(WalkLocation *location) {
for (uint i = 0; i < _locations.size(); ++i) {
if (_locations[i] == location)
return _weight[i];
}
return 0.0;
}
bool WalkShortestPath::isLocationVisited(WalkLocation *location) {
for (uint i = 0; i < _visited.size(); ++i) {
if (_visited[i] == location)
return true;
}
return false;
}
void WalkShortestPath::remove(WalkLocation *location) {
for (uint i = 0; i < _locations.size(); ++i) {
if (_locations[i] == location) {
_locations.remove_at(i);
_weight.remove_at(i);
break;
}
}
}
} // End of namespace Pink

View 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.
*
* 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 PINK_WALK_SHORTEST_PATH_H
#define PINK_WALK_SHORTEST_PATH_H
#include "common/array.h"
namespace Pink {
class WalkLocation;
class WalkMgr;
class WalkShortestPath {
public:
WalkShortestPath(WalkMgr *manager);
WalkLocation *next(WalkLocation *start, WalkLocation *destination);
private:
void add(WalkLocation *wl, double val, WalkLocation *nearest);
void remove(WalkLocation *location);
WalkLocation *build();
WalkLocation *getNearestNeighbor(WalkLocation *location);
WalkLocation *findNearestNeighbor(WalkLocation *location);
double getLengthToNearestNeigbor(WalkLocation *location);
double getWeight(WalkLocation *location);
void addLocationsToVisit();
bool isLocationVisited(WalkLocation *location);
WalkMgr *_manager;
Common::Array<WalkLocation *> _locations;
Common::Array<WalkLocation *> _toVisit;
Common::Array<double> _weight;
Common::Array<WalkLocation *> _visited;
Common::Array<WalkLocation *> _nearestNeigbor;
};
} // End of namespace Pink
#endif

264
engines/pink/pda_mgr.cpp Normal file
View File

@@ -0,0 +1,264 @@
/* 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 "pink/pda_mgr.h"
#include "pink/pink.h"
#include "pink/screen.h"
#include "pink/objects/actors/pda_button_actor.h"
#include "pink/objects/actors/lead_actor.h"
#include "pink/objects/pages/pda_page.h"
#include "pink/objects/actions/action_play_with_sfx.h"
namespace Pink {
static const char * const g_countries[] = {"BRI", "EGY", "BHU", "AUS", "IND", "CHI"};
static const char * const g_domains[] = {"NAT", "CLO", "HIS", "REL", "PLA", "ART", "FOO", "PEO"};
PDAMgr::PDAMgr(PinkEngine *game)
: _game(game), _lead(nullptr), _page(nullptr), _globalPage(nullptr),
_cursorMgr(game, nullptr), _countryIndex(0), _domainIndex(0),
_iteration(0), _handFrame(0), _leftHandAction(kLeft1) {}
PDAMgr::~PDAMgr() {
delete _globalPage;
delete _page;
}
void PDAMgr::saveState(Archive &archive) {
if (_page)
archive.writeString(_page->getName());
else
archive.writeString("");
}
void PDAMgr::execute(const Command &command) {
switch (command.type) {
case Command::kGoToPage:
goToPage(command.arg);
break;
case Command::kGoToPreviousPage:
assert(_previousPages.size() >= 2);
_previousPages.pop();
goToPage(_previousPages.pop());
break;
case Command::kGoToDomain:
goToPage(Common::String::format("%.6s", _page->getName().c_str()));
break;
case Command::kGoToHelp:
warning("Command GoToHelp is not supported and won't be");
break;
case Command::kNavigateToDomain:
goToPage(Common::String(g_countries[_countryIndex]) += g_domains[_domainIndex]);
break;
case Command::kIncrementCountry:
_countryIndex = (_countryIndex + 1) % 6;
updateWheels(1);
updateLocator();
break;
case Command::kDecrementCountry:
_countryIndex = (_countryIndex + 5) % 6;
updateWheels(1);
updateLocator();
break;
case Command::kIncrementDomain:
_domainIndex = (_domainIndex + 1) % 8;
updateWheels(1);
break;
case Command::kDecrementDomain:
_domainIndex = (_domainIndex + 7) % 8;
updateWheels(1);
break;
case Command::kClose:
close();
break;
default:
break;
}
}
void PDAMgr::goToPage(const Common::String pageName) {
if (_page && !_page->getName().compareToIgnoreCase(pageName))
return;
loadGlobal();
delete _page;
_page = new PDAPage(pageName, getGame());
_previousPages.push(_page->getName());
if (_game->isPeril())
initPerilButtons();
_cursorMgr.setPage(_page);
onMouseMove(_game->getEventManager()->getMousePos());
}
void PDAMgr::onLeftButtonClick(Common::Point point) {
Actor* rightHand = _globalPage->findActor(kRightHand);
if (rightHand)
static_cast<ActionStill*>(rightHand->getAction())->setFrame(1);
Actor *actor = _game->getScreen()->getActorByPoint(point);
if (actor)
actor->onLeftClickMessage();
}
void PDAMgr::onLeftButtonUp() {
Actor* rightHand = _globalPage->findActor(kRightHand);
if (rightHand)
static_cast<ActionStill*>(rightHand->getAction())->setFrame(0);
}
void PDAMgr::onMouseMove(Common::Point point) {
Actor *actor = _game->getScreen()->getActorByPoint(point);
if (actor && dynamic_cast<PDAButtonActor *>(actor))
actor->onMouseOver(point, &_cursorMgr);
else
_cursorMgr.setCursor(kPDADefaultCursor, point, Common::String());
if (!_game->isPeril())
return;
float k = (float)point.x / (480 - point.y);
Actor *leftHand = _globalPage->findActor(kLeftHand);
if (k > 0.5) {
if (k > 1) {
if (k > 1.5 && _leftHandAction != kLeft4) {
leftHand->setAction(kLeft4Name);
static_cast<ActionStill*>(leftHand->getAction())->setFrame(_handFrame + 1);
_leftHandAction = kLeft4;
} else if (_leftHandAction != kLeft3) {
leftHand->setAction(kLeft3Name);
static_cast<ActionStill*>(leftHand->getAction())->setFrame(_handFrame + 1);
_leftHandAction = kLeft3;
}
} else if (_leftHandAction != kLeft2) {
leftHand->setAction(kLeft2Name);
static_cast<ActionStill*>(leftHand->getAction())->setFrame(_handFrame + 1);
_leftHandAction = kLeft2;
}
} else if (_leftHandAction != kLeft1) {
leftHand->setAction(kLeft1Name);
static_cast<ActionStill*>(leftHand->getAction())->setFrame(_handFrame + 1);
_leftHandAction = kLeft1;
}
if (_iteration == 0) {
_handFrame = (_handFrame + 1) % 4;
static_cast<ActionStill*>(leftHand->getAction())->nextFrameLooped();
}
_iteration = (_iteration + 1) % 4;
}
void PDAMgr::close() {
if (!_globalPage)
return;
delete _globalPage;
delete _page;
_globalPage = nullptr;
_page = nullptr;
_lead->onPDAClose();
}
void PDAMgr::loadGlobal() {
if (_globalPage == nullptr) {
_globalPage = new PDAPage("GLOBAL", getGame());
}
}
void PDAMgr::initPerilButtons() {
Actor *prevPageButton = _globalPage->findActor(kPreviousPageButton);
if (_previousPages.size() < 2)
prevPageButton->setAction(kInactiveAction);
else
prevPageButton->setAction(kIdleAction);
Actor *navigatorButton = _globalPage->findActor(kNavigatorButton);
Actor *domainButton = _globalPage->findActor(kDomainButton);
if (isNavigate(_page->getName())) {
navigatorButton->setAction(kInactiveAction);
domainButton->setAction(kInactiveAction);
updateWheels();
} else {
calculateIndexes();
navigatorButton->setAction(kIdleAction);
if (isDomain(_page->getName()))
domainButton->setAction(kInactiveAction);
else
domainButton->setAction(kIdleAction);
}
updateLocator();
}
void PDAMgr::updateWheels(bool playSfx) {
Actor *wheel = _page->findActor(kCountryWheel);
if (playSfx && wheel->getAction()->getName() != g_countries[_countryIndex]) {
wheel->setAction(Common::String(g_countries[_countryIndex]) + kSfx);
static_cast<ActionPlayWithSfx*>(wheel->getAction())->update(); // hack
}
wheel->setAction(g_countries[_countryIndex]);
wheel = _page->findActor(kDomainWheel);
if (playSfx && wheel->getAction()->getName() != g_domains[_domainIndex]) {
wheel->setAction(Common::String(g_domains[_domainIndex]) + kSfx);
static_cast<ActionPlayWithSfx*>(wheel->getAction())->update(); // hack
}
wheel->setAction(g_domains[_domainIndex]);
}
bool PDAMgr::isNavigate(const Common::String &name) {
return !name.compareToIgnoreCase(kNavigatePage);
}
bool PDAMgr::isDomain(const Common::String &name) {
return name.size() == 6;
}
void PDAMgr::updateLocator() {
Actor *locator = _globalPage->findActor(kLocator);
if (locator)
locator->setAction(g_countries[_countryIndex]);
}
void PDAMgr::calculateIndexes() {
Common::String country = Common::String::format("%.3s", _page->getName().c_str());
for (uint i = 0; i < 6; ++i) {
if (country == g_countries[i]) {
_countryIndex = i;
break;
}
}
Common::String domain = _page->getName();
domain.erase(0, 3);
if (domain.size() >= 4)
domain.erase(3);
for (uint i = 0; i < 8; ++i) {
if (domain == g_domains[i]) {
_domainIndex = i;
break;
}
}
}
} // End of namespace Pink

97
engines/pink/pda_mgr.h Normal file
View File

@@ -0,0 +1,97 @@
/* 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 PINK_PDA_MGR_H
#define PINK_PDA_MGR_H
#include "common/stack.h"
#include "pink/cursor_mgr.h"
#include "pink/utils.h"
namespace Pink {
class PinkEngine;
class LeadActor;
class PDAPage;
struct Command;
class PDAMgr {
public:
PDAMgr(PinkEngine *game);
~PDAMgr();
void loadState(Archive &archive) { _savedPage = archive.readString(); }
void saveState(Archive &archive);
void execute(const Command &command);
void goToPage(const Common::String pageName);
void update() { _cursorMgr.update(); }
void close();
void onLeftButtonClick(Common::Point point);
void onLeftButtonUp();
void onMouseMove(Common::Point point);
PinkEngine *getGame() const { return _game; }
const Common::String &getSavedPageName() { return _savedPage; }
void setLead(LeadActor *lead) { _lead = lead; }
private:
void loadGlobal();
void initPerilButtons();
void updateWheels(bool playSfx = false);
void updateLocator();
void calculateIndexes();
static bool isNavigate(const Common::String &name);
static bool isDomain(const Common::String &name);
private:
PinkEngine *_game;
LeadActor *_lead;
PDAPage *_page;
PDAPage *_globalPage;
CursorMgr _cursorMgr;
Common::String _savedPage;
Common::Stack<Common::String> _previousPages;
byte _countryIndex;
byte _domainIndex;
byte _iteration;
byte _handFrame;
enum LeftHandAction {
kLeft1,
kLeft2,
kLeft3,
kLeft4
} _leftHandAction;
};
} // End of namespace Pink
#endif

327
engines/pink/pink.cpp Normal file
View File

@@ -0,0 +1,327 @@
/* 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 "common/debug-channels.h"
#include "common/formats/winexe_pe.h"
#include "common/config-manager.h"
#include "common/compression/installshield_cab.h"
#include "engines/advancedDetector.h"
#include "engines/util.h"
#include "graphics/cursorman.h"
#include "graphics/thumbnail.h"
#include "graphics/surface.h"
#include "graphics/wincursor.h"
#include "pink/pink.h"
#include "pink/console.h"
#include "pink/screen.h"
#include "pink/objects/module.h"
#include "pink/objects/actors/lead_actor.h"
namespace Pink {
Graphics::PaletteLookup *g_paletteLookup;
PinkEngine::PinkEngine(OSystem *system, const ADGameDescription *desc)
: Engine(system), _rnd("pink"), _exeResources(nullptr),
_desc(desc), _bro(nullptr), _menu(nullptr), _actor(nullptr),
_module(nullptr), _screen(nullptr), _pdaMgr(this) {
const Common::FSNode gameDataDir(ConfMan.getPath("path"));
SearchMan.addSubDirectoryMatching(gameDataDir, "install");
g_paletteLookup = new Graphics::PaletteLookup;
_isPeril = !strcmp(_desc->gameId, kPeril);
_isPerilDemo = _isPeril && (_desc->flags & ADGF_DEMO);
}
PinkEngine::~PinkEngine() {
delete _exeResources;
delete _bro;
_pdaMgr.close();
for (uint i = 0; i < _modules.size(); ++i) {
delete _modules[i];
}
for (uint j = 0; j < _cursors.size(); ++j) {
delete _cursors[j];
}
delete _screen;
delete g_paletteLookup;
}
Common::Error PinkEngine::init() {
debugC(10, kPinkDebugGeneral, "PinkEngine init");
initGraphics(640, 480);
_exeResources = new Common::PEResources();
Common::Path fileName = isPeril() ? "pptp.exe" : "hpp.exe";
if ((_desc->flags & GF_COMPRESSED) && isPeril()) {
fileName = "pptp.ex_";
Common::Archive *cabinet = Common::makeInstallShieldArchive("data");
if (!cabinet)
error("Failed to open the InstallShield cabinet");
SearchMan.add("data1.cab", cabinet);
}
if (!_exeResources->loadFromEXE(fileName)) {
return Common::kNoGameDataFoundError;
}
setDebugger(new Console(this));
_screen = new Screen(this);
initMenu();
Common::Path orbName;
Common::Path broName;
if (isPeril()) {
orbName = "PPTP.ORB";
broName = "PPTP.BRO";
_bro = new BroFile;
} else {
orbName = "HPP.ORB";
}
if (!_orb.open(orbName))
return Common::kNoGameDataFoundError;
if (_bro) {
if (!_bro->open(broName))
return Common::kNoGameDataFoundError;
if (_orb.getTimestamp() != _bro->getTimestamp()) {
warning("ORB and BRO timestamp mismatch. %x != %x", _orb.getTimestamp(), _bro->getTimestamp());
//return Common::kNoGameDataFoundError;
}
}
if (!loadCursors())
return Common::kNoGameDataFoundError;
setCursor(kLoadingCursor);
_orb.loadGame(this);
debugC(6, kPinkDebugGeneral, "Modules are loaded");
syncSoundSettings();
if (ConfMan.hasKey("save_slot"))
loadGameState(ConfMan.getInt("save_slot"));
else
initModule(_modules[0]->getName(), "", nullptr);
return Common::kNoError;
}
Common::Error Pink::PinkEngine::run() {
Common::Error error = init();
if (error.getCode() != Common::kNoError)
return error;
while (!shouldQuit()) {
Common::Event event;
while (_eventMan->pollEvent(event)) {
if (_screen->processEvent(event))
continue;
switch (event.type) {
case Common::EVENT_QUIT:
case Common::EVENT_RETURN_TO_LAUNCHER:
return Common::kNoError;
case Common::EVENT_MOUSEMOVE:
_actor->onMouseMove(event.mouse);
break;
case Common::EVENT_LBUTTONDOWN:
_actor->onLeftButtonClick(event.mouse);
break;
case Common::EVENT_LBUTTONUP:
_actor->onLeftButtonUp();
break;
case Common::EVENT_RBUTTONDOWN:
if (isPeril())
_actor->onRightButtonClick(event.mouse);
break;
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
_actor->onActionClick(event.customType);
break;
default:
break;
}
}
_actor->update();
_screen->update();
_system->delayMillis(10);
}
return Common::kNoError;
}
void PinkEngine::load(Archive &archive) {
archive.skipString();
archive.skipString();
_modules.deserialize(archive);
}
void PinkEngine::initModule(const Common::String &moduleName, const Common::String &pageName, Archive *saveFile) {
if (_module)
removeModule();
if (moduleName == _modules[0]->getName()) {
// new game
_variables.clear();
debugC(6, kPinkDebugGeneral, "Global Game Variables cleared");
}
addModule(moduleName);
if (saveFile)
_module->loadState(*saveFile);
debugC(6, kPinkDebugGeneral, "Module added");
_module->init(saveFile != nullptr, pageName);
}
void PinkEngine::changeScene() {
setCursor(kLoadingCursor);
_screen->clear();
if (!_nextModule.empty() && _nextModule != _module->getName())
initModule(_nextModule, _nextPage, nullptr);
else
_module->changePage(_nextPage);
}
void PinkEngine::addModule(const Common::String &moduleName) {
_module = new Module(this, moduleName);
_orb.loadObject(_module, _module->getName());
for (uint i = 0; i < _modules.size(); ++i) {
if (_modules[i]->getName() == moduleName) {
delete _modules[i];
_modules[i] = _module;
break;
}
}
}
void PinkEngine::removeModule() {
for (uint i = 0; i < _modules.size(); ++i) {
if (_module == _modules[i]) {
_pdaMgr.close();
_modules[i] = new ModuleProxy(Common::String(_module->getName()));
delete _module;
_module = nullptr;
break;
}
}
}
void PinkEngine::setVariable(Common::String &variable, Common::String &value) {
_variables[variable] = value;
}
bool PinkEngine::checkValueOfVariable(const Common::String &variable, const Common::String &value) const {
if (!_variables.contains(variable))
return value == kUndefinedValue;
return _variables[variable] == value;
}
bool PinkEngine::loadCursors() {
bool isPokus = !isPeril();
_cursors.reserve(kCursorsCount);
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPokusLoadingCursorID));
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPokusClickableFirstCursorID));
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPokusClickableSecondCursorID));
if (isPokus) {
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPokusClickableThirdCursorID));
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPokusNotClickableCursorID));
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPokusHoldingItemCursorID));
} else {
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPerilClickableThirdCursorID));
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPerilNotClickableCursorID));
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPerilHoldingItemCursorID));
}
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPokusPDADefaultCursorID));
if (isPokus) {
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPokusPDAClickableFirstFrameCursorID));
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPokusPDAClickableSecondFrameCursorID));
} else {
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPerilPDAClickableFirstFrameCursorID));
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPerilPDAClickableSecondFrameCursorID));
}
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPokusExitLeftCursorID));
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPokusExitRightCursorID));
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPokusExitForwardCursorID));
if (isPokus)
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(_exeResources, kPokusExitDownCursorID));
return true;
}
void PinkEngine::setCursor(uint cursorIndex) {
CursorMan.replaceCursor(_cursors[cursorIndex]->cursors[0].cursor);
CursorMan.showMouse(true);
}
bool PinkEngine::canLoadGameStateCurrently(Common::U32String *msg) {
return true;
}
bool PinkEngine::canSaveGameStateCurrently(Common::U32String *msg) {
return true;
}
bool PinkEngine::hasFeature(Engine::EngineFeature f) const {
return
f == kSupportsReturnToLauncher ||
f == kSupportsLoadingDuringRuntime ||
f == kSupportsSavingDuringRuntime ||
f == kSupportsChangingOptionsDuringRuntime;
}
void PinkEngine::pauseEngineIntern(bool pause) {
Engine::pauseEngineIntern(pause);
_screen->pause(pause);
}
bool PinkEngine::isPeril() const {
return _isPeril;
}
bool PinkEngine::isPerilDemo() const {
return _isPerilDemo;
}
}

198
engines/pink/pink.h Normal file
View File

@@ -0,0 +1,198 @@
/* 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 PINK_PINK_H
#define PINK_PINK_H
#include "common/random.h"
#include "common/savefile.h"
#include "engines/engine.h"
#include "engines/savestate.h"
#include "gui/debugger.h"
#include "pink/constants.h"
#include "pink/file.h"
#include "pink/utils.h"
#include "pink/pda_mgr.h"
/*
* This is the namespace of the Pink engine.
*
* Status of this engine: In Development
*
* Internal name of original engine: OxCart Runtime
*
* Games using this engine:
* - The Pink Panther: Passport to Peril
* - The Pink Panther: Hokus Pokus Pink
*
* Peril game status:
* Fully playable*
*
* Pokus game status:
* Fully Playable*
*
* Known bugs:
* PDA is partially usable(ActionText is not implemented)
*/
struct ADGameDescription;
namespace Common {
class PEResources;
}
namespace Graphics {
class MacMenu;
struct WinCursorGroup;
class PaletteLookup;
}
namespace Pink {
class Console;
class Screen;
class Archive;
class NamedObject;
class Module;
class Page;
class LeadActor;
enum {
kPinkDebugGeneral = 1,
kPinkDebugLoadingResources,
kPinkDebugLoadingObjects,
kPinkDebugScripts,
kPinkDebugActions,
};
enum {
GF_COMPRESSED = 1 << 0,
};
enum PINKActions {
kActionNone,
kActionSkipWalk,
kActionSkipWalkAndCancelInteraction,
kActionSkipSequence,
kActionSkipSubSequence,
kActionRestartSequence,
};
extern Graphics::PaletteLookup *g_paletteLookup;
class PinkEngine : public Engine {
public:
PinkEngine(OSystem *system, const ADGameDescription *desc);
~PinkEngine() override;
Common::Error run() override;
bool hasFeature(EngineFeature f) const override;
Common::Error loadGameState(int slot) override;
bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override;
Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override;
Common::String getSaveStateName(int slot) const override {
return Common::String::format("%s.s%02d", _targetName.c_str(), slot);
}
SaveStateList listSaves() const;
friend class Console;
protected:
void pauseEngineIntern(bool pause) override;
public:
void load(Archive &archive);
void changeScene();
bool isPeril() const;
bool isPerilDemo() const;
void setVariable(Common::String &variable, Common::String &value);
bool checkValueOfVariable(const Common::String &variable, const Common::String &value) const;
void executeMenuCommand(uint id);
bool executePageChangeCommand(uint id);
Common::Language getLanguage() const;
OrbFile *getOrb() { return &_orb; }
BroFile *getBro() { return _bro; }
Common::RandomSource &getRnd() { return _rnd; };
Screen *getScreen() { return _screen; }
PDAMgr &getPdaMgr() { return _pdaMgr; }
void setNextExecutors(const Common::String &nextModule, const Common::String &nextPage) { _nextModule = nextModule; _nextPage = nextPage; }
void setLeadActor(LeadActor *actor) { _actor = actor; };
void setCursor(uint cursorIndex);
private:
Common::Error init();
void initMenu();
bool loadCursors();
void initModule(const Common::String &moduleName, const Common::String &pageName, Archive *saveFile);
void addModule(const Common::String &moduleName);
void removeModule();
void openLocalWebPage(const Common::String &pageName) const;
private:
Common::RandomSource _rnd;
Common::Array<Graphics::WinCursorGroup *> _cursors;
Common::String _nextModule;
Common::String _nextPage;
Common::PEResources *_exeResources;
OrbFile _orb;
BroFile *_bro;
Graphics::MacMenu *_menu;
Screen *_screen;
LeadActor *_actor;
Module *_module;
Array<NamedObject *> _modules;
StringMap _variables;
PDAMgr _pdaMgr;
const ADGameDescription *_desc;
bool _isPeril;
bool _isPerilDemo;
};
WARN_UNUSED_RESULT bool readSaveHeader(Common::InSaveFile &in, SaveStateDescriptor &desc, bool skipThumbnail = true);
Common::String generateSaveName(int slot, const char *gameId);
} // End of namespace Pink
#endif

View File

@@ -0,0 +1,80 @@
/* 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 "pink/cel_decoder.h"
#include "pink/file.h"
#include "pink/pink.h"
#include "pink/resource_mgr.h"
#include "pink/sound.h"
#include "pink/objects/pages/game_page.h"
namespace Pink {
ResourceMgr::ResourceMgr()
: _game(nullptr), _resDescTable(nullptr), _resCount(0) {}
ResourceMgr::~ResourceMgr() {
clear();
}
void ResourceMgr::init(PinkEngine *game, Page *page) {
OrbFile *orb = game->getOrb();
_game = game;
ObjectDescription *objDesc = orb->getObjDesc(page->getName().c_str());
_resCount = objDesc->resourcesCount;
orb->loadObject(page, objDesc);
_resDescTable = orb->createResDescTable(objDesc);
debugC(kPinkDebugLoadingResources, "%d Resource descriptions are loaded", _resCount);
}
void ResourceMgr::clear() {
delete[] _resDescTable;
_resDescTable = nullptr;
}
static int resDescComp(const void *a, const void *b) {
return scumm_stricmp((const char *)a, (const char *)b);
}
Common::SeekableReadStream *ResourceMgr::getResourceStream(const Common::String &name) {
Common::SeekableReadStream *stream;
ResourceDescription *desc = (ResourceDescription *)bsearch(name.c_str(), _resDescTable, _resCount, sizeof(ResourceDescription), resDescComp);
if (desc->inBro)
stream = _game->getBro();
else
stream = _game->getOrb();
stream->seek(desc->offset);
byte *data = (byte *)malloc(desc->size);
stream->read(data, desc->size);
Common::MemoryReadStream *memstream = new Common::MemoryReadStream(data, desc->size, DisposeAfterUse::YES);
debugC(kPinkDebugLoadingResources, "Got stream of %s resource", name.c_str());
return memstream;
}
} // End of namespace Pink

View File

@@ -0,0 +1,60 @@
/* 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 PINK_RESOURCE_MGR_H
#define PINK_RESOURCE_MGR_H
#include "common/scummsys.h"
namespace Common {
class SafeSeekableSubReadStream;
class String;
}
namespace Pink {
class Page;
class PinkEngine;
struct ResourceDescription;
class ResourceMgr {
public:
ResourceMgr();
~ResourceMgr();
void init(PinkEngine *game, Page *page);
void clear();
Common::SeekableReadStream *getResourceStream(const Common::String &name);
PinkEngine *getGame() const { return _game; }
private:
PinkEngine *_game;
ResourceDescription *_resDescTable;
uint32 _resCount;
};
} // End of namespace Pink
#endif

117
engines/pink/saveload.cpp Normal file
View File

@@ -0,0 +1,117 @@
/* 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 "common/system.h"
#include "graphics/thumbnail.h"
#include "pink/pink.h"
#include "pink/objects/module.h"
namespace Pink {
Common::Error PinkEngine::loadGameState(int slot) {
Common::SeekableReadStream *in = _saveFileMan->openForLoading(generateSaveName(slot, _targetName.c_str()));
if (!in)
return Common::kNoGameDataFoundError;
SaveStateDescriptor desc;
if (!readSaveHeader(*in, desc))
return Common::kUnknownError;
Archive archive(in);
_variables.deserialize(archive);
_nextModule = archive.readString();
_nextPage = archive.readString();
initModule(archive.readString(), "", &archive);
setTotalPlayTime(desc.getPlayTimeMSecs());
delete in;
return Common::kNoError;
}
Common::Error PinkEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
Common::OutSaveFile *out = _saveFileMan->openForSaving(generateSaveName(slot, _targetName.c_str()));
if (!out)
return Common::kUnknownError;
Archive archive(out);
out->writeUint32BE(MKTAG('p', 'i', 'n', 'k'));
archive.writeString(desc);
TimeDate curTime;
_system->getTimeAndDate(curTime);
out->writeUint32LE(((curTime.tm_mday & 0xFF) << 24) | (((curTime.tm_mon + 1) & 0xFF) << 16) | ((curTime.tm_year + 1900) & 0xFFFF));
out->writeUint16LE(((curTime.tm_hour & 0xFF) << 8) | ((curTime.tm_min) & 0xFF));
out->writeUint32LE(getTotalPlayTime() / 1000);
if (!Graphics::saveThumbnail(*out))
return Common::kUnknownError;
_variables.serialize(archive);
archive.writeString(_nextModule);
archive.writeString(_nextPage);
archive.writeString(_module->getName());
_module->saveState(archive);
delete out;
return Common::kNoError;
}
Common::String generateSaveName(int slot, const char *gameId) {
return Common::String::format("%s.s%02d", gameId, slot);
}
WARN_UNUSED_RESULT bool readSaveHeader(Common::InSaveFile &in, SaveStateDescriptor &desc, bool skipThumbnail) {
if (in.readUint32BE() != MKTAG('p', 'i', 'n', 'k'))
return false;
const Common::String description = in.readPascalString();
uint32 date = in.readUint32LE();
uint16 time = in.readUint16LE();
uint32 playTime = in.readUint32LE();
Graphics::Surface *thumbnail = nullptr;
if (!Graphics::loadThumbnail(in, thumbnail, skipThumbnail))
return false;
int day = (date >> 24) & 0xFF;
int month = (date >> 16) & 0xFF;
int year = date & 0xFFFF;
int hour = (time >> 8) & 0xFF;
int minutes = time & 0xFF;
desc.setSaveDate(year, month, day);
desc.setSaveTime(hour, minutes);
desc.setPlayTime(playTime * 1000);
desc.setDescription(description);
desc.setThumbnail(thumbnail);
return true;
}
}

362
engines/pink/screen.cpp Normal file
View File

@@ -0,0 +1,362 @@
/* 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 "graphics/macgui/macfontmanager.h"
#include "graphics/macgui/mactext.h"
#include "graphics/paletteman.h"
#include "graphics/fonts/ttf.h"
#include "pink/pink.h"
#include "pink/cel_decoder.h"
#include "pink/screen.h"
#include "pink/objects/actions/action_sound.h"
#include "pink/objects/actions/action_cel.h"
#include "pink/objects/actions/action_text.h"
#include "pink/objects/actors/actor.h"
#include "graphics/macgui/macmenu.h"
namespace Pink {
enum {
kMenuHighLevel = -1,
kMenuAbout = 0,
kMenuGame = 1,
kMenuBOK = 2,
kMenuOnline = 3,
kMenuHelp = 4
};
enum {
kMenuActionAbout,
kMenuActionNewGame,
kMenuActionOpenSavedGame,
kMenuActionSaveGame,
kMenuActionSaveGameAs,
kMenuActionSongs,
kMenuActionSoundPreferences,
kMenuActionPause,
kMenuActionExit
};
/* Currently Unused
static const Graphics::MacMenuData menuSubItems[] = {
{ kMenuHighLevel, "Game", 0, 0, false },
{ kMenuHighLevel, "Book of Knowledge", 0, 0, false },
{ kMenuHighLevel, "Online", 0, 0, false },
{ kMenuHighLevel, "Help", 0, 0, false },
{ kMenuGame, "New Game", kMenuActionNewGame, 'N', false },
{ kMenuGame, "Open Saved Game...", kMenuActionOpenSavedGame, 'O', false },
{ kMenuGame, "Save Game", kMenuActionSaveGame, 'S', false },
{ kMenuGame, "Save Game As...", kMenuActionSaveGameAs, 0, false },
{ kMenuGame, NULL, 0, 0, false },
{ kMenuGame, "Songs", kMenuActionSongs, 0, false },
{ kMenuGame, NULL, 0, 0, false },
{ kMenuGame, "Sound Preferences...", kMenuActionSoundPreferences, 0, false },
{ kMenuGame, NULL, 0, 0, false },
{ kMenuGame, "Pause", kMenuActionPause, 'P', false },
{ kMenuGame, "Exit", kMenuActionExit, 'N', false },
{ 0, NULL, 0, 0, false }
};
*/
static void redrawCallback(void *ref) {
Screen *dir = (Screen *)ref;
if (dir->getWndManager().isMenuActive()) {
dir->addDirtyRect(Common::Rect(0, 0, 640, 480));
dir->draw(false);
}
}
Screen::Screen(PinkEngine *vm)
: _surface(640, 480), _textRendered(false) {
uint32 wmMode = Graphics::kWMModeNoDesktop | Graphics::kWMModeAutohideMenu
| Graphics::kWMModalMenuMode | Graphics::kWMModeForceBuiltinFonts
| Graphics::kWMModeUnicode | Graphics::kWMModeWin95;
if (vm->getLanguage() == Common::HE_ISR) // We do not have Hebrew font in MS fonts :(
wmMode |= Graphics::kWMModeForceMacFontsInWin95;
_wm = new Graphics::MacWindowManager(wmMode);
_wm->setScreen(&_surface);
_wm->setMenuHotzone(Common::Rect(0, 0, 640, 23));
_wm->setMenuDelay(250);
_wm->setEngineRedrawCallback(this, redrawCallback);
_textFont = nullptr;
_textFontCleanup = true;
#ifdef USE_FREETYPE2
if (vm->getLanguage() == Common::HE_ISR) {
_textFont = _wm->_fontMan->getFont(Graphics::MacFont(Graphics::kMacFontSystem, 12, Graphics::kMacFontRegular));
_textFontCleanup = false;
} else {
_textFont = Graphics::loadTTFFontFromArchive("system.ttf", 16);
}
#endif
if (!_textFont) {
_textFont = FontMan.getFontByUsage(Graphics::FontManager::kBigGUIFont);
warning("Director: falling back to built-in font");
_textFontCleanup = false;
}
}
Screen::~Screen() {
delete _wm;
if (_textFontCleanup)
delete _textFont;
}
void Screen::update() {
if (_wm->isMenuActive()) {
_wm->draw();
g_system->updateScreen();
return;
}
for (uint i = 0; i < _sounds.size(); ++i) {
_sounds[i]->update();
}
for (uint i = 0; i < _sprites.size(); ++i) {
if (_sprites[i]->needsUpdate())
_sprites[i]->update();
}
draw();
_wm->draw();
}
bool Screen::processEvent(Common::Event &event) {
return _wm->processEvent(event);
}
void Screen::setPalette(const byte *palette) {
g_system->getPaletteManager()->setPalette(palette, 0, 256);
_wm->passPalette(palette, 256);
}
void Screen::addTextAction(ActionText *txt) {
_textActions.push_back(txt);
_textRendered = false;
}
void Screen::removeTextAction(ActionText *action) {
for (uint i = 0; i < _textActions.size(); ++i) {
if (_textActions[i] == action) {
_textActions.remove_at(i);
break;
}
}
}
void Screen::addTextWindow(Graphics::MacTextWindow *window) {
_textWindows.push_back(window);
}
void Screen::removeTextWindow(Graphics::MacTextWindow *window) {
for (uint i = 0; i < _textWindows.size(); i++) {
if (_textWindows[i] == window) {
_textWindows.remove_at(i);
break;
}
}
}
void Screen::addSprite(ActionCEL *sprite) {
_sprites.push_back(sprite);
int i;
for (i = _sprites.size() - 1; i > 0 ; --i) {
if (sprite->getZ() < _sprites[i - 1]->getZ())
_sprites[i] = _sprites[i - 1];
else
break;
}
_sprites[i] = sprite;
}
void Screen::removeSprite(ActionCEL *sprite) {
for (uint i = 0; i < _sprites.size(); ++i) {
if (sprite == _sprites[i]) {
_sprites.remove_at(i);
break;
}
}
_dirtyRects.push_back(sprite->getBounds());
}
void Screen::removeSound(ActionSound *sound) {
for (uint i = 0; i < _sounds.size(); ++i) {
if (_sounds[i] == sound)
_sounds.remove_at(i);
}
}
void Screen::clear() {
_dirtyRects.push_back(Common::Rect(0, 0, 640, 480));
_sprites.resize(0);
draw();
}
void Screen::pause(bool pause_) {
if (!pause_) {
_dirtyRects.push_back(Common::Rect(0, 0, 640, 480));
}
for (uint i = 0; i < _sprites.size() ; ++i) {
_sprites[i]->pause(pause_);
}
}
bool Screen::isMenuActive() {
return _wm != nullptr && _wm->isMenuActive();
}
void Screen::saveStage() {
_savedSprites = _sprites;
clear();
}
void Screen::loadStage() {
assert(_sprites.empty());
_dirtyRects.push_back(Common::Rect(0, 0, 640, 480));
_sprites = _savedSprites;
_savedSprites.clear();
}
Actor *Screen::getActorByPoint(Common::Point point) {
for (int i = _sprites.size() - 1; i >= 0; --i) {
if (_sprites[i]->getActor()->isCursor())
continue;
CelDecoder *decoder = _sprites[i]->getDecoder();
const Graphics::Surface *frame = decoder->getCurrentFrame();
const Common::Rect &rect = _sprites[i]->getBounds();
if (rect.contains(point)) {
byte spritePixel = *(const byte *)frame->getBasePtr(point.x - rect.left, point.y - rect.top);
if (spritePixel != decoder->getTransparentColourIndex())
return _sprites[i]->getActor();
}
}
return nullptr;
}
void Screen::draw(bool blit) {
if (!_dirtyRects.empty() || !_textRendered) {
mergeDirtyRects();
for (uint i = 0; i < _dirtyRects.size(); ++i) {
drawRect(_dirtyRects[i]);
}
if (!_textRendered) {
_textRendered = true;
for (uint i = 0; i < _textActions.size(); ++i) {
_textActions[i]->draw(&_surface);
}
}
_dirtyRects.resize(0);
if (blit)
_surface.update();
} else
g_system->updateScreen();
}
void Screen::mergeDirtyRects() {
Common::Array<Common::Rect>::iterator rOuter, rInner;
for (rOuter = _dirtyRects.begin(); rOuter != _dirtyRects.end(); ++rOuter) {
rInner = rOuter;
while (++rInner != _dirtyRects.end()) {
if ((*rOuter).intersects(*rInner)) {
// These two rectangles overlap, so merge them
rOuter->extend(*rInner);
// remove the inner rect from the list
_dirtyRects.erase(rInner);
// move back to beginning of list
rInner = rOuter;
}
}
}
}
void Screen::addDirtyRect(const Common::Rect &rect) {
_dirtyRects.push_back(rect);
}
void Screen::addDirtyRects(ActionCEL *sprite) {
const Common::Rect spriteRect = sprite->getBounds();
const Common::List<Common::Rect> *dirtyRects = sprite->getDecoder()->getDirtyRects();
if (dirtyRects->size() > 100) {
_dirtyRects.push_back(spriteRect);
} else {
for (Common::List<Common::Rect>::const_iterator it = dirtyRects->begin(); it != dirtyRects->end(); ++it) {
Common::Rect dirtyRect = *it;
dirtyRect.translate(spriteRect.left, spriteRect.top);
_dirtyRects.push_back(dirtyRect);
}
}
sprite->getDecoder()->clearDirtyRects();
}
void Screen::drawRect(const Common::Rect &rect) {
_surface.fillRect(rect, 0);
for (uint i = 0; i < _sprites.size(); ++i) {
const Common::Rect &spriteRect = _sprites[i]->getBounds();
Common::Rect interRect = rect.findIntersectingRect(spriteRect);
if (interRect.isEmpty())
continue;
Common::Rect srcRect(interRect);
srcRect.translate(-spriteRect.left, -spriteRect.top);
_surface.transBlitFrom(*_sprites[i]->getDecoder()->getCurrentFrame(), srcRect, interRect, _sprites[i]->getDecoder()->getTransparentColourIndex());
}
// check the intersection with action text
for (uint i = 0; i < _textActions.size(); i++) {
const Common::Rect &textActionRect = _textActions[i]->getBound();
Common::Rect interRect = rect.findIntersectingRect(textActionRect);
if (interRect.isEmpty())
continue;
_textActions[i]->draw(&_surface);
}
// check the intersection with mactextwindow
for (uint i = 0; i < _textWindows.size(); i++) {
const Common::Rect &textWindowRect = _textWindows[i]->getDimensions();
Common::Rect interRect = rect.findIntersectingRect(textWindowRect);
if (interRect.isEmpty())
continue;
_textWindows[i]->draw(_wm->_screen, true);
}
}
} // End of namespace Pink

107
engines/pink/screen.h Normal file
View 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.
*
* 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 PINK_SCREEN_H
#define PINK_SCREEN_H
#include "common/array.h"
#include "common/rect.h"
#include "common/system.h"
#include "graphics/macgui/macwindowmanager.h"
#include "graphics/screen.h"
namespace Graphics {
class MacMenu;
}
namespace Pink {
class Actor;
class ActionCEL;
class ActionSound;
class ActionText;
class PinkEngine;
class Screen {
public:
Screen(PinkEngine *vm);
~Screen();
void update();
bool processEvent(Common::Event &event);
void setPalette(const byte *palette);
void addTextAction(ActionText *action);
void removeTextAction(ActionText *action);
void addSprite(ActionCEL *sprite);
void removeSprite(ActionCEL *sprite);
void addDirtyRect(const Common::Rect &rect);
void addDirtyRects(ActionCEL *sprite);
void addSound(ActionSound *sound) { _sounds.push_back(sound); };
void removeSound(ActionSound *sound);
void addTextWindow(Graphics::MacTextWindow *window);
void removeTextWindow(Graphics::MacTextWindow *window);
void clear();
void pause(bool pause);
bool isMenuActive();
void saveStage();
void loadStage();
Actor *getActorByPoint(Common::Point point);
Graphics::MacWindowManager &getWndManager() { return *_wm; };
void draw(bool blit = true);
const Graphics::Font *getTextFont() { return _textFont; }
private:
void mergeDirtyRects();
void drawRect(const Common::Rect &rect);
private:
Graphics::Screen _surface;
Graphics::MacWindowManager *_wm;
Common::Array<Common::Rect> _dirtyRects;
Common::Array<ActionCEL *> _sprites;
Common::Array<ActionCEL *> _savedSprites;
Common::Array<ActionSound *> _sounds;
Common::Array<ActionText *> _textActions;
Common::Array<Graphics::MacTextWindow *> _textWindows;
bool _textRendered;
const Graphics::Font *_textFont;
bool _textFontCleanup;
};
} // End of namespace Pink
#endif

Some files were not shown because too many files have changed in this diff Show More