diff options
author | Alejandro Marzini | 2010-08-16 00:21:07 +0000 |
---|---|---|
committer | Alejandro Marzini | 2010-08-16 00:21:07 +0000 |
commit | b0409d673921163085d2e2fa440911080a7cf884 (patch) | |
tree | 81b1bb895db6baed7881ca5cbc7ff3a830286189 /engines/gob | |
parent | 503578ac1087b91dcb912fd7918454de73538b34 (diff) | |
parent | b49761b6eae3a0aadefef4c4ffee6a7b583cc3ac (diff) | |
download | scummvm-rg350-b0409d673921163085d2e2fa440911080a7cf884.tar.gz scummvm-rg350-b0409d673921163085d2e2fa440911080a7cf884.tar.bz2 scummvm-rg350-b0409d673921163085d2e2fa440911080a7cf884.zip |
Merge trunk, from r51777 to r52105
svn-id: r52108
Diffstat (limited to 'engines/gob')
27 files changed, 1158 insertions, 1037 deletions
diff --git a/engines/gob/demos/demoplayer.cpp b/engines/gob/demos/demoplayer.cpp index 38e20a46ee..25cd470f04 100644 --- a/engines/gob/demos/demoplayer.cpp +++ b/engines/gob/demos/demoplayer.cpp @@ -152,12 +152,13 @@ void DemoPlayer::playVideo(const char *fileName) { debugC(1, kDebugDemo, "Playing video \"%s\"", file); - int16 x = _rebase0 ? 0 : -1; - int16 y = _rebase0 ? 0 : -1; - if (_vm->_vidPlayer->primaryOpen(file, x, y)) { - bool videoSupportsDouble = - ((_vm->_vidPlayer->getFeatures() & Graphics::CoktelVideo::kFeaturesSupportsDouble) != 0); + VideoPlayer::Properties props; + props.x = _rebase0 ? 0 : -1; + props.y = _rebase0 ? 0 : -1; + + int slot; + if ((slot = _vm->_vidPlayer->openVideo(true, file, props)) >= 0) { if (_autoDouble) { int16 defX = _rebase0 ? 0 : _vm->_vidPlayer->getDefaultX(); int16 defY = _rebase0 ? 0 : _vm->_vidPlayer->getDefaultY(); @@ -167,16 +168,12 @@ void DemoPlayer::playVideo(const char *fileName) { _doubleMode = ((right < 320) && (bottom < 200)); } - if (_doubleMode) { - if (videoSupportsDouble) { - _vm->_vidPlayer->slotSetDoubleMode(-1, true); - playVideoNormal(); - } else - playVideoDoubled(); - } else - playVideoNormal(); + if (_doubleMode) + playVideoDoubled(slot); + else + playVideoNormal(slot); - _vm->_vidPlayer->primaryClose(); + _vm->_vidPlayer->closeVideo(slot); if (waitTime > 0) _vm->_util->longDelay(waitTime); @@ -210,51 +207,67 @@ void DemoPlayer::playADL(const char *params) { playADL(fileName, waitEsc, repeat); } -void DemoPlayer::playVideoNormal() { - _vm->_vidPlayer->primaryPlay(); +void DemoPlayer::playVideoNormal(int slot) { + VideoPlayer::Properties props; + + _vm->_vidPlayer->play(slot, props); } -void DemoPlayer::playVideoDoubled() { - Common::String fileNameOpened = _vm->_vidPlayer->getFileName(); - _vm->_vidPlayer->primaryClose(); +void DemoPlayer::playVideoDoubled(int slot) { + Common::String fileNameOpened = _vm->_vidPlayer->getFileName(slot); + _vm->_vidPlayer->closeVideo(slot); - int16 x = _rebase0 ? 0 : -1; - int16 y = _rebase0 ? 0 : -1; - if (_vm->_vidPlayer->primaryOpen(fileNameOpened.c_str(), x, y, - VideoPlayer::kFlagScreenSurface)) { + VideoPlayer::Properties props; - for (int i = 0; i < _vm->_vidPlayer->getFramesCount(); i++) { - _vm->_vidPlayer->playFrame(i); + props.x = _rebase0 ? 0 : -1; + props.y = _rebase0 ? 0 : -1; + props.flags = VideoPlayer::kFlagScreenSurface; + props.waitEndFrame = false; - Graphics::CoktelVideo::State state = _vm->_vidPlayer->getState(); + _vm->_vidPlayer->evaluateFlags(props); + + slot = _vm->_vidPlayer->openVideo(true, fileNameOpened, props); + if (slot < 0) + return; - int16 w = state.right - state.left + 1; - int16 h = state.bottom - state.top + 1; - int16 wD = (state.left * 2) + (w * 2); - int16 hD = (state.top * 2) + (h * 2); + for (uint i = 0; i < _vm->_vidPlayer->getFrameCount(slot); i++) { + props.startFrame = _vm->_vidPlayer->getCurrentFrame(slot) + 1; + props.lastFrame = _vm->_vidPlayer->getCurrentFrame(slot) + 1; + + _vm->_vidPlayer->play(slot, props); + + const Common::List<Common::Rect> *rects = _vm->_vidPlayer->getDirtyRects(slot); + if (rects) { + for (Common::List<Common::Rect>::const_iterator rect = rects->begin(); rect != rects->end(); ++rect) { + int16 w = rect->right - rect->left; + int16 h = rect->bottom - rect->top; + int16 wD = (rect->left * 2) + (w * 2); + int16 hD = (rect->top * 2) + (h * 2); _vm->_video->drawSpriteDouble(*_vm->_draw->_spritesArray[0], *_vm->_draw->_frontSurface, - state.left, state.top, state.right, state.bottom, state.left, state.top, 0); + rect->left, rect->top, rect->right - 1, rect->bottom - 1, rect->left, rect->top, 0); _vm->_draw->dirtiedRect(_vm->_draw->_frontSurface, - state.left * 2, state.top * 2, wD, hD); - _vm->_video->retrace(); + rect->left * 2, rect->top * 2, wD, hD); + } + } - _vm->_util->processInput(); - if (_vm->shouldQuit()) - break; + _vm->_video->retrace(); - int16 key; - bool end = false; - while (_vm->_util->checkKey(key)) - if (key == kKeyEscape) - end = true; - if (end) - break; + _vm->_util->processInput(); + if (_vm->shouldQuit()) + break; - _vm->_vidPlayer->slotWaitEndFrame(); + int16 key; + bool end = false; + while (_vm->_util->checkKey(key)) + if (key == kKeyEscape) + end = true; + if (end) + break; - } + _vm->_vidPlayer->waitEndFrame(slot); } + } void DemoPlayer::playADL(const Common::String &fileName, bool waitEsc, int32 repeat) { diff --git a/engines/gob/demos/demoplayer.h b/engines/gob/demos/demoplayer.h index f0672b9645..207b050363 100644 --- a/engines/gob/demos/demoplayer.h +++ b/engines/gob/demos/demoplayer.h @@ -59,8 +59,8 @@ protected: void playVideo(const char *fileName); void playADL(const char *params); - void playVideoNormal(); - void playVideoDoubled(); + void playVideoNormal(int slot); + void playVideoDoubled(int slot); void playADL(const Common::String &fileName, bool waitEsc = true, int32 repeat = -1); private: diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp index ff6d558998..b572ccb566 100644 --- a/engines/gob/draw.cpp +++ b/engines/gob/draw.cpp @@ -538,8 +538,6 @@ void Draw::activeWin(int16 id) { SurfaceDescPtr tempSrf; SurfaceDescPtr oldSrf[10]; - warning ("activeWindow %d", id); - if (_fascinWin[id].id == -1) return; @@ -682,9 +680,8 @@ int16 Draw::openWin(int16 id) { _fascinWin[id].top = VAR((_winVarArrayTop / 4) + id); _fascinWin[id].width = VAR((_winVarArrayWidth / 4) + id); _fascinWin[id].height = VAR((_winVarArrayHeight / 4) + id); - _fascinWin[id].savedSurface = _vm->_video->initSurfDesc(_vm->_global->_videoMode, _winMaxWidth + 7, _winMaxHeight, 0); - warning("Draw::openWin id %d- left %d top %d l %d h%d", id, _fascinWin[id].left, _fascinWin[id].top, _fascinWin[id].width, _fascinWin[id].height); + _fascinWin[id].savedSurface = _vm->_video->initSurfDesc(_vm->_global->_videoMode, _winMaxWidth + 7, _winMaxHeight, 0); saveWin(id); WRITE_VAR((_winVarArrayStatus / 4) + id, VAR((_winVarArrayStatus / 4) + id) & 0xFFFFFFFE); @@ -693,7 +690,6 @@ int16 Draw::openWin(int16 id) { } void Draw::restoreWin(int16 i) { - warning("restoreWin"); _vm->_video->drawSprite(*_fascinWin[i].savedSurface, *_backSurface, _fascinWin[i].left & 7, 0, (_fascinWin[i].left & 7) + _fascinWin[i].width - 1, _fascinWin[i].height - 1, @@ -704,7 +700,6 @@ void Draw::restoreWin(int16 i) { } void Draw::saveWin(int16 id) { - warning("saveWin"); _vm->_video->drawSprite(*_backSurface, *_fascinWin[id].savedSurface, _fascinWin[id].left, _fascinWin[id].top, _fascinWin[id].left + _fascinWin[id].width - 1, @@ -765,7 +760,6 @@ void Draw::handleWinBorder(int16 id) { int16 maxX = 320; int16 minY = 0; int16 maxY = 200; - warning("handleWinBorder %d", id); if (VAR((_winVarArrayStatus / 4) + id) & 8) minX = (int16)(VAR((_winVarArrayLimitsX / 4) + id) >> 16L); @@ -884,8 +878,6 @@ int16 Draw::handleCurWin() { } void Draw::winDecomp(int16 x, int16 y, SurfaceDescPtr destPtr) { - warning("winDecomp %d %d - getResource %d %d %d", x, y, _spriteLeft, _spriteRight, _spriteBottom); - Resource *resource; resource = _vm->_game->_resources->getResource((uint16) _spriteLeft, &_spriteRight, &_spriteBottom); @@ -906,15 +898,13 @@ void Draw::winDraw(int16 fct) { int16 width; int16 height; - warning("winDraw %d", fct); - bool found = false; int len; Resource *resource; int table[10]; SurfaceDescPtr tempSrf; - if (_destSurface == 21) { + if (_destSurface == kBackSurface) { if (_vm->_global->_curWinId) { if (_fascinWin[_vm->_global->_curWinId].id == -1) @@ -1032,7 +1022,7 @@ void Draw::winDraw(int16 fct) { table[_fascinWin[i].id] = i; } - if ((_sourceSurface == 21) && (fct == 0)) { + if ((_sourceSurface == kBackSurface) && (fct == 0)) { _vm->_video->drawSprite(*_spritesArray[_sourceSurface], *_spritesArray[_destSurface], _spriteLeft, _spriteTop, _spriteLeft + _spriteRight - 1, _spriteTop + _spriteBottom - 1, _destSpriteX, _destSpriteY, _transparency); @@ -1267,11 +1257,11 @@ void Draw::winDraw(int16 fct) { } if (_renderFlags & 16) { - if (_sourceSurface == 21) { + if (_sourceSurface == kBackSurface) { _spriteLeft -= _backDeltaX; _spriteTop -= _backDeltaY; } - if (_destSurface == 21) { + if (_destSurface == kBackSurface) { _destSpriteX -= _backDeltaX; _destSpriteY -= _backDeltaY; } @@ -1323,9 +1313,9 @@ void Draw::forceBlit(bool backwards) { return; if (_frontSurface == _backSurface) return; - if (_spritesArray[20] != _frontSurface) + if (_spritesArray[kFrontSurface] != _frontSurface) return; - if (_spritesArray[21] != _backSurface) + if (_spritesArray[kBackSurface] != _backSurface) return; if (!backwards) { diff --git a/engines/gob/draw.h b/engines/gob/draw.h index 8997c53362..fa3cbb84cc 100644 --- a/engines/gob/draw.h +++ b/engines/gob/draw.h @@ -45,7 +45,12 @@ namespace Gob { class Draw { public: - static const int kFontCount = 8; + static const int kFontCount = 8; + static const int kFrontSurface = 20; + static const int kBackSurface = 21; + static const int kAnimSurface = 22; + static const int kCursorSurface = 23; + static const int kCaptureSurface = 30; struct FontToSprite { int8 sprite; diff --git a/engines/gob/draw_fascin.cpp b/engines/gob/draw_fascin.cpp index 9d30faa972..1e01db7dfb 100644 --- a/engines/gob/draw_fascin.cpp +++ b/engines/gob/draw_fascin.cpp @@ -53,12 +53,12 @@ void Draw_Fascination::spriteOperation(int16 operation) { _destSurface -= 80; if ((_renderFlags & RENDERFLAG_USEDELTAS) && !deltaVeto) { - if ((_sourceSurface == 21) && (operation != DRAW_LOADSPRITE)) { + if ((_sourceSurface == kBackSurface) && (operation != DRAW_LOADSPRITE)) { _spriteLeft += _backDeltaX; _spriteTop += _backDeltaY; } - if (_destSurface == 21) { + if (_destSurface == kBackSurface) { _destSpriteX += _backDeltaX; _destSpriteY += _backDeltaY; if ((operation == DRAW_DRAWLINE) || @@ -70,7 +70,7 @@ void Draw_Fascination::spriteOperation(int16 operation) { } if (_renderFlags & 0x20) { - if (_destSurface == 21 || (operation == 0 && _sourceSurface == 21)) { + if (_destSurface == kBackSurface || (operation == 0 && _sourceSurface == kBackSurface)) { winDraw(operation); return; } @@ -86,7 +86,7 @@ void Draw_Fascination::spriteOperation(int16 operation) { int16 destSurface = _destSurface; int16 sourceSurface = _sourceSurface; - if (_vm->_video->_splitSurf && ((_destSurface == 20) || (_destSurface == 21))) { + if (_vm->_video->_splitSurf && ((_destSurface == kFrontSurface) || (_destSurface == kBackSurface))) { if ((_destSpriteY >= _vm->_video->_splitStart)) { _destSpriteY -= _vm->_video->_splitStart; if ((operation == DRAW_DRAWLINE) || @@ -340,12 +340,12 @@ void Draw_Fascination::spriteOperation(int16 operation) { } if ((_renderFlags & RENDERFLAG_USEDELTAS) && !deltaVeto) { - if (_sourceSurface == 21) { + if (_sourceSurface == kBackSurface) { _spriteLeft -= _backDeltaX; _spriteTop -= _backDeltaY; } - if (_destSurface == 21) { + if (_destSurface == kBackSurface) { _destSpriteX -= _backDeltaX; _destSpriteY -= _backDeltaY; } diff --git a/engines/gob/draw_playtoons.cpp b/engines/gob/draw_playtoons.cpp index 862cdd33eb..583d13986e 100644 --- a/engines/gob/draw_playtoons.cpp +++ b/engines/gob/draw_playtoons.cpp @@ -53,12 +53,12 @@ void Draw_Playtoons::spriteOperation(int16 operation) { _destSurface -= 80; if ((_renderFlags & RENDERFLAG_USEDELTAS) && !deltaVeto) { - if ((_sourceSurface == 21) && (operation != DRAW_LOADSPRITE)) { + if ((_sourceSurface == kBackSurface) && (operation != DRAW_LOADSPRITE)) { _spriteLeft += _backDeltaX; _spriteTop += _backDeltaY; } - if (_destSurface == 21) { + if (_destSurface == kBackSurface) { _destSpriteX += _backDeltaX; _destSpriteY += _backDeltaY; if ((operation == DRAW_DRAWLINE) || @@ -78,7 +78,7 @@ void Draw_Playtoons::spriteOperation(int16 operation) { int16 destSurface = _destSurface; int16 sourceSurface = _sourceSurface; - if (_vm->_video->_splitSurf && ((_destSurface == 20) || (_destSurface == 21))) { + if (_vm->_video->_splitSurf && ((_destSurface == kFrontSurface) || (_destSurface == kBackSurface))) { if ((_destSpriteY >= _vm->_video->_splitStart)) { _destSpriteY -= _vm->_video->_splitStart; if ((operation == DRAW_DRAWLINE) || @@ -409,12 +409,12 @@ void Draw_Playtoons::spriteOperation(int16 operation) { } if ((_renderFlags & RENDERFLAG_USEDELTAS) && !deltaVeto) { - if (_sourceSurface == 21) { + if (_sourceSurface == kBackSurface) { _spriteLeft -= _backDeltaX; _spriteTop -= _backDeltaY; } - if (_destSurface == 21) { + if (_destSurface == kBackSurface) { _destSpriteX -= _backDeltaX; _destSpriteY -= _backDeltaY; } diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp index 719945fd6f..1cec15ce04 100644 --- a/engines/gob/draw_v1.cpp +++ b/engines/gob/draw_v1.cpp @@ -184,7 +184,7 @@ void Draw_v1::printTotText(int16 id) { _destSpriteY = destY; _spriteRight = spriteRight; _spriteBottom = spriteBottom; - _destSurface = 21; + _destSurface = kBackSurface; _backColor = *ptr++; _transparency = 1; @@ -326,12 +326,12 @@ void Draw_v1::spriteOperation(int16 operation) { _destSurface -= 80; if (_renderFlags & RENDERFLAG_USEDELTAS) { - if (_sourceSurface == 21) { + if (_sourceSurface == kBackSurface) { _spriteLeft += _backDeltaX; _spriteTop += _backDeltaY; } - if (_destSurface == 21) { + if (_destSurface == kBackSurface) { _destSpriteX += _backDeltaX; _destSpriteY += _backDeltaY; if ((operation == DRAW_DRAWLINE) || @@ -508,12 +508,12 @@ void Draw_v1::spriteOperation(int16 operation) { } if (_renderFlags & RENDERFLAG_USEDELTAS) { - if (_sourceSurface == 21) { + if (_sourceSurface == kBackSurface) { _spriteLeft -= _backDeltaX; _spriteTop -= _backDeltaY; } - if (_destSurface == 21) { + if (_destSurface == kBackSurface) { _destSpriteX -= _backDeltaX; _destSpriteY -= _backDeltaY; } diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp index 985f84aaef..5d001f4b59 100644 --- a/engines/gob/draw_v2.cpp +++ b/engines/gob/draw_v2.cpp @@ -51,30 +51,30 @@ void Draw_v2::initScreen() { _scrollOffsetX = 0; _scrollOffsetY = 0; - initSpriteSurf(21, _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0); - _backSurface = _spritesArray[21]; + initSpriteSurf(kBackSurface, _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0); + _backSurface = _spritesArray[kBackSurface]; _vm->_video->clearSurf(*_backSurface); - if (!_spritesArray[23]) { - initSpriteSurf(23, 32, 16, 2); - _cursorSpritesBack = _spritesArray[23]; + if (!_spritesArray[kCursorSurface]) { + initSpriteSurf(kCursorSurface, 32, 16, 2); + _cursorSpritesBack = _spritesArray[kCursorSurface]; _cursorSprites = _cursorSpritesBack; _scummvmCursor = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 16, 16, SCUMMVM_CURSOR); } - _spritesArray[20] = _frontSurface; - _spritesArray[21] = _backSurface; + _spritesArray[kFrontSurface] = _frontSurface; + _spritesArray[kBackSurface ] = _backSurface; _vm->_video->dirtyRectsAll(); } void Draw_v2::closeScreen() { - //freeSprite(23); + //freeSprite(kCursorSurface); //_cursorSprites = 0; //_cursorSpritesBack = 0; //_scummvmCursor = 0; - freeSprite(21); + freeSprite(kBackSurface); } void Draw_v2::blitCursor() { @@ -273,7 +273,7 @@ void Draw_v2::printTotText(int16 id) { _destSpriteY = destY; _spriteRight = spriteRight; _spriteBottom = spriteBottom; - _destSurface = 21; + _destSurface = kBackSurface; _backColor = *ptr++; _transparency = 1; @@ -629,12 +629,12 @@ void Draw_v2::spriteOperation(int16 operation) { _destSurface -= 80; if ((_renderFlags & RENDERFLAG_USEDELTAS) && !deltaVeto) { - if ((_sourceSurface == 21) && (operation != DRAW_LOADSPRITE)) { + if ((_sourceSurface == kBackSurface) && (operation != DRAW_LOADSPRITE)) { _spriteLeft += _backDeltaX; _spriteTop += _backDeltaY; } - if (_destSurface == 21) { + if (_destSurface == kBackSurface) { _destSpriteX += _backDeltaX; _destSpriteY += _backDeltaY; if ((operation == DRAW_DRAWLINE) || @@ -654,7 +654,7 @@ void Draw_v2::spriteOperation(int16 operation) { int16 destSurface = _destSurface; int16 sourceSurface = _sourceSurface; - if (_vm->_video->_splitSurf && ((_destSurface == 20) || (_destSurface == 21))) { + if (_vm->_video->_splitSurf && ((_destSurface == kFrontSurface) || (_destSurface == kBackSurface))) { if ((_destSpriteY >= _vm->_video->_splitStart)) { _destSpriteY -= _vm->_video->_splitStart; if ((operation == DRAW_DRAWLINE) || @@ -908,12 +908,12 @@ void Draw_v2::spriteOperation(int16 operation) { } if ((_renderFlags & RENDERFLAG_USEDELTAS) && !deltaVeto) { - if (_sourceSurface == 21) { + if (_sourceSurface == kBackSurface) { _spriteLeft -= _backDeltaX; _spriteTop -= _backDeltaY; } - if (_destSurface == 21) { + if (_destSurface == kBackSurface) { _destSpriteX -= _backDeltaX; _destSpriteY -= _backDeltaY; } diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index ddf095a5d1..1a8823b156 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -286,8 +286,8 @@ void Game::playTot(int16 skipPlay) { _vm->_mult->initAll(); _vm->_mult->zeroMultData(); - _vm->_draw->_spritesArray[20] = _vm->_draw->_frontSurface; - _vm->_draw->_spritesArray[21] = _vm->_draw->_backSurface; + _vm->_draw->_spritesArray[Draw::kFrontSurface] = _vm->_draw->_frontSurface; + _vm->_draw->_spritesArray[Draw::kBackSurface ] = _vm->_draw->_backSurface; _vm->_draw->_cursorSpritesBack = _vm->_draw->_cursorSprites; } else _vm->_inter->initControlVars(0); @@ -299,7 +299,7 @@ void Game::playTot(int16 skipPlay) { break; if (skipPlay == -2) { - _vm->_vidPlayer->primaryClose(); + _vm->_vidPlayer->closeVideo(); skipPlay = 0; } @@ -397,10 +397,10 @@ void Game::capturePush(int16 left, int16 top, int16 width, int16 height) { left &= 0xFFF0; right |= 0xF; - _vm->_draw->initSpriteSurf(30 + _captureCount, right - left + 1, height, 0); + _vm->_draw->initSpriteSurf(Draw::kCaptureSurface + _captureCount, right - left + 1, height, 0); - _vm->_draw->_sourceSurface = 21; - _vm->_draw->_destSurface = 30 + _captureCount; + _vm->_draw->_sourceSurface = Draw::kBackSurface; + _vm->_draw->_destSurface = Draw::kCaptureSurface + _captureCount; _vm->_draw->_spriteLeft = left; _vm->_draw->_spriteRight = right - left + 1; @@ -425,13 +425,13 @@ void Game::capturePop(char doDraw) { _captureStack[_captureCount].height(); _vm->_draw->_transparency = 0; - _vm->_draw->_sourceSurface = 30 + _captureCount; - _vm->_draw->_destSurface = 21; + _vm->_draw->_sourceSurface = Draw::kCaptureSurface + _captureCount; + _vm->_draw->_destSurface = Draw::kBackSurface; _vm->_draw->_spriteLeft = _vm->_draw->_destSpriteX & 0xF; _vm->_draw->_spriteTop = 0; _vm->_draw->spriteOperation(0); } - _vm->_draw->freeSprite(30 + _captureCount); + _vm->_draw->freeSprite(Draw::kCaptureSurface + _captureCount); } void Game::freeSoundSlot(int16 slot) { diff --git a/engines/gob/hotspots.cpp b/engines/gob/hotspots.cpp index abdf513393..1edb7fc0cb 100644 --- a/engines/gob/hotspots.cpp +++ b/engines/gob/hotspots.cpp @@ -257,7 +257,7 @@ uint16 Hotspots::add(const Hotspot &hotspot) { // Remember the current script spot.script = _vm->_game->_script; - debugC(1, kDebugHotspots, "Adding hotspot %03d: %3d+%3d+%3d+%3d - %04X, %04X, %04X - %5d, %5d, %5d", + debugC(1, kDebugHotspots, "Adding hotspot %03d: Coord:%3d+%3d+%3d+%3d - id:%04X, key:%04X, flag:%04X - fcts:%5d, %5d, %5d", i, spot.left, spot.top, spot.right, spot.bottom, spot.id, spot.key, spot.flags, spot.funcEnter, spot.funcLeave, spot.funcPos); @@ -537,10 +537,12 @@ int16 Hotspots::curWindow(int16 &dx, int16 &dy) const { if (_vm->_global->_inter_mouseX < _vm->_draw->_fascinWin[i].left + 12 && _vm->_global->_inter_mouseY < _vm->_draw->_fascinWin[i].top + 12 && (VAR((_vm->_draw->_winVarArrayStatus / 4) + i) & 2)) + // Cursor on 'Close Window' return(5); if (_vm->_global->_inter_mouseX >= _vm->_draw->_fascinWin[i].left + _vm->_draw->_fascinWin[i].width - 12 && _vm->_global->_inter_mouseY < _vm->_draw->_fascinWin[i].top + 12 && (VAR((_vm->_draw->_winVarArrayStatus / 4) + i) & 4)) + // Cursor on 'Move Window' return(6); return(-i); } @@ -637,7 +639,6 @@ uint16 Hotspots::checkMouse(Type type, uint16 &id, uint16 &index) const { return kKeyEscape; return 0; - } return 0; @@ -798,11 +799,11 @@ uint16 Hotspots::check(uint8 handleMouse, int16 delay, uint16 &id, uint16 &index if (isValid(_currentKey, _currentId, _currentIndex)) enter(_currentIndex); } else { - WRITE_VAR(16, (int32) i); + WRITE_VAR(16, (int32)i); if (id) - id=0; + id = 0; if (index) - index=0; + index = 0; return(0); } } else @@ -1104,7 +1105,6 @@ uint16 Hotspots::updateInput(uint16 xPos, uint16 yPos, uint16 width, uint16 heig // Add character _vm->_util->insertStr(tempStr, str, pos - 1); } - } } } @@ -1204,13 +1204,13 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, // Type and window byte type = _vm->_game->_script->readByte(); - byte window = 0; + byte windowNum = 0; if ((type & 0x40) != 0) { // Got a window ID type -= 0x40; - window = _vm->_game->_script->readByte(); + windowNum = _vm->_game->_script->readByte(); } // Coordinates @@ -1238,21 +1238,21 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, _vm->_draw->_invalidatedRights[0] = 319; _vm->_draw->_invalidatedBottoms[0] = 199; _vm->_draw->_invalidatedCount = 1; - if (window == 0) { + if (windowNum == 0) { _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left + width - 1, top, left + width - 1, top + height - 1, 0); _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left, top + height - 1, 0); _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left + width - 1, top, 0); _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top + height - 1, left + width - 1, top + height - 1, 0); } else - if ((_vm->_draw->_fascinWin[window].id != -1) && (_vm->_draw->_fascinWin[window].id == _vm->_draw->_winCount - 1)) { - left += _vm->_draw->_fascinWin[window].left; - top += _vm->_draw->_fascinWin[window].top; + if ((_vm->_draw->_fascinWin[windowNum].id != -1) && (_vm->_draw->_fascinWin[windowNum].id == _vm->_draw->_winCount - 1)) { + left += _vm->_draw->_fascinWin[windowNum].left; + top += _vm->_draw->_fascinWin[windowNum].top; _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left + width - 1, top, left + width - 1, top + height - 1, 0); _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left, top + height - 1, 0); _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top, left + width - 1, top, 0); _vm->_video->drawLine(*_vm->_draw->_spritesArray[_vm->_draw->_destSurface], left, top + height - 1, left + width - 1, top + height - 1, 0); - left -= _vm->_draw->_fascinWin[window].left; - top -= _vm->_draw->_fascinWin[window].top; + left -= _vm->_draw->_fascinWin[windowNum].left; + top -= _vm->_draw->_fascinWin[windowNum].top; } } type &= 0x7F; @@ -1296,6 +1296,9 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, Font *font = 0; uint32 funcEnter = 0, funcLeave = 0; + if ((windowNum != 0) && (type != 0) && (type != 2)) + warning("evaluateNew - type %d, win %d\n",type, windowNum); + // Evaluate parameters for the new hotspot switch (type) { case kTypeNone: @@ -1308,7 +1311,7 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, _vm->_game->_script->skipBlock(); key = i + ((kStateFilled | kStateType2) << 12); - flags = type + (window << 8); + flags = type + (windowNum << 8); break; case kTypeMove: @@ -1325,7 +1328,7 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, if (key == 0) key = i + ((kStateFilled | kStateType2) << 12); - flags = type + (window << 8) + (flags << 4); + flags = type + (windowNum << 8) + (flags << 4); break; case kTypeInput1NoLeave: @@ -1390,12 +1393,15 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, ids[i] = _vm->_game->_script->readInt16(); flags = _vm->_game->_script->readInt16(); + if (flags > 3) + warning("evaluateNew: Warning, use of type 2 or 20. flags = %d, should be %d\n", flags, flags&3); + funcEnter = 0; funcLeave = _vm->_game->_script->pos(); _vm->_game->_script->skipBlock(); - flags = ((uint16) kTypeClick) + (window << 8) + (flags << 4); + flags = ((uint16) kTypeClick) + (windowNum << 8) + (flags << 4); break; case kTypeClickEnter: @@ -1408,7 +1414,7 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, funcLeave = 0; - flags = ((uint16) kTypeClick) + (window << 8) + (flags << 4); + flags = ((uint16) kTypeClick) + (windowNum << 8) + (flags << 4); break; } @@ -1418,8 +1424,10 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs, } bool Hotspots::evaluateFind(uint16 key, int16 timeVal, const uint16 *ids, - uint16 hotspotIndex1, uint16 hotspotIndex2, uint16 endIndex, - int16 &duration, uint16 &id, uint16 &index, bool &finished) { + uint16 leaveWindowIndex, uint16 hotspotIndex1, uint16 hotspotIndex2, + uint16 endIndex, int16 &duration, uint16 &id, uint16 &index, bool &finished) { + + bool fascinCheck = false; if (id != 0) // We already found a hotspot, nothing to do @@ -1442,8 +1450,10 @@ bool Hotspots::evaluateFind(uint16 key, int16 timeVal, const uint16 *ids, return false; } + if ((_vm->getGameType() == kGameTypeFascination) && (getCurrentHotspot())) + fascinCheck = true; - if (duration != 0) { + if ((duration != 0) && (!fascinCheck)) { // We've got a time duration if (hotspotIndex1 != 0) { @@ -1473,6 +1483,12 @@ bool Hotspots::evaluateFind(uint16 key, int16 timeVal, const uint16 *ids, return true; return false; + } else { + if (leaveWindowIndex != 0) + findNthPlain(leaveWindowIndex, endIndex, id, index); + + if (id != 0) + return true; } return false; @@ -1500,6 +1516,11 @@ void Hotspots::evaluate() { // Parameters of this block _vm->_game->_handleMouse = _vm->_game->_script->peekByte(0); int16 duration = _vm->_game->_script->peekByte(1); + + byte leaveWindowIndex = 0; + if ( _vm->getGameType() == kGameTypeFascination ) + leaveWindowIndex = _vm->_game->_script->peekByte(2); + byte hotspotIndex1 = _vm->_game->_script->peekByte(3); byte hotspotIndex2 = _vm->_game->_script->peekByte(4); bool needRecalculation = _vm->_game->_script->peekByte(5) != 0; @@ -1562,7 +1583,7 @@ void Hotspots::evaluate() { key = convertSpecialKey(key); // Try to find a fitting hotspot - Hotspots::evaluateFind(key, timeVal, ids, hotspotIndex1, hotspotIndex2, endIndex, + evaluateFind(key, timeVal, ids, leaveWindowIndex, hotspotIndex1, hotspotIndex2, endIndex, duration, id, index, finishedDuration); if (finishedDuration) @@ -1623,9 +1644,9 @@ int16 Hotspots::findCursor(uint16 x, uint16 y) const { int16 deltax = 0; int16 deltay = 0; - if ( _vm->getGameType() == kGameTypeFascination ) { + if ( _vm->getGameType() == kGameTypeFascination ) cursor = curWindow(deltax, deltay); - } + if (cursor == 0) { for (int i = 0; (i < kHotspotCount) && !_hotspots[i].isEnd(); i++) { const Hotspot &spot = _hotspots[i]; @@ -2082,7 +2103,7 @@ void Hotspots::getTextCursorPos(const Font &font, const char *str, } void Hotspots::fillRect(uint16 x, uint16 y, uint16 width, uint16 height, uint16 color) const { - _vm->_draw->_destSurface = 21; + _vm->_draw->_destSurface = Draw::kBackSurface; _vm->_draw->_destSpriteX = x; _vm->_draw->_destSpriteY = y; _vm->_draw->_spriteRight = width; diff --git a/engines/gob/hotspots.h b/engines/gob/hotspots.h index a7cbf9d6e8..cba400d5b6 100644 --- a/engines/gob/hotspots.h +++ b/engines/gob/hotspots.h @@ -104,7 +104,6 @@ public: /** implementation of oPlaytoons_F_1B code*/ void oPlaytoons_F_1B(); - private: struct Hotspot { uint16 id; @@ -225,8 +224,8 @@ private: uint16 &inputId, bool &hasInput, uint16 &inputCount); /** Find the hotspot requested by script commands. */ bool evaluateFind(uint16 key, int16 timeVal, const uint16 *ids, - uint16 hotspotIndex1, uint16 hotspotIndex2, uint16 endIndex, - int16 &duration, uint16 &id, uint16 &index, bool &finished); + uint16 leaveWindowIndex, uint16 hotspotIndex1, uint16 hotspotIndex2, + uint16 endIndex, int16 &duration, uint16 &id, uint16 &index, bool &finished); // Finding specific hotspots /** Find the hotspot index that corresponds to the input index. */ diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp index 24a8e0a390..3da71a2ba6 100644 --- a/engines/gob/init.cpp +++ b/engines/gob/init.cpp @@ -174,9 +174,11 @@ void Init::initGame() { _vm->_util->longDelay(200); // Letting everything settle - if (_vm->_vidPlayer->primaryOpen("coktel.imd")) { - _vm->_vidPlayer->primaryPlay(); - _vm->_vidPlayer->primaryClose(); + VideoPlayer::Properties props; + int slot; + if ((slot = _vm->_vidPlayer->openVideo(true, "coktel.imd", props)) >= 0) { + _vm->_vidPlayer->play(slot, props); + _vm->_vidPlayer->closeVideo(slot); } _vm->_draw->closeScreen(); diff --git a/engines/gob/inter_bargon.cpp b/engines/gob/inter_bargon.cpp index da8ca103aa..5c56196641 100644 --- a/engines/gob/inter_bargon.cpp +++ b/engines/gob/inter_bargon.cpp @@ -72,17 +72,47 @@ void Inter_Bargon::setupOpcodesGob() { } void Inter_Bargon::oBargon_intro0(OpGobParams ¶ms) { - if (_vm->_vidPlayer->primaryOpen("scaa", 0, 160)) { - _vm->_vidPlayer->primaryPlay(0, 92, 27, 0, 0, 0); - _vm->_vidPlayer->primaryClose(); - } + VideoPlayer::Properties props; + + props.x = 0; + props.y = 160; + props.startFrame = 0; + props.lastFrame = 92; + props.palCmd = 0; + props.palStart = 0; + props.palEnd = 0; + + int slot; + if ((slot = _vm->_vidPlayer->openVideo(true, "scaa", props)) < 0) + return; + + _vm->_vidPlayer->play(slot, props); + _vm->_vidPlayer->closeVideo(slot); } void Inter_Bargon::oBargon_intro1(OpGobParams ¶ms) { - if (_vm->_vidPlayer->primaryOpen("scaa", 0, 160)) { - _vm->_vidPlayer->primaryPlay(0, -1, 27, 0, 0, 0, 0, 0, true, 23); - _vm->_vidPlayer->primaryClose(); - } + VideoPlayer::Properties props; + + props.x = 0; + props.y = 160; + props.palCmd = 0; + props.palStart = 0; + props.palEnd = 0; + props.fade = true; + + int slot; + if ((slot = _vm->_vidPlayer->openVideo(true, "scaa", props)) < 0) + return; + + _vm->_vidPlayer->play(slot, props); + + props.startFrame = -1; + props.lastFrame = _vm->_vidPlayer->getFrameCount(slot) - 23; + props.fade = false; + + _vm->_vidPlayer->play(slot, props); + + _vm->_vidPlayer->closeVideo(slot); } void Inter_Bargon::oBargon_intro2(OpGobParams ¶ms) { @@ -178,45 +208,106 @@ void Inter_Bargon::oBargon_intro3(OpGobParams ¶ms) { } void Inter_Bargon::oBargon_intro4(OpGobParams ¶ms) { - if (_vm->_vidPlayer->primaryOpen("scba", 191, 54)) { - _vm->_vidPlayer->primaryPlay(0, -1, 27, 0, 0, 0, 0, 0, true); - _vm->_vidPlayer->primaryClose(); - } + VideoPlayer::Properties props; + + props.x = 191; + props.y = 54; + props.palCmd = 0; + props.palStart = 0; + props.palEnd = 0; + props.fade = true; + + int slot; + if ((slot = _vm->_vidPlayer->openVideo(true, "scba", props)) < 0) + return; + + _vm->_vidPlayer->play(slot, props); + _vm->_vidPlayer->closeVideo(slot); } void Inter_Bargon::oBargon_intro5(OpGobParams ¶ms) { - if (_vm->_vidPlayer->primaryOpen("scbb", 191, 54)) { - _vm->_vidPlayer->primaryPlay(0, -1, 27, 0, 0, 0); - _vm->_vidPlayer->primaryClose(); - } + VideoPlayer::Properties props; + + props.x = 191; + props.y = 54; + props.palCmd = 0; + props.palStart = 0; + props.palEnd = 0; + + int slot; + if ((slot = _vm->_vidPlayer->openVideo(true, "scbb", props)) < 0) + return; + + _vm->_vidPlayer->play(slot, props); + _vm->_vidPlayer->closeVideo(slot); } void Inter_Bargon::oBargon_intro6(OpGobParams ¶ms) { - if (_vm->_vidPlayer->primaryOpen("scbc", 191, 54)) { - _vm->_vidPlayer->primaryPlay(0, -1, 27, 0, 0, 0); - _vm->_vidPlayer->primaryClose(); - } + VideoPlayer::Properties props; + + props.x = 191; + props.y = 54; + props.palCmd = 0; + props.palStart = 0; + props.palEnd = 0; + + int slot; + if ((slot = _vm->_vidPlayer->openVideo(true, "scbc", props)) < 0) + return; + + _vm->_vidPlayer->play(slot, props); + _vm->_vidPlayer->closeVideo(slot); } void Inter_Bargon::oBargon_intro7(OpGobParams ¶ms) { - if (_vm->_vidPlayer->primaryOpen("scbf", 191, 54)) { - _vm->_vidPlayer->primaryPlay(0, -1, 27, 0, 0, 0); - _vm->_vidPlayer->primaryClose(); - } + VideoPlayer::Properties props; + + props.x = 191; + props.y = 54; + props.palCmd = 0; + props.palStart = 0; + props.palEnd = 0; + + int slot; + if ((slot = _vm->_vidPlayer->openVideo(true, "scbf", props)) < 0) + return; + + _vm->_vidPlayer->play(slot, props); + _vm->_vidPlayer->closeVideo(slot); } void Inter_Bargon::oBargon_intro8(OpGobParams ¶ms) { - if (_vm->_vidPlayer->primaryOpen("scbc", 191, 54)) { - _vm->_vidPlayer->primaryPlay(0, -1, 27, 0, 0, 0); - _vm->_vidPlayer->primaryClose(); - } + VideoPlayer::Properties props; + + props.x = 191; + props.y = 54; + props.palCmd = 0; + props.palStart = 0; + props.palEnd = 0; + + int slot; + if ((slot = _vm->_vidPlayer->openVideo(true, "scbc", props)) < 0) + return; + + _vm->_vidPlayer->play(slot, props); + _vm->_vidPlayer->closeVideo(slot); } void Inter_Bargon::oBargon_intro9(OpGobParams ¶ms) { - if (_vm->_vidPlayer->primaryOpen("scbd", 191, 54)) { - _vm->_vidPlayer->primaryPlay(0, -1, 27, 0, 0, 0); - _vm->_vidPlayer->primaryClose(); - } + VideoPlayer::Properties props; + + props.x = 191; + props.y = 54; + props.palCmd = 0; + props.palStart = 0; + props.palEnd = 0; + + int slot; + if ((slot = _vm->_vidPlayer->openVideo(true, "scbd", props)) < 0) + return; + + _vm->_vidPlayer->play(slot, props); + _vm->_vidPlayer->closeVideo(slot); } } // End of namespace Gob diff --git a/engines/gob/inter_fascin.cpp b/engines/gob/inter_fascin.cpp index 5738197539..304f02f4fa 100644 --- a/engines/gob/inter_fascin.cpp +++ b/engines/gob/inter_fascin.cpp @@ -131,21 +131,41 @@ bool Inter_Fascination::oFascin_copySprite(OpFuncParams ¶ms) { void Inter_Fascination::oFascin_playTirb(OpGobParams ¶ms) { warning("funcPlayImd with parameter : 'tirb.imd'"); - if (_vm->_vidPlayer->primaryOpen("tirb", 150, 88, VideoPlayer::kFlagFrontSurface, - VideoPlayer::kVideoTypePreIMD, 128, 80)) { - _vm->_vidPlayer->primaryPlay(); - _vm->_vidPlayer->primaryClose(); - } + VideoPlayer::Properties vidProps; + + vidProps.type = VideoPlayer::kVideoTypePreIMD; + vidProps.sprite = Draw::kFrontSurface; + vidProps.x = 150; + vidProps.y = 88; + vidProps.width = 128; + vidProps.height = 80; + + int vidSlot = _vm->_vidPlayer->openVideo(true, "tirb", vidProps); + if (vidSlot < 0) + return; + + _vm->_vidPlayer->play(vidSlot, vidProps); + _vm->_vidPlayer->closeVideo(vidSlot); } void Inter_Fascination::oFascin_playTira(OpGobParams ¶ms) { warning("funcPlayImd with parameter : 'tira.imd'"); - if (_vm->_vidPlayer->primaryOpen("tira", 88, 66, VideoPlayer::kFlagFrontSurface, - VideoPlayer::kVideoTypePreIMD, 128, 80)) { - _vm->_vidPlayer->primaryPlay(); - _vm->_vidPlayer->primaryClose(); - } + VideoPlayer::Properties vidProps; + + vidProps.type = VideoPlayer::kVideoTypePreIMD; + vidProps.sprite = Draw::kFrontSurface; + vidProps.x = 88; + vidProps.y = 66; + vidProps.width = 128; + vidProps.height = 80; + + int vidSlot = _vm->_vidPlayer->openVideo(true, "tira", vidProps); + if (vidSlot < 0) + return; + + _vm->_vidPlayer->play(vidSlot, vidProps); + _vm->_vidPlayer->closeVideo(vidSlot); } void Inter_Fascination::oFascin_loadExtasy(OpGobParams ¶ms) { diff --git a/engines/gob/inter_playtoons.cpp b/engines/gob/inter_playtoons.cpp index 142467b47f..befed4b1c2 100644 --- a/engines/gob/inter_playtoons.cpp +++ b/engines/gob/inter_playtoons.cpp @@ -107,7 +107,7 @@ bool Inter_Playtoons::oPlaytoons_printText(OpFuncParams ¶ms) { _vm->_draw->_backColor = _vm->_game->_script->readValExpr(); _vm->_draw->_frontColor = _vm->_game->_script->readValExpr(); _vm->_draw->_fontIndex = _vm->_game->_script->readValExpr(); - _vm->_draw->_destSurface = 21; + _vm->_draw->_destSurface = Draw::kBackSurface; _vm->_draw->_textToPrint = buf; _vm->_draw->_transparency = 0; diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp index 9e841e7e68..11fe0c9c5e 100644 --- a/engines/gob/inter_v1.cpp +++ b/engines/gob/inter_v1.cpp @@ -328,7 +328,7 @@ void Inter_v1::o1_initCursor() { (height != _vm->_draw->_cursorHeight) || (_vm->_draw->_cursorSprites->getWidth() != (width * count))) { - _vm->_draw->freeSprite(23); + _vm->_draw->freeSprite(Draw::kCursorSurface); _vm->_draw->_cursorSprites.reset(); _vm->_draw->_cursorSpritesBack.reset(); _vm->_draw->_scummvmCursor.reset(); @@ -344,9 +344,9 @@ void Inter_v1::o1_initCursor() { if (count > 0x80) count -= 0x80; - _vm->_draw->initSpriteSurf(23, _vm->_draw->_cursorWidth * count, + _vm->_draw->initSpriteSurf(Draw::kCursorSurface, _vm->_draw->_cursorWidth * count, _vm->_draw->_cursorHeight, 2); - _vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[23]; + _vm->_draw->_cursorSpritesBack = _vm->_draw->_spritesArray[Draw::kCursorSurface]; _vm->_draw->_cursorSprites = _vm->_draw->_cursorSpritesBack; _vm->_draw->_scummvmCursor = @@ -482,14 +482,14 @@ void Inter_v1::o1_initMult() { if (_vm->_mult->_animSurf && ((oldAnimWidth != _vm->_mult->_animWidth) || (oldAnimHeight != _vm->_mult->_animHeight))) { - _vm->_draw->freeSprite(22); + _vm->_draw->freeSprite(Draw::kAnimSurface); _vm->_mult->_animSurf.reset(); } if (!_vm->_mult->_animSurf) { - _vm->_draw->initSpriteSurf(22, _vm->_mult->_animWidth, + _vm->_draw->initSpriteSurf(Draw::kAnimSurface, _vm->_mult->_animWidth, _vm->_mult->_animHeight, 0); - _vm->_mult->_animSurf = _vm->_draw->_spritesArray[22]; + _vm->_mult->_animSurf = _vm->_draw->_spritesArray[Draw::kAnimSurface]; } _vm->_video->drawSprite(*_vm->_draw->_backSurface, *_vm->_mult->_animSurf, @@ -922,7 +922,7 @@ bool Inter_v1::o1_printText(OpFuncParams ¶ms) { _vm->_draw->_backColor = _vm->_game->_script->readValExpr(); _vm->_draw->_frontColor = _vm->_game->_script->readValExpr(); _vm->_draw->_fontIndex = _vm->_game->_script->readValExpr(); - _vm->_draw->_destSurface = 21; + _vm->_draw->_destSurface = Draw::kBackSurface; _vm->_draw->_textToPrint = buf; _vm->_draw->_transparency = 0; diff --git a/engines/gob/inter_v2.cpp b/engines/gob/inter_v2.cpp index 72764eec8d..0003332e47 100644 --- a/engines/gob/inter_v2.cpp +++ b/engines/gob/inter_v2.cpp @@ -360,24 +360,24 @@ void Inter_v2::o2_initMult() { if (_vm->_mult->_animSurf && ((oldAnimWidth != _vm->_mult->_animWidth) || (oldAnimHeight != _vm->_mult->_animHeight))) { - _vm->_draw->freeSprite(22); + _vm->_draw->freeSprite(Draw::kAnimSurface); _vm->_mult->_animSurf.reset(); } _vm->_draw->adjustCoords(0, &_vm->_mult->_animWidth, &_vm->_mult->_animHeight); if (!_vm->_mult->_animSurf) { - _vm->_draw->initSpriteSurf(22, _vm->_mult->_animWidth, + _vm->_draw->initSpriteSurf(Draw::kAnimSurface, _vm->_mult->_animWidth, _vm->_mult->_animHeight, 0); - _vm->_mult->_animSurf = _vm->_draw->_spritesArray[22]; + _vm->_mult->_animSurf = _vm->_draw->_spritesArray[Draw::kAnimSurface]; if (_terminate) return; } _vm->_draw->adjustCoords(1, &_vm->_mult->_animWidth, &_vm->_mult->_animHeight); - _vm->_draw->_sourceSurface = 21; - _vm->_draw->_destSurface = 22; + _vm->_draw->_sourceSurface = Draw::kBackSurface; + _vm->_draw->_destSurface = Draw::kAnimSurface; _vm->_draw->_spriteLeft = _vm->_mult->_animLeft; _vm->_draw->_spriteTop = _vm->_mult->_animTop; _vm->_draw->_spriteRight = _vm->_mult->_animWidth; @@ -481,7 +481,7 @@ void Inter_v2::o2_loadMultObject() { if ((((int32) *(obj.pPosX)) == -1234) && (((int32) *(obj.pPosY)) == -4321)) { if (obj.videoSlot > 0) - _vm->_vidPlayer->slotClose(obj.videoSlot - 1); + _vm->_vidPlayer->closeVideo(obj.videoSlot - 1); obj.videoSlot = 0; obj.lastLeft = -1; @@ -959,50 +959,50 @@ void Inter_v2::o2_setScrollOffset() { void Inter_v2::o2_playImd() { char imd[128]; - int16 x, y; - int16 startFrame; - int16 lastFrame; - int16 breakKey; - int16 flags; - int16 palStart; - int16 palEnd; - uint16 palCmd; bool close; _vm->_game->_script->evalExpr(0); _vm->_game->_script->getResultStr()[8] = 0; strncpy0(imd, _vm->_game->_script->getResultStr(), 127); - x = _vm->_game->_script->readValExpr(); - y = _vm->_game->_script->readValExpr(); - startFrame = _vm->_game->_script->readValExpr(); - lastFrame = _vm->_game->_script->readValExpr(); - breakKey = _vm->_game->_script->readValExpr(); - flags = _vm->_game->_script->readValExpr(); - palStart = _vm->_game->_script->readValExpr(); - palEnd = _vm->_game->_script->readValExpr(); - palCmd = 1 << (flags & 0x3F); + VideoPlayer::Properties props; - debugC(1, kDebugVideo, "Playing video \"%s\" @ %d+%d, frames %d - %d, " - "paletteCmd %d (%d - %d), flags %X", _vm->_game->_script->getResultStr(), x, y, - startFrame, lastFrame, palCmd, palStart, palEnd, flags); + props.x = _vm->_game->_script->readValExpr(); + props.y = _vm->_game->_script->readValExpr(); + props.startFrame = _vm->_game->_script->readValExpr(); + props.lastFrame = _vm->_game->_script->readValExpr(); + props.breakKey = _vm->_game->_script->readValExpr(); + props.flags = _vm->_game->_script->readValExpr(); + props.palStart = _vm->_game->_script->readValExpr(); + props.palEnd = _vm->_game->_script->readValExpr(); + props.palCmd = 1 << (props.flags & 0x3F); - if ((imd[0] != 0) && !_vm->_vidPlayer->primaryOpen(imd, x, y, flags)) { - WRITE_VAR(11, (uint32) -1); - return; + debugC(1, kDebugVideo, "Playing video \"%s\" @ %d+%d, frames %d - %d, " + "paletteCmd %d (%d - %d), flags %X", imd, + props.x, props.y, props.startFrame, props.lastFrame, + props.palCmd, props.palStart, props.palEnd, props.flags); + + int slot = 0; + if (imd[0] != 0) { + _vm->_vidPlayer->evaluateFlags(props); + if ((slot = _vm->_vidPlayer->openVideo(true, imd, props)) < 0) { + WRITE_VAR(11, (uint32) -1); + return; + } } - close = (lastFrame == -1); - if (startFrame == -2) { - startFrame = lastFrame = 0; + close = (props.lastFrame == -1); + if (props.startFrame == -2) { + props.startFrame = 0; + props.lastFrame = 0; close = false; } - if (startFrame >= 0) - _vm->_vidPlayer->primaryPlay(startFrame, lastFrame, breakKey, palCmd, palStart, palEnd, 0); + if (props.startFrame >= 0) + _vm->_vidPlayer->play(slot, props); if (close) - _vm->_vidPlayer->primaryClose(); + _vm->_vidPlayer->closeVideo(slot); } void Inter_v2::o2_getImdInfo() { @@ -1011,10 +1011,10 @@ void Inter_v2::o2_getImdInfo() { int16 varWidth, varHeight; _vm->_game->_script->evalExpr(0); - varX = _vm->_game->_script->readVarIndex(); - varY = _vm->_game->_script->readVarIndex(); + varX = _vm->_game->_script->readVarIndex(); + varY = _vm->_game->_script->readVarIndex(); varFrames = _vm->_game->_script->readVarIndex(); - varWidth = _vm->_game->_script->readVarIndex(); + varWidth = _vm->_game->_script->readVarIndex(); varHeight = _vm->_game->_script->readVarIndex(); // WORKAROUND: The nut rolling animation in the administration center @@ -1106,7 +1106,7 @@ bool Inter_v2::o2_printText(OpFuncParams ¶ms) { _vm->_draw->_backColor = _vm->_game->_script->readValExpr(); _vm->_draw->_frontColor = _vm->_game->_script->readValExpr(); _vm->_draw->_fontIndex = _vm->_game->_script->readValExpr(); - _vm->_draw->_destSurface = 21; + _vm->_draw->_destSurface = Draw::kBackSurface; _vm->_draw->_textToPrint = buf; _vm->_draw->_transparency = 0; diff --git a/engines/gob/inter_v3.cpp b/engines/gob/inter_v3.cpp index beace1b7d8..10ed23619d 100644 --- a/engines/gob/inter_v3.cpp +++ b/engines/gob/inter_v3.cpp @@ -253,8 +253,8 @@ bool Inter_v3::o3_copySprite(OpFuncParams ¶ms) { o1_copySprite(params); // For the close-up "fading" in the CD version - if (_vm->_draw->_destSurface == 20) - _vm->_video->sparseRetrace(20); + if (_vm->_draw->_destSurface == Draw::kFrontSurface) + _vm->_video->sparseRetrace(Draw::kFrontSurface); return false; } diff --git a/engines/gob/inter_v4.cpp b/engines/gob/inter_v4.cpp index 1f6899d85c..d0824ffb58 100644 --- a/engines/gob/inter_v4.cpp +++ b/engines/gob/inter_v4.cpp @@ -142,14 +142,6 @@ void Inter_v4::o4_initScreen() { void Inter_v4::o4_playVmdOrMusic() { char fileName[128]; - int16 x, y; - int16 startFrame; - int16 lastFrame; - int16 breakKey; - int16 flags; - int16 palStart; - int16 palEnd; - uint16 palCmd; bool close; _vm->_game->_script->evalExpr(0); @@ -161,83 +153,92 @@ void Inter_v4::o4_playVmdOrMusic() { (!scumm_stricmp(fileName, "noixroule"))) strcpy(fileName, "noixroul"); - x = _vm->_game->_script->readValExpr(); - y = _vm->_game->_script->readValExpr(); - startFrame = _vm->_game->_script->readValExpr(); - lastFrame = _vm->_game->_script->readValExpr(); - breakKey = _vm->_game->_script->readValExpr(); - flags = _vm->_game->_script->readValExpr(); - palStart = _vm->_game->_script->readValExpr(); - palEnd = _vm->_game->_script->readValExpr(); - palCmd = 1 << (flags & 0x3F); + VideoPlayer::Properties props; + + props.x = _vm->_game->_script->readValExpr(); + props.y = _vm->_game->_script->readValExpr(); + props.startFrame = _vm->_game->_script->readValExpr(); + props.lastFrame = _vm->_game->_script->readValExpr(); + props.breakKey = _vm->_game->_script->readValExpr(); + props.flags = _vm->_game->_script->readValExpr(); + props.palStart = _vm->_game->_script->readValExpr(); + props.palEnd = _vm->_game->_script->readValExpr(); + props.palCmd = 1 << (props.flags & 0x3F); debugC(1, kDebugVideo, "Playing video \"%s\" @ %d+%d, frames %d - %d, " - "paletteCmd %d (%d - %d), flags %X", fileName, x, y, startFrame, lastFrame, - palCmd, palStart, palEnd, flags); + "paletteCmd %d (%d - %d), flags %X", fileName, + props.x, props.y, props.startFrame, props.lastFrame, + props.palCmd, props.palStart, props.palEnd, props.flags); close = false; - if (lastFrame == -1) { + if (props.lastFrame == -1) { close = true; - } else if (lastFrame == -2) { - } else if (lastFrame == -3) { + } else if (props.lastFrame == -2) { + } else if (props.lastFrame == -3) { + + props.flags = VideoPlayer::kFlagOtherSurface; + props.sprite = -1; - _vm->_mult->_objects[startFrame].pAnimData->animation = -startFrame - 1; + _vm->_mult->_objects[props.startFrame].pAnimData->animation = -props.startFrame - 1; - if (_vm->_mult->_objects[startFrame].videoSlot > 0) - _vm->_vidPlayer->slotClose(_vm->_mult->_objects[startFrame].videoSlot - 1); + if (_vm->_mult->_objects[props.startFrame].videoSlot > 0) + _vm->_vidPlayer->closeVideo(_vm->_mult->_objects[props.startFrame].videoSlot - 1); - int slot = _vm->_vidPlayer->slotOpen(fileName); + int slot = _vm->_vidPlayer->openVideo(false, fileName, props); - _vm->_mult->_objects[startFrame].videoSlot = slot + 1; + _vm->_mult->_objects[props.startFrame].videoSlot = slot + 1; - if (x == -1) { - *_vm->_mult->_objects[startFrame].pPosX = _vm->_vidPlayer->getDefaultX(slot); - *_vm->_mult->_objects[startFrame].pPosY = _vm->_vidPlayer->getDefaultY(slot); + if (props.x == -1) { + *_vm->_mult->_objects[props.startFrame].pPosX = _vm->_vidPlayer->getDefaultX(slot); + *_vm->_mult->_objects[props.startFrame].pPosY = _vm->_vidPlayer->getDefaultY(slot); } else { - *_vm->_mult->_objects[startFrame].pPosX = x; - *_vm->_mult->_objects[startFrame].pPosY = y; + *_vm->_mult->_objects[props.startFrame].pPosX = props.x; + *_vm->_mult->_objects[props.startFrame].pPosY = props.y; } return; - } else if (lastFrame == -4) { + } else if (props.lastFrame == -4) { warning("Woodruff Stub: Video/Music command -4: Play background video %s", fileName); return; - } else if (lastFrame == -5) { + } else if (props.lastFrame == -5) { _vm->_sound->bgStop(); return; - } else if (lastFrame == -6) { + } else if (props.lastFrame == -6) { return; - } else if (lastFrame == -7) { + } else if (props.lastFrame == -7) { return; - } else if (lastFrame == -8) { + } else if (props.lastFrame == -8) { warning("Woodruff Stub: Video/Music command -8: Play background video %s", fileName); return; - } else if (lastFrame == -9) { + } else if (props.lastFrame == -9) { _vm->_sound->bgStop(); _vm->_sound->bgSetPlayMode(BackgroundAtmosphere::kPlayModeRandom); - _vm->_sound->bgPlay(fileName, "SND", SOUND_SND, palStart); + _vm->_sound->bgPlay(fileName, "SND", SOUND_SND, props.palStart); return; - } else if (lastFrame < 0) { - warning("Unknown Video/Music command: %d, %s", lastFrame, fileName); + } else if (props.lastFrame < 0) { + warning("Unknown Video/Music command: %d, %s", props.lastFrame, fileName); return; } - if (startFrame == -2) { - startFrame = 0; - lastFrame = -1; + if (props.startFrame == -2) { + props.startFrame = 0; + props.lastFrame = -1; close = false; } - if ((fileName[0] != 0) && !_vm->_vidPlayer->primaryOpen(fileName, x, y, flags)) { + _vm->_vidPlayer->evaluateFlags(props); + + int slot; + if ((fileName[0] != 0) && ((slot = _vm->_vidPlayer->openVideo(true, fileName, props)) < 0)) { WRITE_VAR(11, (uint32) -1); return; } - if (startFrame >= 0) - _vm->_vidPlayer->primaryPlay(startFrame, lastFrame, breakKey, palCmd, palStart, palEnd, 0); + if (props.startFrame >= 0) + _vm->_vidPlayer->play(slot, props); if (close) - _vm->_vidPlayer->primaryClose(); + _vm->_vidPlayer->closeVideo(slot); } } // End of namespace Gob diff --git a/engines/gob/inter_v6.cpp b/engines/gob/inter_v6.cpp index cbc831b5a1..73ef46bf31 100644 --- a/engines/gob/inter_v6.cpp +++ b/engines/gob/inter_v6.cpp @@ -102,88 +102,86 @@ void Inter_v6::o6_totSub() { void Inter_v6::o6_playVmdOrMusic() { char fileName[128]; - int16 x, y; - int16 startFrame; - int16 lastFrame; - int16 breakKey; - int16 flags; - int16 palStart; - int16 palEnd; - uint16 palCmd; bool close; _vm->_game->_script->evalExpr(0); strncpy0(fileName, _vm->_game->_script->getResultStr(), 127); - x = _vm->_game->_script->readValExpr(); - y = _vm->_game->_script->readValExpr(); - startFrame = _vm->_game->_script->readValExpr(); - lastFrame = _vm->_game->_script->readValExpr(); - breakKey = _vm->_game->_script->readValExpr(); - flags = _vm->_game->_script->readValExpr(); - palStart = _vm->_game->_script->readValExpr(); - palEnd = _vm->_game->_script->readValExpr(); - palCmd = 1 << (flags & 0x3F); + VideoPlayer::Properties props; + + props.x = _vm->_game->_script->readValExpr(); + props.y = _vm->_game->_script->readValExpr(); + props.startFrame = _vm->_game->_script->readValExpr(); + props.lastFrame = _vm->_game->_script->readValExpr(); + props.breakKey = _vm->_game->_script->readValExpr(); + props.flags = _vm->_game->_script->readValExpr(); + props.palStart = _vm->_game->_script->readValExpr(); + props.palEnd = _vm->_game->_script->readValExpr(); + props.palCmd = 1 << (props.flags & 0x3F); + props.forceSeek = true; debugC(1, kDebugVideo, "Playing video \"%s\" @ %d+%d, frames %d - %d, " - "paletteCmd %d (%d - %d), flags %X", fileName, x, y, startFrame, lastFrame, - palCmd, palStart, palEnd, flags); + "paletteCmd %d (%d - %d), flags %X", fileName, + props.x, props.y, props.startFrame, props.lastFrame, + props.palCmd, props.palStart, props.palEnd, props.flags); close = false; - if (lastFrame == -1) { + if (props.lastFrame == -1) { close = true; - } else if (lastFrame == -5) { + } else if (props.lastFrame == -5) { // warning("Urban/Playtoons Stub: Stop without delay"); _vm->_sound->bgStop(); return; - } else if (lastFrame == -6) { + } else if (props.lastFrame == -6) { // warning("Urban/Playtoons Stub: Video/Music command -6 (cache video)"); return; - } else if (lastFrame == -7) { + } else if (props.lastFrame == -7) { // warning("Urban/Playtoons Stub: Video/Music command -6 (flush cache)"); return; - } else if ((lastFrame == -8) || (lastFrame == -9)) { + } else if ((props.lastFrame == -8) || (props.lastFrame == -9)) { if (!strchr(fileName, '.')) strcat(fileName, ".WA8"); probe16bitMusic(fileName); - if (lastFrame == -9) { + if (props.lastFrame == -9) { warning("Urban/Playtoons Stub: delayed stop not implemented"); } _vm->_sound->bgStop(); _vm->_sound->bgPlay(fileName, SOUND_WAV); return; - } else if (lastFrame <= -10) { - _vm->_vidPlayer->primaryClose(); - warning("Urban/Playtoons Stub: Video/Music command %d (close video?), %s", lastFrame, fileName); - if (lastFrame <= -100) - lastFrame += 100; + } else if (props.lastFrame <= -10) { + _vm->_vidPlayer->closeVideo(); + warning("Urban/Playtoons Stub: Video/Music command %d (close video?), %s", props.lastFrame, fileName); + if (props.lastFrame <= -100) + props.lastFrame += 100; - if (((-lastFrame) % 10 == 3) && (lastFrame <= -20)) + if (((-props.lastFrame) % 10 == 3) && (props.lastFrame <= -20)) _vm->_sound->bgPlay(fileName, SOUND_WAV); - } else if (lastFrame < 0) { - warning("Urban/Playtoons Stub: Unknown Video/Music command: %d, %s", lastFrame, fileName); + } else if (props.lastFrame < 0) { + warning("Urban/Playtoons Stub: Unknown Video/Music command: %d, %s", props.lastFrame, fileName); return; } - if (startFrame == -2) { - startFrame = 0; - lastFrame = -1; + if (props.startFrame == -2) { + props.startFrame = 0; + props.lastFrame = -1; close = false; } - if ((fileName[0] != 0) && !_vm->_vidPlayer->primaryOpen(fileName, x, y, flags)) { + _vm->_vidPlayer->evaluateFlags(props); + + int slot; + if ((fileName[0] != 0) && ((slot = _vm->_vidPlayer->openVideo(true, fileName, props)) < 0)) { WRITE_VAR(11, (uint32) -1); return; } - if (startFrame >= 0) - _vm->_vidPlayer->primaryPlay(startFrame, lastFrame, breakKey, - palCmd, palStart, palEnd, 0, -1, false, -1, true); + if (props.startFrame >= 0) + _vm->_vidPlayer->play(slot, props); if (close) - _vm->_vidPlayer->primaryClose(); + _vm->_vidPlayer->closeVideo(slot); } void Inter_v6::o6_openItk() { @@ -224,24 +222,30 @@ bool Inter_v6::o6_loadCursor(OpFuncParams ¶ms) { uint16 start = _vm->_game->_script->readUint16(); int8 index = _vm->_game->_script->readInt8(); - int vmdSlot = _vm->_vidPlayer->slotOpen(file); + VideoPlayer::Properties props; + props.sprite = -1; + + int vmdSlot = _vm->_vidPlayer->openVideo(false, file, props); if (vmdSlot == -1) { warning("Can't open video \"%s\" as cursor", file); return false; } - int16 framesCount = _vm->_vidPlayer->getFramesCount(vmdSlot); + int16 framesCount = _vm->_vidPlayer->getFrameCount(vmdSlot); for (int i = 0; i < framesCount; i++) { - _vm->_vidPlayer->slotPlay(vmdSlot); - _vm->_vidPlayer->slotCopyFrame(vmdSlot, _vm->_draw->_cursorSprites->getVidMem(), + props.startFrame = i; + props.lastFrame = i; + + _vm->_vidPlayer->play(vmdSlot, props); + _vm->_vidPlayer->copyFrame(vmdSlot, _vm->_draw->_cursorSprites->getVidMem(), 0, 0, _vm->_draw->_cursorWidth, _vm->_draw->_cursorWidth, (start + i) * _vm->_draw->_cursorWidth, 0, _vm->_draw->_cursorSprites->getWidth()); } - _vm->_vidPlayer->slotClose(vmdSlot); + _vm->_vidPlayer->closeVideo(vmdSlot); _vm->_draw->_cursorAnimLow[index] = start; _vm->_draw->_cursorAnimHigh[index] = framesCount + start - 1; diff --git a/engines/gob/mult.cpp b/engines/gob/mult.cpp index 327b3ed1bd..f744f14faf 100644 --- a/engines/gob/mult.cpp +++ b/engines/gob/mult.cpp @@ -146,7 +146,7 @@ void Mult::freeMult() { _orderArray = 0; _animSurf.reset(); - _vm->_draw->freeSprite(22); + _vm->_draw->freeSprite(Draw::kAnimSurface); } void Mult::checkFreeMult() { @@ -238,7 +238,7 @@ void Mult::playMult(int16 startFrame, int16 endFrame, char checkEscape, _orderArray = 0; _animSurf.reset(); - _vm->_draw->freeSprite(22); + _vm->_draw->freeSprite(Draw::kAnimSurface); _animDataAllocated = false; } @@ -452,7 +452,7 @@ void Mult::clearObjectVideos() { for (int i = 0; i < _objCount; i++) if (_objects[i].videoSlot > 0) - _vm->_vidPlayer->slotClose(_objects[i].videoSlot - 1); + _vm->_vidPlayer->closeVideo(_objects[i].videoSlot - 1); } } // End of namespace Gob diff --git a/engines/gob/mult_v1.cpp b/engines/gob/mult_v1.cpp index 1bb162c789..84869066e1 100644 --- a/engines/gob/mult_v1.cpp +++ b/engines/gob/mult_v1.cpp @@ -236,7 +236,7 @@ void Mult_v1::freeMultKeys() { _animArrayData = 0; _animSurf.reset(); - _vm->_draw->freeSprite(22); + _vm->_draw->freeSprite(Draw::kAnimSurface); _animDataAllocated = false; } @@ -318,7 +318,7 @@ void Mult_v1::playMultInit() { _animSurf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, 320, 200, 0); - _vm->_draw->_spritesArray[22] = _animSurf; + _vm->_draw->_spritesArray[Draw::kAnimSurface] = _animSurf; _vm->_video->drawSprite(*_vm->_draw->_backSurface, *_animSurf, 0, 0, 319, 199, 0, 0, 0); @@ -579,8 +579,8 @@ void Mult_v1::animate() { if ((pNeedRedraw[i] == 0) || (_objects[i].lastLeft == -1)) continue; - _vm->_draw->_sourceSurface = 22; - _vm->_draw->_destSurface = 21; + _vm->_draw->_sourceSurface = Draw::kAnimSurface; + _vm->_draw->_destSurface = Draw::kBackSurface; _vm->_draw->_spriteLeft = pDirtyLefts[i] - _animLeft; _vm->_draw->_spriteTop = pDirtyTops[i] - _animTop; _vm->_draw->_spriteRight = pDirtyRights[i] - pDirtyLefts[i] + 1; diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index 6acd096e58..66488054e7 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -579,11 +579,11 @@ void Mult_v2::playMultInit() { width = _animWidth; height = _animHeight; _vm->_draw->adjustCoords(0, &width, &height); - _vm->_draw->initSpriteSurf(22, width, height, 0); - _animSurf = _vm->_draw->_spritesArray[22]; + _vm->_draw->initSpriteSurf(Draw::kAnimSurface, width, height, 0); + _animSurf = _vm->_draw->_spritesArray[Draw::kAnimSurface]; - _vm->_video->drawSprite(*_vm->_draw->_spritesArray[21], - *_vm->_draw->_spritesArray[22], 0, 0, + _vm->_video->drawSprite(*_vm->_draw->_spritesArray[Draw::kBackSurface], + *_vm->_draw->_spritesArray[Draw::kAnimSurface], 0, 0, _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0, 0, 0); for (_counter = 0; _counter < _objCount; _counter++) @@ -633,14 +633,14 @@ void Mult_v2::drawStatics(bool &stop) { READ_LE_UINT16(_multData->execPtr + layer * 2); _vm->_draw->_destSpriteX = 0; _vm->_draw->_destSpriteY = 0; - _vm->_draw->_destSurface = 21; + _vm->_draw->_destSurface = Draw::kBackSurface; _vm->_draw->_transparency = 0; _vm->_draw->spriteOperation(DRAW_LOADSPRITE); _vm->_scenery->_curStatic = -1; } - _vm->_video->drawSprite(*_vm->_draw->_spritesArray[21], - *_vm->_draw->_spritesArray[22], 0, 0, + _vm->_video->drawSprite(*_vm->_draw->_spritesArray[Draw::kBackSurface], + *_vm->_draw->_spritesArray[Draw::kAnimSurface], 0, 0, _vm->_video->_surfWidth, _vm->_video->_surfHeight, 0, 0, 0); } } @@ -710,7 +710,7 @@ void Mult_v2::newCycleAnim(Mult_Object &animObj) { } else { if (animObj.videoSlot > 0) { _vm->_video->retrace(); - _vm->_vidPlayer->slotWaitEndFrame(animObj.videoSlot - 1, true); + _vm->_vidPlayer->waitEndFrame(animObj.videoSlot - 1, true); } } @@ -736,8 +736,8 @@ void Mult_v2::newCycleAnim(Mult_Object &animObj) { if (animData.animation < 0) { if ((animObj.videoSlot > 0) && - (_vm->_vidPlayer->getCurrentFrame(animObj.videoSlot - 1) < - _vm->_vidPlayer->getFramesCount(animObj.videoSlot - 1))) { + ((_vm->_vidPlayer->getCurrentFrame(animObj.videoSlot - 1) + 1) < + _vm->_vidPlayer->getFrameCount(animObj.videoSlot - 1))) { animData.newCycle = 0; return; } @@ -775,7 +775,7 @@ void Mult_v2::newCycleAnim(Mult_Object &animObj) { animData.isStatic = 1; animData.frame = 0; if ((animData.animation < 0) && (animObj.videoSlot > 0)) { - _vm->_vidPlayer->slotClose(animObj.videoSlot - 1); + _vm->_vidPlayer->closeVideo(animObj.videoSlot - 1); animObj.videoSlot = 0; } @@ -788,7 +788,7 @@ void Mult_v2::newCycleAnim(Mult_Object &animObj) { /* if ((animData.animation < 0) && (animObj.videoSlot > 0)) { if (_vm->_vidPlayer->getFlags(animObj.videoSlot - 1) & 0x1000) { - _vm->_vidPlayer->slotClose(animObj.videoSlot - 1); + _vm->_vidPlayer->closeVideo(animObj.videoSlot - 1); animObj.videoSlot = 0; } } @@ -937,8 +937,8 @@ void Mult_v2::animate() { if ((right <= 0) || (bottom <= 0)) continue; - _vm->_draw->_sourceSurface = 22; - _vm->_draw->_destSurface = 21; + _vm->_draw->_sourceSurface = Draw::kAnimSurface; + _vm->_draw->_destSurface = Draw::kBackSurface; _vm->_draw->_spriteLeft = maxleft - _animLeft; _vm->_draw->_spriteTop = maxtop - _animTop; _vm->_draw->_spriteRight = right; @@ -1100,50 +1100,61 @@ void Mult_v2::animate() { void Mult_v2::playImd(const char *imdFile, Mult::Mult_ImdKey &key, int16 dir, int16 startFrame) { - int16 x, y; - int16 palStart, palEnd; - int16 baseFrame, palFrame, lastFrame; - uint16 flags; + + VideoPlayer::Properties props; if (_vm->_draw->_renderFlags & 0x100) { - x = VAR(55); - y = VAR(56); - } else - x = y = -1; + props.x = VAR(55); + props.y = VAR(56); + } if (key.imdFile == -1) { - _vm->_vidPlayer->primaryClose(); + _vm->_vidPlayer->closeVideo(); return; } - flags = (key.flags >> 8) & 0xFF; - if (flags & 0x20) - flags = (flags & 0x9F) | 0x80; + props.flags = (key.flags >> 8) & 0xFF; + if (props.flags & 0x20) + props.flags = (props.flags & 0x9F) | 0x80; - palStart = key.palStart; - palEnd = key.palEnd; - palFrame = key.palFrame; - lastFrame = key.lastFrame; + props.palStart = key.palStart; + props.palEnd = key.palEnd; + props.palFrame = key.palFrame; + props.lastFrame = key.lastFrame; - if ((palFrame != -1) && (lastFrame != -1)) - if ((lastFrame - palFrame) < startFrame) + if ((props.palFrame != -1) && (props.lastFrame != -1)) + if ((props.lastFrame - props.palFrame) < props.startFrame) if (!(key.flags & 0x4000)) { - _vm->_vidPlayer->primaryClose(); + _vm->_vidPlayer->closeVideo(); return; } - if (!_vm->_vidPlayer->primaryOpen(imdFile, x, y, flags)) + _vm->_vidPlayer->evaluateFlags(props); + + int slot; + if ((slot = _vm->_vidPlayer->openVideo(true, imdFile, props)) < 0) return; - if (palFrame == -1) - palFrame = 0; + if (props.palFrame == -1) + props.palFrame = 0; + + if (props.lastFrame == -1) + props.lastFrame = _vm->_vidPlayer->getFrameCount() - 1; + + uint32 baseFrame = startFrame % (props.lastFrame - props.palFrame + 1); + + props.endFrame = props.lastFrame; + props.startFrame = baseFrame + props.palFrame; + props.lastFrame = baseFrame + props.palFrame; + + props.flags &= 0x7F; - if (lastFrame == -1) - lastFrame = _vm->_vidPlayer->getFramesCount() - 1; + debugC(2, kDebugVideo, "Playing mult video \"%s\" @ %d+%d, frame %d, " + "paletteCmd %d (%d - %d; %d), flags %X", imdFile, + props.x, props.y, props.startFrame, + props.palCmd, props.palStart, props.palEnd, props.endFrame, props.flags); - baseFrame = startFrame % (lastFrame - palFrame + 1); - _vm->_vidPlayer->primaryPlay(baseFrame + palFrame, baseFrame + palFrame, 0, - flags & 0x7F, palStart, palEnd, palFrame, lastFrame); + _vm->_vidPlayer->play(slot, props); } void Mult_v2::advanceObjects(int16 index) { diff --git a/engines/gob/scenery.cpp b/engines/gob/scenery.cpp index a6d6c06544..f9587dc0b3 100644 --- a/engines/gob/scenery.cpp +++ b/engines/gob/scenery.cpp @@ -261,10 +261,10 @@ void Scenery::renderStatic(int16 scenery, int16 layer) { _vm->_draw->_spriteLeft = layerPtr->backResId; if (_vm->_draw->_spriteLeft != -1) { - _vm->_draw->_destSpriteX = 0; - _vm->_draw->_destSpriteY = 0; - _vm->_draw->_destSurface = 21; - _vm->_draw->_transparency = 0; + _vm->_draw->_destSpriteX = 0; + _vm->_draw->_destSpriteY = 0; + _vm->_draw->_destSurface = Draw::kBackSurface; + _vm->_draw->_transparency = 0; _vm->_draw->spriteOperation(DRAW_LOADSPRITE); } @@ -295,7 +295,7 @@ void Scenery::renderStatic(int16 scenery, int16 layer) { _vm->_draw->_sourceSurface = _staticPictToSprite[scenery * 7 + pictIndex]; - _vm->_draw->_destSurface = 21; + _vm->_draw->_destSurface = Draw::kBackSurface; _vm->_draw->_spriteLeft = left; _vm->_draw->_spriteTop = top; _vm->_draw->_spriteRight = right - left + 1; @@ -392,7 +392,7 @@ void Scenery::updateStatic(int16 orderFrom, byte index, byte layer) { _vm->_draw->_sourceSurface = _staticPictToSprite[index * 7 + pictIndex]; - _vm->_draw->_destSurface = 21; + _vm->_draw->_destSurface = Draw::kBackSurface; _vm->_draw->_transparency = planePtr->transp ? 3 : 0; _vm->_draw->spriteOperation(DRAW_BLITSURF); } @@ -616,26 +616,29 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, return; } - if (frame >= _vm->_vidPlayer->getFramesCount(obj.videoSlot - 1)) - frame = _vm->_vidPlayer->getFramesCount(obj.videoSlot - 1) - 1; + if (frame >= (int32)_vm->_vidPlayer->getFrameCount(obj.videoSlot - 1)) + frame = _vm->_vidPlayer->getFrameCount(obj.videoSlot - 1) - 1; - // Seek to frame - if (_vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1) < 256) { - while (_vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1) <= frame) - _vm->_vidPlayer->slotPlay(obj.videoSlot - 1); - } else { - int16 curFrame = _vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1); - uint8 frameWrap = curFrame / 256; - frame = (frame + 1) % 256; + if (frame != (int32)_vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1)) { + // Seek to frame + + VideoPlayer::Properties props; + + props.forceSeek = true; + props.waitEndFrame = false; + props.lastFrame = frame; - while (_vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1) < (frameWrap * 256 + frame)) - _vm->_vidPlayer->slotPlay(obj.videoSlot - 1); + if ((int32)_vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1) < frame) + props.startFrame = _vm->_vidPlayer->getCurrentFrame(obj.videoSlot - 1) + 1; + else + props.startFrame = frame; + + _vm->_vidPlayer->play(obj.videoSlot - 1, props); } - // Subtitle - Graphics::CoktelVideo::State state = _vm->_vidPlayer->getState(obj.videoSlot - 1); - if (state.flags & Graphics::CoktelVideo::kStateSpeech) - _vm->_draw->printTotText(state.speechId); + int32 subtitle = _vm->_vidPlayer->getSubtitleIndex(obj.videoSlot - 1); + if (subtitle != -1) + _vm->_draw->printTotText(subtitle); destX = 0; destY = 0; @@ -716,7 +719,7 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, _vm->_draw->_spriteLeft = _vm->_vidPlayer->getWidth(obj.videoSlot - 1) - (destX + _vm->_draw->_spriteRight); - _vm->_vidPlayer->slotCopyFrame(obj.videoSlot - 1, _vm->_draw->_backSurface->getVidMem(), + _vm->_vidPlayer->copyFrame(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, @@ -726,13 +729,12 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, _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; + _animLeft = _toRedrawLeft = left; + _animTop = _toRedrawTop = top; + _animRight = _toRedrawRight = right; _animBottom = _toRedrawBottom = bottom; } @@ -878,7 +880,7 @@ void Scenery::updateAnim(int16 layer, int16 frame, int16 animation, int16 flags, if (doDraw) { _vm->_draw->_sourceSurface = _animPictToSprite[animation * 7 + pictIndex]; - _vm->_draw->_destSurface = 21; + _vm->_draw->_destSurface = Draw::kBackSurface; _vm->_draw->_spriteLeft = left; _vm->_draw->_spriteTop = top; diff --git a/engines/gob/totfile.cpp b/engines/gob/totfile.cpp index 5cc723ba7d..178deeaf58 100644 --- a/engines/gob/totfile.cpp +++ b/engines/gob/totfile.cpp @@ -49,7 +49,7 @@ bool TOTFile::load(const Common::String &fileName) { if (!_stream) // Trying to open from video - _stream = _vm->_vidPlayer->getExtraData(fileName.c_str()); + _stream = _vm->_vidPlayer->getEmbeddedFile(fileName.c_str()); if (!_stream) return false; diff --git a/engines/gob/videoplayer.cpp b/engines/gob/videoplayer.cpp index 51bc1b88a5..9e49bfc092 100644 --- a/engines/gob/videoplayer.cpp +++ b/engines/gob/videoplayer.cpp @@ -29,7 +29,6 @@ #include "gob/global.h" #include "gob/dataio.h" #include "gob/video.h" -#include "gob/draw.h" #include "gob/game.h" #include "gob/palanim.h" #include "gob/inter.h" @@ -38,767 +37,723 @@ namespace Gob { -const char *VideoPlayer::_extensions[] = { "IMD", "IMD", "VMD", "RMD", "SMD" }; - -VideoPlayer::Video::Video(GobEngine *vm) : _vm(vm), _stream(0), _video(0) { -} - -VideoPlayer::Video::~Video() { - close(); -} - -bool VideoPlayer::Video::open(const char *fileName, Type which, int16 width, int16 height) { - 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 Graphics::Imd(); - } else if (which == kVideoTypePreIMD) { - _video = new Graphics::PreImd(width, height); - } else if (which == kVideoTypeVMD) { - _video = new Graphics::Vmd(_vm->_video->_palLUT); - } else if (which == kVideoTypeRMD) { - _video = new Graphics::Vmd(_vm->_video->_palLUT); - } 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 = fileName; +VideoPlayer::Properties::Properties() : type(kVideoTypeTry), sprite(Draw::kFrontSurface), + x(-1), y(-1), width(-1), height(-1), flags(kFlagFrontSurface), + startFrame(-1), lastFrame(-1), endFrame(-1), forceSeek(false), + breakKey(kShortKeyEscape), palCmd(8), palStart(0), palEnd(255), palFrame(-1), + fade(false), waitEndFrame(true), canceled(false) { - _defaultX = _video->getX(); - _defaultY = _video->getY(); - - return true; } -void VideoPlayer::Video::close() { - delete _video; - delete _stream; - - _video = 0; - _stream = 0; - _fileName.clear(); - memset(&_state, 0, sizeof(Graphics::CoktelVideo::State)); - _defaultX = _defaultY = 0; -} -bool VideoPlayer::Video::isOpen() const { - return (_video != 0); +VideoPlayer::Video::Video() : decoder(0) { } -const char *VideoPlayer::Video::getFileName() const { - return _fileName.c_str(); +bool VideoPlayer::Video::isEmpty() const { + return decoder == 0; } -Graphics::CoktelVideo *VideoPlayer::Video::getVideo() { - return _video; -} +void VideoPlayer::Video::close() { + delete decoder; -const Graphics::CoktelVideo *VideoPlayer::Video::getVideo() const { - return _video; + decoder = 0; + fileName.clear(); + surface.reset(); } -uint32 VideoPlayer::Video::getFeatures() const { - return _video->getFeatures(); -} -Graphics::CoktelVideo::State VideoPlayer::Video::getState() const { - return _state; -} +const char *VideoPlayer::_extensions[] = { "IMD", "IMD", "VMD", "RMD", "SMD" }; -int16 VideoPlayer::Video::getDefaultX() const { - return _defaultX; +VideoPlayer::VideoPlayer(GobEngine *vm) : _vm(vm), _needBlit(false), + _noCursorSwitch(false), _woodruffCohCottWorkaround(false) { } -int16 VideoPlayer::Video::getDefaultY() const { - return _defaultY; +VideoPlayer::~VideoPlayer() { + for (int i = 0; i < kVideoSlotCount; i++) + _videoSlots[i].close(); +} + +void VideoPlayer::evaluateFlags(Properties &properties) { + if (properties.flags & kFlagFrontSurface) { + properties.sprite = Draw::kFrontSurface; + } else if (properties.flags & kFlagOtherSurface) { + properties.sprite = properties.x; + properties.x = 0; + } else if (properties.flags & kFlagScreenSurface) { + properties.sprite = 0; + } else if (properties.flags & kFlagNoVideo) { + properties.sprite = 0; + } else { + properties.sprite = Draw::kBackSurface; + } } -bool VideoPlayer::Video::hasExtraData(const char *fileName) const { - if (!_video) - return false; +int VideoPlayer::openVideo(bool primary, const Common::String &file, Properties &properties) { + int slot = 0; - return _video->hasExtraData(fileName); -} - -Common::MemoryReadStream *VideoPlayer::Video::getExtraData(const char *fileName) { - if (!_video) - return 0; + Video *video = 0; + if (!primary) { + slot = getNextFreeSlot(); + if (slot < 0) { + warning("VideoPlayer::openVideo(): Can't open video \"%s\": No free slot", file.c_str()); + return -1; + } - return _video->getExtraData(fileName); -} + video = &_videoSlots[slot]; + } else + video = &_videoSlots[0]; -Graphics::CoktelVideo::State VideoPlayer::Video::nextFrame() { - if (_video) - _state = _video->nextFrame(); + // Different video already in the slot => close that video + if (!video->isEmpty() && (video->fileName.compareToIgnoreCase(file) != 0)) + video->close(); - return _state; -} + // No video => load the requested file + if (video->isEmpty()) { + // Open the video + if (!(video->decoder = openVideo(file, properties))) + return -1; + // Set the filename + video->fileName = file; -VideoPlayer::VideoPlayer(GobEngine *vm) : _vm(vm) { - _primaryVideo = new Video(vm); - _ownSurf = false; - _backSurf = false; - _needBlit = false; - _noCursorSwitch = false; - _woodruffCohCottWorkaround = false; -} + // WORKAROUND: In some rare cases, the cursor should still be + // displayed while a video is playing. + _noCursorSwitch = false; + if (primary && (_vm->getGameType() == kGameTypeLostInTime)) { + if (!file.compareToIgnoreCase("PORTA03") || + !file.compareToIgnoreCase("PORTA03A") || + !file.compareToIgnoreCase("CALE1") || + !file.compareToIgnoreCase("AMIL2") || + !file.compareToIgnoreCase("AMIL3B") || + !file.compareToIgnoreCase("DELB")) + _noCursorSwitch = true; + } -VideoPlayer::~VideoPlayer() { - delete _primaryVideo; - for (uint i = 0; i < _videoSlots.size(); i++) - delete _videoSlots[i]; -} + // WORKAROUND: In Woodruff, Coh Cott vanished in one video on her party. + // This is a bug in video, so we work around it. + _woodruffCohCottWorkaround = false; + if (primary && (_vm->getGameType() == kGameTypeWoodruff)) { + if (!file.compareToIgnoreCase("SQ32-03")) + _woodruffCohCottWorkaround = true; + } -bool VideoPlayer::findFile(char *fileName, Type &which) { - char *extStart = strrchr(fileName, '.'); - // There's no empty extension, Or the filename with its current extension is not found - if ((extStart) && ((extStart == (fileName + strlen(fileName) - 1)) || (!_vm->_dataIO->existData(fileName)))) { - *extStart = 0; - extStart = 0; - } + if (!(properties.flags & kFlagNoVideo) && (properties.sprite >= 0)) { + bool ownSurf = (properties.sprite != Draw::kFrontSurface) && (properties.sprite != Draw::kBackSurface); + bool screenSize = properties.flags & kFlagScreenSurface; - if (extStart) { - // The requested file already has an extension. Verifying. + if (ownSurf) { + _vm->_draw->_spritesArray[properties.sprite] = + _vm->_video->initSurfDesc(_vm->_global->_videoMode, + screenSize ? _vm->_width : video->decoder->getWidth(), + screenSize ? _vm->_height : video->decoder->getHeight(), 0); + } - int i; - for (i = 0; i < ARRAYSIZE(_extensions); i++) { - if (!scumm_stricmp(extStart + 1, _extensions[i])) { - if ((which != kVideoTypeTry) && (which == ((Type) i))) { - warning("Attempted to open video \"%s\", " - "but requested a different type", fileName); - return false; - } - which = (Type) i; - break; + if (!_vm->_draw->_spritesArray[properties.sprite]) { + properties.sprite = -1; + video->surface.reset(); + video->decoder->setSurfaceMemory(); + video->decoder->setXY(0, 0); + } else { + video->surface = _vm->_draw->_spritesArray[properties.sprite]; + video->decoder->setSurfaceMemory(video->surface->getVidMem(), + video->surface->getWidth(), video->surface->getHeight(), 1); + + if (!ownSurf || (ownSurf && screenSize)) { + if ((properties.x >= 0) || (properties.y >= 0)) + video->decoder->setXY((properties.x < 0) ? 0xFFFF : properties.x, + (properties.y < 0) ? 0xFFFF : properties.y); + else + video->decoder->setXY(); + } else + video->decoder->setXY(0, 0); } - } - if (i >= ARRAYSIZE(_extensions)) - extStart = 0; + } else { + properties.sprite = -1; + video->surface.reset(); + video->decoder->setSurfaceMemory(); + video->decoder->setXY(0, 0); + } } - if (!extStart) { - // No or unrecognized extension. Probing. + if (primary) + _needBlit = (properties.flags & kFlagUseBackSurfaceContent) && (properties.sprite == Draw::kFrontSurface); - int len = strlen(fileName); + if (!video->decoder->hasSound()) + video->decoder->setFrameRate(_vm->_util->getFrameRate()); - int i; - for (i = 0; i < ARRAYSIZE(_extensions); i++) { - if ((which == kVideoTypeTry) || (which == ((Type) i))) { - fileName[len] = '.'; - fileName[len + 1] = 0; - strcat(fileName, _extensions[i]); + WRITE_VAR(7, video->decoder->getFrameCount()); - if (_vm->_dataIO->existData(fileName)) { - which = (Type) i; - break; - } - } - } - if ((i >= ARRAYSIZE(_extensions)) || (which == kVideoTypeTry)) { - fileName[len] = 0; - warning("Couldn't open video \"%s\"", fileName); - return false; - } + return slot; +} - } +bool VideoPlayer::closeVideo(int slot) { + Video *video = getVideoBySlot(slot); + if (!video) + return false; + video->close(); return true; } -bool VideoPlayer::primaryOpen(const char *videoFile, int16 x, int16 y, - int32 flags, Type which, int16 width, int16 height) { - - char fileName[256]; - - strncpy0(fileName, videoFile, 250); - - if (!findFile(fileName, which)) +bool VideoPlayer::play(int slot, Properties &properties) { + Video *video = getVideoBySlot(slot); + if (!video) return false; - if (scumm_strnicmp(_primaryVideo->getFileName(), fileName, strlen(fileName))) { - if (!_primaryVideo->open(fileName, which, width, height)) - return false; + bool primary = slot == 0; - // WORKAROUND: In some rare cases, the cursor should still be - // displayed while a video is playing. - _noCursorSwitch = false; - if (_vm->getGameType() == kGameTypeLostInTime) { - if (!scumm_stricmp(fileName, "PORTA03.IMD") || - !scumm_stricmp(fileName, "PORTA03A.IMD") || - !scumm_stricmp(fileName, "CALE1.IMD") || - !scumm_stricmp(fileName, "AMIL2.IMD") || - !scumm_stricmp(fileName, "AMIL3B.IMD") || - !scumm_stricmp(fileName, "DELB.IMD")) - _noCursorSwitch = true; - } + // NOTE: For testing (and comfort?) purposes, we enable aborting of all videos) + properties.breakKey = kShortKeyEscape; - // WORKAROUND: In Woodruff, Coh Cott vanished in one video on her party. - // This is a bug in video, so we work around it. - _woodruffCohCottWorkaround = false; - if (_vm->getGameType() == kGameTypeWoodruff) { - if (!scumm_stricmp(fileName, "SQ32-03.VMD")) - _woodruffCohCottWorkaround = true; - } + if (properties.startFrame < 0) + properties.startFrame = video->decoder->getCurFrame() + 1; + if (properties.lastFrame < 0) + properties.lastFrame = video->decoder->getFrameCount() - 1; + if (properties.endFrame < 0) + properties.endFrame = properties.lastFrame; + if (properties.palFrame < 0) + properties.palFrame = properties.startFrame; - _ownSurf = false; + properties.startFrame--; + properties.endFrame--; + properties.palFrame--; - if (!(flags & kFlagNoVideo)) { - SurfaceDescPtr surf; + if (primary) { + _vm->_draw->_showCursor = _noCursorSwitch ? 3 : 0; - if (flags & kFlagOtherSurface) { - _ownSurf = true; - _backSurf = false; + if (properties.fade) + _vm->_palAnim->fade(0, -2, 0); + } - surf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, - _primaryVideo->getVideo()->getWidth(), - _primaryVideo->getVideo()->getHeight(), 0); - _vm->_draw->_spritesArray[x] = surf; + bool backwards = properties.startFrame > properties.lastFrame; - x = 0; - } else if (flags & kFlagScreenSurface) { - _ownSurf = true; - _backSurf = false; + properties.canceled = false; - surf = _vm->_video->initSurfDesc(_vm->_global->_videoMode, - _vm->_width, _vm->_height, 0); - _vm->_draw->_spritesArray[0] = surf; - } else { - _backSurf = ((flags & kFlagFrontSurface) == 0); - surf = _vm->_draw->_spritesArray[_backSurf ? 21 : 20]; - } + while ((properties.startFrame != properties.lastFrame) && + (properties.startFrame < (int32)(video->decoder->getFrameCount() - 1))) { - _primaryVideo->getVideo()->setVideoMemory(surf->getVidMem(), - surf->getWidth(), surf->getHeight()); + playFrame(slot, properties); + if (properties.canceled) + break; - } else - _primaryVideo->getVideo()->setVideoMemory(); + properties.startFrame += backwards ? -1 : 1; - _needBlit = ((flags & kFlagUseBackSurfaceContent) != 0) && ((flags & kFlagFrontSurface) != 0); + evalBgShading(*video); - _primaryVideo->getVideo()->enableSound(*_vm->_mixer); - } + if (primary && properties.fade) { + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0); + properties.fade = false; + } - if (!_primaryVideo->isOpen()) - return false; + if (!_noCursorSwitch && properties.waitEndFrame) + waitEndFrame(slot); + } - _primaryVideo->getVideo()->setFrameRate(_vm->_util->getFrameRate()); - _primaryVideo->getVideo()->setXY(x, y); - WRITE_VAR(7, _primaryVideo->getVideo()->getFramesCount()); + evalBgShading(*video); return true; } -bool VideoPlayer::primaryPlay(int16 startFrame, int16 lastFrame, int16 breakKey, - uint16 palCmd, int16 palStart, int16 palEnd, - int16 palFrame, int16 endFrame, bool fade, int16 reverseTo, bool forceSeek) { +void VideoPlayer::waitEndFrame(int slot, bool onlySound) { + Video *video = getVideoBySlot(slot); + if (!video) + return; + + if (!onlySound || video->decoder->hasSound()) + _vm->_util->delay(video->decoder->getTimeToNextFrame()); +} - if (!_primaryVideo->isOpen()) +bool VideoPlayer::playFrame(int slot, Properties &properties) { + Video *video = getVideoBySlot(slot); + if (!video) return false; - Graphics::CoktelVideo &video = *(_primaryVideo->getVideo()); - - breakKey = 27; - if (startFrame < 0) - startFrame = video.getCurrentFrame(); - if (lastFrame < 0) - lastFrame = video.getFramesCount() - 1; - if (palFrame < 0) - palFrame = startFrame; - if (endFrame < 0) - endFrame = lastFrame; - palCmd &= 0x3F; - - int16 realStartFrame = startFrame; - if (video.getCurrentFrame() != startFrame) { - if (!forceSeek && (video.getFeatures() & Graphics::CoktelVideo::kFeaturesSound)) - startFrame = video.getCurrentFrame(); - else - video.seekFrame(startFrame); - } + bool primary = slot == 0; - _vm->_draw->_showCursor = _noCursorSwitch ? 3 : 0; + if (video->decoder->getCurFrame() != properties.startFrame) { - if (fade) - _vm->_palAnim->fade(0, -2, 0); + if (properties.startFrame != -1) { + // Seek into the middle of the video - bool canceled = false; + if (video->decoder->hasSound()) { + // But there's sound - while (startFrame <= lastFrame) { - if (doPlay(startFrame, breakKey, - palCmd, palStart, palEnd, palFrame, endFrame, startFrame < realStartFrame)) { + if (properties.forceSeek) { + // And we force seeking => Seek - canceled = true; - break; - } + video->decoder->disableSound(); + video->decoder->seek(properties.startFrame + 1, SEEK_SET, true); + } - evalBgShading(video); + } else + // No sound => We can safely seek + video->decoder->seek(properties.startFrame + 1, SEEK_SET, true); - if (fade) { - _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0); - fade = false; + } else { + // Seek to the start => We can safely seek + + video->decoder->disableSound(); + video->decoder->seek(0, SEEK_SET, true); + video->decoder->enableSound(); } - if (!_noCursorSwitch) - video.waitEndFrame(); - startFrame++; } - evalBgShading(video); + if (video->decoder->getCurFrame() > properties.startFrame) + // If the video is already beyond the wanted frame, skip + return true; - if (reverseTo >= 0) { - int16 toFrame = video.getFramesCount() - reverseTo; - for (int i = video.getCurrentFrame(); i >= toFrame; i--) { - video.seekFrame(i, SEEK_SET, true); + bool modifiedPal = false; - bool b = doPlay(i, breakKey, 0, 0, 0, 0, 0); - evalBgShading(video); + if (primary) { + // Pre-decoding palette and blitting, only for primary videos - if (b) { - _vm->_palAnim->fade(0, -2, 0); - memset((char *)_vm->_draw->_vgaPalette, 0, 768); - } + if ((properties.startFrame == properties.palFrame) || + ((properties.startFrame == properties.endFrame) && (properties.palCmd == 8))) { - if (!_noCursorSwitch) - video.waitEndFrame(); - } - } + modifiedPal = true; + _vm->_draw->_applyPal = true; - evalBgShading(video); + if (properties.palCmd >= 4) + copyPalette(*video, properties.palStart, properties.palEnd); + } - return canceled; -} + if (modifiedPal && (properties.palCmd == 8) && (video->surface != _vm->_draw->_backSurface)) + _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); -void VideoPlayer::primaryClose() { - _primaryVideo->close(); -} + if (_needBlit) + _vm->_draw->forceBlit(); + } -int VideoPlayer::slotOpen(const char *videoFile, Type which, int16 width, int16 height) { - Video *video = new Video(_vm); - char fileName[256]; + Graphics::Surface *surface = video->decoder->decodeNextFrame(); - strncpy0(fileName, videoFile, 250); + WRITE_VAR(11, video->decoder->getCurFrame()); - if (!findFile(fileName, which)) { - delete video; - return -1; - } - - if (!video->open(fileName, which, width, height)) { - delete video; - return -1; + uint32 ignoreBorder = 0; + if (_woodruffCohCottWorkaround && (properties.startFrame == 31)) { + // WORKAROUND: This frame mistakenly masks Coh Cott, making her vanish + // To prevent that, we'll never draw that part + ignoreBorder = 50; } - video->getVideo()->setVideoMemory(); - video->getVideo()->enableSound(*_vm->_mixer); + if (surface && primary) { + // Post-decoding palette and blitting, only for primary videos - int slot = getNextFreeSlot(); + if (_needBlit) + _vm->_draw->forceBlit(true); - _videoSlots[slot] = video; + if (modifiedPal && (properties.palCmd == 16)) { + if (video->surface == _vm->_draw->_backSurface) + _vm->_draw->forceBlit(); + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0); + _vm->_draw->_noInvalidated = true; + _vm->_video->dirtyRectsAll(); + } - WRITE_VAR(7, video->getVideo()->getFramesCount()); + if (video->decoder->hasPalette() && (properties.palCmd > 1)) { + copyPalette(*video, properties.palStart, properties.palEnd); - return slot; -} + if (video->surface != _vm->_draw->_backSurface) + _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + else + _vm->_draw->_applyPal = true; + } -int VideoPlayer::getNextFreeSlot() { - uint slot; + const Common::List<Common::Rect> &dirtyRects = video->decoder->getDirtyRects(); - for (slot = 0; slot < _videoSlots.size(); slot++) - if (!_videoSlots[slot]) - break; + if (modifiedPal && (properties.palCmd == 8) && (video->surface == _vm->_draw->_backSurface)) + _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - if (slot == _videoSlots.size()) - _videoSlots.push_back(0); + if (video->surface == _vm->_draw->_backSurface) { - return slot; -} - -void VideoPlayer::slotPlay(int slot, int16 frame) { - if ((slot < 0) || (((uint) slot) >= _videoSlots.size()) || !_videoSlots[slot]) - return; + for (Common::List<Common::Rect>::const_iterator rect = dirtyRects.begin(); rect != dirtyRects.end(); ++rect) + _vm->_draw->invalidateRect(rect->left + ignoreBorder, rect->top, rect->right - 1, rect->bottom - 1); + _vm->_draw->blitInvalidated(); - Graphics::CoktelVideo &video = *(_videoSlots[slot]->getVideo()); + } else if (video->surface == _vm->_draw->_frontSurface) { + for (Common::List<Common::Rect>::const_iterator rect = dirtyRects.begin(); rect != dirtyRects.end(); ++rect) + _vm->_video->dirtyRectsAdd(rect->left + ignoreBorder, rect->top, rect->right - 1, rect->bottom - 1); - if (frame < 0) - frame = video.getCurrentFrame(); + } - if (frame >= video.getFramesCount()) - return; + if ((video->decoder->getCurFrame() - 1) == properties.startFrame) + // Only retrace if we're playing the frame we actually want to play + _vm->_video->retrace(); - if (video.getCurrentFrame() != frame) - video.seekFrame(frame); + int32 subtitle = video->decoder->getSubtitleIndex(); + if (subtitle != -1) + _vm->_draw->printTotText(subtitle); - _videoSlots[slot]->nextFrame(); - WRITE_VAR(11, frame); + if (modifiedPal && ((properties.palCmd == 2) || (properties.palCmd == 4))) + _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0); + } - evalBgShading(video); -} + if (primary && properties.waitEndFrame) + checkAbort(*video, properties); -void VideoPlayer::slotClose(int slot) { - if ((slot < 0) || (((uint) slot) >= _videoSlots.size()) || !_videoSlots[slot]) - return; + if ((video->decoder->getCurFrame() - 1) < properties.startFrame) + // The video played a frame we actually didn't want, so we have to adjust + properties.startFrame--; - delete _videoSlots[slot]; - _videoSlots[slot] = 0; + return true; } -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()) || !_videoSlots[slot]) - return; +void VideoPlayer::checkAbort(Video &video, Properties &properties) { + _vm->_util->processInput(); - _videoSlots[slot]->getVideo()->copyCurrentFrame(dest, - left, top, width, height, x, y, pitch, transp); -} + if (_vm->shouldQuit()) { + video.decoder->disableSound(); -void VideoPlayer::slotCopyPalette(int slot, int16 palStart, int16 palEnd) { - if ((slot < 0) || (((uint) slot) >= _videoSlots.size()) || !_videoSlots[slot]) + properties.canceled = true; return; + } - copyPalette(*(_videoSlots[slot]->getVideo()), palStart, palEnd); -} + if (properties.breakKey != 0) { + _vm->_util->getMouseState(&_vm->_global->_inter_mouseX, + &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons); -void VideoPlayer::slotWaitEndFrame(int slot, bool onlySound) { - Video *video = getVideoBySlot(slot); + _vm->_inter->storeKey(_vm->_util->checkKey()); + if (VAR(0) == (unsigned) properties.breakKey) { + video.decoder->disableSound(); - if (video) { - Graphics::CoktelVideo &cVideo = *video->getVideo(); + // Seek to the last frame. Some scripts depend on that. + video.decoder->seek(properties.endFrame + 1, SEEK_SET, true); - if (!onlySound || (cVideo.getFeatures() & Graphics::CoktelVideo::kFeaturesSound)) - cVideo.waitEndFrame(); + properties.canceled = true; + } } } bool VideoPlayer::slotIsOpen(int slot) const { - if ((slot >= 0) && (((uint) slot) < _videoSlots.size()) && _videoSlots[slot]) - return true; - - return false; -} - -void VideoPlayer::slotSetDoubleMode(int slot, bool doubleMode) { - Video *video = getVideoBySlot(slot); - - if (video) - video->getVideo()->setDoubleMode(doubleMode); + return getVideoBySlot(slot) != 0; } -const VideoPlayer::Video *VideoPlayer::getVideoBySlot(int slot) const { - if (slot < 0) { - if (_primaryVideo->isOpen()) - return _primaryVideo; - } else if (((uint) slot) < _videoSlots.size() && _videoSlots[slot]) - return _videoSlots[slot]; +Common::String VideoPlayer::getFileName(int slot) const { + const Video *video = getVideoBySlot(slot); + if (!video) + return ""; - return 0; + return video->fileName; } -VideoPlayer::Video *VideoPlayer::getVideoBySlot(int slot) { - if (slot < 0) { - if (_primaryVideo->isOpen()) - return _primaryVideo; - } else if (((uint) slot) < _videoSlots.size() && _videoSlots[slot]) - return _videoSlots[slot]; +uint32 VideoPlayer::getFrameCount(int slot) const { + const Video *video = getVideoBySlot(slot); + if (!video) + return 0; - return 0; + return video->decoder->getFrameCount(); } -const char *VideoPlayer::getFileName(int slot) const { +uint32 VideoPlayer::getCurrentFrame(int slot) const { const Video *video = getVideoBySlot(slot); + if (!video) + return 0; - if (video) - return video->getFileName(); - - return ""; + return video->decoder->getCurFrame(); } -uint16 VideoPlayer::getFlags(int slot) const { +uint16 VideoPlayer::getWidth(int slot) const { const Video *video = getVideoBySlot(slot); + if (!video) + return 0; - if (video) - return video->getVideo()->getFlags(); - - return 0; + return video->decoder->getWidth(); } -int16 VideoPlayer::getFramesCount(int slot) const { +uint16 VideoPlayer::getHeight(int slot) const { const Video *video = getVideoBySlot(slot); + if (!video) + return 0; - if (video) - return video->getVideo()->getFramesCount(); - - return 0; + return video->decoder->getHeight(); } -int16 VideoPlayer::getCurrentFrame(int slot) const { +uint16 VideoPlayer::getDefaultX(int slot) const { const Video *video = getVideoBySlot(slot); + if (!video) + return 0; - if (video) - return video->getVideo()->getCurrentFrame(); - - return 0; + return video->decoder->getDefaultX(); } -int16 VideoPlayer::getWidth(int slot) const { +uint16 VideoPlayer::getDefaultY(int slot) const { const Video *video = getVideoBySlot(slot); + if (!video) + return 0; - if (video) - return video->getVideo()->getWidth(); - - return 0; + return video->decoder->getDefaultY(); } -int16 VideoPlayer::getHeight(int slot) const { +const Common::List<Common::Rect> *VideoPlayer::getDirtyRects(int slot) const { const Video *video = getVideoBySlot(slot); + if (!video) + return 0; - if (video) - return video->getVideo()->getHeight(); - - return 0; + return &video->decoder->getDirtyRects(); } -int16 VideoPlayer::getDefaultX(int slot) const { +bool VideoPlayer::hasEmbeddedFile(const Common::String &fileName, int slot) const { const Video *video = getVideoBySlot(slot); + if (!video) + return false; - if (video) - return video->getDefaultX(); - - return 0; + return video->decoder->hasEmbeddedFile(fileName); } -int16 VideoPlayer::getDefaultY(int slot) const { +Common::MemoryReadStream *VideoPlayer::getEmbeddedFile(const Common::String &fileName, int slot) { const Video *video = getVideoBySlot(slot); + if (!video) + return 0; - if (video) - return video->getDefaultY(); - - return 0; + return video->decoder->getEmbeddedFile(fileName); } -uint32 VideoPlayer::getFeatures(int slot) const { +int32 VideoPlayer::getSubtitleIndex(int slot) const { const Video *video = getVideoBySlot(slot); + if (!video) + return -1; - if (video) - return video->getFeatures(); - - return 0; + return video->decoder->getSubtitleIndex(); } -Graphics::CoktelVideo::State VideoPlayer::getState(int slot) const { - const Video *video = getVideoBySlot(slot); - Graphics::CoktelVideo::State state; +void VideoPlayer::writeVideoInfo(const Common::String &file, int16 varX, int16 varY, + int16 varFrames, int16 varWidth, int16 varHeight) { - if (video) - state = video->getState(); + Properties properties; - return state; -} + int slot = openVideo(false, file, properties); + if (slot >= 0) { + Video &video = _videoSlots[slot]; -bool VideoPlayer::hasExtraData(const char *fileName, int slot) const { - const Video *video = getVideoBySlot(slot); + int16 x = -1, y = -1, width = -1, height = -1; - if (video) - return video->hasExtraData(fileName); + x = video.decoder->getDefaultX(); + y = video.decoder->getDefaultY(); + width = video.decoder->getWidth(); + height = video.decoder->getHeight(); - return false; -} + if (VAR_OFFSET(varX) == 0xFFFFFFFF) + video.decoder->getFrameCoords(1, x, y, width, height); -Common::MemoryReadStream *VideoPlayer::getExtraData(const char *fileName, int slot) { - Video *video = getVideoBySlot(slot); + WRITE_VAR_OFFSET(varX , x); + WRITE_VAR_OFFSET(varY , y); + WRITE_VAR_OFFSET(varFrames, video.decoder->getFrameCount()); + WRITE_VAR_OFFSET(varWidth , width); + WRITE_VAR_OFFSET(varHeight, height); - if (video) - return video->getExtraData(fileName); + closeVideo(slot); - return 0; + } else { + WRITE_VAR_OFFSET(varX , (uint32) -1); + WRITE_VAR_OFFSET(varY , (uint32) -1); + WRITE_VAR_OFFSET(varFrames, (uint32) -1); + WRITE_VAR_OFFSET(varWidth , (uint32) -1); + WRITE_VAR_OFFSET(varHeight, (uint32) -1); + } } -void VideoPlayer::playFrame(int16 frame, int16 breakKey, - uint16 palCmd, int16 palStart, int16 palEnd, - int16 palFrame, int16 endFrame, bool noRetrace) { +bool VideoPlayer::copyFrame(int slot, byte *dest, + uint16 left, uint16 top, uint16 width, uint16 height, + uint16 x, uint16 y, uint16 pitch, int16 transp) const { - if (!_primaryVideo) - return; + const Video *video = getVideoBySlot(slot); + if (!video) + return false; - Video &video = *_primaryVideo; - Graphics::CoktelVideo &cVideo = *video.getVideo(); + const Graphics::Surface *surface = video->decoder->getSurface(); + if (!surface) + return false; - if (cVideo.getCurrentFrame() != frame) - cVideo.seekFrame(frame); - if (palFrame < 0) - palFrame = 0; - if (endFrame < 0) - endFrame = cVideo.getFramesCount() - 1; + int32 w = MIN<int32>(width , surface->w); + int32 h = MIN<int32>(height, surface->h); + const byte *src = (byte*)surface->pixels + (top * surface->pitch) + left; + byte *dst = dest + (y * pitch) + x; - bool modifiedPal = false; + if (transp < 0) { + // No transparency - if ((frame == palFrame) || ((frame == endFrame) && (palCmd == 8))) { - modifiedPal = true; - _vm->_draw->_applyPal = true; + if ((x == 0) && (left == 0) && (pitch == surface->pitch) && (width == surface->w)) { + // Dimensions fit, we can copy everything at once - if (palCmd >= 4) - copyPalette(cVideo, palStart, palEnd); - } + memcpy(dst, src, w * h); + return true; + } - if (modifiedPal && (palCmd == 8) && !_backSurf) - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + // Copy row-by-row + while (h-- > 0) { + const byte *srcRow = src; + byte *dstRow = dst; - if (_needBlit) - _vm->_draw->forceBlit(); + memcpy(dstRow, srcRow, w); - Graphics::CoktelVideo::State state = video.nextFrame(); - WRITE_VAR(11, frame); + src += surface->pitch; + dst += pitch; + } - if (_woodruffCohCottWorkaround && (frame == 32)) { - // WORKAROUND: This frame mistakenly masks Coh Cott, making her vanish - // To prevent that, we'll never draw that part - state.left += 50; + return true; } - if (_needBlit) - _vm->_draw->forceBlit(true); + // Copy pixel-by-pixel + while (h-- > 0) { + const byte *srcRow = src; + byte *dstRow = dst; - if (modifiedPal && (palCmd == 16)) { - if (_backSurf) - _vm->_draw->forceBlit(); - _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0); - _vm->_draw->_noInvalidated = true; - _vm->_video->dirtyRectsAll(); + for (int32 i = 0; i < w; i++, srcRow++, dstRow++) + if (*srcRow != transp) + *dstRow = *srcRow; + + src += surface->pitch; + dst += pitch; } - if ((state.flags & Graphics::CoktelVideo::kStatePalette) && (palCmd > 1)) { - copyPalette(cVideo, palStart, palEnd); + return true; +} - if (!_backSurf) - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); - else - _vm->_draw->_applyPal = true; - } +const VideoPlayer::Video *VideoPlayer::getVideoBySlot(int slot) const { + if ((slot < 0) || (slot >= kVideoSlotCount)) + return 0; - if (modifiedPal && (palCmd == 8) && _backSurf) - _vm->_video->setFullPalette(_vm->_global->_pPaletteDesc); + if (_videoSlots[slot].isEmpty()) + return 0; + return &_videoSlots[slot]; +} - if (!_ownSurf) { - if (_backSurf) { - _vm->_draw->invalidateRect(state.left, state.top, state.right, state.bottom); - _vm->_draw->blitInvalidated(); - } else - _vm->_video->dirtyRectsAdd(state.left, state.top, state.right, state.bottom); +VideoPlayer::Video *VideoPlayer::getVideoBySlot(int slot) { + if ((slot < 0) || (slot >= kVideoSlotCount)) + return 0; - if (!noRetrace) - _vm->_video->retrace(); - } + if (_videoSlots[slot].isEmpty()) + return 0; - // Subtitle - if (state.flags & Graphics::CoktelVideo::kStateSpeech) - _vm->_draw->printTotText(state.speechId); + return &_videoSlots[slot]; +} - if (modifiedPal && ((palCmd == 2) || (palCmd == 4))) - _vm->_palAnim->fade(_vm->_global->_pPaletteDesc, -2, 0); +int VideoPlayer::getNextFreeSlot() { + // Starting with 1, since 0 is reserved for the "primary" video + for (int i = 1; i < kVideoSlotCount; i++) + if (_videoSlots[i].isEmpty()) + return i; + + return -1; } -bool VideoPlayer::doPlay(int16 frame, int16 breakKey, - uint16 palCmd, int16 palStart, int16 palEnd, - int16 palFrame, int16 endFrame, bool noRetrace) { +void VideoPlayer::evalBgShading(Video &video) { + if (video.decoder->isSoundPlaying()) + _vm->_sound->bgShade(); + else + _vm->_sound->bgUnshade(); +} - playFrame(frame, breakKey, palCmd, palStart, palEnd, palFrame, endFrame, noRetrace); +Common::String VideoPlayer::findFile(const Common::String &file, Properties &properties) { - _vm->_util->processInput(); + bool hasExtension = false; - if (_vm->shouldQuit()) { - _primaryVideo->getVideo()->disableSound(); - return true; - } + Common::String base = file; + Common::String fileName = file; - if (breakKey != 0) { - _vm->_util->getMouseState(&_vm->_global->_inter_mouseX, - &_vm->_global->_inter_mouseY, &_vm->_game->_mouseButtons); + const char *posDot = strrchr(base.c_str(), '.'); + if (posDot) { + hasExtension = true; + base = Common::String(base.c_str(), posDot); + posDot++; + } - _vm->_inter->storeKey(_vm->_util->checkKey()); - if (VAR(0) == (unsigned) breakKey) { - _primaryVideo->getVideo()->disableSound(); - // Seek to the last frame. Some scripts depend on that. - _primaryVideo->getVideo()->seekFrame(endFrame, SEEK_SET, true); - return true; + if (hasExtension) { + int i; + for (i = 0; i < ARRAYSIZE(_extensions); i++) { + if (!scumm_stricmp(posDot, _extensions[i])) { + if ((properties.type != kVideoTypeTry) && (properties.type == ((Type) i))) { + warning("Attempted to open video \"%s\", but requested a different type", fileName.c_str()); + return ""; + } + properties.type = (Type) i; + break; + } } + if (i >= ARRAYSIZE(_extensions)) + hasExtension = false; } - return false; -} + if (!hasExtension) { + // No or unrecognized extension. Probing. -void VideoPlayer::copyPalette(Graphics::CoktelVideo &video, int16 palStart, int16 palEnd) { - if (!(video.getFeatures() & Graphics::CoktelVideo::kFeaturesPalette)) - return; + int i; + for (i = 0; i < ARRAYSIZE(_extensions); i++) { + if ((properties.type == kVideoTypeTry) || (properties.type == ((Type) i))) { + fileName = base + "." + _extensions[i]; - if (palStart < 0) - palStart = 0; - if (palEnd < 0) - palEnd = 255; + if (_vm->_dataIO->existData(fileName.c_str())) { + properties.type = (Type) i; + break; + } + } + } + if ((i >= ARRAYSIZE(_extensions)) || (properties.type == kVideoTypeTry)) { + warning("Couldn't open video \"%s\"", file.c_str()); + return ""; + } - memcpy(((char *)(_vm->_global->_pPaletteDesc->vgaPal)) + palStart * 3, - video.getPalette() + palStart * 3, - (palEnd - palStart + 1) * 3); -} + } -void VideoPlayer::writeVideoInfo(const char *videoFile, int16 varX, int16 varY, - int16 varFrames, int16 varWidth, int16 varHeight) { + return fileName; +} - if (primaryOpen(videoFile)) { - int16 x, y, width, height; +Graphics::CoktelDecoder *VideoPlayer::openVideo(const Common::String &file, Properties &properties) { + Common::String fileName = findFile(file, properties); + if (fileName.empty()) + return 0; - x = _primaryVideo->getVideo()->getX(); - y = _primaryVideo->getVideo()->getY(); - width = _primaryVideo->getVideo()->getWidth(); - height = _primaryVideo->getVideo()->getHeight(); + Common::SeekableReadStream *stream = _vm->_dataIO->getDataStream(fileName.c_str()); + if (!stream) + return 0; - if (VAR_OFFSET(varX) == 0xFFFFFFFF) - _primaryVideo->getVideo()->getFrameCoords(1, x, y, width, height); + Graphics::CoktelDecoder *video = 0; + if (properties.type == kVideoTypeIMD) + video = new Graphics::IMDDecoder(_vm->_mixer, Audio::Mixer::kSFXSoundType); + else if (properties.type == kVideoTypePreIMD) + video = new Graphics::PreIMDDecoder(properties.width, properties.height, _vm->_mixer, Audio::Mixer::kSFXSoundType); + else if (properties.type == kVideoTypeVMD) + video = new Graphics::VMDDecoder(_vm->_mixer, Audio::Mixer::kSFXSoundType); + else if (properties.type == kVideoTypeRMD) + video = new Graphics::VMDDecoder(_vm->_mixer, Audio::Mixer::kSFXSoundType); + else + warning("Couldn't open video \"%s\": Invalid video Type", fileName.c_str()); - 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); + if (!video) { + delete stream; + return 0; + } - primaryClose(); - } else { - WRITE_VAR_OFFSET(varX, (uint32) -1); - WRITE_VAR_OFFSET(varY, (uint32) -1); - WRITE_VAR_OFFSET(varFrames, (uint32) -1); - WRITE_VAR_OFFSET(varWidth, (uint32) -1); - WRITE_VAR_OFFSET(varHeight, (uint32) -1); + if (!video->load(stream)) { + delete video; + return 0; } + + properties.width = video->getWidth(); + properties.height = video->getHeight(); + + return video; } -void VideoPlayer::evalBgShading(Graphics::CoktelVideo &video) { - if (video.isSoundPlaying()) - _vm->_sound->bgShade(); - else - _vm->_sound->bgUnshade(); +void VideoPlayer::copyPalette(const Video &video, int16 palStart, int16 palEnd) { + if (!video.decoder->hasPalette()) + return; + + if (palStart < 0) + palStart = 0; + if (palEnd < 0) + palEnd = 255; + + palStart = palStart * 3; + palEnd = (palEnd + 1) * 3; + + for (int i = palStart; i <= palEnd; i++) + ((char *)(_vm->_global->_pPaletteDesc->vgaPal))[i] = video.decoder->getPalette()[i] >> 2; } } // End of namespace Gob diff --git a/engines/gob/videoplayer.h b/engines/gob/videoplayer.h index 8ca8aebf44..d91d0a3845 100644 --- a/engines/gob/videoplayer.h +++ b/engines/gob/videoplayer.h @@ -27,11 +27,15 @@ #define GOB_VIDEOPLAYER_H #include "common/array.h" +#include "common/list.h" +#include "common/rect.h" #include "common/str.h" -#include "graphics/video/coktelvideo/coktelvideo.h" +#include "graphics/surface.h" +#include "graphics/video/coktel_decoder.h" #include "gob/util.h" +#include "gob/draw.h" namespace Gob { @@ -41,132 +45,135 @@ class DataStream; class VideoPlayer { public: enum Flags { - kFlagNone = 0, - kFlagUseBackSurfaceContent = 0x40, - kFlagFrontSurface = 0x80, - kFlagNoVideo = 0x100, - kFlagOtherSurface = 0x800, - kFlagScreenSurface = 0x400000 + kFlagNone = 0x000000, + kFlagUseBackSurfaceContent = 0x000040, ///< Use the back surface as a video "base". + kFlagFrontSurface = 0x000080, ///< Draw directly into the front surface. + kFlagNoVideo = 0x000100, ///< Only sound. + kFlagOtherSurface = 0x000800, ///< Draw into a specific sprite. + kFlagScreenSurface = 0x400000 ///< Draw into a newly created sprite of screen dimensions. }; + /** Video format. */ enum Type { - kVideoTypeTry = -1, - kVideoTypeIMD = 0, - kVideoTypePreIMD = 1, - kVideoTypeVMD = 2, - kVideoTypeRMD = 3 + kVideoTypeTry = -1, ///< Try any format. + kVideoTypeIMD = 0, + kVideoTypePreIMD = 1, ///< Early IMD format found in Fascination. + kVideoTypeVMD = 2, + kVideoTypeRMD = 3 ///< VMD containing "reversed" video. }; - VideoPlayer(GobEngine *vm); - ~VideoPlayer(); + struct Properties { + Type type; ///< Type of the video to open. - bool primaryOpen(const char *videoFile, int16 x = -1, int16 y = -1, - int32 flags = kFlagFrontSurface, Type which = kVideoTypeTry, - int16 width = -1, int16 height = -1); - bool primaryPlay(int16 startFrame = -1, int16 lastFrame = -1, - int16 breakKey = kShortKeyEscape, - uint16 palCmd = 8, int16 palStart = 0, int16 palEnd = 255, - int16 palFrame = -1, int16 endFrame = -1, bool fade = false, - int16 reverseTo = -1, bool forceSeek = false); - void primaryClose(); - - void playFrame(int16 frame, int16 breakKey = kShortKeyEscape, - uint16 palCmd = 8, int16 palStart = 0, int16 palEnd = 255, - int16 palFrame = -1 , int16 endFrame = -1, bool noRetrace = false); - - int slotOpen(const char *videoFile, Type which = kVideoTypeTry, - int16 width = -1, int16 height = -1); - void slotPlay(int slot, int16 frame = -1); - 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); - void slotWaitEndFrame(int slot = -1, bool onlySound = false); + int sprite; ///< The sprite onto which to draw the video. - void slotSetDoubleMode(int slot, bool doubleMode); + int32 x; ///< X coordinate of the video. + int32 y; ///< Y coordinate of the video. + int32 width; ///< Width of the video. + int32 height; ///< Height of the video. - bool slotIsOpen(int slot) const; + uint32 flags; ///< Video flags. - const char *getFileName(int slot = -1) 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; - int16 getDefaultX(int slot = -1) const; - int16 getDefaultY(int slot = -1) const; + int32 startFrame; ///< Frame to start playback from. + int32 lastFrame; ///< Frame to stop playback at. + int32 endFrame; ///< Last frame of this playback cycle. - Graphics::CoktelVideo::State getState(int slot = -1) const; - uint32 getFeatures(int slot = -1) const; + bool forceSeek; ///< Force the seeking to the start frame. - bool hasExtraData(const char *fileName, int slot = -1) const; - Common::MemoryReadStream *getExtraData(const char *fileName, int slot = -1); + int16 breakKey; ///< Keycode of the break/abort key. - void writeVideoInfo(const char *videoFile, int16 varX, int16 varY, - int16 varFrames, int16 varWidth, int16 varHeight); + uint16 palCmd; ///< Palette command. + int16 palStart; ///< Palette entry to start with. + int16 palEnd; ///< Palette entry to end at. + int32 palFrame; ///< Frame to apply the palette command at. -private: - class Video { - public: - Video(GobEngine *vm); - ~Video(); + bool fade; ///< Fade in? + + bool waitEndFrame; ///< Wait for the frame's time to run out? + + bool canceled; ///< Was the video canceled? + + Properties(); + }; + + VideoPlayer(GobEngine *vm); + ~VideoPlayer(); + + void evaluateFlags(Properties &properties); + + int openVideo(bool primary, const Common::String &file, Properties &properties); + bool closeVideo(int slot = 0); + + bool play(int slot, Properties &properties); + void waitEndFrame(int slot, bool onlySound = false); - bool open(const char *fileName, Type which, int16 width, int16 height); - void close(); + bool slotIsOpen(int slot = 0) const; - bool isOpen() const; + Common::String getFileName(int slot = 0) const; - const char *getFileName() const; - Graphics::CoktelVideo *getVideo(); - const Graphics::CoktelVideo *getVideo() const; + uint32 getFrameCount (int slot = 0) const; + uint32 getCurrentFrame(int slot = 0) const; + uint16 getWidth (int slot = 0) const; + uint16 getHeight (int slot = 0) const; + uint16 getDefaultX (int slot = 0) const; + uint16 getDefaultY (int slot = 0) const; - Graphics::CoktelVideo::State getState() const; - uint32 getFeatures() const; + const Common::List<Common::Rect> *getDirtyRects(int slot = 0) const; - int16 getDefaultX() const; - int16 getDefaultY() const; + bool hasEmbeddedFile(const Common::String &fileName, int slot = 0) const; + Common::MemoryReadStream *getEmbeddedFile(const Common::String &fileName, int slot = 0); - bool hasExtraData(const char *fileName) const; - Common::MemoryReadStream *getExtraData(const char *fileName); + int32 getSubtitleIndex(int slot = 0) const; - Graphics::CoktelVideo::State nextFrame(); + void writeVideoInfo(const Common::String &file, int16 varX, int16 varY, + int16 varFrames, int16 varWidth, int16 varHeight); + + bool copyFrame(int slot, byte *dest, + uint16 left, uint16 top, uint16 width, uint16 height, + uint16 x, uint16 y, uint16 pitch, int16 transp = -1) const; + +private: + struct Video { + Graphics::CoktelDecoder *decoder; + Common::String fileName; + + SurfaceDescPtr surface; - private: - GobEngine *_vm; + Video(); - Common::String _fileName; - DataStream *_stream; - Graphics::CoktelVideo *_video; - Graphics::CoktelVideo::State _state; - int16 _defaultX, _defaultY; + bool isEmpty() const; + void close(); }; + static const int kVideoSlotCount = 32; + static const char *_extensions[]; GobEngine *_vm; - Common::Array<Video *> _videoSlots; - Video *_primaryVideo; - bool _ownSurf; - bool _backSurf; + // _videoSlots[0] is reserved for the "primary" video + Video _videoSlots[kVideoSlotCount]; + bool _needBlit; - bool _noCursorSwitch; + bool _noCursorSwitch; bool _woodruffCohCottWorkaround; - bool findFile(char *fileName, Type &which); - - const Video *getVideoBySlot(int slot = -1) const; - Video *getVideoBySlot(int slot = -1); + const Video *getVideoBySlot(int slot) const; + Video *getVideoBySlot(int slot); int getNextFreeSlot(); - void copyPalette(Graphics::CoktelVideo &video, int16 palStart = -1, int16 palEnd = -1); - bool doPlay(int16 frame, int16 breakKey, - uint16 palCmd, int16 palStart, int16 palEnd, - int16 palFrame, int16 endFrame, bool noRetrace = false); - void evalBgShading(Graphics::CoktelVideo &video); + Common::String findFile(const Common::String &file, Properties &properties); + + Graphics::CoktelDecoder *openVideo(const Common::String &file, Properties &properties); + + bool playFrame(int slot, Properties &properties); + + void checkAbort(Video &video, Properties &properties); + void evalBgShading(Video &video); + + void copyPalette(const Video &video, int16 palStart, int16 palEnd); }; } // End of namespace Gob |