diff options
author | johndoe123 | 2014-03-19 13:59:13 +0100 |
---|---|---|
committer | Eugene Sandulenko | 2018-07-20 06:43:33 +0000 |
commit | e881db073200fb2b3d7087c076ff3da77135516a (patch) | |
tree | 6e552b6fe387e77fbde6ad161e1a1c3345103c1d /engines | |
parent | 18540a5e385997815f5a7c237328d7bc0b10c174 (diff) | |
download | scummvm-rg350-e881db073200fb2b3d7087c076ff3da77135516a.tar.gz scummvm-rg350-e881db073200fb2b3d7087c076ff3da77135516a.tar.bz2 scummvm-rg350-e881db073200fb2b3d7087c076ff3da77135516a.zip |
ILLUSIONS: Implement more sequence opcodes and work on the graphics system
Diffstat (limited to 'engines')
-rw-r--r-- | engines/illusions/actor.cpp | 106 | ||||
-rw-r--r-- | engines/illusions/actor.h | 10 | ||||
-rw-r--r-- | engines/illusions/actorresource.cpp | 9 | ||||
-rw-r--r-- | engines/illusions/backgroundresource.cpp | 12 | ||||
-rw-r--r-- | engines/illusions/backgroundresource.h | 8 | ||||
-rw-r--r-- | engines/illusions/illusions.cpp | 88 | ||||
-rw-r--r-- | engines/illusions/illusions.h | 10 | ||||
-rw-r--r-- | engines/illusions/sequenceopcodes.cpp | 182 | ||||
-rw-r--r-- | engines/illusions/sequenceopcodes.h | 20 | ||||
-rw-r--r-- | engines/illusions/spritedecompressqueue.cpp | 13 |
10 files changed, 421 insertions, 37 deletions
diff --git a/engines/illusions/actor.cpp b/engines/illusions/actor.cpp index 74443c3aac..e1aa5f772f 100644 --- a/engines/illusions/actor.cpp +++ b/engines/illusions/actor.cpp @@ -27,6 +27,7 @@ #include "illusions/input.h" #include "illusions/screen.h" #include "illusions/scriptman.h" +#include "illusions/scriptopcodes.h" #include "illusions/sequenceopcodes.h" namespace Illusions { @@ -53,6 +54,8 @@ void DefaultSequences::set(uint32 sequenceId, uint32 newSequenceId) { Actor::Actor(IllusionsEngine *vm) : _vm(vm), _pauseCtr(0) { _pauseCtr = 0; + _spriteFlags = 0; + _drawFlags = 0; _flags = 0; _scale = 100; _frameIndex = 0; @@ -84,15 +87,16 @@ Actor::Actor(IllusionsEngine *vm) _seqCodeValue1 = 0; _seqCodeValue2 = 600; _seqCodeValue3 = 0; + + _notifyId3C = 0; _pathCtrY = 0; + + _controlRoutine = 0; + setControlRoutine(new Common::Functor2Mem<Control*, uint32, void, Controls>(_vm->_controls, &Controls::actorControlRouine)); #if 0 // TODO _field2 = 0; - _spriteFlags = 0; - _drawFlags = 0; - _controlRoutine = Actor_defaultControlRoutine; - _notifyId3C = 0; _path40 = 0; _path4C = 0; _pathFlag50 = 0; @@ -166,6 +170,16 @@ int16 Actor::popSequenceStack() { return _seqStack[--_seqStackCount]; } +void Actor::setControlRoutine(ActorControlRoutine *controlRoutine) { + delete _controlRoutine; + _controlRoutine = controlRoutine; +} + +void Actor::runControlRoutine(Control *control, uint32 deltaTime) { + if (_controlRoutine) + (*_controlRoutine)(control, deltaTime); +} + // Control Control::Control(IllusionsEngine *vm) @@ -501,10 +515,8 @@ void Control::stopActor() { _actor->_path40 = 0; } */ - _vm->notifyThreadId(_actor->_notifyThreadId1); _vm->notifyThreadId(_actor->_notifyId3C); - } void Control::startSequenceActor(uint32 sequenceId, int value, uint32 notifyThreadId) { @@ -528,7 +540,52 @@ void Control::stopSequenceActor() { } void Control::sequenceActor() { - // TODO + + if (_actor->_pauseCtr > 0) + return; + + OpCall opCall; + bool sequenceFinished = false; + + opCall._result = 0; + _actor->_seqCodeValue3 -= _actor->_seqCodeValue1; + + while (_actor->_seqCodeValue3 <= 0 && !sequenceFinished) { + bool breakInner = false; + while (!breakInner) { + debug("op: %08X", _actor->_seqCodeIp[0]); + opCall._op = _actor->_seqCodeIp[0] & 0x7F; + opCall._opSize = _actor->_seqCodeIp[1]; + opCall._code = _actor->_seqCodeIp + 2; + opCall._deltaOfs = opCall._opSize; + if (_actor->_seqCodeIp[0] & 0x80) + breakInner = true; + execSequenceOpcode(opCall); + if (opCall._result == 1) { + sequenceFinished = true; + breakInner = true; + } else if (opCall._result == 2) { + breakInner = true; + } + _actor->_seqCodeIp += opCall._deltaOfs; + } + _actor->_seqCodeValue3 += _actor->_seqCodeValue2; + } + + if (_actor->_newFrameIndex != 0) { + debug("New frame %d", _actor->_newFrameIndex); + setActorFrameIndex(_actor->_newFrameIndex); + if (!(_actor->_flags & 1) && (_actor->_flags & 0x1000) && (_objectId != 0x40004)) { + appearActor(); + _actor->_flags &= ~0x1000; + } + } + + if (sequenceFinished) { + debug("Sequence has finished"); + _actor->_seqCodeIp = 0; + } + } void Control::startSequenceActorIntern(uint32 sequenceId, int value, int value2, uint32 notifyThreadId) { @@ -567,7 +624,7 @@ void Control::startSequenceActorIntern(uint32 sequenceId, int value, int value2, _actor->_notifyThreadId2 = notifyThreadId; } - // TODO sequenceActor(); + sequenceActor(); } @@ -672,7 +729,7 @@ void Controls::placeSequenceLessActor(uint32 objectId, Common::Point placePt, Wi control->_position.y = 0; control->_actorTypeId = 0x50004; control->_actor = actor; - // TODO actor->setControlRoutine(0); + actor->setControlRoutine(0); actor->_surfInfo._pixelSize = dimensions._width * dimensions._height; actor->_surfInfo._dimensions = dimensions; actor->createSurface(actor->_surfInfo); @@ -743,4 +800,35 @@ void Controls::destroyControl(Control *control) { delete control; } +void Controls::actorControlRouine(Control *control, uint32 deltaTime) { + //debug("Controls::actorControlRouine()"); + + Actor *actor = control->_actor; + + if (actor->_pauseCtr > 0) + return; + + if (false/*actor->_pathNode*/) { + // TODO Update pathwalking + } else { + actor->_seqCodeValue1 = 100 * deltaTime; + } + + if (actor->_flags & 4) { + int scale = actor->_scaleLayer->getScale(actor->_position); + control->setActorScale(scale); + } + + if (actor->_flags & 8) { + int16 priority = actor->_priorityLayer->getPriority(actor->_position); + if (priority) + control->setPriority(priority + 1); + } + + if (actor->_flags & 0x20) { + // TODO Update transition sequence (seems to be unused in BBDOU?) + } + +} + } // End of namespace Illusions diff --git a/engines/illusions/actor.h b/engines/illusions/actor.h index 0684ce1834..6a682c6a9e 100644 --- a/engines/illusions/actor.h +++ b/engines/illusions/actor.h @@ -27,6 +27,7 @@ #include "illusions/backgroundresource.h" #include "illusions/graphics.h" #include "common/algorithm.h" +#include "common/func.h" #include "common/list.h" #include "graphics/surface.h" @@ -64,6 +65,8 @@ protected: Common::Array<DefaultSequence> _items; }; +typedef Common::Functor2<Control*, uint32, void> ActorControlRoutine; + class Actor { public: Actor(IllusionsEngine *vm); @@ -74,6 +77,8 @@ public: void initSequenceStack(); void pushSequenceStack(int16 value); int16 popSequenceStack(); + void setControlRoutine(ActorControlRoutine *controlRoutine); + void runControlRoutine(Control *control, uint32 deltaTime); public: IllusionsEngine *_vm; byte _drawFlags; @@ -117,6 +122,8 @@ public: int _surfaceTextFlag; + ActorControlRoutine *_controlRoutine; + byte *_seqCodeIp; uint32 _sequenceId; int _seqCodeValue1; @@ -187,7 +194,8 @@ public: ~Controls(); void placeActor(uint32 actorTypeId, Common::Point placePt, uint32 sequenceId, uint32 objectId, uint32 notifyThreadId); void placeSequenceLessActor(uint32 objectId, Common::Point placePt, WidthHeight dimensions, int16 priority); - void placeActorLessObject(uint32 objectId, Common::Point feetPt, Common::Point pt, int16 priority, uint flags); + void placeActorLessObject(uint32 objectId, Common::Point feetPt, Common::Point pt, int16 priority, uint flags); + void actorControlRouine(Control *control, uint32 deltaTime); public: typedef Common::List<Control*> Items; typedef Items::iterator ItemsIterator; diff --git a/engines/illusions/actorresource.cpp b/engines/illusions/actorresource.cpp index 426fff653d..831a932b7a 100644 --- a/engines/illusions/actorresource.cpp +++ b/engines/illusions/actorresource.cpp @@ -95,6 +95,8 @@ void Sequence::load(byte *dataStart, Common::SeekableReadStream &stream) { debug(5, "Sequence::load() _sequenceId: %08X; _unk4: %d; sequenceCodeOffs: %08X", _sequenceId, _unk4, sequenceCodeOffs); + + debug("_sequenceId: %08X", _sequenceId); } void ActorType::load(byte *dataStart, Common::SeekableReadStream &stream) { @@ -125,6 +127,9 @@ void ActorType::load(byte *dataStart, Common::SeekableReadStream &stream) { _pathWalkPointsIndex, _scaleLayerIndex, _pathWalkRectIndex); debug(5, "ActorType::load() _priorityLayerIndex: %d; _regionLayerIndex: %d; _flags: %04X", _priorityLayerIndex, _regionLayerIndex,_flags); + + debug("_actorTypeId: %08X; dimensions: (%d, %d)", _actorTypeId, _surfInfo._dimensions._width, _surfInfo._dimensions._height); + } // ActorResource @@ -159,7 +164,7 @@ void ActorResource::load(byte *data, uint32 dataSize) { stream.seek(0x14); uint32 sequencesOffs = stream.readUint32LE(); stream.seek(sequencesOffs); - _actorTypes.reserve(sequencesCount); + _sequences.reserve(sequencesCount); for (uint i = 0; i < sequencesCount; ++i) { Sequence sequence; sequence.load(data, stream); @@ -172,7 +177,7 @@ void ActorResource::load(byte *data, uint32 dataSize) { stream.seek(0x18); uint32 framesOffs = stream.readUint32LE(); stream.seek(framesOffs); - _actorTypes.reserve(framesCount); + _frames.reserve(framesCount); for (uint i = 0; i < framesCount; ++i) { Frame frame; frame.load(data, stream); diff --git a/engines/illusions/backgroundresource.cpp b/engines/illusions/backgroundresource.cpp index bdce1c4669..6c7808c33e 100644 --- a/engines/illusions/backgroundresource.cpp +++ b/engines/illusions/backgroundresource.cpp @@ -173,6 +173,18 @@ void BackgroundResource::load(byte *data, uint32 dataSize) { _scaleLayers[i].load(data, stream); } + // Load priority layers + stream.seek(0x14); + _priorityLayersCount = stream.readUint16LE(); + _priorityLayers = new PriorityLayer[_priorityLayersCount]; + stream.seek(0x34); + uint32 priorityLayersOffs = stream.readUint32LE(); + debug("_priorityLayersCount: %d", _priorityLayersCount); + for (uint i = 0; i < _priorityLayersCount; ++i) { + stream.seek(priorityLayersOffs + i * 12); + _priorityLayers[i].load(data, stream); + } + } int BackgroundResource::findMasterBgIndex() { diff --git a/engines/illusions/backgroundresource.h b/engines/illusions/backgroundresource.h index de6204e94b..d3865d1c75 100644 --- a/engines/illusions/backgroundresource.h +++ b/engines/illusions/backgroundresource.h @@ -90,13 +90,13 @@ protected: #if 0 BgResource_PathWalkRects struc ; (sizeof=0x8) -count dd ? -rects dd ? +count dd ? +rects dd ? BgResource_PathWalkRects ends BgResource_PathWalkPoints struc ; (sizeof=0x8) -count dd ? -points dd ? +count dd ? +points dd ? BgResource_PathWalkPoints ends #endif diff --git a/engines/illusions/illusions.cpp b/engines/illusions/illusions.cpp index ddb4d6039e..2a92d94d35 100644 --- a/engines/illusions/illusions.cpp +++ b/engines/illusions/illusions.cpp @@ -97,6 +97,11 @@ Common::Error IllusionsEngine::run() { _camera = new Camera(this); _controls = new Controls(this); + // TODO Move to own class + _resGetCtr = 0; + _unpauseControlActorFlag = false; + _lastUpdateTime = 0; + #if 0 // ActorResource test _resSys->loadResource(0x00100006, 0, 0); @@ -134,18 +139,25 @@ Common::Error IllusionsEngine::run() { #if 1 // Actor/graphics test - _resSys->loadResource(0x00110007, 0, 0); - _resSys->loadResource(0x00100006, 0, 0); - _controls->placeActor(0x00050008, Common::Point(200, 200), 0x00060136, 0x00040001, 0); + + /* TODO 0x0010000B LinkIndex 0x00060AAB 0x00060556 + */ + + _resSys->loadResource(0x0011000B, 0, 0); + _resSys->loadResource(0x0010000B, 0, 0); + _controls->placeActor(0x00050009, Common::Point(0, 0), 0x00060573, 0x00040001, 0); Control *control = *_controls->_controls.begin(); control->setActorFrameIndex(1); control->appearActor(); //_camera->panToPoint(Common::Point(800, 0), 500, 0); while (!shouldQuit()) { + updateActors(); + updateSequences(); updateGraphics(); _screen->updateSprites(); _system->updateScreen(); updateEvents(); + _system->delayMillis(10); } #endif @@ -235,18 +247,58 @@ bool IllusionsEngine::hideCursor() { return false; } +uint32 IllusionsEngine::getElapsedUpdateTime() { + uint32 result = 0; + uint32 currTime = getCurrentTime(); + if (_resGetCtr <= 0 ) { + if (_unpauseControlActorFlag) { + _unpauseControlActorFlag = false; + result = 0; + } else { + result = currTime - _lastUpdateTime; + } + _lastUpdateTime = currTime; + } else { + result = _resGetTime - _lastUpdateTime; + _lastUpdateTime = _resGetTime; + } + return result; +} + +int IllusionsEngine::updateActors() { + // TODO Move to Controls class + uint32 deltaTime = getElapsedUpdateTime(); + //debug("deltaTime: %d", deltaTime); + for (Controls::ItemsIterator it = _controls->_controls.begin(); it != _controls->_controls.end(); ++it) { + Control *control = *it; + if (control->_pauseCtr == 0 && control->_actor && control->_actor->_controlRoutine) + control->_actor->runControlRoutine(control, deltaTime); + } + return 1; +} + +int IllusionsEngine::updateSequences() { + // TODO Move to Controls class + for (Controls::ItemsIterator it = _controls->_controls.begin(); it != _controls->_controls.end(); ++it) { + Control *control = *it; + if (control->_pauseCtr == 0 && control->_actor && control->_actor->_seqCodeIp) + control->sequenceActor(); + } + return 1; +} + int IllusionsEngine::updateGraphics() { Common::Point panPoint(0, 0); uint32 currTime = getCurrentTime(); - _camera->update(currTime); - - // TODO Move to BackgroundItems class - BackgroundItem *backgroundItem = _backgroundItems->findActiveBackground(); - if (backgroundItem) { - BackgroundResource *bgRes = backgroundItem->_bgRes; - for (uint i = 0; i < bgRes->_bgInfosCount; ++i) { - BgInfo *bgInfo = &bgRes->_bgInfos[i]; + _camera->update(currTime); + + // TODO Move to BackgroundItems class + BackgroundItem *backgroundItem = _backgroundItems->findActiveBackground(); + if (backgroundItem) { + BackgroundResource *bgRes = backgroundItem->_bgRes; + for (uint i = 0; i < bgRes->_bgInfosCount; ++i) { + BgInfo *bgInfo = &bgRes->_bgInfos[i]; // TODO int16 priority = artcntrlGetPriorityFromBase(bgInfos[v7].priorityBase); int16 priority = -1; _screen->_drawQueue->insertSurface(backgroundItem->_surfaces[i], @@ -261,11 +313,8 @@ int IllusionsEngine::updateGraphics() { Control *control = *it; Actor *actor = control->_actor; - debug("control->_pauseCtr: %d; actor->_flags: %04X", control->_pauseCtr, actor->_flags); - if (control->_pauseCtr == 0 && actor && (actor->_flags & 1) && !(actor->_flags & 0x0200)) { Common::Point drawPosition = control->calcPosition(panPoint); - debug("drawPosition: %d, %d", drawPosition.x, drawPosition.y); if (actor->_flags & 0x2000) { Frame *frame = &(*actor->_frames)[actor->_frameIndex - 1]; _screen->_decompressQueue->insert(&actor->_drawFlags, frame->_flags, @@ -296,8 +345,17 @@ int IllusionsEngine::updateGraphics() { _textInfo._position, priority); } #endif - + return 1; } +int IllusionsEngine::getRandom(int max) { + return _random->getRandomNumber(max - 1); +} + +int IllusionsEngine::convertPanXCoord(int16 x) { + // TODO + return 0; +} + } // End of namespace Illusions diff --git a/engines/illusions/illusions.h b/engines/illusions/illusions.h index d262690a7f..33e0a70ff1 100644 --- a/engines/illusions/illusions.h +++ b/engines/illusions/illusions.h @@ -91,6 +91,11 @@ public: BackgroundItems *_backgroundItems; Camera *_camera; Controls *_controls; + + int _resGetCtr; + uint32 _resGetTime; + bool _unpauseControlActorFlag; + uint32 _lastUpdateTime; Common::Point *getObjectActorPositionPtr(uint32 objectId); @@ -100,7 +105,12 @@ public: void placeCursor(Control *control, uint32 sequenceId); bool showCursor(); bool hideCursor(); + uint32 getElapsedUpdateTime(); + int updateActors(); + int updateSequences(); int updateGraphics(); + int getRandom(int max); + int convertPanXCoord(int16 x); #if 0 diff --git a/engines/illusions/sequenceopcodes.cpp b/engines/illusions/sequenceopcodes.cpp index 22845f0944..e19d8cdf7d 100644 --- a/engines/illusions/sequenceopcodes.cpp +++ b/engines/illusions/sequenceopcodes.cpp @@ -46,7 +46,7 @@ void SequenceOpcodes::execOpcode(Control *control, OpCall &opCall) { (*_opcodes[opCall._op])(control, opCall); } -typedef Common::Functor2Mem<ScriptThread*, OpCall&, void, SequenceOpcodes> SequenceOpcodeI; +typedef Common::Functor2Mem<Control*, OpCall&, void, SequenceOpcodes> SequenceOpcodeI; #define OPCODE(op, func) _opcodes[op] = new SequenceOpcodeI(this, &SequenceOpcodes::func); void SequenceOpcodes::initOpcodes() { @@ -54,7 +54,24 @@ void SequenceOpcodes::initOpcodes() { for (uint i = 0; i < 256; ++i) _opcodes[i] = 0; // Register opcodes - //OPCODE(42, opIncBlockCounter); + OPCODE(2, opSetFrameIndex); + OPCODE(3, opEndSequence); + OPCODE(5, opSetRandomFrameDelay); + OPCODE(6, opSetFrameSpeed); + OPCODE(7, opJump); + OPCODE(9, opGotoSequence); + OPCODE(11, opBeginLoop); + OPCODE(12, opNextLoop); + OPCODE(15, opJumpIfNotFacing); + OPCODE(28, opNotifyThreadId1); + OPCODE(29, opSetPathCtrY); + OPCODE(33, opSetPathWalkPoints); + OPCODE(36, opSetScaleLayer); + OPCODE(38, opSetPathWalkRects); + OPCODE(39, opSetPriority); + OPCODE(40, opSetPriorityLayer); + OPCODE(50, opPlaySound); + OPCODE(51, opStopSound); } #undef OPCODE @@ -69,6 +86,165 @@ void SequenceOpcodes::freeOpcodes() { // Convenience macros #define ARG_SKIP(x) opCall.skip(x); #define ARG_INT16(name) int16 name = opCall.readSint16(); debug("ARG_INT16(" #name " = %d)", name); -#define ARG_UINT32(name) uint32 name = opCall.readUint32(); debug("ARG_UINT32(" #name " = %d)", name); +#define ARG_UINT32(name) uint32 name = opCall.readUint32(); debug("ARG_UINT32(" #name " = %08X)", name); + +void SequenceOpcodes::opSetFrameIndex(Control *control, OpCall &opCall) { + ARG_INT16(frameIndex); + if (control->_actor->_flags & 0x80) { + debug("opSetFrameIndex TODO"); + /* TODO + v9 = actor->field30; + if (*(_WORD *)v9) { + LOWORD(flag) = *(_WORD *)v9; + v6 = v6 + flag - 1; + actor->field30 = v9 + 2; + } else { + actor->flags &= 0xFF7Fu; + v10 = actor->notifyThreadId1; + actor->field30 = 0; + actor->notifyThreadId2 = 0; + if (v10) { + actor->notifyThreadId1 = 0; + ThreadList_notifyId__(v10); + } + actorDead = 1; + breakInner = 1; + } + */ + } + control->_actor->_flags &= ~0x0100; + if (control->_actor->_flags & 0x8000) { + control->appearActor(); + control->_actor->_flags &= ~0x800; + } + control->_actor->_newFrameIndex = frameIndex; +} + +void SequenceOpcodes::opEndSequence(Control *control, OpCall &opCall) { + control->_actor->_seqCodeIp = 0; + if (control->_actor->_flags & 0x0800) { + control->_actor->_flags &= ~0x0800; + control->_actor->_frames = 0; + control->_actor->_frameIndex = 0; + control->_actor->_newFrameIndex = 0; + // TODO _vm->_resSys->unloadResourceById(control->_actor->_sequenceId); + } + _vm->notifyThreadId(control->_actor->_notifyThreadId1); + opCall._result = 1; +} + +void SequenceOpcodes::opSetRandomFrameDelay(Control *control, OpCall &opCall) { + ARG_INT16(minFrameDelay); + ARG_INT16(maxFrameDelay); + control->_actor->_seqCodeValue3 += 0;//DEBUG minFrameDelay + _vm->getRandom(maxFrameDelay); +} + +void SequenceOpcodes::opSetFrameSpeed(Control *control, OpCall &opCall) { + ARG_INT16(frameSpeed); + control->_actor->_seqCodeValue2 = frameSpeed; +} + +void SequenceOpcodes::opJump(Control *control, OpCall &opCall) { + ARG_INT16(jumpOffs); + opCall._deltaOfs += jumpOffs; +} + +void SequenceOpcodes::opGotoSequence(Control *control, OpCall &opCall) { + ARG_SKIP(2); + ARG_UINT32(nextSequenceId); + uint32 notifyThreadId1 = control->_actor->_notifyThreadId1; + control->clearNotifyThreadId1(); + if (false/*TODO control->_actor->_pathNode*/) { + control->startSequenceActor(nextSequenceId, 1, notifyThreadId1); + } else { + control->startSequenceActor(nextSequenceId, 2, notifyThreadId1); + } + opCall._deltaOfs = 0; +} + +void SequenceOpcodes::opBeginLoop(Control *control, OpCall &opCall) { + ARG_INT16(loopCount); + control->_actor->pushSequenceStack(loopCount); +} + +void SequenceOpcodes::opNextLoop(Control *control, OpCall &opCall) { + ARG_INT16(jumpOffs); + int16 currLoopCount = control->_actor->popSequenceStack(); + if (currLoopCount > 0) { + control->_actor->pushSequenceStack(currLoopCount - 1); + opCall._deltaOfs = -jumpOffs; + } +} + +void SequenceOpcodes::opJumpIfNotFacing(Control *control, OpCall &opCall) { + ARG_INT16(facing); + ARG_INT16(jumpOffs); + if (!(control->_actor->_facing & facing)) + opCall._deltaOfs += jumpOffs; +} + +void SequenceOpcodes::opNotifyThreadId1(Control *control, OpCall &opCall) { + _vm->notifyThreadId(control->_actor->_notifyThreadId1); +} + +void SequenceOpcodes::opSetPathCtrY(Control *control, OpCall &opCall) { + ARG_INT16(pathCtrY); + control->_actor->_pathCtrY = pathCtrY; +} + +void SequenceOpcodes::opSetPathWalkPoints(Control *control, OpCall &opCall) { + ARG_INT16(pathWalkPointsIndex); + BackgroundResource *bgRes = _vm->_backgroundItems->getActiveBgResource(); + control->_actor->_flags |= 2; + // TODO control->_actor->_pathWalkPoints = bgRes->getPathWalkPoints(pathWalkPointsIndex - 1); +} + +void SequenceOpcodes::opSetScaleLayer(Control *control, OpCall &opCall) { + ARG_INT16(scaleLayerIndex); + BackgroundResource *bgRes = _vm->_backgroundItems->getActiveBgResource(); + control->_actor->_flags |= 4; + control->_actor->_scaleLayer = bgRes->getScaleLayer(scaleLayerIndex - 1); + int scale = control->_actor->_scaleLayer->getScale(control->_actor->_position); + control->setActorScale(scale); +} + +void SequenceOpcodes::opSetPathWalkRects(Control *control, OpCall &opCall) { + ARG_INT16(pathWalkRectsIndex); + BackgroundResource *bgRes = _vm->_backgroundItems->getActiveBgResource(); + control->_actor->_flags |= 0x10; + // TODO control->_actor->_pathWalkRects = bgRes->getPathWalkRects(pathWalkRectsIndex - 1); +} + +void SequenceOpcodes::opSetPriority(Control *control, OpCall &opCall) { + ARG_INT16(priority); + control->_actor->_flags &= ~8; + control->setPriority(priority); +} + +void SequenceOpcodes::opSetPriorityLayer(Control *control, OpCall &opCall) { + ARG_INT16(priorityLayerIndex); + BackgroundResource *bgRes = _vm->_backgroundItems->getActiveBgResource(); + control->_actor->_flags |= 8; + control->_actor->_priorityLayer = bgRes->getPriorityLayer(priorityLayerIndex - 1); + int priority = control->_actor->_priorityLayer->getPriority(control->_actor->_position); + control->setPriority(priority); +} + +void SequenceOpcodes::opPlaySound(Control *control, OpCall &opCall) { + ARG_INT16(flags); + ARG_INT16(volume); + ARG_INT16(pan); + ARG_UINT32(soundEffectId); + if (!(flags & 1)) + volume = 255; + if (!(flags & 2)) + pan = _vm->convertPanXCoord(control->_actor->_position.x); + // TODO _vm->startSound(soundEffectId, volume, pan); +} + +void SequenceOpcodes::opStopSound(Control *control, OpCall &opCall) { + ARG_UINT32(soundEffectId); + // TODO _vm->stopSound(soundEffectId); +} } // End of namespace Illusions diff --git a/engines/illusions/sequenceopcodes.h b/engines/illusions/sequenceopcodes.h index aa31a76176..366fbba6b7 100644 --- a/engines/illusions/sequenceopcodes.h +++ b/engines/illusions/sequenceopcodes.h @@ -44,7 +44,25 @@ protected: void initOpcodes(); void freeOpcodes(); - // Opcodes + // Opcodes + void opSetFrameIndex(Control *control, OpCall &opCall); + void opEndSequence(Control *control, OpCall &opCall); + void opSetRandomFrameDelay(Control *control, OpCall &opCall); + void opSetFrameSpeed(Control *control, OpCall &opCall); + void opJump(Control *control, OpCall &opCall); + void opGotoSequence(Control *control, OpCall &opCall); + void opBeginLoop(Control *control, OpCall &opCall); + void opNextLoop(Control *control, OpCall &opCall); + void opJumpIfNotFacing(Control *control, OpCall &opCall); + void opNotifyThreadId1(Control *control, OpCall &opCall); + void opSetPathCtrY(Control *control, OpCall &opCall); + void opSetPathWalkPoints(Control *control, OpCall &opCall); + void opSetScaleLayer(Control *control, OpCall &opCall); + void opSetPathWalkRects(Control *control, OpCall &opCall); + void opSetPriority(Control *control, OpCall &opCall); + void opSetPriorityLayer(Control *control, OpCall &opCall); + void opPlaySound(Control *control, OpCall &opCall); + void opStopSound(Control *control, OpCall &opCall); }; diff --git a/engines/illusions/spritedecompressqueue.cpp b/engines/illusions/spritedecompressqueue.cpp index acb4547a76..c20b0dba28 100644 --- a/engines/illusions/spritedecompressqueue.cpp +++ b/engines/illusions/spritedecompressqueue.cpp @@ -55,11 +55,20 @@ void SpriteDecompressQueue::decompressAll() { void SpriteDecompressQueue::decompress(SpriteDecompressQueueItem *item) { byte *src = item->_compressedPixels; Graphics::Surface *dstSurface = item->_surface; - int dstSize = item->_dimensions._height * item->_dimensions._width; + int dstSize = item->_dimensions._width * item->_dimensions._height; int processedSize = 0; int xincr, x, xstart; int yincr, y; - + + // Safeguard + if (item->_dimensions._width > item->_surface->w || + item->_dimensions._height > item->_surface->h) { + debug("Incorrect frame dimensions (%d, %d <> %d, %d)", + item->_dimensions._width, item->_dimensions._height, + item->_surface->w, item->_surface->h); + return; + } + if (item->_flags & 1) { x = xstart = item->_dimensions._width - 1; xincr = -1; |