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

View File

@@ -0,0 +1,3 @@
engines/wintermute/metaengine.cpp
engines/wintermute/wintermute.cpp
engines/wintermute/keymapper_tables.h

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 WINTERMUTE_ACHIEVEMENTS_H
#define WINTERMUTE_ACHIEVEMENTS_H
#include "engines/achievements.h"
namespace Wintermute {
static const Common::AchievementDescriptionList achievementDescriptionList[] = {
{"alphapolaris", Common::STEAM_ACHIEVEMENTS, "405780"},
{"carolreed10", Common::STEAM_ACHIEVEMENTS, "337130"},
{"carolreed10", Common::UNK_ACHIEVEMENTS, "337130"},
{"carolreed11", Common::STEAM_ACHIEVEMENTS, "340370"},
{"carolreed11", Common::UNK_ACHIEVEMENTS, "340370"},
{"corrosion", Common::STEAM_ACHIEVEMENTS, "349140"},
{"drdoylemotch", Common::STEAM_ACHIEVEMENTS, "574420"},
{"erinmyers", Common::STEAM_ACHIEVEMENTS, "1064660"},
{"jamesperis2", Common::STEAM_ACHIEVEMENTS, "1642970"},
{"juliastars", Common::GALAXY_ACHIEVEMENTS, "1457085654"},
{"juliastars", Common::STEAM_ACHIEVEMENTS, "257690"},
{"juliauntold", Common::GALAXY_ACHIEVEMENTS, "1457085654"},
{"juliauntold", Common::STEAM_ACHIEVEMENTS, "257690"},
{"reversion1", Common::STEAM_ACHIEVEMENTS, "270570"},
{"reversion2", Common::STEAM_ACHIEVEMENTS, "281060"},
{"reversion3", Common::STEAM_ACHIEVEMENTS, "281080"},
{"oknytt", Common::STEAM_ACHIEVEMENTS, "286320"},
{"sotv1", Common::STEAM_ACHIEVEMENTS, "286360"},
{"sotv2", Common::STEAM_ACHIEVEMENTS, "378630"},
{"thelostcrowngha", Common::STEAM_ACHIEVEMENTS, "291710"},
ACHIEVEMENT_DESC_TABLE_END_MARKER
};
} // End of namespace Wintermute
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,109 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADACTOR_H
#define WINTERMUTE_ADACTOR_H
#include "engines/wintermute/dctypes.h" // Added by ClassView
#include "engines/wintermute/ad/ad_types.h" // Added by ClassView
#include "engines/wintermute/ad/ad_talk_holder.h"
#include "engines/wintermute/coll_templ.h"
#include "engines/wintermute/base/base_point.h" // Added by ClassView
#include "engines/wintermute/persistent.h"
#include "common/str.h"
namespace Wintermute {
class AdSpriteSet;
class AdPath;
class BaseSprite;
class AdActor : public AdTalkHolder {
public:
TDirection angleToDirection(int angle);
DECLARE_PERSISTENT(AdActor, AdTalkHolder)
int32 getHeight() override;
BaseSprite *getTalkStance(const char *stance) override;
virtual void goTo(int x, int y, TDirection afterWalkDir = DI_NONE);
BasePoint *_targetPoint;
bool update() override;
bool display() override;
TDirection _targetDir{DI_NONE};
TDirection _afterWalkDir;
virtual void turnTo(TDirection dir);
AdPath *_path;
AdSpriteSet *_walkSprite;
AdSpriteSet *_standSprite;
AdSpriteSet *_turnLeftSprite;
AdSpriteSet *_turnRightSprite;
BaseArray<AdSpriteSet *> _talkSprites;
BaseArray<AdSpriteSet *> _talkSpritesEx;
TDirection _dir;
AdActor(BaseGame *inGame/*=nullptr*/);
~AdActor() override;
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
// new anim system
char *_talkAnimName;
char *_idleAnimName;
char *_walkAnimName;
char *_turnLeftAnimName;
char *_turnRightAnimName;
BaseArray<AdSpriteSet *> _anims;
bool playAnim(const char *filename) override;
AdSpriteSet *getAnimByName(const char *animName);
// alternative behaviour when actor is blocked
bool _stopOnBlocked;
bool _actorIsBlocked;
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
private:
bool setDefaultAnimNames();
BaseSprite *getTalkStanceOld(const char *stance);
bool mergeAnims(const char *animsFilename);
BaseSprite *_animSprite2;
void initLine(BasePoint startPt, BasePoint endPt);
void getNextStep();
void followPath();
double _pFStepX{};
double _pFStepY{};
double _pFX{};
double _pFY{};
int32 _pFCount{};
};
} // End of namespace Wintermute
#endif

File diff suppressed because it is too large Load Diff

View 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 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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#ifndef WINTERMUTE_AD_ACTOR_3DX_H
#define WINTERMUTE_AD_ACTOR_3DX_H
#include "engines/wintermute/ad/ad_object_3d.h"
#include "engines/wintermute/base/base_animation_transition_time.h"
#include "engines/wintermute/base/base_point.h"
#include "engines/wintermute/base/gfx/xmath.h"
#include "engines/wintermute/coll_templ.h"
namespace Wintermute {
class AdAttach3DX;
class AdPath;
class AdPath3D;
class AdActor3DX : public AdObject3D {
public:
PartEmitter *createParticleEmitter(bool followParent = false, int offsetX = 0, int offsetY = 0) override;
virtual PartEmitter *createParticleEmitter(const char *boneName, DXVector3 offset);
bool updatePartEmitter() override;
char *_partBone;
DXVector3 _partOffset;
bool displayShadowVolume();
bool displayFlatShadow();
bool restoreDeviceObjects() override;
bool invalidateDeviceObjects() override;
int32 _stateAnimChannel;
void talk(const char *text, const char *sound = nullptr, uint32 duration = 0, const char *stances = nullptr, TTextAlign align = TAL_CENTER) override;
int32 getHeight() override;
bool playAnim3DX(const char *name, bool setState);
bool playAnim3DX(int channel, const char *name, bool setState);
uint32 getAnimTransitionTime(const char *from, const char *to) override;
BaseArray<BaseAnimationTransitionTime *> _transitionTimes;
virtual bool renderModel() override;
uint32 _defaultTransTime;
uint32 _defaultStopTransTime;
float _afterWalkAngle;
char *_talkAnimName;
char *_idleAnimName;
char *_walkAnimName;
char *_turnLeftAnimName;
char *_turnRightAnimName;
int32 _talkAnimChannel;
TDirectWalkMode _directWalkMode;
TDirectTurnMode _directTurnMode;
char *_directWalkAnim;
char *_directTurnAnim;
float _directWalkVelocity;
float _directTurnVelocity;
int32 _goToTolerance;
DECLARE_PERSISTENT(AdActor3DX, AdObject3D)
bool _turningLeft;
void initLine3D(DXVector3 startPt, DXVector3 endPt, bool firstStep);
void getNextStep3D();
void followPath3D();
void getNextStep2D();
void followPath2D();
void goTo3D(DXVector3 targetPos, float targetAngle = -1.0f);
void goTo2D(int x, int y, float targetAngle = -1.0f);
bool turnTo(float angle);
DXVector3 _targetPoint3D;
BasePoint *_targetPoint2D;
float _targetAngle;
bool display() override;
bool update() override;
AdActor3DX(BaseGame *inGame);
virtual ~AdActor3DX();
AdPath3D *_path3D;
AdPath *_path2D;
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
float dirToAngle(TDirection dir);
TDirection angleToDir(float angle);
bool updateAttachments();
bool displayAttachments(bool registerObjects);
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
private:
bool parseEffect(char *buffer);
BaseArray<AdAttach3DX *> _attachments;
bool turnToStep(float velocity);
bool prepareTurn(float targetAngle);
bool mergeAnimations(const char *filename);
bool mergeAnimations2(const char *filename);
bool unloadAnimation(const char *animName);
bool isGoToNeeded(int32 x, int32 y);
};
} // namespace Wintermute
#endif

View File

@@ -0,0 +1,265 @@
/* 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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#include "engines/wintermute/ad/ad_attach_3dx.h"
#include "engines/wintermute/base/base_active_rect.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/gfx/3dshadow_volume.h"
#include "engines/wintermute/base/gfx/opengl/base_render_opengl3d.h"
#include "engines/wintermute/base/gfx/xmodel.h"
#include "engines/wintermute/base/scriptables/script.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdAttach3DX, false)
//////////////////////////////////////////////////////////////////////////
AdAttach3DX::AdAttach3DX(BaseGame *inGame, BaseObject *owner) : AdObject3D(inGame) {
_owner = owner;
_parentBone = nullptr;
_dropToFloor = false;
}
//////////////////////////////////////////////////////////////////////////
AdAttach3DX::~AdAttach3DX() {
SAFE_DELETE_ARRAY(_parentBone);
_owner = nullptr; // ref only
}
//////////////////////////////////////////////////////////////////////////
bool AdAttach3DX::init(const char *modelFile, const char *name, const char *parentBone) {
SAFE_DELETE(_xmodel);
BaseUtils::setString(&_parentBone, parentBone);
setName(name);
_xmodel = new XModel(_game, _owner);
if (!_xmodel) {
return false;
}
bool res = _xmodel->loadFromFile(modelFile);
if (!res) {
SAFE_DELETE(_xmodel);
}
return res;
}
//////////////////////////////////////////////////////////////////////////
bool AdAttach3DX::update() {
AdObject3D::update();
if (_xmodel) {
return _xmodel->update();
} else {
return true;
}
}
//////////////////////////////////////////////////////////////////////////
bool AdAttach3DX::displayAttachable(DXMatrix *viewMat, bool registerObjects) {
BaseRenderer3D *renderer = _game->_renderer3D;
DXMatrix finalMat;
DXMatrixMultiply(&finalMat, &_worldMatrix, viewMat);
renderer->setWorldTransform(finalMat);
if (_xmodel) {
_xmodel->render();
if (registerObjects && _owner && _owner->_registrable) {
renderer->_rectList.add(new BaseActiveRect(_game, _owner, _xmodel, _xmodel->_boundingRect.left, _xmodel->_boundingRect.top, _xmodel->_boundingRect.right - _xmodel->_boundingRect.left, _xmodel->_boundingRect.bottom - _xmodel->_boundingRect.top, true));
}
}
_game->_renderer3D->invalidateLastTexture();
return true;
}
//////////////////////////////////////////////////////////////////////////
bool AdAttach3DX::displayShadowVol(DXMatrix *modelMat, DXVector3 *light, float extrusionDepth, bool update) {
BaseRenderer3D *renderer = _game->_renderer3D;
DXMatrix finalMat;
DXMatrixMultiply(&finalMat, &_worldMatrix, modelMat);
if (_xmodel) {
if (update) {
getShadowVolume()->reset();
_xmodel->updateShadowVol(getShadowVolume(), &finalMat, light, extrusionDepth);
}
renderer->setWorldTransform(finalMat);
getShadowVolume()->renderToStencilBuffer();
}
return true;
}
//////////////////////////////////////////////////////////////////////////
char *AdAttach3DX::getParentBone() {
return _parentBone;
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool AdAttach3DX::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
//////////////////////////////////////////////////////////////////////////
// PlayAnim / PlayAnimAsync
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "PlayAnim") == 0 || strcmp(name, "PlayAnimAsync") == 0) {
stack->correctParams(1);
const char *animName = stack->pop()->getString();
if (!_xmodel || !_xmodel->playAnim(0, animName, 0, true)) {
stack->pushBool(false);
} else {
if (strcmp(name, "PlayAnimAsync") != 0)
script->waitFor(this);
stack->pushBool(true);
}
return true;
}
//////////////////////////////////////////////////////////////////////////
// StopAnim
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "StopAnim") == 0) {
stack->correctParams(0);
bool ret = false;
if (_xmodel) {
ret = _xmodel->stopAnim(0);
}
stack->pushBool(ret);
return true;
}
//////////////////////////////////////////////////////////////////////////
// StopAnimChannel
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "StopAnimChannel") == 0) {
stack->correctParams(1);
int channel = stack->pop()->getInt();
bool ret = false;
if (_xmodel) {
ret = _xmodel->stopAnim(channel, 0);
}
stack->pushBool(ret);
return true;
}
//////////////////////////////////////////////////////////////////////////
// PlayAnimChannel / PlayAnimChannelAsync
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "PlayAnimChannel") == 0 || strcmp(name, "PlayAnimChannelAsync") == 0) {
stack->correctParams(2);
int channel = stack->pop()->getInt();
const char *animName = stack->pop()->getString();
if (!_xmodel || !_xmodel->playAnim(channel, animName, 0, true)) {
stack->pushBool(false);
} else {
if (strcmp(name, "PlayAnimChannelAsync") != 0) {
script->waitFor(this);
}
stack->pushBool(true);
}
return true;
}
else {
return AdObject3D::scCallMethod(script, stack, thisStack, name);
}
}
//////////////////////////////////////////////////////////////////////////
ScValue *AdAttach3DX::scGetProperty(const char *name) {
_scValue->setNULL();
//////////////////////////////////////////////////////////////////////////
// Type
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Type") == 0) {
_scValue->setString("attachment");
return _scValue;
} else {
return AdObject3D::scGetProperty(name);
}
}
//////////////////////////////////////////////////////////////////////////
bool AdAttach3DX::scSetProperty(const char *name, ScValue *value) {
return AdObject3D::scSetProperty(name, value);
}
//////////////////////////////////////////////////////////////////////////
const char *AdAttach3DX::scToString() {
return "[attachment object]";
}
//////////////////////////////////////////////////////////////////////////
bool AdAttach3DX::persist(BasePersistenceManager *persistMgr) {
AdObject3D::persist(persistMgr);
persistMgr->transferPtr(TMEMBER(_owner));
persistMgr->transferCharPtr(TMEMBER(_parentBone));
return true;
}
//////////////////////////////////////////////////////////////////////////
bool AdAttach3DX::invalidateDeviceObjects() {
if (_xmodel) {
_xmodel->invalidateDeviceObjects();
}
if (_shadowModel) {
_shadowModel->invalidateDeviceObjects();
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool AdAttach3DX::restoreDeviceObjects() {
if (_xmodel) {
_xmodel->restoreDeviceObjects();
}
if (_shadowModel) {
_shadowModel->restoreDeviceObjects();
}
return true;
}
} // namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#ifndef WINTERMUTE_AD_ATTACH_3DX_H
#define WINTERMUTE_AD_ATTACH_3DX_H
#include "engines/wintermute/ad/ad_object_3d.h"
namespace Wintermute {
class AdAttach3DX : public AdObject3D {
public:
DECLARE_PERSISTENT(AdAttach3DX, AdObject3D)
AdAttach3DX(BaseGame *inGame, BaseObject *owner);
virtual ~AdAttach3DX();
bool init(const char *modelFile, const char *name, const char *parentBone);
bool update() override;
bool displayAttachable(DXMatrix *viewMat, bool registerObjects);
bool displayShadowVol(DXMatrix *modelMat, DXVector3 *light, float extrusionDepth, bool update);
bool invalidateDeviceObjects() override;
bool restoreDeviceObjects() override;
char *getParentBone();
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
private:
BaseObject *_owner;
char *_parentBone;
};
} // namespace Wintermute
#endif

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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#include "engines/wintermute/ad/ad_block.h"
#include "engines/wintermute/base/base_persistence_manager.h"
#include "engines/wintermute/base/gfx/3dmesh.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
//////////////////////////////////////////////////////////////////////////
AdBlock::AdBlock(BaseGame *inGame) : BaseScriptable(inGame, false, false) {
_mesh = nullptr;
_active = true;
_receiveShadows = false;
}
//////////////////////////////////////////////////////////////////////////
AdBlock::~AdBlock() {
SAFE_DELETE(_mesh);
}
//////////////////////////////////////////////////////////////////////////
bool AdBlock::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferBool(TMEMBER(_active));
return true;
}
} // namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#ifndef WINTERMUTE_AD_BLOCK_H
#define WINTERMUTE_AD_BLOCK_H
#include "engines/wintermute/base/base_scriptable.h"
namespace Wintermute {
class Mesh3DS;
class AdBlock : public BaseScriptable {
public:
bool _receiveShadows;
bool persist(BasePersistenceManager *persistMgr);
bool _active;
AdBlock(BaseGame *inGame);
virtual ~AdBlock();
Mesh3DS *_mesh;
};
} // namespace Wintermute
#endif

File diff suppressed because it is too large Load Diff

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADENTITY_H
#define WINTERMUTE_ADENTITY_H
#include "engines/wintermute/ad/ad_talk_holder.h"
namespace Wintermute {
class VideoTheoraPlayer;
class AdEntity : public AdTalkHolder {
public:
VideoTheoraPlayer *_theora;
bool setSprite(const char *filename);
int32 _walkToX;
int32 _walkToY;
TDirection _walkToDir;
void setItem(const char *itemName);
char *_item;
DECLARE_PERSISTENT(AdEntity, AdTalkHolder)
void updatePosition();
int32 getHeight() override;
BaseRegion *_region;
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
bool update() override;
bool display() override;
AdEntity(BaseGame *inGame);
~AdEntity() override;
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
TEntityType _subtype;
#ifdef ENABLE_FOXTAIL
int32 getHintX() const;
int32 getHintY() const;
#endif
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
Common::String debuggerToString() const override;
private:
#ifdef ENABLE_FOXTAIL
int32 _hintX;
int32 _hintY;
#endif
};
} // End of namespace Wintermute
#endif

File diff suppressed because it is too large Load Diff

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADGAME_H
#define WINTERMUTE_ADGAME_H
#include "engines/wintermute/ad/ad_types.h"
#include "engines/wintermute/base/base_game.h"
namespace Wintermute {
class AdItem;
class AdInventory;
class AdSceneState;
class AdScene;
class AdItem;
class AdObject;
class AdSentence;
class AdInventoryBox;
class AdResponseContext;
class AdResponseBox;
class AdGame : public BaseGame {
public:
bool onScriptShutdown(ScScript *script) override;
bool onMouseLeftDown() override;
bool onMouseLeftUp() override;
bool onMouseLeftDblClick() override;
bool onMouseRightDown() override;
bool onMouseRightUp() override;
bool displayDebugInfo() override;
virtual BaseObject *getNextAccessObject(BaseObject *currObject) override;
virtual BaseObject *getPrevAccessObject(BaseObject *currObject) override;
virtual bool getLayerSize(int *layerWidth, int *layerHeight, Common::Rect32 *viewport, bool *customViewport) override;
#ifdef ENABLE_WME3D
uint32 getAmbientLightColor() override;
bool getFogParams(bool *fogEnabled, uint32 *fogColor, float *start, float *end) override;
virtual bool renderShadowGeometry() override;
TShadowType getMaxShadowType(BaseObject *object = nullptr) override;
#endif
bool _smartItemCursor;
BaseArray<char *> _speechDirs;
bool addSpeechDir(const char *dir);
bool removeSpeechDir(const char *dir);
char *findSpeechFile(char *StringID);
bool deleteItem(AdItem *Item);
char *_itemsFile;
bool _tempDisableSaveState;
bool resetContent() override;
bool addItem(AdItem *item);
AdItem *getItemByName(const char *name) const;
BaseArray<AdItem *> _items;
AdObject *_inventoryOwner;
bool isItemTaken(char *itemName);
bool registerInventory(AdInventory *inv);
bool unregisterInventory(AdInventory *inv);
AdObject *_invObject;
BaseArray<AdInventory *> _inventories;
bool displayContent(bool update = true, bool displayAll = false) override;
char *_debugStartupScene;
char *_startupScene;
bool _initialScene;
bool gameResponseUsed(int id) const;
bool addGameResponse(int id);
bool resetResponse(int id);
bool branchResponseUsed(int id) const;
bool addBranchResponse(int id);
bool clearBranchResponses(char *name);
bool startDlgBranch(const char *branchName, const char *scriptName, const char *eventName);
bool endDlgBranch(const char *branchName, const char *scriptName, const char *eventName);
bool windowLoadHook(UIWindow *win, char **buf, char **params) override;
bool windowScriptMethodHook(UIWindow *win, ScScript *script, ScStack *stack, const char *name) override;
AdSceneState *getSceneState(const char *filename, bool saving);
BaseViewport *_sceneViewport;
int32 _texItemLifeTime;
int32 _texWalkLifeTime;
int32 _texStandLifeTime;
int32 _texTalkLifeTime;
TTalkSkipButton _talkSkipButton;
TVideoSkipButton _videoSkipButton;
bool getVersion(byte *verMajor, byte *verMinor, byte *extMajor, byte *extMinor) override;
bool scheduleChangeScene(const char *filename, bool fadeIn);
char *_scheduledScene;
bool _scheduledFadeIn;
void setPrevSceneName(const char *name);
void setPrevSceneFilename(const char *name);
char *_prevSceneName;
char *_prevSceneFilename;
AdItem *_selectedItem;
bool cleanup() override;
DECLARE_PERSISTENT(AdGame, BaseGame)
void finishSentences();
bool showCursor() override;
TGameStateEx _stateEx;
AdResponseBox *_responseBox;
AdInventoryBox *_inventoryBox;
bool displaySentences(bool frozen);
void addSentence(AdSentence *sentence);
bool changeScene(const char *filename, bool fadeIn);
bool removeObject(AdObject *object);
bool addObject(AdObject *object);
AdScene *_scene;
bool initLoop();
AdGame(const Common::String &gameId);
~AdGame() override;
BaseArray<AdObject *> _objects;
BaseArray<AdSentence *> _sentences;
BaseArray<AdSceneState *> _sceneStates;
BaseArray<char *> _dlgPendingBranches;
BaseArray<AdResponseContext *> _responsesBranch;
BaseArray<AdResponseContext *> _responsesGame;
bool loadFile(const char *filename) override;
bool loadBuffer(char *buffer, bool complete = true) override;
bool loadItemsFile(const char *filename, bool merge = false);
bool loadItemsBuffer(char *buffer, bool merge = false);
bool externalCall(ScScript *script, ScStack *stack, ScStack *thisStack, char *name) override;
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
bool validMouse();
Common::String debuggerToString() const override;
bool handleCustomActionStart(BaseGameCustomAction action) override;
bool handleCustomActionEnd(BaseGameCustomAction action) override;
};
} // End of namespace Wintermute
#endif

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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#include "engines/wintermute/ad/ad_generic.h"
#include "engines/wintermute/base/base_persistence_manager.h"
#include "engines/wintermute/base/gfx/3dmesh.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
//////////////////////////////////////////////////////////////////////////
AdGeneric::AdGeneric(BaseGame *inGame) : BaseScriptable(inGame, false, false) {
_mesh = nullptr;
_active = true;
_receiveShadows = false;
}
//////////////////////////////////////////////////////////////////////////
AdGeneric::~AdGeneric() {
SAFE_DELETE(_mesh);
}
//////////////////////////////////////////////////////////////////////////
bool AdGeneric::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferBool(TMEMBER(_active));
return true;
}
} // namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#ifndef WINTERMUTE_AD_GENERIC_H
#define WINTERMUTE_AD_GENERIC_H
#include "engines/wintermute/base/base_scriptable.h"
namespace Wintermute {
class Mesh3DS;
class AdGeneric : public BaseScriptable {
public:
bool _receiveShadows;
bool persist(BasePersistenceManager *persistMgr);
bool _active;
AdGeneric(BaseGame *inGame);
virtual ~AdGeneric();
Mesh3DS *_mesh;
};
} // namespace Wintermute
#endif

View File

@@ -0,0 +1,154 @@
/* 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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#include "engines/wintermute/ad/ad_geom_ext.h"
#include "engines/wintermute/ad/ad_geom_ext_node.h"
#include "engines/wintermute/ad/ad_types.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/utils/utils.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
//////////////////////////////////////////////////////////////////////////
AdGeomExt::AdGeomExt(BaseGame *in_game) : BaseClass(in_game) {
}
//////////////////////////////////////////////////////////////////////////
AdGeomExt::~AdGeomExt() {
for (int32 i = 0; i < _nodes.getSize(); i++) {
SAFE_DELETE(_nodes[i]);
}
_nodes.removeAll();
}
//////////////////////////////////////////////////////////////////////////
bool AdGeomExt::loadFile(char *filename) {
char *buffer = (char *)BaseFileManager::getEngineInstance()->readWholeFile(filename);
if (buffer == nullptr) {
_game->LOG(0, "AdGeomExt::LoadFile failed for file '%s'", filename);
return false;
}
bool ret = loadBuffer(buffer);
if (!ret) {
_game->LOG(0, "Error parsing geometry description file '%s'", filename);
}
delete[] buffer;
return ret;
}
TOKEN_DEF_START
TOKEN_DEF(GEOMETRY)
TOKEN_DEF(NODE)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool AdGeomExt::loadBuffer(char *buffer) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(GEOMETRY)
TOKEN_TABLE(NODE)
TOKEN_TABLE_END
char *params;
int cmd;
BaseParser parser(_game);
if (parser.getCommand(&buffer, commands, &params) != TOKEN_GEOMETRY) {
_game->LOG(0, "'GEOMETRY' keyword expected.");
return false;
}
buffer = params;
while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_NODE: {
AdGeomExtNode *node = new AdGeomExtNode(_game);
if (node && node->loadBuffer(params, false)) {
_nodes.add(node);
} else {
SAFE_DELETE(node);
cmd = PARSERR_GENERIC;
}
}
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in geometry description file");
return false;
}
if (cmd == PARSERR_GENERIC) {
_game->LOG(0, "Error loading geometry description");
return false;
}
addStandardNodes();
return true;
}
//////////////////////////////////////////////////////////////////////////
bool AdGeomExt::addStandardNodes() {
AdGeomExtNode *node;
node = new AdGeomExtNode(_game);
node->setupNode("walk_*", GEOM_WALKPLANE, true);
_nodes.add(node);
node = new AdGeomExtNode(_game);
node->setupNode("blk_*", GEOM_BLOCKED, false);
_nodes.add(node);
node = new AdGeomExtNode(_game);
node->setupNode("wpt_*", GEOM_WAYPOINT, false);
_nodes.add(node);
return true;
}
//////////////////////////////////////////////////////////////////////////
AdGeomExtNode *AdGeomExt::matchName(const char *name) {
if (!name) {
return nullptr;
}
for (int32 i = 0; i < _nodes.getSize(); i++) {
if (_nodes[i]->matchesName(name)) {
return _nodes[i];
}
}
return nullptr;
}
} // namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#ifndef WINTERMUTE_AD_GEOM_EXT_H
#define WINTERMUTE_AD_GEOM_EXT_H
#include "engines/wintermute/base/base.h"
#include "engines/wintermute/coll_templ.h"
namespace Wintermute {
class AdGeomExtNode;
class AdGeomExt : public BaseClass {
public:
AdGeomExt(BaseGame *inGame);
virtual ~AdGeomExt();
bool loadFile(char *filename);
bool loadBuffer(char *buffer);
bool addStandardNodes();
AdGeomExtNode *matchName(const char *name);
private:
BaseArray<AdGeomExtNode *> _nodes;
};
} // namespace Wintermute
#endif

View File

@@ -0,0 +1,146 @@
/* 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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#include "common/str.h"
#include "engines/wintermute/ad/ad_geom_ext_node.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/utils/utils.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
//////////////////////////////////////////////////////////////////////////
AdGeomExtNode::AdGeomExtNode(BaseGame *inGame) : BaseClass(inGame) {
_namePattern = nullptr;
_receiveShadows = false;
_type = GEOM_GENERIC;
}
//////////////////////////////////////////////////////////////////////////
AdGeomExtNode::~AdGeomExtNode() {
SAFE_DELETE_ARRAY(_namePattern);
}
TOKEN_DEF_START
TOKEN_DEF(NODE)
TOKEN_DEF(NAME)
TOKEN_DEF(WALKPLANE)
TOKEN_DEF(BLOCKED)
TOKEN_DEF(WAYPOINT)
TOKEN_DEF(RECEIVE_SHADOWS)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool AdGeomExtNode::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(NODE)
TOKEN_TABLE(NAME)
TOKEN_TABLE(WALKPLANE)
TOKEN_TABLE(BLOCKED)
TOKEN_TABLE(WAYPOINT)
TOKEN_TABLE(RECEIVE_SHADOWS)
TOKEN_TABLE_END
char *params;
int cmd = 2;
BaseParser parser(_game);
if (complete) {
if (parser.getCommand(&buffer, commands, &params) != TOKEN_NODE) {
_game->LOG(0, "'NODE' keyword expected.");
return false;
}
buffer = params;
}
while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_NAME:
BaseUtils::setString(&_namePattern, params);
break;
case TOKEN_RECEIVE_SHADOWS:
parser.scanStr(params, "%b", &_receiveShadows);
break;
case TOKEN_WALKPLANE: {
bool isWalkplane = false;
parser.scanStr(params, "%b", &isWalkplane);
if (isWalkplane) {
_type = GEOM_WALKPLANE;
}
break;
}
case TOKEN_BLOCKED: {
bool isBlocked = false;
parser.scanStr(params, "%b", &isBlocked);
if (isBlocked) {
_type = GEOM_BLOCKED;
}
break;
}
case TOKEN_WAYPOINT: {
bool isWaypoint = false;
parser.scanStr(params, "%b", &isWaypoint);
if (isWaypoint) {
_type = GEOM_WAYPOINT;
}
break;
}
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in geometry description file");
return false;
}
if (cmd == PARSERR_GENERIC) {
_game->LOG(0, "Error loading geometry description");
return false;
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool AdGeomExtNode::setupNode(const char *namePattern, TGeomNodeType type, bool receiveShadows) {
BaseUtils::setString(&_namePattern, namePattern);
_type = type;
_receiveShadows = receiveShadows;
return true;
}
//////////////////////////////////////////////////////////////////////////
bool AdGeomExtNode::matchesName(const char *name) {
return BaseUtils::matchesPattern(_namePattern, name);
}
} // namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#ifndef WINTERMUTE_AD_GEOM_EXT_NODE_H
#define WINTERMUTE_AD_GEOM_EXT_NODE_H
#include "engines/wintermute/ad/ad_types.h"
#include "engines/wintermute/base/base.h"
namespace Wintermute {
class AdGeomExtNode : public BaseClass {
public:
AdGeomExtNode(BaseGame *inGame);
virtual ~AdGeomExtNode();
bool loadBuffer(char *buffer, bool complete);
bool setupNode(const char *namePattern, TGeomNodeType type = GEOM_GENERIC, bool receiveShadows = false);
bool matchesName(const char *name);
bool _receiveShadows;
TGeomNodeType _type;
private:
char *_namePattern;
};
} // namespace Wintermute
#endif

View File

@@ -0,0 +1,135 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_inventory.h"
#include "engines/wintermute/ad/ad_game.h"
#include "engines/wintermute/ad/ad_item.h"
#include "engines/wintermute/platform_osystem.h"
#include "common/str.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdInventory, false)
//////////////////////////////////////////////////////////////////////////
AdInventory::AdInventory(BaseGame *inGame) : BaseObject(inGame) {
_scrollOffset = 0;
}
//////////////////////////////////////////////////////////////////////////
AdInventory::~AdInventory() {
_takenItems.removeAll(); // ref only
}
//////////////////////////////////////////////////////////////////////////
bool AdInventory::insertItem(const char *name, const char *insertAfter) {
if (name == nullptr) {
return STATUS_FAILED;
}
AdItem *item = ((AdGame *)_game)->getItemByName(name);
if (item == nullptr) {
return STATUS_FAILED;
}
int32 insertIndex = -1;
for (int32 i = 0; i < _takenItems.getSize(); i++) {
if (scumm_stricmp(_takenItems[i]->_name, name) == 0) {
_takenItems.removeAt(i);
i--;
continue;
}
if (insertAfter && scumm_stricmp(_takenItems[i]->_name, insertAfter) == 0) {
insertIndex = i + 1;
}
}
if (insertIndex == -1) {
_takenItems.add(item);
} else {
_takenItems.insertAt(insertIndex, item);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdInventory::removeItem(const char *name) {
if (name == nullptr) {
return STATUS_FAILED;
}
for (int32 i = 0; i < _takenItems.getSize(); i++) {
if (scumm_stricmp(_takenItems[i]->_name, name) == 0) {
if (((AdGame *)_game)->_selectedItem == _takenItems[i]) {
((AdGame *)_game)->_selectedItem = nullptr;
}
_takenItems.removeAt(i);
return STATUS_OK;
}
}
return STATUS_FAILED;
}
//////////////////////////////////////////////////////////////////////////
bool AdInventory::removeItem(AdItem *item) {
if (item == nullptr) {
return STATUS_FAILED;
}
for (int32 i = 0; i < _takenItems.getSize(); i++) {
if (_takenItems[i] == item) {
if (((AdGame *)_game)->_selectedItem == _takenItems[i]) {
((AdGame *)_game)->_selectedItem = nullptr;
}
_takenItems.removeAt(i);
return STATUS_OK;
}
}
return STATUS_FAILED;
}
//////////////////////////////////////////////////////////////////////////
bool AdInventory::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
_takenItems.persist(persistMgr);
persistMgr->transferSint32(TMEMBER(_scrollOffset));
return STATUS_OK;
}
} // End of namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADINVENTORY_H
#define WINTERMUTE_ADINVENTORY_H
#include "engines/wintermute/base/base_object.h"
namespace Wintermute {
class AdItem;
class AdInventory : public BaseObject {
public:
DECLARE_PERSISTENT(AdInventory, BaseObject)
bool removeItem(const char *name);
bool removeItem(AdItem *Item);
bool insertItem(const char *name, const char *insertAfter = nullptr);
AdInventory(BaseGame *inGame);
~AdInventory() override;
BaseArray<AdItem *> _takenItems;
int32 _scrollOffset;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,390 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_game.h"
#include "engines/wintermute/ad/ad_inventory_box.h"
#include "engines/wintermute/ad/ad_inventory.h"
#include "engines/wintermute/ad/ad_item.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/base_viewport.h"
#include "engines/wintermute/base/base_dynamic_buffer.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "engines/wintermute/ui/ui_button.h"
#include "engines/wintermute/ui/ui_window.h"
#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/dcgf.h"
#include "common/str.h"
#include "common/rect.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdInventoryBox, false)
//////////////////////////////////////////////////////////////////////////
AdInventoryBox::AdInventoryBox(BaseGame *inGame) : BaseObject(inGame) {
BasePlatform::setRectEmpty(&_itemsArea);
_scrollOffset = 0;
_spacing = 0;
_itemWidth = _itemHeight = 50;
_scrollBy = 1;
_window = nullptr;
_closeButton = nullptr;
_hideSelected = false;
_visible = false;
_exclusive = false;
}
//////////////////////////////////////////////////////////////////////////
AdInventoryBox::~AdInventoryBox() {
_game->unregisterObject(_window);
_window = nullptr;
SAFE_DELETE(_closeButton);
}
//////////////////////////////////////////////////////////////////////////
bool AdInventoryBox::listen(BaseScriptHolder *param1, uint32 param2) {
UIObject *obj = (UIObject *)param1;
switch (obj->_type) {
case UI_BUTTON:
if (scumm_stricmp(obj->_name, "close") == 0) {
_visible = false;
} else if (scumm_stricmp(obj->_name, "prev") == 0) {
_scrollOffset -= _scrollBy;
_scrollOffset = MAX<int32>(_scrollOffset, 0);
} else if (scumm_stricmp(obj->_name, "next") == 0) {
_scrollOffset += _scrollBy;
} else {
return BaseObject::listen(param1, param2);
}
break;
default:
break;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdInventoryBox::display() {
AdGame *adGame = (AdGame *)_game;
if (!_visible) {
return STATUS_OK;
}
int itemsX, itemsY;
itemsX = (int)floor((float)((_itemsArea.right - _itemsArea.left + _spacing) / (_itemWidth + _spacing)));
itemsY = (int)floor((float)((_itemsArea.bottom - _itemsArea.top + _spacing) / (_itemHeight + _spacing)));
if (_window) {
_window->enableWidget("prev", _scrollOffset > 0);
_window->enableWidget("next", _scrollOffset + itemsX * itemsY < adGame->_inventoryOwner->getInventory()->_takenItems.getSize());
}
if (_closeButton) {
_closeButton->_posX = _closeButton->_posY = 0;
_closeButton->_width = _game->_renderer->getWidth();
_closeButton->_height = _game->_renderer->getHeight();
_closeButton->display();
}
// display window
Common::Rect32 rect = _itemsArea;
if (_window) {
BasePlatform::offsetRect(&rect, _window->_posX, _window->_posY);
_window->display();
}
// display items
if (_window && _window->_alphaColor != 0) {
_game->_renderer->_forceAlphaColor = _window->_alphaColor;
}
int yyy = rect.top;
for (int j = 0; j < itemsY; j++) {
int xxx = rect.left;
for (int i = 0; i < itemsX; i++) {
int itemIndex = _scrollOffset + j * itemsX + i;
if (itemIndex >= 0 && itemIndex < adGame->_inventoryOwner->getInventory()->_takenItems.getSize()) {
AdItem *item = adGame->_inventoryOwner->getInventory()->_takenItems[itemIndex];
if (item != ((AdGame *)_game)->_selectedItem || !_hideSelected) {
item->update();
item->display(xxx, yyy);
}
}
xxx += (_itemWidth + _spacing);
}
yyy += (_itemHeight + _spacing);
}
if (_window && _window->_alphaColor != 0) {
_game->_renderer->_forceAlphaColor = 0;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdInventoryBox::loadFile(const char *filename) {
char *buffer = (char *)_game->_fileManager->readWholeFile(filename);
if (buffer == nullptr) {
_game->LOG(0, "AdInventoryBox::loadFile failed for file '%s'", filename);
return STATUS_FAILED;
}
bool ret;
setFilename(filename);
if (DID_FAIL(ret = loadBuffer(buffer, true))) {
_game->LOG(0, "Error parsing INVENTORY_BOX file '%s'", filename);
}
delete[] buffer;
return ret;
}
TOKEN_DEF_START
TOKEN_DEF(INVENTORY_BOX)
TOKEN_DEF(TEMPLATE)
TOKEN_DEF(WINDOW)
TOKEN_DEF(EXCLUSIVE)
TOKEN_DEF(ALWAYS_VISIBLE)
TOKEN_DEF(AREA)
TOKEN_DEF(SPACING)
TOKEN_DEF(ITEM_WIDTH)
TOKEN_DEF(ITEM_HEIGHT)
TOKEN_DEF(SCROLL_BY)
TOKEN_DEF(NAME)
TOKEN_DEF(CAPTION)
TOKEN_DEF(HIDE_SELECTED)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool AdInventoryBox::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(INVENTORY_BOX)
TOKEN_TABLE(TEMPLATE)
TOKEN_TABLE(WINDOW)
TOKEN_TABLE(EXCLUSIVE)
TOKEN_TABLE(ALWAYS_VISIBLE)
TOKEN_TABLE(AREA)
TOKEN_TABLE(SPACING)
TOKEN_TABLE(ITEM_WIDTH)
TOKEN_TABLE(ITEM_HEIGHT)
TOKEN_TABLE(SCROLL_BY)
TOKEN_TABLE(NAME)
TOKEN_TABLE(CAPTION)
TOKEN_TABLE(HIDE_SELECTED)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
char *params;
int cmd = 2;
BaseParser parser(_game);
bool alwaysVisible = false;
_exclusive = false;
if (complete) {
if (parser.getCommand(&buffer, commands, &params) != TOKEN_INVENTORY_BOX) {
_game->LOG(0, "'INVENTORY_BOX' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
setName(params);
break;
case TOKEN_CAPTION:
setCaption(params);
break;
case TOKEN_WINDOW:
SAFE_DELETE(_window);
_window = new UIWindow(_game);
if (!_window || DID_FAIL(_window->loadBuffer(params, false))) {
SAFE_DELETE(_window);
cmd = PARSERR_GENERIC;
} else {
_game->registerObject(_window);
}
break;
case TOKEN_AREA:
parser.scanStr(params, "%d,%d,%d,%d", &_itemsArea.left, &_itemsArea.top, &_itemsArea.right, &_itemsArea.bottom);
break;
case TOKEN_EXCLUSIVE:
parser.scanStr(params, "%b", &_exclusive);
break;
case TOKEN_HIDE_SELECTED:
parser.scanStr(params, "%b", &_hideSelected);
break;
case TOKEN_ALWAYS_VISIBLE:
parser.scanStr(params, "%b", &alwaysVisible);
break;
case TOKEN_SPACING:
parser.scanStr(params, "%d", &_spacing);
break;
case TOKEN_ITEM_WIDTH:
parser.scanStr(params, "%d", &_itemWidth);
break;
case TOKEN_ITEM_HEIGHT:
parser.scanStr(params, "%d", &_itemHeight);
break;
case TOKEN_SCROLL_BY:
parser.scanStr(params, "%d", &_scrollBy);
break;
case TOKEN_EDITOR_PROPERTY:
parseEditorProperty(params, false);
break;
default:
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in INVENTORY_BOX definition");
return STATUS_FAILED;
}
if (cmd == PARSERR_GENERIC) {
_game->LOG(0, "Error loading INVENTORY_BOX definition");
return STATUS_FAILED;
}
if (_exclusive) {
SAFE_DELETE(_closeButton);
_closeButton = new UIButton(_game);
if (_closeButton) {
_closeButton->setName("close");
_closeButton->setListener(this, _closeButton, 0);
_closeButton->_parent = _window;
}
}
_visible = alwaysVisible;
if (_window) {
for (int32 i = 0; i < _window->_widgets.getSize(); i++) {
if (!_window->_widgets[i]->_listenerObject) {
_window->_widgets[i]->setListener(this, _window->_widgets[i], 0);
}
}
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdInventoryBox::saveAsText(BaseDynamicBuffer *buffer, int indent) {
buffer->putTextIndent(indent, "INVENTORY_BOX\n");
buffer->putTextIndent(indent, "{\n");
buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", _name);
buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
buffer->putTextIndent(indent + 2, "AREA { %d, %d, %d, %d }\n", _itemsArea.left, _itemsArea.top, _itemsArea.right, _itemsArea.bottom);
buffer->putTextIndent(indent + 2, "EXCLUSIVE=%s\n", _exclusive ? "TRUE" : "FALSE");
buffer->putTextIndent(indent + 2, "HIDE_SELECTED=%s\n", _hideSelected ? "TRUE" : "FALSE");
buffer->putTextIndent(indent + 2, "ALWAYS_VISIBLE=%s\n", _visible ? "TRUE" : "FALSE");
buffer->putTextIndent(indent + 2, "SPACING=%d\n", _spacing);
buffer->putTextIndent(indent + 2, "ITEM_WIDTH=%d\n", _itemWidth);
buffer->putTextIndent(indent + 2, "ITEM_HEIGHT=%d\n", _itemHeight);
buffer->putTextIndent(indent + 2, "SCROLL_BY=%d\n", _scrollBy);
buffer->putTextIndent(indent + 2, "\n");
// window
if (_window) {
_window->saveAsText(buffer, indent + 2);
}
buffer->putTextIndent(indent + 2, "\n");
// editor properties
BaseClass::saveAsText(buffer, indent + 2);
buffer->putTextIndent(indent, "}\n");
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdInventoryBox::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_closeButton));
persistMgr->transferBool(TMEMBER(_hideSelected));
persistMgr->transferSint32(TMEMBER(_itemHeight));
persistMgr->transferRect32(TMEMBER(_itemsArea));
persistMgr->transferSint32(TMEMBER(_itemWidth));
persistMgr->transferSint32(TMEMBER(_scrollBy));
persistMgr->transferSint32(TMEMBER(_scrollOffset));
persistMgr->transferSint32(TMEMBER(_spacing));
persistMgr->transferBool(TMEMBER(_visible));
persistMgr->transferPtr(TMEMBER_PTR(_window));
persistMgr->transferBool(TMEMBER(_exclusive));
return STATUS_OK;
}
} // End of namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADINVENTORYBOX_H
#define WINTERMUTE_ADINVENTORYBOX_H
#include "engines/wintermute/base/base_object.h"
#include "common/rect.h"
namespace Wintermute {
class UIButton;
class UIWindow;
class AdInventoryBox : public BaseObject {
public:
bool _hideSelected;
DECLARE_PERSISTENT(AdInventoryBox, BaseObject)
bool _exclusive;
int32 _scrollBy;
int32 _itemHeight;
int32 _itemWidth;
bool _visible;
bool display() override;
UIButton *_closeButton;
int32 _spacing;
int32 _scrollOffset;
Common::Rect32 _itemsArea;
bool listen(BaseScriptHolder *param1, uint32 param2) override;
UIWindow *_window;
AdInventoryBox(BaseGame *inGame);
~AdInventoryBox() override;
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,840 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_item.h"
#include "engines/wintermute/ad/ad_game.h"
#include "engines/wintermute/ad/ad_sentence.h"
#include "engines/wintermute/base/font/base_font_storage.h"
#include "engines/wintermute/base/font/base_font.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/base/sound/base_sound.h"
#include "engines/wintermute/base/base_sprite.h"
#include "engines/wintermute/base/scriptables/script.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/utils/utils.h"
#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/dcgf.h"
#include "common/str.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdItem, false)
//////////////////////////////////////////////////////////////////////////
AdItem::AdItem(BaseGame *inGame) : AdTalkHolder(inGame) {
_spriteHover = nullptr;
_cursorNormal = _cursorHover = nullptr;
_cursorCombined = true;
_inInventory = false;
_displayAmount = false;
_amount = 0;
_amountOffsetX = 0;
_amountOffsetY = 0;
_amountAlign = TAL_RIGHT;
_amountString = nullptr;
_state = STATE_READY;
_movable = false;
}
//////////////////////////////////////////////////////////////////////////
AdItem::~AdItem() {
SAFE_DELETE(_spriteHover);
SAFE_DELETE(_cursorNormal);
SAFE_DELETE(_cursorHover);
SAFE_DELETE_ARRAY(_amountString);
}
//////////////////////////////////////////////////////////////////////////
bool AdItem::loadFile(const char *filename) {
char *buffer = (char *)_game->_fileManager->readWholeFile(filename);
if (buffer == nullptr) {
_game->LOG(0, "AdItem::loadFile failed for file '%s'", filename);
return STATUS_FAILED;
}
bool ret;
setFilename(filename);
if (DID_FAIL(ret = loadBuffer(buffer, true))) {
_game->LOG(0, "Error parsing ITEM file '%s'", filename);
}
delete[] buffer;
return ret;
}
TOKEN_DEF_START
TOKEN_DEF(ITEM)
TOKEN_DEF(TEMPLATE)
TOKEN_DEF(CURSOR_HOVER)
TOKEN_DEF(CURSOR_COMBINED)
TOKEN_DEF(CURSOR)
TOKEN_DEF(NAME)
TOKEN_DEF(IMAGE_HOVER)
TOKEN_DEF(IMAGE)
TOKEN_DEF(EVENTS)
TOKEN_DEF(SCRIPT)
TOKEN_DEF(CAPTION)
TOKEN_DEF(PROPERTY)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF(FONT)
TOKEN_DEF(ALPHA_COLOR)
TOKEN_DEF(ALPHA)
TOKEN_DEF(TALK_SPECIAL)
TOKEN_DEF(TALK)
TOKEN_DEF(SPRITE_HOVER)
TOKEN_DEF(SPRITE)
TOKEN_DEF(DISPLAY_AMOUNT)
TOKEN_DEF(AMOUNT_OFFSET_X)
TOKEN_DEF(AMOUNT_OFFSET_Y)
TOKEN_DEF(AMOUNT_ALIGN)
TOKEN_DEF(AMOUNT_STRING)
TOKEN_DEF(AMOUNT)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool AdItem::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ITEM)
TOKEN_TABLE(TEMPLATE)
TOKEN_TABLE(CURSOR_HOVER)
TOKEN_TABLE(CURSOR_COMBINED)
TOKEN_TABLE(CURSOR)
TOKEN_TABLE(NAME)
TOKEN_TABLE(IMAGE_HOVER)
TOKEN_TABLE(IMAGE)
TOKEN_TABLE(EVENTS)
TOKEN_TABLE(SCRIPT)
TOKEN_TABLE(CAPTION)
TOKEN_TABLE(PROPERTY)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE(FONT)
TOKEN_TABLE(ALPHA_COLOR)
TOKEN_TABLE(ALPHA)
TOKEN_TABLE(TALK_SPECIAL)
TOKEN_TABLE(TALK)
TOKEN_TABLE(SPRITE_HOVER)
TOKEN_TABLE(SPRITE)
TOKEN_TABLE(DISPLAY_AMOUNT)
TOKEN_TABLE(AMOUNT_OFFSET_X)
TOKEN_TABLE(AMOUNT_OFFSET_Y)
TOKEN_TABLE(AMOUNT_ALIGN)
TOKEN_TABLE(AMOUNT_STRING)
TOKEN_TABLE(AMOUNT)
TOKEN_TABLE_END
char *params;
int cmd = 2;
BaseParser parser(_game);
if (complete) {
if (parser.getCommand(&buffer, commands, &params) != TOKEN_ITEM) {
_game->LOG(0, "'ITEM' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
int ar = 0, ag = 0, ab = 0, alpha = 255;
while (cmd > 0 && (cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
setName(params);
break;
case TOKEN_FONT:
setFont(params);
break;
case TOKEN_CAPTION:
setCaption(params);
break;
case TOKEN_IMAGE:
case TOKEN_SPRITE:
SAFE_DELETE(_sprite);
_sprite = new BaseSprite(_game, this);
if (!_sprite || DID_FAIL(_sprite->loadFile(params, ((AdGame *)_game)->_texItemLifeTime))) {
SAFE_DELETE(_sprite);
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_IMAGE_HOVER:
case TOKEN_SPRITE_HOVER:
SAFE_DELETE(_spriteHover);
_spriteHover = new BaseSprite(_game, this);
if (!_spriteHover || DID_FAIL(_spriteHover->loadFile(params, ((AdGame *)_game)->_texItemLifeTime))) {
SAFE_DELETE(_spriteHover);
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_AMOUNT:
parser.scanStr(params, "%d", &_amount);
break;
case TOKEN_DISPLAY_AMOUNT:
parser.scanStr(params, "%b", &_displayAmount);
break;
case TOKEN_AMOUNT_OFFSET_X:
parser.scanStr(params, "%d", &_amountOffsetX);
break;
case TOKEN_AMOUNT_OFFSET_Y:
parser.scanStr(params, "%d", &_amountOffsetY);
break;
case TOKEN_AMOUNT_ALIGN:
if (scumm_stricmp(params, "left") == 0) {
_amountAlign = TAL_LEFT;
} else if (scumm_stricmp(params, "right") == 0) {
_amountAlign = TAL_RIGHT;
} else {
_amountAlign = TAL_CENTER;
}
break;
case TOKEN_AMOUNT_STRING:
BaseUtils::setString(&_amountString, params);
break;
case TOKEN_TALK: {
BaseSprite *spr = new BaseSprite(_game, this);
if (!spr || DID_FAIL(spr->loadFile(params, ((AdGame *)_game)->_texTalkLifeTime))) {
cmd = PARSERR_GENERIC;
} else {
_talkSprites.add(spr);
}
}
break;
case TOKEN_TALK_SPECIAL: {
BaseSprite *spr = new BaseSprite(_game, this);
if (!spr || DID_FAIL(spr->loadFile(params, ((AdGame *)_game)->_texTalkLifeTime))) {
cmd = PARSERR_GENERIC;
} else {
_talkSpritesEx.add(spr);
}
}
break;
case TOKEN_CURSOR:
SAFE_DELETE(_cursorNormal);
_cursorNormal = new BaseSprite(_game);
if (!_cursorNormal || DID_FAIL(_cursorNormal->loadFile(params, ((AdGame *)_game)->_texItemLifeTime))) {
SAFE_DELETE(_cursorNormal);
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_CURSOR_HOVER:
SAFE_DELETE(_cursorHover);
_cursorHover = new BaseSprite(_game);
if (!_cursorHover || DID_FAIL(_cursorHover->loadFile(params, ((AdGame *)_game)->_texItemLifeTime))) {
SAFE_DELETE(_cursorHover);
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_CURSOR_COMBINED:
parser.scanStr(params, "%b", &_cursorCombined);
break;
case TOKEN_SCRIPT:
addScript(params);
break;
case TOKEN_PROPERTY:
parseProperty(params, false);
break;
case TOKEN_ALPHA_COLOR:
parser.scanStr(params, "%d,%d,%d", &ar, &ag, &ab);
break;
case TOKEN_ALPHA:
parser.scanStr(params, "%d", &alpha);
break;
case TOKEN_EDITOR_PROPERTY:
parseEditorProperty(params, false);
break;
default:
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in ITEM definition");
return STATUS_FAILED;
}
if (cmd == PARSERR_GENERIC) {
_game->LOG(0, "Error loading ITEM definition");
return STATUS_FAILED;
}
if (alpha != 0 && ar == 0 && ag == 0 && ab == 0) {
ar = ag = ab = 255;
}
_alphaColor = BYTETORGBA(ar, ag, ab, alpha);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdItem::update() {
_currentSprite = nullptr;
if (_state == STATE_READY && _animSprite) {
SAFE_DELETE(_animSprite);
}
// finished playing animation?
if (_state == STATE_PLAYING_ANIM && _animSprite != nullptr && _animSprite->_finished) {
_state = STATE_READY;
_currentSprite = _animSprite;
}
if (_sentence && _state != STATE_TALKING) {
_sentence->finish();
}
// default: stand animation
if (!_currentSprite) {
_currentSprite = _sprite;
}
switch (_state) {
//////////////////////////////////////////////////////////////////////////
case STATE_PLAYING_ANIM:
_currentSprite = _animSprite;
break;
//////////////////////////////////////////////////////////////////////////
case STATE_READY:
if (!_animSprite) {
if (_game->_activeObject == this && _spriteHover) {
_currentSprite = _spriteHover;
} else {
_currentSprite = _sprite;
}
}
break;
//////////////////////////////////////////////////////////////////////////
case STATE_TALKING: {
_sentence->update();
if (_sentence->_currentSprite) {
_tempSprite2 = _sentence->_currentSprite;
}
bool timeIsUp = (_sentence->_sound && _sentence->_soundStarted && (!_sentence->_sound->isPlaying() && !_sentence->_sound->isPaused())) || (!_sentence->_sound && _sentence->_duration <= _game->_timer - _sentence->_startTime);
if (_tempSprite2 == nullptr || _tempSprite2->_finished || (/*_tempSprite2->_looping &&*/ timeIsUp)) {
if (timeIsUp) {
_sentence->finish();
_tempSprite2 = nullptr;
_state = STATE_READY;
} else {
_tempSprite2 = getTalkStance(_sentence->getNextStance());
if (_tempSprite2) {
_tempSprite2->reset();
_currentSprite = _tempSprite2;
}
((AdGame *)_game)->addSentence(_sentence);
}
} else {
_currentSprite = _tempSprite2;
((AdGame *)_game)->addSentence(_sentence);
}
}
default:
break;
}
_ready = (_state == STATE_READY);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdItem::display(int x, int y) {
int width = 0;
if (_currentSprite) {
Common::Rect32 rc;
_currentSprite->getBoundingRect(&rc, 0, 0);
width = rc.right - rc.left;
}
_posX = x + width / 2;
_posY = y;
bool ret;
if (_currentSprite) {
ret = _currentSprite->draw(x, y, this, 100, 100, _alphaColor);
} else {
ret = STATUS_OK;
}
if (_displayAmount) {
int amountX = x;
int amountY = y + _amountOffsetY;
if (_amountAlign == TAL_RIGHT) {
width -= _amountOffsetX;
amountX -= _amountOffsetX;
}
amountX += _amountOffsetX;
BaseFont *font = _font ? _font : _game->_systemFont;
if (font) {
if (_amountString && _amountString[0]) {
font->drawText((byte *)_amountString, amountX, amountY, width, _amountAlign);
} else {
char str[256];
Common::sprintf_s(str, "%d", _amount);
font->drawText((byte *)str, amountX, amountY, width, _amountAlign);
}
}
}
return ret;
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool AdItem::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
//////////////////////////////////////////////////////////////////////////
// SetHoverSprite
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "SetHoverSprite") == 0) {
stack->correctParams(1);
bool setCurrent = false;
if (_currentSprite && _currentSprite == _spriteHover) {
setCurrent = true;
}
const char *filename = stack->pop()->getString();
SAFE_DELETE(_spriteHover);
BaseSprite *spr = new BaseSprite(_game, this);
if (!spr || DID_FAIL(spr->loadFile(filename))) {
stack->pushBool(false);
script->runtimeError("Item.SetHoverSprite failed for file '%s'", filename);
} else {
_spriteHover = spr;
if (setCurrent) {
_currentSprite = _spriteHover;
}
stack->pushBool(true);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// GetHoverSprite
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GetHoverSprite") == 0) {
stack->correctParams(0);
if (!_spriteHover || !_spriteHover->_filename || !_spriteHover->_filename[0]) {
stack->pushNULL();
} else {
stack->pushString(_spriteHover->_filename);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// GetHoverSpriteObject
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GetHoverSpriteObject") == 0) {
stack->correctParams(0);
if (!_spriteHover) {
stack->pushNULL();
} else {
stack->pushNative(_spriteHover, true);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// SetNormalCursor
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "SetNormalCursor") == 0) {
stack->correctParams(1);
const char *filename = stack->pop()->getString();
SAFE_DELETE(_cursorNormal);
BaseSprite *spr = new BaseSprite(_game);
if (!spr || DID_FAIL(spr->loadFile(filename))) {
stack->pushBool(false);
script->runtimeError("Item.SetNormalCursor failed for file '%s'", filename);
} else {
_cursorNormal = spr;
stack->pushBool(true);
}
return STATUS_OK;
}
#ifdef ENABLE_FOXTAIL
//////////////////////////////////////////////////////////////////////////
// [FoxTail] RemoveNormalCursor
// Used while changing cursor type at some included script
// Return value is never used
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "RemoveNormalCursor") == 0) {
stack->correctParams(0);
delete _cursorNormal;
_cursorNormal = nullptr;
stack->pushNULL();
return STATUS_OK;
}
#endif
//////////////////////////////////////////////////////////////////////////
// GetNormalCursor
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GetNormalCursor") == 0) {
stack->correctParams(0);
if (!_cursorNormal || !_cursorNormal->_filename || !_cursorNormal->_filename[0]) {
stack->pushNULL();
} else {
stack->pushString(_cursorNormal->_filename);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// GetNormalCursorObject
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GetNormalCursorObject") == 0) {
stack->correctParams(0);
if (!_cursorNormal) {
stack->pushNULL();
} else {
stack->pushNative(_cursorNormal, true);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// SetHoverCursor
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "SetHoverCursor") == 0) {
stack->correctParams(1);
const char *filename = stack->pop()->getString();
SAFE_DELETE(_cursorHover);
BaseSprite *spr = new BaseSprite(_game);
if (!spr || DID_FAIL(spr->loadFile(filename))) {
stack->pushBool(false);
script->runtimeError("Item.SetHoverCursor failed for file '%s'", filename);
} else {
_cursorHover = spr;
stack->pushBool(true);
}
return STATUS_OK;
}
#ifdef ENABLE_FOXTAIL
//////////////////////////////////////////////////////////////////////////
// [FoxTail] RemoveHoverCursor
// Used while changing cursor type at some included script
// Return value is never used
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "RemoveHoverCursor") == 0) {
stack->correctParams(0);
delete _cursorHover;
_cursorHover = nullptr;
stack->pushNULL();
return STATUS_OK;
}
#endif
//////////////////////////////////////////////////////////////////////////
// GetHoverCursor
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GetHoverCursor") == 0) {
stack->correctParams(0);
if (!_cursorHover || !_cursorHover->_filename || !_cursorHover->_filename[0]) {
stack->pushNULL();
} else {
stack->pushString(_cursorHover->_filename);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// GetHoverCursorObject
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GetHoverCursorObject") == 0) {
stack->correctParams(0);
if (!_cursorHover) {
stack->pushNULL();
} else {
stack->pushNative(_cursorHover, true);
}
return STATUS_OK;
} else {
return AdTalkHolder::scCallMethod(script, stack, thisStack, name);
}
}
//////////////////////////////////////////////////////////////////////////
ScValue *AdItem::scGetProperty(const char *name) {
_scValue->setNULL();
//////////////////////////////////////////////////////////////////////////
// Type
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Type") == 0) {
_scValue->setString("item");
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Name
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Name") == 0) {
_scValue->setString(_name);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// DisplayAmount
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "DisplayAmount") == 0) {
_scValue->setBool(_displayAmount);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Amount
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Amount") == 0) {
_scValue->setInt(_amount);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// AmountOffsetX
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AmountOffsetX") == 0) {
_scValue->setInt(_amountOffsetX);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// AmountOffsetY
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AmountOffsetY") == 0) {
_scValue->setInt(_amountOffsetY);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// AmountAlign
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AmountAlign") == 0) {
_scValue->setInt(_amountAlign);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// AmountString
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AmountString") == 0) {
if (!_amountString || _amountString[0]) {
_scValue->setNULL();
} else {
_scValue->setString(_amountString);
}
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// CursorCombined
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "CursorCombined") == 0) {
_scValue->setBool(_cursorCombined);
return _scValue;
} else {
return AdTalkHolder::scGetProperty(name);
}
}
//////////////////////////////////////////////////////////////////////////
bool AdItem::scSetProperty(const char *name, ScValue *value) {
//////////////////////////////////////////////////////////////////////////
// Name
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Name") == 0) {
setName(value->getString());
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// DisplayAmount
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "DisplayAmount") == 0) {
_displayAmount = value->getBool();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Amount
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Amount") == 0) {
_amount = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// AmountOffsetX
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AmountOffsetX") == 0) {
_amountOffsetX = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// AmountOffsetY
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AmountOffsetY") == 0) {
_amountOffsetY = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// AmountAlign
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AmountAlign") == 0) {
_amountAlign = (TTextAlign)value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// AmountString
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AmountString") == 0) {
if (value->isNULL()) {
SAFE_DELETE_ARRAY(_amountString);
} else {
BaseUtils::setString(&_amountString, value->getString());
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// CursorCombined
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "CursorCombined") == 0) {
_cursorCombined = value->getBool();
return STATUS_OK;
} else {
return AdTalkHolder::scSetProperty(name, value);
}
}
//////////////////////////////////////////////////////////////////////////
const char *AdItem::scToString() {
return "[item]";
}
//////////////////////////////////////////////////////////////////////////
bool AdItem::persist(BasePersistenceManager *persistMgr) {
AdTalkHolder::persist(persistMgr);
persistMgr->transferBool(TMEMBER(_cursorCombined));
persistMgr->transferPtr(TMEMBER_PTR(_cursorHover));
persistMgr->transferPtr(TMEMBER_PTR(_cursorNormal));
persistMgr->transferPtr(TMEMBER_PTR(_spriteHover));
persistMgr->transferBool(TMEMBER(_inInventory));
persistMgr->transferBool(TMEMBER(_displayAmount));
persistMgr->transferSint32(TMEMBER(_amount));
persistMgr->transferSint32(TMEMBER(_amountOffsetX));
persistMgr->transferSint32(TMEMBER(_amountOffsetY));
persistMgr->transferSint32(TMEMBER_INT(_amountAlign));
persistMgr->transferCharPtr(TMEMBER(_amountString));
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdItem::getExtendedFlag(const char *flagName) {
if (!flagName) {
return false;
} else if (strcmp(flagName, "usable") == 0) {
return true;
} else {
return AdObject::getExtendedFlag(flagName);
}
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,70 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADITEM_H
#define WINTERMUTE_ADITEM_H
#include "engines/wintermute/ad/ad_talk_holder.h"
namespace Wintermute {
class AdItem : public AdTalkHolder {
using Wintermute::AdObject::display;
public:
bool _displayAmount;
int32 _amount;
int32 _amountOffsetX;
int32 _amountOffsetY;
TTextAlign _amountAlign;
char *_amountString;
bool update() override;
DECLARE_PERSISTENT(AdItem, AdTalkHolder)
bool display(int x, int y);
bool getExtendedFlag(const char *flagName) override;
bool _inInventory;
bool _cursorCombined;
BaseSprite *_spriteHover;
BaseSprite *_cursorNormal;
BaseSprite *_cursorHover;
AdItem(BaseGame *inGame);
~AdItem() override;
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,566 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/ad/ad_layer.h"
#include "engines/wintermute/ad/ad_game.h"
#include "engines/wintermute/ad/ad_scene.h"
#include "engines/wintermute/ad/ad_scene_node.h"
#include "engines/wintermute/base/base_dynamic_buffer.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/base/scriptables/script.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/dcgf.h"
#include "common/str.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdLayer, false)
//////////////////////////////////////////////////////////////////////////
AdLayer::AdLayer(BaseGame *inGame) : BaseObject(inGame) {
_main = false;
_width = _height = 0;
_active = true;
_closeUp = false;
}
//////////////////////////////////////////////////////////////////////////
AdLayer::~AdLayer() {
for (int32 i = 0; i < _nodes.getSize(); i++) {
delete _nodes[i];
}
_nodes.removeAll();
}
//////////////////////////////////////////////////////////////////////////
bool AdLayer::loadFile(const char *filename) {
char *buffer = (char *)_game->_fileManager->readWholeFile(filename);
if (buffer == nullptr) {
_game->LOG(0, "AdLayer::loadFile failed for file '%s'", filename);
return STATUS_FAILED;
}
bool ret;
setFilename(filename);
if (DID_FAIL(ret = loadBuffer(buffer, true))) {
_game->LOG(0, "Error parsing LAYER file '%s'", filename);
}
delete[] buffer;
return ret;
}
TOKEN_DEF_START
TOKEN_DEF(LAYER)
TOKEN_DEF(TEMPLATE)
TOKEN_DEF(NAME)
TOKEN_DEF(WIDTH)
TOKEN_DEF(HEIGHT)
TOKEN_DEF(MAIN)
TOKEN_DEF(ENTITY)
TOKEN_DEF(REGION)
TOKEN_DEF(ACTIVE)
TOKEN_DEF(EDITOR_SELECTED)
TOKEN_DEF(SCRIPT)
TOKEN_DEF(CAPTION)
TOKEN_DEF(PROPERTY)
TOKEN_DEF(CLOSE_UP)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool AdLayer::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(LAYER)
TOKEN_TABLE(TEMPLATE)
TOKEN_TABLE(NAME)
TOKEN_TABLE(WIDTH)
TOKEN_TABLE(HEIGHT)
TOKEN_TABLE(MAIN)
TOKEN_TABLE(ENTITY)
TOKEN_TABLE(REGION)
TOKEN_TABLE(ACTIVE)
TOKEN_TABLE(EDITOR_SELECTED)
TOKEN_TABLE(SCRIPT)
TOKEN_TABLE(CAPTION)
TOKEN_TABLE(PROPERTY)
TOKEN_TABLE(CLOSE_UP)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
char *params;
int cmd;
BaseParser parser(_game);
if (complete) {
if (parser.getCommand(&buffer, commands, &params) != TOKEN_LAYER) {
_game->LOG(0, "'LAYER' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
setName(params);
break;
case TOKEN_CAPTION:
setCaption(params);
break;
case TOKEN_MAIN:
parser.scanStr(params, "%b", &_main);
break;
case TOKEN_CLOSE_UP:
parser.scanStr(params, "%b", &_closeUp);
break;
case TOKEN_WIDTH:
parser.scanStr(params, "%d", &_width);
break;
case TOKEN_HEIGHT:
parser.scanStr(params, "%d", &_height);
break;
case TOKEN_ACTIVE:
parser.scanStr(params, "%b", &_active);
break;
case TOKEN_REGION: {
AdRegion *region = new AdRegion(_game);
AdSceneNode *node = new AdSceneNode(_game);
if (!region || !node || DID_FAIL(region->loadBuffer(params, false))) {
cmd = PARSERR_GENERIC;
SAFE_DELETE(region);
SAFE_DELETE(node);
} else {
node->setRegion(region);
_nodes.add(node);
}
}
break;
case TOKEN_ENTITY: {
AdEntity *entity = new AdEntity(_game);
AdSceneNode *node = new AdSceneNode(_game);
if (entity) {
entity->_zoomable = false; // scene entites default to NOT zoom
}
if (!entity || !node || DID_FAIL(entity->loadBuffer(params, false))) {
cmd = PARSERR_GENERIC;
SAFE_DELETE(entity);
SAFE_DELETE(node);
} else {
node->setEntity(entity);
_nodes.add(node);
}
}
break;
case TOKEN_EDITOR_SELECTED:
parser.scanStr(params, "%b", &_editorSelected);
break;
case TOKEN_SCRIPT:
addScript(params);
break;
case TOKEN_PROPERTY:
parseProperty(params, false);
break;
case TOKEN_EDITOR_PROPERTY:
parseEditorProperty(params, false);
break;
default:
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in LAYER definition");
return STATUS_FAILED;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool AdLayer::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
//////////////////////////////////////////////////////////////////////////
// GetNode
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "GetNode") == 0) {
stack->correctParams(1);
ScValue *val = stack->pop();
int32 node = -1;
if (val->_type == VAL_INT) {
node = val->getInt();
} else { // get by name
for (int32 i = 0; i < _nodes.getSize(); i++) {
if ((_nodes[i]->_type == OBJECT_ENTITY && scumm_stricmp(_nodes[i]->_entity->_name, val->getString()) == 0) ||
(_nodes[i]->_type == OBJECT_REGION && scumm_stricmp(_nodes[i]->_region->_name, val->getString()) == 0)) {
node = i;
break;
}
}
}
if (node < 0 || node >= _nodes.getSize()) {
stack->pushNULL();
} else {
switch (_nodes[node]->_type) {
case OBJECT_ENTITY:
stack->pushNative(_nodes[node]->_entity, true);
break;
case OBJECT_REGION:
stack->pushNative(_nodes[node]->_region, true);
break;
default:
stack->pushNULL();
}
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// AddRegion / AddEntity
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AddRegion") == 0 || strcmp(name, "AddEntity") == 0) {
stack->correctParams(1);
ScValue *val = stack->pop();
AdSceneNode *node = new AdSceneNode(_game);
if (strcmp(name, "AddRegion") == 0) {
AdRegion *region = new AdRegion(_game);
if (!val->isNULL()) {
region->setName(val->getString());
}
node->setRegion(region);
stack->pushNative(region, true);
} else {
AdEntity *entity = new AdEntity(_game);
if (!val->isNULL()) {
entity->setName(val->getString());
}
node->setEntity(entity);
stack->pushNative(entity, true);
}
_nodes.add(node);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// InsertRegion / InsertEntity
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "InsertRegion") == 0 || strcmp(name, "InsertEntity") == 0) {
stack->correctParams(2);
int32 index = stack->pop()->getInt();
ScValue *val = stack->pop();
AdSceneNode *node = new AdSceneNode(_game);
if (strcmp(name, "InsertRegion") == 0) {
AdRegion *region = new AdRegion(_game);
if (!val->isNULL()) {
region->setName(val->getString());
}
node->setRegion(region);
stack->pushNative(region, true);
} else {
AdEntity *entity = new AdEntity(_game);
if (!val->isNULL()) {
entity->setName(val->getString());
}
node->setEntity(entity);
stack->pushNative(entity, true);
}
if (index < 0) {
index = 0;
}
if (index <= _nodes.getSize() - 1) {
_nodes.insertAt(index, node);
} else {
_nodes.add(node);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// DeleteNode
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "DeleteNode") == 0) {
stack->correctParams(1);
ScValue *val = stack->pop();
AdSceneNode *toDelete = nullptr;
if (val->isNative()) {
BaseScriptable *temp = val->getNative();
for (int32 i = 0; i < _nodes.getSize(); i++) {
if (_nodes[i]->_region == temp || _nodes[i]->_entity == temp) {
toDelete = _nodes[i];
break;
}
}
} else {
int32 index = val->getInt();
if (index >= 0 && index < _nodes.getSize()) {
toDelete = _nodes[index];
}
}
if (toDelete == nullptr) {
stack->pushBool(false);
return STATUS_OK;
}
for (int32 i = 0; i < _nodes.getSize(); i++) {
if (_nodes[i] == toDelete) {
SAFE_DELETE(_nodes[i]);
_nodes.removeAt(i);
break;
}
}
stack->pushBool(true);
return STATUS_OK;
} else {
return BaseObject::scCallMethod(script, stack, thisStack, name);
}
}
//////////////////////////////////////////////////////////////////////////
ScValue *AdLayer::scGetProperty(const char *name) {
_scValue->setNULL();
//////////////////////////////////////////////////////////////////////////
// Type
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Type") == 0) {
_scValue->setString("layer");
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// NumNodes (RO)
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "NumNodes") == 0) {
_scValue->setInt(_nodes.getSize());
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Width
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Width") == 0) {
_scValue->setInt(_width);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Height
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Height") == 0) {
_scValue->setInt(_height);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Main (RO)
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Main") == 0) {
_scValue->setBool(_main);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// CloseUp
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "CloseUp") == 0) {
_scValue->setBool(_closeUp);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Active
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Active") == 0) {
_scValue->setBool(_active);
return _scValue;
} else {
return BaseObject::scGetProperty(name);
}
}
//////////////////////////////////////////////////////////////////////////
bool AdLayer::scSetProperty(const char *name, ScValue *value) {
//////////////////////////////////////////////////////////////////////////
// Name
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Name") == 0) {
setName(value->getString());
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// CloseUp
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "CloseUp") == 0) {
_closeUp = value->getBool();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Width
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Width") == 0) {
_width = value->getInt();
if (_width < 0) {
_width = 0;
}
((AdGame *)_game)->_scene->onLayerResized(this);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Height
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Height") == 0) {
_height = value->getInt();
if (_height < 0) {
_height = 0;
}
((AdGame *)_game)->_scene->onLayerResized(this);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Active
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Active") == 0) {
bool b = value->getBool();
if (b == false && _main) {
_game->LOG(0, "Warning: cannot deactivate scene's main layer");
} else {
_active = b;
}
return STATUS_OK;
} else {
return BaseObject::scSetProperty(name, value);
}
}
//////////////////////////////////////////////////////////////////////////
const char *AdLayer::scToString() {
return "[layer]";
}
//////////////////////////////////////////////////////////////////////////
bool AdLayer::saveAsText(BaseDynamicBuffer *buffer, int indent) {
buffer->putTextIndent(indent, "LAYER {\n");
buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", _name);
buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
buffer->putTextIndent(indent + 2, "MAIN=%s\n", _main ? "TRUE" : "FALSE");
buffer->putTextIndent(indent + 2, "WIDTH=%d\n", _width);
buffer->putTextIndent(indent + 2, "HEIGHT=%d\n", _height);
buffer->putTextIndent(indent + 2, "ACTIVE=%s\n", _active ? "TRUE" : "FALSE");
buffer->putTextIndent(indent + 2, "EDITOR_SELECTED=%s\n", _editorSelected ? "TRUE" : "FALSE");
if (_closeUp) {
buffer->putTextIndent(indent + 2, "CLOSE_UP=%s\n", _closeUp ? "TRUE" : "FALSE");
}
for (int32 i = 0; i < _scripts.getSize(); i++) {
buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename);
}
if (_scProp) {
_scProp->saveAsText(buffer, indent + 2);
}
for (int32 i = 0; i < _nodes.getSize(); i++) {
switch (_nodes[i]->_type) {
case OBJECT_ENTITY:
_nodes[i]->_entity->saveAsText(buffer, indent + 2);
break;
case OBJECT_REGION:
_nodes[i]->_region->saveAsText(buffer, indent + 2);
break;
default:
break;
}
}
BaseClass::saveAsText(buffer, indent + 2);
buffer->putTextIndent(indent, "}\n\n");
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdLayer::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferBool(TMEMBER(_active));
persistMgr->transferBool(TMEMBER(_closeUp));
persistMgr->transferSint32(TMEMBER(_height));
persistMgr->transferBool(TMEMBER(_main));
_nodes.persist(persistMgr);
persistMgr->transferSint32(TMEMBER(_width));
return STATUS_OK;
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,57 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADLAYER_H
#define WINTERMUTE_ADLAYER_H
namespace Wintermute {
class AdSceneNode;
class AdLayer : public BaseObject {
public:
bool _closeUp;
DECLARE_PERSISTENT(AdLayer, BaseObject)
bool _active;
int32 _height;
int32 _width;
bool _main;
AdLayer(BaseGame *inGame);
~AdLayer() override;
BaseArray<AdSceneNode *> _nodes;
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,188 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/ad/ad_node_state.h"
#include "engines/wintermute/ad/ad_entity.h"
#include "engines/wintermute/base/base_sprite.h"
#include "engines/wintermute/utils/utils.h"
#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/dcgf.h"
#include "common/str.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdNodeState, false)
//////////////////////////////////////////////////////////////////////////
AdNodeState::AdNodeState(BaseGame *inGame) : BaseClass(inGame) {
_name = nullptr;
_active = false;
for (int i = 0; i < 7; i++) {
_caption[i] = nullptr;
}
_alphaColor = 0;
_filename = nullptr;
_cursor = nullptr;
}
//////////////////////////////////////////////////////////////////////////
AdNodeState::~AdNodeState() {
SAFE_DELETE_ARRAY(_name);
SAFE_DELETE_ARRAY(_filename);
SAFE_DELETE_ARRAY(_cursor);
for (int i = 0; i < 7; i++) {
SAFE_DELETE_ARRAY(_caption[i]);
}
}
//////////////////////////////////////////////////////////////////////////
void AdNodeState::setName(const char *name) {
SAFE_DELETE_ARRAY(_name);
BaseUtils::setString(&_name, name);
}
//////////////////////////////////////////////////////////////////////////
void AdNodeState::setFilename(const char *filename) {
SAFE_DELETE_ARRAY(_filename);
BaseUtils::setString(&_filename, filename);
}
//////////////////////////////////////////////////////////////////////////
void AdNodeState::setCursor(const char *filename) {
SAFE_DELETE_ARRAY(_cursor);
BaseUtils::setString(&_cursor, filename);
}
//////////////////////////////////////////////////////////////////////////
bool AdNodeState::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_game));
persistMgr->transferBool(TMEMBER(_active));
persistMgr->transferCharPtr(TMEMBER(_name));
persistMgr->transferCharPtr(TMEMBER(_filename));
persistMgr->transferCharPtr(TMEMBER(_cursor));
persistMgr->transferUint32(TMEMBER(_alphaColor));
for (int i = 0; i < 7; i++) {
persistMgr->transferCharPtr(TMEMBER(_caption[i]));
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
void AdNodeState::setCaption(const char *caption, int caseVal) {
if (caseVal == 0) {
caseVal = 1;
}
if (caseVal < 1 || caseVal > 7) {
return;
}
SAFE_DELETE_ARRAY(_caption[caseVal - 1]);
size_t captionSize = strlen(caption) + 1;
_caption[caseVal - 1] = new char[captionSize];
Common::strcpy_s(_caption[caseVal - 1], captionSize, caption);
_game->_stringTable->expand(&_caption[caseVal - 1]);
}
//////////////////////////////////////////////////////////////////////////
const char *AdNodeState::getCaption(int caseVal) {
if (caseVal == 0) {
caseVal = 1;
}
if (caseVal < 1 || caseVal > 7 || _caption[caseVal - 1] == nullptr) {
return "";
} else {
return _caption[caseVal - 1];
}
}
//////////////////////////////////////////////////////////////////////////
bool AdNodeState::transferEntity(AdEntity *entity, bool includingSprites, bool saving) {
if (!entity) {
return STATUS_FAILED;
}
// HACK!
if (this->_game != entity->_game) {
this->_game = entity->_game;
}
if (saving) {
for (int i = 0; i < 7; i++) {
if (entity->_caption[i]) {
setCaption(entity->_caption[i], i);
}
}
if (!entity->_region && entity->_sprite && entity->_sprite->_filename && entity->_sprite->_filename[0]) {
if (includingSprites) {
setFilename(entity->_sprite->_filename);
} else {
setFilename("");
}
}
if (entity->_cursor && entity->_cursor->_filename && entity->_cursor->_filename[0]) {
setCursor(entity->_cursor->_filename);
}
_alphaColor = entity->_alphaColor;
_active = entity->_active;
} else {
for (int i = 0; i < 7; i++) {
if (_caption[i] && _caption[i][0]) {
entity->setCaption(_caption[i], i);
}
}
if (_filename && _filename[0] && !entity->_region && includingSprites) {
if (!entity->_sprite || !entity->_sprite->_filename || scumm_stricmp(entity->_sprite->_filename, _filename) != 0) {
entity->setSprite(_filename);
}
}
if (_cursor && _cursor[0]) {
if (!entity->_cursor || !entity->_cursor->_filename || scumm_stricmp(entity->_cursor->_filename, _cursor) != 0) {
entity->setCursor(_cursor);
}
}
entity->_active = _active;
entity->_alphaColor = _alphaColor;
}
return STATUS_OK;
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,57 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADNODESTATE_H
#define WINTERMUTE_ADNODESTATE_H
namespace Wintermute {
class AdEntity;
class AdNodeState : public BaseClass {
public:
bool transferEntity(AdEntity *entity, bool includingSprites, bool saving);
void setName(const char *name);
void setFilename(const char *filename);
void setCursor(const char *filename);
DECLARE_PERSISTENT(AdNodeState, BaseClass)
AdNodeState(BaseGame *inGame);
~AdNodeState() override;
char *_name;
bool _active;
char *_caption[7];
void setCaption(const char *caption, int caseVal);
const char *getCaption(int caseVal);
uint32 _alphaColor;
char *_filename;
char *_cursor;
};
} // End of namespace Wintermute
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,124 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADOBJECT_H
#define WINTERMUTE_ADOBJECT_H
#include "engines/wintermute/ad/ad_types.h"
#include "engines/wintermute/base/base_object.h"
namespace Wintermute {
class AdWaypointGroup;
class AdRegion;
class AdSentence;
class BaseFont;
class BaseRegion;
class AdInventory;
class PartEmitter;
#define MAX_NUM_REGIONS 10
class AdObject : public BaseObject {
public:
PartEmitter *_partEmitter;
virtual PartEmitter *createParticleEmitter(bool followParent = false, int offsetX = 0, int offsetY = 0);
virtual bool updatePartEmitter();
bool _partFollowParent;
int32 _partOffsetX;
int32 _partOffsetY;
bool invalidateCurrRegions();
bool _subtitlesModRelative;
bool _subtitlesModXCenter;
int32 _subtitlesModX;
int32 _subtitlesModY;
int32 _subtitlesWidth;
AdRegion *_stickRegion;
bool _sceneIndependent;
bool _ignoreItems;
bool updateBlockRegion();
bool _forcedTalkAnimUsed;
char *_forcedTalkAnimName;
bool getExtendedFlag(const char *flagName) override;
bool resetSoundPan() override;
bool updateSounds() override;
bool reset();
DECLARE_PERSISTENT(AdObject, BaseObject)
virtual void talk(const char *text, const char *sound = nullptr, uint32 duration = 0, const char *stances = nullptr, TTextAlign align = TAL_CENTER);
int32 getHeight() override;
AdSentence *_sentence;
bool setFont(const char *filename);
bool update() override;
bool display() override;
bool _drawn;
bool _active;
virtual bool playAnim(const char *filename);
BaseSprite *_animSprite;
BaseSprite *_currentSprite;
TObjectState _state;
TObjectState _nextState;
TObjectType _type;
AdObject(BaseGame *inGame);
~AdObject() override;
BaseFont *_font;
BaseSprite *_tempSprite2;
BaseRegion *_blockRegion;
AdWaypointGroup *_wptGroup;
BaseRegion *_currentBlockRegion;
AdWaypointGroup *_currentWptGroup;
AdInventory *getInventory();
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
bool afterMove() override;
AdRegion *_currentRegions[MAX_NUM_REGIONS];
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
BaseArray<AdObject *> _attachmentsPre;
BaseArray<AdObject *> _attachmentsPost;
bool updateSpriteAttachments();
bool displaySpriteAttachments(bool preDisplay);
AdObject *_registerAlias;
private:
bool displaySpriteAttachment(AdObject *attachment);
AdInventory *_inventory;
protected:
bool getScale(float *scaleX, float *scaleY);
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,647 @@
/* 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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#include "engines/wintermute/ad/ad_game.h"
#include "engines/wintermute/ad/ad_object_3d.h"
#include "engines/wintermute/ad/ad_scene.h"
#include "engines/wintermute/ad/ad_scene_geometry.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "engines/wintermute/base/gfx/3dshadow_volume.h"
#include "engines/wintermute/base/gfx/opengl/base_render_opengl3d.h"
#include "engines/wintermute/base/gfx/xmodel.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/dcgf.h"
#include "engines/wintermute/utils/utils.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdObject3D, false)
//////////////////////////////////////////////////////////////////////////
AdObject3D::AdObject3D(BaseGame *inGame) : AdObject(inGame) {
_is3D = true;
_velocity = 1.0f;
_angVelocity = 1.0f;
_lastPosVector = DXVector3(0.0f, 0.0f, 0.0f);
_state = _nextState = STATE_READY;
_dropToFloor = true;
_shadowType = SHADOW_STENCIL;
_tempSkelAnim = nullptr;
_shadowVolume = nullptr;
_ambientLightColor = 0x00000000;
_hasAmbientLightColor = false;
}
//////////////////////////////////////////////////////////////////////////
AdObject3D::~AdObject3D() {
_tempSkelAnim = nullptr; // ref only
SAFE_DELETE(_shadowVolume);
clearIgnoredLights();
}
//////////////////////////////////////////////////////////////////////////
void AdObject3D::clearIgnoredLights() {
for (int32 i = 0; i < _ignoredLights.getSize(); ++i) {
delete _ignoredLights[i];
}
_ignoredLights.removeAll();
}
//////////////////////////////////////////////////////////////////////////
bool AdObject3D::addIgnoredLight(const char *lightName) {
for (int32 i = 0; i < _ignoredLights.getSize(); i++) {
if (scumm_stricmp(_ignoredLights[i], lightName) == 0) {
return true;
}
}
size_t tempSize = strlen(lightName) + 1;
char *temp = new char[tempSize];
Common::strcpy_s(temp, tempSize, lightName);
_ignoredLights.add(temp);
return true;
}
//////////////////////////////////////////////////////////////////////////
bool AdObject3D::removeIgnoredLight(const char *lightName) {
for (int32 i = 0; i < _ignoredLights.getSize(); i++) {
if (scumm_stricmp(_ignoredLights[i], lightName) == 0) {
delete[] _ignoredLights[i];
_ignoredLights.removeAt(i);
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////////////
bool AdObject3D::update() {
AdGame *adGame = (AdGame *)_game;
// drop to floor
if (_dropToFloor && adGame->_scene && adGame->_scene->_geom) {
_posVector._y = adGame->_scene->_geom->getHeightAt(_posVector, 5.0f);
}
getMatrix(&_worldMatrix);
// setup 2D position
if (_posVector != _lastPosVector) {
_lastPosVector = _posVector;
convert3DTo2D(&_worldMatrix, &_posX, &_posY);
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool AdObject3D::convert3DTo2D(DXMatrix *worldMat, int32 *posX, int32 *posY) {
BaseRenderer3D *renderer = _game->_renderer3D;
DXMatrix viewMat, projMat;
DXVector3 vec2d(0.0f, 0.0f, 0.0f);
renderer->getViewTransform(&viewMat);
renderer->getProjectionTransform(&projMat);
DXViewport viewport = renderer->getViewPort();
DXVector3 origin(0.0f, 0.0f, 0.0f);
DXVec3Project(&vec2d, &origin, &viewport, &projMat, &viewMat, worldMat);
*posX = vec2d._x + _game->_offsetX - _game->_renderer3D->_drawOffsetX;
*posY = vec2d._y + _game->_offsetY - _game->_renderer3D->_drawOffsetY;
return true;
}
//////////////////////////////////////////////////////////////////////////
bool AdObject3D::display() {
return true;
}
//////////////////////////////////////////////////////////////////////////
bool AdObject3D::setupLights() {
AdGame *adGame = (AdGame *)_game;
if (adGame->_scene && adGame->_scene->_geom) {
return adGame->_scene->_geom->enableLights(_posVector, _ignoredLights);
} else {
return false;
}
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool AdObject3D::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
//////////////////////////////////////////////////////////////////////////
// SkipTo
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "SkipTo") == 0) {
stack->correctParams(2);
int x = stack->pop()->getInt();
int y = stack->pop()->getInt();
skipTo(x, y);
stack->pushNULL();
return true;
}
//////////////////////////////////////////////////////////////////////////
// SkipTo3D
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "SkipTo3D") == 0) {
stack->correctParams(3);
_posVector._x = stack->pop()->getFloat();
_posVector._y = stack->pop()->getFloat();
_posVector._z = stack->pop()->getFloat();
stack->pushNULL();
return true;
}
//////////////////////////////////////////////////////////////////////////
// GetBonePosition2D
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GetBonePosition2D") == 0) {
stack->correctParams(1);
const char *boneName = stack->pop()->getString();
int32 x = 0, y = 0;
getBonePosition2D(boneName, &x, &y);
ScValue *val = stack->getPushValue();
if (val) {
val->setProperty("X", x);
val->setProperty("Y", y);
}
return true;
}
//////////////////////////////////////////////////////////////////////////
// GetBonePosition3D
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GetBonePosition3D") == 0) {
stack->correctParams(1);
const char *boneName = stack->pop()->getString();
DXVector3 pos(0, 0, 0);
getBonePosition3D(boneName, &pos);
ScValue *val = stack->getPushValue();
if (val) {
val->setProperty("X", pos._x);
val->setProperty("Y", pos._y);
val->setProperty("Z", pos._z);
}
return true;
}
//////////////////////////////////////////////////////////////////////////
// AddIgnoredLight
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AddIgnoredLight") == 0) {
stack->correctParams(1);
const char *lightName = stack->pop()->getString();
stack->pushBool(addIgnoredLight(lightName));
return true;
}
//////////////////////////////////////////////////////////////////////////
// RemoveIgnoredLight
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "RemoveIgnoredLight") == 0) {
stack->correctParams(1);
const char *lightName = stack->pop()->getString();
stack->pushBool(removeIgnoredLight(lightName));
return true;
}
else {
return AdObject::scCallMethod(script, stack, thisStack, name);
}
}
//////////////////////////////////////////////////////////////////////////
ScValue *AdObject3D::scGetProperty(const char *name) {
_scValue->setNULL();
//////////////////////////////////////////////////////////////////////////
// Angle
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Angle") == 0) {
_scValue->setFloat(_angle);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// PosX
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "PosX") == 0) {
_scValue->setFloat(_posVector._x);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// PosY
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "PosY") == 0) {
_scValue->setFloat(_posVector._y);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// PosZ
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "PosZ") == 0) {
_scValue->setFloat(_posVector._z);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Velocity
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Velocity") == 0) {
_scValue->setFloat(_velocity);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// AngularVelocity / AngVelocity
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AngularVelocity") == 0 || strcmp(name, "AngVelocity") == 0) {
_scValue->setFloat(_angVelocity);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// DropToFloor
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "DropToFloor") == 0) {
_scValue->setBool(_dropToFloor);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// ShadowType
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "ShadowType") == 0) {
_scValue->setInt(_shadowType);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Shadow (obsolete)
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Shadow") == 0) {
_scValue->setBool(_shadowType > SHADOW_NONE);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// SimpleShadow (obsolete)
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "SimpleShadow") == 0) {
_scValue->setBool(_shadowType == SHADOW_SIMPLE);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// ShadowColor
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "ShadowColor") == 0) {
_scValue->setInt(_shadowColor);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Scale
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Scale") == 0) {
_scValue->setFloat(_scale3D * 100.0f);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// DrawBackfaces
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "DrawBackfaces") == 0) {
_scValue->setBool(_drawBackfaces);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// AmbientLightColor
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AmbientLightColor") == 0) {
if (_hasAmbientLightColor) {
_scValue->setInt(_ambientLightColor);
} else {
_scValue->setNULL();
}
return _scValue;
}
else {
return AdObject::scGetProperty(name);
}
}
//////////////////////////////////////////////////////////////////////////
bool AdObject3D::scSetProperty(const char *name, ScValue *value) {
//////////////////////////////////////////////////////////////////////////
// Angle
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Angle") == 0) {
_angle = value->getFloat();
return true;
}
//////////////////////////////////////////////////////////////////////////
// PosX
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "PosX") == 0) {
_posVector._x = value->getFloat();
return true;
}
//////////////////////////////////////////////////////////////////////////
// PosY
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "PosY") == 0) {
_posVector._y = value->getFloat();
return true;
}
//////////////////////////////////////////////////////////////////////////
// PosZ
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "PosZ") == 0) {
_posVector._z = value->getFloat();
return true;
}
//////////////////////////////////////////////////////////////////////////
// X
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "X") == 0) {
_posX = value->getInt();
AdGame *adGame = (AdGame *)_game;
DXVector3 pos;
if (adGame->_scene->_geom && adGame->_scene->_geom->convert2Dto3D(_posX, _posY, &pos)) {
_posVector = pos;
}
return true;
}
//////////////////////////////////////////////////////////////////////////
// Y
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Y") == 0) {
_posY = value->getInt();
AdGame *adGame = (AdGame *)_game;
DXVector3 pos;
if (adGame->_scene->_geom && adGame->_scene->_geom->convert2Dto3D(_posX, _posY, &pos)) {
_posVector = pos;
}
return true;
}
//////////////////////////////////////////////////////////////////////////
// Velocity
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Velocity") == 0) {
_velocity = value->getFloat();
return true;
}
//////////////////////////////////////////////////////////////////////////
// AngularVelocity / AngVelocity
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AngularVelocity") == 0 || strcmp(name, "AngVelocity") == 0) {
_angVelocity = value->getFloat();
return true;
}
//////////////////////////////////////////////////////////////////////////
// DropToFloor
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "DropToFloor") == 0) {
_dropToFloor = value->getBool();
return true;
}
//////////////////////////////////////////////////////////////////////////
// Shadow (obsolete)
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Shadow") == 0) {
if (value->getBool()) {
_shadowType = SHADOW_STENCIL;
} else {
_shadowType = SHADOW_NONE;
}
return true;
}
//////////////////////////////////////////////////////////////////////////
// ShadowType
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "ShadowType") == 0) {
_shadowType = (TShadowType)value->getInt();
if (_shadowType < 0) {
_shadowType = SHADOW_NONE;
}
if (_shadowType > SHADOW_STENCIL) {
_shadowType = SHADOW_STENCIL;
}
return true;
}
//////////////////////////////////////////////////////////////////////////
// SimpleShadow (obsolete)
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "SimpleShadow") == 0) {
if (value->getBool()) {
_shadowType = SHADOW_SIMPLE;
} else {
_shadowType = SHADOW_STENCIL;
}
return true;
}
//////////////////////////////////////////////////////////////////////////
// ShadowColor
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "ShadowColor") == 0) {
_shadowColor = value->getInt();
return true;
}
//////////////////////////////////////////////////////////////////////////
// Scale
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Scale") == 0) {
_scale3D = value->getFloat() / 100.0f;
return true;
}
//////////////////////////////////////////////////////////////////////////
// DrawBackfaces
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "DrawBackfaces") == 0) {
_drawBackfaces = value->getBool();
return true;
}
//////////////////////////////////////////////////////////////////////////
// AmbientLightColor
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AmbientLightColor") == 0) {
if (value->isNULL()) {
_ambientLightColor = 0x00000000;
_hasAmbientLightColor = false;
} else {
_ambientLightColor = value->getInt();
_hasAmbientLightColor = true;
}
return true;
}
else {
return AdObject::scSetProperty(name, value);
}
}
//////////////////////////////////////////////////////////////////////////
const char *AdObject3D::scToString() {
return "[ad object3d]";
}
//////////////////////////////////////////////////////////////////////////
bool AdObject3D::persist(BasePersistenceManager *persistMgr) {
AdObject::persist(persistMgr);
persistMgr->transferFloat(TMEMBER(_angVelocity));
persistMgr->transferBool(TMEMBER(_dropToFloor));
persistMgr->transferCharPtr(TMEMBER(_tempSkelAnim));
persistMgr->transferVector3d(TMEMBER(_lastPosVector));
persistMgr->transferFloat(TMEMBER(_velocity));
if (!persistMgr->getIsSaving()) {
_shadowVolume = nullptr;
}
_ignoredLights.persist(persistMgr);
persistMgr->transferUint32(TMEMBER(_ambientLightColor));
persistMgr->transferBool(TMEMBER(_hasAmbientLightColor));
return true;
}
//////////////////////////////////////////////////////////////////////////
bool AdObject3D::skipTo(int x, int y, bool tolerant) {
AdGame *adGame = (AdGame *)_game;
DXVector3 pos;
bool success;
if (tolerant) {
success = adGame->_scene->_geom && adGame->_scene->_geom->convert2Dto3DTolerant(x, y, &pos);
} else {
success = adGame->_scene->_geom && adGame->_scene->_geom->convert2Dto3D(x, y, &pos);
}
if (success) {
_posVector = pos;
_posX = x;
_posY = y;
return true;
} else {
return false;
}
}
//////////////////////////////////////////////////////////////////////////
ShadowVolume *AdObject3D::getShadowVolume() {
if (_shadowVolume == nullptr)
_shadowVolume = _game->_renderer3D->createShadowVolume();
return _shadowVolume;
}
//////////////////////////////////////////////////////////////////////////
bool AdObject3D::getBonePosition2D(const char *boneName, int32 *x, int32 *y) {
if (!_xmodel) {
return false;
}
AdGame *adGame = (AdGame *)_game;
if (!adGame->_scene || !adGame->_scene->_geom)
return false;
DXMatrix *boneMat = _xmodel->getBoneMatrix(boneName);
if (!boneMat) {
return false;
}
DXMatrix bonePosMat;
DXMatrixMultiply(&bonePosMat, boneMat, &_worldMatrix);
DXVector4 vectBone4;
DXVector3 vectBone3(0, 0, 0);
DXVec3Transform(&vectBone4, &vectBone3, &bonePosMat);
DXVector3 vectBone(vectBone4._x, vectBone4._y, vectBone4._z);
adGame->_scene->_geom->convert3Dto2D(&vectBone, x, y);
return true;
}
//////////////////////////////////////////////////////////////////////////
bool AdObject3D::getBonePosition3D(const char *boneName, DXVector3 *pos, DXVector3 *offset) {
if (!_xmodel) {
return false;
}
DXMatrix *boneMat = _xmodel->getBoneMatrix(boneName);
if (!boneMat) {
return false;
}
DXVector3 vz(0, 0, 0);
if (!offset) {
offset = &vz;
}
DXMatrix bonePosMat;
DXMatrixMultiply(&bonePosMat, boneMat, &_worldMatrix);
DXVector4 vectBone4;
DXVec3Transform(&vectBone4, offset, &bonePosMat);
pos->_x = vectBone4._x;
pos->_y = vectBone4._y;
pos->_z = vectBone4._z;
return true;
}
} // namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#ifndef WINTERMUTE_AD_OBJECT_3D_H
#define WINTERMUTE_AD_OBJECT_3D_H
#include "engines/wintermute/ad/ad_object.h"
namespace Wintermute {
class ShadowVolume;
class AdObject3D : public AdObject {
public:
bool setupLights();
bool convert3DTo2D(DXMatrix *worldMat, int32 *posX, int32 *posY);
bool skipTo(int x, int y, bool tolerant = false);
char *_tempSkelAnim;
DXVector3 _lastPosVector;
DECLARE_PERSISTENT(AdObject3D, AdObject)
bool _dropToFloor;
bool display() override;
bool update() override;
AdObject3D(BaseGame *inGame);
virtual ~AdObject3D();
bool getBonePosition2D(const char *boneName, int32 *x, int32 *y);
bool getBonePosition3D(const char *boneName, DXVector3 *pos, DXVector3 *offset = nullptr);
float _velocity;
float _angVelocity;
uint32 _ambientLightColor;
bool _hasAmbientLightColor;
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
ShadowVolume *getShadowVolume();
private:
ShadowVolume *_shadowVolume;
BaseArray<char *> _ignoredLights;
void clearIgnoredLights();
bool addIgnoredLight(const char *lightName);
bool removeIgnoredLight(const char *lightName);
};
} // namespace Wintermute
#endif

View File

@@ -0,0 +1,119 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_path.h"
#include "engines/wintermute/base/base_point.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdPath, false)
//////////////////////////////////////////////////////////////////////////
AdPath::AdPath(BaseGame *inGame) : BaseClass(inGame) {
_currIndex = -1;
_ready = false;
}
//////////////////////////////////////////////////////////////////////////
AdPath::~AdPath() {
reset();
}
//////////////////////////////////////////////////////////////////////////
void AdPath::reset() {
for (int32 i = 0; i < _points.getSize(); i++) {
delete _points[i];
}
_points.removeAll();
_currIndex = -1;
_ready = false;
}
//////////////////////////////////////////////////////////////////////////
BasePoint *AdPath::getFirst() {
if (_points.getSize() > 0) {
_currIndex = 0;
return _points[_currIndex];
} else {
return nullptr;
}
}
//////////////////////////////////////////////////////////////////////////
BasePoint *AdPath::getNext() {
_currIndex++;
if (_currIndex < _points.getSize()) {
return _points[_currIndex];
} else {
return nullptr;
}
}
//////////////////////////////////////////////////////////////////////////
BasePoint *AdPath::getCurrent() {
if (_currIndex >= 0 && _currIndex < _points.getSize()) {
return _points[_currIndex];
} else {
return nullptr;
}
}
//////////////////////////////////////////////////////////////////////////
void AdPath::addPoint(BasePoint *point) {
_points.add(point);
}
//////////////////////////////////////////////////////////////////////////
bool AdPath::setReady(bool ready) {
bool orig = _ready;
_ready = ready;
return orig;
}
//////////////////////////////////////////////////////////////////////////
bool AdPath::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_game));
persistMgr->transferSint32(TMEMBER(_currIndex));
_points.persist(persistMgr);
persistMgr->transferBool(TMEMBER(_ready));
return STATUS_OK;
}
} // End of namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADPATH_H
#define WINTERMUTE_ADPATH_H
#include "engines/wintermute/persistent.h"
#include "engines/wintermute/coll_templ.h"
#include "engines/wintermute/base/base.h"
namespace Wintermute {
class BasePoint;
class AdPath : public BaseClass {
public:
DECLARE_PERSISTENT(AdPath, BaseClass)
BasePoint *getCurrent();
bool setReady(bool ready = true);
void addPoint(BasePoint *point);
BasePoint *getNext();
BasePoint *getFirst();
void reset();
AdPath(BaseGame *inGame);
~AdPath() override;
BaseArray<BasePoint *> _points;
int32 _currIndex;
bool _ready;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,134 @@
/* 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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#include "engines/wintermute/ad/ad_path3d.h"
#include "engines/wintermute/base/base_persistence_manager.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdPath3D, false)
//////////////////////////////////////////////////////////////////////////
AdPath3D::AdPath3D(BaseGame *inGame) : BaseClass(inGame) {
_currIndex = -1;
_ready = false;
}
//////////////////////////////////////////////////////////////////////////
AdPath3D::~AdPath3D() {
reset();
}
//////////////////////////////////////////////////////////////////////////
void AdPath3D::reset() {
for (int32 i = 0; i < _points.getSize(); i++) {
delete _points[i];
}
_points.removeAll();
_currIndex = -1;
_ready = false;
}
//////////////////////////////////////////////////////////////////////////
void AdPath3D::addPoint(DXVector3 point) {
_points.add(new DXVector3(point));
}
//////////////////////////////////////////////////////////////////////////
void AdPath3D::addPoint(float x, float y, float z) {
_points.add(new DXVector3(x, y, z));
}
//////////////////////////////////////////////////////////////////////////
bool AdPath3D::setReady(bool ready) {
bool orig = _ready;
_ready = ready;
return orig;
}
//////////////////////////////////////////////////////////////////////////
DXVector3 *AdPath3D::getFirst() {
if (_points.getSize() > 0) {
_currIndex = 0;
return _points[_currIndex];
} else {
return nullptr;
}
}
//////////////////////////////////////////////////////////////////////////
DXVector3 *AdPath3D::getNext() {
_currIndex++;
if (_currIndex < _points.getSize()) {
return _points[_currIndex];
} else {
return nullptr;
}
}
//////////////////////////////////////////////////////////////////////////
DXVector3 *AdPath3D::getCurrent() {
if (_currIndex >= 0 && _currIndex < _points.getSize()) {
return _points[_currIndex];
} else {
return nullptr;
}
}
//////////////////////////////////////////////////////////////////////////
bool AdPath3D::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER(_game));
persistMgr->transferSint32(TMEMBER(_currIndex));
persistMgr->transferBool(TMEMBER(_ready));
if (persistMgr->getIsSaving()) {
int32 j = _points.getSize();
persistMgr->transferSint32("ArraySize", &j);
for (int32 i = 0; i < j; i++) {
persistMgr->transferFloat("x", &_points[i]->_x);
persistMgr->transferFloat("y", &_points[i]->_y);
persistMgr->transferFloat("z", &_points[i]->_z);
}
} else {
int32 j = 0;
persistMgr->transferSint32("ArraySize", &j);
for (int32 i = 0; i < j; i++) {
float x, y, z;
persistMgr->transferFloat("x", &x);
persistMgr->transferFloat("y", &y);
persistMgr->transferFloat("z", &z);
addPoint(x, y, z);
}
}
return true;
}
} // namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#ifndef WINTERMUTE_AD_PATH3D_H
#define WINTERMUTE_AD_PATH3D_H
#include "engines/wintermute/base/base.h"
#include "engines/wintermute/coll_templ.h"
#include "engines/wintermute/persistent.h"
namespace Wintermute {
class AdPath3D : public BaseClass {
public:
DECLARE_PERSISTENT(AdPath3D, BaseClass)
DXVector3 *getCurrent();
DXVector3 *getNext();
DXVector3 *getFirst();
bool setReady(bool ready);
void addPoint(float x, float y, float z);
void addPoint(DXVector3 Point);
void reset();
AdPath3D(BaseGame *inGame);
virtual ~AdPath3D();
bool _ready;
BaseArray<DXVector3 *> _points;
int32 _currIndex;
};
} // namespace Wintermute
#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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_path_point.h"
#include "engines/wintermute/base/base_persistence_manager.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdPathPoint, false)
//////////////////////////////////////////////////////////////////////////
AdPathPoint::AdPathPoint() {
x = y = 0;
_distance = 0;
_marked = false;
_origin = nullptr;
}
//////////////////////////////////////////////////////////////////////////
AdPathPoint::AdPathPoint(int initX, int initY, int initDistance) {
x = initX;
y = initY;
_distance = initDistance;
_marked = false;
_origin = nullptr;
}
//////////////////////////////////////////////////////////////////////////
AdPathPoint::~AdPathPoint() {
_origin = nullptr;
}
//////////////////////////////////////////////////////////////////////////
bool AdPathPoint::persist(BasePersistenceManager *persistMgr) {
BasePoint::persist(persistMgr);
persistMgr->transferSint32(TMEMBER(_distance));
persistMgr->transferBool(TMEMBER(_marked));
persistMgr->transferPtr(TMEMBER_PTR(_origin));
return STATUS_OK;
}
} // End of namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADPATHPOINT_H
#define WINTERMUTE_ADPATHPOINT_H
#include "engines/wintermute/persistent.h"
#include "engines/wintermute/base/base_point.h"
namespace Wintermute {
class AdPathPoint : public BasePoint {
public:
DECLARE_PERSISTENT(AdPathPoint, BasePoint)
AdPathPoint(int initX, int initY, int initDistance);
AdPathPoint();
~AdPathPoint() override;
AdPathPoint *_origin;
bool _marked;
int32 _distance;
};
} // End of namespace Wintermute
#endif

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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#include "engines/wintermute/ad/ad_path_point3d.h"
#include "engines/wintermute/base/base_persistence_manager.h"
#include "engines/wintermute/base/gfx/xmath.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdPathPoint3D, false)
//////////////////////////////////////////////////////////////////////////
AdPathPoint3D::AdPathPoint3D() : BaseClass() {
_pos = DXVector3(0.0f, 0.0f, 0.0f);
_distance = 0.0f;
_marked = false;
_origin = nullptr;
}
//////////////////////////////////////////////////////////////////////////
AdPathPoint3D::AdPathPoint3D(DXVector3 pos, float dist) {
_pos = pos;
_distance = dist;
_marked = false;
_origin = nullptr;
}
//////////////////////////////////////////////////////////////////////////
AdPathPoint3D::~AdPathPoint3D() {
_origin = nullptr;
}
//////////////////////////////////////////////////////////////////////////
bool AdPathPoint3D::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferFloat(TMEMBER(_distance));
persistMgr->transferBool(TMEMBER(_marked));
persistMgr->transferPtr(TMEMBER(_origin));
persistMgr->transferFloat("x", &_pos._x);
persistMgr->transferFloat("y", &_pos._y);
persistMgr->transferFloat("z", &_pos._z);
return true;
}
} // namespace Wintermute

View File

@@ -0,0 +1,52 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#ifndef WINTERMUTE_AD_PATH_POINT3D_H
#define WINTERMUTE_AD_PATH_POINT3D_H
#include "engines/wintermute/persistent.h"
#include "engines/wintermute/base/base.h"
#include "engines/wintermute/base/gfx/xmath.h"
namespace Wintermute {
class AdPathPoint3D: public BaseClass {
public:
DECLARE_PERSISTENT(AdPathPoint3D, BaseClass)
AdPathPoint3D(DXVector3 pos, float dist);
AdPathPoint3D();
virtual ~AdPathPoint3D();
AdPathPoint3D *_origin;
bool _marked;
float _distance;
DXVector3 _pos;
};
}
#endif

View File

@@ -0,0 +1,399 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_region.h"
#include "engines/wintermute/base/base_dynamic_buffer.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/base/scriptables/script.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdRegion, false)
//////////////////////////////////////////////////////////////////////////
AdRegion::AdRegion(BaseGame *inGame) : BaseRegion(inGame) {
_blocked = false;
_decoration = false;
_zoom = 0;
_alpha = 0xFFFFFFFF;
}
//////////////////////////////////////////////////////////////////////////
AdRegion::~AdRegion() {
}
//////////////////////////////////////////////////////////////////////////
bool AdRegion::loadFile(const char *filename) {
char *buffer = (char *)_game->_fileManager->readWholeFile(filename);
if (buffer == nullptr) {
_game->LOG(0, "AdRegion::loadFile failed for file '%s'", filename);
return STATUS_FAILED;
}
bool ret;
setFilename(filename);
if (DID_FAIL(ret = loadBuffer(buffer, true))) {
_game->LOG(0, "Error parsing REGION file '%s'", filename);
}
delete[] buffer;
return ret;
}
TOKEN_DEF_START
TOKEN_DEF(REGION)
TOKEN_DEF(TEMPLATE)
TOKEN_DEF(NAME)
TOKEN_DEF(ACTIVE)
TOKEN_DEF(ZOOM)
TOKEN_DEF(SCALE)
TOKEN_DEF(BLOCKED)
TOKEN_DEF(DECORATION)
TOKEN_DEF(POINT)
TOKEN_DEF(ALPHA_COLOR)
TOKEN_DEF(ALPHA)
TOKEN_DEF(EDITOR_SELECTED_POINT)
TOKEN_DEF(EDITOR_SELECTED)
TOKEN_DEF(SCRIPT)
TOKEN_DEF(CAPTION)
TOKEN_DEF(PROPERTY)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool AdRegion::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(REGION)
TOKEN_TABLE(TEMPLATE)
TOKEN_TABLE(NAME)
TOKEN_TABLE(ACTIVE)
TOKEN_TABLE(ZOOM)
TOKEN_TABLE(SCALE)
TOKEN_TABLE(BLOCKED)
TOKEN_TABLE(DECORATION)
TOKEN_TABLE(POINT)
TOKEN_TABLE(ALPHA_COLOR)
TOKEN_TABLE(ALPHA)
TOKEN_TABLE(EDITOR_SELECTED_POINT)
TOKEN_TABLE(EDITOR_SELECTED)
TOKEN_TABLE(SCRIPT)
TOKEN_TABLE(CAPTION)
TOKEN_TABLE(PROPERTY)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
char *params;
int cmd;
BaseParser parser(_game);
if (complete) {
if (parser.getCommand(&buffer, commands, &params) != TOKEN_REGION) {
_game->LOG(0, "'REGION' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
for (int32 i = 0; i < _points.getSize(); i++) {
delete _points[i];
}
_points.removeAll();
int ar = 255, ag = 255, ab = 255, alpha = 255;
while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
setName(params);
break;
case TOKEN_CAPTION:
setCaption(params);
break;
case TOKEN_ACTIVE:
parser.scanStr(params, "%b", &_active);
break;
case TOKEN_BLOCKED:
parser.scanStr(params, "%b", &_blocked);
break;
case TOKEN_DECORATION:
parser.scanStr(params, "%b", &_decoration);
break;
case TOKEN_ZOOM:
case TOKEN_SCALE: {
int j;
parser.scanStr(params, "%d", &j);
_zoom = (float)j;
}
break;
case TOKEN_POINT: {
int x, y;
parser.scanStr(params, "%d,%d", &x, &y);
_points.add(new BasePoint(x, y));
}
break;
case TOKEN_ALPHA_COLOR:
parser.scanStr(params, "%d,%d,%d", &ar, &ag, &ab);
break;
case TOKEN_ALPHA:
parser.scanStr(params, "%d", &alpha);
break;
case TOKEN_EDITOR_SELECTED:
parser.scanStr(params, "%b", &_editorSelected);
break;
case TOKEN_EDITOR_SELECTED_POINT:
parser.scanStr(params, "%d", &_editorSelectedPoint);
break;
case TOKEN_SCRIPT:
addScript(params);
break;
case TOKEN_PROPERTY:
parseProperty(params, false);
break;
case TOKEN_EDITOR_PROPERTY:
parseEditorProperty(params, false);
break;
default:
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in REGION definition");
return STATUS_FAILED;
}
createRegion();
_alpha = BYTETORGBA(ar, ag, ab, alpha);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool AdRegion::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
/*
//////////////////////////////////////////////////////////////////////////
// SkipTo
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "SkipTo")==0) {
stack->correctParams(2);
_posX = stack->pop()->getInt();
_posY = stack->pop()->getInt();
stack->pushNULL();
return STATUS_OK;
}
else*/ return BaseRegion::scCallMethod(script, stack, thisStack, name);
}
//////////////////////////////////////////////////////////////////////////
ScValue *AdRegion::scGetProperty(const char *name) {
_scValue->setNULL();
//////////////////////////////////////////////////////////////////////////
// Type
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Type") == 0) {
_scValue->setString("ad region");
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Name
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Name") == 0) {
_scValue->setString(_name);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Blocked
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Blocked") == 0) {
_scValue->setBool(_blocked);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Decoration
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Decoration") == 0) {
_scValue->setBool(_decoration);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Scale
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Scale") == 0) {
_scValue->setFloat(_zoom);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// AlphaColor
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AlphaColor") == 0) {
_scValue->setInt((int)_alpha);
return _scValue;
} else {
return BaseRegion::scGetProperty(name);
}
}
//////////////////////////////////////////////////////////////////////////
bool AdRegion::scSetProperty(const char *name, ScValue *value) {
//////////////////////////////////////////////////////////////////////////
// Name
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Name") == 0) {
setName(value->getString());
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Blocked
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Blocked") == 0) {
_blocked = value->getBool();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Decoration
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Decoration") == 0) {
_decoration = value->getBool();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Scale
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Scale") == 0) {
_zoom = value->getFloat();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// AlphaColor
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AlphaColor") == 0) {
_alpha = (uint32)value->getInt();
return STATUS_OK;
} else {
return BaseRegion::scSetProperty(name, value);
}
}
//////////////////////////////////////////////////////////////////////////
const char *AdRegion::scToString() {
return "[ad region]";
}
//////////////////////////////////////////////////////////////////////////
bool AdRegion::saveAsText(BaseDynamicBuffer *buffer, int indent) {
buffer->putTextIndent(indent, "REGION {\n");
buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", _name);
buffer->putTextIndent(indent + 2, "CAPTION=\"%s\"\n", getCaption());
buffer->putTextIndent(indent + 2, "BLOCKED=%s\n", _blocked ? "TRUE" : "FALSE");
buffer->putTextIndent(indent + 2, "DECORATION=%s\n", _decoration ? "TRUE" : "FALSE");
buffer->putTextIndent(indent + 2, "ACTIVE=%s\n", _active ? "TRUE" : "FALSE");
buffer->putTextIndent(indent + 2, "SCALE=%d\n", (int)_zoom);
buffer->putTextIndent(indent + 2, "ALPHA_COLOR { %d,%d,%d }\n", RGBCOLGetR(_alpha), RGBCOLGetG(_alpha), RGBCOLGetB(_alpha));
buffer->putTextIndent(indent + 2, "ALPHA = %d\n", RGBCOLGetA(_alpha));
buffer->putTextIndent(indent + 2, "EDITOR_SELECTED=%s\n", _editorSelected ? "TRUE" : "FALSE");
for (int32 i = 0; i < _scripts.getSize(); i++) {
buffer->putTextIndent(indent + 2, "SCRIPT=\"%s\"\n", _scripts[i]->_filename);
}
if (_scProp) {
_scProp->saveAsText(buffer, indent + 2);
}
for (int32 i = 0; i < _points.getSize(); i++) {
buffer->putTextIndent(indent + 2, "POINT {%d,%d}\n", _points[i]->x, _points[i]->y);
}
BaseClass::saveAsText(buffer, indent + 2);
buffer->putTextIndent(indent, "}\n\n");
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdRegion::persist(BasePersistenceManager *persistMgr) {
BaseRegion::persist(persistMgr);
persistMgr->transferUint32(TMEMBER(_alpha));
persistMgr->transferBool(TMEMBER(_blocked));
persistMgr->transferBool(TMEMBER(_decoration));
persistMgr->transferFloat(TMEMBER(_zoom));
return STATUS_OK;
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,57 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADREGION_H
#define WINTERMUTE_ADREGION_H
#include "engines/wintermute/base/base_region.h"
namespace Wintermute {
class AdRegion : public BaseRegion {
public:
DECLARE_PERSISTENT(AdRegion, BaseRegion)
uint32 _alpha;
float _zoom;
bool _blocked;
bool _decoration;
AdRegion(BaseGame *inGame);
~AdRegion() override;
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,138 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_response.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_sprite.h"
#include "engines/wintermute/base/font/base_font_storage.h"
#include "engines/wintermute/utils/utils.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdResponse, false)
//////////////////////////////////////////////////////////////////////////
AdResponse::AdResponse(BaseGame *inGame) : BaseObject(inGame) {
_text = nullptr;
_textOrig = nullptr;
_icon = _iconHover = _iconPressed = nullptr;
_font = nullptr;
_id = 0;
_responseType = RESPONSE_ALWAYS;
}
//////////////////////////////////////////////////////////////////////////
AdResponse::~AdResponse() {
SAFE_DELETE_ARRAY(_text);
SAFE_DELETE_ARRAY(_textOrig);
SAFE_DELETE(_icon);
SAFE_DELETE(_iconHover);
SAFE_DELETE(_iconPressed);
if (_font) {
_game->_fontStorage->removeFont(_font);
}
}
//////////////////////////////////////////////////////////////////////////
void AdResponse::setText(const char *text) {
BaseUtils::setString(&_text, text);
BaseUtils::setString(&_textOrig, text);
}
//////////////////////////////////////////////////////////////////////////
bool AdResponse::setIcon(const char *filename) {
SAFE_DELETE(_icon);
_icon = new BaseSprite(_game);
if (!_icon || DID_FAIL(_icon->loadFile(filename))) {
_game->LOG(0, "AdResponse::setIcon failed for file '%s'", filename);
SAFE_DELETE(_icon);
return STATUS_FAILED;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdResponse::setFont(const char *filename) {
if (_font) {
_game->_fontStorage->removeFont(_font);
}
_font = _game->_fontStorage->addFont(filename);
if (!_font) {
_game->LOG(0, "AdResponse::setFont failed for file '%s'", filename);
return STATUS_FAILED;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdResponse::setIconHover(const char *filename) {
SAFE_DELETE(_iconHover);
_iconHover = new BaseSprite(_game);
if (!_iconHover || DID_FAIL(_iconHover->loadFile(filename))) {
_game->LOG(0, "AdResponse::setIconHover failed for file '%s'", filename);
SAFE_DELETE(_iconHover);
return STATUS_FAILED;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdResponse::setIconPressed(const char *filename) {
SAFE_DELETE(_iconPressed);
_iconPressed = new BaseSprite(_game);
if (!_iconPressed || DID_FAIL(_iconPressed->loadFile(filename))) {
_game->LOG(0, "AdResponse::setIconPressed failed for file '%s'", filename);
SAFE_DELETE(_iconPressed);
return STATUS_FAILED;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdResponse::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_icon));
persistMgr->transferPtr(TMEMBER_PTR(_iconHover));
persistMgr->transferPtr(TMEMBER_PTR(_iconPressed));
persistMgr->transferSint32(TMEMBER(_id));
persistMgr->transferCharPtr(TMEMBER(_text));
persistMgr->transferCharPtr(TMEMBER(_textOrig));
persistMgr->transferSint32(TMEMBER_INT(_responseType));
persistMgr->transferPtr(TMEMBER_PTR(_font));
return STATUS_OK;
}
} // End of namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADRESPONSE_H
#define WINTERMUTE_ADRESPONSE_H
#include "engines/wintermute/base/base_object.h"
#include "engines/wintermute/ad/ad_types.h"
namespace Wintermute {
class BaseFont;
class AdResponse : public BaseObject {
public:
DECLARE_PERSISTENT(AdResponse, BaseObject)
bool setIcon(const char *filename);
bool setFont(const char *filename);
bool setIconHover(const char *filename);
bool setIconPressed(const char *filename);
void setText(const char *text);
int32 _id;
BaseSprite *_icon;
BaseSprite *_iconHover;
BaseSprite *_iconPressed;
BaseFont *_font;
char *_text;
char *_textOrig;
AdResponse(BaseGame *inGame);
~AdResponse() override;
TResponseType _responseType;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,736 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_game.h"
#include "engines/wintermute/ad/ad_response.h"
#include "engines/wintermute/ad/ad_response_box.h"
#include "engines/wintermute/base/base_engine.h"
#include "engines/wintermute/base/base_dynamic_buffer.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/base/base_sprite.h"
#include "engines/wintermute/base/base_surface_storage.h"
#include "engines/wintermute/base/font/base_font_storage.h"
#include "engines/wintermute/base/font/base_font.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "engines/wintermute/base/scriptables/script.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
#include "engines/wintermute/ui/ui_button.h"
#include "engines/wintermute/ui/ui_window.h"
#include "engines/wintermute/utils/utils.h"
#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/wintermute.h"
#include "engines/wintermute/dcgf.h"
#include "common/str.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdResponseBox, false)
//////////////////////////////////////////////////////////////////////////
AdResponseBox::AdResponseBox(BaseGame *inGame) : BaseObject(inGame) {
_font = _fontHover = nullptr;
_window = nullptr;
_shieldWindow = new UIWindow(_game);
_horizontal = false;
BasePlatform::setRectEmpty(&_responseArea);
_scrollOffset = 0;
_spacing = 0;
_waitingScript = nullptr;
_lastResponseText = nullptr;
_lastResponseTextOrig = nullptr;
_verticalAlign = VAL_BOTTOM;
_align = TAL_LEFT;
}
//////////////////////////////////////////////////////////////////////////
AdResponseBox::~AdResponseBox() {
SAFE_DELETE(_window);
SAFE_DELETE(_shieldWindow);
SAFE_DELETE_ARRAY(_lastResponseText);
SAFE_DELETE_ARRAY(_lastResponseTextOrig);
if (_font) {
_game->_fontStorage->removeFont(_font);
}
if (_fontHover) {
_game->_fontStorage->removeFont(_fontHover);
}
clearResponses();
clearButtons();
_waitingScript = nullptr;
}
//////////////////////////////////////////////////////////////////////////
void AdResponseBox::clearResponses() {
for (int32 i = 0; i < _responses.getSize(); i++) {
delete _responses[i];
}
_responses.removeAll();
}
//////////////////////////////////////////////////////////////////////////
void AdResponseBox::clearButtons() {
for (int32 i = 0; i < _respButtons.getSize(); i++) {
delete _respButtons[i];
}
_respButtons.removeAll();
}
//////////////////////////////////////////////////////////////////////////
bool AdResponseBox::invalidateButtons() {
for (int32 i = 0; i < _respButtons.getSize(); i++) {
_respButtons[i]->_image = nullptr;
_respButtons[i]->_cursor = nullptr;
_respButtons[i]->_font = nullptr;
_respButtons[i]->_fontHover = nullptr;
_respButtons[i]->_fontPress = nullptr;
_respButtons[i]->setText("");
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdResponseBox::createButtons() {
clearButtons();
_scrollOffset = 0;
for (int32 i = 0; i < _responses.getSize(); i++) {
UIButton *btn = new UIButton(_game);
if (btn) {
btn->_parent = _window;
btn->_sharedFonts = btn->_sharedImages = true;
btn->_sharedCursors = true;
// iconic
if (_responses[i]->_icon) {
btn->_image = _responses[i]->_icon;
if (_responses[i]->_iconHover) {
btn->_imageHover = _responses[i]->_iconHover;
}
if (_responses[i]->_iconPressed) {
btn->_imagePress = _responses[i]->_iconPressed;
}
btn->setCaption(_responses[i]->_text);
if (_cursor) {
btn->_cursor = _cursor;
} else if (_game->_activeCursor) {
btn->_cursor = _game->_activeCursor;
}
}
// textual
else {
btn->setText(_responses[i]->_text);
btn->_font = (_font == nullptr) ? _game->_systemFont : _font;
btn->_fontHover = (_fontHover == nullptr) ? _game->_systemFont : _fontHover;
btn->_fontPress = btn->_fontHover;
btn->_align = _align;
if (_game->_touchInterface) {
btn->_fontHover = btn->_font;
}
if (_responses[i]->_font) {
btn->_font = _responses[i]->_font;
}
btn->_width = _responseArea.right - _responseArea.left;
if (btn->_width <= 0) {
btn->_width = _game->_renderer->getWidth();
}
}
#ifdef ENABLE_FOXTAIL
if (BaseEngine::instance().isFoxTail()) {
btn->addScript("interface/scripts/dialogue_button.script");
btn->_width = 120;
if (_fontHover == nullptr) {
btn->_fontHover = btn->_font;
btn->_fontPress = btn->_fontHover;
}
}
#endif
btn->setName("response");
btn->correctSize();
// make the responses touchable
if (_game->_touchInterface) {
btn->_height = MAX<int32>(btn->_height, 50);
}
//btn->setListener(this, btn, _responses[i]->_id);
btn->setListener(this, btn, i);
btn->_visible = false;
_respButtons.add(btn);
if (_responseArea.bottom - _responseArea.top < btn->_height) {
_game->LOG(0, "Warning: Response '%s' is too high to be displayed within response box. Correcting.", _responses[i]->_text);
_responseArea.bottom += (btn->_height - (_responseArea.bottom - _responseArea.top));
}
}
}
_ready = false;
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdResponseBox::loadFile(const char *filename) {
char *buffer = (char *)_game->_fileManager->readWholeFile(filename);
if (buffer == nullptr) {
_game->LOG(0, "AdResponseBox::loadFile failed for file '%s'", filename);
return STATUS_FAILED;
}
bool ret;
setFilename(filename);
if (DID_FAIL(ret = loadBuffer(buffer, true))) {
_game->LOG(0, "Error parsing RESPONSE_BOX file '%s'", filename);
}
delete[] buffer;
return ret;
}
TOKEN_DEF_START
TOKEN_DEF(RESPONSE_BOX)
TOKEN_DEF(TEMPLATE)
TOKEN_DEF(FONT_HOVER)
TOKEN_DEF(FONT)
TOKEN_DEF(AREA)
TOKEN_DEF(HORIZONTAL)
TOKEN_DEF(SPACING)
TOKEN_DEF(WINDOW)
TOKEN_DEF(CURSOR)
TOKEN_DEF(TEXT_ALIGN)
TOKEN_DEF(VERTICAL_ALIGN)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool AdResponseBox::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(RESPONSE_BOX)
TOKEN_TABLE(TEMPLATE)
TOKEN_TABLE(FONT_HOVER)
TOKEN_TABLE(FONT)
TOKEN_TABLE(AREA)
TOKEN_TABLE(HORIZONTAL)
TOKEN_TABLE(SPACING)
TOKEN_TABLE(WINDOW)
TOKEN_TABLE(CURSOR)
TOKEN_TABLE(TEXT_ALIGN)
TOKEN_TABLE(VERTICAL_ALIGN)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
char *params;
int cmd;
BaseParser parser(_game);
if (complete) {
if (parser.getCommand(&buffer, commands, &params) != TOKEN_RESPONSE_BOX) {
_game->LOG(0, "'RESPONSE_BOX' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_WINDOW:
SAFE_DELETE(_window);
_window = new UIWindow(_game);
if (!_window || DID_FAIL(_window->loadBuffer(params, false))) {
SAFE_DELETE(_window);
cmd = PARSERR_GENERIC;
} else if (_shieldWindow) {
_shieldWindow->_parent = _window;
}
break;
case TOKEN_FONT:
if (_font) {
_game->_fontStorage->removeFont(_font);
}
_font = _game->_fontStorage->addFont(params);
if (!_font) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_FONT_HOVER:
if (_fontHover) {
_game->_fontStorage->removeFont(_fontHover);
}
_fontHover = _game->_fontStorage->addFont(params);
if (!_fontHover) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_AREA:
parser.scanStr(params, "%d,%d,%d,%d", &_responseArea.left, &_responseArea.top, &_responseArea.right, &_responseArea.bottom);
break;
case TOKEN_HORIZONTAL:
parser.scanStr(params, "%b", &_horizontal);
break;
case TOKEN_TEXT_ALIGN:
if (scumm_stricmp(params, "center") == 0) {
_align = TAL_CENTER;
} else if (scumm_stricmp(params, "right") == 0) {
_align = TAL_RIGHT;
} else {
_align = TAL_LEFT;
}
break;
case TOKEN_VERTICAL_ALIGN:
if (scumm_stricmp(params, "top") == 0) {
_verticalAlign = VAL_TOP;
} else if (scumm_stricmp(params, "center") == 0) {
_verticalAlign = VAL_CENTER;
} else {
_verticalAlign = VAL_BOTTOM;
}
break;
case TOKEN_SPACING:
parser.scanStr(params, "%d", &_spacing);
break;
case TOKEN_EDITOR_PROPERTY:
parseEditorProperty(params, false);
break;
case TOKEN_CURSOR:
SAFE_DELETE(_cursor);
_cursor = new BaseSprite(_game);
if (!_cursor || DID_FAIL(_cursor->loadFile(params))) {
SAFE_DELETE(_cursor);
cmd = PARSERR_GENERIC;
}
break;
default:
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in RESPONSE_BOX definition");
return STATUS_FAILED;
}
if (_window) {
for (int32 i = 0; i < _window->_widgets.getSize(); i++) {
if (!_window->_widgets[i]->_listenerObject) {
_window->_widgets[i]->setListener(this, _window->_widgets[i], 0);
}
}
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdResponseBox::saveAsText(BaseDynamicBuffer *buffer, int indent) {
buffer->putTextIndent(indent, "RESPONSE_BOX\n");
buffer->putTextIndent(indent, "{\n");
buffer->putTextIndent(indent + 2, "AREA { %d, %d, %d, %d }\n", _responseArea.left, _responseArea.top, _responseArea.right, _responseArea.bottom);
if (_font && _font->_filename && _font->_filename[0]) {
buffer->putTextIndent(indent + 2, "FONT=\"%s\"\n", _font->_filename);
}
if (_fontHover && _fontHover->_filename && _fontHover->_filename[0]) {
buffer->putTextIndent(indent + 2, "FONT_HOVER=\"%s\"\n", _fontHover->_filename);
}
if (_cursor && _cursor->_filename && _cursor->_filename[0]) {
buffer->putTextIndent(indent + 2, "CURSOR=\"%s\"\n", _cursor->_filename);
}
buffer->putTextIndent(indent + 2, "HORIZONTAL=%s\n", _horizontal ? "TRUE" : "FALSE");
switch (_align) {
case TAL_LEFT:
buffer->putTextIndent(indent + 2, "TEXT_ALIGN=\"%s\"\n", "left");
break;
case TAL_RIGHT:
buffer->putTextIndent(indent + 2, "TEXT_ALIGN=\"%s\"\n", "right");
break;
case TAL_CENTER:
buffer->putTextIndent(indent + 2, "TEXT_ALIGN=\"%s\"\n", "center");
break;
default:
break;
}
switch (_verticalAlign) {
case VAL_TOP:
buffer->putTextIndent(indent + 2, "VERTICAL_ALIGN=\"%s\"\n", "top");
break;
case VAL_BOTTOM:
buffer->putTextIndent(indent + 2, "VERTICAL_ALIGN=\"%s\"\n", "bottom");
break;
case VAL_CENTER:
buffer->putTextIndent(indent + 2, "VERTICAL_ALIGN=\"%s\"\n", "center");
break;
default:
break;
}
buffer->putTextIndent(indent + 2, "SPACING=%d\n", _spacing);
buffer->putTextIndent(indent + 2, "\n");
// window
if (_window) {
_window->saveAsText(buffer, indent + 2);
}
buffer->putTextIndent(indent + 2, "\n");
// editor properties
BaseClass::saveAsText(buffer, indent + 2);
buffer->putTextIndent(indent, "}\n");
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdResponseBox::display() {
Common::Rect32 rect = _responseArea;
if (_window) {
BasePlatform::offsetRect(&rect, _window->_posX, _window->_posY);
//_window->display();
}
int xxx, yyy;
int32 i;
xxx = rect.left;
yyy = rect.top;
// shift down if needed
if (!_horizontal) {
int32 totalHeight = 0;
for (i = 0; i < _respButtons.getSize(); i++) {
totalHeight += (_respButtons[i]->_height + _spacing);
}
totalHeight -= _spacing;
switch (_verticalAlign) {
case VAL_BOTTOM:
if (yyy + totalHeight < rect.bottom) {
yyy = rect.bottom - totalHeight;
}
break;
case VAL_CENTER:
if (yyy + totalHeight < rect.bottom) {
yyy += ((rect.bottom - rect.top) - totalHeight) / 2;
}
break;
case VAL_TOP:
default:
// do nothing
break;
}
}
// prepare response buttons
bool scrollNeeded = false;
for (i = _scrollOffset; i < _respButtons.getSize(); i++) {
#ifdef ENABLE_FOXTAIL
// FoxTail's "HORIZONTAL=TRUE" display boxes are actual 2x3 display boxes
// Tests show that this hack was removed in FOXTAIL_1_2_362
if (_horizontal && BaseEngine::instance().isFoxTail(FOXTAIL_OLDEST_VERSION, FOXTAIL_1_2_304)) {
if (i >= _scrollOffset + 6) {
scrollNeeded = true;
break;
}
_respButtons[i]->_visible = true;
_respButtons[i]->_posX = 55 + 120 * (i / 3);
_respButtons[i]->_posY = 100 + 10 * (i % 3);
continue;
}
#endif
if ((_horizontal && xxx + _respButtons[i]->_width > rect.right) || (!_horizontal && yyy + _respButtons[i]->_height > rect.bottom)) {
scrollNeeded = true;
_respButtons[i]->_visible = false;
break;
}
_respButtons[i]->_visible = true;
_respButtons[i]->_posX = xxx;
_respButtons[i]->_posY = yyy;
if (_horizontal) {
xxx += (_respButtons[i]->_width + _spacing);
} else {
yyy += (_respButtons[i]->_height+ _spacing);
}
}
// show appropriate scroll buttons
if (_window) {
_window->showWidget("prev", _scrollOffset > 0);
_window->showWidget("next", scrollNeeded);
}
// go exclusive
if (_shieldWindow) {
_shieldWindow->_posX = _shieldWindow->_posY = 0;
_shieldWindow->_width = _game->_renderer->getWidth();
_shieldWindow->_height = _game->_renderer->getHeight();
_shieldWindow->display();
}
// display window
if (_window) {
_window->display();
}
// display response buttons
for (i = _scrollOffset; i < _respButtons.getSize(); i++) {
_respButtons[i]->display();
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdResponseBox::listen(BaseScriptHolder *param1, uint32 param2) {
UIObject *obj = (UIObject *)param1;
switch (obj->_type) {
case UI_BUTTON:
if (scumm_stricmp(obj->_name, "prev") == 0) {
_scrollOffset--;
} else if (scumm_stricmp(obj->_name, "next") == 0) {
_scrollOffset++;
} else if (scumm_stricmp(obj->_name, "response") == 0) {
if (_waitingScript) {
_waitingScript->_stack->pushInt(_responses[param2]->_id);
}
handleResponse(_responses[param2]);
_waitingScript = nullptr;
_game->_state = GAME_RUNNING;
((AdGame *)_game)->_stateEx = GAME_NORMAL;
_ready = true;
invalidateButtons();
clearResponses();
} else {
return BaseObject::listen(param1, param2);
}
break;
default:
break;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdResponseBox::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_font));
persistMgr->transferPtr(TMEMBER_PTR(_fontHover));
persistMgr->transferBool(TMEMBER(_horizontal));
persistMgr->transferCharPtr(TMEMBER(_lastResponseText));
persistMgr->transferCharPtr(TMEMBER(_lastResponseTextOrig));
_respButtons.persist(persistMgr);
persistMgr->transferRect32(TMEMBER(_responseArea));
_responses.persist(persistMgr);
persistMgr->transferSint32(TMEMBER(_scrollOffset));
persistMgr->transferPtr(TMEMBER_PTR(_shieldWindow));
persistMgr->transferSint32(TMEMBER(_spacing));
persistMgr->transferPtr(TMEMBER_PTR(_waitingScript));
persistMgr->transferPtr(TMEMBER_PTR(_window));
persistMgr->transferSint32(TMEMBER_INT(_verticalAlign));
persistMgr->transferSint32(TMEMBER_INT(_align));
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdResponseBox::weedResponses() {
AdGame *adGame = (AdGame *)_game;
for (int32 i = 0; i < _responses.getSize(); i++) {
switch (_responses[i]->_responseType) {
case RESPONSE_ONCE:
if (adGame->branchResponseUsed(_responses[i]->_id)) {
delete _responses[i];
_responses.removeAt(i);
i--;
}
break;
case RESPONSE_ONCE_GAME:
if (adGame->gameResponseUsed(_responses[i]->_id)) {
delete _responses[i];
_responses.removeAt(i);
i--;
}
break;
default:
break;
}
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
void AdResponseBox::setLastResponseText(const char *text, const char *textOrig) {
BaseUtils::setString(&_lastResponseText, text);
BaseUtils::setString(&_lastResponseTextOrig, textOrig);
}
//////////////////////////////////////////////////////////////////////////
bool AdResponseBox::handleResponse(AdResponse *response) {
setLastResponseText(response->_text, response->_textOrig);
AdGame *adGame = (AdGame *)_game;
switch (response->_responseType) {
case RESPONSE_ONCE:
adGame->addBranchResponse(response->_id);
break;
case RESPONSE_ONCE_GAME:
adGame->addGameResponse(response->_id);
break;
default:
break;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
BaseObject *AdResponseBox::getNextAccessObject(BaseObject *currObject) {
BaseArray<UIObject *> objects;
getObjects(objects, true);
if (objects.getSize() == 0) {
return nullptr;
} else {
if (currObject != nullptr) {
for (int32 i = 0; i < objects.getSize(); i++) {
if (objects[i] == currObject) {
if (i < objects.getSize() - 1) {
return objects[i + 1];
} else {
break;
}
}
}
}
return objects[0];
}
return nullptr;
}
//////////////////////////////////////////////////////////////////////////
BaseObject *AdResponseBox::getPrevAccessObject(BaseObject *currObject) {
BaseArray<UIObject *> objects;
getObjects(objects, true);
if (objects.getSize() == 0) {
return nullptr;
} else {
if (currObject != nullptr) {
for (int32 i = objects.getSize() - 1; i >= 0; i--) {
if (objects[i] == currObject) {
if (i > 0) {
return objects[i - 1];
} else {
break;
}
}
}
}
return objects[objects.getSize() - 1];
}
return nullptr;
}
//////////////////////////////////////////////////////////////////////////
bool AdResponseBox::getObjects(BaseArray<UIObject *> &objects, bool interactiveOnly) {
for (int32 i = 0; i < _respButtons.getSize(); i++) {
objects.add(_respButtons[i]);
}
if (_window) {
_window->getWindowObjects(objects, interactiveOnly);
}
return STATUS_OK;
}
} // End of namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADRESPONSEBOX_H
#define WINTERMUTE_ADRESPONSEBOX_H
#include "engines/wintermute/base/base_object.h"
namespace Wintermute {
class UIButton;
class UIWindow;
class UIObject;
class AdResponse;
class AdResponseBox : public BaseObject {
public:
BaseObject *getNextAccessObject(BaseObject *currObject);
BaseObject *getPrevAccessObject(BaseObject *currObject);
bool getObjects(BaseArray<UIObject *> &objects, bool interactiveOnly);
bool handleResponse(AdResponse *response);
void setLastResponseText(const char *text, const char *textOrig);
char *_lastResponseText;
char *_lastResponseTextOrig;
DECLARE_PERSISTENT(AdResponseBox, BaseObject)
ScScript *_waitingScript;
bool listen(BaseScriptHolder *param1, uint32 param2) override;
typedef enum {
EVENT_PREV,
EVENT_NEXT,
EVENT_RESPONSE
} TResponseEvent;
bool weedResponses();
bool display() override;
int32 _spacing;
int32 _scrollOffset;
BaseFont *_fontHover;
BaseFont *_font;
bool createButtons();
bool invalidateButtons();
void clearButtons();
void clearResponses();
AdResponseBox(BaseGame *inGame);
~AdResponseBox() override;
BaseArray<AdResponse *> _responses;
BaseArray<UIButton *> _respButtons;
UIWindow *_window;
UIWindow *_shieldWindow;
bool _horizontal;
Common::Rect32 _responseArea;
int32 _verticalAlign;
TTextAlign _align;
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
};
} // End of namespace Wintermute
#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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_response_context.h"
#include "engines/wintermute/base/base_persistence_manager.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdResponseContext, false)
//////////////////////////////////////////////////////////////////////////
AdResponseContext::AdResponseContext(BaseGame *inGame) : BaseClass(inGame) {
_id = 0;
_context = nullptr;
}
//////////////////////////////////////////////////////////////////////////
AdResponseContext::~AdResponseContext() {
SAFE_DELETE_ARRAY(_context);
}
//////////////////////////////////////////////////////////////////////////
bool AdResponseContext::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_game));
persistMgr->transferCharPtr(TMEMBER(_context));
persistMgr->transferSint32(TMEMBER(_id));
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
void AdResponseContext::setContext(const char *context) {
SAFE_DELETE_ARRAY(_context);
if (context) {
size_t contextSize = strlen(context) + 1;
_context = new char [contextSize];
Common::strcpy_s(_context, contextSize, context);
}
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,48 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADRESPONSECONTEXT_H
#define WINTERMUTE_ADRESPONSECONTEXT_H
#include "engines/wintermute/persistent.h"
#include "engines/wintermute/base/base.h"
namespace Wintermute {
class AdResponseContext : public BaseClass {
public:
void setContext(const char *context);
int32 _id;
char *_context;
DECLARE_PERSISTENT(AdResponseContext, BaseClass)
AdResponseContext(BaseGame *inGame);
~AdResponseContext() override;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,163 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_rot_level.h"
#include "engines/wintermute/base/base_dynamic_buffer.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/base/base_sprite.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdRotLevel, false)
//////////////////////////////////////////////////////////////////////////
AdRotLevel::AdRotLevel(BaseGame *inGame) : BaseObject(inGame) {
_posX = 0;
_rotation = 0.0f;
}
//////////////////////////////////////////////////////////////////////////
AdRotLevel::~AdRotLevel() {
}
//////////////////////////////////////////////////////////////////////////
bool AdRotLevel::loadFile(const char *filename) {
char *buffer = (char *)_game->_fileManager->readWholeFile(filename);
if (buffer == nullptr) {
_game->LOG(0, "AdRotLevel::loadFile failed for file '%s'", filename);
return STATUS_FAILED;
}
bool ret;
setFilename(filename);
if (DID_FAIL(ret = loadBuffer(buffer, true))) {
_game->LOG(0, "Error parsing ROTATION_LEVEL file '%s'", filename);
}
delete[] buffer;
return ret;
}
TOKEN_DEF_START
TOKEN_DEF(ROTATION_LEVEL)
TOKEN_DEF(TEMPLATE)
TOKEN_DEF(X)
TOKEN_DEF(ROTATION)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool AdRotLevel::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ROTATION_LEVEL)
TOKEN_TABLE(TEMPLATE)
TOKEN_TABLE(X)
TOKEN_TABLE(ROTATION)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
char *params;
int cmd;
BaseParser parser(_game);
if (complete) {
if (parser.getCommand(&buffer, commands, &params) != TOKEN_ROTATION_LEVEL) {
_game->LOG(0, "'ROTATION_LEVEL' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_X:
parser.scanStr(params, "%d", &_posX);
break;
case TOKEN_ROTATION: {
int i;
parser.scanStr(params, "%d", &i);
_rotation = (float)i;
}
break;
case TOKEN_EDITOR_PROPERTY:
parseEditorProperty(params, false);
break;
default:
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in ROTATION_LEVEL definition");
return STATUS_FAILED;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdRotLevel::saveAsText(BaseDynamicBuffer *buffer, int indent) {
buffer->putTextIndent(indent, "ROTATION_LEVEL {\n");
buffer->putTextIndent(indent + 2, "X=%d\n", _posX);
buffer->putTextIndent(indent + 2, "ROTATION=%d\n", (int)_rotation);
BaseClass::saveAsText(buffer, indent + 2);
buffer->putTextIndent(indent, "}\n");
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdRotLevel::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferFloat(TMEMBER(_rotation));
return STATUS_OK;
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,48 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADROTLEVEL_H
#define WINTERMUTE_ADROTLEVEL_H
#include "engines/wintermute/base/base_object.h"
namespace Wintermute {
class AdRotLevel : public BaseObject {
public:
DECLARE_PERSISTENT(AdRotLevel, BaseObject)
AdRotLevel(BaseGame *inGame);
~AdRotLevel() override;
float _rotation;
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,160 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_scale_level.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_dynamic_buffer.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdScaleLevel, false)
//////////////////////////////////////////////////////////////////////////
AdScaleLevel::AdScaleLevel(BaseGame *inGame) : BaseObject(inGame) {
_posY = 0;
_scale = 100;
}
//////////////////////////////////////////////////////////////////////////
AdScaleLevel::~AdScaleLevel() {
}
//////////////////////////////////////////////////////////////////////////
bool AdScaleLevel::loadFile(const char *filename) {
char *buffer = (char *)_game->_fileManager->readWholeFile(filename);
if (buffer == nullptr) {
_game->LOG(0, "AdScaleLevel::LoadFile failed for file '%s'", filename);
return STATUS_FAILED;
}
bool ret;
setFilename(filename);
if (DID_FAIL(ret = loadBuffer(buffer, true))) {
_game->LOG(0, "Error parsing SCALE_LEVEL file '%s'", filename);
}
delete[] buffer;
return ret;
}
TOKEN_DEF_START
TOKEN_DEF(SCALE_LEVEL)
TOKEN_DEF(TEMPLATE)
TOKEN_DEF(Y)
TOKEN_DEF(SCALE)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool AdScaleLevel::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(SCALE_LEVEL)
TOKEN_TABLE(TEMPLATE)
TOKEN_TABLE(Y)
TOKEN_TABLE(SCALE)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
char *params;
int cmd;
BaseParser parser(_game);
if (complete) {
if (parser.getCommand(&buffer, commands, &params) != TOKEN_SCALE_LEVEL) {
_game->LOG(0, "'SCALE_LEVEL' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_Y:
parser.scanStr(params, "%d", &_posY);
break;
case TOKEN_SCALE: {
int i;
parser.scanStr(params, "%d", &i);
_scale = (float)i;
}
break;
case TOKEN_EDITOR_PROPERTY:
parseEditorProperty(params, false);
break;
default:
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in SCALE_LEVEL definition");
return STATUS_FAILED;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdScaleLevel::saveAsText(BaseDynamicBuffer *buffer, int indent) {
buffer->putTextIndent(indent, "SCALE_LEVEL {\n");
buffer->putTextIndent(indent + 2, "Y=%d\n", _posY);
buffer->putTextIndent(indent + 2, "SCALE=%d\n", (int)_scale);
BaseClass::saveAsText(buffer, indent + 2);
buffer->putTextIndent(indent, "}\n");
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdScaleLevel::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferFloat(TMEMBER(_scale));
return STATUS_OK;
}
} // End of namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADSCALELEVEL_H
#define WINTERMUTE_ADSCALELEVEL_H
#include "engines/wintermute/base/base_object.h"
namespace Wintermute {
class AdScaleLevel : public BaseObject {
public:
DECLARE_PERSISTENT(AdScaleLevel, BaseObject)
float _scale;
AdScaleLevel(BaseGame *inGame);
~AdScaleLevel() override;
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
};
} // End of namespace Wintermute
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,224 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADSCENE_H
#define WINTERMUTE_ADSCENE_H
#include "engines/wintermute/base/base_fader.h"
namespace Wintermute {
class UIWindow;
class AdObject;
class AdRegion;
class BaseViewport;
class AdLayer;
class BasePoint;
class Light3D;
class AdWaypointGroup;
class AdPath;
class AdScaleLevel;
class AdRotLevel;
class AdPathPoint;
#ifdef ENABLE_WME3D
class AdSceneGeometry;
#endif
class AdScene : public BaseObject {
public:
#ifdef ENABLE_WME3D
uint32 _ambientLightColor;
TShadowType _maxShadowType;
bool _scroll3DCompatibility;
bool _fogEnabled;
uint32 _fogColor;
float _fogStart;
float _fogEnd;
#endif
BaseObject *getNextAccessObject(BaseObject *currObject);
BaseObject *getPrevAccessObject(BaseObject *currObject);
bool getSceneObjects(BaseArray<AdObject *> &objects, bool interactiveOnly);
bool getRegionObjects(AdRegion *region, BaseArray<AdObject *> &objects, bool interactiveOnly);
#ifdef ENABLE_WME3D
bool display3DContent(DXMatrix &viewMat, DXMatrix &projMat);
#endif
#ifdef ENABLE_WME3D
bool _2DPathfinding;
#endif
bool afterLoad();
#ifdef ENABLE_WME3D
float _nearClipPlane;
float _farClipPlane;
float _fov;
#endif
int32 _editorResolutionWidth;
int32 _editorResolutionHeight;
#ifdef ENABLE_WME3D
Light3D *getActiveLight();
#endif
bool getRegionsAt(int x, int y, AdRegion **regionList, int numRegions);
bool handleItemAssociations(const char *itemName, bool show);
UIWindow *_shieldWindow;
float getRotationAt(int x, int y);
bool loadState();
bool saveState();
bool _persistentState;
bool _persistentStateSprites;
BaseObject *getNodeByName(const char *name);
void setOffset(int offsetLeft, int offsetTop);
bool pointInViewport(int x, int y);
int getOffsetTop();
int getOffsetLeft();
bool getViewportSize(int32 *width = nullptr, int32 *height = nullptr);
bool getViewportOffset(int32 *offsetX = nullptr, int32 *offsetY = nullptr);
BaseViewport *_viewport;
BaseFader *_fader;
int32 _pfPointsNum;
void pfPointsAdd(int x, int y, int distance);
void pfPointsStart();
bool _initialized;
bool correctTargetPoint(int32 startX, int32 startY, int32 *x, int32 *y, bool checkFreeObjects = false, BaseObject *requester = nullptr);
bool correctTargetPoint2(int32 startX, int32 startY, int32 *targetX, int32 *targetY, bool checkFreeObjects, BaseObject *requester);
DECLARE_PERSISTENT(AdScene, BaseObject)
bool displayRegionContent(AdRegion *region = nullptr, bool display3DOnly = false);
bool displayRegionContentOld(AdRegion *region = nullptr);
static int32 compareObjs(const void *obj1, const void *obj2);
bool updateFreeObjects();
bool traverseNodes(bool update = false);
float getScaleAt(int y);
bool sortScaleLevels();
bool sortRotLevels();
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
#ifdef ENABLE_WME3D
bool _showGeometry;
AdSceneGeometry *_geom;
#endif
uint32 getAlphaAt(int x, int y, bool colorCheck = false);
bool _paralaxScrolling;
void skipTo(int offsetX, int offsetY);
void setDefaults();
void cleanup();
void skipToObject(BaseObject *object);
void scrollToObject(BaseObject *object);
void scrollTo(int offsetX, int offsetY);
bool update() override;
bool _autoScroll;
int32 _targetOffsetTop;
int32 _targetOffsetLeft;
int32 _scrollPixelsV;
uint32 _scrollTimeV;
uint32 _lastTimeV;
int32 _scrollPixelsH;
uint32 _scrollTimeH;
uint32 _lastTimeH;
bool display() override;
uint32 _pfMaxTime;
bool initLoop();
void pathFinderStep();
/*
* Added the possibility to configure the default behaviour of this function. If neither free objects nor a main layer
* exist, the function used to return "blocked". This results in all actors being "blocked" shortly after load.
* The default behaviour is unchanged to avoid strange side effects. The actor class is now able to override this default.
*
*/
bool isBlockedAt(int x, int y, bool checkFreeObjects = false, BaseObject *requester = nullptr, bool defaultBlock = true);
bool isWalkableAt(int x, int y, bool checkFreeObjects = false, BaseObject *requester = nullptr);
AdLayer *_mainLayer;
float getZoomAt(int x, int y);
bool getPath(BasePoint source, BasePoint target, AdPath *path, BaseObject *requester = nullptr);
AdScene(BaseGame *inGame);
~AdScene() override;
BaseArray<AdLayer *> _layers;
BaseArray<AdObject *> _objects;
BaseArray<AdWaypointGroup *> _waypointGroups;
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
int32 _width{};
int32 _height{};
bool addObject(AdObject *object);
bool removeObject(AdObject *object);
int32 _editorMarginH;
int32 _editorMarginV;
uint32 _editorColFrame;
uint32 _editorColEntity;
uint32 _editorColRegion;
uint32 _editorColBlocked;
uint32 _editorColWaypoints;
uint32 _editorColEntitySel;
uint32 _editorColRegionSel;
uint32 _editorColBlockedSel;
uint32 _editorColWaypointsSel;
uint32 _editorColScale;
uint32 _editorColDecor;
uint32 _editorColDecorSel;
bool _editorShowRegions;
bool _editorShowBlocked;
bool _editorShowDecor;
bool _editorShowEntities;
bool _editorShowScale;
BaseArray<AdScaleLevel *> _scaleLevels;
BaseArray<AdRotLevel *> _rotLevels;
bool restoreDeviceObjects() override;
void setMaxShadowType(TShadowType shadowType);
int getPointsDist(BasePoint p1, BasePoint p2, BaseObject *requester = nullptr);
void onLayerResized(AdLayer *layer);
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
Common::String debuggerToString() const override;
private:
bool persistState(bool saving = true);
void pfAddWaypointGroup(AdWaypointGroup *wpt, BaseObject *requester = nullptr);
bool _pfReady;
BasePoint *_pfTarget;
AdPath *_pfTargetPath;
BaseObject *_pfRequester;
BaseArray<AdPathPoint *> _pfPath;
int32 _offsetTop;
int32 _offsetLeft;
};
} // End of namespace Wintermute
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,131 @@
/* 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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#ifndef WINTERMUTE_AD_SCENE_GEOMETRY_H
#define WINTERMUTE_AD_SCENE_GEOMETRY_H
#include "engines/wintermute/base/base_object.h"
namespace Wintermute {
class BaseSprite;
class Camera3D;
class Light3D;
class Block3D;
class AdGeneric;
class AdBlock;
class AdWalkplane;
class AdPath3D;
class AdWaypointGroup3D;
class AdGeomExt;
class AdPathPoint3D;
class AdSceneGeometry : public BaseObject {
public:
bool _maxLightsWarning;
bool dropWaypoints();
bool setLightColor(const char *lightName, uint32 color);
uint32 getLightColor(const char *lightName);
DXVector3 getLightPos(const char *lightName);
bool enableNode(const char *nodeName, bool enable = true);
bool isNodeEnabled(const char *nodeName);
bool enableLight(const char *lightName, bool enable = true);
bool isLightEnabled(const char *lightName);
DECLARE_PERSISTENT(AdSceneGeometry, BaseObject)
bool correctTargetPoint(const DXVector3 &source, DXVector3 *target);
bool _lastValuesInitialized;
DXMatrix _lastWorldMat;
DXMatrix _lastViewMat;
DXMatrix _lastProjMat;
int _lastOffsetX;
int _lastOffsetY;
DXViewport _drawingViewport;
int _lastScrollX;
int _lastScrollY;
bool createLights();
bool enableLights(DXVector3 Point, BaseArray<char *> &IgnoreLights);
static int32 compareLights(const void *obj1, const void *obj2);
bool initLoop();
float getPointsDist(DXVector3 p1, DXVector3 p2);
void pathFinderStep();
bool getPath(DXVector3 source, DXVector3 target, AdPath3D *path, bool rerun = false);
bool convert2Dto3D(int x, int y, DXVector3 *pos);
bool convert2Dto3DTolerant(int x, int y, DXVector3 *pos);
bool convert3Dto2D(DXVector3 *pos, int32 *x, int32 *y);
BaseSprite *_wptMarker;
float _waypointHeight;
bool directPathExists(DXVector3 *p1, DXVector3 *p2);
float getHeightAt(DXVector3 pos, float Ttlerance = 0.0f, bool *intFound = NULL);
bool storeDrawingParams();
bool render(bool render);
bool renderShadowGeometry();
DXMatrix *getViewMatrix();
DXMatrix _viewMatrix;
bool setActiveCamera(const char *camera, float fov, float nearClipPlane, float farClipPlane);
bool setActiveCamera(int camera, float fow, float nearClipPlane, float farClipPlane);
//bool SetActiveCameraTwin(char* Camera);
//bool SetActiveCameraTwin(int Camera);
Camera3D *getActiveCamera();
int32 _activeCamera;
bool setActiveLight(char *light);
bool setActiveLight(int32 light);
int32 _activeLight;
void cleanup();
AdSceneGeometry(BaseGame *inGame);
virtual ~AdSceneGeometry();
bool loadFile(const char *filename);
BaseArray<AdWalkplane *> _planes;
BaseArray<AdBlock *> _blocks;
BaseArray<AdGeneric *> _generics;
BaseArray<Camera3D *> _cameras;
BaseArray<Light3D *> _lights;
BaseArray<AdWaypointGroup3D *> _waypointGroups;
uint32 _PFMaxTime;
private:
AdGeomExt *getGeometryExtension(char *filename);
DXVector3 getBlockIntersection(DXVector3 *p1, DXVector3 *p2);
bool _PFReady;
DXVector3 _PFSource;
DXVector3 _PFTarget;
AdPath3D *_PFTargetPath;
DXVector3 _PFAlternateTarget;
float _PFAlternateDist;
bool _PFRerun;
BaseArray<AdPathPoint3D *> _PFPath;
};
} // namespace Wintermute
#endif

View File

@@ -0,0 +1,81 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_scene_node.h"
#include "engines/wintermute/base/base_game.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdSceneNode, false)
//////////////////////////////////////////////////////////////////////////
AdSceneNode::AdSceneNode(BaseGame *inGame) : BaseObject(inGame) {
_type = OBJECT_NONE;
_region = nullptr;
_entity = nullptr;
}
//////////////////////////////////////////////////////////////////////////
AdSceneNode::~AdSceneNode() {
_game->unregisterObject(_region);
_region = nullptr;
_game->unregisterObject(_entity);
_entity = nullptr;
}
//////////////////////////////////////////////////////////////////////////
bool AdSceneNode::setEntity(AdEntity *entity) {
_type = OBJECT_ENTITY;
_entity = entity;
return _game->registerObject(entity);
}
//////////////////////////////////////////////////////////////////////////
bool AdSceneNode::setRegion(AdRegion *region) {
_type = OBJECT_REGION;
_region = region;
return _game->registerObject(region);
}
//////////////////////////////////////////////////////////////////////////
bool AdSceneNode::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_entity));
persistMgr->transferPtr(TMEMBER_PTR(_region));
persistMgr->transferSint32(TMEMBER_INT(_type));
return STATUS_OK;
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,52 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADSCENENODE_H
#define WINTERMUTE_ADSCENENODE_H
#include "engines/wintermute/ad/ad_types.h" // Added by ClassView
#include "engines/wintermute/ad/ad_region.h" // Added by ClassView
#include "engines/wintermute/ad/ad_entity.h"
namespace Wintermute {
class AdSceneNode : public BaseObject {
public:
DECLARE_PERSISTENT(AdSceneNode, BaseObject)
bool setRegion(AdRegion *region);
bool setEntity(AdEntity *entity);
AdEntity *_entity;
AdRegion *_region;
TObjectType _type;
AdSceneNode(BaseGame *inGame);
~AdSceneNode() override;
};
}
#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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_scene_state.h"
#include "engines/wintermute/ad/ad_node_state.h"
#include "engines/wintermute/persistent.h"
#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/dcgf.h"
#include "common/str.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdSceneState, false)
//////////////////////////////////////////////////////////////////////////
AdSceneState::AdSceneState(BaseGame *inGame) : BaseClass(inGame) {
_filename = nullptr;
}
//////////////////////////////////////////////////////////////////////////
AdSceneState::~AdSceneState() {
SAFE_DELETE_ARRAY(_filename);
for (int32 i = 0; i < _nodeStates.getSize(); i++) {
delete _nodeStates[i];
}
_nodeStates.removeAll();
}
//////////////////////////////////////////////////////////////////////////
bool AdSceneState::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferCharPtr(TMEMBER(_filename));
_nodeStates.persist(persistMgr);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
void AdSceneState::setFilename(const char *filename) {
SAFE_DELETE_ARRAY(_filename);
size_t filenameSize = strlen(filename) + 1;
_filename = new char [filenameSize];
Common::strcpy_s(_filename, filenameSize, filename);
}
//////////////////////////////////////////////////////////////////////////
AdNodeState *AdSceneState::getNodeState(const char *name, bool saving) {
for (int32 i = 0; i < _nodeStates.getSize(); i++) {
if (scumm_stricmp(_nodeStates[i]->_name, name) == 0) {
return _nodeStates[i];
}
}
if (saving) {
AdNodeState *ret = new AdNodeState(_game);
ret->setName(name);
_nodeStates.add(ret);
return ret;
} else {
return nullptr;
}
}
} // End of namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADSCENESTATE_H
#define WINTERMUTE_ADSCENESTATE_H
#include "engines/wintermute/persistent.h"
#include "engines/wintermute/base/base.h"
#include "engines/wintermute/coll_templ.h"
namespace Wintermute {
class AdNodeState;
class AdSceneState : public BaseClass {
public:
AdNodeState *getNodeState(const char *name, bool saving);
void setFilename(const char *filename);
DECLARE_PERSISTENT(AdSceneState, BaseClass)
AdSceneState(BaseGame *inGame);
~AdSceneState() override;
char *_filename;
BaseArray<AdNodeState *> _nodeStates;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,349 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_game.h"
#include "engines/wintermute/ad/ad_scene.h"
#include "engines/wintermute/ad/ad_sentence.h"
#include "engines/wintermute/ad/ad_talk_def.h"
#include "engines/wintermute/ad/ad_talk_node.h"
#include "engines/wintermute/utils/path_util.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_sprite.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/font/base_font.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "engines/wintermute/base/sound/base_sound.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdSentence, false)
//////////////////////////////////////////////////////////////////////////
AdSentence::AdSentence(BaseGame *inGame) : BaseClass(inGame) {
_text = nullptr;
_stances = nullptr;
_tempStance = nullptr;
_duration = 0;
_startTime = 0;
_currentStance = 0;
_font = nullptr;
_pos.x = _pos.y = 0;
_width = _game->_renderer->getWidth();
_align = (TTextAlign)TAL_CENTER;
_sound = nullptr;
_soundStarted = false;
_talkDef = nullptr;
_currentSprite = nullptr;
_currentSkelAnim = nullptr;
_fixedPos = false;
_freezable = true;
}
//////////////////////////////////////////////////////////////////////////
AdSentence::~AdSentence() {
SAFE_DELETE(_sound);
SAFE_DELETE_ARRAY(_text);
SAFE_DELETE_ARRAY(_stances);
SAFE_DELETE_ARRAY(_tempStance);
SAFE_DELETE(_talkDef);
_currentSprite = nullptr; // ref only
_currentSkelAnim = nullptr;
_font = nullptr; // ref only
}
//////////////////////////////////////////////////////////////////////////
void AdSentence::setText(const char *text) {
delete[] _text;
size_t textSize = strlen(text) + 1;
_text = new char[textSize];
Common::strcpy_s(_text, textSize, text);
}
//////////////////////////////////////////////////////////////////////////
void AdSentence::setStances(const char *stances) {
delete[] _stances;
if (stances) {
size_t stancesSize = strlen(stances) + 1;
_stances = new char[stancesSize];
Common::strcpy_s(_stances, stancesSize, stances);
} else {
_stances = nullptr;
}
}
//////////////////////////////////////////////////////////////////////////
char *AdSentence::getCurrentStance() {
return getStance(_currentStance);
}
//////////////////////////////////////////////////////////////////////////
char *AdSentence::getNextStance() {
_currentStance++;
return getStance(_currentStance);
}
//////////////////////////////////////////////////////////////////////////
char *AdSentence::getStance(int stance) {
if (_stances == nullptr || !_stances[0]) {
return nullptr;
}
if (_tempStance) {
delete[] _tempStance;
}
_tempStance = nullptr;
char *start;
char *curr;
int pos;
if (stance == 0) {
start = _stances;
} else {
pos = 0;
start = nullptr;
curr = _stances;
while (pos < stance) {
if (*curr == '\0') {
break;
}
if (*curr == ',') {
pos++;
}
curr++;
}
if (pos == stance) {
start = curr;
}
}
if (start == nullptr) {
return nullptr;
}
while (*start == ' ' && *start != ',' && *start != '\0') {
start++;
}
curr = start;
while (*curr != '\0' && *curr != ',') {
curr++;
}
while (curr > start && *(curr - 1) == ' ') {
curr--;
}
_tempStance = new char [curr - start + 1];
if (_tempStance) {
_tempStance[curr - start] = '\0';
Common::strlcpy(_tempStance, start, curr - start);
}
return _tempStance;
}
//////////////////////////////////////////////////////////////////////////
bool AdSentence::display() {
if (!_font || !_text) {
return STATUS_FAILED;
}
if (_sound && !_soundStarted) {
_sound->play();
_soundStarted = true;
}
if (_game->_subtitles) {
int32 x = _pos.x;
int32 y = _pos.y;
if (!_fixedPos) {
x = x - ((AdGame *)_game)->_scene->getOffsetLeft();
y = y - ((AdGame *)_game)->_scene->getOffsetTop();
}
x = MAX<int32>(x, 0);
x = MIN(x, _game->_renderer->getWidth() - _width);
y = MAX<int32>(y, 0);
_font->drawText((byte *)_text, x, y, _width, _align);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
void AdSentence::setSound(BaseSound *sound) {
if (!sound) {
return;
}
SAFE_DELETE(_sound);
_sound = sound;
_soundStarted = false;
}
//////////////////////////////////////////////////////////////////////////
bool AdSentence::finish() {
if (_sound) {
_sound->stop();
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdSentence::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferPtr(TMEMBER_PTR(_game));
persistMgr->transferSint32(TMEMBER_INT(_align));
persistMgr->transferSint32(TMEMBER(_currentStance));
persistMgr->transferPtr(TMEMBER_PTR(_currentSprite));
persistMgr->transferCharPtr(TMEMBER(_currentSkelAnim));
persistMgr->transferUint32(TMEMBER(_duration));
persistMgr->transferPtr(TMEMBER_PTR(_font));
persistMgr->transferPoint32(TMEMBER(_pos));
persistMgr->transferPtr(TMEMBER_PTR(_sound));
persistMgr->transferBool(TMEMBER(_soundStarted));
persistMgr->transferCharPtr(TMEMBER(_stances));
persistMgr->transferUint32(TMEMBER(_startTime));
persistMgr->transferPtr(TMEMBER_PTR(_talkDef));
persistMgr->transferCharPtr(TMEMBER(_tempStance));
persistMgr->transferCharPtr(TMEMBER(_text));
persistMgr->transferSint32(TMEMBER(_width));
persistMgr->transferBool(TMEMBER(_fixedPos));
persistMgr->transferBool(TMEMBER(_freezable));
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdSentence::setupTalkFile(const char *soundFilename) {
SAFE_DELETE(_talkDef);
_currentSprite = nullptr;
if (!soundFilename) {
return STATUS_OK;
}
AnsiString path = PathUtil::getDirectoryName(soundFilename);
AnsiString name = PathUtil::getFileNameWithoutExtension(soundFilename);
AnsiString talkDefFileName = PathUtil::combine(path, name + ".talk");
if (!_game->_fileManager->hasFile(talkDefFileName)) {
return STATUS_OK; // no talk def file found
}
_talkDef = new AdTalkDef(_game);
if (!_talkDef || DID_FAIL(_talkDef->loadFile(talkDefFileName.c_str()))) {
SAFE_DELETE(_talkDef);
return STATUS_FAILED;
}
//_game->LOG(0, "Using .talk file: %s", TalkDefFile);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdSentence::update(TDirection dir) {
if (!_talkDef) {
return STATUS_OK;
}
uint32 currentTime;
// if sound is available, synchronize with sound, otherwise use timer
/*
if (_sound) currentTime = _sound->getPositionTime();
else currentTime = _game->_timer - _startTime;
*/
currentTime = _game->_timer - _startTime;
bool talkNodeFound = false;
for (int32 i = 0; i < _talkDef->_nodes.getSize(); i++) {
if (_talkDef->_nodes[i]->isInTimeInterval(currentTime, dir)) {
talkNodeFound = true;
BaseSprite *newSprite = _talkDef->_nodes[i]->getSprite(dir);
if (newSprite != _currentSprite) {
newSprite->reset();
}
_currentSprite = newSprite;
if (!_talkDef->_nodes[i]->_playToEnd) {
break;
}
}
}
// no talk node, try to use default sprite instead (if any)
if (!talkNodeFound) {
BaseSprite *newSprite = _talkDef->getDefaultSprite(dir);
if (newSprite) {
if (newSprite != _currentSprite) {
newSprite->reset();
}
_currentSprite = newSprite;
} else {
_currentSprite = nullptr;
}
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdSentence::canSkip() {
// prevent accidental sentence skipping (TODO make configurable)
return (_game->_timer - _startTime) > 300;
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,81 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADSENTENCE_H
#define WINTERMUTE_ADSENTENCE_H
#include "engines/wintermute/base/base.h"
#include "engines/wintermute/persistent.h"
#include "engines/wintermute/dctypes.h" // Added by ClassView
#include "common/rect.h"
namespace Wintermute {
class AdTalkDef;
class BaseFont;
class BaseSprite;
class BaseSound;
class AdSentence : public BaseClass {
public:
bool _freezable;
bool _fixedPos;
BaseSprite *_currentSprite;
char *_currentSkelAnim;
bool update(TDirection dir = DI_DOWN);
bool setupTalkFile(const char *soundFilename);
DECLARE_PERSISTENT(AdSentence, BaseClass)
bool finish();
void setSound(BaseSound *sound);
bool _soundStarted;
BaseSound *_sound;
TTextAlign _align;
bool display();
int32 _width;
Common::Point32 _pos;
BaseFont *_font;
char *getNextStance();
char *getCurrentStance();
void setStances(const char *stances);
void setText(const char *text);
int32 _currentStance;
uint32 _startTime;
char *_stances;
char *_text;
uint32 _duration;
AdSentence(BaseGame *inGame);
~AdSentence() override;
AdTalkDef *_talkDef;
bool canSkip();
private:
char *_tempStance;
char *getStance(int stance);
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,352 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_sprite_set.h"
#include "engines/wintermute/base/base_dynamic_buffer.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/base/base_sprite.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdSpriteSet, false)
//////////////////////////////////////////////////////////////////////////
AdSpriteSet::AdSpriteSet(BaseGame *inGame, BaseObject *owner) : BaseObject(inGame) {
_owner = owner;
for (int i = 0; i < NUM_DIRECTIONS; i++) {
_sprites[i] = nullptr;
}
}
//////////////////////////////////////////////////////////////////////////
AdSpriteSet::~AdSpriteSet() {
for (int i = 0; i < NUM_DIRECTIONS; i++) {
SAFE_DELETE(_sprites[i]);
}
_owner = nullptr;
}
//////////////////////////////////////////////////////////////////////////
bool AdSpriteSet::loadFile(const char *filename, int lifeTime, TSpriteCacheType cacheType) {
char *buffer = (char *)_game->_fileManager->readWholeFile(filename);
if (buffer == nullptr) {
_game->LOG(0, "AdSpriteSet::loadFile failed for file '%s'", filename);
return STATUS_FAILED;
}
bool ret;
if (DID_FAIL(ret = loadBuffer(buffer, true))) {
_game->LOG(0, "Error parsing SPRITESET file '%s'", filename);
}
delete[] buffer;
return ret;
}
TOKEN_DEF_START
TOKEN_DEF(SPRITESET)
TOKEN_DEF(NAME)
TOKEN_DEF(UP_LEFT)
TOKEN_DEF(DOWN_LEFT)
TOKEN_DEF(LEFT)
TOKEN_DEF(UP_RIGHT)
TOKEN_DEF(DOWN_RIGHT)
TOKEN_DEF(RIGHT)
TOKEN_DEF(UP)
TOKEN_DEF(DOWN)
TOKEN_DEF(TEMPLATE)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool AdSpriteSet::loadBuffer(char *buffer, bool complete, int lifeTime, TSpriteCacheType cacheType) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(SPRITESET)
TOKEN_TABLE(NAME)
TOKEN_TABLE(UP_LEFT)
TOKEN_TABLE(DOWN_LEFT)
TOKEN_TABLE(LEFT)
TOKEN_TABLE(UP_RIGHT)
TOKEN_TABLE(DOWN_RIGHT)
TOKEN_TABLE(RIGHT)
TOKEN_TABLE(UP)
TOKEN_TABLE(DOWN)
TOKEN_TABLE(TEMPLATE)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
char *params;
int cmd;
BaseParser parser(_game);
if (complete) {
if (parser.getCommand(&buffer, commands, &params) != TOKEN_SPRITESET) {
_game->LOG(0, "'SPRITESET' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
BaseSprite *spr = nullptr;
while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
if (DID_FAIL(loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
setName(params);
break;
case TOKEN_LEFT:
SAFE_DELETE(_sprites[DI_LEFT]);
spr = new BaseSprite(_game, _owner);
if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_LEFT] = spr;
}
break;
case TOKEN_RIGHT:
SAFE_DELETE(_sprites[DI_RIGHT]);
spr = new BaseSprite(_game, _owner);
if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_RIGHT] = spr;
}
break;
case TOKEN_UP:
SAFE_DELETE(_sprites[DI_UP]);
spr = new BaseSprite(_game, _owner);
if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_UP] = spr;
}
break;
case TOKEN_DOWN:
SAFE_DELETE(_sprites[DI_DOWN]);
spr = new BaseSprite(_game, _owner);
if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_DOWN] = spr;
}
break;
case TOKEN_UP_LEFT:
SAFE_DELETE(_sprites[DI_UPLEFT]);
spr = new BaseSprite(_game, _owner);
if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_UPLEFT] = spr;
}
break;
case TOKEN_UP_RIGHT:
SAFE_DELETE(_sprites[DI_UPRIGHT]);
spr = new BaseSprite(_game, _owner);
if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_UPRIGHT] = spr;
}
break;
case TOKEN_DOWN_LEFT:
SAFE_DELETE(_sprites[DI_DOWNLEFT]);
spr = new BaseSprite(_game, _owner);
if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_DOWNLEFT] = spr;
}
break;
case TOKEN_DOWN_RIGHT:
SAFE_DELETE(_sprites[DI_DOWNRIGHT]);
spr = new BaseSprite(_game, _owner);
if (!spr || DID_FAIL(spr->loadFile(params, lifeTime, cacheType))) {
cmd = PARSERR_GENERIC;
} else {
_sprites[DI_DOWNRIGHT] = spr;
}
break;
case TOKEN_EDITOR_PROPERTY:
parseEditorProperty(params, false);
break;
default:
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in SPRITESET definition");
return STATUS_FAILED;
}
if (cmd == PARSERR_GENERIC) {
_game->LOG(0, "Error loading SPRITESET definition");
if (spr) {
delete spr;
}
return STATUS_FAILED;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdSpriteSet::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_owner));
for (int i = 0; i < NUM_DIRECTIONS; i++) {
persistMgr->transferPtr("", &_sprites[i]);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
BaseSprite *AdSpriteSet::getSprite(TDirection direction) {
int dir = (int)direction;
if (dir < 0) {
dir = 0;
}
if (dir >= NUM_DIRECTIONS) {
dir = NUM_DIRECTIONS - 1;
}
BaseSprite *ret = nullptr;
// find nearest set sprite
int numSteps = 0;
for (int i = dir; i >= 0; i--) {
if (_sprites[i] != nullptr) {
ret = _sprites[i];
numSteps = dir - i;
break;
}
}
for (int i = dir; i < NUM_DIRECTIONS; i++) {
if (_sprites[i] != nullptr) {
if (ret == nullptr || numSteps > i - dir) {
return _sprites[i];
} else {
return ret;
}
}
}
return ret;
}
//////////////////////////////////////////////////////////////////////////
bool AdSpriteSet::saveAsText(BaseDynamicBuffer *buffer, int indent) {
buffer->putTextIndent(indent, "SPRITESET {\n");
if (_name && _name[0]) {
buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", _name);
}
for (int i = 0; i < NUM_DIRECTIONS; i++) {
if (_sprites[i]) {
switch (i) {
case DI_UP:
buffer->putTextIndent(indent + 2, "UP=\"%s\"\n", _sprites[i]->_filename);
break;
case DI_UPRIGHT:
buffer->putTextIndent(indent + 2, "UP_RIGHT=\"%s\"\n", _sprites[i]->_filename);
break;
case DI_RIGHT:
buffer->putTextIndent(indent + 2, "RIGHT=\"%s\"\n", _sprites[i]->_filename);
break;
case DI_DOWNRIGHT:
buffer->putTextIndent(indent + 2, "DOWN_RIGHT=\"%s\"\n", _sprites[i]->_filename);
break;
case DI_DOWN:
buffer->putTextIndent(indent + 2, "DOWN=\"%s\"\n", _sprites[i]->_filename);
break;
case DI_DOWNLEFT:
buffer->putTextIndent(indent + 2, "DOWN_LEFT=\"%s\"\n", _sprites[i]->_filename);
break;
case DI_LEFT:
buffer->putTextIndent(indent + 2, "LEFT=\"%s\"\n", _sprites[i]->_filename);
break;
case DI_UPLEFT:
buffer->putTextIndent(indent + 2, "UP_LEFT=\"%s\"\n", _sprites[i]->_filename);
break;
default:
break;
}
}
}
BaseClass::saveAsText(buffer, indent + 2);
buffer->putTextIndent(indent, "}\n");
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdSpriteSet::containsSprite(BaseSprite *sprite) {
if (!sprite) {
return false;
}
for (int i = 0; i < NUM_DIRECTIONS; i++) {
if (_sprites[i] == sprite) {
return true;
}
}
return false;
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,52 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADSPRITESET_H
#define WINTERMUTE_ADSPRITESET_H
#include "engines/wintermute/base/base_object.h"
namespace Wintermute {
class BaseSprite;
class AdSpriteSet : public BaseObject {
public:
bool containsSprite(BaseSprite *sprite);
bool saveAsText(BaseDynamicBuffer *buffer, int indent = 0) override;
BaseSprite *getSprite(TDirection direction);
DECLARE_PERSISTENT(AdSpriteSet, BaseObject)
BaseObject *_owner;
AdSpriteSet(BaseGame *inGame, BaseObject *owner = nullptr);
~AdSpriteSet() override;
bool loadFile(const char *filename, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
bool loadBuffer(char *buffer, bool complete = true, int lifeTime = -1, TSpriteCacheType cacheType = CACHE_ALL);
BaseSprite *_sprites[NUM_DIRECTIONS];
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,278 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_sprite_set.h"
#include "engines/wintermute/ad/ad_talk_def.h"
#include "engines/wintermute/ad/ad_talk_node.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_dynamic_buffer.h"
#include "engines/wintermute/base/base_sprite.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/utils/utils.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdTalkDef, false)
//////////////////////////////////////////////////////////////////////////
AdTalkDef::AdTalkDef(BaseGame *inGame) : BaseObject(inGame) {
_defaultSpriteFilename = nullptr;
_defaultSprite = nullptr;
_defaultSpriteSetFilename = nullptr;
_defaultSpriteSet = nullptr;
}
//////////////////////////////////////////////////////////////////////////
AdTalkDef::~AdTalkDef() {
for (int32 i = 0; i < _nodes.getSize(); i++) {
delete _nodes[i];
}
_nodes.removeAll();
SAFE_DELETE_ARRAY(_defaultSpriteFilename);
SAFE_DELETE(_defaultSprite);
SAFE_DELETE_ARRAY(_defaultSpriteSetFilename);
SAFE_DELETE(_defaultSpriteSet);
}
//////////////////////////////////////////////////////////////////////////
bool AdTalkDef::loadFile(const char *filename) {
char *buffer = (char *)_game->_fileManager->readWholeFile(filename);
if (buffer == nullptr) {
_game->LOG(0, "AdTalkDef::loadFile failed for file '%s'", filename);
return STATUS_FAILED;
}
bool ret;
setFilename(filename);
if (DID_FAIL(ret = loadBuffer(buffer, true))) {
_game->LOG(0, "Error parsing TALK file '%s'", filename);
}
delete[] buffer;
return ret;
}
TOKEN_DEF_START
TOKEN_DEF(TALK)
TOKEN_DEF(TEMPLATE)
TOKEN_DEF(ACTION)
TOKEN_DEF(DEFAULT_SPRITESET_FILE)
TOKEN_DEF(DEFAULT_SPRITESET)
TOKEN_DEF(DEFAULT_SPRITE)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool AdTalkDef::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(TALK)
TOKEN_TABLE(TEMPLATE)
TOKEN_TABLE(ACTION)
TOKEN_TABLE(DEFAULT_SPRITESET_FILE)
TOKEN_TABLE(DEFAULT_SPRITESET)
TOKEN_TABLE(DEFAULT_SPRITE)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
char *params;
int cmd;
BaseParser parser(_game);
if (complete) {
if (parser.getCommand(&buffer, commands, &params) != TOKEN_TALK) {
_game->LOG(0, "'TALK' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_ACTION: {
AdTalkNode *node = new AdTalkNode(_game);
if (node && DID_SUCCEED(node->loadBuffer(params, false))) {
_nodes.add(node);
} else {
SAFE_DELETE(node);
cmd = PARSERR_GENERIC;
}
}
break;
case TOKEN_DEFAULT_SPRITE:
BaseUtils::setString(&_defaultSpriteFilename, params);
break;
case TOKEN_DEFAULT_SPRITESET_FILE:
BaseUtils::setString(&_defaultSpriteSetFilename, params);
break;
case TOKEN_DEFAULT_SPRITESET: {
SAFE_DELETE(_defaultSpriteSet);
_defaultSpriteSet = new AdSpriteSet(_game);
if (!_defaultSpriteSet || DID_FAIL(_defaultSpriteSet->loadBuffer(params, false))) {
SAFE_DELETE(_defaultSpriteSet);
cmd = PARSERR_GENERIC;
}
}
break;
case TOKEN_EDITOR_PROPERTY:
parseEditorProperty(params, false);
break;
default:
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in TALK definition");
return STATUS_FAILED;
}
if (cmd == PARSERR_GENERIC) {
_game->LOG(0, "Error loading TALK definition");
return STATUS_FAILED;
}
SAFE_DELETE(_defaultSprite);
SAFE_DELETE(_defaultSpriteSet);
if (_defaultSpriteFilename && _defaultSpriteFilename[0]) {
_defaultSprite = new BaseSprite(_game);
if (!_defaultSprite || DID_FAIL(_defaultSprite->loadFile(_defaultSpriteFilename))) {
return STATUS_FAILED;
}
}
if (_defaultSpriteSetFilename && _defaultSpriteSetFilename[0]) {
_defaultSpriteSet = new AdSpriteSet(_game);
if (!_defaultSpriteSet || DID_FAIL(_defaultSpriteSet->loadFile(_defaultSpriteSetFilename))) {
return STATUS_FAILED;
}
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdTalkDef::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_defaultSprite));
persistMgr->transferCharPtr(TMEMBER(_defaultSpriteFilename));
persistMgr->transferPtr(TMEMBER_PTR(_defaultSpriteSet));
persistMgr->transferCharPtr(TMEMBER(_defaultSpriteSetFilename));
_nodes.persist(persistMgr);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdTalkDef::saveAsText(BaseDynamicBuffer *buffer, int indent) {
buffer->putTextIndent(indent, "TALK {\n");
if (_defaultSpriteFilename && _defaultSpriteFilename[0]) {
buffer->putTextIndent(indent + 2, "DEFAULT_SPRITE=\"%s\"\n", _defaultSpriteFilename);
}
if (_defaultSpriteSetFilename && _defaultSpriteSetFilename[0]) {
buffer->putTextIndent(indent + 2, "DEFAULT_SPRITESET_FILE=\"%s\"\n", _defaultSpriteSetFilename);
} else if (_defaultSpriteSet) {
_defaultSpriteSet->saveAsText(buffer, indent + 2);
}
for (int32 i = 0; i < _nodes.getSize(); i++) {
_nodes[i]->saveAsText(buffer, indent + 2);
buffer->putTextIndent(indent, "\n");
}
BaseClass::saveAsText(buffer, indent + 2);
buffer->putTextIndent(indent, "}\n");
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdTalkDef::loadDefaultSprite() {
if (_defaultSpriteFilename && _defaultSpriteFilename[0] && !_defaultSprite) {
_defaultSprite = new BaseSprite(_game);
if (!_defaultSprite || DID_FAIL(_defaultSprite->loadFile(_defaultSpriteFilename))) {
SAFE_DELETE(_defaultSprite);
return STATUS_FAILED;
} else {
return STATUS_OK;
}
} else if (_defaultSpriteSetFilename && _defaultSpriteSetFilename[0] && !_defaultSpriteSet) {
_defaultSpriteSet = new AdSpriteSet(_game);
if (!_defaultSpriteSet || DID_FAIL(_defaultSpriteSet->loadFile(_defaultSpriteSetFilename))) {
SAFE_DELETE(_defaultSpriteSet);
return STATUS_FAILED;
} else {
return STATUS_OK;
}
} else {
return STATUS_OK;
}
}
//////////////////////////////////////////////////////////////////////////
BaseSprite *AdTalkDef::getDefaultSprite(TDirection dir) {
loadDefaultSprite();
if (_defaultSprite) {
return _defaultSprite;
} else if (_defaultSpriteSet) {
return _defaultSpriteSet->getSprite(dir);
} else {
return nullptr;
}
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,57 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADTALKDEF_H
#define WINTERMUTE_ADTALKDEF_H
#include "engines/wintermute/coll_templ.h"
#include "engines/wintermute/base/base_object.h"
namespace Wintermute {
class AdTalkNode;
class AdSpriteSet;
class AdTalkDef : public BaseObject {
public:
char *_defaultSpriteSetFilename;
AdSpriteSet *_defaultSpriteSet;
BaseSprite *getDefaultSprite(TDirection dir);
bool loadDefaultSprite();
DECLARE_PERSISTENT(AdTalkDef, BaseObject)
AdTalkDef(BaseGame *inGame);
~AdTalkDef() override;
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
BaseArray<AdTalkNode *> _nodes;
char *_defaultSpriteFilename;
BaseSprite *_defaultSprite;
bool saveAsText(BaseDynamicBuffer *buffer, int indent = 0) override;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,424 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_talk_holder.h"
#include "engines/wintermute/base/base_dynamic_buffer.h"
#include "engines/wintermute/base/base_engine.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_sprite.h"
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/base/scriptables/script.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
#include "engines/wintermute/base/scriptables/script_ext_array.h"
#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/dcgf.h"
#include "common/str.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdTalkHolder, false)
//////////////////////////////////////////////////////////////////////////
AdTalkHolder::AdTalkHolder(BaseGame *inGame) : AdObject(inGame) {
_sprite = nullptr;
}
//////////////////////////////////////////////////////////////////////////
AdTalkHolder::~AdTalkHolder() {
SAFE_DELETE(_sprite);
for (int32 i = 0; i < _talkSprites.getSize(); i++) {
delete _talkSprites[i];
}
_talkSprites.removeAll();
for (int32 i = 0; i < _talkSpritesEx.getSize(); i++) {
delete _talkSpritesEx[i];
}
_talkSpritesEx.removeAll();
}
//////////////////////////////////////////////////////////////////////////
BaseSprite *AdTalkHolder::getTalkStance(const char *stance) {
BaseSprite *ret = nullptr;
// forced stance?
if (_forcedTalkAnimName && _forcedTalkAnimName[0] && !_forcedTalkAnimUsed) {
_forcedTalkAnimUsed = true;
SAFE_DELETE(_animSprite);
_animSprite = new BaseSprite(_game, this);
if (_animSprite) {
bool res = _animSprite->loadFile(_forcedTalkAnimName);
if (DID_FAIL(res)) {
_game->LOG(res, "AdTalkHolder::getTalkStance: error loading talk sprite (object:\"%s\" sprite:\"%s\")", _name, _forcedTalkAnimName);
SAFE_DELETE(_animSprite);
} else {
return _animSprite;
}
}
}
if (stance != nullptr) {
// search special talk stances
for (int32 i = 0; i < _talkSpritesEx.getSize(); i++) {
if (scumm_stricmp(_talkSpritesEx[i]->_name, stance) == 0) {
ret = _talkSpritesEx[i];
break;
}
}
if (ret == nullptr) {
// serach generic talk stances
for (int32 i = 0; i < _talkSprites.getSize(); i++) {
if (scumm_stricmp(_talkSprites[i]->_name, stance) == 0) {
ret = _talkSprites[i];
break;
}
}
}
}
// not a valid stance? get a random one
if (ret == nullptr) {
if (_talkSprites.getSize() < 1) {
ret = _sprite;
} else {
// TODO: remember last
int rnd = BaseEngine::instance().randInt(0, _talkSprites.getSize() - 1);
ret = _talkSprites[rnd];
}
}
return ret;
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool AdTalkHolder::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
//////////////////////////////////////////////////////////////////////////
// SetSprite
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "SetSprite") == 0) {
stack->correctParams(1);
ScValue *val = stack->pop();
bool setCurrent = false;
if (_currentSprite && _currentSprite == _sprite) {
setCurrent = true;
}
SAFE_DELETE(_sprite);
if (val->isNULL()) {
_sprite = nullptr;
if (setCurrent) {
_currentSprite = nullptr;
}
stack->pushBool(true);
} else {
const char *filename = val->getString();
BaseSprite *spr = new BaseSprite(_game, this);
if (!spr || DID_FAIL(spr->loadFile(filename))) {
script->runtimeError("SetSprite method failed for file '%s'", filename);
stack->pushBool(false);
} else {
_sprite = spr;
if (setCurrent) {
_currentSprite = _sprite;
}
stack->pushBool(true);
}
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// GetSprite
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GetSprite") == 0) {
stack->correctParams(0);
if (!_sprite || !_sprite->_filename || !_sprite->_filename[0]) {
stack->pushNULL();
} else {
stack->pushString(_sprite->_filename);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// GetSpriteObject
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GetSpriteObject") == 0) {
stack->correctParams(0);
if (!_sprite) {
stack->pushNULL();
} else {
stack->pushNative(_sprite, true);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// AddTalkSprite
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AddTalkSprite") == 0) {
stack->correctParams(2);
const char *filename = stack->pop()->getString();
bool ex = stack->pop()->getBool();
BaseSprite *spr = new BaseSprite(_game, this);
if (!spr || DID_FAIL(spr->loadFile(filename))) {
stack->pushBool(false);
script->runtimeError("AddTalkSprite method failed for file '%s'", filename);
} else {
if (ex) {
_talkSpritesEx.add(spr);
} else {
_talkSprites.add(spr);
}
stack->pushBool(true);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// RemoveTalkSprite
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "RemoveTalkSprite") == 0) {
stack->correctParams(2);
const char *filename = stack->pop()->getString();
bool ex = stack->pop()->getBool();
bool setCurrent = false;
bool setTemp2 = false;
if (ex) {
for (int32 i = 0; i < _talkSpritesEx.getSize(); i++) {
if (scumm_stricmp(_talkSpritesEx[i]->_filename, filename) == 0) {
if (_currentSprite == _talkSpritesEx[i]) {
setCurrent = true;
}
if (_tempSprite2 == _talkSpritesEx[i]) {
setTemp2 = true;
}
delete _talkSpritesEx[i];
_talkSpritesEx.removeAt(i);
break;
}
}
} else {
for (int32 i = 0; i < _talkSprites.getSize(); i++) {
if (scumm_stricmp(_talkSprites[i]->_filename, filename) == 0) {
if (_currentSprite == _talkSprites[i]) {
setCurrent = true;
}
if (_tempSprite2 == _talkSprites[i]) {
setTemp2 = true;
}
delete _talkSprites[i];
_talkSprites.removeAt(i);
break;
}
}
}
stack->pushBool(true);
if (setCurrent) {
_currentSprite = _sprite;
}
if (setTemp2) {
_tempSprite2 = _sprite;
}
return STATUS_OK;
}
#ifdef ENABLE_FOXTAIL
//////////////////////////////////////////////////////////////////////////
// [FoxTail] GetTalkSprites
// This is used once, to store Fenek's TalkSprites array to a temporary var
// Later state is restored with this.SetTalkSprite(array_talk_sprites[0])
// Return value should be array
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GetTalkSprites") == 0) {
stack->correctParams(1);
bool ex = stack->pop()->getBool();
BaseArray<BaseSprite *> &sprites = ex ? _talkSpritesEx : _talkSprites;
BaseScriptable *arr;
stack->pushInt(0);
arr = makeSXArray(_game, stack);
for (int32 i = 0; i < sprites.getSize(); i++) {
stack->pushString(sprites[i]->_filename);
((SXArray *)arr)->push(stack->pop());
}
stack->pushNative(arr, false);
return STATUS_OK;
}
#endif
//////////////////////////////////////////////////////////////////////////
// SetTalkSprite
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "SetTalkSprite") == 0) {
stack->correctParams(2);
const char *filename = stack->pop()->getString();
bool ex = stack->pop()->getBool();
bool setCurrent = false;
bool setTemp2 = false;
BaseSprite *spr = new BaseSprite(_game, this);
if (!spr || DID_FAIL(spr->loadFile(filename))) {
stack->pushBool(false);
script->runtimeError("SetTalkSprite method failed for file '%s'", filename);
} else {
// delete current
if (ex) {
for (int32 i = 0; i < _talkSpritesEx.getSize(); i++) {
if (_talkSpritesEx[i] == _currentSprite) {
setCurrent = true;
}
if (_talkSpritesEx[i] == _tempSprite2) {
setTemp2 = true;
}
delete _talkSpritesEx[i];
}
_talkSpritesEx.removeAll();
} else {
for (int32 i = 0; i < _talkSprites.getSize(); i++) {
if (_talkSprites[i] == _currentSprite) {
setCurrent = true;
}
if (_talkSprites[i] == _tempSprite2) {
setTemp2 = true;
}
delete _talkSprites[i];
}
_talkSprites.removeAll();
}
// set new
if (ex) {
_talkSpritesEx.add(spr);
} else {
_talkSprites.add(spr);
}
stack->pushBool(true);
if (setCurrent) {
_currentSprite = spr;
}
if (setTemp2) {
_tempSprite2 = spr;
}
}
return STATUS_OK;
} else {
return AdObject::scCallMethod(script, stack, thisStack, name);
}
}
//////////////////////////////////////////////////////////////////////////
ScValue *AdTalkHolder::scGetProperty(const char *name) {
_scValue->setNULL();
//////////////////////////////////////////////////////////////////////////
// Type (RO)
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Type") == 0) {
_scValue->setString("talk-holder");
return _scValue;
} else {
return AdObject::scGetProperty(name);
}
}
//////////////////////////////////////////////////////////////////////////
bool AdTalkHolder::scSetProperty(const char *name, ScValue *value) {
/*
//////////////////////////////////////////////////////////////////////////
// Item
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Item")==0) {
setItem(value->getString());
return STATUS_OK;
}
else*/ return AdObject::scSetProperty(name, value);
}
//////////////////////////////////////////////////////////////////////////
const char *AdTalkHolder::scToString() {
return "[talk-holder object]";
}
//////////////////////////////////////////////////////////////////////////
bool AdTalkHolder::saveAsText(BaseDynamicBuffer *buffer, int indent) {
for (int32 i = 0; i < _talkSprites.getSize(); i++) {
if (_talkSprites[i]->_filename && _talkSprites[i]->_filename[0]) {
buffer->putTextIndent(indent + 2, "TALK=\"%s\"\n", _talkSprites[i]->_filename);
}
}
for (int32 i = 0; i < _talkSpritesEx.getSize(); i++) {
if (_talkSpritesEx[i]->_filename && _talkSpritesEx[i]->_filename[0]) {
buffer->putTextIndent(indent + 2, "TALK_SPECIAL=\"%s\"\n", _talkSpritesEx[i]->_filename);
}
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdTalkHolder::persist(BasePersistenceManager *persistMgr) {
AdObject::persist(persistMgr);
persistMgr->transferPtr(TMEMBER_PTR(_sprite));
_talkSprites.persist(persistMgr);
_talkSpritesEx.persist(persistMgr);
return STATUS_OK;
}
} // End of namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADTALKHOLDER_H
#define WINTERMUTE_ADTALKHOLDER_H
#include "engines/wintermute/ad/ad_object.h"
namespace Wintermute {
class AdTalkHolder : public AdObject {
public:
DECLARE_PERSISTENT(AdTalkHolder, AdObject)
virtual BaseSprite *getTalkStance(const char *stance);
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
BaseSprite *_sprite;
BaseArray<BaseSprite *> _talkSprites;
BaseArray<BaseSprite *> _talkSpritesEx;
AdTalkHolder(BaseGame *inGame);
~AdTalkHolder() override;
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,294 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/ad/ad_sprite_set.h"
#include "engines/wintermute/ad/ad_talk_node.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/base/base_dynamic_buffer.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_sprite.h"
#include "engines/wintermute/utils/utils.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdTalkNode, false)
//////////////////////////////////////////////////////////////////////////
AdTalkNode::AdTalkNode(BaseGame *inGame) : BaseClass(inGame) {
_sprite = nullptr;
_spriteFilename = nullptr;
_spriteSet = nullptr;
_spriteSetFilename = nullptr;
_comment = nullptr;
_startTime = _endTime = 0;
_playToEnd = false;
_preCache = false;
}
//////////////////////////////////////////////////////////////////////////
AdTalkNode::~AdTalkNode() {
SAFE_DELETE_ARRAY(_spriteFilename);
SAFE_DELETE(_sprite);
SAFE_DELETE_ARRAY(_spriteSetFilename);
SAFE_DELETE(_spriteSet);
SAFE_DELETE_ARRAY(_comment);
}
TOKEN_DEF_START
TOKEN_DEF(ACTION)
TOKEN_DEF(SPRITESET_FILE)
TOKEN_DEF(SPRITESET)
TOKEN_DEF(SPRITE)
TOKEN_DEF(START_TIME)
TOKEN_DEF(END_TIME)
TOKEN_DEF(COMMENT)
TOKEN_DEF(PRECACHE)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool AdTalkNode::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(ACTION)
TOKEN_TABLE(SPRITESET_FILE)
TOKEN_TABLE(SPRITESET)
TOKEN_TABLE(SPRITE)
TOKEN_TABLE(START_TIME)
TOKEN_TABLE(END_TIME)
TOKEN_TABLE(COMMENT)
TOKEN_TABLE(PRECACHE)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
char *params;
int cmd;
BaseParser parser(_game);
if (complete) {
if (parser.getCommand(&buffer, commands, &params) != TOKEN_ACTION) {
_game->LOG(0, "'ACTION' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
_endTime = 0;
_playToEnd = false;
_preCache = false;
while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_SPRITE:
BaseUtils::setString(&_spriteFilename, params);
break;
case TOKEN_SPRITESET_FILE:
BaseUtils::setString(&_spriteSetFilename, params);
break;
case TOKEN_SPRITESET: {
SAFE_DELETE(_spriteSet);
_spriteSet = new AdSpriteSet(_game);
if (!_spriteSet || DID_FAIL(_spriteSet->loadBuffer(params, false))) {
SAFE_DELETE(_spriteSet);
cmd = PARSERR_GENERIC;
}
}
break;
case TOKEN_START_TIME:
parser.scanStr(params, "%d", &_startTime);
break;
case TOKEN_END_TIME:
parser.scanStr(params, "%d", &_endTime);
break;
case TOKEN_PRECACHE:
parser.scanStr(params, "%b", &_preCache);
break;
case TOKEN_COMMENT:
if (_game->_editorMode) {
BaseUtils::setString(&_comment, params);
}
break;
case TOKEN_EDITOR_PROPERTY:
parseEditorProperty(params, false);
break;
default:
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in ACTION definition");
return STATUS_FAILED;
}
if (cmd == PARSERR_GENERIC) {
_game->LOG(0, "Error loading ACTION definition");
return STATUS_FAILED;
}
if (_endTime == 0) {
_playToEnd = true;
} else {
_playToEnd = false;
}
if (_preCache && _spriteFilename && _spriteFilename[0]) {
SAFE_DELETE(_sprite);
_sprite = new BaseSprite(_game);
if (!_sprite || DID_FAIL(_sprite->loadFile(_spriteFilename))) {
return STATUS_FAILED;
}
}
if (_preCache && _spriteSetFilename && _spriteSetFilename[0]) {
SAFE_DELETE(_spriteSet);
_spriteSet = new AdSpriteSet(_game);
if (!_spriteSet || DID_FAIL(_spriteSet->loadFile(_spriteSetFilename))) {
return STATUS_FAILED;
}
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdTalkNode::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferCharPtr(TMEMBER(_comment));
persistMgr->transferUint32(TMEMBER(_startTime));
persistMgr->transferUint32(TMEMBER(_endTime));
persistMgr->transferBool(TMEMBER(_playToEnd));
persistMgr->transferPtr(TMEMBER_PTR(_sprite));
persistMgr->transferCharPtr(TMEMBER(_spriteFilename));
persistMgr->transferPtr(TMEMBER_PTR(_spriteSet));
persistMgr->transferCharPtr(TMEMBER(_spriteSetFilename));
// initialise to default
if (!persistMgr->getIsSaving()) {
_preCache = false;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdTalkNode::saveAsText(BaseDynamicBuffer *buffer, int indent) {
buffer->putTextIndent(indent, "ACTION {\n");
if (_comment && _comment[0]) {
buffer->putTextIndent(indent + 2, "COMMENT=\"%s\"\n", _comment);
}
buffer->putTextIndent(indent + 2, "START_TIME=%d\n", _startTime);
if (!_playToEnd) {
buffer->putTextIndent(indent + 2, "END_TIME=%d\n", _endTime);
}
if (_spriteFilename && _spriteFilename[0]) {
buffer->putTextIndent(indent + 2, "SPRITE=\"%s\"\n", _spriteFilename);
}
if (_spriteSetFilename && _spriteSetFilename[0]) {
buffer->putTextIndent(indent + 2, "SPRITESET_FILE=\"%s\"\n", _spriteSetFilename);
} else if (_spriteSet) {
_spriteSet->saveAsText(buffer, indent + 2);
}
if (_preCache) {
buffer->putTextIndent(indent + 2, "PRECACHE=\"%s\"\n", _preCache ? "TRUE" : "FALSE");
}
BaseClass::saveAsText(buffer, indent + 2);
buffer->putTextIndent(indent, "}\n");
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdTalkNode::loadSprite() {
if (_spriteFilename && _spriteFilename[0] && !_sprite) {
_sprite = new BaseSprite(_game);
if (!_sprite || DID_FAIL(_sprite->loadFile(_spriteFilename))) {
SAFE_DELETE(_sprite);
return STATUS_FAILED;
} else {
return STATUS_OK;
}
} else if (_spriteSetFilename && _spriteSetFilename[0] && !_spriteSet) {
_spriteSet = new AdSpriteSet(_game);
if (!_spriteSet || DID_FAIL(_spriteSet->loadFile(_spriteSetFilename))) {
SAFE_DELETE(_spriteSet);
return STATUS_FAILED;
} else {
return STATUS_OK;
}
} else {
return STATUS_OK;
}
}
//////////////////////////////////////////////////////////////////////////
bool AdTalkNode::isInTimeInterval(uint32 time, TDirection dir) {
if (time >= _startTime) {
if (_playToEnd) {
if ((_spriteFilename && _spriteFilename[0] && _sprite == nullptr) || (_sprite && _sprite->_finished == false)) {
return true;
} else if ((_spriteSetFilename && _spriteSetFilename[0] && _spriteSet == nullptr) || (_spriteSet && _spriteSet->getSprite(dir) && _spriteSet->getSprite(dir)->_finished == false)) {
return true;
} else {
return false;
}
} else {
return _endTime >= time;
}
} else {
return false;
}
}
//////////////////////////////////////////////////////////////////////////
BaseSprite *AdTalkNode::getSprite(TDirection dir) {
loadSprite();
if (_sprite) {
return _sprite;
} else if (_spriteSet) {
return _spriteSet->getSprite(dir);
} else {
return nullptr;
}
}
} // End of namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADTALKNODE_H
#define WINTERMUTE_ADTALKNODE_H
#include "engines/wintermute/persistent.h"
#include "engines/wintermute/base/base.h"
namespace Wintermute {
class AdSpriteSet;
class BaseSprite;
class AdTalkNode : public BaseClass {
public:
char *_spriteSetFilename;
AdSpriteSet *_spriteSet;
BaseSprite *getSprite(TDirection dir);
bool isInTimeInterval(uint32 time, TDirection dir);
bool loadSprite();
DECLARE_PERSISTENT(AdTalkNode, BaseClass)
AdTalkNode(BaseGame *inGame);
~AdTalkNode() override;
bool loadBuffer(char *buffer, bool complete = true);
bool saveAsText(BaseDynamicBuffer *buffer, int indent = 0) override;
char *_spriteFilename;
BaseSprite *_sprite;
uint32 _startTime;
uint32 _endTime;
bool _playToEnd;
bool _preCache;
char *_comment;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,112 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADTYPES_H
#define WINTERMUTE_ADTYPES_H
namespace Wintermute {
typedef enum {
GAME_NORMAL,
GAME_WAITING_RESPONSE
} TGameStateEx;
typedef enum {
OBJECT_ENTITY,
OBJECT_REGION,
OBJECT_ACTOR,
OBJECT_NONE
} TObjectType;
typedef enum {
ENTITY_NORMAL,
ENTITY_SOUND
} TEntityType;
typedef enum {
STATE_NONE,
STATE_IDLE,
STATE_PLAYING_ANIM,
STATE_READY,
STATE_FOLLOWING_PATH,
STATE_SEARCHING_PATH,
STATE_WAITING_PATH,
STATE_TURNING_LEFT,
STATE_TURNING_RIGHT,
STATE_TURNING,
STATE_TALKING,
STATE_DIRECT_CONTROL,
STATE_PLAYING_ANIM_SET
} TObjectState;
typedef enum {
DIRECT_WALK_NONE,
DIRECT_WALK_FW,
DIRECT_WALK_BK
} TDirectWalkMode;
typedef enum {
DIRECT_TURN_NONE,
DIRECT_TURN_CW,
DIRECT_TURN_CCW
} TDirectTurnMode;
typedef enum {
RESPONSE_TEXT,
RESPONSE_ICON
} TResponseStyle;
typedef enum {
RESPONSE_ALWAYS,
RESPONSE_ONCE,
RESPONSE_ONCE_GAME
} TResponseType;
typedef enum {
TALK_SKIP_LEFT = 0,
TALK_SKIP_RIGHT = 1,
TALK_SKIP_BOTH = 2,
TALK_SKIP_NONE = 3
} TTalkSkipButton;
typedef enum {
VIDEO_SKIP_LEFT = 0,
VIDEO_SKIP_RIGHT = 1,
VIDEO_SKIP_BOTH = 2,
VIDEO_SKIP_NONE = 3
} TVideoSkipButton;
typedef enum {
GEOM_WAYPOINT,
GEOM_WALKPLANE,
GEOM_BLOCKED,
GEOM_GENERIC
} TGeomNodeType;
} // End of namespace Wintermute
#endif

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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#include "engines/wintermute/ad/ad_walkplane.h"
#include "engines/wintermute/base/base_persistence_manager.h"
#include "engines/wintermute/base/gfx/3dmesh.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
//////////////////////////////////////////////////////////////////////////
AdWalkplane::AdWalkplane(BaseGame *inGame) : BaseScriptable(inGame, false, false) {
_mesh = nullptr;
_active = true;
_receiveShadows = false;
}
//////////////////////////////////////////////////////////////////////////
AdWalkplane::~AdWalkplane() {
SAFE_DELETE(_mesh);
}
//////////////////////////////////////////////////////////////////////////
bool AdWalkplane::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferBool(TMEMBER(_active));
return true;
}
} // namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#ifndef WINTERMUTE_AD_WALKPLANE_H
#define WINTERMUTE_AD_WALKPLANE_H
#include "engines/wintermute/base/base_scriptable.h"
namespace Wintermute {
class Mesh3DS;
class AdWalkplane : public BaseScriptable {
public:
bool _receiveShadows;
bool persist(BasePersistenceManager *persistMgr);
bool _active;
Mesh3DS *_mesh;
AdWalkplane(BaseGame *inGame);
virtual ~AdWalkplane();
};
} // namespace Wintermute
#endif

View File

@@ -0,0 +1,272 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/wintermute.h"
#include "engines/wintermute/ad/ad_waypoint_group.h"
#include "engines/wintermute/base/base_dynamic_buffer.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/base/base_region.h"
#include "engines/wintermute/base/scriptables/script_value.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(AdWaypointGroup, false)
//////////////////////////////////////////////////////////////////////////
AdWaypointGroup::AdWaypointGroup(BaseGame *inGame) : BaseObject(inGame) {
_active = true;
_editorSelectedPoint = -1;
_lastMimicScale = -1;
_lastMimicX = _lastMimicY = INT_MIN_VALUE;
}
//////////////////////////////////////////////////////////////////////////
AdWaypointGroup::~AdWaypointGroup() {
cleanup();
}
//////////////////////////////////////////////////////////////////////////
void AdWaypointGroup::cleanup() {
for (int32 i = 0; i < _points.getSize(); i++) {
delete _points[i];
}
_points.removeAll();
_editorSelectedPoint = -1;
}
//////////////////////////////////////////////////////////////////////////
bool AdWaypointGroup::loadFile(const char *filename) {
char *buffer = (char *)_game->_fileManager->readWholeFile(filename);
if (buffer == nullptr) {
_game->LOG(0, "AdWaypointGroup::loadFile failed for file '%s'", filename);
return STATUS_FAILED;
}
bool ret;
setFilename(filename);
if (DID_FAIL(ret = loadBuffer(buffer, true))) {
_game->LOG(0, "Error parsing WAYPOINTS file '%s'", filename);
}
delete[] buffer;
return ret;
}
TOKEN_DEF_START
TOKEN_DEF(WAYPOINTS)
TOKEN_DEF(TEMPLATE)
TOKEN_DEF(NAME)
TOKEN_DEF(POINT)
TOKEN_DEF(EDITOR_SELECTED_POINT)
TOKEN_DEF(EDITOR_SELECTED)
TOKEN_DEF(PROPERTY)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool AdWaypointGroup::loadBuffer(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(WAYPOINTS)
TOKEN_TABLE(TEMPLATE)
TOKEN_TABLE(NAME)
TOKEN_TABLE(POINT)
TOKEN_TABLE(EDITOR_SELECTED_POINT)
TOKEN_TABLE(EDITOR_SELECTED)
TOKEN_TABLE(PROPERTY)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE_END
char *params;
int cmd;
BaseParser parser(_game);
if (complete) {
if (parser.getCommand(&buffer, commands, &params) != TOKEN_WAYPOINTS) {
_game->LOG(0, "'WAYPOINTS' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_TEMPLATE:
if (DID_FAIL(loadFile(params))) {
cmd = PARSERR_GENERIC;
}
break;
case TOKEN_NAME:
setName(params);
break;
case TOKEN_POINT: {
int x, y;
parser.scanStr(params, "%d,%d", &x, &y);
_points.add(new BasePoint(x, y));
}
break;
case TOKEN_EDITOR_SELECTED:
parser.scanStr(params, "%b", &_editorSelected);
break;
case TOKEN_EDITOR_SELECTED_POINT:
parser.scanStr(params, "%d", &_editorSelectedPoint);
break;
case TOKEN_PROPERTY:
parseProperty(params, false);
break;
case TOKEN_EDITOR_PROPERTY:
parseEditorProperty(params, false);
break;
default:
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in WAYPOINTS definition");
return STATUS_FAILED;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdWaypointGroup::saveAsText(BaseDynamicBuffer *buffer, int indent) {
buffer->putTextIndent(indent, "WAYPOINTS {\n");
buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", _name);
buffer->putTextIndent(indent + 2, "EDITOR_SELECTED=%s\n", _editorSelected ? "TRUE" : "FALSE");
buffer->putTextIndent(indent + 2, "EDITOR_SELECTED_POINT=%d\n", _editorSelectedPoint);
if (_scProp) {
_scProp->saveAsText(buffer, indent + 2);
}
BaseClass::saveAsText(buffer, indent + 2);
for (int32 i = 0; i < _points.getSize(); i++) {
buffer->putTextIndent(indent + 2, "POINT {%d,%d}\n", _points[i]->x, _points[i]->y);
}
buffer->putTextIndent(indent, "}\n");
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool AdWaypointGroup::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferBool(TMEMBER(_active));
persistMgr->transferSint32(TMEMBER(_editorSelectedPoint));
persistMgr->transferFloat(TMEMBER(_lastMimicScale));
persistMgr->transferSint32(TMEMBER(_lastMimicX));
persistMgr->transferSint32(TMEMBER(_lastMimicY));
_points.persist(persistMgr);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
ScValue *AdWaypointGroup::scGetProperty(const char *name) {
_scValue->setNULL();
//////////////////////////////////////////////////////////////////////////
// Type
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Type") == 0) {
_scValue->setString("waypoint-group");
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Active
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Active") == 0) {
_scValue->setBool(_active);
return _scValue;
} else {
return BaseObject::scGetProperty(name);
}
}
//////////////////////////////////////////////////////////////////////////
bool AdWaypointGroup::scSetProperty(const char *name, ScValue *value) {
//////////////////////////////////////////////////////////////////////////
// Active
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Active") == 0) {
_active = value->getBool();
return STATUS_OK;
}
else {
return BaseObject::scSetProperty(name, value);
}
}
//////////////////////////////////////////////////////////////////////////
bool AdWaypointGroup::mimic(AdWaypointGroup *wpt, float scale, int argX, int argY) {
if (scale == _lastMimicScale && argX == _lastMimicX && argY == _lastMimicY) {
return STATUS_OK;
}
cleanup();
for (int32 i = 0; i < wpt->_points.getSize(); i++) {
int x = (int)((float)wpt->_points[i]->x * scale / 100.0f);
int y = (int)((float)wpt->_points[i]->y * scale / 100.0f);
_points.add(new BasePoint(x + argX, y + argY));
}
_lastMimicScale = scale;
_lastMimicX = argX;
_lastMimicY = argY;
return STATUS_OK;
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,57 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_ADWAYPOINTGROUP_H
#define WINTERMUTE_ADWAYPOINTGROUP_H
#include "engines/wintermute/base/base_object.h"
namespace Wintermute {
class BasePoint;
class AdWaypointGroup : public BaseObject {
public:
float _lastMimicScale;
int32 _lastMimicX;
int32 _lastMimicY;
void cleanup();
bool mimic(AdWaypointGroup *wpt, float scale = 100.0f, int x = 0, int y = 0);
DECLARE_PERSISTENT(AdWaypointGroup, BaseObject)
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
bool _active;
AdWaypointGroup(BaseGame *inGame);
bool loadFile(const char *filename);
bool loadBuffer(char *buffer, bool complete = true);
~AdWaypointGroup() override;
BaseArray<BasePoint *> _points;
int32 _editorSelectedPoint;
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
};
} // End of namespace Wintermute
#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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#include "common/util.h"
#include "engines/wintermute/ad/ad_waypoint_group3d.h"
#include "engines/wintermute/base/gfx/3dmesh.h"
namespace Wintermute {
//////////////////////////////////////////////////////////////////////////
AdWaypointGroup3D::AdWaypointGroup3D(BaseGame *inGame) : BaseClass(inGame) {
_active = true;
}
//////////////////////////////////////////////////////////////////////////
AdWaypointGroup3D::~AdWaypointGroup3D() {
for (int32 i = 0; i < _points.getSize(); i++) {
delete _points[i];
}
_points.removeAll();
}
//////////////////////////////////////////////////////////////////////////
bool AdWaypointGroup3D::addFromMesh(Mesh3DS *mesh) {
DXVector3 min = DXVector3(0, 0, 0);
DXVector3 max = DXVector3(0, 0, 0);
if (mesh->_numVertices > 0) {
min = max = mesh->_vertices[0]._pos;
}
for (int i = 0; i < mesh->_numVertices; i++) {
min._x = MIN(min._x, mesh->_vertices[i]._pos._x);
min._y = MIN(min._y, mesh->_vertices[i]._pos._y);
min._z = MIN(min._z, mesh->_vertices[i]._pos._z);
max._x = MAX(max._x, mesh->_vertices[i]._pos._x);
max._y = MAX(max._y, mesh->_vertices[i]._pos._y);
max._z = MAX(max._z, mesh->_vertices[i]._pos._z);
}
DXVector3 *vect = new DXVector3;
vect->_x = min._x + (max._x - min._x) / 2;
vect->_y = min._y + (max._y - min._y) / 2;
vect->_z = min._z + (max._z - min._z) / 2;
_points.add(vect);
return true;
}
} // namespace Wintermute

View File

@@ -0,0 +1,52 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#ifndef WINTERMUTE_AD_WAYPOINT_GROUP_3D_H
#define WINTERMUTE_AD_WAYPOINT_GROUP_3D_H
#include "engines/wintermute/base/base.h"
#include "engines/wintermute/coll_templ.h"
namespace Wintermute {
class CAdSceneGeometry;
class Mesh3DS;
class AdWaypointGroup3D : public BaseClass {
public:
//DECLARE_PERSISTENT(AdWaypointGroup3D, BaseClass);
bool _active;
bool addFromMesh(Mesh3DS *mesh);
AdWaypointGroup3D(BaseGame *inGame);
virtual ~AdWaypointGroup3D();
BaseArray<DXVector3 *> _points;
};
}
#endif

View File

@@ -0,0 +1,177 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/base/base.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_engine.h"
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/base/base_dynamic_buffer.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
//////////////////////////////////////////////////////////////////////
BaseClass::BaseClass(BaseGame *gameOwner) {
_game = gameOwner;
_persistable = true;
}
//////////////////////////////////////////////////////////////////////////
BaseClass::BaseClass() {
_game = nullptr;
_persistable = true;
}
//////////////////////////////////////////////////////////////////////
BaseClass::~BaseClass() {
_editorProps.clear();
}
//////////////////////////////////////////////////////////////////////////
Common::String BaseClass::getEditorProp(const Common::String &propName, const Common::String &initVal) {
_editorPropsIter = _editorProps.find(propName);
if (_editorPropsIter != _editorProps.end()) {
return _editorPropsIter->_value.c_str();
} else {
return initVal;
}
}
//////////////////////////////////////////////////////////////////////////
bool BaseClass::setEditorProp(const Common::String &propName, const Common::String &propValue) {
if (propName.empty()) {
return STATUS_FAILED;
}
if (propValue.empty()) {
_editorProps.erase(propName);
} else {
_editorProps[propName] = propValue;
}
return STATUS_OK;
}
TOKEN_DEF_START
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF(NAME)
TOKEN_DEF(VALUE)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////////
bool BaseClass::parseEditorProperty(char *buffer, bool complete) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE(NAME)
TOKEN_TABLE(VALUE)
TOKEN_TABLE_END
if (!_game->_editorMode) {
return STATUS_OK;
}
char *params;
int cmd;
BaseParser parser(_game);
if (complete) {
if (parser.getCommand(&buffer, commands, &params) != TOKEN_EDITOR_PROPERTY) {
_game->LOG(0, "'EDITOR_PROPERTY' keyword expected.");
return STATUS_FAILED;
}
buffer = params;
}
char *propName = nullptr;
char *propValue = nullptr;
while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_NAME: {
SAFE_DELETE_ARRAY(propName);
size_t propNameSize = strlen(params) + 1;
propName = new char[propNameSize];
Common::strcpy_s(propName, propNameSize, params);
break;
}
case TOKEN_VALUE: {
SAFE_DELETE_ARRAY(propValue);
size_t propValueSize = strlen(params) + 1;
propValue = new char[propValueSize];
Common::strcpy_s(propValue, propValueSize, params);
break;
}
default:
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
SAFE_DELETE_ARRAY(propName);
SAFE_DELETE_ARRAY(propValue);
_game->LOG(0, "Syntax error in EDITOR_PROPERTY definition");
return STATUS_FAILED;
}
if (cmd == PARSERR_GENERIC || propName == nullptr || propValue == nullptr) {
SAFE_DELETE_ARRAY(propName);
SAFE_DELETE_ARRAY(propValue);
_game->LOG(0, "Error loading EDITOR_PROPERTY definition");
return STATUS_FAILED;
}
setEditorProp(propName, propValue);
SAFE_DELETE_ARRAY(propName);
SAFE_DELETE_ARRAY(propValue);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool BaseClass::saveAsText(BaseDynamicBuffer *buffer, int indent) {
_editorPropsIter = _editorProps.begin();
while (_editorPropsIter != _editorProps.end()) {
buffer->putTextIndent(indent, "EDITOR_PROPERTY\n");
buffer->putTextIndent(indent, "{\n");
buffer->putTextIndent(indent + 2, "NAME=\"%s\"\n", _editorPropsIter->_key.c_str());
buffer->putTextIndent(indent + 2, "VALUE=\"%s\"\n", _editorPropsIter->_value.c_str());
buffer->putTextIndent(indent, "}\n\n");
_editorPropsIter++;
}
return STATUS_OK;
}
} // End of namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_BASE_BASE_H
#define WINTERMUTE_BASE_BASE_H
#include "engines/wintermute/wintypes.h"
#include "engines/wintermute/dctypes.h"
#include "common/str.h"
#include "common/hashmap.h"
#include "common/hash-str.h"
namespace Wintermute {
class BaseGame;
class BaseDynamicBuffer;
class BasePersistenceManager;
class BaseClass {
public:
bool _persistable;
bool setEditorProp(const Common::String &propName, const Common::String &propValue);
Common::String getEditorProp(const Common::String &propName, const Common::String &initVal = Common::String());
BaseClass(TDynamicConstructor, TDynamicConstructor) {}
bool parseEditorProperty(char *buffer, bool complete = true);
virtual bool saveAsText(BaseDynamicBuffer *buffer, int indent = 0);
BaseClass();
BaseGame *_game;
BaseClass(BaseGame *gameOwner);
virtual ~BaseClass();
virtual const char *getClassName() { return ""; }
virtual bool persist(BasePersistenceManager *persistMgr) { return true; }
Common::HashMap<Common::String, Common::String> _editorProps;
Common::HashMap<Common::String, Common::String>::iterator _editorPropsIter;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,221 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#include "engines/wintermute/base/base.h"
#include "engines/wintermute/base/base_access_mgr.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "engines/wintermute/utils/string_util.h"
#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/dcgf.h"
#include "common/text-to-speech.h"
namespace Wintermute {
//////////////////////////////////////////////////////////////////////////
BaseAccessMgr::BaseAccessMgr(BaseGame *inGame) : BaseClass(inGame) {
_voice = nullptr;
_ttsAvailable = false;
_activeObject = nullptr;
_prevActiveObject = nullptr;
BasePlatform::setRectEmpty(&_hintRect);
_hintAfterGUI = false;
_playingType = TTS_CAPTION;
_ctrlPressed = false;
}
//////////////////////////////////////////////////////////////////////////
BaseAccessMgr::~BaseAccessMgr() {
_activeObject = nullptr; // ref only
_ttsAvailable = false;
}
//////////////////////////////////////////////////////////////////////////
bool BaseAccessMgr::initialize() {
_ttsAvailable = false;
if (!_game->_accessTTSEnabled)
return true;
_voice = g_system->getTextToSpeechManager();
if (_voice) {
_ttsAvailable = true;
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool BaseAccessMgr::initLoop() {
BasePlatform::setRectEmpty(&_hintRect);
return true;
}
//////////////////////////////////////////////////////////////////////////
bool BaseAccessMgr::displayBeforeGUI() {
if (!_game->_accessKeyboardEnabled)
return true;
if (!_hintAfterGUI) {
return displayInternal();
} else {
return true;
}
}
//////////////////////////////////////////////////////////////////////////
bool BaseAccessMgr::displayAfterGUI() {
if (!_game->_accessKeyboardEnabled)
return true;
if (_hintAfterGUI) {
return displayInternal();
} else {
return true;
}
}
//////////////////////////////////////////////////////////////////////////
bool BaseAccessMgr::displayInternal() {
if (!_ctrlPressed) {
return true;
}
if (!BasePlatform::isRectEmpty(&_hintRect)) {
_game->_renderer->drawRect(_hintRect.left, _hintRect.top, _hintRect.right, _hintRect.bottom, 0xFFFF0000, 4);
// reposition mouse pointer
if (_game->_accessKeyboardCursorSkip && _activeObject != _prevActiveObject) {
_prevActiveObject = _activeObject;
Common::Point32 p;
p.x = _hintRect.left + (_hintRect.right - _hintRect.left) / 2;
p.y = _hintRect.top + (_hintRect.bottom - _hintRect.top) / 2;
p.x += _game->_renderer->_drawOffsetX;
p.y += _game->_renderer->_drawOffsetY;
p.x = MAX<int32>(0, p.x);
p.y = MAX<int32>(0, p.y);
p.x = MIN<int32>(_game->_renderer->_width - 1, p.x);
p.y = MIN<int32>(_game->_renderer->_height - 1, p.y);
//ClientToScreen(Game->m_Renderer->m_Window, &p);
BasePlatform::setCursorPos(p.x, p.y);
}
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool BaseAccessMgr::setHintRect(Common::Rect32 *hintRect, bool afterGUI) {
if (!hintRect) {
BasePlatform::setRectEmpty(&_hintRect);
} else {
_hintRect = *hintRect;
}
_hintAfterGUI = afterGUI;
return true;
}
//////////////////////////////////////////////////////////////////////////
bool BaseAccessMgr::setActiveObject(BaseObject *activeObj) {
if (!_game->_accessKeyboardEnabled) {
return true;
}
_activeObject = activeObj;
if (!activeObj) {
_prevActiveObject = nullptr;
}
return true;
}
//////////////////////////////////////////////////////////////////////////
BaseObject *BaseAccessMgr::getActiveObject() {
return _activeObject;
}
//////////////////////////////////////////////////////////////////////////
bool BaseAccessMgr::speak(const char *str, TTTSType type) {
if (!_ttsAvailable) {
return true;
}
if (type == TTS_CAPTION && !_game->_accessTTSCaptions) {
return true;
}
if (type == TTS_TALK && !_game->_accessTTSTalk) {
return true;
}
if (type == TTS_KEYPRESS && !_game->_accessTTSKeypress) {
return true;
}
if (!str || !str[0]) {
return true;
}
WideString textStr;
if (_game->_textEncoding == TEXT_UTF8) {
textStr = StringUtil::utf8ToWide(str);
} else {
textStr = StringUtil::ansiToWide(str, CHARSET_DEFAULT);
}
if (!textStr.empty()) {
_playingType = type;
return _voice->say(str);
} else {
return false;
}
}
//////////////////////////////////////////////////////////////////////////
bool BaseAccessMgr::stop() {
if (!_ttsAvailable) {
return true;
}
_playingType = TTS_CAPTION;
return _voice->stop();
}
//////////////////////////////////////////////////////////////////////////
BaseObject *BaseAccessMgr::getNextObject() {
_activeObject = _game->getNextAccessObject(_activeObject);
return _activeObject;
}
//////////////////////////////////////////////////////////////////////////
BaseObject *BaseAccessMgr::getPrevObject() {
_activeObject = _game->getPrevAccessObject(_activeObject);
return _activeObject;
}
} // End of namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#ifndef WINTERMUTE_BASE_ACCESS_MGR_H
#define WINTERMUTE_BASE_ACCESS_MGR_H
#include "engines/wintermute/base/base.h"
#include "engines/wintermute/dctypes.h"
#include "common/rect.h"
#include "common/text-to-speech.h"
namespace Wintermute {
class BaseObject;
class BaseAccessMgr : public BaseClass {
public:
BaseAccessMgr(BaseGame *inGame);
virtual ~BaseAccessMgr();
bool _ttsAvailable;
bool initialize();
bool speak(const char *str, TTTSType type);
bool stop();
BaseObject *getNextObject();
BaseObject *getPrevObject();
bool initLoop();
bool displayBeforeGUI();
bool displayAfterGUI();
bool setHintRect(Common::Rect32 *hintRect = nullptr, bool afterGUI = false);
bool setActiveObject(BaseObject *activeObj = nullptr);
BaseObject *getActiveObject();
bool _ctrlPressed;
private:
TTTSType _playingType;
bool displayInternal();
Common::TextToSpeechManager *_voice;
BaseObject *_activeObject;
BaseObject *_prevActiveObject;
Common::Rect32 _hintRect;
bool _hintAfterGUI;
};
#endif
} // End of namespace Wintermute

View File

@@ -0,0 +1,138 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/base/base_active_rect.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_engine.h"
#include "engines/wintermute/base/base_region.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "engines/wintermute/platform_osystem.h"
namespace Wintermute {
//////////////////////////////////////////////////////////////////////
BaseActiveRect::BaseActiveRect(BaseGame *inGame) : BaseClass(inGame) {
BasePlatform::setRectEmpty(&_rect);
_owner = nullptr;
_frame = nullptr;
#ifdef ENABLE_WME3D
_xmodel = nullptr;
#endif
_region = nullptr;
_zoomX = 100;
_zoomY = 100;
_offsetX = _offsetY = 0;
clipRect();
}
//////////////////////////////////////////////////////////////////////
BaseActiveRect::BaseActiveRect(BaseGame *inGame, BaseObject *owner, BaseSubFrame *frame, int x, int y, int width, int height, float zoomX, float zoomY, bool precise) : BaseClass(inGame) {
_owner = owner;
_frame = frame;
BasePlatform::setRect(&_rect, x, y, x + width, y + height);
_zoomX = zoomX;
_zoomY = zoomY;
_precise = precise;
#ifdef ENABLE_WME3D
_xmodel = nullptr;
#endif
_region = nullptr;
_offsetX = _offsetY = 0;
clipRect();
}
//////////////////////////////////////////////////////////////////////
#ifdef ENABLE_WME3D
BaseActiveRect::BaseActiveRect(BaseGame *inGame, BaseObject *owner, XModel *model, int x, int y, int width, int height, bool precise) : BaseClass(inGame) {
_owner = owner;
_xmodel = model;
BasePlatform::setRect(&_rect, x, y, x + width, y + height);
_zoomX = 100;
_zoomY = 100;
_precise = precise;
_frame = nullptr;
_region = nullptr;
_offsetX = _offsetY = 0;
clipRect();
}
#endif
//////////////////////////////////////////////////////////////////////
BaseActiveRect::BaseActiveRect(BaseGame *inGame, BaseObject *owner, BaseRegion *region, int offsetX, int offsetY) : BaseClass(inGame) {
_owner = owner;
_region = region;
BasePlatform::copyRect(&_rect, &region->_rect);
BasePlatform::offsetRect(&_rect, -offsetX, -offsetY);
_zoomX = 100;
_zoomY = 100;
_precise = true;
_frame = nullptr;
#ifdef ENABLE_WME3D
_xmodel = nullptr;
#endif
clipRect();
_offsetX = offsetX;
_offsetY = offsetY;
}
//////////////////////////////////////////////////////////////////////
BaseActiveRect::~BaseActiveRect() {
_owner = nullptr;
_frame = nullptr;
#ifdef ENABLE_WME3D
_xmodel = nullptr;
#endif
_region = nullptr;
}
//////////////////////////////////////////////////////////////////////////
void BaseActiveRect::clipRect() {
Common::Rect32 rc;
bool customViewport;
_game->getCurrentViewportRect(&rc, &customViewport);
BaseRenderer *rend = _game->_renderer;
if (!customViewport) {
rc.left -= rend->_drawOffsetX;
rc.right -= rend->_drawOffsetX;
rc.top -= rend->_drawOffsetY;
rc.bottom -= rend->_drawOffsetY;
}
if (rc.left > _rect.left) {
_offsetX = rc.left - _rect.left;
}
if (rc.top > _rect.top) {
_offsetY = rc.top - _rect.top;
}
BasePlatform::intersectRect(&_rect, &_rect, &rc);
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,67 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_BASE_ACTIVE_RECT_H
#define WINTERMUTE_BASE_ACTIVE_RECT_H
#include "common/rect.h"
#include "engines/wintermute/base/base.h"
namespace Wintermute {
class BaseRegion;
class BaseSubFrame;
class BaseObject;
#ifdef ENABLE_WME3D
class XModel;
#endif
class BaseActiveRect : BaseClass {
public:
void clipRect();
bool _precise{};
float _zoomX;
float _zoomY;
BaseSubFrame *_frame;
#ifdef ENABLE_WME3D
XModel *_xmodel;
#endif
BaseObject *_owner;
BaseRegion *_region;
int32 _offsetX;
int32 _offsetY;
Common::Rect32 _rect;
BaseActiveRect(BaseGame *inGameOwner = nullptr);
BaseActiveRect(BaseGame *inGameOwner, BaseObject *owner, BaseSubFrame *frame, int x, int y, int width, int height, float zoomX = 100, float zoomY = 100, bool precise = true);
BaseActiveRect(BaseGame *inGame, BaseObject *owner, BaseRegion *region, int offsetX, int offsetY);
#ifdef ENABLE_WME3D
BaseActiveRect(BaseGame *inGame, BaseObject *owner, XModel *model, int x, int y, int width, int height, bool precise = true);
#endif
~BaseActiveRect() override;
};
} // End of namespace Wintermute
#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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#include "engines/wintermute/base/base_animation_transition_time.h"
#include "engines/wintermute/persistent.h"
#include "engines/wintermute/utils/utils.h"
#include "engines/wintermute/dcgf.h"
namespace Wintermute {
//////////////////////////////////////////////////////////////////////////
BaseAnimationTransitionTime::BaseAnimationTransitionTime(const char *from, const char *to, uint32 time) {
_animFrom = nullptr;
_animTo = nullptr;
BaseUtils::setString(&_animFrom, from);
BaseUtils::setString(&_animTo, to);
_time = time;
}
//////////////////////////////////////////////////////////////////////////
BaseAnimationTransitionTime::BaseAnimationTransitionTime() {
_animFrom = nullptr;
_animTo = nullptr;
_time = 0;
}
//////////////////////////////////////////////////////////////////////////
BaseAnimationTransitionTime::~BaseAnimationTransitionTime() {
SAFE_DELETE_ARRAY(_animFrom);
SAFE_DELETE_ARRAY(_animTo);
}
//////////////////////////////////////////////////////////////////////////
bool BaseAnimationTransitionTime::persist(BasePersistenceManager *persistMgr) {
persistMgr->transferCharPtr(TMEMBER(_animFrom));
persistMgr->transferCharPtr(TMEMBER(_animTo));
persistMgr->transferUint32(TMEMBER(_time));
return true;
}
}

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/>.
*
*/
/*
* This file is based on WME.
* http://dead-code.org/redir.php?target=wme
* Copyright (c) 2003-2013 Jan Nedoma and contributors
*/
#ifndef WINTERMUTE_BASE_ANIMATION_TRANSITION_TIME_H
#define WINTERMUTE_BASE_ANIMATION_TRANSITION_TIME_H
#include "engines/wintermute/base/base_persistence_manager.h"
namespace Wintermute {
class BaseAnimationTransitionTime {
public:
BaseAnimationTransitionTime(const char *from, const char *to, uint32 Time);
BaseAnimationTransitionTime();
virtual ~BaseAnimationTransitionTime();
bool persist(BasePersistenceManager *persistMgr);
char *_animFrom;
char *_animTo;
uint32 _time;
};
}
#endif

View File

@@ -0,0 +1,204 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/base/base_engine.h"
#include "engines/wintermute/base/base_dynamic_buffer.h"
#include "engines/wintermute/base/base_game.h"
namespace Wintermute {
//////////////////////////////////////////////////////////////////////////
BaseDynamicBuffer::BaseDynamicBuffer(BaseGame *inGame, uint32 initSize, uint32 growBy) : BaseClass(inGame) {
_buffer = nullptr;
_size = 0;
_realSize = 0;
_offset = 0;
_initSize = initSize;
_growBy = growBy;
_initialized = false;
}
//////////////////////////////////////////////////////////////////////////
BaseDynamicBuffer::~BaseDynamicBuffer() {
cleanup();
}
//////////////////////////////////////////////////////////////////////////
void BaseDynamicBuffer::cleanup() {
if (_buffer) {
free(_buffer);
}
_buffer = nullptr;
_size = 0;
_realSize = 0;
_offset = 0;
_initialized = false;
}
//////////////////////////////////////////////////////////////////////////
uint32 BaseDynamicBuffer::getSize() {
return _size;
}
//////////////////////////////////////////////////////////////////////////
bool BaseDynamicBuffer::init(uint32 initSize) {
cleanup();
if (initSize == 0) {
initSize = _initSize;
}
_buffer = (byte *)malloc(initSize);
if (!_buffer) {
_game->LOG(0, "BaseDynamicBuffer::init - Error allocating %d bytes", initSize);
return STATUS_FAILED;
}
_realSize = initSize;
_initialized = true;
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool BaseDynamicBuffer::putBytes(const byte *buffer, uint32 size) {
if (!_initialized) {
init();
}
while (_offset + size > _realSize) {
_realSize += _growBy;
_buffer = (byte *)realloc(_buffer, _realSize);
if (!_buffer) {
_game->LOG(0, "BaseDynamicBuffer::putBytes - Error reallocating buffer to %d bytes", _realSize);
return STATUS_FAILED;
}
}
memcpy(_buffer + _offset, buffer, size);
_offset += size;
_size += size;
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool BaseDynamicBuffer::getBytes(byte *buffer, uint32 size) {
if (!_initialized) {
init();
}
if (_offset + size > _size) {
_game->LOG(0, "BaseDynamicBuffer::getBytes - Buffer underflow");
return STATUS_FAILED;
}
memcpy(buffer, _buffer + _offset, size);
_offset += size;
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
void BaseDynamicBuffer::putDWORD(uint32 val) {
putBytes((byte *)&val, sizeof(uint32));
}
//////////////////////////////////////////////////////////////////////////
uint32 BaseDynamicBuffer::getDWORD() {
uint32 ret = 0;
getBytes((byte *)&ret, sizeof(uint32));
return ret;
}
//////////////////////////////////////////////////////////////////////////
void BaseDynamicBuffer::putString(const char *val) {
if (!val) {
putString("(null)");
} else {
putDWORD(strlen(val) + 1);
putBytes((const byte *)val, strlen(val) + 1);
}
}
//////////////////////////////////////////////////////////////////////////
char *BaseDynamicBuffer::getString() {
uint32 len = getDWORD();
char *ret = (char *)(_buffer + _offset);
_offset += len;
if (!strcmp(ret, "(null)")) {
return nullptr;
} else {
return ret;
}
}
//////////////////////////////////////////////////////////////////////////
void BaseDynamicBuffer::putText(const char *fmt, ...) {
va_list va;
va_start(va, fmt);
putTextForm(fmt, va);
va_end(va);
}
//////////////////////////////////////////////////////////////////////////
void BaseDynamicBuffer::putTextIndent(int indent, const char *fmt, ...) {
va_list va;
putText("%*s", indent, "");
va_start(va, fmt);
putTextForm(fmt, va);
va_end(va);
}
//////////////////////////////////////////////////////////////////////////
void BaseDynamicBuffer::putTextForm(const char *format, va_list argptr) {
char buff[32768];
Common::vsprintf_s(buff, format, argptr);
putBytes((byte *)buff, strlen(buff));
}
} // End of namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_BASE_DYNAMIC_BUFFER_H
#define WINTERMUTE_BASE_DYNAMIC_BUFFER_H
#include "engines/wintermute/base/base.h"
namespace Wintermute {
class BaseDynamicBuffer : public BaseClass {
public:
bool _initialized;
void putText(const char *fmt, ...);
void putTextIndent(int indent, const char *fmt, ...);
uint32 getDWORD();
void putDWORD(uint32 val);
char *getString();
void putString(const char *val);
bool getBytes(byte *buffer, uint32 size);
bool putBytes(const byte *buffer, uint32 size);
uint32 getSize();
bool init(uint32 initSize = 0);
void cleanup();
uint32 _size;
byte *_buffer;
BaseDynamicBuffer(BaseGame *inGame, uint32 initSize = 1000, uint32 growBy = 1000);
virtual ~BaseDynamicBuffer();
private:
uint32 _realSize;
uint32 _growBy;
uint32 _initSize;
uint32 _offset;
void putTextForm(const char *format, va_list argptr);
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,118 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_engine.h"
#include "engines/wintermute/wintermute.h"
#include "engines/wintermute/system/sys_class_registry.h"
#include "engines/wintermute/platform_osystem.h"
#include "common/system.h"
namespace Common {
DECLARE_SINGLETON(Wintermute::BaseEngine);
}
namespace Wintermute {
BaseEngine::BaseEngine() {
_fileManager = nullptr;
_gameRef = nullptr;
_classReg = nullptr;
_rnd = nullptr;
_gameId = "";
_language = Common::UNK_LANG;
_targetExecutable = LATEST_VERSION;
_flags = 0;
}
void BaseEngine::init() {
_fileManager = new BaseFileManager(_language);
// Don't forget to register your random source
_rnd = new Common::RandomSource("Wintermute");
_classReg = new SystemClassRegistry();
_classReg->registerClasses();
}
BaseEngine::~BaseEngine() {
delete _fileManager;
delete _rnd;
delete _classReg;
}
void BaseEngine::createInstance(const Common::String &targetName, const Common::String &gameId, Common::Language lang, WMETargetExecutable targetExecutable, uint32 flags) {
instance()._targetName = targetName;
instance()._gameId = gameId;
instance()._language = lang;
instance()._targetExecutable = targetExecutable;
instance()._flags = flags;
instance().init();
}
void BaseEngine::LOG(bool res, const char *fmt, ...) {
uint32 secs = BasePlatform::getTime() / 1000;
uint32 hours = secs / 3600;
secs = secs % 3600;
uint32 mins = secs / 60;
secs = secs % 60;
char buff[512];
va_list va;
va_start(va, fmt);
Common::vsprintf_s(buff, fmt, va);
va_end(va);
if (instance()._gameRef) {
instance()._gameRef->LOG(res, "%s", buff);
} else {
debugCN(kWintermuteDebugLog, "%02d:%02d:%02d: %s\n", hours, mins, secs, buff);
}
}
uint32 BaseEngine::randInt(int from, int to) {
return _rnd->getRandomNumberRng(from, to);
}
BaseSoundMgr *BaseEngine::getSoundMgr() {
if (instance()._gameRef) {
return _gameRef->_soundMgr;
} else {
return nullptr;
}
}
BaseRenderer *BaseEngine::getRenderer() {
if (instance()._gameRef) {
return instance()._gameRef->_renderer;
} else {
return nullptr;
}
}
} // End of namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_BASE_ENGINE_H
#define WINTERMUTE_BASE_ENGINE_H
#include "common/str.h"
#include "common/singleton.h"
#include "common/random.h"
#include "common/language.h"
#include "engines/wintermute/detection.h"
namespace Wintermute {
class BaseFileManager;
class BaseRegistry;
class BaseGame;
class BaseSoundMgr;
class BaseRenderer;
class SystemClassRegistry;
class Timer;
class BaseEngine : public Common::Singleton<Wintermute::BaseEngine> {
void init();
BaseFileManager *_fileManager;
Common::String _gameId;
Common::String _targetName;
BaseGame *_gameRef;
// We need random numbers
Common::RandomSource *_rnd;
SystemClassRegistry *_classReg;
Common::Language _language;
WMETargetExecutable _targetExecutable;
uint32 _flags;
public:
BaseEngine();
~BaseEngine() override;
static void createInstance(const Common::String &targetName, const Common::String &gameId, Common::Language lang, WMETargetExecutable targetExecutable, uint32 flags);
void setGameRef(BaseGame *game) { _gameRef = game; }
Common::RandomSource *getRandomSource() { return _rnd; }
uint32 randInt(int from, int to);
SystemClassRegistry *getClassRegistry() { return _classReg; }
BaseGame *getGameRef() { return _gameRef; }
BaseFileManager *getFileManager() { return _fileManager; }
BaseSoundMgr *getSoundMgr();
static BaseRenderer *getRenderer();
static const Timer *getTimer();
static const Timer *getLiveTimer();
static void LOG(bool res, const char *fmt, ...);
Common::String getGameTargetName() const { return _targetName; }
Common::String getGameId() const { return _gameId; }
Common::Language getLanguage() const { return _language; }
uint32 getFlags() const { return _flags; }
WMETargetExecutable getTargetExecutable() const {
return _targetExecutable;
}
static bool isFoxTailCheck(WMETargetExecutable t, WMETargetExecutable v1=FOXTAIL_OLDEST_VERSION, WMETargetExecutable v2=FOXTAIL_LATEST_VERSION) {
return t >= v1 && t <= v2;
}
bool isFoxTail(WMETargetExecutable v1=FOXTAIL_OLDEST_VERSION, WMETargetExecutable v2=FOXTAIL_LATEST_VERSION) const {
return isFoxTailCheck(_targetExecutable, v1, v2);
}
void addFlags(uint32 flags) { _flags |= flags; }
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,196 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/base/base_fader.h"
#include "engines/wintermute/base/base_engine.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/gfx/base_renderer.h"
#include "engines/wintermute/platform_osystem.h"
#include "common/util.h"
namespace Wintermute {
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
IMPLEMENT_PERSISTENT(BaseFader, false)
//////////////////////////////////////////////////////////////////////////
BaseFader::BaseFader(BaseGame *inGame) : BaseObject(inGame) {
_active = false;
_red = _green = _blue = 0;
_currentAlpha = 0x00;
_sourceAlpha = 0;
_targetAlpha = 0;
_duration = 1000;
_startTime = 0;
_system = false;
}
//////////////////////////////////////////////////////////////////////////
BaseFader::~BaseFader() {
}
//////////////////////////////////////////////////////////////////////////
bool BaseFader::update() {
if (!_active) {
return STATUS_OK;
}
int alphaDelta = _targetAlpha - _sourceAlpha;
uint32 time;
if (_system) {
time = BasePlatform::getTime() - _startTime;
} else {
time = _game->_timer - _startTime;
}
if (time >= _duration) {
_currentAlpha = _targetAlpha;
} else {
_currentAlpha = (byte)(_sourceAlpha + (float)time / (float)_duration * alphaDelta);
}
_currentAlpha = MIN((byte)255, MAX(_currentAlpha, (byte)0));
_ready = time >= _duration;
if (_ready && _currentAlpha == 0x00) {
_active = false;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool BaseFader::display() {
if (!_active) {
return STATUS_OK;
}
if (_currentAlpha > 0x00) {
return _game->_renderer->fadeToColor(_red, _green, _blue, _currentAlpha);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool BaseFader::deactivate() {
_active = false;
_ready = true;
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool BaseFader::fadeIn(uint32 sourceColor, uint32 duration, bool system) {
_ready = false;
_active = true;
_red = RGBCOLGetR(sourceColor);
_green = RGBCOLGetG(sourceColor);
_blue = RGBCOLGetB(sourceColor);
_sourceAlpha = RGBCOLGetA(sourceColor);
_targetAlpha = 0;
_duration = duration;
_system = system;
if (_system) {
_startTime = BasePlatform::getTime();
} else {
_startTime = _game->_timer;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool BaseFader::fadeOut(uint32 targetColor, uint32 duration, bool system) {
_ready = false;
_active = true;
_red = RGBCOLGetR(targetColor);
_green = RGBCOLGetG(targetColor);
_blue = RGBCOLGetB(targetColor);
//_sourceAlpha = 0;
_sourceAlpha = _currentAlpha;
_targetAlpha = RGBCOLGetA(targetColor);
_duration = duration;
_system = system;
if (_system) {
_startTime = BasePlatform::getTime();
} else {
_startTime = _game->_timer;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
uint32 BaseFader::getCurrentColor() {
return BYTETORGBA(_red, _green, _blue, _currentAlpha);
}
//////////////////////////////////////////////////////////////////////////
bool BaseFader::persist(BasePersistenceManager *persistMgr) {
BaseObject::persist(persistMgr);
persistMgr->transferBool(TMEMBER(_active));
persistMgr->transferByte(TMEMBER(_blue));
persistMgr->transferByte(TMEMBER(_currentAlpha));
persistMgr->transferUint32(TMEMBER(_duration));
persistMgr->transferByte(TMEMBER(_green));
persistMgr->transferByte(TMEMBER(_red));
persistMgr->transferByte(TMEMBER(_sourceAlpha));
persistMgr->transferUint32(TMEMBER(_startTime));
persistMgr->transferByte(TMEMBER(_targetAlpha));
persistMgr->transferBool(TMEMBER(_system));
if (_system && !persistMgr->getIsSaving()) {
_startTime = 0;
}
return STATUS_OK;
}
} // End of namespace Wintermute

View File

@@ -0,0 +1,61 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_BASE_FADER_H
#define WINTERMUTE_BASE_FADER_H
#include "engines/wintermute/base/base_object.h"
namespace Wintermute {
class BaseFader : public BaseObject {
public:
bool _system;
uint32 getCurrentColor();
bool fadeOut(uint32 targetColor, uint32 duration, bool system = false);
bool fadeIn(uint32 sourceColor, uint32 duration, bool system = false);
bool deactivate();
bool display() override;
bool update() override;
DECLARE_PERSISTENT(BaseFader, BaseObject)
BaseFader(BaseGame *inGame);
~BaseFader() override;
bool _active;
byte _red;
byte _green;
byte _blue;
byte _currentAlpha;
byte _targetAlpha;
byte _sourceAlpha;
uint32 _duration;
uint32 _startTime;
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,584 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/base/base_file_manager.h"
#include "engines/wintermute/base/base_persistence_manager.h"
#include "engines/wintermute/base/file/base_disk_file.h"
#include "engines/wintermute/base/file/base_savefile_manager_file.h"
#include "engines/wintermute/base/file/base_save_thumb_file.h"
#include "engines/wintermute/base/file/base_package.h"
#include "engines/wintermute/base/base.h"
#include "engines/wintermute/base/base_engine.h"
#include "engines/wintermute/wintermute.h"
#include "engines/wintermute/dcgf.h"
#include "common/algorithm.h"
#include "common/array.h"
#include "common/debug.h"
#include "common/str.h"
#include "common/tokenizer.h"
#include "common/textconsole.h"
#include "common/util.h"
#include "common/config-manager.h"
#include "common/system.h"
#include "common/fs.h"
#include "common/file.h"
#include "common/savefile.h"
#include "common/fs.h"
#include "common/compression/unzip.h"
namespace Wintermute {
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
BaseFileManager::BaseFileManager(Common::Language lang, bool detectionMode) {
_detectionMode = detectionMode;
_language = lang;
_resources = nullptr;
initResources();
initPaths();
registerPackages();
}
//////////////////////////////////////////////////////////////////////
BaseFileManager::~BaseFileManager() {
cleanup();
}
//////////////////////////////////////////////////////////////////////////
bool BaseFileManager::cleanup() {
// delete registered paths
_packagePaths.clear();
// close open files
for (uint32 i = 0; i < _openFiles.size(); i++) {
delete _openFiles[i];
}
_openFiles.clear();
// delete packages
_packages.clear();
// get rid of the resources:
SAFE_DELETE(_resources);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////
byte *BaseFileManager::readWholeFile(const Common::String &filename, uint32 *size, bool mustExist) {
byte *buffer = nullptr;
Common::SeekableReadStream *file = openFile(filename);
if (!file) {
if (mustExist) {
debugC(kWintermuteDebugFileAccess, "Error opening file '%s'", filename.c_str());
}
return nullptr;
}
buffer = new byte[file->size() + 1];
if (buffer == nullptr) {
debugC(kWintermuteDebugFileAccess, "Error allocating buffer for file '%s' (%d bytes)", filename.c_str(), (int)file->size() + 1);
closeFile(file);
return nullptr;
}
if (file->read(buffer, (uint32)file->size()) != (uint32)file->size()) {
debugC(kWintermuteDebugFileAccess, "Error reading file '%s'", filename.c_str());
closeFile(file);
delete[] buffer;
return nullptr;
};
buffer[file->size()] = '\0';
if (size != nullptr) {
*size = file->size();
}
closeFile(file);
return buffer;
}
//////////////////////////////////////////////////////////////////////////
bool BaseFileManager::addPath(TPathType type, const Common::FSNode &path) {
if (!path.exists()) {
return STATUS_FAILED;
}
switch (type) {
case PATH_SINGLE:
default:
// _singlePaths.push_back(path);
error("TODO: Allow adding single-paths");
break;
case PATH_PACKAGE:
_packagePaths.push_back(path);
break;
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool BaseFileManager::reloadPaths() {
// delete registered paths
//_singlePaths.clear();
_packagePaths.clear();
return initPaths();
}
//////////////////////////////////////////////////////////////////////////
bool BaseFileManager::initPaths() {
// Removed: Config-based file-path choice.
// package files paths
const Common::FSNode gameData(ConfMan.getPath("path"));
addPath(PATH_PACKAGE, gameData);
Common::FSNode dataSubFolder = gameData.getChild("data");
if (dataSubFolder.exists()) {
addPath(PATH_PACKAGE, dataSubFolder);
}
Common::FSNode languageSubFolder = gameData.getChild("language");
if (languageSubFolder.exists()) {
addPath(PATH_PACKAGE, languageSubFolder);
}
// Also add languages/ for Reversion1.
languageSubFolder = gameData.getChild("languages");
if (languageSubFolder.exists()) {
addPath(PATH_PACKAGE, languageSubFolder);
}
// Special paths init for the SD/HD combo multi-language versions of sotv:
// such versions include a launcher which allows selecting the SD/HD
// version and mixing any combination of available voices and subtitles
bool use_sd_assets = ConfMan.getBool("use_sd_assets"); // if false: hd
bool use_it_voices = ConfMan.getBool("use_it_voices"); // if false: en
Common::Language lang = Common::parseLanguage(ConfMan.get("language"));
switch (lang) {
case Common::DE_DEU:
case Common::EN_ANY:
case Common::ES_ESP:
case Common::FR_FRA:
case Common::IT_ITA:
case Common::PL_POL:
case Common::RU_RUS:
// supported (in terms of subtitles) language selected, all good
break;
default:
// unsupported language selected, fallback to English subtitles
lang = Common::EN_ANY;
break;
}// switch(lang)
// Now that we have values for the three options needed (SD/HD, voices
// language and subtitles language), we can emulate the SotV launcher logic,
// which, according to the options selected via its UI, writes to the
// Windows registry a suitable "PackagePaths" entry. Such entry is then used
// by WME on startup to load only the subset of the available packages which
// is relevant to the selected options, avoiding incorrect overrides.
const char *gameVersion = use_sd_assets ? "sd" : "hd";
const char *voicesLang = use_it_voices ? "it" : "en";
const char *subtitleLang = Common::getLanguageCode(lang);
Common::Array<Common::String> sotvSubfolders;
sotvSubfolders.push_back("common");
sotvSubfolders.push_back(Common::String::format("common_%s", gameVersion));
sotvSubfolders.push_back(Common::String::format("i18n_audio_%s", voicesLang));
sotvSubfolders.push_back(Common::String::format("i18n_audio_%s_%s", voicesLang, gameVersion));
sotvSubfolders.push_back(Common::String::format("i18n_%s", subtitleLang));
sotvSubfolders.push_back(Common::String::format("i18n_%s_%s", subtitleLang, gameVersion));
for (const auto &sotvSubfolder : sotvSubfolders) {
Common::FSNode subFolder = gameData.getChild(sotvSubfolder);
if (subFolder.exists()) {
addPath(PATH_PACKAGE, subFolder);
}
}
// end of special sotv1/sotv2 paths init
return STATUS_OK;
}
bool BaseFileManager::registerPackages(const Common::FSList &fslist) {
for (Common::FSList::const_iterator it = fslist.begin(); it != fslist.end(); ++it) {
debugC(kWintermuteDebugFileAccess, "Adding %s", it->getName().c_str());
if (it->getName().contains(".dcp")) {
if (registerPackage(*it, it->getName())) {
addPath(PATH_PACKAGE, *it);
}
}
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool BaseFileManager::registerPackages() {
debugC(kWintermuteDebugFileAccess, "Scanning packages");
// We need game flags to perform some game-specific hacks.
uint32 flags = BaseEngine::instance().getFlags();
// Register without using SearchMan, as otherwise the FSNode-based lookup in openPackage will fail
// and that has to be like that to support the detection-scheme.
Common::FSList files;
for (Common::FSList::const_iterator it = _packagePaths.begin(); it != _packagePaths.end(); ++it) {
debugC(kWintermuteDebugFileAccess, "Should register folder: %s %s", it->getPath().toString(Common::Path::kNativeSeparator).c_str(), it->getName().c_str());
if (!it->getChildren(files, Common::FSNode::kListFilesOnly)) {
warning("getChildren() failed for path: %s", it->getName().c_str());
}
for (Common::FSList::const_iterator fileIt = files.begin(); fileIt != files.end(); ++fileIt) {
if (!fileIt)
continue;
// To prevent any case sensitivity issues we make the filename
// all lowercase here. This makes the code slightly prettier
// than the equivalent of using equalsIgnoreCase.
Common::String fileName = fileIt->getName();
fileName.toLowercase();
bool searchSignature = false;
if (!fileName.hasSuffix(".dcp") && !fileName.hasSuffix(".exe")) {
continue;
}
if (fileName.hasSuffix(".exe")) {
searchSignature = true;
}
// Again, make the parent's name all lowercase to avoid any case
// issues.
Common::String parentName = it->getName();
parentName.toLowercase();
// Avoid registering all the resolutions for SD/HD games
if (flags & GF_IGNORE_HD_FILES && fileName.hasSuffix("_hd.dcp")) {
continue;
} else if (flags & GF_IGNORE_SD_FILES && fileName.hasSuffix("_sd.dcp")) {
continue;
}
// Avoid registering all the language files
// TODO: Select based on the gameDesc.
if (_language != Common::UNK_LANG) {
// English
if (fileName == "english.dcp" || fileName == "xlanguage_en.dcp" || fileName == "english_language_pack.dcp") {
if (_language != Common::EN_ANY) {
continue;
}
// Chinese
} else if (fileName == "chinese.dcp" || fileName == "xlanguage_nz.dcp" || fileName == "chinese_language_pack.dcp") {
if (_language != Common::ZH_ANY) {
continue;
}
// Simplified Chinese
} else if (fileName == "xlanguage_zh_s.dcp") {
if (_language != Common::ZH_CHN) {
continue;
}
// Traditional Chinese
} else if (fileName == "xlanguage_zh_t.dcp") {
if (_language != Common::ZH_TWN) {
continue;
}
// Czech
} else if (fileName == "czech.dcp" || fileName == "xlanguage_cz.dcp" || fileName == "czech_language_pack.dcp") {
if (_language != Common::CS_CZE) {
continue;
}
// French
} else if (fileName == "french.dcp" || fileName == "xlanguage_fr.dcp" || fileName == "french_language_pack.dcp") {
if (_language != Common::FR_FRA) {
continue;
}
// German
} else if (fileName == "german.dcp" || fileName == "xlanguage_de.dcp" || fileName == "german_language_pack.dcp") {
if (_language != Common::DE_DEU) {
continue;
}
// Italian
} else if (fileName == "italian.dcp" || fileName == "xlanguage_it.dcp" || fileName == "italian_language_pack.dcp") {
if (_language != Common::IT_ITA) {
continue;
}
// Latvian
} else if (fileName == "latvian.dcp" || fileName == "xlanguage_lv.dcp" || fileName == "latvian_language_pack.dcp") {
if (_language != Common::LV_LVA) {
continue;
}
// Persian
} else if (fileName == "persian.dcp" || fileName == "xlanguage_fa.dcp" || fileName == "persian_language_pack.dcp") {
if (_language != Common::FA_IRN) {
continue;
}
// Polish
} else if (fileName == "polish.dcp" || fileName == "xlanguage_pl.dcp" || fileName == "polish_language_pack.dcp") {
if (_language != Common::PL_POL) {
continue;
}
// Portuguese
} else if (fileName == "portuguese.dcp" || fileName == "xlanguage_pt.dcp" || fileName == "portuguese_language_pack.dcp") {
if (_language != Common::PT_BRA) {
continue;
}
// Russian
} else if (fileName == "russian.dcp" || fileName == "xlanguage_ru.dcp" || fileName == "russian_language_pack.dcp") {
if (_language != Common::RU_RUS) {
continue;
}
// Serbian
} else if (fileName == "serbian.dcp" || fileName == "xlanguage_sr.dcp" || fileName == "serbian_language_pack.dcp") {
if (_language != Common::SR_SRB) {
continue;
}
// Spanish
} else if (fileName == "spanish.dcp" || fileName == "xlanguage_es.dcp" || fileName == "spanish_language_pack.dcp") {
if (_language != Common::ES_ESP) {
continue;
}
// generic
} else if (fileName.hasPrefix("xlanguage_")) {
warning("Unknown language package: %s", fileName.c_str());
continue;
}
}
debugC(kWintermuteDebugFileAccess, "Registering %s %s", fileIt->getPath().toString(Common::Path::kNativeSeparator).c_str(), fileIt->getName().c_str());
registerPackage((*fileIt), fileName, searchSignature);
}
}
// debugC(kWintermuteDebugFileAccess, " Registered %d files in %d package(s)", _files.size(), _packages.size());
return STATUS_OK;
}
bool BaseFileManager::registerPackage(Common::FSNode file, const Common::String &filename, bool searchSignature) {
if (_packages.hasArchive(filename.c_str())) {
debugC(kWintermuteDebugFileAccess, "BaseFileManager::registerPackage - file %s already added to archive", filename.c_str());
return STATUS_FAILED;
}
PackageSet *pack = new PackageSet(file, filename, searchSignature);
_packages.add(filename, pack, pack->getPriority() , true);
_versions[filename] = pack->getVersion();
return STATUS_OK;
}
void BaseFileManager::initResources() {
_resources = Common::makeZipArchive("wintermute.zip");
if (!_resources && !_detectionMode) { // Wintermute.zip is unavailable during detection
error("Couldn't load wintermute.zip");
}
if (_resources) {
assert(_resources->hasFile("syste_font.bmp"));
assert(_resources->hasFile("invalid.bmp"));
assert(_resources->hasFile("invalid_debug.bmp"));
}
}
//////////////////////////////////////////////////////////////////////////
Common::SeekableReadStream *BaseFileManager::openPkgFile(const Common::String &filename) {
Common::String upcName = filename;
upcName.toUppercase();
Common::SeekableReadStream *file = nullptr;
// correct slashes
for (uint32 i = 0; i < upcName.size(); i++) {
if (upcName[(int32)i] == '/') {
upcName.setChar('\\', (uint32)i);
}
}
Common::ArchiveMemberPtr entry = _packages.getMember(Common::Path(upcName, '\\'));
if (!entry) {
return nullptr;
}
file = entry->createReadStream();
return file;
}
//////////////////////////////////////////////////////////////////////////
uint32 BaseFileManager::getPackageVersion(const Common::String &filename) {
Common::HashMap<Common::String, uint32>::iterator it = _versions.find(filename);
if (it != _versions.end()) {
return it->_value;
}
return 0;
}
//////////////////////////////////////////////////////////////////////////
bool BaseFileManager::hasFile(const Common::String &filename) {
Common::String backslashPath(filename);
for (uint32 i = 0; i < backslashPath.size(); i++) {
if (backslashPath[(int32)i] == '/') {
backslashPath.setChar('\\', (uint32)i);
}
}
Common::Path path(backslashPath, '\\');
if (scumm_strnicmp(filename.c_str(), "savegame:", 9) == 0) {
BasePersistenceManager pm(BaseEngine::instance().getGameTargetName());
if (filename.size() <= 9) {
return false;
}
int slot = atoi(filename.c_str() + 9);
return pm.getSaveExists(slot);
}
if (sfmFileExists(filename)) {
return true;
}
if (diskFileExists(filename)) {
return true;
}
if (_packages.hasFile(path)) {
return true; // We don't bother checking if the file can actually be opened, something bigger is wrong if that is the case.
}
if (!_detectionMode && _resources->hasFile(path)) {
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////////
int BaseFileManager::listMatchingPackageMembers(Common::ArchiveMemberList &list, const Common::String &pattern) {
return _packages.listMatchingMembers(list, Common::Path(pattern));
}
//////////////////////////////////////////////////////////////////////////
int BaseFileManager::listMatchingFiles(Common::StringArray &list, const Common::String &pattern) {
list = sfmFileList(pattern);
Common::ArchiveMemberList files;
listMatchingDiskFileMembers(files, pattern);
for (Common::ArchiveMemberList::const_iterator it = files.begin(); it != files.end(); ++it) {
list.push_back((*it)->getName());
}
return list.size();
}
//////////////////////////////////////////////////////////////////////////
Common::SeekableReadStream *BaseFileManager::openFile(const Common::String &filename, bool absPathWarning, bool keepTrackOf) {
if (filename.empty()) {
return nullptr;
}
debugC(kWintermuteDebugFileAccess, "Open file %s", filename.c_str());
Common::SeekableReadStream *file = openFileRaw(filename);
if (file && keepTrackOf) {
_openFiles.push_back(file);
}
return file;
}
//////////////////////////////////////////////////////////////////////////
Common::WriteStream *BaseFileManager::openFileForWrite(const Common::String &filename) {
if (filename.empty()) {
return nullptr;
}
debugC(kWintermuteDebugFileAccess, "Open file %s for write", filename.c_str());
return openFileForWriteRaw(filename);
}
//////////////////////////////////////////////////////////////////////////
bool BaseFileManager::closeFile(Common::SeekableReadStream *File) {
for (uint32 i = 0; i < _openFiles.size(); i++) {
if (_openFiles[i] == File) {
delete _openFiles[i];
_openFiles.remove_at(i);
return STATUS_OK;
}
}
return STATUS_FAILED;
}
//////////////////////////////////////////////////////////////////////////
Common::SeekableReadStream *BaseFileManager::openFileRaw(const Common::String &filename) {
Common::SeekableReadStream *ret = nullptr;
if (scumm_strnicmp(filename.c_str(), "savegame:", 9) == 0) {
if (!BaseEngine::instance().getGameRef()) {
error("Attempt to load filename: %s without BaseEngine-object, this is unsupported", filename.c_str());
}
return openThumbFile(filename);
}
ret = openSfmFile(filename);
if (ret) {
return ret;
}
ret = openDiskFile(filename);
if (ret) {
return ret;
}
ret = openPkgFile(filename);
if (ret) {
return ret;
}
if (!_detectionMode) {
ret = _resources->createReadStreamForMember(Common::Path(filename));
}
if (ret) {
return ret;
}
debugC(kWintermuteDebugFileAccess ,"BFileManager::OpenFileRaw - Failed to open %s", filename.c_str());
return nullptr;
}
//////////////////////////////////////////////////////////////////////////
Common::WriteStream *BaseFileManager::openFileForWriteRaw(const Common::String &filename) {
Common::WriteStream *ret = nullptr;
ret = openSfmFileForWrite(filename);
if (ret) {
return ret;
}
debugC(kWintermuteDebugFileAccess ,"BFileManager::OpenFileRaw - Failed to open %s", filename.c_str());
return nullptr;
}
BaseFileManager *BaseFileManager::getEngineInstance() {
if (BaseEngine::instance().getFileManager()) {
return BaseEngine::instance().getFileManager();
}
return nullptr;
}
} // End of namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_BASE_FILE_MANAGER_H
#define WINTERMUTE_BASE_FILE_MANAGER_H
#include "common/archive.h"
#include "common/str.h"
#include "common/str-array.h"
#include "common/fs.h"
#include "common/file.h"
#include "common/language.h"
namespace Wintermute {
class BaseFileManager {
public:
bool cleanup();
bool closeFile(Common::SeekableReadStream *File);
bool hasFile(const Common::String &filename);
int listMatchingPackageMembers(Common::ArchiveMemberList &list, const Common::String &pattern);
int listMatchingFiles(Common::StringArray &list, const Common::String &pattern);
Common::SeekableReadStream *openFile(const Common::String &filename, bool absPathWarning = true, bool keepTrackOf = true);
Common::WriteStream *openFileForWrite(const Common::String &filename);
byte *readWholeFile(const Common::String &filename, uint32 *size = nullptr, bool mustExist = true);
uint32 getPackageVersion(const Common::String &filename);
BaseFileManager(Common::Language lang, bool detectionMode = false);
virtual ~BaseFileManager();
// Used only for detection
bool registerPackages(const Common::FSList &fslist);
static BaseFileManager *getEngineInstance();
private:
typedef enum {
PATH_PACKAGE,
PATH_SINGLE
} TPathType;
bool reloadPaths();
bool initPaths();
bool addPath(TPathType type, const Common::FSNode &path);
bool registerPackages();
void initResources();
Common::SeekableReadStream *openFileRaw(const Common::String &filename);
Common::WriteStream *openFileForWriteRaw(const Common::String &filename);
Common::SeekableReadStream *openPkgFile(const Common::String &filename);
Common::FSList _packagePaths;
bool registerPackage(Common::FSNode package, const Common::String &filename = "", bool searchSignature = false);
bool _detectionMode;
Common::SearchSet _packages;
Common::Array<Common::SeekableReadStream *> _openFiles;
Common::Language _language;
Common::Archive *_resources;
Common::HashMap<Common::String, uint32> _versions;
// This class is intentionally not a subclass of Base, as it needs to be used by
// the detector too, without launching the entire engine:
};
} // End of namespace Wintermute
#endif

View File

@@ -0,0 +1,772 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#include "engines/wintermute/base/base_parser.h"
#include "engines/wintermute/base/base_engine.h"
#include "engines/wintermute/base/base_frame.h"
#include "engines/wintermute/base/base_game.h"
#include "engines/wintermute/base/base_object.h"
#include "engines/wintermute/base/base_dynamic_buffer.h"
#include "engines/wintermute/base/sound/base_sound_manager.h"
#include "engines/wintermute/base/sound/base_sound.h"
#include "engines/wintermute/base/base_sub_frame.h"
#include "engines/wintermute/platform_osystem.h"
#include "engines/wintermute/base/scriptables/script_value.h"
#include "engines/wintermute/base/scriptables/script.h"
#include "engines/wintermute/base/scriptables/script_stack.h"
#include "engines/wintermute/dcgf.h"
#include "common/str.h"
namespace Wintermute {
IMPLEMENT_PERSISTENT(BaseFrame, false)
//////////////////////////////////////////////////////////////////////
BaseFrame::BaseFrame(BaseGame *inGame) : BaseScriptable(inGame, true) {
_delay = 0;
_moveX = _moveY = 0;
_sound = nullptr;
_killSound = false;
_editorExpanded = false;
_keyframe = false;
}
//////////////////////////////////////////////////////////////////////
BaseFrame::~BaseFrame() {
SAFE_DELETE(_sound);
for (int32 i = 0; i < _subframes.getSize(); i++) {
delete _subframes[i];
}
_subframes.removeAll();
for (int32 i = 0; i < _applyEvent.getSize(); i++) {
SAFE_DELETE_ARRAY(_applyEvent[i]);
}
_applyEvent.removeAll();
}
//////////////////////////////////////////////////////////////////////
bool BaseFrame::draw(int x, int y, BaseObject *registerOwner, float zoomX, float zoomY, bool precise, uint32 alpha, bool allFrames, float rotate, Graphics::TSpriteBlendMode blendMode) {
bool res;
for (int32 i = 0; i < _subframes.getSize(); i++) {
// filter out subframes unsupported by current renderer
//
// This is not present in original Lite version of WME.
// It's in assumption Lite support only 2D games.
// Our 3D renderer has full 2D capability, so not filter 2D only subframes.
if (!allFrames) {
if (/*(_subframes[i]->_2DOnly && _game->_useD3D) || */(_subframes[i]->_3DOnly && !_game->_useD3D))
continue;
}
res = _subframes[i]->draw(x, y, registerOwner, zoomX, zoomY, precise, alpha, rotate, blendMode);
if (DID_FAIL(res)) {
return res;
}
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool BaseFrame::oneTimeDisplay(BaseObject *owner, bool muted) {
if (_sound && !muted) {
if (owner) {
owner->updateOneSound(_sound);
}
_sound->play();
/*
if (_game->_state == GAME_FROZEN) {
_sound->pause(true);
}
*/
}
if (owner) {
for (int32 i = 0; i < _applyEvent.getSize(); i++) {
owner->applyEvent(_applyEvent[i]);
}
}
return STATUS_OK;
}
TOKEN_DEF_START
TOKEN_DEF(DELAY)
TOKEN_DEF(IMAGE)
TOKEN_DEF(TRANSPARENT)
TOKEN_DEF(RECT)
TOKEN_DEF(HOTSPOT)
TOKEN_DEF(2D_ONLY)
TOKEN_DEF(3D_ONLY)
TOKEN_DEF(MIRROR_X)
TOKEN_DEF(MIRROR_Y)
TOKEN_DEF(MOVE)
TOKEN_DEF(ALPHA_COLOR)
TOKEN_DEF(ALPHA)
TOKEN_DEF(SUBFRAME)
TOKEN_DEF(SOUND)
TOKEN_DEF(KEYFRAME)
TOKEN_DEF(DECORATION)
TOKEN_DEF(APPLY_EVENT)
TOKEN_DEF(EDITOR_SELECTED)
TOKEN_DEF(EDITOR_EXPANDED)
TOKEN_DEF(EDITOR_PROPERTY)
TOKEN_DEF(KILL_SOUND)
TOKEN_DEF_END
//////////////////////////////////////////////////////////////////////
bool BaseFrame::loadBuffer(char *buffer, int lifeTime, bool keepLoaded) {
TOKEN_TABLE_START(commands)
TOKEN_TABLE(DELAY)
TOKEN_TABLE(IMAGE)
TOKEN_TABLE(TRANSPARENT)
TOKEN_TABLE(RECT)
TOKEN_TABLE(HOTSPOT)
TOKEN_TABLE(2D_ONLY)
TOKEN_TABLE(3D_ONLY)
TOKEN_TABLE(MIRROR_X)
TOKEN_TABLE(MIRROR_Y)
TOKEN_TABLE(MOVE)
TOKEN_TABLE(ALPHA_COLOR)
TOKEN_TABLE(ALPHA)
TOKEN_TABLE(SUBFRAME)
TOKEN_TABLE(SOUND)
TOKEN_TABLE(KEYFRAME)
TOKEN_TABLE(DECORATION)
TOKEN_TABLE(APPLY_EVENT)
TOKEN_TABLE(EDITOR_SELECTED)
TOKEN_TABLE(EDITOR_EXPANDED)
TOKEN_TABLE(EDITOR_PROPERTY)
TOKEN_TABLE(KILL_SOUND)
TOKEN_TABLE_END
char *params;
int cmd;
BaseParser parser(_game);
Common::Rect32 rect;
int r = 255, g = 255, b = 255;
int ar = 255, ag = 255, ab = 255, alpha = 255;
int hotspotX = 0, hotspotY = 0;
bool customTrans = false;
bool editorSelected = false;
bool is2DOnly = false;
bool is3DOnly = false;
bool decoration = false;
bool mirrorX = false;
bool mirrorY = false;
BasePlatform::setRectEmpty(&rect);
char *surface_file = nullptr;
while ((cmd = parser.getCommand(&buffer, commands, &params)) > 0) {
switch (cmd) {
case TOKEN_DELAY:
parser.scanStr(params, "%d", &_delay);
break;
case TOKEN_IMAGE:
surface_file = params;
break;
case TOKEN_TRANSPARENT:
parser.scanStr(params, "%d,%d,%d", &r, &g, &b);
customTrans = true;
break;
case TOKEN_RECT:
parser.scanStr(params, "%d,%d,%d,%d", &rect.left, &rect.top, &rect.right, &rect.bottom);
break;
case TOKEN_HOTSPOT:
parser.scanStr(params, "%d,%d", &hotspotX, &hotspotY);
break;
case TOKEN_MOVE:
parser.scanStr(params, "%d,%d", &_moveX, &_moveY);
break;
case TOKEN_2D_ONLY:
parser.scanStr(params, "%b", &is2DOnly);
break;
case TOKEN_3D_ONLY:
parser.scanStr(params, "%b", &is3DOnly);
break;
case TOKEN_MIRROR_X:
parser.scanStr(params, "%b", &mirrorX);
break;
case TOKEN_MIRROR_Y:
parser.scanStr(params, "%b", &mirrorY);
break;
case TOKEN_ALPHA_COLOR:
parser.scanStr(params, "%d,%d,%d", &ar, &ag, &ab);
break;
case TOKEN_ALPHA:
parser.scanStr(params, "%d", &alpha);
break;
case TOKEN_EDITOR_SELECTED:
parser.scanStr(params, "%b", &editorSelected);
break;
case TOKEN_EDITOR_EXPANDED:
parser.scanStr(params, "%b", &_editorExpanded);
break;
case TOKEN_KILL_SOUND:
parser.scanStr(params, "%b", &_killSound);
break;
case TOKEN_SUBFRAME: {
BaseSubFrame *subframe = new BaseSubFrame(_game);
if (!subframe || DID_FAIL(subframe->loadBuffer(params, lifeTime, keepLoaded))) {
delete subframe;
cmd = PARSERR_GENERIC;
} else {
_subframes.add(subframe);
}
}
break;
case TOKEN_SOUND: {
if (_sound) {
SAFE_DELETE(_sound);
}
_sound = new BaseSound(_game);
if (!_sound || DID_FAIL(_sound->setSound(params, TSoundType::SOUND_SFX, false))) {
if (_game->_soundMgr->_soundAvailable) {
_game->LOG(0, "Error loading sound '%s'.", params);
}
SAFE_DELETE(_sound);
}
}
break;
case TOKEN_APPLY_EVENT: {
size_t eventSize = strlen(params) + 1;
char *event = new char[eventSize];
Common::strcpy_s(event, eventSize, params);
_applyEvent.add(event);
}
break;
case TOKEN_KEYFRAME:
parser.scanStr(params, "%b", &_keyframe);
break;
case TOKEN_DECORATION:
parser.scanStr(params, "%b", &decoration);
break;
case TOKEN_EDITOR_PROPERTY:
parseEditorProperty(params, false);
break;
default:
break;
}
}
if (cmd == PARSERR_TOKENNOTFOUND) {
_game->LOG(0, "Syntax error in FRAME definition");
return STATUS_FAILED;
}
if (cmd == PARSERR_GENERIC) {
_game->LOG(0, "Error loading FRAME definition");
return STATUS_FAILED;
}
BaseSubFrame *sub = new BaseSubFrame(_game);
if (surface_file != nullptr) {
if (customTrans) {
sub->setSurface(surface_file, false, r, g, b, lifeTime, keepLoaded);
} else {
sub->setSurface(surface_file, true, 0, 0, 0, lifeTime, keepLoaded);
}
if (!sub->_surface) {
delete sub;
_game->LOG(0, "Error loading SUBFRAME");
return STATUS_FAILED;
}
sub->_alpha = BYTETORGBA(ar, ag, ab, alpha);
if (customTrans) {
sub->_transparent = BYTETORGBA(r, g, b, 0xFF);
}
}
if (BasePlatform::isRectEmpty(&rect)) {
sub->setDefaultRect();
} else {
sub->_rect = rect;
}
sub->_hotspotX = hotspotX;
sub->_hotspotY = hotspotY;
sub->_2DOnly = is2DOnly;
sub->_3DOnly = is3DOnly;
sub->_decoration = decoration;
sub->_mirrorX = mirrorX;
sub->_mirrorY = mirrorY;
sub->_editorSelected = editorSelected;
_subframes.insertAt(0, sub);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool BaseFrame::getBoundingRect(Common::Rect32 *rect, int x, int y, float scaleX, float scaleY) {
if (!rect) {
return false;
}
BasePlatform::setRectEmpty(rect);
Common::Rect32 subRect;
for (int32 i = 0; i < _subframes.getSize(); i++) {
_subframes[i]->getBoundingRect(&subRect, x, y, scaleX, scaleY);
BasePlatform::unionRect(rect, rect, &subRect);
}
return true;
}
//////////////////////////////////////////////////////////////////////////
bool BaseFrame::saveAsText(BaseDynamicBuffer *buffer, int indent) {
buffer->putTextIndent(indent, "FRAME {\n");
buffer->putTextIndent(indent + 2, "DELAY = %d\n", _delay);
if (_moveX != 0 || _moveY != 0) {
buffer->putTextIndent(indent + 2, "MOVE {%d, %d}\n", _moveX, _moveY);
}
if (_sound && _sound->_soundFilename && _sound->_soundFilename[0]) {
buffer->putTextIndent(indent + 2, "SOUND=\"%s\"\n", _sound->_soundFilename);
}
buffer->putTextIndent(indent + 2, "KEYFRAME=%s\n", _keyframe ? "TRUE" : "FALSE");
if (_killSound) {
buffer->putTextIndent(indent + 2, "KILL_SOUND=%s\n", _killSound ? "TRUE" : "FALSE");
}
if (_editorExpanded) {
buffer->putTextIndent(indent + 2, "EDITOR_EXPANDED=%s\n", _editorExpanded ? "TRUE" : "FALSE");
}
if (_subframes.getSize() > 0) {
_subframes[0]->saveAsText(buffer, indent, false);
}
for (int32 i = 1; i < _subframes.getSize(); i++) {
_subframes[i]->saveAsText(buffer, indent + 2);
}
for (int32 i = 0; i < _applyEvent.getSize(); i++) {
buffer->putTextIndent(indent + 2, "APPLY_EVENT=\"%s\"\n", _applyEvent[i]);
}
BaseClass::saveAsText(buffer, indent + 2);
buffer->putTextIndent(indent, "}\n\n");
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
bool BaseFrame::persist(BasePersistenceManager *persistMgr) {
BaseScriptable::persist(persistMgr);
_applyEvent.persist(persistMgr);
persistMgr->transferUint32(TMEMBER(_delay));
persistMgr->transferBool(TMEMBER(_editorExpanded));
persistMgr->transferBool(TMEMBER(_keyframe));
persistMgr->transferBool(TMEMBER(_killSound));
persistMgr->transferSint32(TMEMBER(_moveX));
persistMgr->transferSint32(TMEMBER(_moveY));
persistMgr->transferPtr(TMEMBER_PTR(_sound));
_subframes.persist(persistMgr);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// high level scripting interface
//////////////////////////////////////////////////////////////////////////
bool BaseFrame::scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) {
//////////////////////////////////////////////////////////////////////////
// GetSound
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "GetSound") == 0) {
stack->correctParams(0);
if (_sound && _sound->_soundFilename && _sound->_soundFilename[0]) {
stack->pushString(_sound->_soundFilename);
} else {
stack->pushNULL();
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// SetSound
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "SetSound") == 0) {
stack->correctParams(1);
ScValue *val = stack->pop();
SAFE_DELETE(_sound);
if (!val->isNULL()) {
_sound = new BaseSound(_game);
if (!_sound || DID_FAIL(_sound->setSound(val->getString(), TSoundType::SOUND_SFX, false))) {
stack->pushBool(false);
SAFE_DELETE(_sound);
} else {
stack->pushBool(true);
}
} else {
stack->pushBool(true);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// GetSubframe
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "GetSubframe") == 0) {
stack->correctParams(1);
int index = stack->pop()->getInt(-1);
if (index < 0 || index >= _subframes.getSize()) {
script->runtimeError("Frame.GetSubframe: Subframe index %d is out of range.", index);
stack->pushNULL();
} else {
stack->pushNative(_subframes[index], true);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// DeleteSubframe
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "DeleteSubframe") == 0) {
stack->correctParams(1);
ScValue *val = stack->pop();
if (val->isInt()) {
int index = val->getInt(-1);
if (index < 0 || index >= _subframes.getSize()) {
script->runtimeError("Frame.DeleteSubframe: Subframe index %d is out of range.", index);
}
} else {
BaseSubFrame *sub = (BaseSubFrame *)val->getNative();
for (int32 i = 0; i < _subframes.getSize(); i++) {
if (_subframes[i] == sub) {
delete _subframes[i];
_subframes.removeAt(i);
break;
}
}
}
stack->pushNULL();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// AddSubframe
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AddSubframe") == 0) {
stack->correctParams(1);
ScValue *val = stack->pop();
const char *filename = nullptr;
if (!val->isNULL()) {
filename = val->getString();
}
BaseSubFrame *sub = new BaseSubFrame(_game);
if (filename != nullptr) {
sub->setSurface(filename);
sub->setDefaultRect();
}
_subframes.add(sub);
stack->pushNative(sub, true);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// InsertSubframe
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "InsertSubframe") == 0) {
stack->correctParams(2);
int index = stack->pop()->getInt();
if (index < 0) {
index = 0;
}
ScValue *val = stack->pop();
const char *filename = nullptr;
if (!val->isNULL()) {
filename = val->getString();
}
BaseSubFrame *sub = new BaseSubFrame(_game);
if (filename != nullptr) {
sub->setSurface(filename);
}
if (index >= _subframes.getSize()) {
_subframes.add(sub);
} else {
_subframes.insertAt(index, sub);
}
stack->pushNative(sub, true);
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// GetEvent
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "GetSubframe") == 0) {
stack->correctParams(1);
int index = stack->pop()->getInt(-1);
if (index < 0 || index >= _applyEvent.getSize()) {
script->runtimeError("Frame.GetEvent: Event index %d is out of range.", index);
stack->pushNULL();
} else {
stack->pushString(_applyEvent[index]);
}
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// AddEvent
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "AddEvent") == 0) {
stack->correctParams(1);
const char *event = stack->pop()->getString();
for (int32 i = 0; i < _applyEvent.getSize(); i++) {
if (scumm_stricmp(_applyEvent[i], event) == 0) {
stack->pushNULL();
return STATUS_OK;
}
}
_applyEvent.add(event);
stack->pushNULL();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// DeleteEvent
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "DeleteEvent") == 0) {
stack->correctParams(1);
const char *event = stack->pop()->getString();
for (int32 i = 0; i < _applyEvent.getSize(); i++) {
if (scumm_stricmp(_applyEvent[i], event) == 0) {
delete[] _applyEvent[i];
_applyEvent.removeAt(i);
break;
}
}
stack->pushNULL();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
else {
if (_subframes.getSize() == 1) {
return _subframes[0]->scCallMethod(script, stack, thisStack, name);
} else {
return BaseScriptable::scCallMethod(script, stack, thisStack, name);
}
}
}
//////////////////////////////////////////////////////////////////////////
ScValue *BaseFrame::scGetProperty(const char *name) {
if (!_scValue) {
_scValue = new ScValue(_game);
}
_scValue->setNULL();
//////////////////////////////////////////////////////////////////////////
// Type (RO)
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Type") == 0) {
_scValue->setString("frame");
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Delay
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Delay") == 0) {
_scValue->setInt(_delay);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// Keyframe
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Keyframe") == 0) {
_scValue->setBool(_keyframe);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// KillSounds
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "KillSounds") == 0) {
_scValue->setBool(_killSound);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// MoveX
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "MoveX") == 0) {
_scValue->setInt(_moveX);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// MoveY
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "MoveY") == 0) {
_scValue->setInt(_moveY);
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// NumSubframes (RO)
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "NumSubframes") == 0) {
_scValue->setInt(_subframes.getSize());
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
// NumEvents (RO)
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "NumEvents") == 0) {
_scValue->setInt(_applyEvent.getSize());
return _scValue;
}
//////////////////////////////////////////////////////////////////////////
else {
if (_subframes.getSize() == 1) {
return _subframes[0]->scGetProperty(name);
} else {
return BaseScriptable::scGetProperty(name);
}
}
}
//////////////////////////////////////////////////////////////////////////
bool BaseFrame::scSetProperty(const char *name, ScValue *value) {
//////////////////////////////////////////////////////////////////////////
// Delay
//////////////////////////////////////////////////////////////////////////
if (strcmp(name, "Delay") == 0) {
_delay = MAX(0, value->getInt());
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// Keyframe
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "Keyframe") == 0) {
_keyframe = value->getBool();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// KillSounds
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "KillSounds") == 0) {
_killSound = value->getBool();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// MoveX
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "MoveX") == 0) {
_moveX = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
// MoveY
//////////////////////////////////////////////////////////////////////////
else if (strcmp(name, "MoveY") == 0) {
_moveY = value->getInt();
return STATUS_OK;
}
//////////////////////////////////////////////////////////////////////////
else {
if (_subframes.getSize() == 1) {
return _subframes[0]->scSetProperty(name, value);
} else {
return BaseScriptable::scSetProperty(name, value);
}
}
}
//////////////////////////////////////////////////////////////////////////
const char *BaseFrame::scToString() {
return "[frame]";
}
Common::String BaseFrame::debuggerToString() const {
return Common::String::format("%p: Frame \"%s\": #subframes %d ", (const void *)this, _name, _subframes.getSize());
}
} // End of namespace Wintermute

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_BASE_FRAME_H
#define WINTERMUTE_BASE_FRAME_H
#include "engines/wintermute/base/base_scriptable.h"
#include "engines/wintermute/coll_templ.h"
#include "graphics/transform_struct.h"
namespace Wintermute {
class BaseSound;
class BaseSubFrame;
class BaseObject;
class ScScript;
class ScStack;
class BaseFrame : public BaseScriptable {
public:
bool _killSound;
bool _keyframe;
bool oneTimeDisplay(BaseObject *owner, bool muted = false);
DECLARE_PERSISTENT(BaseFrame, BaseScriptable)
BaseSound *_sound;
bool _editorExpanded;
bool getBoundingRect(Common::Rect32 *rect, int x, int y, float scaleX = 100, float scaleY = 100);
bool saveAsText(BaseDynamicBuffer *buffer, int indent) override;
int32 _moveY;
int32 _moveX;
uint32 _delay;
BaseArray<BaseSubFrame *> _subframes;
bool draw(int x, int y, BaseObject *registerOwner = nullptr, float zoomX = 100, float zoomY = 100, bool precise = true, uint32 alpha = 0xFFFFFFFF, bool allFrames = false, float rotate = 0.0f, Graphics::TSpriteBlendMode blendMode = Graphics::BLEND_NORMAL);
bool loadBuffer(char *buffer, int lifeTime, bool keepLoaded);
BaseFrame(BaseGame *inGame);
~BaseFrame() override;
BaseArray<const char *> _applyEvent;
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
Common::String debuggerToString() const override;
};
} // End of namespace Wintermute
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,473 @@
/* 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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_BASE_GAME_H
#define WINTERMUTE_BASE_GAME_H
#include "engines/wintermute/base/base_object.h"
#include "engines/wintermute/base/base_game_custom_actions.h"
#include "engines/wintermute/base/base_string_table.h"
#include "engines/wintermute/ext/plugin_event.h"
#include "engines/wintermute/persistent.h"
#include "engines/wintermute/coll_templ.h"
#include "engines/wintermute/debugger.h"
#if EXTENDED_DEBUGGER_ENABLED
#include "engines/wintermute/base/scriptables/debuggable/debuggable_script_engine.h"
#endif
#include "common/events.h"
#include "common/random.h"
namespace Wintermute {
typedef void (*ENGINE_LOG_CALLBACK)(char *text, bool result, void *data);
class BaseSoundMgr;
class BaseFader;
class BaseFont;
class BaseFileManager;
class BaseTransitionMgr;
class BaseFontStorage;
class BaseGameMusic;
class BaseQuickMsg;
class BaseViewport;
class BaseRenderer;
class BaseRegistry;
class BaseSurfaceStorage;
class BaseKeyboardState;
class BaseGameSettings;
class BaseAccessMgr;
class ScEngine;
class SXMath;
class SXDirectory;
class UIWindow;
class VideoPlayer;
class VideoTheoraPlayer;
class SaveThumbHelper;
#ifdef ENABLE_WME3D
class BaseRenderer3D;
struct FogParameters;
#endif
#define NUM_MUSIC_CHANNELS 5
class BaseGame : public BaseObject {
public:
DECLARE_PERSISTENT(BaseGame, BaseObject)
virtual bool onScriptShutdown(ScScript *script);
virtual bool getLayerSize(int *LayerWidth, int *LayerHeight, Common::Rect32 *viewport, bool *customViewport);
#ifdef ENABLE_WME3D
virtual uint32 getAmbientLightColor();
virtual bool getFogParams(bool *fogEnabled, uint32 *fogColor, float *start, float *end);
#endif
virtual BaseObject *getNextAccessObject(BaseObject *currObject);
virtual BaseObject *getPrevAccessObject(BaseObject *currObject);
virtual bool onActivate(bool activate, bool refreshMouse);
virtual bool onMouseLeftDown();
virtual bool onMouseLeftUp();
virtual bool onMouseLeftDblClick();
virtual bool onMouseRightDblClick();
virtual bool onMouseRightDown();
virtual bool onMouseRightUp();
virtual bool onMouseMiddleDown();
virtual bool onMouseMiddleUp();
virtual bool onPaint();
virtual bool onWindowClose();
bool isLeftDoubleClick();
bool isRightDoubleClick();
bool _autorunDisabled;
uint32 _lastMiniUpdate;
bool _miniUpdateEnabled;
virtual bool miniUpdate();
void getMousePos(Common::Point32 *pos);
Common::Rect32 _mouseLockRect;
bool _shuttingDown;
virtual bool displayDebugInfo();
bool _debugShowFPS;
bool _suspendedRendering;
int32 _soundBufferSizeSec;
virtual bool renderShadowGeometry();
TTextEncoding _textEncoding;
bool _textRTL;
BaseSprite *_loadingIcon;
int32 _loadingIconX;
int32 _loadingIconY;
int32 _loadingIconPersistent;
virtual bool resetContent();
void DEBUG_DumpClassRegistry();
bool setWaitCursor(const char *filename);
char *_localSaveDir;
bool _saveDirChecked;
#ifdef ENABLE_WME3D
bool _supportsRealTimeShadows;
TShadowType _maxShadowType;
bool setMaxShadowType(TShadowType maxShadowType);
virtual TShadowType getMaxShadowType(BaseObject *object = nullptr);
#endif
bool _indicatorDisplay;
uint32 _indicatorColor;
int32 _indicatorProgress;
int32 _indicatorX;
int32 _indicatorY;
int32 _indicatorWidth;
int32 _indicatorHeight;
bool _richSavedGames;
char *_savedGameExt;
int32 _editorResolutionWidth;
int32 _editorResolutionHeight;
char *_loadImageName;
char *_saveImageName;
int32 _saveImageX;
int32 _saveImageY;
int32 _loadImageX;
int32 _loadImageY;
BaseSurface *_saveLoadImage;
bool _hasDrawnSaveLoadImage;
bool displayIndicator();
#ifdef ENABLE_FOXTAIL
bool displayIndicatorFoxTail();
#endif
uint32 _thumbnailWidth;
uint32 _thumbnailHeight;
bool _reportTextureFormat;
void setEngineLogCallback(ENGINE_LOG_CALLBACK callback = nullptr, void *data = nullptr);
ENGINE_LOG_CALLBACK _engineLogCallback;
void *_engineLogCallbackData;
bool _editorMode;
void getOffset(int *offsetX, int *offsetY) const;
void setOffset(int32 offsetX, int32 offsetY);
int getSequence();
int32 _offsetY;
int32 _offsetX;
float _offsetPercentX;
float _offsetPercentY;
BaseObject *_mainObject;
bool initInput();
bool initLoop();
uint32 _currentTime{};
uint32 _deltaTime;
BaseFont *_systemFont;
BaseFont *_videoFont;
bool initConfManSettings();
bool initRenderer();
bool initialize1();
bool initialize2();
bool initialize3();
BaseAccessMgr *_accessMgr;
BaseFileManager *_fileManager;
BaseTransitionMgr *_transMgr;
void LOG(bool res, const char *fmt, ...);
BaseRenderer *_renderer;
#ifdef ENABLE_WME3D
BaseRenderer3D *_renderer3D;
bool _playing3DGame;
#endif
BaseSoundMgr *_soundMgr;
#if EXTENDED_DEBUGGER_ENABLED
DebuggableScEngine *_scEngine;
#else
ScEngine *_scEngine;
#endif
BaseScriptable *_mathClass;
BaseScriptable *_directoryClass;
BaseSurfaceStorage *_surfaceStorage;
BaseFontStorage *_fontStorage;
BaseGame(const Common::String &targetName);
~BaseGame() override;
void debugDisable();
void debugEnable(const char *filename = nullptr);
bool _debugMode;
void *_debugLogFile;
int32 _sequence;
virtual bool loadFile(const char *filename);
virtual bool loadBuffer(char *buffer, bool complete = true);
BaseArray<BaseQuickMsg *> _quickMessages;
BaseArray<UIWindow *> _windows;
BaseArray<BaseViewport *> _viewportStack;
int32 _viewportSP;
bool _mouseLeftDown;
bool _mouseRightDown;
bool _mouseMidlleDown;
BaseStringTable *_stringTable;
int _settingsResWidth;
int _settingsResHeight;
bool _settingsRequireAcceleration;
bool _settingsAllowWindowed;
bool _settingsAllowAdvanced;
bool _settingsAllowAccessTab;
bool _settingsAllowAboutTab;
bool _settingsRequireSound;
bool _settingsAllowDesktopRes;
int32 _settingsTLMode;
char *_settingsGameFile;
BaseFader *_fader;
bool _suppressScriptErrors;
bool invalidateDeviceObjects() override;
bool restoreDeviceObjects() override;
virtual bool externalCall(ScScript *script, ScStack *stack, ScStack *thisStack, char *name);
// scripting interface
ScValue *scGetProperty(const char *name) override;
bool scSetProperty(const char *name, ScValue *value) override;
bool scCallMethod(ScScript *script, ScStack *stack, ScStack *thisStack, const char *name) override;
const char *scToString() override;
// compatibility bits
bool _compatKillMethodThreads;
private:
// FPS stuff
uint32 _lastTime;
uint32 _fpsTime;
uint32 _framesRendered;
public:
uint32 _surfaceGCCycleTime;
bool _smartCache; // RO
bool _videoSubtitles;
bool _subtitles; // RO
uint32 _musicStartTime[NUM_MUSIC_CHANNELS];
bool _compressedSavegames;
int32 _scheduledLoadSlot;
bool _loading;
bool _personalizedSave;
static bool emptySaveSlot(int slot);
static bool isSaveSlotUsed(int slot);
static bool getSaveSlotDescription(int slot, Common::String &desc);
static void getSaveSlotTimestamp(int slot, TimeDate *time);
static bool getSaveSlotFilename(int slot, Common::String &desc);
void setWindowTitle();
bool handleMouseWheel(int32 delta) override;
bool _quitting;
virtual bool getVersion(byte *verMajor, byte *verMinor, byte *extMajor, byte *extMinor);
bool handleKeypress(Common::Event *event, bool printable = false) override;
virtual void handleKeyRelease(Common::Event *event);
bool handleAccessKey(Common::Event *event, bool printable);
virtual bool handleCustomActionStart(BaseGameCustomAction action);
virtual bool handleCustomActionEnd(BaseGameCustomAction action);
int32 _freezeLevel;
bool unfreeze();
bool freeze(bool includingMusic = true);
bool focusWindow(UIWindow *window);
VideoPlayer *_videoPlayer;
VideoTheoraPlayer *_theoraPlayer;
bool _loadInProgress;
UIWindow *_focusedWindow;
bool _editorForceScripts;
static void afterLoadRegion(void *region, void *data);
static void afterLoadSubFrame(void *subframe, void *data);
static void afterLoadSound(void *sound, void *data);
static void afterLoadFont(void *font, void *data);
#ifdef ENABLE_WME3D
static void afterLoadXModel(void *model, void *data);
#endif
static void afterLoadScript(void *script, void *data);
static void afterLoadScene(void *scene, void *data);
static void invalidateValues(void *value, void *data);
bool loadSettings(const char *filename);
bool resumeMusic(int channel);
bool setMusicStartTime(int channel, uint32 time);
bool pauseMusic(int channel);
bool stopMusic(int channel);
bool playMusic(int channel, const char *filename, bool looping = true, uint32 loopStart = 0, uint32 privVolume = 100);
BaseSound *_music[NUM_MUSIC_CHANNELS];
bool _musicCrossfadeRunning;
bool _musicCrossfadeSwap;
uint32 _musicCrossfadeStartTime;
uint32 _musicCrossfadeLength;
int32 _musicCrossfadeChannel1;
int32 _musicCrossfadeChannel2;
int32 _musicCrossfadeVolume1;
int32 _musicCrossfadeVolume2;
bool displayWindows(bool inGame = false);
Common::String readRegistryString(const Common::String &key, const Common::String &initValue) const;
bool _useD3D;
virtual bool cleanup();
bool loadGame(uint32 slot);
bool loadGame(const char *filename);
bool saveGame(int32 slot, const char *desc, bool quickSave = false);
bool showCursor() override;
BaseSprite *_cursorNoninteractive;
BaseObject *_activeObject;
BaseKeyboardState *_keyboardState;
bool _interactive;
TGameState _state;
TGameState _origState;
bool _origInteractive;
uint32 _timer;
uint32 _timerDelta;
uint32 _timerLast;
uint32 _liveTimer;
uint32 _liveTimerDelta;
uint32 _liveTimerLast;
BaseObject *_capturedObject;
Common::Point32 _mousePos;
bool validObject(BaseObject *object);
bool unregisterObject(BaseObject *object);
bool registerObject(BaseObject *object);
void quickMessage(const char *text);
void quickMessageForm(char *fmt, ...);
bool displayQuickMsg();
uint32 _fps;
bool updateMusicCrossfade();
bool isVideoPlaying();
bool stopVideo();
BaseArray<BaseObject *> _regObjects;
// accessibility flags
bool _accessTTSEnabled;
bool _accessTTSTalk;
bool _accessTTSCaptions;
bool _accessTTSKeypress;
bool _accessKeyboardEnabled;
bool _accessKeyboardCursorSkip;
bool _accessKeyboardPause;
bool _accessGlobalPaused;
UIWindow *_accessShieldWin;
bool accessPause();
bool accessUnpause();
public:
virtual bool displayContent(bool update = true, bool displayAll = false);
virtual bool displayContentSimple();
bool _forceNonStreamedSounds;
void resetMousePos();
int32 _subtitlesSpeed;
void setInteractive(bool state);
virtual bool windowLoadHook(UIWindow *win, char **buf, char **params);
virtual bool windowScriptMethodHook(UIWindow *win, ScScript *script, ScStack *stack, const char *name);
bool getCurrentViewportOffset(int *offsetX = nullptr, int *offsetY = nullptr);
bool getCurrentViewportRect(Common::Rect32 *rect, bool *custom = nullptr);
bool popViewport();
bool pushViewport(BaseViewport *viewport);
bool setActiveObject(BaseObject *obj);
BaseSprite *_lastCursor;
bool drawCursor(BaseSprite *cursor);
virtual bool initAfterLoad();
SaveThumbHelper *_cachedThumbnail;
private:
bool getSaveDir(char *Buffer);
public:
BaseGameMusic *_musicSystem;
Common::String _targetName;
void setIndicatorVal(int value);
bool getBilinearFiltering() { return _bilinearFiltering; }
void addMem(int32 bytes);
bool _touchInterface;
bool _bilinearFiltering{};
#ifdef ENABLE_WME3D
bool _force2dRenderer{};
#endif
AnsiString getDeviceType() const;
struct LastClickInfo {
LastClickInfo() {
posX = posY = 0;
time = 0;
}
int32 posX;
int32 posY;
uint32 time;
};
LastClickInfo _lastClick[2];
bool isDoubleClick(int32 buttonIndex);
uint32 _usedMem;
protected:
// WME Lite specific
bool _autoSaveOnExit;
uint32 _autoSaveSlot;
bool _cursorHidden;
public:
void autoSaveOnExit();
PluginEvent &pluginEvents() { return _pluginEvents; }
private:
#ifdef ENABLE_HEROCRAFT
// HeroCraft games specific random source with ability a in-script function to set the seed
Common::RandomSource *_rndHc;
// HeroCraft games specific checksum function, used in Papa's Daughters 2 selfcheck
uint8 getFilePartChecksumHc(const char *filename, uint32 begin, uint32 end);
#endif
PluginEvent _pluginEvents;
};
} // End of namespace Wintermute
#endif

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/>.
*
*/
/*
* This file is based on WME Lite.
* http://dead-code.org/redir.php?target=wmelite
* Copyright (c) 2011 Jan Nedoma
*/
#ifndef WINTERMUTE_BASE_GAME_CUSTOM_ACTION_H
#define WINTERMUTE_BASE_GAME_CUSTOM_ACTION_H
namespace Wintermute {
enum BaseGameCustomAction {
kClickAtCenter = 0,
kClickAtLeft = 1,
kClickAtRight = 2,
kClickAtTop = 3,
kClickAtBottom = 4,
kClickAtEntityNearestToCenter = 5
};
} // End of namespace Wintermute
#endif

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