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

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