Implemented support for VMDs substituting object animations.
Still far from being complete (and correct), but it's a start... - Only VMD "command" -3 is followed - Not all animation types are working - Timing is still off in most cases - Offsets are generally OK, but not always - No sound yet - Shouldn't segfault randomly, but I'm not entirely sure ;) svn-id: r31750
This commit is contained in:
parent
1d167da633
commit
ab1a3b0cc8
18 changed files with 1355 additions and 197 deletions
|
@ -333,41 +333,44 @@ void Imd::waitEndFrame() {
|
||||||
g_system->delayMillis(_frameLength);
|
g_system->delayMillis(_frameLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Imd::copyCurrentFrame(byte *dest, uint16 x, uint16 y, uint16 width, int16 transp) {
|
void Imd::copyCurrentFrame(byte *dest,
|
||||||
|
uint16 left, uint16 top, uint16 width, uint16 height,
|
||||||
|
uint16 x, uint16 y, uint16 pitch, int16 transp) {
|
||||||
|
|
||||||
if (!_vidMem)
|
if (!_vidMem)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dest += width * y;
|
if (((left + width) > _width) || ((top + height) > _height))
|
||||||
|
return;
|
||||||
|
|
||||||
uint16 copyWidth = MIN<int16>(width - x, _width);
|
dest += pitch * y;
|
||||||
uint16 destPitch = width - x;
|
byte *vidMem = _vidMem + _width * top;
|
||||||
byte *vidMem = _vidMem;
|
|
||||||
|
|
||||||
if (transp < 0) {
|
if (transp < 0) {
|
||||||
// No transparency
|
// No transparency
|
||||||
if ((x > 0) || (_width != width)) {
|
if ((x > 0) || (left > 0) || (pitch != _width) || (width != _width)) {
|
||||||
// Copy row-by-row
|
// Copy row-by-row
|
||||||
for (int i = 0; i < _height; i++) {
|
for (int i = 0; i < height; i++) {
|
||||||
dest += x;
|
byte *d = dest + x;
|
||||||
memcpy(dest, vidMem, copyWidth);
|
byte *s = vidMem + left;
|
||||||
dest += destPitch;
|
|
||||||
|
memcpy(d, s, width);
|
||||||
|
|
||||||
|
dest += pitch;
|
||||||
vidMem += _width;
|
vidMem += _width;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else
|
} else
|
||||||
// Dimensions fit, copy everything at once
|
// Dimensions fit, copy everything at once
|
||||||
memcpy(dest, _vidMem, _width * _height);
|
memcpy(dest, vidMem, width * height);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transparency, copy per pixel
|
for (int i = 0; i < height; i++) {
|
||||||
for (int i = 0; i < _height; i++) {
|
byte *d = dest + x;
|
||||||
byte *s = vidMem;
|
byte *s = vidMem + left;
|
||||||
byte *d = dest;
|
|
||||||
|
|
||||||
d += x;
|
for (int j = 0; j < width; j++) {
|
||||||
for (int j = 0; j < _width; j++) {
|
|
||||||
if (*s != transp)
|
if (*s != transp)
|
||||||
*d = *s;
|
*d = *s;
|
||||||
|
|
||||||
|
@ -375,9 +378,10 @@ void Imd::copyCurrentFrame(byte *dest, uint16 x, uint16 y, uint16 width, int16 t
|
||||||
d++;
|
d++;
|
||||||
}
|
}
|
||||||
|
|
||||||
dest += width;
|
dest += pitch;
|
||||||
vidMem += _width;
|
vidMem += _width;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Imd::deleteVidMem(bool del) {
|
void Imd::deleteVidMem(bool del) {
|
||||||
|
@ -938,9 +942,9 @@ bool Vmd::load(Common::SeekableReadStream &stream) {
|
||||||
} else
|
} else
|
||||||
_frameLength = 1000 / _frameRate;
|
_frameLength = 1000 / _frameRate;
|
||||||
|
|
||||||
uint32 frameInfoOffset = _stream->readUint32LE();
|
_frameInfoOffset = _stream->readUint32LE();
|
||||||
|
|
||||||
_stream->seek(frameInfoOffset);
|
_stream->seek(_frameInfoOffset);
|
||||||
_frames = new Frame[_framesCount];
|
_frames = new Frame[_framesCount];
|
||||||
for (uint16 i = 0; i < _framesCount; i++) {
|
for (uint16 i = 0; i < _framesCount; i++) {
|
||||||
_frames[i].parts = new Part[_partsPerFrame];
|
_frames[i].parts = new Part[_partsPerFrame];
|
||||||
|
@ -1350,4 +1354,43 @@ void Vmd::deDPCM(byte *soundBuf, byte *dataBuf, int16 &init, uint32 n) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Vmd::getAnchor(int16 frame, uint16 partType,
|
||||||
|
int16 &x, int16 &y, int16 &width, int16 &height) {
|
||||||
|
|
||||||
|
uint32 pos = _stream->pos();
|
||||||
|
|
||||||
|
_stream->seek(_frameInfoOffset);
|
||||||
|
// Offsets to frames
|
||||||
|
_stream->skip(_framesCount * 6);
|
||||||
|
// Jump to the specified frame
|
||||||
|
_stream->skip(_partsPerFrame * frame * 16);
|
||||||
|
|
||||||
|
// Find the anchor part
|
||||||
|
uint16 i;
|
||||||
|
for (i = 0; i < _partsPerFrame; i++) {
|
||||||
|
byte type = _stream->readByte();
|
||||||
|
|
||||||
|
if ((type == 0) || (type == partType))
|
||||||
|
break;
|
||||||
|
|
||||||
|
_stream->skip(15);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == _partsPerFrame) {
|
||||||
|
// No anchor
|
||||||
|
|
||||||
|
_stream->seek(pos);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_stream->skip(5);
|
||||||
|
x = _stream->readSint16LE();
|
||||||
|
y = _stream->readSint16LE();
|
||||||
|
width = _stream->readSint16LE() - x + 1;
|
||||||
|
height = _stream->readSint16LE() - y + 1;
|
||||||
|
|
||||||
|
_stream->seek(pos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace Gob
|
} // End of namespace Gob
|
||||||
|
|
|
@ -90,6 +90,8 @@ public:
|
||||||
|
|
||||||
/** Returns the features the loaded video possesses. */
|
/** Returns the features the loaded video possesses. */
|
||||||
virtual uint16 getFeatures() const = 0;
|
virtual uint16 getFeatures() const = 0;
|
||||||
|
/** Returns the flags the loaded video possesses. */
|
||||||
|
virtual uint16 getFlags() const = 0;
|
||||||
/** Returns the x coordinate of the video. */
|
/** Returns the x coordinate of the video. */
|
||||||
virtual int16 getX() const = 0;
|
virtual int16 getX() const = 0;
|
||||||
/** Returns the y coordinate of the video. */
|
/** Returns the y coordinate of the video. */
|
||||||
|
@ -113,6 +115,10 @@ public:
|
||||||
/** Returns the current frame's palette. */
|
/** Returns the current frame's palette. */
|
||||||
virtual const byte *getPalette() const = 0;
|
virtual const byte *getPalette() const = 0;
|
||||||
|
|
||||||
|
/** Reads the video's anchor pointer */
|
||||||
|
virtual bool getAnchor(int16 frame, uint16 partType,
|
||||||
|
int16 &x, int16 &y, int16 &width, int16 &height) = 0;
|
||||||
|
|
||||||
/** Load a video out of a stream. */
|
/** Load a video out of a stream. */
|
||||||
virtual bool load(Common::SeekableReadStream &stream) = 0;
|
virtual bool load(Common::SeekableReadStream &stream) = 0;
|
||||||
/** Unload the currently loaded video. */
|
/** Unload the currently loaded video. */
|
||||||
|
@ -148,13 +154,19 @@ public:
|
||||||
|
|
||||||
/** Copy the current frame.
|
/** Copy the current frame.
|
||||||
*
|
*
|
||||||
* @param dest The memory to which to copy the current frame
|
* @param dest The memory to which to copy the current frame.
|
||||||
|
* @param left The x position within the frame.
|
||||||
|
* @param top The y position within the frame.
|
||||||
|
* @param width The width of the area to copy.
|
||||||
|
* @param height The height of the area to copy.
|
||||||
* @param x The x position to where to copy.
|
* @param x The x position to where to copy.
|
||||||
* @param y The y position to where to copy.
|
* @param y The y position to where to copy.
|
||||||
* @param pitch The buffer's width.
|
* @param pitch The buffer's width.
|
||||||
* @param transp Which color should be seen as transparent?
|
* @param transp Which color should be seen as transparent?
|
||||||
*/
|
*/
|
||||||
virtual void copyCurrentFrame(byte *dest, uint16 x, uint16 y, uint16 width, int16 transp = -1) = 0;
|
virtual void copyCurrentFrame(byte *dest,
|
||||||
|
uint16 left, uint16 top, uint16 width, uint16 height,
|
||||||
|
uint16 x, uint16 y, uint16 pitch, int16 transp = -1) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Coktel Vision's IMD files.
|
/** Coktel Vision's IMD files.
|
||||||
|
@ -165,6 +177,7 @@ public:
|
||||||
~Imd();
|
~Imd();
|
||||||
|
|
||||||
uint16 getFeatures() const { return _features; }
|
uint16 getFeatures() const { return _features; }
|
||||||
|
uint16 getFlags() const { return _flags; }
|
||||||
int16 getX() const { return _x; }
|
int16 getX() const { return _x; }
|
||||||
int16 getY() const { return _y; }
|
int16 getY() const { return _y; }
|
||||||
int16 getWidth() const { return _width; }
|
int16 getWidth() const { return _width; }
|
||||||
|
@ -175,6 +188,9 @@ public:
|
||||||
uint32 getSyncLag() const { return _skipFrames; }
|
uint32 getSyncLag() const { return _skipFrames; }
|
||||||
const byte *getPalette() const { return _palette; }
|
const byte *getPalette() const { return _palette; }
|
||||||
|
|
||||||
|
bool getAnchor(int16 frame, uint16 partType,
|
||||||
|
int16 &x, int16 &y, int16 &width, int16 &height) { return false; }
|
||||||
|
|
||||||
void setFrameRate(int16 frameRate);
|
void setFrameRate(int16 frameRate);
|
||||||
|
|
||||||
bool load(Common::SeekableReadStream &stream);
|
bool load(Common::SeekableReadStream &stream);
|
||||||
|
@ -192,7 +208,9 @@ public:
|
||||||
State nextFrame();
|
State nextFrame();
|
||||||
void waitEndFrame();
|
void waitEndFrame();
|
||||||
|
|
||||||
void copyCurrentFrame(byte *dest, uint16 x, uint16 y, uint16 width, int16 transp = -1);
|
void copyCurrentFrame(byte *dest,
|
||||||
|
uint16 left, uint16 top, uint16 width, uint16 height,
|
||||||
|
uint16 x, uint16 y, uint16 pitch, int16 transp = -1);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
struct Coord {
|
struct Coord {
|
||||||
|
@ -260,6 +278,9 @@ public:
|
||||||
Vmd();
|
Vmd();
|
||||||
~Vmd();
|
~Vmd();
|
||||||
|
|
||||||
|
bool getAnchor(int16 frame, uint16 partType,
|
||||||
|
int16 &x, int16 &y, int16 &width, int16 &height);
|
||||||
|
|
||||||
bool load(Common::SeekableReadStream &stream);
|
bool load(Common::SeekableReadStream &stream);
|
||||||
void unload();
|
void unload();
|
||||||
|
|
||||||
|
@ -295,6 +316,7 @@ protected:
|
||||||
|
|
||||||
bool _hasVideo;
|
bool _hasVideo;
|
||||||
|
|
||||||
|
uint32 _frameInfoOffset;
|
||||||
uint16 _partsPerFrame;
|
uint16 _partsPerFrame;
|
||||||
Frame *_frames;
|
Frame *_frames;
|
||||||
|
|
||||||
|
|
|
@ -272,7 +272,7 @@ void Game_v2::playTot(int16 skipPlay) {
|
||||||
_vm->_snd->freeSample(_soundSamples[i]);
|
_vm->_snd->freeSample(_soundSamples[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
_vm->_vidPlayer->closeVideo();
|
_vm->_vidPlayer->primaryClose();
|
||||||
if (_totToLoad[0] == 0)
|
if (_totToLoad[0] == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -315,6 +315,20 @@ protected:
|
||||||
virtual void advMovement(Mult::Mult_Object *obj, int8 state);
|
virtual void advMovement(Mult::Mult_Object *obj, int8 state);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class Goblin_v4 : public Goblin_v3 {
|
||||||
|
public:
|
||||||
|
virtual void movePathFind(Mult::Mult_Object *obj,
|
||||||
|
Gob_Object *gobDesc, int16 nextAct);
|
||||||
|
virtual void moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc,
|
||||||
|
int16 nextAct, int16 framesCount);
|
||||||
|
|
||||||
|
Goblin_v4(GobEngine *vm);
|
||||||
|
virtual ~Goblin_v4() {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int16 sub_20430(int16 state, uint16 dir);
|
||||||
|
};
|
||||||
|
|
||||||
} // End of namespace Gob
|
} // End of namespace Gob
|
||||||
|
|
||||||
#endif // GOB_GOBLIN_H
|
#endif // GOB_GOBLIN_H
|
||||||
|
|
|
@ -266,7 +266,7 @@ void Goblin_v2::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16
|
||||||
if (_vm->_map->_screenWidth == 640) {
|
if (_vm->_map->_screenWidth == 640) {
|
||||||
if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10)
|
if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10)
|
||||||
animData->nextState = 41;
|
animData->nextState = 41;
|
||||||
if (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY + 2) != 10)
|
if (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY) != 10)
|
||||||
animData->nextState = 7;
|
animData->nextState = 7;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
635
engines/gob/goblin_v4.cpp
Normal file
635
engines/gob/goblin_v4.cpp
Normal file
|
@ -0,0 +1,635 @@
|
||||||
|
/* 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 2
|
||||||
|
* 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, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "gob/gob.h"
|
||||||
|
#include "gob/goblin.h"
|
||||||
|
#include "gob/global.h"
|
||||||
|
#include "gob/mult.h"
|
||||||
|
#include "gob/map.h"
|
||||||
|
#include "gob/scenery.h"
|
||||||
|
|
||||||
|
namespace Gob {
|
||||||
|
|
||||||
|
Goblin_v4::Goblin_v4(GobEngine *vm) : Goblin_v3(vm) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Goblin_v4::movePathFind(Mult::Mult_Object *obj, Gob_Object *gobDesc, int16 nextAct) {
|
||||||
|
Mult::Mult_AnimData *animData;
|
||||||
|
int16 framesCount;
|
||||||
|
int16 gobX;
|
||||||
|
int16 gobY;
|
||||||
|
int16 gobDestX;
|
||||||
|
int16 gobDestY;
|
||||||
|
int16 destX;
|
||||||
|
int16 destY;
|
||||||
|
int16 dir;
|
||||||
|
|
||||||
|
dir = 0;
|
||||||
|
animData = obj->pAnimData;
|
||||||
|
framesCount = _vm->_scenery->getAnimLayer(animData->animation, animData->layer)->framesCount;
|
||||||
|
animData->newCycle = framesCount;
|
||||||
|
gobX = obj->goblinX;
|
||||||
|
gobY = obj->goblinY;
|
||||||
|
animData->order = gobY;
|
||||||
|
gobDestX = obj->gobDestX;
|
||||||
|
gobDestY = obj->gobDestY;
|
||||||
|
animData->destX = gobDestX;
|
||||||
|
animData->destY = gobDestY;
|
||||||
|
destX = obj->destX;
|
||||||
|
destY = obj->destY;
|
||||||
|
|
||||||
|
if (animData->pathExistence == 1) {
|
||||||
|
dir = _vm->_map->getDirection(gobX, gobY, destX, destY);
|
||||||
|
if (dir == 0)
|
||||||
|
animData->pathExistence = 0;
|
||||||
|
if ((gobX == destX) && (gobY == destY))
|
||||||
|
animData->pathExistence = 4;
|
||||||
|
} else if (animData->pathExistence == 3) {
|
||||||
|
if ((gobX == gobDestX) && (gobY == gobDestY)) {
|
||||||
|
animData->pathExistence = 4;
|
||||||
|
destX = gobDestX;
|
||||||
|
destY = gobDestY;
|
||||||
|
} else {
|
||||||
|
if (_vm->_map->checkDirectPath(obj, gobX, gobY, gobDestX, gobDestY) != 1) {
|
||||||
|
if ((gobX == destX) && (gobY == destY)) {
|
||||||
|
if (obj->nearestWayPoint > obj->nearestDest) {
|
||||||
|
_vm->_map->optimizePoints(obj, gobX, gobY);
|
||||||
|
destX = _vm->_map->_wayPoints[obj->nearestWayPoint].x;
|
||||||
|
destY = _vm->_map->_wayPoints[obj->nearestWayPoint].y;
|
||||||
|
if (_vm->_map->checkDirectPath(obj, gobX, gobY, destX, destY) == 3) {
|
||||||
|
WRITE_VAR(56, 1);
|
||||||
|
animData->pathExistence = 0;
|
||||||
|
}
|
||||||
|
if (obj->nearestWayPoint > obj->nearestDest)
|
||||||
|
obj->nearestWayPoint--;
|
||||||
|
} else if (obj->nearestWayPoint < obj->nearestDest) {
|
||||||
|
_vm->_map->optimizePoints(obj, gobX, gobY);
|
||||||
|
destX = _vm->_map->_wayPoints[obj->nearestWayPoint].x;
|
||||||
|
destY = _vm->_map->_wayPoints[obj->nearestWayPoint].y;
|
||||||
|
if (_vm->_map->checkDirectPath(obj, gobX, gobY, destX, destY) == 3) {
|
||||||
|
WRITE_VAR(56, 1);
|
||||||
|
animData->pathExistence = 0;
|
||||||
|
}
|
||||||
|
if (obj->nearestWayPoint < obj->nearestDest)
|
||||||
|
obj->nearestWayPoint++;
|
||||||
|
} else {
|
||||||
|
if ((_vm->_map->checkDirectPath(obj, gobX, gobY, gobDestX, gobDestY) == 3) &&
|
||||||
|
(_vm->_map->getPass(gobDestX, gobDestY) != 0)) {
|
||||||
|
destX = _vm->_map->_wayPoints[obj->nearestWayPoint].x;
|
||||||
|
destY = _vm->_map->_wayPoints[obj->nearestWayPoint].y;
|
||||||
|
WRITE_VAR(56, 1);
|
||||||
|
} else {
|
||||||
|
animData->pathExistence = 1;
|
||||||
|
destX = gobDestX;
|
||||||
|
destY = gobDestY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
destX = gobDestX;
|
||||||
|
destY = gobDestY;
|
||||||
|
}
|
||||||
|
dir = _vm->_map->getDirection(gobX, gobY, destX, destY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
obj->goblinX = gobX;
|
||||||
|
obj->goblinY = gobY;
|
||||||
|
obj->gobDestX = gobDestX;
|
||||||
|
obj->gobDestY = gobDestY;
|
||||||
|
obj->destX = destX;
|
||||||
|
obj->destY = destY;
|
||||||
|
|
||||||
|
if (_vm->_map->_widthByte == 4) {
|
||||||
|
switch (dir) {
|
||||||
|
case Map::kDirNW:
|
||||||
|
animData->nextState = sub_20430(animData->state, Map::kDirNW);
|
||||||
|
if ((_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10) &&
|
||||||
|
(animData->nextState == 1))
|
||||||
|
animData->nextState = 40;
|
||||||
|
if (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY - 2) != 10)
|
||||||
|
animData->nextState = sub_20430(animData->state, Map::kDirNW);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirN:
|
||||||
|
animData->nextState =
|
||||||
|
(animData->curLookDir == 2) ? 2 : sub_20430(animData->state, Map::kDirN);
|
||||||
|
if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10) {
|
||||||
|
if (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY - 2) != 10) {
|
||||||
|
if (_vm->_map->getPass(obj->goblinX + 1, obj->goblinY - 2) == 10)
|
||||||
|
animData->nextState = 42;
|
||||||
|
else
|
||||||
|
animData->nextState = 2;
|
||||||
|
} else
|
||||||
|
animData->nextState = 40;
|
||||||
|
}
|
||||||
|
if ((_vm->_map->getPass(obj->goblinX, obj->goblinY) == 20) &&
|
||||||
|
(animData->nextState == 2))
|
||||||
|
animData->nextState = 38;
|
||||||
|
if ((_vm->_map->getPass(obj->goblinX, obj->goblinY) == 19) &&
|
||||||
|
(animData->nextState == 2))
|
||||||
|
animData->nextState = 26;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirNE:
|
||||||
|
animData->nextState = sub_20430(animData->state, Map::kDirNE);
|
||||||
|
if ((_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10) &&
|
||||||
|
(animData->nextState == 3))
|
||||||
|
animData->nextState = 42;
|
||||||
|
if (_vm->_map->getPass(obj->goblinX + 1, obj->goblinY - 2) != 10)
|
||||||
|
animData->nextState = sub_20430(animData->state, Map::kDirNE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirW:
|
||||||
|
animData->nextState = sub_20430(animData->state, Map::kDirW);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirE:
|
||||||
|
animData->nextState = sub_20430(animData->state, Map::kDirE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirSW:
|
||||||
|
animData->nextState = sub_20430(animData->state, Map::kDirSW);
|
||||||
|
if ((_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10) &&
|
||||||
|
(animData->nextState == 7))
|
||||||
|
animData->nextState = 41;
|
||||||
|
if (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY) != 10)
|
||||||
|
animData->nextState = sub_20430(animData->state, Map::kDirSW);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirS:
|
||||||
|
animData->nextState =
|
||||||
|
(animData->curLookDir == 6) ? 6 : sub_20430(animData->state, Map::kDirS);
|
||||||
|
if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10) {
|
||||||
|
if (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY + 2) != 10) {
|
||||||
|
if (_vm->_map->getPass(obj->goblinX + 1, obj->goblinY + 2) == 10)
|
||||||
|
animData->nextState = 43;
|
||||||
|
else
|
||||||
|
animData->nextState = 6;
|
||||||
|
} else
|
||||||
|
animData->nextState = 41;
|
||||||
|
}
|
||||||
|
// loc_20AAD
|
||||||
|
if ((_vm->_map->getPass(obj->goblinX, obj->goblinY) == 20) &&
|
||||||
|
(animData->nextState == 6))
|
||||||
|
animData->nextState = 39;
|
||||||
|
if ((_vm->_map->getPass(obj->goblinX, obj->goblinY) == 19) &&
|
||||||
|
(animData->nextState == 6))
|
||||||
|
animData->nextState = 27;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirSE:
|
||||||
|
animData->nextState = sub_20430(animData->state, Map::kDirSE);
|
||||||
|
if ((_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10) &&
|
||||||
|
(animData->nextState == 5))
|
||||||
|
animData->nextState = 43;
|
||||||
|
if (_vm->_map->getPass(obj->goblinX + 1, obj->goblinY) != 10)
|
||||||
|
animData->nextState = sub_20430(animData->state, Map::kDirSE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// loc_20D18
|
||||||
|
switch (animData->state) {
|
||||||
|
case 0:
|
||||||
|
case 8:
|
||||||
|
// loc_21134
|
||||||
|
animData->nextState = 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
case 10:
|
||||||
|
case 40:
|
||||||
|
// loc_21152
|
||||||
|
animData->nextState = 10;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
case 29:
|
||||||
|
// loc_2113E
|
||||||
|
animData->nextState = 29;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
case 11:
|
||||||
|
case 42:
|
||||||
|
// loc_2115C
|
||||||
|
animData->nextState = 11;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
case 9:
|
||||||
|
// loc_2112A
|
||||||
|
animData->nextState = 9;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
case 30:
|
||||||
|
case 43:
|
||||||
|
// loc_21166
|
||||||
|
animData->nextState = 30;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
case 28:
|
||||||
|
// loc_21148
|
||||||
|
animData->nextState = 28;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
case 31:
|
||||||
|
case 41:
|
||||||
|
// loc_21170
|
||||||
|
animData->nextState = 31;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
switch (dir) {
|
||||||
|
case Map::kDirNW:
|
||||||
|
animData->nextState = 1;
|
||||||
|
if (_vm->_map->_screenWidth == 640) {
|
||||||
|
if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10)
|
||||||
|
animData->nextState = 40;
|
||||||
|
if (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY - 2) != 10)
|
||||||
|
animData->nextState = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirN:
|
||||||
|
animData->nextState =
|
||||||
|
(animData->curLookDir == 2) ? 2 : rotateState(animData->curLookDir, 2);
|
||||||
|
if (_vm->_map->_screenWidth == 640) {
|
||||||
|
if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10) {
|
||||||
|
if (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY - 2) != 10) {
|
||||||
|
if (_vm->_map->getPass(obj->goblinX + 1, obj->goblinY - 2) == 10)
|
||||||
|
animData->nextState = 42;
|
||||||
|
else
|
||||||
|
animData->nextState = 2;
|
||||||
|
} else
|
||||||
|
animData->nextState = 40;
|
||||||
|
} else if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 20)
|
||||||
|
animData->nextState = 38;
|
||||||
|
else if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 19)
|
||||||
|
animData->nextState = 26;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirNE:
|
||||||
|
animData->nextState = 3;
|
||||||
|
if (_vm->_map->_screenWidth == 640) {
|
||||||
|
if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10)
|
||||||
|
animData->nextState = 42;
|
||||||
|
if (_vm->_map->getPass(obj->goblinX + 1, obj->goblinY - 2) != 10)
|
||||||
|
animData->nextState = 3;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirW:
|
||||||
|
animData->nextState = rotateState(animData->curLookDir, 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirE:
|
||||||
|
animData->nextState = rotateState(animData->curLookDir, 4);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirSW:
|
||||||
|
animData->nextState = 7;
|
||||||
|
if (_vm->_map->_screenWidth == 640) {
|
||||||
|
if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10)
|
||||||
|
animData->nextState = 41;
|
||||||
|
if (_vm->_map->getPass(obj->goblinX - 1, obj->goblinY + 2) != 10)
|
||||||
|
animData->nextState = 7;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirS:
|
||||||
|
animData->nextState =
|
||||||
|
(animData->curLookDir == 6) ? 6 : rotateState(animData->curLookDir, 6);
|
||||||
|
if (_vm->_map->_screenWidth == 640) {
|
||||||
|
if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 20)
|
||||||
|
animData->nextState = 39;
|
||||||
|
else if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 19)
|
||||||
|
animData->nextState = 27;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirSE:
|
||||||
|
animData->nextState = 5;
|
||||||
|
if (_vm->_map->_screenWidth == 640) {
|
||||||
|
if (_vm->_map->getPass(obj->goblinX, obj->goblinY) == 10)
|
||||||
|
animData->nextState = 43;
|
||||||
|
if (_vm->_map->getPass(obj->goblinX + 1, obj->goblinY + 2) != 10)
|
||||||
|
animData->nextState = 5;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
switch (animData->curLookDir) {
|
||||||
|
case 0:
|
||||||
|
animData->nextState = 8;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
animData->nextState = 10;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
animData->nextState = 29;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
animData->nextState = 11;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
animData->nextState = 9;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
animData->nextState = 30;
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
animData->nextState = 28;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
animData->nextState = 31;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Goblin_v4::moveAdvance(Mult::Mult_Object *obj, Gob_Object *gobDesc,
|
||||||
|
int16 nextAct, int16 framesCount) {
|
||||||
|
Mult::Mult_AnimData *animData;
|
||||||
|
int16 gobX;
|
||||||
|
int16 gobY;
|
||||||
|
int16 animation;
|
||||||
|
int16 state;
|
||||||
|
int16 layer;
|
||||||
|
|
||||||
|
if (!obj->goblinStates)
|
||||||
|
return;
|
||||||
|
|
||||||
|
movePathFind(obj, 0, 0);
|
||||||
|
playSounds(obj);
|
||||||
|
|
||||||
|
animData = obj->pAnimData;
|
||||||
|
|
||||||
|
framesCount = _vm->_scenery->getAnimLayer(animData->animation, animData->layer)->framesCount;
|
||||||
|
|
||||||
|
if (animData->isPaused == 0)
|
||||||
|
animData->frame++;
|
||||||
|
|
||||||
|
switch (animData->stateType) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
animData->isPaused = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4:
|
||||||
|
if (animData->frame == 0)
|
||||||
|
animData->isPaused = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
if (animData->frame >= framesCount)
|
||||||
|
animData->isPaused = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (animData->state) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
case 7:
|
||||||
|
case 13:
|
||||||
|
case 16:
|
||||||
|
case 23:
|
||||||
|
animData->curLookDir = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
case 15:
|
||||||
|
case 18:
|
||||||
|
case 21:
|
||||||
|
animData->curLookDir = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
case 12:
|
||||||
|
case 19:
|
||||||
|
case 22:
|
||||||
|
animData->curLookDir = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 6:
|
||||||
|
case 14:
|
||||||
|
case 17:
|
||||||
|
case 20:
|
||||||
|
animData->curLookDir = 6;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 28:
|
||||||
|
case 29:
|
||||||
|
if (animData->pathExistence == 4)
|
||||||
|
animData->pathExistence = 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((animData->newState != -1) && (animData->frame == framesCount) &&
|
||||||
|
(animData->newState != animData->state)) {
|
||||||
|
animData->nextState = animData->newState;
|
||||||
|
animData->newState = -1;
|
||||||
|
animData->state = animData->nextState;
|
||||||
|
|
||||||
|
Scenery::AnimLayer *animLayer =
|
||||||
|
_vm->_scenery->getAnimLayer(animData->animation, animData->layer);
|
||||||
|
*obj->pPosX += animLayer->animDeltaX;
|
||||||
|
*obj->pPosY += animLayer->animDeltaY;
|
||||||
|
|
||||||
|
animation = obj->goblinStates[animData->nextState][0].animation;
|
||||||
|
layer = obj->goblinStates[animData->nextState][0].layer;
|
||||||
|
animData->layer = layer;
|
||||||
|
animData->animation = animation;
|
||||||
|
animData->frame = 0;
|
||||||
|
} else {
|
||||||
|
if (isMovement(animData->state)) {
|
||||||
|
state = animData->nextState;
|
||||||
|
if (animData->frame == ((framesCount + 1) / 2)) {
|
||||||
|
gobX = obj->goblinX;
|
||||||
|
gobY = obj->goblinY;
|
||||||
|
|
||||||
|
advMovement(obj, state);
|
||||||
|
|
||||||
|
if (animData->state != state) {
|
||||||
|
animation = obj->goblinStates[state][0].animation;
|
||||||
|
layer = obj->goblinStates[state][0].layer;
|
||||||
|
animData->layer = layer;
|
||||||
|
animData->animation = animation;
|
||||||
|
animData->frame = 0;
|
||||||
|
animData->state = state;
|
||||||
|
_vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 0);
|
||||||
|
if (_vm->_map->_bigTiles)
|
||||||
|
*obj->pPosY = ((gobY + 1) * _vm->_map->_tilesHeight) -
|
||||||
|
(_vm->_scenery->_animBottom - _vm->_scenery->_animTop) - (gobY + 1) / 2;
|
||||||
|
else
|
||||||
|
*obj->pPosY = ((gobY + 1) * _vm->_map->_tilesHeight) -
|
||||||
|
(_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
|
||||||
|
*obj->pPosX = gobX * _vm->_map->_tilesWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (animData->frame >= framesCount) {
|
||||||
|
state = animData->nextState;
|
||||||
|
animation = obj->goblinStates[state][0].animation;
|
||||||
|
layer = obj->goblinStates[state][0].layer;
|
||||||
|
animData->layer = layer;
|
||||||
|
animData->animation = animation;
|
||||||
|
animData->frame = 0;
|
||||||
|
animData->state = state;
|
||||||
|
gobX = obj->goblinX;
|
||||||
|
gobY = obj->goblinY;
|
||||||
|
|
||||||
|
advMovement(obj, state);
|
||||||
|
|
||||||
|
_vm->_scenery->updateAnim(layer, 0, animation, 0, *obj->pPosX, *obj->pPosY, 0);
|
||||||
|
if (_vm->_map->_bigTiles)
|
||||||
|
*obj->pPosY = ((gobY + 1) * _vm->_map->_tilesHeight) -
|
||||||
|
(_vm->_scenery->_animBottom - _vm->_scenery->_animTop) - (gobY + 1) / 2;
|
||||||
|
else
|
||||||
|
*obj->pPosY = ((gobY + 1) * _vm->_map->_tilesHeight) -
|
||||||
|
(_vm->_scenery->_animBottom - _vm->_scenery->_animTop);
|
||||||
|
*obj->pPosX = gobX * _vm->_map->_tilesWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 Goblin_v4::sub_20430(int16 state, uint16 dir) {
|
||||||
|
static const int16 word_3F25E[8][8] = {
|
||||||
|
{0, 1, 10, 10, 10, 31, 31, 7},
|
||||||
|
{0, 1, 2, 29, 29, 29, 8, 8},
|
||||||
|
{10, 1, 2, 3, 11, 11, 11, 10},
|
||||||
|
{29, 29, 2, 3, 4, 9, 9, 9},
|
||||||
|
{30, 11, 11, 3, 4, 5, 30, 30},
|
||||||
|
{28, 28, 9, 9, 4, 5, 6, 28},
|
||||||
|
{31, 31, 31, 30, 30, 5, 6, 7},
|
||||||
|
{0, 8, 8, 8, 28, 28, 6, 7}
|
||||||
|
};
|
||||||
|
int16 dx = state, cx = 0;
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case 0:
|
||||||
|
case 8:
|
||||||
|
// loc_20447
|
||||||
|
dx = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
case 10:
|
||||||
|
case 40:
|
||||||
|
// loc_2044B
|
||||||
|
dx = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
case 11:
|
||||||
|
case 42:
|
||||||
|
// loc_20455
|
||||||
|
dx = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5:
|
||||||
|
case 30:
|
||||||
|
case 43:
|
||||||
|
// loc_2045F
|
||||||
|
dx = 5;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7:
|
||||||
|
case 31:
|
||||||
|
case 41:
|
||||||
|
// loc_20469
|
||||||
|
dx = 7;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 9:
|
||||||
|
// loc_2045A
|
||||||
|
dx = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 28:
|
||||||
|
// loc_20464
|
||||||
|
dx = 6;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 29:
|
||||||
|
// loc_20450
|
||||||
|
dx = 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// loc_2046C
|
||||||
|
|
||||||
|
|
||||||
|
switch (dir) {
|
||||||
|
case Map::kDirNW:
|
||||||
|
cx = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirN:
|
||||||
|
cx = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirNE:
|
||||||
|
cx = 3;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirW:
|
||||||
|
cx = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirE:
|
||||||
|
cx = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirSW:
|
||||||
|
cx = 7;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirS:
|
||||||
|
cx = 6;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Map::kDirSE:
|
||||||
|
cx = 5;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return word_3F25E[dx][cx];
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Gob
|
|
@ -181,9 +181,9 @@ void Init::initGame(const char *totName) {
|
||||||
|
|
||||||
_vm->_util->longDelay(200); // Letting everything settle
|
_vm->_util->longDelay(200); // Letting everything settle
|
||||||
|
|
||||||
if (_vm->_vidPlayer->openVideo("coktel.imd")) {
|
if (_vm->_vidPlayer->primaryOpen("coktel.imd")) {
|
||||||
_vm->_vidPlayer->play();
|
_vm->_vidPlayer->primaryPlay();
|
||||||
_vm->_vidPlayer->closeVideo();
|
_vm->_vidPlayer->primaryClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
_vm->_draw->closeScreen();
|
_vm->_draw->closeScreen();
|
||||||
|
|
|
@ -717,16 +717,16 @@ const char *Inter_Bargon::getOpcodeGoblinDesc(int i) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Inter_Bargon::oBargon_intro0(OpGobParams ¶ms) {
|
void Inter_Bargon::oBargon_intro0(OpGobParams ¶ms) {
|
||||||
if (_vm->_vidPlayer->openVideo("scaa", 0, 160)) {
|
if (_vm->_vidPlayer->primaryOpen("scaa", 0, 160)) {
|
||||||
_vm->_vidPlayer->play(0, 92, 27, 0, 0, 0);
|
_vm->_vidPlayer->primaryPlay(0, 92, 27, 0, 0, 0);
|
||||||
_vm->_vidPlayer->closeVideo();
|
_vm->_vidPlayer->primaryClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Inter_Bargon::oBargon_intro1(OpGobParams ¶ms) {
|
void Inter_Bargon::oBargon_intro1(OpGobParams ¶ms) {
|
||||||
if (_vm->_vidPlayer->openVideo("scaa", 0, 160)) {
|
if (_vm->_vidPlayer->primaryOpen("scaa", 0, 160)) {
|
||||||
_vm->_vidPlayer->play(0, -1, 27, 0, 0, 0, 0, 0, true, 23);
|
_vm->_vidPlayer->primaryPlay(0, -1, 27, 0, 0, 0, 0, 0, true, 23);
|
||||||
_vm->_vidPlayer->closeVideo();
|
_vm->_vidPlayer->primaryClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -819,44 +819,44 @@ void Inter_Bargon::oBargon_intro3(OpGobParams ¶ms) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Inter_Bargon::oBargon_intro4(OpGobParams ¶ms) {
|
void Inter_Bargon::oBargon_intro4(OpGobParams ¶ms) {
|
||||||
if (_vm->_vidPlayer->openVideo("scba", 191, 54)) {
|
if (_vm->_vidPlayer->primaryOpen("scba", 191, 54)) {
|
||||||
_vm->_vidPlayer->play(0, -1, 27, 0, 0, 0, 0, 0, true);
|
_vm->_vidPlayer->primaryPlay(0, -1, 27, 0, 0, 0, 0, 0, true);
|
||||||
_vm->_vidPlayer->closeVideo();
|
_vm->_vidPlayer->primaryClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Inter_Bargon::oBargon_intro5(OpGobParams ¶ms) {
|
void Inter_Bargon::oBargon_intro5(OpGobParams ¶ms) {
|
||||||
if (_vm->_vidPlayer->openVideo("scbb", 191, 54)) {
|
if (_vm->_vidPlayer->primaryOpen("scbb", 191, 54)) {
|
||||||
_vm->_vidPlayer->play(0, -1, 27, 0, 0, 0);
|
_vm->_vidPlayer->primaryPlay(0, -1, 27, 0, 0, 0);
|
||||||
_vm->_vidPlayer->closeVideo();
|
_vm->_vidPlayer->primaryClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Inter_Bargon::oBargon_intro6(OpGobParams ¶ms) {
|
void Inter_Bargon::oBargon_intro6(OpGobParams ¶ms) {
|
||||||
if (_vm->_vidPlayer->openVideo("scbc", 191, 54)) {
|
if (_vm->_vidPlayer->primaryOpen("scbc", 191, 54)) {
|
||||||
_vm->_vidPlayer->play(0, -1, 27, 0, 0, 0);
|
_vm->_vidPlayer->primaryPlay(0, -1, 27, 0, 0, 0);
|
||||||
_vm->_vidPlayer->closeVideo();
|
_vm->_vidPlayer->primaryClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Inter_Bargon::oBargon_intro7(OpGobParams ¶ms) {
|
void Inter_Bargon::oBargon_intro7(OpGobParams ¶ms) {
|
||||||
if (_vm->_vidPlayer->openVideo("scbf", 191, 54)) {
|
if (_vm->_vidPlayer->primaryOpen("scbf", 191, 54)) {
|
||||||
_vm->_vidPlayer->play(0, -1, 27, 0, 0, 0);
|
_vm->_vidPlayer->primaryPlay(0, -1, 27, 0, 0, 0);
|
||||||
_vm->_vidPlayer->closeVideo();
|
_vm->_vidPlayer->primaryClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Inter_Bargon::oBargon_intro8(OpGobParams ¶ms) {
|
void Inter_Bargon::oBargon_intro8(OpGobParams ¶ms) {
|
||||||
if (_vm->_vidPlayer->openVideo("scbc", 191, 54)) {
|
if (_vm->_vidPlayer->primaryOpen("scbc", 191, 54)) {
|
||||||
_vm->_vidPlayer->play(0, -1, 27, 0, 0, 0);
|
_vm->_vidPlayer->primaryPlay(0, -1, 27, 0, 0, 0);
|
||||||
_vm->_vidPlayer->closeVideo();
|
_vm->_vidPlayer->primaryClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Inter_Bargon::oBargon_intro9(OpGobParams ¶ms) {
|
void Inter_Bargon::oBargon_intro9(OpGobParams ¶ms) {
|
||||||
if (_vm->_vidPlayer->openVideo("scbd", 191, 54)) {
|
if (_vm->_vidPlayer->primaryOpen("scbd", 191, 54)) {
|
||||||
_vm->_vidPlayer->play(0, -1, 27, 0, 0, 0);
|
_vm->_vidPlayer->primaryPlay(0, -1, 27, 0, 0, 0);
|
||||||
_vm->_vidPlayer->closeVideo();
|
_vm->_vidPlayer->primaryClose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -988,12 +988,10 @@ void Inter_v2::o2_loadMultObject() {
|
||||||
_vm->_global->_inter_execPtr++;
|
_vm->_global->_inter_execPtr++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_vm->_goblin->_gobsCount <= objIndex)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Mult::Mult_Object &obj = _vm->_mult->_objects[objIndex];
|
Mult::Mult_Object &obj = _vm->_mult->_objects[objIndex];
|
||||||
Mult::Mult_AnimData &objAnim = *(obj.pAnimData);
|
Mult::Mult_AnimData &objAnim = *(obj.pAnimData);
|
||||||
if (objAnim.animType == 100) {
|
|
||||||
|
if ((objAnim.animType == 100) && (objIndex < _vm->_goblin->_gobsCount)) {
|
||||||
|
|
||||||
val = *(obj.pPosX) % 256;
|
val = *(obj.pPosX) % 256;
|
||||||
obj.destX = val;
|
obj.destX = val;
|
||||||
|
@ -1029,7 +1027,7 @@ void Inter_v2::o2_loadMultObject() {
|
||||||
((obj.goblinY + 1) / 2);
|
((obj.goblinY + 1) / 2);
|
||||||
*(obj.pPosX) = obj.goblinX * _vm->_map->_tilesWidth;
|
*(obj.pPosX) = obj.goblinX * _vm->_map->_tilesWidth;
|
||||||
|
|
||||||
} else if (objAnim.animType == 101) {
|
} else if ((objAnim.animType == 101) && (objIndex < _vm->_goblin->_gobsCount)) {
|
||||||
|
|
||||||
layer = objAnim.layer;
|
layer = objAnim.layer;
|
||||||
animation = obj.goblinStates[layer][0].animation;
|
animation = obj.goblinStates[layer][0].animation;
|
||||||
|
@ -1048,6 +1046,21 @@ void Inter_v2::o2_loadMultObject() {
|
||||||
}
|
}
|
||||||
_vm->_scenery->updateAnim(layer, 0, animation, 0,
|
_vm->_scenery->updateAnim(layer, 0, animation, 0,
|
||||||
*(obj.pPosX), *(obj.pPosY), 0);
|
*(obj.pPosX), *(obj.pPosY), 0);
|
||||||
|
|
||||||
|
} else if ((objAnim.animType != 100) && (objAnim.animType != 101)) {
|
||||||
|
|
||||||
|
if ((*(obj.pPosX) == -1234) && (*(obj.pPosY) == -4321)) {
|
||||||
|
|
||||||
|
if (obj.videoSlot > 0)
|
||||||
|
_vm->_vidPlayer->slotClose(obj.videoSlot - 1);
|
||||||
|
|
||||||
|
obj.videoSlot = 0;
|
||||||
|
obj.lastLeft = -1;
|
||||||
|
obj.lastTop = -1;
|
||||||
|
obj.lastBottom = -1;
|
||||||
|
obj.lastRight = -1;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1519,7 +1532,7 @@ void Inter_v2::o2_playImd() {
|
||||||
palEnd = _vm->_parse->parseValExpr();
|
palEnd = _vm->_parse->parseValExpr();
|
||||||
palCmd = 1 << (flags & 0x3F);
|
palCmd = 1 << (flags & 0x3F);
|
||||||
|
|
||||||
if ((imd[0] != 0) && !_vm->_vidPlayer->openVideo(imd, x, y, flags)) {
|
if ((imd[0] != 0) && !_vm->_vidPlayer->primaryOpen(imd, x, y, flags)) {
|
||||||
WRITE_VAR(11, -1);
|
WRITE_VAR(11, -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1532,12 +1545,12 @@ void Inter_v2::o2_playImd() {
|
||||||
|
|
||||||
if (startFrame >= 0) {
|
if (startFrame >= 0) {
|
||||||
_vm->_game->_preventScroll = true;
|
_vm->_game->_preventScroll = true;
|
||||||
_vm->_vidPlayer->play(startFrame, lastFrame, breakKey, palCmd, palStart, palEnd, 0);
|
_vm->_vidPlayer->primaryPlay(startFrame, lastFrame, breakKey, palCmd, palStart, palEnd, 0);
|
||||||
_vm->_game->_preventScroll = false;
|
_vm->_game->_preventScroll = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (close)
|
if (close)
|
||||||
_vm->_vidPlayer->closeVideo();
|
_vm->_vidPlayer->primaryClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Inter_v2::o2_getImdInfo() {
|
void Inter_v2::o2_getImdInfo() {
|
||||||
|
|
|
@ -544,9 +544,9 @@ void Inter_v4::setupOpcodes() {
|
||||||
|
|
||||||
static const OpcodeGoblinEntryV4 opcodesGoblin[71] = {
|
static const OpcodeGoblinEntryV4 opcodesGoblin[71] = {
|
||||||
/* 00 */
|
/* 00 */
|
||||||
OPCODE(o2_loadInfogramesIns),
|
{NULL, ""},
|
||||||
OPCODE(o2_startInfogrames),
|
{NULL, ""},
|
||||||
OPCODE(o2_stopInfogrames),
|
{NULL, ""},
|
||||||
{NULL, ""},
|
{NULL, ""},
|
||||||
/* 04 */
|
/* 04 */
|
||||||
{NULL, ""},
|
{NULL, ""},
|
||||||
|
@ -555,7 +555,7 @@ void Inter_v4::setupOpcodes() {
|
||||||
{NULL, ""},
|
{NULL, ""},
|
||||||
/* 08 */
|
/* 08 */
|
||||||
{NULL, ""},
|
{NULL, ""},
|
||||||
OPCODE(o2_playInfogrames),
|
{NULL, ""},
|
||||||
{NULL, ""},
|
{NULL, ""},
|
||||||
{NULL, ""},
|
{NULL, ""},
|
||||||
/* 0C */
|
/* 0C */
|
||||||
|
@ -592,7 +592,7 @@ void Inter_v4::setupOpcodes() {
|
||||||
{NULL, ""},
|
{NULL, ""},
|
||||||
{NULL, ""},
|
{NULL, ""},
|
||||||
{NULL, ""},
|
{NULL, ""},
|
||||||
OPCODE(o2_handleGoblins),
|
{NULL, ""},
|
||||||
/* 28 */
|
/* 28 */
|
||||||
{NULL, ""},
|
{NULL, ""},
|
||||||
{NULL, ""},
|
{NULL, ""},
|
||||||
|
@ -723,7 +723,6 @@ void Inter_v4::o4_playVmdOrMusic() {
|
||||||
bool close;
|
bool close;
|
||||||
|
|
||||||
evalExpr(0);
|
evalExpr(0);
|
||||||
_vm->_global->_inter_resStr[8] = 0;
|
|
||||||
strncpy0(fileName, _vm->_global->_inter_resStr, 127);
|
strncpy0(fileName, _vm->_global->_inter_resStr, 127);
|
||||||
|
|
||||||
x = _vm->_parse->parseValExpr();
|
x = _vm->_parse->parseValExpr();
|
||||||
|
@ -740,8 +739,20 @@ void Inter_v4::o4_playVmdOrMusic() {
|
||||||
if (lastFrame == -1) {
|
if (lastFrame == -1) {
|
||||||
close = true;
|
close = true;
|
||||||
} else if (lastFrame == -3) {
|
} else if (lastFrame == -3) {
|
||||||
warning("Woodruff Stub: Video/Music command -3: Play background video %s", fileName);
|
warning("Woodruff Stub: Video/Music command -3: Play background video %s, %d, %d", fileName, x, y);
|
||||||
// return;
|
|
||||||
|
_vm->_mult->_objects[startFrame].pAnimData->animation = -startFrame - 1;
|
||||||
|
|
||||||
|
if (_vm->_mult->_objects[startFrame].videoSlot > 0)
|
||||||
|
_vm->_vidPlayer->slotClose(_vm->_mult->_objects[startFrame].videoSlot - 1);
|
||||||
|
_vm->_mult->_objects[startFrame].videoSlot = _vm->_vidPlayer->slotOpen(fileName) + 1;
|
||||||
|
|
||||||
|
if (x != -1) {
|
||||||
|
*_vm->_mult->_objects[startFrame].pPosX = x;
|
||||||
|
*_vm->_mult->_objects[startFrame].pPosY = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
} else if (lastFrame == -4) {
|
} else if (lastFrame == -4) {
|
||||||
warning("Woodruff Stub: Video/Music command -4: Play background video %s", fileName);
|
warning("Woodruff Stub: Video/Music command -4: Play background video %s", fileName);
|
||||||
return;
|
return;
|
||||||
|
@ -767,19 +778,19 @@ void Inter_v4::o4_playVmdOrMusic() {
|
||||||
close = false;
|
close = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((fileName[0] != 0) && !_vm->_vidPlayer->openVideo(fileName, x, y, flags)) {
|
if ((fileName[0] != 0) && !_vm->_vidPlayer->primaryOpen(fileName, x, y, flags)) {
|
||||||
WRITE_VAR(11, -1);
|
WRITE_VAR(11, -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (startFrame >= 0) {
|
if (startFrame >= 0) {
|
||||||
_vm->_game->_preventScroll = true;
|
_vm->_game->_preventScroll = true;
|
||||||
_vm->_vidPlayer->play(startFrame, lastFrame, breakKey, palCmd, palStart, palEnd, 0);
|
_vm->_vidPlayer->primaryPlay(startFrame, lastFrame, breakKey, palCmd, palStart, palEnd, 0);
|
||||||
_vm->_game->_preventScroll = false;
|
_vm->_game->_preventScroll = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (close)
|
if (close)
|
||||||
_vm->_vidPlayer->closeVideo();
|
_vm->_vidPlayer->primaryClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace Gob
|
} // End of namespace Gob
|
||||||
|
|
|
@ -18,6 +18,7 @@ MODULE_OBJS := \
|
||||||
goblin_v1.o \
|
goblin_v1.o \
|
||||||
goblin_v2.o \
|
goblin_v2.o \
|
||||||
goblin_v3.o \
|
goblin_v3.o \
|
||||||
|
goblin_v4.o \
|
||||||
coktelvideo.o \
|
coktelvideo.o \
|
||||||
videoplayer.o \
|
videoplayer.o \
|
||||||
init.o \
|
init.o \
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
#include "common/pack-start.h" // START STRUCT PACKING
|
#include "common/pack-start.h" // START STRUCT PACKING
|
||||||
|
|
||||||
struct Mult_AnimData {
|
struct Mult_AnimData {
|
||||||
uint8 animation;
|
int8 animation;
|
||||||
uint8 layer;
|
uint8 layer;
|
||||||
uint8 frame;
|
uint8 frame;
|
||||||
int8 animType;
|
int8 animType;
|
||||||
|
@ -104,6 +104,7 @@ public:
|
||||||
int16 newTop;
|
int16 newTop;
|
||||||
int16 newRight;
|
int16 newRight;
|
||||||
int16 newBottom;
|
int16 newBottom;
|
||||||
|
uint32 videoSlot;
|
||||||
} PACKED_STRUCT;
|
} PACKED_STRUCT;
|
||||||
|
|
||||||
struct Mult_StaticKey {
|
struct Mult_StaticKey {
|
||||||
|
|
|
@ -463,8 +463,7 @@ void Mult_v2::multSub(uint16 multIndex) {
|
||||||
int obj = _multData->animObjs[index][i];
|
int obj = _multData->animObjs[index][i];
|
||||||
|
|
||||||
if ((obj != -1) && (obj != 1024))
|
if ((obj != -1) && (obj != 1024))
|
||||||
_objects[obj].pAnimData->animTypeBak =
|
_objects[obj].pAnimData->animTypeBak = _objects[obj].pAnimData->animType;
|
||||||
_objects[obj].pAnimData->animType;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,8 +471,10 @@ void Mult_v2::multSub(uint16 multIndex) {
|
||||||
_multData->animKeysIndices[index][i] = 0;
|
_multData->animKeysIndices[index][i] = 0;
|
||||||
|
|
||||||
for (int j = 0; j < _multData->animKeysCount[i]; j++)
|
for (int j = 0; j < _multData->animKeysCount[i]; j++)
|
||||||
if (_multData->animKeys[i][j].frame == startFrame)
|
if (_multData->animKeys[i][j].frame >= startFrame) {
|
||||||
_multData->animKeysIndices[index][i] = j;
|
_multData->animKeysIndices[index][i] = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_multData->animDirection == -1) {
|
if (_multData->animDirection == -1) {
|
||||||
|
@ -487,6 +488,7 @@ void Mult_v2::multSub(uint16 multIndex) {
|
||||||
firstFrame = (_multData->animDirection == 1) ? startFrame : stopFrame;
|
firstFrame = (_multData->animDirection == 1) ? startFrame : stopFrame;
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
_multData->imdKeysIndices[index][i] = 0;
|
_multData->imdKeysIndices[index][i] = 0;
|
||||||
|
|
||||||
for (int j = 0; j < _multData->imdKeysCount[i]; j++)
|
for (int j = 0; j < _multData->imdKeysCount[i]; j++)
|
||||||
if (_multData->imdKeys[i][j].frame >= firstFrame) {
|
if (_multData->imdKeys[i][j].frame >= firstFrame) {
|
||||||
_multData->imdKeysIndices[index][i] = j;
|
_multData->imdKeysIndices[index][i] = j;
|
||||||
|
@ -675,27 +677,53 @@ void Mult_v2::drawAnims(bool &stop) { // loc_50D5
|
||||||
|
|
||||||
void Mult_v2::newCycleAnim(Mult_Object &animObj) {
|
void Mult_v2::newCycleAnim(Mult_Object &animObj) {
|
||||||
Mult_AnimData &animData = *(animObj.pAnimData);
|
Mult_AnimData &animData = *(animObj.pAnimData);
|
||||||
int nAnim = animData.animation;
|
Scenery::AnimLayer *animLayer = 0;
|
||||||
int nLayer = animData.layer;
|
|
||||||
|
if (animData.animation >= 0) {
|
||||||
|
int nAnim = animData.animation, nLayer = animData.layer;
|
||||||
|
|
||||||
if (_vm->_scenery->getAnimLayersCount(nAnim) <= nLayer)
|
if (_vm->_scenery->getAnimLayersCount(nAnim) <= nLayer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Scenery::AnimLayer *animLayer = _vm->_scenery->getAnimLayer(nAnim, nLayer);
|
animLayer = _vm->_scenery->getAnimLayer(nAnim, nLayer);
|
||||||
|
}
|
||||||
|
|
||||||
if (animData.animType == 4) {
|
if (animData.animType == 4) {
|
||||||
|
// loc_1E091
|
||||||
animData.frame = 0;
|
animData.frame = 0;
|
||||||
animData.isPaused = 1;
|
animData.isPaused = 1;
|
||||||
|
if (animData.animation < 0)
|
||||||
|
warning("TODO: AnimType 4, animation: %d", animData.animation);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (animData.animType == 12)
|
||||||
|
animData.animType = 11;
|
||||||
|
|
||||||
|
if (animData.animType == 11) {
|
||||||
|
if (animData.isBusy != 0) {
|
||||||
|
warning("TODO: AnimType 11");
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (animData.animType != 8)
|
if (animData.animType != 8)
|
||||||
animData.frame++;
|
animData.frame++;
|
||||||
|
|
||||||
|
if (animData.animation < 0) {
|
||||||
|
if ((animObj.videoSlot > 0) &&
|
||||||
|
(_vm->_vidPlayer->getCurrentFrame(animObj.videoSlot - 1) <
|
||||||
|
_vm->_vidPlayer->getFramesCount(animObj.videoSlot - 1))) {
|
||||||
|
animData.newCycle = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (animData.frame < animLayer->framesCount) {
|
if (animData.frame < animLayer->framesCount) {
|
||||||
animData.newCycle = 0;
|
animData.newCycle = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
switch (animData.animType) {
|
switch (animData.animType) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -728,6 +756,12 @@ void Mult_v2::newCycleAnim(Mult_Object &animObj) {
|
||||||
case 7:
|
case 7:
|
||||||
animData.frame--;
|
animData.frame--;
|
||||||
animData.isPaused = 1;
|
animData.isPaused = 1;
|
||||||
|
if ((animData.animation < 0) && (animObj.videoSlot > 0)) {
|
||||||
|
if (_vm->_vidPlayer->getFlags(animObj.videoSlot - 1) & 0x1000) {
|
||||||
|
_vm->_vidPlayer->slotClose(animObj.videoSlot - 1);
|
||||||
|
animObj.videoSlot = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
animData.newCycle = 1;
|
animData.newCycle = 1;
|
||||||
|
@ -897,6 +931,9 @@ void Mult_v2::animate() {
|
||||||
Mult_Object &animObj1 = *_renderObjs[orderArray[i]];
|
Mult_Object &animObj1 = *_renderObjs[orderArray[i]];
|
||||||
Mult_AnimData &animData1 = *(animObj1.pAnimData);
|
Mult_AnimData &animData1 = *(animObj1.pAnimData);
|
||||||
|
|
||||||
|
if (!animObj1.goblinStates)
|
||||||
|
continue;
|
||||||
|
|
||||||
for (int j = i+1; j < orderArrayPos; j++) {
|
for (int j = i+1; j < orderArrayPos; j++) {
|
||||||
Mult_Object &animObj2 = *_renderObjs[orderArray[j]];
|
Mult_Object &animObj2 = *_renderObjs[orderArray[j]];
|
||||||
Mult_AnimData &animData2 = *(animObj2.pAnimData);
|
Mult_AnimData &animData2 = *(animObj2.pAnimData);
|
||||||
|
@ -1043,7 +1080,7 @@ void Mult_v2::playImd(const char *imdFile, Mult::Mult_ImdKey &key, int16 dir,
|
||||||
x = y = -1;
|
x = y = -1;
|
||||||
|
|
||||||
if (key.imdFile == -1) {
|
if (key.imdFile == -1) {
|
||||||
_vm->_vidPlayer->closeVideo();
|
_vm->_vidPlayer->primaryClose();
|
||||||
_vm->_game->_preventScroll = false;
|
_vm->_game->_preventScroll = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1061,11 +1098,11 @@ void Mult_v2::playImd(const char *imdFile, Mult::Mult_ImdKey &key, int16 dir,
|
||||||
if ((lastFrame - palFrame) < startFrame)
|
if ((lastFrame - palFrame) < startFrame)
|
||||||
if (!(key.flags & 0x4000)) {
|
if (!(key.flags & 0x4000)) {
|
||||||
_vm->_game->_preventScroll = false;
|
_vm->_game->_preventScroll = false;
|
||||||
_vm->_vidPlayer->closeVideo();
|
_vm->_vidPlayer->primaryClose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_vm->_vidPlayer->openVideo(imdFile, x, y, flags)) {
|
if (!_vm->_vidPlayer->primaryOpen(imdFile, x, y, flags)) {
|
||||||
_vm->_game->_preventScroll = false;
|
_vm->_game->_preventScroll = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1077,7 +1114,7 @@ void Mult_v2::playImd(const char *imdFile, Mult::Mult_ImdKey &key, int16 dir,
|
||||||
lastFrame = _vm->_vidPlayer->getFramesCount() - 1;
|
lastFrame = _vm->_vidPlayer->getFramesCount() - 1;
|
||||||
|
|
||||||
baseFrame = startFrame % (lastFrame - palFrame + 1);
|
baseFrame = startFrame % (lastFrame - palFrame + 1);
|
||||||
_vm->_vidPlayer->play(baseFrame + palFrame, baseFrame + palFrame, 0,
|
_vm->_vidPlayer->primaryPlay(baseFrame + palFrame, baseFrame + palFrame, 0,
|
||||||
flags & 0x7F, palStart, palEnd, palFrame, lastFrame);
|
flags & 0x7F, palStart, palEnd, palFrame, lastFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,8 @@
|
||||||
#include "gob/draw.h"
|
#include "gob/draw.h"
|
||||||
#include "gob/game.h"
|
#include "gob/game.h"
|
||||||
#include "gob/inter.h"
|
#include "gob/inter.h"
|
||||||
|
#include "gob/map.h"
|
||||||
|
#include "gob/videoplayer.h"
|
||||||
|
|
||||||
namespace Gob {
|
namespace Gob {
|
||||||
|
|
||||||
|
@ -454,6 +456,7 @@ int16 Scenery::loadAnim(char search) {
|
||||||
ptr->layers = new AnimLayer[ptr->layersCount];
|
ptr->layers = new AnimLayer[ptr->layersCount];
|
||||||
ptr->pieces = new PieceDesc*[picsCount];
|
ptr->pieces = new PieceDesc*[picsCount];
|
||||||
ptr->piecesFromExt = new bool[picsCount];
|
ptr->piecesFromExt = new bool[picsCount];
|
||||||
|
ptr->sizes = new uint16[picsCount];
|
||||||
|
|
||||||
for (i = 0; i < ptr->layersCount; i++) {
|
for (i = 0; i < ptr->layersCount; i++) {
|
||||||
int16 offset = READ_LE_UINT16(dataPtr + i * 2);
|
int16 offset = READ_LE_UINT16(dataPtr + i * 2);
|
||||||
|
@ -492,13 +495,19 @@ int16 Scenery::loadAnim(char search) {
|
||||||
for (i = 0; i < picsCount; i++) {
|
for (i = 0; i < picsCount; i++) {
|
||||||
pictDescId = _vm->_inter->load16();
|
pictDescId = _vm->_inter->load16();
|
||||||
if (pictDescId >= 30000) {
|
if (pictDescId >= 30000) {
|
||||||
|
uint32 size;
|
||||||
|
|
||||||
ptr->pieces[i] =
|
ptr->pieces[i] =
|
||||||
(PieceDesc *) _vm->_game->loadExtData(pictDescId, 0, 0);
|
(PieceDesc *) _vm->_game->loadExtData(pictDescId, 0, 0, &size);
|
||||||
ptr->piecesFromExt[i] = true;
|
ptr->piecesFromExt[i] = true;
|
||||||
|
ptr->sizes[i] = size / 8;
|
||||||
} else {
|
} else {
|
||||||
|
int16 size;
|
||||||
|
|
||||||
ptr->pieces[i] =
|
ptr->pieces[i] =
|
||||||
(PieceDesc *) _vm->_game->loadTotResource(pictDescId);
|
(PieceDesc *) _vm->_game->loadTotResource(pictDescId, &size);
|
||||||
ptr->piecesFromExt[i] = false;
|
ptr->piecesFromExt[i] = false;
|
||||||
|
ptr->sizes[i] = size / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
width = _vm->_inter->load16();
|
width = _vm->_inter->load16();
|
||||||
|
@ -561,6 +570,7 @@ void Scenery::freeAnim(int16 index) {
|
||||||
delete[] _animations[index].layers;
|
delete[] _animations[index].layers;
|
||||||
delete[] _animations[index].pieces;
|
delete[] _animations[index].pieces;
|
||||||
delete[] _animations[index].piecesFromExt;
|
delete[] _animations[index].piecesFromExt;
|
||||||
|
delete[] _animations[index].sizes;
|
||||||
|
|
||||||
_animPictCount[index] = 0;
|
_animPictCount[index] = 0;
|
||||||
}
|
}
|
||||||
|
@ -592,6 +602,135 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
|
||||||
int16 destX;
|
int16 destX;
|
||||||
int16 destY;
|
int16 destY;
|
||||||
|
|
||||||
|
if (animation < 0) {
|
||||||
|
// Object video
|
||||||
|
|
||||||
|
if (flags & 1) { // Do capture
|
||||||
|
updateAnim(layer, frame, animation, 0, drawDeltaX, drawDeltaY, 0);
|
||||||
|
|
||||||
|
if (_toRedrawLeft == -12345)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_vm->_game->capturePush(_toRedrawLeft, _toRedrawTop,
|
||||||
|
_toRedrawRight - _toRedrawLeft + 1,
|
||||||
|
_toRedrawBottom - _toRedrawTop + 1);
|
||||||
|
|
||||||
|
*_pCaptureCounter = *_pCaptureCounter + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mult::Mult_Object &obj = _vm->_mult->_objects[-animation - 1];
|
||||||
|
|
||||||
|
if (!_vm->_vidPlayer->slotIsOpen(obj.videoSlot - 1)) {
|
||||||
|
_toRedrawLeft = -1234;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seek to frame
|
||||||
|
while (_vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1) <= frame)
|
||||||
|
_vm->_vidPlayer->slotPlay(obj.videoSlot - 1);
|
||||||
|
|
||||||
|
destX = 0;
|
||||||
|
destY = 0;
|
||||||
|
left = *(obj.pPosX);
|
||||||
|
top = *(obj.pPosY);
|
||||||
|
right = left + _vm->_vidPlayer->getWidth(obj.videoSlot - 1) - 1;
|
||||||
|
bottom = top + _vm->_vidPlayer->getHeight(obj.videoSlot - 1) - 1;
|
||||||
|
|
||||||
|
if (flags & 2) {
|
||||||
|
if (left < _vm->_mult->_animLeft) {
|
||||||
|
destX += _vm->_mult->_animLeft - left;
|
||||||
|
left = _vm->_mult->_animLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_vm->_mult->_animLeft + _vm->_mult->_animWidth) <= right)
|
||||||
|
right = _vm->_mult->_animLeft + _vm->_mult->_animWidth - 1;
|
||||||
|
|
||||||
|
if (top < _vm->_mult->_animTop) {
|
||||||
|
destY += _vm->_mult->_animTop - top;
|
||||||
|
top = _vm->_mult->_animTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_vm->_mult->_animTop + _vm->_mult->_animHeight) <= bottom)
|
||||||
|
bottom = _vm->_mult->_animTop + _vm->_mult->_animHeight - 1;
|
||||||
|
|
||||||
|
} else if (flags & 4) {
|
||||||
|
if (left < _toRedrawLeft) {
|
||||||
|
destX += _toRedrawLeft - left;
|
||||||
|
left = _toRedrawLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (right > _toRedrawRight)
|
||||||
|
right = _toRedrawRight;
|
||||||
|
|
||||||
|
if (top < _toRedrawTop) {
|
||||||
|
destY += _toRedrawTop - top;
|
||||||
|
top = _toRedrawTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bottom > _toRedrawBottom)
|
||||||
|
bottom = _toRedrawBottom;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
_toRedrawTop = top;
|
||||||
|
_toRedrawLeft = left;
|
||||||
|
_toRedrawRight = right;
|
||||||
|
_toRedrawBottom = bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (doDraw) {
|
||||||
|
if ((left > right) || (top > bottom))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (left < _vm->_mult->_animLeft) {
|
||||||
|
destX += _vm->_mult->_animLeft - left;
|
||||||
|
left = _vm->_mult->_animLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_vm->_mult->_animLeft + _vm->_mult->_animWidth) <= right)
|
||||||
|
right = _vm->_mult->_animLeft + _vm->_mult->_animWidth - 1;
|
||||||
|
|
||||||
|
if (top < _vm->_mult->_animTop) {
|
||||||
|
destY += _vm->_mult->_animTop - top;
|
||||||
|
top = _vm->_mult->_animTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_vm->_mult->_animTop + _vm->_mult->_animHeight) <= bottom)
|
||||||
|
bottom = _vm->_mult->_animTop + _vm->_mult->_animHeight - 1;
|
||||||
|
|
||||||
|
_vm->_draw->_spriteLeft = destX;
|
||||||
|
_vm->_draw->_spriteTop = destY;
|
||||||
|
_vm->_draw->_spriteRight = right - left + 1;
|
||||||
|
_vm->_draw->_spriteBottom = bottom - top + 1;
|
||||||
|
_vm->_draw->_destSpriteX = left;
|
||||||
|
_vm->_draw->_destSpriteY = top;
|
||||||
|
_vm->_draw->_transparency = layer;
|
||||||
|
if (layer & 0x80)
|
||||||
|
_vm->_draw->_spriteLeft = _vm->_vidPlayer->getWidth(obj.videoSlot - 1) -
|
||||||
|
(destX + _vm->_draw->_spriteRight);
|
||||||
|
|
||||||
|
_vm->_vidPlayer->slotCopyFrame(obj.videoSlot - 1, _vm->_draw->_backSurface->getVidMem(),
|
||||||
|
_vm->_draw->_spriteLeft, _vm->_draw->_spriteTop,
|
||||||
|
_vm->_draw->_spriteRight, _vm->_draw->_spriteBottom,
|
||||||
|
_vm->_draw->_destSpriteX, _vm->_draw->_destSpriteY,
|
||||||
|
_vm->_draw->_backSurface->getWidth(),
|
||||||
|
(_vm->_draw->_transparency != 0) ? 0 : -1);
|
||||||
|
|
||||||
|
_vm->_draw->invalidateRect(_vm->_draw->_destSpriteX, _vm->_draw->_destSpriteY,
|
||||||
|
_vm->_draw->_destSpriteX + _vm->_draw->_spriteRight - 1,
|
||||||
|
_vm->_draw->_destSpriteY + _vm->_draw->_spriteBottom - 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flags & 4) {
|
||||||
|
_animLeft = _toRedrawLeft = left;
|
||||||
|
_animTop = _toRedrawTop = top;
|
||||||
|
_animRight = _toRedrawRight = right;
|
||||||
|
_animBottom = _toRedrawBottom = bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if ((_animPictCount[animation] == 0) || (layer < 0))
|
if ((_animPictCount[animation] == 0) || (layer < 0))
|
||||||
return;
|
return;
|
||||||
if (layer >= _animations[animation].layersCount)
|
if (layer >= _animations[animation].layersCount)
|
||||||
|
@ -670,6 +809,16 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags,
|
||||||
|
|
||||||
pictIndex = (pictIndex & 15) - 1;
|
pictIndex = (pictIndex & 15) - 1;
|
||||||
|
|
||||||
|
if ((pictIndex == 0xFFFF) || (_animPictCount[animation] <= pictIndex)) {
|
||||||
|
warning("Scenery::updateAnim: pictIndex out of range");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_animations[animation].sizes[pictIndex] <= pieceIndex) {
|
||||||
|
warning("Scenery::updateAnim: pieceIndex out of range");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
left = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].left);
|
left = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].left);
|
||||||
right = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].right);
|
right = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].right);
|
||||||
top = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].top);
|
top = READ_LE_UINT16(&pictPtr[pictIndex][pieceIndex].top);
|
||||||
|
|
|
@ -92,6 +92,7 @@ public:
|
||||||
AnimLayer *layers;
|
AnimLayer *layers;
|
||||||
PieceDesc **pieces;
|
PieceDesc **pieces;
|
||||||
bool *piecesFromExt;
|
bool *piecesFromExt;
|
||||||
|
uint16 *sizes;
|
||||||
Animation() : layersCount(0), layers(0), pieces(0),
|
Animation() : layersCount(0), layers(0), pieces(0),
|
||||||
piecesFromExt(0) {}
|
piecesFromExt(0) {}
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,29 +32,105 @@
|
||||||
#include "gob/game.h"
|
#include "gob/game.h"
|
||||||
#include "gob/palanim.h"
|
#include "gob/palanim.h"
|
||||||
#include "gob/inter.h"
|
#include "gob/inter.h"
|
||||||
|
#include "gob/map.h"
|
||||||
|
|
||||||
namespace Gob {
|
namespace Gob {
|
||||||
|
|
||||||
const char *VideoPlayer::_extensions[] = { "IMD", "VMD" };
|
const char *VideoPlayer::_extensions[] = { "IMD", "VMD" };
|
||||||
|
|
||||||
VideoPlayer::VideoPlayer(GobEngine *vm) : _vm(vm) {
|
VideoPlayer::Video::Video(GobEngine *vm) : _vm(vm), _fileName(0), _stream(0), _video(0) {
|
||||||
_curFile[0] = 0;
|
}
|
||||||
_stream = 0;
|
|
||||||
|
VideoPlayer::Video::~Video() {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VideoPlayer::Video::open(const char *fileName, Type which) {
|
||||||
|
close();
|
||||||
|
|
||||||
|
int16 handle = _vm->_dataIO->openData(fileName);
|
||||||
|
|
||||||
|
if (handle < 0) {
|
||||||
|
warning("Couldn't open video \"%s\": No such file", fileName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_stream = _vm->_dataIO->openAsStream(handle, true);
|
||||||
|
|
||||||
|
if (which == kVideoTypeIMD) {
|
||||||
|
_video = new Imd();
|
||||||
|
} else if (which == kVideoTypeVMD) {
|
||||||
|
_video = new Vmd();
|
||||||
|
} else {
|
||||||
|
warning("Couldn't open video \"%s\": Invalid video Type", fileName);
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_video->load(*_stream)) {
|
||||||
|
warning("While loading video \"%s\"", fileName);
|
||||||
|
close();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_fileName = new char[strlen(fileName) + 1];
|
||||||
|
strcpy(_fileName, fileName);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoPlayer::Video::close() {
|
||||||
|
delete _video;
|
||||||
|
delete _stream;
|
||||||
|
delete[] _fileName;
|
||||||
|
|
||||||
_video = 0;
|
_video = 0;
|
||||||
|
_stream = 0;
|
||||||
|
_fileName = 0;
|
||||||
|
memset(&_state, 0, sizeof(CoktelVideo::State));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VideoPlayer::Video::isOpen() const {
|
||||||
|
return (_video != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *VideoPlayer::Video::getFileName() const {
|
||||||
|
return _fileName ? _fileName : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
CoktelVideo *VideoPlayer::Video::getVideo() {
|
||||||
|
return _video;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CoktelVideo *VideoPlayer::Video::getVideo() const {
|
||||||
|
return _video;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoktelVideo::State VideoPlayer::Video::getState() const {
|
||||||
|
return _state;
|
||||||
|
}
|
||||||
|
|
||||||
|
CoktelVideo::State VideoPlayer::Video::nextFrame() {
|
||||||
|
if (_video)
|
||||||
|
_state = _video->nextFrame();
|
||||||
|
|
||||||
|
return _state;
|
||||||
|
}
|
||||||
|
|
||||||
|
VideoPlayer::VideoPlayer(GobEngine *vm) : _vm(vm) {
|
||||||
|
_primaryVideo = new Video(vm);
|
||||||
_backSurf = false;
|
_backSurf = false;
|
||||||
_needBlit = false;
|
_needBlit = false;
|
||||||
_noCursorSwitch = false;
|
_noCursorSwitch = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
VideoPlayer::~VideoPlayer() {
|
VideoPlayer::~VideoPlayer() {
|
||||||
closeVideo();
|
delete _primaryVideo;
|
||||||
|
for (uint i = 0; i < _videoSlots.size(); i++)
|
||||||
|
delete _videoSlots[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VideoPlayer::openVideo(const char *video, int16 x, int16 y, int16 flags, Type which) {
|
bool VideoPlayer::findFile(char *fileName, Type &which) {
|
||||||
char fileName[256];
|
|
||||||
|
|
||||||
strncpy0(fileName, video, 250);
|
|
||||||
|
|
||||||
char *extStart = strrchr(fileName, '.');
|
char *extStart = strrchr(fileName, '.');
|
||||||
// There's no empty extension
|
// There's no empty extension
|
||||||
if (extStart == (fileName + strlen(fileName) - 1)) {
|
if (extStart == (fileName + strlen(fileName) - 1)) {
|
||||||
|
@ -112,33 +188,22 @@ bool VideoPlayer::openVideo(const char *video, int16 x, int16 y, int16 flags, Ty
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scumm_strnicmp(_curFile, fileName, strlen(fileName))) {
|
return true;
|
||||||
closeVideo();
|
|
||||||
|
|
||||||
int16 handle = _vm->_dataIO->openData(fileName);
|
|
||||||
|
|
||||||
if (handle < 0) {
|
|
||||||
warning("Couldn't open video \"%s\": No such file", fileName);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_stream = _vm->_dataIO->openAsStream(handle, true);
|
bool VideoPlayer::primaryOpen(const char *videoFile, int16 x, int16 y,
|
||||||
|
int16 flags, Type which) {
|
||||||
|
|
||||||
if (which == kVideoTypeIMD) {
|
char fileName[256];
|
||||||
_video = new Imd();
|
|
||||||
} else if (which == kVideoTypeVMD) {
|
|
||||||
_video = new Vmd();
|
|
||||||
} else {
|
|
||||||
warning("Couldn't open video \"%s\": Invalid video Type", fileName);
|
|
||||||
closeVideo();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_video->load(*_stream)) {
|
strncpy0(fileName, videoFile, 250);
|
||||||
warning("While loading video \"%s\"", fileName);
|
|
||||||
closeVideo();
|
if (!findFile(fileName, which))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (scumm_strnicmp(_primaryVideo->getFileName(), fileName, strlen(fileName))) {
|
||||||
|
if (!_primaryVideo->open(fileName, which))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// WORKAROUND: In some rare cases, the cursor should still be
|
// WORKAROUND: In some rare cases, the cursor should still be
|
||||||
// displayed while a video is playing.
|
// displayed while a video is playing.
|
||||||
|
@ -153,53 +218,54 @@ bool VideoPlayer::openVideo(const char *video, int16 x, int16 y, int16 flags, Ty
|
||||||
_noCursorSwitch = true;
|
_noCursorSwitch = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(_curFile, fileName);
|
|
||||||
|
|
||||||
if (!(flags & kFlagNoVideo)) {
|
if (!(flags & kFlagNoVideo)) {
|
||||||
_backSurf = ((flags & kFlagFrontSurface) == 0);
|
_backSurf = ((flags & kFlagFrontSurface) == 0);
|
||||||
SurfaceDesc::Ptr surf = _vm->_draw->_spritesArray[_backSurf ? 21 : 20];
|
SurfaceDesc::Ptr surf = _vm->_draw->_spritesArray[_backSurf ? 21 : 20];
|
||||||
_video->setVideoMemory(surf->getVidMem(), surf->getWidth(), surf->getHeight());
|
_primaryVideo->getVideo()->setVideoMemory(surf->getVidMem(),
|
||||||
|
surf->getWidth(), surf->getHeight());
|
||||||
} else
|
} else
|
||||||
_video->setVideoMemory();
|
_primaryVideo->getVideo()->setVideoMemory();
|
||||||
|
|
||||||
_needBlit = ((flags & kFlagUseBackSurfaceContent) != 0) && ((flags & kFlagFrontSurface) != 0);
|
_needBlit = ((flags & kFlagUseBackSurfaceContent) != 0) && ((flags & kFlagFrontSurface) != 0);
|
||||||
|
|
||||||
_video->enableSound(*_vm->_mixer);
|
_primaryVideo->getVideo()->enableSound(*_vm->_mixer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_video)
|
if (!_primaryVideo->isOpen())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
_video->setFrameRate(_vm->_util->getFrameRate());
|
_primaryVideo->getVideo()->setFrameRate(_vm->_util->getFrameRate());
|
||||||
_video->setXY(x, y);
|
_primaryVideo->getVideo()->setXY(x, y);
|
||||||
WRITE_VAR(7, _video->getFramesCount());
|
WRITE_VAR(7, _primaryVideo->getVideo()->getFramesCount());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoPlayer::play(int16 startFrame, int16 lastFrame, int16 breakKey,
|
void VideoPlayer::primaryPlay(int16 startFrame, int16 lastFrame, int16 breakKey,
|
||||||
uint16 palCmd, int16 palStart, int16 palEnd,
|
uint16 palCmd, int16 palStart, int16 palEnd,
|
||||||
int16 palFrame, int16 endFrame, bool fade, int16 reverseTo) {
|
int16 palFrame, int16 endFrame, bool fade, int16 reverseTo) {
|
||||||
|
|
||||||
if (!_video)
|
if (!_primaryVideo->isOpen())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
CoktelVideo &video = *(_primaryVideo->getVideo());
|
||||||
|
|
||||||
breakKey = 27;
|
breakKey = 27;
|
||||||
if (startFrame < 0)
|
if (startFrame < 0)
|
||||||
startFrame = _video->getCurrentFrame();
|
startFrame = video.getCurrentFrame();
|
||||||
if (lastFrame < 0)
|
if (lastFrame < 0)
|
||||||
lastFrame = _video->getFramesCount() - 1;
|
lastFrame = video.getFramesCount() - 1;
|
||||||
if (palFrame < 0)
|
if (palFrame < 0)
|
||||||
palFrame = startFrame;
|
palFrame = startFrame;
|
||||||
if (endFrame < 0)
|
if (endFrame < 0)
|
||||||
endFrame = lastFrame;
|
endFrame = lastFrame;
|
||||||
palCmd &= 0x3F;
|
palCmd &= 0x3F;
|
||||||
|
|
||||||
if (_video->getCurrentFrame() != startFrame) {
|
if (video.getCurrentFrame() != startFrame) {
|
||||||
if (_video->getFeatures() & CoktelVideo::kFeaturesSound)
|
if (video.getFeatures() & CoktelVideo::kFeaturesSound)
|
||||||
startFrame = _video->getCurrentFrame();
|
startFrame = video.getCurrentFrame();
|
||||||
else
|
else
|
||||||
_video->seekFrame(startFrame);
|
video.seekFrame(startFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
_vm->_draw->_showCursor = _noCursorSwitch ? 3 : 0;
|
_vm->_draw->_showCursor = _noCursorSwitch ? 3 : 0;
|
||||||
|
@ -217,36 +283,156 @@ void VideoPlayer::play(int16 startFrame, int16 lastFrame, int16 breakKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_noCursorSwitch)
|
if (!_noCursorSwitch)
|
||||||
_video->waitEndFrame();
|
video.waitEndFrame();
|
||||||
startFrame++;
|
startFrame++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reverseTo >= 0) {
|
if (reverseTo >= 0) {
|
||||||
int16 toFrame = _video->getFramesCount() - reverseTo;
|
int16 toFrame = video.getFramesCount() - reverseTo;
|
||||||
for (int i = _video->getCurrentFrame(); i >= toFrame; i--) {
|
for (int i = video.getCurrentFrame(); i >= toFrame; i--) {
|
||||||
_video->seekFrame(i, SEEK_SET, true);
|
video.seekFrame(i, SEEK_SET, true);
|
||||||
if (doPlay(i, breakKey, 0, 0, 0, 0, 0)) {
|
if (doPlay(i, breakKey, 0, 0, 0, 0, 0)) {
|
||||||
_vm->_palAnim->fade(0, -2, 0);
|
_vm->_palAnim->fade(0, -2, 0);
|
||||||
memset((char *) _vm->_draw->_vgaPalette, 0, 768);
|
memset((char *) _vm->_draw->_vgaPalette, 0, 768);
|
||||||
}
|
}
|
||||||
if (!_noCursorSwitch)
|
if (!_noCursorSwitch)
|
||||||
_video->waitEndFrame();
|
video.waitEndFrame();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 VideoPlayer::getFramesCount() const {
|
void VideoPlayer::primaryClose() {
|
||||||
if (!_video)
|
_primaryVideo->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
int VideoPlayer::slotOpen(const char *videoFile, Type which) {
|
||||||
|
Video *video = new Video(_vm);
|
||||||
|
char fileName[256];
|
||||||
|
|
||||||
|
strncpy0(fileName, videoFile, 250);
|
||||||
|
|
||||||
|
if (!findFile(fileName, which)) {
|
||||||
|
delete video;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!video->open(fileName, which)) {
|
||||||
|
delete video;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
video->getVideo()->setVideoMemory();
|
||||||
|
video->getVideo()->disableSound();
|
||||||
|
|
||||||
|
_videoSlots.push_back(video);
|
||||||
|
|
||||||
|
WRITE_VAR(7, video->getVideo()->getFramesCount());
|
||||||
|
|
||||||
|
return _videoSlots.size() - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoPlayer::slotPlay(int slot, int16 frame) {
|
||||||
|
if ((slot < 0) || (((uint) slot) >= _videoSlots.size()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
CoktelVideo &video = *(_videoSlots[slot]->getVideo());
|
||||||
|
|
||||||
|
if (frame < 0)
|
||||||
|
frame = video.getCurrentFrame();
|
||||||
|
|
||||||
|
if (video.getCurrentFrame() != frame)
|
||||||
|
video.seekFrame(frame);
|
||||||
|
|
||||||
|
_videoSlots[slot]->nextFrame();
|
||||||
|
WRITE_VAR(11, frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoPlayer::slotClose(int slot) {
|
||||||
|
if ((slot < 0) || (((uint) slot) >= _videoSlots.size()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
delete _videoSlots[slot];
|
||||||
|
_videoSlots.remove_at(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoPlayer::slotCopyFrame(int slot, byte *dest,
|
||||||
|
uint16 left, uint16 top, uint16 width, uint16 height,
|
||||||
|
uint16 x, uint16 y, uint16 pitch, int16 transp) {
|
||||||
|
|
||||||
|
if ((slot < 0) || (((uint) slot) >= _videoSlots.size()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
_videoSlots[slot]->getVideo()->copyCurrentFrame(dest,
|
||||||
|
left, top, width, height, x, y, pitch, transp);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VideoPlayer::slotCopyPalette(int slot, int16 palStart, int16 palEnd) {
|
||||||
|
if ((slot < 0) || (((uint) slot) >= _videoSlots.size()))
|
||||||
|
return;
|
||||||
|
|
||||||
|
copyPalette(*(_videoSlots[slot]->getVideo()), palStart, palEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VideoPlayer::slotIsOpen(int slot) const {
|
||||||
|
if ((slot >= 0) && (((uint) slot) < _videoSlots.size()))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const VideoPlayer::Video *VideoPlayer::getVideoBySlot(int slot) const {
|
||||||
|
if (slot < 0) {
|
||||||
|
if (_primaryVideo->isOpen())
|
||||||
|
return _primaryVideo;
|
||||||
|
} else if (((uint) slot) < _videoSlots.size())
|
||||||
|
return _videoSlots[slot];
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return _video->getFramesCount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 VideoPlayer::getCurrentFrame() const {
|
uint16 VideoPlayer::getFlags(int slot) const {
|
||||||
if (!_video)
|
const Video *video = getVideoBySlot(slot);
|
||||||
return 0;
|
|
||||||
|
|
||||||
return _video->getCurrentFrame();
|
if (video)
|
||||||
|
return video->getVideo()->getFlags();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 VideoPlayer::getFramesCount(int slot) const {
|
||||||
|
const Video *video = getVideoBySlot(slot);
|
||||||
|
|
||||||
|
if (video)
|
||||||
|
return video->getVideo()->getFramesCount();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 VideoPlayer::getCurrentFrame(int slot) const {
|
||||||
|
const Video *video = getVideoBySlot(slot);
|
||||||
|
|
||||||
|
if (video)
|
||||||
|
return video->getVideo()->getCurrentFrame();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 VideoPlayer::getWidth(int slot) const {
|
||||||
|
const Video *video = getVideoBySlot(slot);
|
||||||
|
|
||||||
|
if (video)
|
||||||
|
return video->getVideo()->getWidth();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16 VideoPlayer::getHeight(int slot) const {
|
||||||
|
const Video *video = getVideoBySlot(slot);
|
||||||
|
|
||||||
|
if (video)
|
||||||
|
return video->getVideo()->getHeight();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
|
bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
|
||||||
|
@ -260,7 +446,7 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
|
||||||
_vm->_draw->_applyPal = true;
|
_vm->_draw->_applyPal = true;
|
||||||
|
|
||||||
if (palCmd >= 4)
|
if (palCmd >= 4)
|
||||||
copyPalette(palStart, palEnd);
|
copyPalette(*(_primaryVideo->getVideo()), palStart, palEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modifiedPal && (palCmd == 8) && !_backSurf)
|
if (modifiedPal && (palCmd == 8) && !_backSurf)
|
||||||
|
@ -270,7 +456,7 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
|
||||||
if (_needBlit)
|
if (_needBlit)
|
||||||
_vm->_draw->forceBlit();
|
_vm->_draw->forceBlit();
|
||||||
|
|
||||||
CoktelVideo::State state = _video->nextFrame();
|
CoktelVideo::State state = _primaryVideo->nextFrame();
|
||||||
WRITE_VAR(11, frame);
|
WRITE_VAR(11, frame);
|
||||||
|
|
||||||
if (_needBlit)
|
if (_needBlit)
|
||||||
|
@ -285,7 +471,7 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.flags & CoktelVideo::kStatePalette) {
|
if (state.flags & CoktelVideo::kStatePalette) {
|
||||||
copyPalette(palStart, palEnd);
|
copyPalette(*(_primaryVideo->getVideo()), palStart, palEnd);
|
||||||
|
|
||||||
if (!_backSurf)
|
if (!_backSurf)
|
||||||
_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
|
_vm->_video->setFullPalette(_vm->_global->_pPaletteDesc);
|
||||||
|
@ -311,7 +497,7 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
|
||||||
_vm->_util->processInput();
|
_vm->_util->processInput();
|
||||||
|
|
||||||
if (_vm->_quitRequested) {
|
if (_vm->_quitRequested) {
|
||||||
_video->disableSound();
|
_primaryVideo->getVideo()->disableSound();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +507,7 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
|
||||||
|
|
||||||
_vm->_inter->storeKey(_vm->_util->checkKey());
|
_vm->_inter->storeKey(_vm->_util->checkKey());
|
||||||
if (VAR(0) == (unsigned) breakKey) {
|
if (VAR(0) == (unsigned) breakKey) {
|
||||||
_video->disableSound();
|
_primaryVideo->getVideo()->disableSound();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -329,26 +515,37 @@ bool VideoPlayer::doPlay(int16 frame, int16 breakKey,
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoPlayer::copyPalette(int16 palStart, int16 palEnd) {
|
void VideoPlayer::copyPalette(CoktelVideo &video, int16 palStart, int16 palEnd) {
|
||||||
if ((palStart == -1) || (palEnd == -1))
|
if ((palStart != -1) && (palEnd != -1))
|
||||||
memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal,
|
memcpy(((char *) (_vm->_global->_pPaletteDesc->vgaPal)) + palStart * 3,
|
||||||
_video->getPalette(), 768);
|
video.getPalette() + palStart * 3,
|
||||||
else
|
|
||||||
memcpy(((char *) (_vm->_global->_pPaletteDesc->vgaPal)) +
|
|
||||||
palStart * 3, _video->getPalette() + palStart * 3,
|
|
||||||
(palEnd - palStart + 1) * 3);
|
(palEnd - palStart + 1) * 3);
|
||||||
|
else
|
||||||
|
memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal, video.getPalette(), 768);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoPlayer::writeVideoInfo(const char *video, int16 varX, int16 varY,
|
void VideoPlayer::writeVideoInfo(const char *videoFile, int16 varX, int16 varY,
|
||||||
int16 varFrames, int16 varWidth, int16 varHeight) {
|
int16 varFrames, int16 varWidth, int16 varHeight) {
|
||||||
|
|
||||||
if (openVideo(video)) {
|
if (primaryOpen(videoFile)) {
|
||||||
WRITE_VAR_OFFSET(varX, _video->getX());
|
int16 x, y, width, height;
|
||||||
WRITE_VAR_OFFSET(varY, _video->getY());
|
|
||||||
WRITE_VAR_OFFSET(varFrames, _video->getFramesCount());
|
if ((VAR_OFFSET(varX) != 0xFFFFFFFF) ||
|
||||||
WRITE_VAR_OFFSET(varWidth, _video->getWidth());
|
!_primaryVideo->getVideo()->getAnchor(1, 2, x, y, width, height)) {
|
||||||
WRITE_VAR_OFFSET(varHeight, _video->getHeight());
|
|
||||||
closeVideo();
|
x = _primaryVideo->getVideo()->getX();
|
||||||
|
y = _primaryVideo->getVideo()->getY();
|
||||||
|
width = _primaryVideo->getVideo()->getWidth();
|
||||||
|
height = _primaryVideo->getVideo()->getHeight();
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_VAR_OFFSET(varX, x);
|
||||||
|
WRITE_VAR_OFFSET(varY, y);
|
||||||
|
WRITE_VAR_OFFSET(varFrames, _primaryVideo->getVideo()->getFramesCount());
|
||||||
|
WRITE_VAR_OFFSET(varWidth, width);
|
||||||
|
WRITE_VAR_OFFSET(varHeight, height);
|
||||||
|
|
||||||
|
primaryClose();
|
||||||
} else {
|
} else {
|
||||||
WRITE_VAR_OFFSET(varX, -1);
|
WRITE_VAR_OFFSET(varX, -1);
|
||||||
WRITE_VAR_OFFSET(varY, -1);
|
WRITE_VAR_OFFSET(varY, -1);
|
||||||
|
@ -358,13 +555,4 @@ void VideoPlayer::writeVideoInfo(const char *video, int16 varX, int16 varY,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VideoPlayer::closeVideo() {
|
|
||||||
delete _video;
|
|
||||||
delete _stream;
|
|
||||||
|
|
||||||
_video = 0;
|
|
||||||
_stream = 0;
|
|
||||||
*_curFile = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // End of namespace Gob
|
} // End of namespace Gob
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
#ifndef GOB_VIDEOPLAYER_H
|
#ifndef GOB_VIDEOPLAYER_H
|
||||||
#define GOB_VIDEOPLAYER_H
|
#define GOB_VIDEOPLAYER_H
|
||||||
|
|
||||||
|
#include "common/array.h"
|
||||||
|
|
||||||
#include "gob/coktelvideo.h"
|
#include "gob/coktelvideo.h"
|
||||||
#include "gob/dataio.h"
|
#include "gob/dataio.h"
|
||||||
|
|
||||||
|
@ -51,34 +53,75 @@ public:
|
||||||
VideoPlayer(GobEngine *vm);
|
VideoPlayer(GobEngine *vm);
|
||||||
~VideoPlayer();
|
~VideoPlayer();
|
||||||
|
|
||||||
bool openVideo(const char *video, int16 x = -1, int16 y = -1,
|
bool primaryOpen(const char *videoFile, int16 x = -1, int16 y = -1,
|
||||||
int16 flags = kFlagFrontSurface, Type which = kVideoTypeTry);
|
int16 flags = kFlagFrontSurface, Type which = kVideoTypeTry);
|
||||||
|
void primaryPlay(int16 startFrame = -1, int16 lastFrame = -1, int16 breakKey = 27,
|
||||||
void play(int16 startFrame = -1, int16 lastFrame = -1, int16 breakKey = 27,
|
|
||||||
uint16 palCmd = 8, int16 palStart = 0, int16 palEnd = 255,
|
uint16 palCmd = 8, int16 palStart = 0, int16 palEnd = 255,
|
||||||
int16 palFrame = -1, int16 endFrame = -1, bool fade = false,
|
int16 palFrame = -1, int16 endFrame = -1, bool fade = false,
|
||||||
int16 reverseTo = -1);
|
int16 reverseTo = -1);
|
||||||
|
void primaryClose();
|
||||||
|
|
||||||
int16 getFramesCount() const;
|
int slotOpen(const char *videoFile, Type which = kVideoTypeTry);
|
||||||
int16 getCurrentFrame() const;
|
void slotPlay(int slot, int16 frame = -1);
|
||||||
void writeVideoInfo(const char *video, int16 varX, int16 varY,
|
void slotClose(int slot);
|
||||||
|
void slotCopyFrame(int slot, byte *dest,
|
||||||
|
uint16 left, uint16 top, uint16 width, uint16 height,
|
||||||
|
uint16 x, uint16 y, uint16 pitch, int16 transp = -1);
|
||||||
|
void slotCopyPalette(int slot, int16 palStart = -1, int16 palEnd = -1);
|
||||||
|
|
||||||
|
bool slotIsOpen(int slot) const;
|
||||||
|
|
||||||
|
uint16 getFlags(int slot = -1) const;
|
||||||
|
int16 getFramesCount(int slot = -1) const;
|
||||||
|
int16 getCurrentFrame(int slot = -1) const;
|
||||||
|
int16 getWidth(int slot = -1) const;
|
||||||
|
int16 getHeight(int slot = -1) const;
|
||||||
|
|
||||||
|
void writeVideoInfo(const char *videoFile, int16 varX, int16 varY,
|
||||||
int16 varFrames, int16 varWidth, int16 varHeight);
|
int16 varFrames, int16 varWidth, int16 varHeight);
|
||||||
|
|
||||||
void closeVideo();
|
private:
|
||||||
|
class Video {
|
||||||
|
public:
|
||||||
|
Video(GobEngine *vm);
|
||||||
|
~Video();
|
||||||
|
|
||||||
|
bool open(const char *fileName, Type which);
|
||||||
|
void close();
|
||||||
|
|
||||||
|
bool isOpen() const;
|
||||||
|
|
||||||
|
const char *getFileName() const;
|
||||||
|
CoktelVideo *getVideo();
|
||||||
|
const CoktelVideo *getVideo() const;
|
||||||
|
CoktelVideo::State getState() const;
|
||||||
|
|
||||||
|
CoktelVideo::State nextFrame();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
GobEngine *_vm;
|
||||||
|
|
||||||
|
char *_fileName;
|
||||||
|
DataStream *_stream;
|
||||||
|
CoktelVideo *_video;
|
||||||
|
CoktelVideo::State _state;
|
||||||
|
};
|
||||||
|
|
||||||
static const char *_extensions[];
|
static const char *_extensions[];
|
||||||
|
|
||||||
GobEngine *_vm;
|
GobEngine *_vm;
|
||||||
|
|
||||||
char _curFile[256];
|
Common::Array<Video *> _videoSlots;
|
||||||
DataStream *_stream;
|
Video *_primaryVideo;
|
||||||
CoktelVideo *_video;
|
|
||||||
bool _backSurf;
|
bool _backSurf;
|
||||||
bool _needBlit;
|
bool _needBlit;
|
||||||
bool _noCursorSwitch;
|
bool _noCursorSwitch;
|
||||||
|
|
||||||
void copyPalette(int16 palStart = -1, int16 palEnd = -1);
|
bool findFile(char *fileName, Type &which);
|
||||||
|
|
||||||
|
const Video *getVideoBySlot(int slot = -1) const;
|
||||||
|
|
||||||
|
void copyPalette(CoktelVideo &video, int16 palStart = -1, int16 palEnd = -1);
|
||||||
bool doPlay(int16 frame, int16 breakKey,
|
bool doPlay(int16 frame, int16 breakKey,
|
||||||
uint16 palCmd, int16 palStart, int16 palEnd,
|
uint16 palCmd, int16 palStart, int16 palEnd,
|
||||||
int16 palFrame, int16 endFrame);
|
int16 palFrame, int16 endFrame);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue