diff options
Diffstat (limited to 'engines/sci/graphics')
-rw-r--r-- | engines/sci/graphics/controls32.cpp | 2 | ||||
-rw-r--r-- | engines/sci/graphics/cursor.h | 2 | ||||
-rw-r--r-- | engines/sci/graphics/frameout.cpp | 52 | ||||
-rw-r--r-- | engines/sci/graphics/frameout.h | 19 | ||||
-rw-r--r-- | engines/sci/graphics/paint32.cpp | 2 | ||||
-rw-r--r-- | engines/sci/graphics/screen_item32.h | 2 | ||||
-rw-r--r-- | engines/sci/graphics/video32.cpp | 365 | ||||
-rw-r--r-- | engines/sci/graphics/video32.h | 275 |
8 files changed, 704 insertions, 15 deletions
diff --git a/engines/sci/graphics/controls32.cpp b/engines/sci/graphics/controls32.cpp index 4cbb4541df..6b91bb4679 100644 --- a/engines/sci/graphics/controls32.cpp +++ b/engines/sci/graphics/controls32.cpp @@ -459,7 +459,7 @@ void ScrollWindow::hide() { return; } - g_sci->_gfxFrameout->deleteScreenItem(_screenItem, _plane); + g_sci->_gfxFrameout->deleteScreenItem(*_screenItem, _plane); _screenItem = nullptr; g_sci->_gfxFrameout->frameOut(true); diff --git a/engines/sci/graphics/cursor.h b/engines/sci/graphics/cursor.h index 8d125c45b3..5125469cfe 100644 --- a/engines/sci/graphics/cursor.h +++ b/engines/sci/graphics/cursor.h @@ -25,6 +25,8 @@ #include "common/array.h" #include "common/hashmap.h" +#include "sci/sci.h" +#include "sci/graphics/helpers.h" namespace Sci { diff --git a/engines/sci/graphics/frameout.cpp b/engines/sci/graphics/frameout.cpp index c0feea8999..ceab949969 100644 --- a/engines/sci/graphics/frameout.cpp +++ b/engines/sci/graphics/frameout.cpp @@ -278,20 +278,52 @@ bool GfxFrameout::checkForFred(const reg_t object) { #pragma mark - #pragma mark Screen items -void GfxFrameout::deleteScreenItem(ScreenItem *screenItem, Plane *plane) { - if (screenItem->_created == 0) { - screenItem->_created = 0; - screenItem->_updated = 0; - screenItem->_deleted = getScreenCount(); +void GfxFrameout::addScreenItem(ScreenItem &screenItem) const { + Plane *plane = _planes.findByObject(screenItem._plane); + if (plane == nullptr) { + error("GfxFrameout::addScreenItem: Could not find plane %04x:%04x for screen item %04x:%04x", PRINT_REG(screenItem._plane), PRINT_REG(screenItem._object)); + } + plane->_screenItemList.add(&screenItem); +} + +void GfxFrameout::updateScreenItem(ScreenItem &screenItem) const { + // TODO: In SCI3+ this will need to go through Plane +// Plane *plane = _planes.findByObject(screenItem._plane); +// if (plane == nullptr) { +// error("GfxFrameout::updateScreenItem: Could not find plane %04x:%04x for screen item %04x:%04x", PRINT_REG(screenItem._plane), PRINT_REG(screenItem._object)); +// } + + screenItem.update(); +} + +void GfxFrameout::deleteScreenItem(ScreenItem &screenItem) { + Plane *plane = _planes.findByObject(screenItem._plane); + if (plane == nullptr) { + error("GfxFrameout::deleteScreenItem: Could not find plane %04x:%04x for screen item %04x:%04x", PRINT_REG(screenItem._plane), PRINT_REG(screenItem._object)); + } + if (plane->_screenItemList.findByObject(screenItem._object) == nullptr) { + error("GfxFrameout::deleteScreenItem: Screen item %04x:%04x not found in plane %04x:%04x", PRINT_REG(screenItem._object), PRINT_REG(screenItem._plane)); + } + deleteScreenItem(screenItem, *plane); +} + +void GfxFrameout::deleteScreenItem(ScreenItem &screenItem, Plane &plane) { + if (screenItem._created == 0) { + screenItem._created = 0; + screenItem._updated = 0; + screenItem._deleted = getScreenCount(); } else { - plane->_screenItemList.erase(screenItem); - plane->_screenItemList.pack(); + plane._screenItemList.erase(&screenItem); + plane._screenItemList.pack(); } } -void GfxFrameout::deleteScreenItem(ScreenItem *screenItem, const reg_t planeObject) { +void GfxFrameout::deleteScreenItem(ScreenItem &screenItem, const reg_t planeObject) { Plane *plane = _planes.findByObject(planeObject); - deleteScreenItem(screenItem, plane); + if (plane == nullptr) { + error("GfxFrameout::deleteScreenItem: Could not find plane %04x:%04x for screen item %04x:%04x", PRINT_REG(planeObject), PRINT_REG(screenItem._object)); + } + deleteScreenItem(screenItem, *plane); } void GfxFrameout::kernelAddScreenItem(const reg_t object) { @@ -364,7 +396,7 @@ void GfxFrameout::kernelDeleteScreenItem(const reg_t object) { return; } - deleteScreenItem(screenItem, plane); + deleteScreenItem(*screenItem, *plane); } #pragma mark - diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h index cc62c61d22..99658ede6a 100644 --- a/engines/sci/graphics/frameout.h +++ b/engines/sci/graphics/frameout.h @@ -202,14 +202,29 @@ private: public: /** + * Adds a screen item. + */ + void addScreenItem(ScreenItem &screenItem) const; + + /** + * Updates a screen item. + */ + void updateScreenItem(ScreenItem &screenItem) const; + + /** + * Deletes a screen item. + */ + void deleteScreenItem(ScreenItem &screenItem); + + /** * Deletes a screen item from the given plane. */ - void deleteScreenItem(ScreenItem *screenItem, Plane *plane); + void deleteScreenItem(ScreenItem &screenItem, Plane &plane); /** * Deletes a screen item from the given plane. */ - void deleteScreenItem(ScreenItem *screenItem, const reg_t plane); + void deleteScreenItem(ScreenItem &screenItem, const reg_t plane); void kernelAddScreenItem(const reg_t object); void kernelUpdateScreenItem(const reg_t object); diff --git a/engines/sci/graphics/paint32.cpp b/engines/sci/graphics/paint32.cpp index bfd46484e9..74eb1629d0 100644 --- a/engines/sci/graphics/paint32.cpp +++ b/engines/sci/graphics/paint32.cpp @@ -81,7 +81,7 @@ void GfxPaint32::kernelDeleteLine(const reg_t screenItemObject, const reg_t plan } _segMan->freeHunkEntry(screenItem->_celInfo.bitmap); - g_sci->_gfxFrameout->deleteScreenItem(screenItem, plane); + g_sci->_gfxFrameout->deleteScreenItem(*screenItem, *plane); } void GfxPaint32::plotter(int x, int y, int color, void *data) { diff --git a/engines/sci/graphics/screen_item32.h b/engines/sci/graphics/screen_item32.h index caa7a9d725..56f858dc74 100644 --- a/engines/sci/graphics/screen_item32.h +++ b/engines/sci/graphics/screen_item32.h @@ -64,12 +64,12 @@ private: */ static uint16 _nextObjectId; +public: /** * The parent plane of this screen item. */ reg_t _plane; -public: /** * Scaling data used to calculate the final screen * dimensions of the screen item as well as the scaling diff --git a/engines/sci/graphics/video32.cpp b/engines/sci/graphics/video32.cpp new file mode 100644 index 0000000000..0f0116e41c --- /dev/null +++ b/engines/sci/graphics/video32.cpp @@ -0,0 +1,365 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#include "audio/mixer.h" +#include "sci/console.h" +#include "sci/event.h" +#include "sci/graphics/cursor.h" +#include "sci/graphics/frameout.h" +#include "sci/graphics/palette32.h" +#include "sci/graphics/text32.h" +#include "sci/graphics/video32.h" +#include "sci/sci.h" +#include "video/coktel_decoder.h" + +namespace Sci { +VMDPlayer::VMDPlayer(SegManager *segMan, EventManager *eventMan) : + _segMan(segMan), + _eventMan(eventMan), + _decoder(new Video::AdvancedVMDDecoder(Audio::Mixer::kSFXSoundType)), + _isOpen(false), + _isInitialized(false), + _startColor(0), + _planeSet(false), + _endColor(255), + _blackLines(false), + _doublePixels(false), + _lastYieldedFrameNo(0), + _blackoutRect(), + _blackPalette(false), + _boostPercent(100), + _boostStartColor(0), + _boostEndColor(255), + _leaveLastFrame(false), + _leaveScreenBlack(false), + _plane(nullptr), + _screenItem(nullptr), + _stretchVertical(false), + _priority(0), + _blackoutPlane(nullptr), + _yieldInterval(0) {} + +VMDPlayer::~VMDPlayer() { + close(); + delete _decoder; +} + +VMDPlayer::IOStatus VMDPlayer::open(const Common::String &fileName, const OpenFlags flags) { + if (_isOpen) { + error("Attempted to play %s, but another VMD was loaded", fileName.c_str()); + } + + if (_decoder->loadFile(fileName)) { + if (flags & kOpenFlagMute) { + _decoder->setVolume(0); + } + _isOpen = true; + return kIOSuccess; + } else { + return kIOError; + } +} + +void VMDPlayer::init(const int16 x, const int16 y, const PlayFlags flags, const int16 boostPercent, const int16 boostStartColor, const int16 boostEndColor) { + _x = getSciVersion() >= SCI_VERSION_3 ? x : (x & ~1); + _y = y; + _leaveScreenBlack = flags & kPlayFlagLeaveScreenBlack; + _leaveLastFrame = flags & kPlayFlagLeaveLastFrame; + _doublePixels = flags & kPlayFlagDoublePixels; + _blackLines = flags & kPlayFlagBlackLines; + _boostPercent = 100 + (flags & kPlayFlagBoost ? boostPercent : 0); + _blackPalette = flags & kPlayFlagBlackPalette; + _stretchVertical = flags & kPlayFlagStretchVertical; + _boostStartColor = CLIP<int16>(boostStartColor, 0, 255); + _boostEndColor = CLIP<int16>(boostEndColor, 0, 255); +} + +void VMDPlayer::restrictPalette(const uint8 startColor, const uint8 endColor) { + _startColor = startColor; + _endColor = endColor; +} + +VMDPlayer::EventFlags VMDPlayer::kernelPlayUntilEvent(const EventFlags flags, const int16 lastFrameNo, const int16 yieldInterval) { + assert(lastFrameNo >= -1); + + const int32 maxFrameNo = (int32)(_decoder->getFrameCount() - 1); + + if ((flags & kEventFlagToFrame) && lastFrameNo > 0) { + _decoder->setEndFrame(MIN((int32)lastFrameNo, maxFrameNo)); + } else { + _decoder->setEndFrame(maxFrameNo); + } + + if (flags & kEventFlagYieldToVM) { + _yieldInterval = 3; + if (yieldInterval == -1 && !(flags & kEventFlagToFrame)) { + _yieldInterval = lastFrameNo; + } else if (yieldInterval != -1) { + _yieldInterval = MIN((int32)yieldInterval, maxFrameNo); + } + } else { + _yieldInterval = maxFrameNo; + } + + return playUntilEvent(flags); +} + +VMDPlayer::EventFlags VMDPlayer::playUntilEvent(const EventFlags flags) { + // Flushing all the keyboard and mouse events out of the event manager to + // avoid letting any events queued from before the video started from + // accidentally activating an event callback + for (;;) { + const SciEvent event = _eventMan->getSciEvent(SCI_EVENT_KEYBOARD | SCI_EVENT_MOUSE_PRESS | SCI_EVENT_MOUSE_RELEASE | SCI_EVENT_QUIT); + if (event.type == SCI_EVENT_NONE) { + break; + } else if (event.type == SCI_EVENT_QUIT) { + return kEventFlagEnd; + } + } + + _decoder->pauseVideo(false); + + if (flags & kEventFlagReverse) { + // NOTE: This flag may not work properly since SSCI does not care + // if a video has audio, but the VMD decoder does. + const bool success = _decoder->setReverse(true); + assert(success); + _decoder->setVolume(0); + } + + if (!_isInitialized) { + _isInitialized = true; + + if (!_showCursor) { + g_sci->_gfxCursor->kernelHide(); + } + + const int16 screenWidth = g_sci->_gfxFrameout->getCurrentBuffer().screenWidth; + const int16 screenHeight = g_sci->_gfxFrameout->getCurrentBuffer().screenHeight; + const int16 scriptWidth = g_sci->_gfxFrameout->getCurrentBuffer().scriptWidth; + const int16 scriptHeight = g_sci->_gfxFrameout->getCurrentBuffer().scriptHeight; + + Common::Rect vmdRect( + _x, + _y, + _x + _decoder->getWidth(), + _y + _decoder->getHeight() + ); + ScaleInfo vmdScaleInfo; + + if (!_blackoutRect.isEmpty() && !_planeSet) { + _blackoutPlane = new Plane(_blackoutRect); + g_sci->_gfxFrameout->addPlane(*_blackoutPlane); + } + + if (_doublePixels) { + vmdScaleInfo.x = 256; + vmdScaleInfo.y = 256; + vmdScaleInfo.signal = kScaleSignalDoScaling32; + vmdRect.right += vmdRect.width(); + vmdRect.bottom += vmdRect.height(); + } else if (_stretchVertical) { + vmdScaleInfo.y = 256; + vmdScaleInfo.signal = kScaleSignalDoScaling32; + vmdRect.bottom += vmdRect.height(); + } + + BitmapResource vmdBitmap(_segMan, vmdRect.width(), vmdRect.height(), 255, 0, 0, screenWidth, screenHeight, 0, false); + + if (screenWidth != scriptWidth || screenHeight != scriptHeight) { + mulru(vmdRect, Ratio(scriptWidth, screenWidth), Ratio(scriptHeight, screenHeight), 1); + } + + CelInfo32 vmdCelInfo; + vmdCelInfo.bitmap = vmdBitmap.getObject(); + _decoder->setSurfaceMemory(vmdBitmap.getPixels(), vmdBitmap.getWidth(), vmdBitmap.getHeight(), 1); + + if (!_planeSet) { + _x = 0; + _y = 0; + _plane = new Plane(vmdRect, kPlanePicColored); + if (_priority) { + _plane->_priority = _priority; + } + g_sci->_gfxFrameout->addPlane(*_plane); + _screenItem = new ScreenItem(_plane->_object, vmdCelInfo, Common::Point(), vmdScaleInfo); + } else { + _screenItem = new ScreenItem(_plane->_object, vmdCelInfo, Common::Point(_x, _y), vmdScaleInfo); + if (_priority) { + _screenItem->_priority = _priority; + } + } + + // NOTE: There was code for positioning the screen item using insetRect + // here, but none of the game scripts seem to use this functionality. + + g_sci->_gfxFrameout->addScreenItem(*_screenItem); + + _decoder->start(); + } + + EventFlags stopFlag = kEventFlagNone; + while (!g_engine->shouldQuit()) { + if (_decoder->endOfVideo()) { + stopFlag = kEventFlagEnd; + break; + } + + g_sci->getEngineState()->speedThrottler(_decoder->getTimeToNextFrame()); + g_sci->getEngineState()->_throttleTrigger = true; + if (_decoder->needsUpdate()) { + renderFrame(); + } + + const int currentFrameNo = _decoder->getCurFrame(); + + if ( + _yieldInterval > 0 && + currentFrameNo != _lastYieldedFrameNo && + (currentFrameNo % _yieldInterval) == 0 + ) { + _lastYieldedFrameNo = currentFrameNo; + stopFlag = kEventFlagYieldToVM; + break; + } + + if (flags & kEventFlagMouseDown && _eventMan->getSciEvent(SCI_EVENT_MOUSE_PRESS | SCI_EVENT_PEEK).type != SCI_EVENT_NONE) { + stopFlag = kEventFlagMouseDown; + break; + } + + if (flags & kEventFlagEscapeKey) { + const SciEvent event = _eventMan->getSciEvent(SCI_EVENT_KEYBOARD | SCI_EVENT_PEEK); + if (event.type != SCI_EVENT_NONE && event.character == SCI_KEY_ESC) { + stopFlag = kEventFlagEscapeKey; + break; + } + } + + if (flags & kEventFlagHotRectangle) { + // TODO: Hot rectangles + warning("Hot rectangles not implemented in VMD player"); + stopFlag = kEventFlagHotRectangle; + break; + } + } + + _decoder->pauseVideo(true); + return stopFlag; +} + +void VMDPlayer::renderFrame() { + // TODO: This is kind of different from the original implementation + // which has access to dirty rects from the decoder; we probably do + // not need to care to limit output this way + + _decoder->decodeNextFrame(); + + // NOTE: Normally this would write a hunk palette at the end of the + // video bitmap that CelObjMem would read out and submit, but instead + // we are just submitting it directly here because the decoder exposes + // this information a little bit differently than the one in SSCI + const bool dirtyPalette = _decoder->hasDirtyPalette(); + if (dirtyPalette) { + Palette palette; + if (_blackPalette) { + for (uint16 i = _startColor; i <= _endColor; ++i) { + palette.colors[i].r = palette.colors[i].g = palette.colors[i].b = 0; + palette.colors[i].used = true; + } + } else { + const byte *vmdPalette = _decoder->getPalette() + _startColor * 3; + for (uint16 i = _startColor; i <= _endColor; ++i) { + palette.colors[i].r = *vmdPalette++; + palette.colors[i].g = *vmdPalette++; + palette.colors[i].b = *vmdPalette++; + palette.colors[i].used = true; + } + } + + g_sci->_gfxPalette32->submit(palette); + g_sci->_gfxFrameout->updateScreenItem(*_screenItem); + g_sci->_gfxFrameout->frameOut(true); + + if (_blackPalette) { + const byte *vmdPalette = _decoder->getPalette() + _startColor * 3; + for (uint16 i = _startColor; i <= _endColor; ++i) { + palette.colors[i].r = *vmdPalette++; + palette.colors[i].g = *vmdPalette++; + palette.colors[i].b = *vmdPalette++; + palette.colors[i].used = true; + } + + g_sci->_gfxPalette32->submit(palette); + g_sci->_gfxPalette32->updateForFrame(); + g_sci->_gfxPalette32->updateHardware(); + } + } else { + g_sci->_gfxFrameout->updateScreenItem(*_screenItem); + g_sci->getSciDebugger()->onFrame(); + g_sci->_gfxFrameout->frameOut(true); + g_sci->_gfxFrameout->throttle(); + } +} + +VMDPlayer::IOStatus VMDPlayer::close() { + if (!_isOpen) { + return kIOSuccess; + } + + _decoder->close(); + _isOpen = false; + _isInitialized = false; + + if (_planeSet && _screenItem != nullptr) { + g_sci->_gfxFrameout->deleteScreenItem(*_screenItem); + _screenItem = nullptr; + } else if (_plane != nullptr) { + g_sci->_gfxFrameout->deletePlane(*_plane); + _plane = nullptr; + } + + if (!_leaveLastFrame && _leaveScreenBlack) { + // This call *actually* deletes the plane/screen item + g_sci->_gfxFrameout->frameOut(true); + } + + if (_blackoutPlane != nullptr) { + g_sci->_gfxFrameout->deletePlane(*_blackoutPlane); + _blackoutPlane = nullptr; + } + + if (!_leaveLastFrame && !_leaveScreenBlack) { + // This call *actually* deletes the blackout plane + g_sci->_gfxFrameout->frameOut(true); + } + + if (!_showCursor) { + g_sci->_gfxCursor->kernelShow(); + } + + _planeSet = false; + _priority = 0; + return kIOSuccess; +} + +} // End of namespace Sci diff --git a/engines/sci/graphics/video32.h b/engines/sci/graphics/video32.h new file mode 100644 index 0000000000..481b222f6f --- /dev/null +++ b/engines/sci/graphics/video32.h @@ -0,0 +1,275 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef SCI_GRAPHICS_VIDEO32_H +#define SCI_GRAPHICS_VIDEO32_H + +namespace Video { class AdvancedVMDDecoder; } +namespace Sci { +class Plane; +class ScreenItem; +class SegManager; + +class VMDPlayer { +public: + enum OpenFlags { + kOpenFlagNone = 0, + kOpenFlagMute = 1 + }; + + enum IOStatus { + kIOSuccess = 0, + kIOError = 0xFFFF + }; + + enum PlayFlags { + kPlayFlagNone = 0, + kPlayFlagDoublePixels = 1, + kPlayFlagNoFrameskip = 2, // NOTE: the current VMD decoder does not allow this + kPlayFlagBlackLines = 4, + kPlayFlagBoost = 0x10, + kPlayFlagLeaveScreenBlack = 0x20, + kPlayFlagLeaveLastFrame = 0x40, + kPlayFlagBlackPalette = 0x80, + kPlayFlagStretchVertical = 0x100 + }; + + enum EventFlags { + kEventFlagNone = 0, + kEventFlagEnd = 1, + kEventFlagEscapeKey = 2, + kEventFlagMouseDown = 4, + kEventFlagHotRectangle = 8, + kEventFlagToFrame = 0x10, + kEventFlagYieldToVM = 0x20, + kEventFlagReverse = 0x80 + }; + + VMDPlayer(SegManager *segMan, EventManager *eventMan); + ~VMDPlayer(); + + /** + * Opens a stream to a VMD resource. + */ + IOStatus open(const Common::String &fileName, const OpenFlags flags); + + /** + * Initializes the VMD rendering parameters for the + * current VMD. This must be called after `open`. + */ + void init(const int16 x, const int16 y, const PlayFlags flags, const int16 boostPercent, const int16 boostStartColor, const int16 boostEndColor); + + /** + * Stops playback and closes the currently open VMD stream. + */ + IOStatus close(); + + /** + * Restricts use of the system palette by VMD playback to + * the given range of palette indexes. + */ + void restrictPalette(const uint8 startColor, const uint8 endColor); + + // NOTE: Was WaitForEvent in SSCI + EventFlags kernelPlayUntilEvent(const EventFlags flags, const int16 lastFrameNo, const int16 yieldInterval); + + /** + * Sets the area of the screen that should be blacked out + * during VMD playback. + */ + void setBlackoutArea(const Common::Rect &rect) { _blackoutRect = rect; } + + /** + * Sets whether or not the mouse cursor should be drawn. + * This does not have any effect during playback, but can + * be used to prevent the mouse cursor from being shown + * after the video has finished. + */ + void setShowCursor(const bool shouldShow) { _showCursor = shouldShow; } + +private: + SegManager *_segMan; + EventManager *_eventMan; + Video::AdvancedVMDDecoder *_decoder; + + /** + * Plays the VMD until an event occurs (e.g. user + * presses escape, clicks, etc.). + */ + EventFlags playUntilEvent(const EventFlags flags); + + /** + * Renders a frame of video to the output bitmap. + */ + void renderFrame(); + + /** + * Whether or not a VMD stream has been opened with + * `open`. + */ + bool _isOpen; + + /** + * Whether or not a VMD player has been initialised + * with `init`. + */ + bool _isInitialized; + + /** + * Whether or not the playback area of the VMD + * should be left black at the end of playback. + */ + bool _leaveScreenBlack; + + /** + * Whether or not the area of the VMD should be left + * displaying the final frame of the video. + */ + bool _leaveLastFrame; + + /** + * Whether or not the video should be pixel doubled. + */ + bool _doublePixels; + + /** + * Whether or not the video should be pixel doubled + * vertically only. + */ + bool _stretchVertical; + + /** + * Whether or not black lines should be rendered + * across the video. + */ + bool _blackLines; + + /** + * The amount of brightness boost for the video. + * Values above 100 increase brightness; values below + * 100 reduce it. + */ + int16 _boostPercent; + + /** + * The first color in the palette that should be + * brightness boosted. + */ + uint8 _boostStartColor; + + /** + * The last color in the palette that should be + * brightness boosted. + */ + uint8 _boostEndColor; + + /** + * The first color in the system palette that the VMD + * can write to. + */ + uint8 _startColor; + + /** + * The last color in the system palette that the VMD + * can write to. + */ + uint8 _endColor; + + /** + * If true, video frames are rendered after a blank + * palette is submitted to the palette manager, + * which is then restored after the video pixels + * have already been rendered. + */ + bool _blackPalette; + + // TODO: planeSet and priority are used in SCI3+ only + bool _planeSet; + + /** + * The screen priority of the video. + * @see ScreenItem::_priority + */ + int _priority; + + /** + * The plane where the VMD will be drawn. + */ + Plane *_plane; + + /** + * The screen item representing the VMD surface. + */ + ScreenItem *_screenItem; + + /** + * An optional plane that will be used to black out + * areas of the screen outside the area of the VMD + * surface. + */ + Plane *_blackoutPlane; + + /** + * The dimensions of the blackout plane. + */ + Common::Rect _blackoutRect; + + /** + * Whether or not the mouse cursor should be shown + * during playback. + */ + bool _showCursor; + + /** + * The location of the VMD plane, in game script + * coordinates. + */ + int16 _x, _y; + + /** + * For VMDs played with the `kEventFlagYieldToVM` flag, + * the number of frames that should be drawn until + * yielding back to the SCI VM. + */ + int32 _yieldInterval; + + /** + * For VMDs played with the `kEventFlagYieldToVM` flag, + * the last frame when control of the main thread was + * yielded back to the SCI VM. + */ + int _lastYieldedFrameNo; +}; + +class Video32 { +public: + Video32(SegManager *segMan, EventManager *eventMan) : + _VMDPlayer(segMan, eventMan) {} + + VMDPlayer &getVMDPlayer() { return _VMDPlayer; } + +private: + VMDPlayer _VMDPlayer; +}; +} // End of namespace Sci + +#endif |