diff options
Diffstat (limited to 'engines/illusions')
-rw-r--r-- | engines/illusions/actor.cpp | 304 | ||||
-rw-r--r-- | engines/illusions/actor.h | 109 | ||||
-rw-r--r-- | engines/illusions/illusions.cpp | 15 | ||||
-rw-r--r-- | engines/illusions/illusions.h | 6 |
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 |