mirror of
https://github.com/libretro/scummvm.git
synced 2025-01-22 10:17:22 +00:00
PINK: added basic cursor implementation, fixed sequenceAudio restarting and skipping, fixed various mem leaks, hopefully fixed finding of transparent color index.
This commit is contained in:
parent
e48ac17f68
commit
49d5ea28c0
@ -45,68 +45,10 @@
|
||||
#include <engines/pink/objects/actors/cursor_actor.h>
|
||||
#include <engines/pink/objects/handlers/handler_timer.h>
|
||||
#include <engines/pink/objects/actors/inventory_actor.h>
|
||||
#include "constants.h"
|
||||
|
||||
namespace Pink {
|
||||
|
||||
enum {
|
||||
kMaxClassLength = 32,
|
||||
kMaxStringLength = 64, // adjust
|
||||
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
|
||||
};
|
||||
|
||||
static const struct RuntimeClass {
|
||||
const char *name;
|
||||
int id;
|
||||
|
@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include <common/stream.h>
|
||||
#include <graphics/surface.h>
|
||||
#include "cel_decoder.h"
|
||||
|
||||
namespace Pink {
|
||||
@ -79,6 +80,18 @@ const Graphics::Surface *CelDecoder::getCurrentFrame() {
|
||||
return track->getCurrentFrame();
|
||||
}
|
||||
|
||||
Common::Point CelDecoder::getCenter() {
|
||||
CelVideoTrack *track = (CelVideoTrack*) getTrack(0);
|
||||
if (!track)
|
||||
return {0,0};
|
||||
return track->getCenter();
|
||||
}
|
||||
|
||||
Common::Rect &CelDecoder::getRectangle() {
|
||||
CelVideoTrack *track = (CelVideoTrack*) getTrack(0);
|
||||
return track->getRect();
|
||||
}
|
||||
|
||||
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();
|
||||
@ -100,33 +113,21 @@ void CelDecoder::CelVideoTrack::readPrefixChunk() {
|
||||
|
||||
switch (subchunkType) {
|
||||
case CEL_DATA:
|
||||
debug("%u", _fileStream->readUint16LE());
|
||||
_fileStream->readUint16LE();
|
||||
_center.x = _fileStream->readUint16LE();
|
||||
_center.y = _fileStream->readUint16LE();
|
||||
debug("stretch x: %u", _fileStream->readUint16LE());
|
||||
debug("stretch y: %u", _fileStream->readUint16LE());
|
||||
debug("rotation x: %u", _fileStream->readUint16LE());
|
||||
debug("rotation y: %u", _fileStream->readUint16LE());
|
||||
debug("rotation z: %u", _fileStream->readUint16LE());
|
||||
debug("current Frame: %u", _fileStream->readUint16LE());
|
||||
debug("next frame offset: %u",_fileStream->readUint32LE());
|
||||
debug("tcolor: %u", _transparentColourIndex = _fileStream->readUint16LE());
|
||||
for (int j = 0; j < 18; ++j) {
|
||||
debug("%u", _fileStream->readUint16LE());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
error("Unknown subchunk type");
|
||||
_fileStream->skip(subchunkSize - 6);
|
||||
break;
|
||||
}
|
||||
|
||||
_rect = Common::Rect::center(_center.x, _center.y, _surface->w, _surface->h);
|
||||
}
|
||||
|
||||
void CelDecoder::CelVideoTrack::readHeader() {
|
||||
_fileStream->readUint16LE(); // flags
|
||||
// Note: The normal delay is a 32-bit integer (dword), whereas the overridden delay is a 16-bit integer (word)
|
||||
// the frame delay is the FLIC "speed", in milliseconds.
|
||||
_fileStream->readUint16LE();
|
||||
|
||||
_frameDelay = _startFrameDelay = _fileStream->readUint32LE();
|
||||
|
||||
_fileStream->seek(80);
|
||||
@ -137,7 +138,6 @@ void CelDecoder::CelVideoTrack::readHeader() {
|
||||
readPrefixChunk();
|
||||
}
|
||||
|
||||
// Seek to the first frame
|
||||
_fileStream->seek(_offsetFrame1);
|
||||
}
|
||||
|
||||
@ -157,4 +157,42 @@ const Graphics::Surface *CelDecoder::CelVideoTrack::getCurrentFrame() {
|
||||
return _surface;
|
||||
}
|
||||
|
||||
Common::Point CelDecoder::CelVideoTrack::getCenter() {
|
||||
return _center;
|
||||
}
|
||||
|
||||
Common::Rect &CelDecoder::CelVideoTrack::getRect() {
|
||||
return _rect;
|
||||
}
|
||||
|
||||
#define FRAME_TYPE 0xF1FA
|
||||
|
||||
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;
|
||||
_fileStream->seek(_offsetFrame2);
|
||||
}
|
||||
|
||||
if (_curFrame == 0)
|
||||
_transparentColourIndex = *(byte*)_surface->getBasePtr(0,0);
|
||||
return _surface;
|
||||
}
|
||||
|
||||
} // End of namepsace Pink
|
@ -32,6 +32,9 @@ class CelDecoder : public Video::FlicDecoder {
|
||||
public:
|
||||
uint32 getX();
|
||||
uint32 getY();
|
||||
Common::Point getCenter();
|
||||
Common::Rect &getRectangle();
|
||||
|
||||
uint16 getTransparentColourIndex();
|
||||
const Graphics::Surface *getCurrentFrame();
|
||||
|
||||
@ -45,14 +48,19 @@ protected:
|
||||
|
||||
uint32 getX() const;
|
||||
uint32 getY() const;
|
||||
Common::Point getCenter();
|
||||
Common::Rect &getRect();
|
||||
|
||||
uint16 getTransparentColourIndex();
|
||||
const Graphics::Surface *getCurrentFrame();
|
||||
|
||||
private:
|
||||
const Graphics::Surface *decodeNextFrame();
|
||||
void readPrefixChunk();
|
||||
uint16 _transparentColourIndex;
|
||||
|
||||
Common::Point _center;
|
||||
Common::Rect _rect;
|
||||
byte _transparentColourIndex;
|
||||
};
|
||||
};
|
||||
|
||||
|
136
engines/pink/constants.h
Normal file
136
engines/pink/constants.h
Normal file
@ -0,0 +1,136 @@
|
||||
/* 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 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PINK_CONSTANTS_H
|
||||
#define PINK_CONSTANTS_H
|
||||
|
||||
namespace Pink {
|
||||
|
||||
enum {
|
||||
kMaxClassLength = 32,
|
||||
kMaxStringLength = 64,
|
||||
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 = 11
|
||||
};
|
||||
|
||||
enum {
|
||||
kLoadingCursor = 0,
|
||||
kExitForwardCursor = 1,
|
||||
kExitLeftCursor = 2,
|
||||
kExitRightCursor = 3,
|
||||
kDefaultCursor = 4,
|
||||
kClickableFirstFrameCursor = 5,
|
||||
kClickableSecondFrameCursor = 6,
|
||||
kNotClickableCursor = 7,
|
||||
kHoldingItemCursor = 8,
|
||||
kPDAFirstCursor = 9,
|
||||
kPDASecondCursor = 10
|
||||
};
|
||||
|
||||
|
||||
// values are from Hokus Pokus
|
||||
enum {
|
||||
kPokusLoadingCursorID = 135,
|
||||
kPokusExitForwardCursorID = 138,
|
||||
kPokusExitLeftCursorID = 133,
|
||||
kPokusExitRightCursorID = 134,
|
||||
kPokusClickableFirstCursorID = 137,
|
||||
kPokusClickableSecondCursorID = 136,
|
||||
kPokusClickableThirdCursorID = 145,
|
||||
kPokusNotClickableCursorID = 140,
|
||||
kPokusHoldingItemCursorID = 147,
|
||||
kPokusPDAFirstCursorID = 141,
|
||||
kPokusPDASecondCursorID = 144
|
||||
};
|
||||
|
||||
// from Peril
|
||||
// it contains cursors whose ids differ
|
||||
enum {
|
||||
kPerilClickableThirdCursorID = 140,
|
||||
kPerilNotClickableCursorID = 139,
|
||||
kPerilPDASecondCursorID = 142
|
||||
};
|
||||
|
||||
enum {
|
||||
kLoadingSave = 1,
|
||||
kLoadingNewGame = 0
|
||||
};
|
||||
|
||||
} // End of namespace Pink
|
||||
|
||||
#endif
|
@ -21,9 +21,57 @@
|
||||
*/
|
||||
|
||||
#include "cursor_mgr.h"
|
||||
#include "pink.h"
|
||||
|
||||
namespace Pink {
|
||||
|
||||
CursorMgr::CursorMgr(GamePage *page) : _page(page) {}
|
||||
CursorMgr::CursorMgr(PinkEngine *game, GamePage *page)
|
||||
: _actor(nullptr), _page(page), _game(game),
|
||||
_isPlayingAnimation(0), _firstFrameIndex(0)
|
||||
{}
|
||||
|
||||
CursorMgr::~CursorMgr() {}
|
||||
|
||||
void CursorMgr::setCursor(uint index, Common::Point point) {
|
||||
if (index == kClickableFirstFrameCursor) {
|
||||
if (!_isPlayingAnimation) {
|
||||
_isPlayingAnimation = 1;
|
||||
_time = _game->getTotalPlayTime();
|
||||
_firstFrameIndex = index;
|
||||
_isSecondFrame = 0;
|
||||
_game->setCursor(index);
|
||||
}
|
||||
}
|
||||
else {
|
||||
_isPlayingAnimation = 0;
|
||||
_game->setCursor(index);
|
||||
}
|
||||
}
|
||||
|
||||
void CursorMgr::update() {
|
||||
if (!_isPlayingAnimation)
|
||||
return;
|
||||
|
||||
uint newTime = _game->getTotalPlayTime();
|
||||
if (newTime - _time > 0xC8){
|
||||
_time = newTime;
|
||||
_isSecondFrame = !_isSecondFrame;
|
||||
_game->setCursor(_firstFrameIndex + _isSecondFrame);
|
||||
}
|
||||
}
|
||||
|
||||
void CursorMgr::setCursor(Common::String &cursorName, Common::Point point) {
|
||||
uint index;
|
||||
if (cursorName == "ExitLeft") {
|
||||
index = kExitLeftCursor;
|
||||
}
|
||||
else if (cursorName == "ExitRight"){
|
||||
index = kExitRightCursor;
|
||||
}
|
||||
else if (cursorName == "ExitForward")
|
||||
index = kExitForwardCursor;
|
||||
else assert(0);
|
||||
setCursor(index, point);
|
||||
}
|
||||
|
||||
} // End of namespace Pink
|
@ -23,21 +23,35 @@
|
||||
#ifndef PINK_CURSOR_MGR_H
|
||||
#define PINK_CURSOR_MGR_H
|
||||
|
||||
#include "engines/pink/objects/object.h"
|
||||
#include <graphics/wincursor.h>
|
||||
#include <engines/pink/objects/object.h>
|
||||
#include <common/rect.h>
|
||||
|
||||
namespace Pink {
|
||||
|
||||
|
||||
class Actor;
|
||||
class GamePage;
|
||||
class PinkEngine;
|
||||
|
||||
class CursorMgr : public Object {
|
||||
public:
|
||||
CursorMgr(GamePage *page);
|
||||
CursorMgr(PinkEngine *game, GamePage *page);
|
||||
~CursorMgr();
|
||||
|
||||
void update();
|
||||
void setCursor(uint index, Common::Point point);
|
||||
void setCursor(Common::String &cursorName, Common::Point point);
|
||||
|
||||
private:
|
||||
Actor *_actor;
|
||||
GamePage *_page;
|
||||
PinkEngine *_game;
|
||||
|
||||
uint _time;
|
||||
uint _firstFrameIndex;
|
||||
bool _isPlayingAnimation;
|
||||
bool _isSecondFrame;
|
||||
};
|
||||
|
||||
} // End of namespace Pink
|
||||
|
@ -33,6 +33,7 @@ static const ADGameDescription gameDescriptions[] = {
|
||||
0,{
|
||||
{"PPTP.ORB", NULL, NULL, -1},
|
||||
{"PPTP.BRO", NULL, NULL, -1},
|
||||
{"PPTP.EXE", NULL, NULL, -1},
|
||||
AD_LISTEND},
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformWindows,
|
||||
@ -41,8 +42,10 @@ static const ADGameDescription gameDescriptions[] = {
|
||||
},
|
||||
{
|
||||
"pokus",
|
||||
0,
|
||||
AD_ENTRY1s("hpp.ORB", NULL, -1),
|
||||
0, {
|
||||
{"HPP.orb", NULL, NULL, -1},
|
||||
{"hpp.exe", NULL, NULL, -1},
|
||||
AD_LISTEND},
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformWindows,
|
||||
ADGF_UNSTABLE,
|
||||
|
@ -32,28 +32,28 @@ Director::Director(OSystem *system)
|
||||
: _system(system), showBounds(0) {}
|
||||
|
||||
void Director::draw() {
|
||||
_system->fillScreen(0);
|
||||
for (int i = 0; i < _sprites.size(); ++i) {
|
||||
CelDecoder *decoder = _sprites[i]->getDecoder();
|
||||
drawSprite(decoder);
|
||||
drawSprite(_sprites[i]);
|
||||
}
|
||||
_system->updateScreen();
|
||||
}
|
||||
|
||||
void Director::drawSprite(CelDecoder *decoder) {
|
||||
void Director::drawSprite(ActionCEL *sprite) {
|
||||
CelDecoder *decoder = sprite->getDecoder();
|
||||
const Graphics::Surface *surface;
|
||||
if (decoder->needsUpdate())
|
||||
surface = decoder->decodeNextFrame();
|
||||
else surface = decoder->getCurrentFrame();
|
||||
|
||||
|
||||
|
||||
uint16 colourIndex = decoder->getTransparentColourIndex();
|
||||
if (!showBounds && colourIndex != 0) {
|
||||
if (!showBounds) {
|
||||
Graphics::Surface *screen = _system->lockScreen();
|
||||
|
||||
for (int y = 0; y < decoder->getHeight(); ++y) {
|
||||
for (int x = 0; x < decoder->getWidth(); ++x) {
|
||||
byte spritePixelColourIndex = *(byte*)surface->getBasePtr(x, y);
|
||||
if (spritePixelColourIndex != colourIndex && spritePixelColourIndex != 229) { // hack because sprite have wrong colour index
|
||||
uint16 spritePixelColourIndex = *(byte*)surface->getBasePtr(x, y);
|
||||
if (spritePixelColourIndex != decoder->getTransparentColourIndex()) {
|
||||
*(byte *) screen->getBasePtr(decoder->getX() + x, decoder->getY() + y) = spritePixelColourIndex;
|
||||
}
|
||||
}
|
||||
@ -115,4 +115,16 @@ void Director::clear() {
|
||||
_sprites.clear();
|
||||
}
|
||||
|
||||
Actor *Director::getActorByPoint(Common::Point point) {
|
||||
for (int i = _sprites.size() - 1; i > 0; --i) {
|
||||
CelDecoder *decoder = _sprites[i]->getDecoder();
|
||||
if (decoder->getRectangle().contains(point) &&
|
||||
*(byte*)decoder->getCurrentFrame()->getBasePtr(640 - point.x, 480 - point.y)
|
||||
!= decoder->getTransparentColourIndex())
|
||||
return _sprites[i]->getActor();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
@ -25,9 +25,11 @@
|
||||
|
||||
#include <common/array.h>
|
||||
#include <common/system.h>
|
||||
#include <common/rect.h>
|
||||
|
||||
namespace Pink {
|
||||
|
||||
class Actor;
|
||||
class ActionCEL;
|
||||
class ActionSound;
|
||||
class CelDecoder;
|
||||
@ -49,10 +51,11 @@ public:
|
||||
|
||||
void clear();
|
||||
|
||||
Actor *getActorByPoint(Common::Point point);
|
||||
bool showBounds;
|
||||
|
||||
private:
|
||||
void drawSprite(CelDecoder *decoder);
|
||||
void drawSprite(ActionCEL *sprite);
|
||||
OSystem *_system;
|
||||
Common::Array<ActionCEL*> _sprites;
|
||||
Common::Array<ActionSound*> _sounds;
|
||||
|
@ -40,6 +40,8 @@ public:
|
||||
|
||||
virtual bool initPalette(Director *director) { return 0;}
|
||||
|
||||
Actor *getActor() { return _actor;}
|
||||
|
||||
protected:
|
||||
Actor *_actor;
|
||||
};
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include <common/debug.h>
|
||||
#include "action_cel.h"
|
||||
#include <pink/objects/actors/actor.h>
|
||||
#include <graphics/surface.h>
|
||||
#include "engines/pink/archive.h"
|
||||
#include "engines/pink/objects/pages/game_page.h"
|
||||
#include "pink/pink.h"
|
||||
@ -44,6 +45,7 @@ void ActionCEL::start(bool unk) {
|
||||
if (!_decoder)
|
||||
_decoder = _actor->getPage()->loadCel(_fileName);
|
||||
_actor->getPage()->getGame()->getDirector()->addSprite(this);
|
||||
|
||||
this->onStart();
|
||||
}
|
||||
|
||||
|
@ -55,7 +55,7 @@ void ActionLoop::update() {
|
||||
// for now it supports only forward loop animation
|
||||
if (_style == kForward) {
|
||||
if (_decoder->endOfVideo()){
|
||||
debug("ACTION LOOP : NEXT ITERATION");
|
||||
//debug("ACTION LOOP : NEXT ITERATION");
|
||||
_decoder->rewind();
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +93,8 @@ void ActionSfx::play(GamePage *page) {
|
||||
if (!_sound)
|
||||
_sound = page->loadSound(_sfxName);
|
||||
|
||||
_sound->play(Audio::Mixer::SoundType::kSFXSoundType, _volume, 0);
|
||||
if (!_sound->isPlaying())
|
||||
_sound->play(Audio::Mixer::SoundType::kSFXSoundType, _volume, 0);
|
||||
}
|
||||
|
||||
ActionSfx::~ActionSfx() {
|
||||
|
@ -31,12 +31,11 @@ namespace Pink {
|
||||
class ActionSfx;
|
||||
|
||||
class ActionPlayWithSfx : public ActionPlay {
|
||||
public:
|
||||
virtual ~ActionPlayWithSfx();
|
||||
virtual void deserialize(Archive &archive);
|
||||
virtual void toConsole();
|
||||
virtual void update();
|
||||
|
||||
public:
|
||||
virtual void end();
|
||||
|
||||
protected:
|
||||
|
@ -20,10 +20,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <engines/pink/constants.h>
|
||||
#include "actor.h"
|
||||
#include "engines/pink/objects/pages/game_page.h"
|
||||
#include "lead_actor.h"
|
||||
#include "engines/pink/objects/actions/action.h"
|
||||
#include "pink/cursor_mgr.h"
|
||||
|
||||
namespace Pink {
|
||||
|
||||
@ -122,4 +124,14 @@ bool Actor::initPallete(Director *director) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Actor::onMouseOver(Common::Point point, CursorMgr *mgr) {
|
||||
mgr->setCursor(kDefaultCursor, point);
|
||||
}
|
||||
|
||||
Actor::~Actor() {
|
||||
for (int i = 0; i < _actions.size(); ++i) {
|
||||
delete _actions[i];
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Pink
|
||||
|
@ -24,6 +24,7 @@
|
||||
#define PINK_ACTOR_H
|
||||
|
||||
#include <common/array.h>
|
||||
#include <common/rect.h>
|
||||
#include "engines/pink/objects/object.h"
|
||||
|
||||
namespace Pink {
|
||||
@ -32,6 +33,7 @@ class GamePage;
|
||||
class Action;
|
||||
class Sequencer;
|
||||
class Director;
|
||||
class CursorMgr;
|
||||
|
||||
class Actor : public NamedObject {
|
||||
public:
|
||||
@ -39,6 +41,7 @@ public:
|
||||
: _page(nullptr), _action(nullptr),
|
||||
_isActionEnded(1)
|
||||
{};
|
||||
~Actor();
|
||||
virtual void deserialize(Archive &archive);
|
||||
|
||||
virtual void toConsole();
|
||||
@ -61,6 +64,9 @@ public:
|
||||
|
||||
virtual void update() {};
|
||||
|
||||
virtual void onMouseOver(Common::Point point, CursorMgr *mgr);
|
||||
|
||||
virtual bool isClickable() { return 0;}
|
||||
protected:
|
||||
GamePage *_page;
|
||||
Action *_action;
|
||||
|
@ -29,13 +29,13 @@
|
||||
#include "engines/pink/archive.h"
|
||||
#include "engines/pink/objects/pages/game_page.h"
|
||||
#include "engines/pink/pink.h"
|
||||
#include "supporting_actor.h"
|
||||
|
||||
namespace Pink {
|
||||
|
||||
void LeadActor::deserialize(Archive &archive) {
|
||||
_state = kReady;
|
||||
Actor::deserialize(archive);
|
||||
_state = kReady;
|
||||
_cursorMgr = static_cast<CursorMgr*>(archive.readObject());
|
||||
_walkMgr = static_cast<WalkMgr*>(archive.readObject());
|
||||
_sequencer = static_cast<Sequencer*>(archive.readObject());
|
||||
@ -70,18 +70,36 @@ LeadActor::State LeadActor::getState() const {
|
||||
|
||||
void LeadActor::update() {
|
||||
switch (_state) {
|
||||
case kReady:
|
||||
|
||||
_sequencer->update();
|
||||
//fall-through intended
|
||||
case kMoving:
|
||||
|
||||
_cursorMgr->update();
|
||||
break;
|
||||
case kInDialog1:
|
||||
case kInDialog2:
|
||||
_sequencer->update();
|
||||
break;
|
||||
|
||||
case kInventory:
|
||||
case kPDA:
|
||||
break;
|
||||
|
||||
case kPlayingVideo:
|
||||
_sequencer->update();
|
||||
if (!_sequencer->_context){
|
||||
_state = kUnk_Loading;
|
||||
_page->getGame()->changeScene(_page);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
case kUnk_Loading:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LeadActor::OnKeyboardButtonClick(Common::KeyCode code) {
|
||||
void LeadActor::onKeyboardButtonClick(Common::KeyCode code) {
|
||||
switch(_state) {
|
||||
case kMoving:
|
||||
switch (code){
|
||||
@ -116,6 +134,73 @@ void LeadActor::OnKeyboardButtonClick(Common::KeyCode code) {
|
||||
}
|
||||
}
|
||||
|
||||
void LeadActor::start(bool isHandler) {
|
||||
if (isHandler && _state != kPlayingVideo){
|
||||
_state = kReady;
|
||||
}
|
||||
updateCursor({0,0});
|
||||
}
|
||||
|
||||
void LeadActor::onMouseMove(Common::Point point) {
|
||||
if (_state != kPDA)
|
||||
updateCursor(point);
|
||||
else error("pda is not supported");
|
||||
}
|
||||
|
||||
void LeadActor::updateCursor(Common::Point point) {
|
||||
switch (_state) {
|
||||
case kReady:
|
||||
case kMoving: {
|
||||
Director *director = _page->getGame()->getDirector();
|
||||
Actor *actor = director->getActorByPoint(point);
|
||||
if (actor)
|
||||
actor->onMouseOver(point, _cursorMgr);
|
||||
else _cursorMgr->setCursor(kDefaultCursor, point);
|
||||
break;
|
||||
}
|
||||
case kInDialog1:
|
||||
case kInDialog2:
|
||||
case kPlayingVideo:
|
||||
_cursorMgr->setCursor(kNotClickableCursor, point);
|
||||
break;
|
||||
case kPDA:
|
||||
case kInventory:
|
||||
_cursorMgr->setCursor(kDefaultCursor, point);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LeadActor::onLeftButtonClick(Common::Point point) {
|
||||
switch (_state) {
|
||||
case kReady:
|
||||
case kMoving: {
|
||||
Actor *actor = _page->getGame()->getDirector()->getActorByPoint(point);
|
||||
if (this == actor){
|
||||
// inventory is not implemented
|
||||
return;
|
||||
}
|
||||
|
||||
if (actor->isClickable() &&
|
||||
((SupportingActor*) actor)->isLeftClickHandlers())
|
||||
|
||||
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
case kPDA:
|
||||
|
||||
break;
|
||||
case kInventory:
|
||||
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ParlSqPink::toConsole() {
|
||||
debug("ParlSqPink: _name = %s", _name.c_str());
|
||||
for (int i = 0; i < _actions.size(); ++i) {
|
||||
|
@ -24,6 +24,7 @@
|
||||
#define PINK_LEAD_ACTOR_H
|
||||
|
||||
#include <common/keyboard.h>
|
||||
#include <common/rect.h>
|
||||
#include "actor.h"
|
||||
|
||||
namespace Pink {
|
||||
@ -58,8 +59,14 @@ public:
|
||||
void start(bool isHandler);
|
||||
void update();
|
||||
|
||||
void OnKeyboardButtonClick(Common::KeyCode code);
|
||||
void onKeyboardButtonClick(Common::KeyCode code);
|
||||
void onLeftButtonClick(Common::Point point);
|
||||
void onMouseMove(Common::Point point);
|
||||
|
||||
private:
|
||||
void updateCursor(Common::Point point);
|
||||
|
||||
|
||||
State _state;
|
||||
CursorMgr *_cursorMgr;
|
||||
WalkMgr *_walkMgr;
|
||||
|
@ -23,7 +23,8 @@
|
||||
#include "supporting_actor.h"
|
||||
#include <engines/pink/archive.h>
|
||||
#include <engines/pink/objects/actions/action.h>
|
||||
#include <common/debug.h>
|
||||
#include <engines/pink/constants.h>
|
||||
#include "pink/cursor_mgr.h"
|
||||
|
||||
namespace Pink {
|
||||
|
||||
@ -42,4 +43,18 @@ void SupportingActor::toConsole() {
|
||||
_handlerMgr.toConsole();
|
||||
}
|
||||
|
||||
void SupportingActor::onMouseOver(Common::Point point, CursorMgr *mgr) {
|
||||
if (isLeftClickHandlers()){
|
||||
if (!_cursor.empty()){
|
||||
mgr->setCursor(_cursor, point);
|
||||
}
|
||||
else mgr->setCursor(kClickableFirstFrameCursor, point);
|
||||
}
|
||||
else Actor::onMouseOver(point, mgr);
|
||||
}
|
||||
|
||||
bool SupportingActor::isLeftClickHandlers() {
|
||||
return _handlerMgr.isLeftClickHandler(this);
|
||||
}
|
||||
|
||||
} // End of namespace Pink
|
@ -33,6 +33,11 @@ public:
|
||||
virtual void deserialize(Archive &archive);
|
||||
virtual void toConsole();
|
||||
|
||||
virtual void onMouseOver(Common::Point point, CursorMgr *mgr);
|
||||
|
||||
virtual bool isClickable() { return 1; }
|
||||
bool isLeftClickHandlers();
|
||||
|
||||
private:
|
||||
HandlerMgr _handlerMgr;
|
||||
Common::String _location;
|
||||
|
@ -32,7 +32,7 @@ void Pink::ConditionVariable::deserialize(Archive &archive) {
|
||||
archive >> _name >> _value;
|
||||
}
|
||||
|
||||
bool Pink::ConditionGameVariable::evaluate(LeadActor *leadActor) {
|
||||
bool Pink::ConditionGameVariable::evaluate(Actor *leadActor) {
|
||||
return leadActor->getPage()->getModule()->getGame()->checkValueOfVariable(_name, _value);
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ void ConditionGameVariable::toConsole() {
|
||||
debug("\t\tConditionGameVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str());
|
||||
}
|
||||
|
||||
bool Pink::ConditionModuleVariable::evaluate(LeadActor *leadActor) {
|
||||
bool Pink::ConditionModuleVariable::evaluate(Actor *leadActor) {
|
||||
return leadActor->getPage()->getModule()->checkValueOfVariable(_name, _value);
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ void ConditionModuleVariable::toConsole() {
|
||||
debug("\t\tConditionModuleVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str());
|
||||
}
|
||||
|
||||
bool Pink::ConditionNotModuleVariable::evaluate(LeadActor *leadActor) {
|
||||
bool Pink::ConditionNotModuleVariable::evaluate(Actor *leadActor) {
|
||||
return !ConditionModuleVariable::evaluate(leadActor);
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ void ConditionNotModuleVariable::toConsole() {
|
||||
debug("\t\tConditionNotModuleVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str());
|
||||
}
|
||||
|
||||
bool ConditionPageVariable::evaluate(LeadActor *leadActor) {
|
||||
bool ConditionPageVariable::evaluate(Actor *leadActor) {
|
||||
return leadActor->getPage()->checkValueOfVariable(_name, _value);
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ void ConditionPageVariable::toConsole() {
|
||||
debug("\t\tConditionPageVariable: _name=%s, _value=%s", _name.c_str(), _value.c_str());
|
||||
}
|
||||
|
||||
bool ConditionNotPageVariable::evaluate(LeadActor *leadActor) {
|
||||
bool ConditionNotPageVariable::evaluate(Actor *leadActor) {
|
||||
return !ConditionPageVariable::evaluate(leadActor);
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ void ConditionInventoryItemOwner::deserialize(Archive &archive) {
|
||||
archive >> _item >> _owner;
|
||||
}
|
||||
|
||||
bool ConditionInventoryItemOwner::evaluate(LeadActor *leadActor) {
|
||||
bool ConditionInventoryItemOwner::evaluate(Actor *leadActor) {
|
||||
InventoryMgr *mgr = leadActor->getPage()->getModule()->getInventoryMgr();
|
||||
InventoryItem *item = mgr->findInventoryItem(_item);
|
||||
return item->getCurrentOwner() == _owner;
|
||||
@ -86,7 +86,7 @@ void ConditionInventoryItemOwner::toConsole() {
|
||||
debug("\t\tConditionInventoryItemOwner: _item=%s, _owner=%s", _item.c_str(), _owner.c_str());
|
||||
}
|
||||
|
||||
bool ConditionNotInventoryItemOwner::evaluate(LeadActor *leadActor) {
|
||||
bool ConditionNotInventoryItemOwner::evaluate(Actor *leadActor) {
|
||||
return !ConditionInventoryItemOwner::evaluate(leadActor);
|
||||
}
|
||||
|
||||
|
@ -32,14 +32,14 @@ class LeadActor;
|
||||
class Condition : public Object {
|
||||
public:
|
||||
virtual void deserialize(Archive &archive) = 0;
|
||||
virtual bool evaluate(LeadActor *leadActor) = 0;
|
||||
virtual bool evaluate(Actor *leadActor) = 0;
|
||||
};
|
||||
|
||||
class ConditionVariable : public Condition {
|
||||
public:
|
||||
|
||||
virtual void deserialize(Archive &archive);
|
||||
virtual bool evaluate(LeadActor *leadActor) = 0;
|
||||
virtual bool evaluate(Actor *actor) = 0;
|
||||
|
||||
protected:
|
||||
Common::String _name;
|
||||
@ -49,7 +49,7 @@ protected:
|
||||
class ConditionGameVariable : public ConditionVariable {
|
||||
public:
|
||||
virtual void toConsole();
|
||||
virtual bool evaluate(LeadActor *leadActor);
|
||||
virtual bool evaluate(Actor *actor);
|
||||
};
|
||||
|
||||
/*
|
||||
@ -62,32 +62,32 @@ class ConditionNotGameVariable : public ConditionGameVariable {
|
||||
class ConditionModuleVariable : public ConditionVariable {
|
||||
public:
|
||||
virtual void toConsole();
|
||||
virtual bool evaluate(LeadActor *leadActor);
|
||||
virtual bool evaluate(Actor *actor);
|
||||
};
|
||||
|
||||
class ConditionNotModuleVariable : public ConditionModuleVariable {
|
||||
public:
|
||||
virtual void toConsole();
|
||||
virtual bool evaluate(LeadActor *leadActor);
|
||||
virtual bool evaluate(Actor *actor);
|
||||
};
|
||||
|
||||
class ConditionPageVariable : public ConditionVariable {
|
||||
public:
|
||||
virtual void toConsole();
|
||||
virtual bool evaluate(LeadActor *leadActor);
|
||||
virtual bool evaluate(Actor *actor);
|
||||
};
|
||||
|
||||
class ConditionNotPageVariable : public ConditionPageVariable {
|
||||
public:
|
||||
virtual void toConsole();
|
||||
virtual bool evaluate(LeadActor *leadActor);
|
||||
virtual bool evaluate(Actor *actor);
|
||||
};
|
||||
|
||||
class ConditionInventoryItemOwner : public Condition {
|
||||
public:
|
||||
virtual void toConsole();
|
||||
virtual void deserialize(Archive &archive);
|
||||
virtual bool evaluate(LeadActor *leadActor);
|
||||
virtual bool evaluate(Actor *actor);
|
||||
|
||||
protected:
|
||||
Common::String _item;
|
||||
@ -97,7 +97,7 @@ protected:
|
||||
class ConditionNotInventoryItemOwner : public ConditionInventoryItemOwner {
|
||||
public:
|
||||
virtual void toConsole();
|
||||
virtual bool evaluate(LeadActor *leadActor);
|
||||
virtual bool evaluate(Actor *actor);
|
||||
};
|
||||
|
||||
} // End of namespace Pink
|
||||
|
@ -37,7 +37,7 @@ void Handler::deserialize(Archive &archive) {
|
||||
archive >> _sideEffects;
|
||||
}
|
||||
|
||||
bool Handler::isSuitable(LeadActor *actor) {
|
||||
bool Handler::isSuitable(Actor *actor) {
|
||||
for (int i = 0; i < _conditions.size(); ++i) {
|
||||
if (!_conditions[i]->evaluate(actor)){
|
||||
return false;
|
||||
@ -56,6 +56,15 @@ void Handler::onMessage(LeadActor *actor) {
|
||||
executeSideEffects(actor);
|
||||
}
|
||||
|
||||
Handler::~Handler() {
|
||||
for (int i = 0; i < _sideEffects.size(); ++i) {
|
||||
delete _sideEffects[i];
|
||||
}
|
||||
for (int i = 0; i < _conditions.size(); ++i) {
|
||||
delete _conditions[i];
|
||||
}
|
||||
}
|
||||
|
||||
void HandlerSequences::deserialize(Archive &archive) {
|
||||
Handler::deserialize(archive);
|
||||
archive >> _sequences;
|
||||
|
@ -33,12 +33,14 @@ namespace Pink {
|
||||
class Condition;
|
||||
class SideEffect;
|
||||
class LeadActor;
|
||||
class Actor;
|
||||
|
||||
class Handler : public Object {
|
||||
public:
|
||||
~Handler();
|
||||
virtual void deserialize(Archive &archive);
|
||||
virtual void onMessage(LeadActor *actor);
|
||||
bool isSuitable(LeadActor *actor);
|
||||
bool isSuitable(Actor *actor);
|
||||
|
||||
protected:
|
||||
void executeSideEffects(LeadActor *actor);
|
||||
|
@ -27,4 +27,13 @@ void HandlerMgr::toConsole() {
|
||||
}
|
||||
}
|
||||
|
||||
bool HandlerMgr::isLeftClickHandler(Actor *actor) {
|
||||
for (int i = 0; i < _leftClickHandlers.size(); ++i) {
|
||||
if (_leftClickHandlers[i]->isSuitable(actor))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ namespace Pink {
|
||||
class HandlerLeftClick;
|
||||
class HandlerUseClick;
|
||||
class HandlerTimer;
|
||||
class Actor;
|
||||
|
||||
class HandlerMgr : public Object {
|
||||
public:
|
||||
@ -38,6 +39,8 @@ public:
|
||||
|
||||
virtual void toConsole();
|
||||
|
||||
bool isLeftClickHandler(Actor *actor);
|
||||
|
||||
private:
|
||||
Common::Array<HandlerLeftClick*> _leftClickHandlers;
|
||||
Common::Array<HandlerUseClick*> _useClickHandlers;
|
||||
|
@ -93,6 +93,12 @@ InventoryMgr *Module::getInventoryMgr() {
|
||||
return &_invMgr;
|
||||
}
|
||||
|
||||
Module::~Module() {
|
||||
for (int i = 0; i < _pages.size(); ++i) {
|
||||
delete _pages[i];
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Pink
|
||||
|
||||
|
||||
|
@ -43,6 +43,7 @@ class GamePage;
|
||||
class Module : public NamedObject {
|
||||
public:
|
||||
Module(PinkEngine *game, const Common::String &name);
|
||||
~Module();
|
||||
|
||||
void load(Archive &archive);
|
||||
void init(bool isLoadingSave, const Common::String &pageName);
|
||||
|
@ -77,7 +77,7 @@ void GamePage::init(bool isLoadingSave) {
|
||||
isHandler = initHandler();
|
||||
}
|
||||
|
||||
//_leadActor->start(isHandler);
|
||||
_leadActor->start(isHandler);
|
||||
}
|
||||
|
||||
bool GamePage::initHandler() {
|
||||
@ -92,7 +92,7 @@ bool GamePage::initHandler() {
|
||||
|
||||
void GamePage::loadManagers() {
|
||||
perhapsIsLoaded = true;
|
||||
_cursorMgr = new CursorMgr(this);
|
||||
_cursorMgr = new CursorMgr(_module->getGame(), this);
|
||||
_walkMgr = new WalkMgr;
|
||||
_sequencer = new Sequencer(this);
|
||||
|
||||
@ -137,4 +137,19 @@ void GamePage::toConsole() {
|
||||
}
|
||||
}
|
||||
|
||||
GamePage::~GamePage() {
|
||||
delete _cursorMgr;
|
||||
delete _walkMgr;
|
||||
delete _sequencer;
|
||||
for (int i = 0; i < _handlers.size(); ++i) {
|
||||
delete _handlers[i];
|
||||
}
|
||||
}
|
||||
|
||||
GamePage::GamePage()
|
||||
: _cursorMgr(nullptr), _walkMgr(nullptr), _sequencer(nullptr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
} // End of namespace Pink
|
@ -34,6 +34,8 @@ class HandlerStartPage;
|
||||
|
||||
class GamePage : public Page {
|
||||
public:
|
||||
GamePage();
|
||||
~GamePage();
|
||||
virtual void deserialize(Archive &archive);
|
||||
|
||||
virtual void load(Archive &archive);
|
||||
|
@ -65,4 +65,10 @@ void Page::init() {
|
||||
}
|
||||
}
|
||||
|
||||
Page::~Page() {
|
||||
for (int i = 0; i < _actors.size(); ++i) {
|
||||
delete _actors[i];
|
||||
}
|
||||
}
|
||||
|
||||
} // End of namespace Pink
|
||||
|
@ -36,7 +36,7 @@ class LeadActor;
|
||||
|
||||
class Page : public NamedObject {
|
||||
public:
|
||||
|
||||
~Page();
|
||||
void load(Archive &archive);
|
||||
Actor *findActor(Common::String &name);
|
||||
Sound* loadSound(Common::String &fileName);
|
||||
|
@ -134,6 +134,11 @@ void Sequence::skipItemsTo(int index) {
|
||||
}
|
||||
}
|
||||
|
||||
void Sequence::skipSubSequence() {
|
||||
if (_context->getNextItemIndex() < _context->getSequence()->getItems().size())
|
||||
_context->getSequence()->start(0);
|
||||
}
|
||||
|
||||
void SequenceAudio::deserialize(Archive &archive) {
|
||||
Sequence::deserialize(archive);
|
||||
archive >> _soundName;
|
||||
@ -182,4 +187,8 @@ void SequenceAudio::restart() {
|
||||
Sequence::restart();
|
||||
}
|
||||
|
||||
void SequenceAudio::skipToLastSubSequence() {
|
||||
end();
|
||||
}
|
||||
|
||||
} // End of namespace Pink
|
@ -49,9 +49,11 @@ public:
|
||||
|
||||
virtual void update();
|
||||
virtual void restart();
|
||||
void skipToLastSubSequence();
|
||||
virtual void skipSubSequence();
|
||||
virtual void skipToLastSubSequence();
|
||||
void skipItemsTo(int index);
|
||||
|
||||
|
||||
public:
|
||||
SequenceContext *_context;
|
||||
Sequencer *_sequencer;
|
||||
@ -69,9 +71,13 @@ public:
|
||||
virtual void init(int unk);
|
||||
virtual void start(int unk);
|
||||
virtual void end();
|
||||
|
||||
virtual void update();
|
||||
virtual void restart();
|
||||
|
||||
virtual void skipSubSequence() {};
|
||||
virtual void skipToLastSubSequence();
|
||||
|
||||
private:
|
||||
Common::String _soundName;
|
||||
Sound *_sound;
|
||||
|
@ -73,7 +73,8 @@ void Sequencer::toConsole() {
|
||||
}
|
||||
|
||||
void Sequencer::update() {
|
||||
_context->_sequence->update();
|
||||
if (_context)
|
||||
_context->_sequence->update();
|
||||
}
|
||||
|
||||
void Sequencer::removeContext(SequenceContext *context) {
|
||||
@ -82,8 +83,8 @@ void Sequencer::removeContext(SequenceContext *context) {
|
||||
}
|
||||
|
||||
void Sequencer::skipSubSequence() {
|
||||
if (_context && _context->getNextItemIndex() < _context->getSequence()->getItems().size())
|
||||
_context->getSequence()->start(0);
|
||||
if (_context)
|
||||
_context->getSequence()->skipSubSequence();
|
||||
}
|
||||
|
||||
void Sequencer::restartSequence() {
|
||||
|
@ -28,6 +28,8 @@
|
||||
#include "engines/pink/objects/module.h"
|
||||
#include "engines/pink/objects/actors/lead_actor.h"
|
||||
#include <graphics/surface.h>
|
||||
#include <graphics/cursorman.h>
|
||||
#include <common/winexe_pe.h>
|
||||
|
||||
|
||||
namespace Pink {
|
||||
@ -51,6 +53,9 @@ Pink::PinkEngine::~PinkEngine() {
|
||||
for (uint i = 0; i < _modules.size(); ++i) {
|
||||
delete _modules[i];
|
||||
}
|
||||
for (int j = 0; j < _cursors.size(); ++j) {
|
||||
delete _cursors[j];
|
||||
}
|
||||
|
||||
DebugMan.clearAllDebugChannels();
|
||||
}
|
||||
@ -65,7 +70,7 @@ Common::Error PinkEngine::init() {
|
||||
Common::String orbName{_desc.filesDescriptions[0].fileName};
|
||||
Common::String broName{_desc.filesDescriptions[1].fileName};
|
||||
|
||||
if (!broName.empty()){
|
||||
if (strcmp(_desc.gameId, "peril") == 0){
|
||||
_bro = new BroFile();
|
||||
}
|
||||
else debug("This game doesn't need to use bro");
|
||||
@ -74,8 +79,11 @@ Common::Error PinkEngine::init() {
|
||||
return Common::kNoGameDataFoundError;
|
||||
}
|
||||
|
||||
// TODO load cursor
|
||||
if (!loadCursors())
|
||||
return Common::kNoGameDataFoundError;
|
||||
|
||||
setCursor(kLoadingCursor);
|
||||
_system->showMouse(1);
|
||||
|
||||
_orb.loadGame(this);
|
||||
const Common::String empty;
|
||||
@ -86,10 +94,8 @@ Common::Error PinkEngine::init() {
|
||||
|
||||
Common::Error Pink::PinkEngine::run() {
|
||||
Common::Error error = init();
|
||||
if (error.getCode() != Common::kNoError){
|
||||
if (error.getCode() != Common::kNoError)
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
while(!shouldQuit()){
|
||||
Common::Event event;
|
||||
@ -99,15 +105,15 @@ Common::Error Pink::PinkEngine::run() {
|
||||
case Common::EVENT_RTL:
|
||||
return Common::kNoError;
|
||||
case Common::EVENT_MOUSEMOVE:
|
||||
|
||||
_actor->onMouseMove(event.mouse);
|
||||
break;
|
||||
case Common::EVENT_LBUTTONDOWN:
|
||||
|
||||
_actor->onLeftButtonClick(event.mouse);
|
||||
break;
|
||||
case Common::EVENT_KEYDOWN:
|
||||
if (event.kbd.keycode == Common::KEYCODE_d)
|
||||
_director.showBounds = !_director.showBounds;
|
||||
else _actor->OnKeyboardButtonClick(event.kbd.keycode);
|
||||
else _actor->onKeyboardButtonClick(event.kbd.keycode);
|
||||
break;
|
||||
|
||||
// don't know why it is used in original
|
||||
@ -118,10 +124,11 @@ Common::Error Pink::PinkEngine::run() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
_actor->update();
|
||||
_director.update();
|
||||
_director.draw();
|
||||
_system->delayMillis(50);
|
||||
_system->delayMillis(5);
|
||||
}
|
||||
|
||||
return Common::kNoError;
|
||||
@ -135,35 +142,30 @@ void PinkEngine::load(Archive &archive) {
|
||||
|
||||
void PinkEngine::initModule(const Common::String &moduleName, bool isLoadingFromSave, const Common::String &pageName) {
|
||||
if (_module) {
|
||||
|
||||
//call module function (smth with unloading)
|
||||
|
||||
uint i;
|
||||
for (i = 0; i < _modules.size(); ++i) {
|
||||
for (uint i = 0; i < _modules.size(); ++i) {
|
||||
if (_module == _modules[i]){
|
||||
_modules[i] = new ModuleProxy(_module->getName());
|
||||
|
||||
delete _module;
|
||||
_module = nullptr;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_modules[i] = new ModuleProxy(_module->getName());
|
||||
|
||||
delete _module;
|
||||
_module = nullptr;
|
||||
}
|
||||
|
||||
uint i;
|
||||
for (i = 0; i < _modules.size(); ++i) {
|
||||
for (uint i = 0; i < _modules.size(); ++i) {
|
||||
if (_modules[i]->getName() == moduleName) {
|
||||
loadModule(i);
|
||||
_module = static_cast<Module*>(_modules[i]);
|
||||
_module->init(isLoadingFromSave, pageName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_module = static_cast<Module*>(_modules[i]);
|
||||
_module->init(isLoadingFromSave, pageName);
|
||||
}
|
||||
|
||||
void PinkEngine::changeScene(GamePage *page) {
|
||||
setCursor(kLoadingCursor);
|
||||
if (!_nextModule.empty() && _nextModule.compareTo(_module->getName())) {
|
||||
initModule(_nextModule, kLoadingNewGame, _nextPage);
|
||||
}
|
||||
@ -198,4 +200,47 @@ void PinkEngine::setVariable(Common::String &variable, Common::String &value) {
|
||||
_variables[variable] = value;
|
||||
}
|
||||
|
||||
bool PinkEngine::loadCursors() {
|
||||
Common::PEResources exeResources;
|
||||
bool isPokus = !strcmp(_desc.gameId, "pokus");
|
||||
Common::String fileName = isPokus ? _desc.filesDescriptions[1].fileName : _desc.filesDescriptions[2].fileName;
|
||||
if (!exeResources.loadFromEXE(fileName))
|
||||
return false;
|
||||
|
||||
_cursors.reserve(kCursorsCount);
|
||||
|
||||
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusLoadingCursorID));
|
||||
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusExitForwardCursorID));
|
||||
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusExitLeftCursorID));
|
||||
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusExitRightCursorID));
|
||||
_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));
|
||||
}
|
||||
else {
|
||||
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPerilClickableThirdCursorID));
|
||||
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPerilNotClickableCursorID));
|
||||
}
|
||||
|
||||
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusHoldingItemCursorID));
|
||||
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusPDAFirstCursorID));
|
||||
|
||||
if (isPokus)
|
||||
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPokusPDASecondCursorID));
|
||||
else
|
||||
_cursors.push_back(Graphics::WinCursorGroup::createCursorGroup(exeResources, kPerilPDASecondCursorID));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void PinkEngine::setCursor(uint cursorIndex) {
|
||||
Graphics::Cursor *cursor = _cursors[cursorIndex]->cursors[0].cursor;
|
||||
_system->setCursorPalette(cursor->getPalette(), cursor->getPaletteStartIndex(), cursor->getPaletteCount());
|
||||
_system->setMouseCursor(cursor->getSurface(), cursor->getWidth(), cursor->getHeight(),
|
||||
cursor->getHotspotX(), cursor->getHotspotY(), cursor->getKeyColor());
|
||||
}
|
||||
|
||||
}
|
@ -23,13 +23,14 @@
|
||||
#ifndef PINK_PINK_H
|
||||
#define PINK_PINK_H
|
||||
|
||||
#include <graphics/wincursor.h>
|
||||
#include "common/random.h"
|
||||
#include "engines/engine.h"
|
||||
#include "gui/EventRecorder.h"
|
||||
#include "gui/debugger.h"
|
||||
#include "file.h"
|
||||
#include "director.h"
|
||||
|
||||
#include "constants.h"
|
||||
|
||||
/*
|
||||
* This is the namespace of the Pink engine.
|
||||
@ -60,11 +61,6 @@ enum {
|
||||
kPinkDebugSound = 1 << 4
|
||||
};
|
||||
|
||||
enum {
|
||||
kLoadingSave = 1,
|
||||
kLoadingNewGame = 0
|
||||
};
|
||||
|
||||
class PinkEngine : public Engine {
|
||||
public:
|
||||
PinkEngine(OSystem *system, const ADGameDescription *desc);
|
||||
@ -87,14 +83,16 @@ public:
|
||||
void setVariable(Common::String &variable, Common::String &value);
|
||||
bool checkValueOfVariable(Common::String &variable, Common::String &value);
|
||||
|
||||
inline void setCursor(uint cursorIndex);
|
||||
private:
|
||||
Common::Error init();
|
||||
bool loadCursors();
|
||||
|
||||
void loadModule(int index);
|
||||
|
||||
|
||||
|
||||
Console *_console;
|
||||
Common::RandomSource _rnd;
|
||||
Common::Array<Graphics::WinCursorGroup*> _cursors;
|
||||
|
||||
Common::String _nextModule;
|
||||
Common::String _nextPage;
|
||||
|
@ -23,24 +23,24 @@
|
||||
#include <audio/audiostream.h>
|
||||
#include <audio/decoders/wave.h>
|
||||
#include <audio/decoders/adpcm.h>
|
||||
#include <common/substream.h>
|
||||
#include "sound.h"
|
||||
|
||||
namespace Pink {
|
||||
|
||||
Sound::Sound(Audio::Mixer *mixer, Common::SeekableReadStream *stream)
|
||||
: _mixer(mixer)
|
||||
Sound::Sound(Audio::Mixer *mixer, Common::SafeSeekableSubReadStream *stream)
|
||||
: _mixer(mixer), _fileStream(stream)
|
||||
{
|
||||
load(stream);
|
||||
|
||||
}
|
||||
|
||||
Sound::~Sound() {
|
||||
stop();
|
||||
delete _stream;
|
||||
delete _fileStream;
|
||||
}
|
||||
|
||||
bool Sound::isPlaying() {
|
||||
return _mixer->isSoundHandleActive(_handle);
|
||||
|
||||
}
|
||||
|
||||
void Sound::pause() {
|
||||
@ -56,28 +56,19 @@ void Sound::stop() {
|
||||
}
|
||||
|
||||
void Sound::play(Audio::Mixer::SoundType type, int volume, bool isLoop) {
|
||||
_mixer->stopHandle(_handle);
|
||||
|
||||
if (isLoop) {
|
||||
//bad impl?
|
||||
Audio::SeekableAudioStream *seekableStream = dynamic_cast<Audio::SeekableAudioStream*>(_stream);
|
||||
_stream = Audio::makeLoopingAudioStream(seekableStream, 0, 0, 0);
|
||||
}
|
||||
|
||||
_mixer->playStream(type, &_handle ,_stream, -1 , Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO);
|
||||
}
|
||||
|
||||
bool Sound::load(Common::SeekableReadStream *stream) {
|
||||
// Vox files in pink have wave format.
|
||||
// RIFF (little-endian) data, WAVE audio, Microsoft PCM, 8 bit, mono 22050 Hz
|
||||
_mixer->stopHandle(_handle);
|
||||
|
||||
_stream = Audio::makeWAVStream(stream, DisposeAfterUse::YES);
|
||||
_fileStream->seek(0);
|
||||
Audio::AudioStream *audioStream ;
|
||||
Audio::SeekableAudioStream *wavStream = Audio::makeWAVStream(_fileStream, DisposeAfterUse::NO);
|
||||
if (isLoop) {
|
||||
audioStream = Audio::makeLoopingAudioStream(wavStream, 0, 0, 0);
|
||||
}
|
||||
else audioStream = wavStream;
|
||||
|
||||
return isLoaded();
|
||||
}
|
||||
|
||||
bool Sound::isLoaded() {
|
||||
return _stream != nullptr;
|
||||
_mixer->playStream(type, &_handle , audioStream, -1 , Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::YES);
|
||||
}
|
||||
|
||||
void Sound::setBalance(int8 balance) {
|
||||
|
@ -36,13 +36,11 @@ namespace Pink {
|
||||
|
||||
class Sound {
|
||||
public:
|
||||
Sound(Audio::Mixer *mixer, Common::SeekableReadStream *stream);
|
||||
Sound(Audio::Mixer *mixer, Common::SafeSeekableSubReadStream *stream);
|
||||
~Sound();
|
||||
|
||||
bool load(Common::SeekableReadStream *stream);
|
||||
void play(Audio::Mixer::SoundType type, int volume, bool isLoop);
|
||||
|
||||
bool isLoaded();
|
||||
bool isPlaying();
|
||||
|
||||
void pause();
|
||||
@ -54,8 +52,8 @@ public:
|
||||
|
||||
private:
|
||||
Audio::Mixer *_mixer;
|
||||
Audio::AudioStream *_stream;
|
||||
Audio::SoundHandle _handle;
|
||||
Common::SafeSeekableSubReadStream *_fileStream;
|
||||
};
|
||||
|
||||
} // End of namespace Pink
|
||||
|
Loading…
x
Reference in New Issue
Block a user