mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-16 22:58:09 +00:00
SCI: VMD video related changes
- VMD videos are now properly started from the associated play subop of the kPlayVMD kernel call, and are now properly positioned on screen, and doubled only if the games require them to be - Added an enum for VMD video flags svn-id: r55003
This commit is contained in:
parent
5a3ed29a4b
commit
430dc10c49
@ -226,7 +226,7 @@ void Console::preEnter() {
|
||||
_engine->pauseEngine(true);
|
||||
}
|
||||
|
||||
extern void playVideo(Graphics::VideoDecoder *videoDecoder);
|
||||
extern void playVideo(Graphics::VideoDecoder *videoDecoder, VideoState videoState);
|
||||
|
||||
void Console::postEnter() {
|
||||
if (!_videoFile.empty()) {
|
||||
@ -272,7 +272,10 @@ void Console::postEnter() {
|
||||
}
|
||||
#endif
|
||||
|
||||
playVideo(videoDecoder);
|
||||
VideoState emptyState;
|
||||
emptyState.fileName = _videoFile;
|
||||
emptyState.flags = kDoubled; // always allow the videos to be double sized
|
||||
playVideo(videoDecoder, emptyState);
|
||||
|
||||
#ifdef ENABLE_SCI32
|
||||
// Switch back to 8bpp if we played a duck video
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
namespace Sci {
|
||||
|
||||
void playVideo(Graphics::VideoDecoder *videoDecoder) {
|
||||
void playVideo(Graphics::VideoDecoder *videoDecoder, VideoState videoState) {
|
||||
if (!videoDecoder)
|
||||
return;
|
||||
|
||||
@ -50,16 +50,24 @@ void playVideo(Graphics::VideoDecoder *videoDecoder) {
|
||||
uint16 pitch = videoDecoder->getWidth() * bytesPerPixel;
|
||||
uint16 screenWidth = g_system->getWidth();
|
||||
uint16 screenHeight = g_system->getHeight();
|
||||
bool isVMD = videoState.fileName.hasSuffix(".vmd");
|
||||
|
||||
if (screenWidth == 640 && width <= 320 && height <= 240) {
|
||||
if (screenWidth == 640 && width <= 320 && height <= 240 && ((videoState.flags & kDoubled) || !isVMD)) {
|
||||
width *= 2;
|
||||
height *= 2;
|
||||
pitch *= 2;
|
||||
scaleBuffer = new byte[width * height * bytesPerPixel];
|
||||
}
|
||||
|
||||
uint16 x = (screenWidth - width) / 2;
|
||||
uint16 y = (screenHeight - height) / 2;
|
||||
uint16 x, y;
|
||||
|
||||
if (videoState.x > 0 && videoState.y > 0 && isVMD) {
|
||||
x = videoState.x;
|
||||
y = videoState.y;
|
||||
} else {
|
||||
x = (screenWidth - width) / 2;
|
||||
y = (screenHeight - height) / 2;
|
||||
}
|
||||
bool skipVideo = false;
|
||||
|
||||
if (videoDecoder->hasDirtyPalette())
|
||||
@ -172,7 +180,7 @@ reg_t kShowMovie(EngineState *s, int argc, reg_t *argv) {
|
||||
}
|
||||
|
||||
if (videoDecoder) {
|
||||
playVideo(videoDecoder);
|
||||
playVideo(videoDecoder, s->_videoState);
|
||||
|
||||
// HACK: Switch back to 8bpp if we played a QuickTime video.
|
||||
// We also won't be copying the screen to the SCI screen...
|
||||
@ -196,32 +204,17 @@ reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv) {
|
||||
uint16 operation = argv[0].toUint16();
|
||||
Graphics::VideoDecoder *videoDecoder = 0;
|
||||
bool reshowCursor = g_sci->_gfxCursor->isVisible();
|
||||
Common::String fileName, warningMsg;
|
||||
Common::String warningMsg;
|
||||
|
||||
switch (operation) {
|
||||
case 0: // init
|
||||
// This is actually meant to init the video file, but we play it instead
|
||||
fileName = s->_segMan->derefString(argv[1]);
|
||||
s->_videoState.reset();
|
||||
s->_videoState.fileName = s->_segMan->derefString(argv[1]);
|
||||
// TODO: argv[2] (usually null). When it exists, it points to an "Event" object,
|
||||
// that holds no data initially (e.g. in the intro of Phantasmagoria 1 demo).
|
||||
// Perhaps it's meant for syncing
|
||||
if (argv[2] != NULL_REG)
|
||||
warning("kPlayVMD: third parameter isn't 0 (it's %04x:%04x - %s)", PRINT_REG(argv[2]), s->_segMan->getObjectName(argv[2]));
|
||||
|
||||
videoDecoder = new Graphics::VMDDecoder(g_system->getMixer());
|
||||
|
||||
if (!videoDecoder->loadFile(fileName)) {
|
||||
warning("Could not open VMD %s", fileName.c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
if (reshowCursor)
|
||||
g_sci->_gfxCursor->kernelHide();
|
||||
|
||||
playVideo(videoDecoder);
|
||||
|
||||
if (reshowCursor)
|
||||
g_sci->_gfxCursor->kernelShow();
|
||||
break;
|
||||
case 1:
|
||||
{
|
||||
@ -229,17 +222,6 @@ reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv) {
|
||||
//
|
||||
// x, y, flags, gammaBoost, gammaFirst, gammaLast
|
||||
//
|
||||
// Flags are as follows:
|
||||
// bit 0 doubled
|
||||
// bit 1 "drop frames"?
|
||||
// bit 2 insert black lines
|
||||
// bit 3 unknown
|
||||
// bit 4 gamma correction
|
||||
// bit 5 hold black frame
|
||||
// bit 6 hold last frame
|
||||
// bit 7 unknown
|
||||
// bit 8 stretch
|
||||
|
||||
// gammaBoost boosts palette colors in the range gammaFirst to
|
||||
// gammaLast, but only if bit 4 in flags is set. Percent value such that
|
||||
// 0% = no amplification These three parameters are optional if bit 4 is
|
||||
@ -247,40 +229,58 @@ reg_t kPlayVMD(EngineState *s, int argc, reg_t *argv) {
|
||||
// with subfx 21. The subtleness has to do with creation of temporary
|
||||
// planes and positioning relative to such planes.
|
||||
|
||||
int flags = argv[3].offset;
|
||||
uint16 flags = argv[3].offset;
|
||||
Common::String flagspec;
|
||||
|
||||
if (argc > 3) {
|
||||
if (flags & 1)
|
||||
if (flags & kDoubled)
|
||||
flagspec += "doubled ";
|
||||
if (flags & 2)
|
||||
if (flags & kDropFrames)
|
||||
flagspec += "dropframes ";
|
||||
if (flags & 4)
|
||||
if (flags & kBlackLines)
|
||||
flagspec += "blacklines ";
|
||||
if (flags & 8)
|
||||
if (flags & kUnkBit3)
|
||||
flagspec += "bit3 ";
|
||||
if (flags & 16)
|
||||
if (flags & kGammaBoost)
|
||||
flagspec += "gammaboost ";
|
||||
if (flags & 32)
|
||||
if (flags & kHoldBlackFrame)
|
||||
flagspec += "holdblack ";
|
||||
if (flags & 64)
|
||||
if (flags & kHoldLastFrame)
|
||||
flagspec += "holdlast ";
|
||||
if (flags & 128)
|
||||
if (flags & kUnkBit7)
|
||||
flagspec += "bit7 ";
|
||||
if (flags & 256)
|
||||
if (flags & kStretch)
|
||||
flagspec += "stretch";
|
||||
|
||||
warning("VMDFlags: %s", flagspec.c_str());
|
||||
|
||||
s->_videoState.flags = flags;
|
||||
}
|
||||
|
||||
warning("x, y: %d, %d", argv[1].offset, argv[2].offset);
|
||||
s->_videoState.x = argv[1].offset;
|
||||
s->_videoState.y = argv[2].offset;
|
||||
|
||||
if (argc > 4 && flags & 16)
|
||||
warning("gammaBoost: %d%% between palette entries %d and %d", argv[4].offset, argv[5].offset, argv[6].offset);
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
// Play, perhaps? Or stop? This is the last call made, and takes no extra parameters
|
||||
case 6: // Play
|
||||
videoDecoder = new Graphics::VMDDecoder(g_system->getMixer());
|
||||
|
||||
if (!videoDecoder->loadFile(s->_videoState.fileName)) {
|
||||
warning("Could not open VMD %s", s->_videoState.fileName.c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
if (reshowCursor)
|
||||
g_sci->_gfxCursor->kernelHide();
|
||||
|
||||
playVideo(videoDecoder, s->_videoState);
|
||||
|
||||
if (reshowCursor)
|
||||
g_sci->_gfxCursor->kernelShow();
|
||||
break;
|
||||
case 14:
|
||||
// Takes an additional integer parameter (e.g. 3)
|
||||
case 16:
|
||||
|
@ -116,6 +116,9 @@ void EngineState::reset(bool isRestoring) {
|
||||
|
||||
scriptStepCounter = 0;
|
||||
scriptGCInterval = GC_INTERVAL;
|
||||
|
||||
_videoState.reset();
|
||||
_syncedAudioOptions = false;
|
||||
}
|
||||
|
||||
void EngineState::speedThrottler(uint32 neededSleep) {
|
||||
|
@ -113,6 +113,31 @@ public:
|
||||
bool isOpen() const;
|
||||
};
|
||||
|
||||
enum VideoFlags {
|
||||
kNone = 0,
|
||||
kDoubled = 1 << 0,
|
||||
kDropFrames = 1 << 1,
|
||||
kBlackLines = 1 << 2,
|
||||
kUnkBit3 = 1 << 3,
|
||||
kGammaBoost = 1 << 4,
|
||||
kHoldBlackFrame = 1 << 5,
|
||||
kHoldLastFrame = 1 << 6,
|
||||
kUnkBit7 = 1 << 7,
|
||||
kStretch = 1 << 8
|
||||
};
|
||||
|
||||
struct VideoState {
|
||||
Common::String fileName;
|
||||
uint16 x;
|
||||
uint16 y;
|
||||
uint16 flags;
|
||||
|
||||
void reset() {
|
||||
fileName = "";
|
||||
x = y = 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct EngineState : public Common::Serializable {
|
||||
public:
|
||||
EngineState(SegManager *segMan);
|
||||
@ -197,7 +222,6 @@ public:
|
||||
|
||||
int gcCountDown; /**< Number of kernel calls until next gc */
|
||||
|
||||
public:
|
||||
MessageState *_msgState;
|
||||
|
||||
// MemorySegment provides access to a 256-byte block of memory that remains
|
||||
@ -208,6 +232,9 @@ public:
|
||||
uint _memorySegmentSize;
|
||||
byte _memorySegment[kMemorySegmentMax];
|
||||
|
||||
VideoState _videoState;
|
||||
bool _syncedAudioOptions;
|
||||
|
||||
/**
|
||||
* Resets the engine state.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user