aboutsummaryrefslogtreecommitdiff
path: root/engines/illusions
diff options
context:
space:
mode:
Diffstat (limited to 'engines/illusions')
-rw-r--r--engines/illusions/actor.cpp304
-rw-r--r--engines/illusions/actor.h109
-rw-r--r--engines/illusions/illusions.cpp15
-rw-r--r--engines/illusions/illusions.h6
4 files changed, 428 insertions, 6 deletions
diff --git a/engines/illusions/actor.cpp b/engines/illusions/actor.cpp
index 5185fda7e9..9f5975fb16 100644
--- a/engines/illusions/actor.cpp
+++ b/engines/illusions/actor.cpp
@@ -20,12 +20,35 @@
*
*/
+#include "illusions/illusions.h"
#include "illusions/actor.h"
+#include "illusions/actorresource.h"
+#include "illusions/camera.h"
+#include "illusions/input.h"
namespace Illusions {
-Actor::Actor()
- : _pauseCtr(0) {
+// DefaultSequences
+
+uint32 DefaultSequences::use(uint32 sequenceId) {
+ ItemsIterator it = Common::find_if(_items.begin(), _items.end(), DefaultSequenceEqual(sequenceId));
+ return it != _items.end() ? (*it)._newSequenceId : sequenceId;
+}
+
+void DefaultSequences::set(uint32 sequenceId, uint32 newSequenceId) {
+ ItemsIterator it = Common::find_if(_items.begin(), _items.end(), DefaultSequenceEqual(sequenceId));
+ if (it == _items.end())
+ _items.push_back(DefaultSequence(sequenceId, newSequenceId));
+ else if (sequenceId == newSequenceId)
+ _items.remove_at(it - _items.begin());
+ else
+ (*it)._newSequenceId = newSequenceId;
+}
+
+// Actor
+
+Actor::Actor(IllusionsEngine *vm)
+ : _vm(vm), _pauseCtr(0) {
}
@@ -37,4 +60,281 @@ void Actor::unpause() {
--_pauseCtr;
}
+void Actor::createSurface(SurfInfo &surfInfo) {
+ _surface = _vm->allocSurface(surfInfo);
+ if (_frameIndex) {
+ if (_surfaceTextFlag) {
+ /* TODO
+ Font *font = _vm->findFont(_fontId);
+ _surface->fillRect(Common::Rect(surfInfo._dimensions._width, surfInfo._dimensions._height), 0);
+ gfx_sub_40CA70(_surface, font, _field18C, _surfInfo._dimensions, _field198);
+ */
+ _flags |= 0x4000;
+ }
+ else {
+ _flags |= 0x2000;
+ _flags |= 0x4000;
+ }
+ }
+}
+
+void Actor::destroySurface() {
+ if (_surface) {
+ _surface->free();
+ delete _surface;
+ _surface = 0;
+ }
+}
+
+// Control
+
+Control::Control(IllusionsEngine *vm)
+ : _vm(vm) {
+}
+
+Control::~Control() {
+}
+
+void Control::pause() {
+
+ // TODO scrmgrSetObjectArtThread(control->objectId, 0);
+
+ /* TODO
+ if (_objectId == 0x40004)
+ _cursor.control = 0;
+ */
+
+ if (_actor && !(_actor->_flags & 0x0200))
+ _actor->destroySurface();
+
+}
+
+void Control::unpause() {
+
+ // TODO scrmgrSetObjectArtThread(control->objectId, control);
+
+ /* TODO
+ if (_objectId == 0x40004)
+ _cursor.control = this;
+ */
+
+ if (_actor && !(_actor->_flags & 0x0200)) {
+ SurfInfo surfInfo;
+ ActorType *actorType = _vm->findActorType(_actorTypeId);
+ if (actorType)
+ surfInfo = actorType->_surfInfo;
+ else
+ surfInfo = _actor->_surfInfo;
+ _actor->createSurface(surfInfo);
+ }
+
+}
+
+void Control::appearActor() {
+ if (_objectId == 0x40004) {
+ // TODO ++cursor._visibleCtr;
+ // TODO if (cursor._visibleCtr > 0)
+ {
+ _flags |= 1;
+ _actor->_flags |= 1;
+ if (_actor->_frameIndex) {
+ _actor->_flags |= 0x2000;
+ _actor->_flags |= 0x4000;
+ }
+ _vm->_input->discardButtons(0xFFFF);
+ }
+ } else {
+ if (_actor->_frameIndex || _actorTypeId == 0x50004)
+ _actor->_flags |= 1;
+ else
+ _actor->_flags |= 0x1000;
+ for (uint i = 0; i < kSubObjectsCount; ++i)
+ if (_actor->_subobjects[i]) {
+ Control *subControl = _vm->findControl(_actor->_subobjects[i]);
+ subControl->appearActor();
+ }
+ }
+}
+
+void Control::disappearActor() {
+ if (_objectId == 0x40004) {
+ // TODO --cursor.visibleCtr;
+ // TODO if (cursor.visibleCtr <= 0)
+ {
+ _flags &= 0xFFFEu;
+ _actor->_flags &= 0xFFFE;
+ }
+ } else {
+ _actor->_flags |= ~1;
+ _actor->_flags |= ~0x1000;
+ for (uint i = 0; i < kSubObjectsCount; ++i)
+ if (_actor->_subobjects[i]) {
+ Control *subControl = _vm->findControl(_actor->_subobjects[i]);
+ subControl->disappearActor();
+ }
+ }
+}
+
+bool Control::isActorVisible() {
+ return (_actor->_flags & 1) != 0;
+}
+
+void Control::activateObject() {
+ _flags |= 1;
+ for (uint i = 0; i < kSubObjectsCount; ++i)
+ if (_actor->_subobjects[i]) {
+ Control *subControl = _vm->findControl(_actor->_subobjects[i]);
+ subControl->activateObject();
+ }
+}
+
+void Control::deactivateObject() {
+ _flags |= ~1;
+ for (uint i = 0; i < kSubObjectsCount; ++i)
+ if (_actor->_subobjects[i]) {
+ Control *subControl = _vm->findControl(_actor->_subobjects[i]);
+ subControl->deactivateObject();
+ }
+}
+
+void Control::setActorPosition(Common::Point position) {
+ _actor->_position = position;
+}
+
+Common::Point Control::getActorPosition() {
+ if (_actor)
+ return _actor->_position;
+ return _position;
+}
+
+void Control::setActorScale(int scale) {
+ _actor->_scale = scale;
+ for (uint i = 0; i < kSubObjectsCount; ++i)
+ if (_actor->_subobjects[i]) {
+ Control *subControl = _vm->findControl(_actor->_subobjects[i]);
+ subControl->activateObject();
+ }
+}
+
+void Control::faceActor(uint facing) {
+ _actor->_facing = facing;
+ for (uint i = 0; i < kSubObjectsCount; ++i)
+ if (_actor->_subobjects[i]) {
+ Control *subControl = _vm->findControl(_actor->_subobjects[i]);
+ subControl->faceActor(facing);
+ }
+}
+
+void Control::linkToObject(uint32 parentObjectId, uint32 linkedObjectValue) {
+ _actor->_parentObjectId = parentObjectId;
+ _actor->_linkIndex = linkedObjectValue;
+}
+
+void Control::unlinkObject() {
+ _actor->_parentObjectId = 0;
+ _actor->_linkIndex = 0;
+}
+
+void Control::clearNotifyThreadId1() {
+ _actor->_notifyThreadId1 = 0;
+}
+
+void Control::clearNotifyThreadId2() {
+ for (uint i = 0; i < kSubObjectsCount; ++i)
+ if (_actor->_subobjects[i]) {
+ Control *subControl = _vm->findControl(_actor->_subobjects[i]);
+ subControl->_actor->_flags &= ~0x80;
+ subControl->_actor->_field30 = 0;
+ subControl->_actor->_notifyThreadId2 = 0;
+ }
+ _actor->_flags &= ~0x80;
+ _actor->_field30 = 0;
+ _actor->_notifyThreadId2 = 0;
+}
+
+void Control::setPriority(int16 priority) {
+ _priority = priority;
+}
+
+int Control::getPriority() {
+ uint32 objectId;
+ int16 positionY, priority, priority1;
+ if (_actor) {
+ if (_actor->_parentObjectId && (_actor->_flags & 0x40)) {
+ uint32 objectId2 = getSubActorParent();
+ Control *control2 = _vm->findControl(objectId2);
+ objectId = control2->_objectId;
+ priority = control2->_priority;
+ positionY = control2->_actor->_position.y;
+ priority1 = _priority;
+ } else {
+ objectId = _objectId;
+ positionY = _actor->_position.y;
+ priority = _priority;
+ priority1 = 50;
+ }
+ } else {
+ positionY = _position.y;
+ objectId = _objectId;
+ priority = _priority;
+ priority1 = 1;
+ }
+
+ priority -= 1;
+ int p = 50 * priority1 / 100;
+ if (p)
+ --p;
+
+ positionY = CLIP<int16>(positionY, -5000, 5000);
+
+ return p + 50 * ((objectId & 0x3F) + ((10000 * priority + positionY + 5000) << 6));
+}
+
+uint32 Control::getSubActorParent() {
+ uint32 parentObjectId = _objectId;
+ while (1) {
+ Actor *actor = _vm->findControl(parentObjectId)->_actor;
+ if (actor->_parentObjectId && (actor->_flags & 0x40))
+ parentObjectId = actor->_parentObjectId;
+ else
+ break;
+ }
+ return parentObjectId;
+}
+
+void Control::getCollisionRectAccurate(Common::Rect &collisionRect) {
+
+ if (_actor && _actor->_frameIndex) {
+ collisionRect = Common::Rect(-_position.x, -_position.y,
+ -_position.x + _actor->_surfInfo._dimensions._width - 1,
+ -_position.y + _actor->_surfInfo._dimensions._height - 1);
+ } else {
+ collisionRect = Common::Rect(_unkPt.x, _unkPt.y, _pt.x, _pt.y);
+ }
+
+ if (_actor) {
+ if (_actor->_scale != 100 ) {
+ // scaledValue = value * scale div 100
+ collisionRect.left = collisionRect.left * _actor->_scale / 100;
+ collisionRect.top = collisionRect.top * _actor->_scale / 100;
+ collisionRect.right = collisionRect.right * _actor->_scale / 100;
+ collisionRect.bottom = collisionRect.bottom * _actor->_scale / 100;
+ }
+ collisionRect.translate(_actor->_position.x, _actor->_position.y);
+ }
+
+ if (_flags & 8) {
+ Common::Point screenOffs = _vm->_camera->getScreenOffset();
+ collisionRect.translate(screenOffs.x, screenOffs.y);
+ }
+
+}
+
+void Control::setActorUsePan(int usePan) {
+ if (usePan == 1)
+ _flags &= ~8;
+ else
+ _flags |= 8;
+}
+
} // End of namespace Illusions
diff --git a/engines/illusions/actor.h b/engines/illusions/actor.h
index 2817b1df40..43e7ef4959 100644
--- a/engines/illusions/actor.h
+++ b/engines/illusions/actor.h
@@ -23,15 +23,120 @@
#ifndef ILLUSIONS_ACTOR_H
#define ILLUSIONS_ACTOR_H
+#include "illusions/graphics.h"
+#include "common/algorithm.h"
+#include "graphics/surface.h"
+
namespace Illusions {
+class IllusionsEngine;
+
+const uint kSubObjectsCount = 15;
+
+struct DefaultSequence {
+ uint32 _sequenceId;
+ uint32 _newSequenceId;
+ DefaultSequence()
+ : _sequenceId(0), _newSequenceId(0) {}
+ DefaultSequence(uint32 sequenceId, uint32 newSequenceId)
+ : _sequenceId(sequenceId), _newSequenceId(newSequenceId) {}
+};
+
+class DefaultSequences {
+public:
+ uint32 use(uint32 sequenceId);
+ void set(uint32 sequenceId, uint32 newSequenceId);
+protected:
+ typedef Common::Array<DefaultSequence> Items;
+ typedef Items::iterator ItemsIterator;
+ struct DefaultSequenceEqual : public Common::UnaryFunction<const DefaultSequence&, bool> {
+ uint32 _sequenceId;
+ DefaultSequenceEqual(uint32 sequenceId) : _sequenceId(sequenceId) {}
+ bool operator()(const DefaultSequence &defaultSequence) const {
+ return defaultSequence._sequenceId == _sequenceId;
+ }
+ };
+ Common::Array<DefaultSequence> _items;
+};
+
class Actor {
public:
- Actor();
+ Actor(IllusionsEngine *vm);
void pause();
void unpause();
-protected:
+ void createSurface(SurfInfo &surfInfo);
+ void destroySurface();
+public:
+ IllusionsEngine *_vm;
+
+ int _pauseCtr;
+ uint _flags;
+
+ int _scale;
+ int16 _frameIndex;
+ int16 _newFrameIndex;
+ SurfInfo _surfInfo;
+ Graphics::Surface *_surface;
+
+ Common::Point _position;
+ uint _facing;
+
+ DefaultSequences _defaultSequences;
+
+ uint32 _parentObjectId;
+ int _linkIndex;
+ int _linkIndex2;
+ uint32 _subobjects[kSubObjectsCount];
+
+ uint32 _notifyThreadId1;
+
+ uint32 _notifyThreadId2;
+ int _field30;
+
+ int _surfaceTextFlag;
+
+};
+
+class Control {
+public:
+ Control(IllusionsEngine *vm);
+ ~Control();
+ void pause();
+ void unpause();
+ void appearActor();
+ void disappearActor();
+ bool isActorVisible();
+ void activateObject();
+ void deactivateObject();
+ void setActorPosition(Common::Point position);
+ Common::Point getActorPosition();
+ void setActorScale(int scale);
+ void faceActor(uint facing);
+ void linkToObject(uint32 parentObjectId, uint32 linkedObjectValue);
+ void unlinkObject();
+ void clearNotifyThreadId1();
+ void clearNotifyThreadId2();
+ void setPriority(int16 priority);
+ int getPriority();
+ uint32 getSubActorParent();
+ void getCollisionRectAccurate(Common::Rect &collisionRect);
+ void setActorUsePan(int usePan);
+public:
+ IllusionsEngine *_vm;
+ uint _flags;
int _pauseCtr;
+ int16 _priority;
+ Actor *_actor;
+ //field_6 dw
+ uint32 _tag;
+ uint32 _objectId;
+ uint32 _actorTypeId;
+ // TODO Move points into own struct
+ Common::Point _unkPt;
+ Common::Point _pt;
+ Common::Point _feetPt;
+ Common::Point _position;
+ // TODO 0000001C - 00000054 unknown
};
} // End of namespace Illusions
diff --git a/engines/illusions/illusions.cpp b/engines/illusions/illusions.cpp
index a3ed76ee3b..f0bbc0951f 100644
--- a/engines/illusions/illusions.cpp
+++ b/engines/illusions/illusions.cpp
@@ -85,9 +85,9 @@ Common::Error IllusionsEngine::run() {
_resSys->addResourceLoader(0x000D0000, new ScriptResourceLoader(this));
_resSys->addResourceLoader(0x00100000, new ActorResourceLoader(this));
_resSys->addResourceLoader(0x00110000, new BackgroundResourceLoader(this));
-
- _scriptMan = new ScriptMan(this);
+ _input = new Input();
+ _scriptMan = new ScriptMan(this);
_actorItems = new ActorItems(this);
_backgroundItems = new BackgroundItems(this);
_camera = new Camera(this);
@@ -130,6 +130,7 @@ Common::Error IllusionsEngine::run() {
delete _backgroundItems;
delete _actorItems;
delete _scriptMan;
+ delete _input;
delete _resSys;
return Common::kNoError;
@@ -205,4 +206,14 @@ Common::Point *IllusionsEngine::getObjectActorPositionPtr(uint32 objectId) {
return 0;
}
+Control *IllusionsEngine::findControl(uint32 objectId) {
+ // TODO Dummy, to be replaced later
+ return 0;
+}
+
+ActorType *IllusionsEngine::findActorType(uint32 actorTypeId) {
+ // TODO Dummy, to be replaced later
+ return 0;
+}
+
} // End of namespace Illusions
diff --git a/engines/illusions/illusions.h b/engines/illusions/illusions.h
index bfb7335be4..4b5a1683d5 100644
--- a/engines/illusions/illusions.h
+++ b/engines/illusions/illusions.h
@@ -50,10 +50,13 @@ struct SurfInfo;
class ActorItem;
class ActorItems;
+class ActorType;
class BackgroundItem;
class BackgroundItems;
class BackgroundResource;
class Camera;
+class Control;
+class Input;
class ScriptResource;
class ScriptMan;
@@ -75,6 +78,7 @@ public:
void updateEvents();
+ Input *_input;
ScriptMan *_scriptMan;
ActorItems *_actorItems;
BackgroundItems *_backgroundItems;
@@ -88,6 +92,8 @@ public:
Graphics::Surface *getBackSurface();
Common::Point *getObjectActorPositionPtr(uint32 objectId);
+ Control *findControl(uint32 objectId);
+ ActorType *findActorType(uint32 actorTypeId);
#if 0