aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
authorWillem Jan Palenstijn2012-02-23 22:43:56 +0100
committerWillem Jan Palenstijn2012-02-23 22:49:59 +0100
commit4637d55337d083d85bea762db7d59b47e92c0fbe (patch)
tree38a53feb1d8ffcbb53a62635da18127e492e2905 /engines
parent6e70f7728915b766d647668a156b09f84a3c40cf (diff)
parent7a3e0ea45300ba950d71ba0eae9381a0b0869f01 (diff)
downloadscummvm-rg350-4637d55337d083d85bea762db7d59b47e92c0fbe.tar.gz
scummvm-rg350-4637d55337d083d85bea762db7d59b47e92c0fbe.tar.bz2
scummvm-rg350-4637d55337d083d85bea762db7d59b47e92c0fbe.zip
Merge pull request #171 from clone2727/psx-stream-2
This is a manual merge based on clone2727's merge of his branch with the sword1 subtitle changes on master.
Diffstat (limited to 'engines')
-rw-r--r--engines/sword1/animation.cpp147
-rw-r--r--engines/sword1/animation.h13
-rw-r--r--engines/sword1/sword1.cpp5
-rw-r--r--engines/sword2/animation.cpp140
-rw-r--r--engines/sword2/animation.h17
-rw-r--r--engines/sword2/function.cpp4
-rw-r--r--engines/sword2/sword2.cpp1
7 files changed, 261 insertions, 66 deletions
diff --git a/engines/sword1/animation.cpp b/engines/sword1/animation.cpp
index e274e02cfd..1e2964054a 100644
--- a/engines/sword1/animation.cpp
+++ b/engines/sword1/animation.cpp
@@ -37,6 +37,11 @@
#include "gui/message.h"
+#include "video/psx_decoder.h"
+#include "video/smk_decoder.h"
+
+#include "engines/util.h"
+
namespace Sword1 {
static const char *const sequenceList[20] = {
@@ -62,6 +67,31 @@ static const char *const sequenceList[20] = {
"credits", // 19 CD2 credits, to follow "finale" sequence
};
+// This is the list of the names of the PlayStation videos
+// TODO: fight.str, flashy.str,
+static const char *const sequenceListPSX[20] = {
+ "e_ferr1",
+ "ladder1",
+ "steps1",
+ "sewer1",
+ "e_intro1",
+ "river1",
+ "truck1",
+ "grave1",
+ "montfcn1",
+ "tapesty1",
+ "ireland1",
+ "e_fin1",
+ "e_hist1",
+ "spanish1",
+ "well1",
+ "candle1",
+ "geodrop1",
+ "vulture1",
+ "", // demo video not present
+ "" // credits are not a video
+};
+
///////////////////////////////////////////////////////////////////////////////
// Basic movie player
///////////////////////////////////////////////////////////////////////////////
@@ -150,6 +180,21 @@ bool MoviePlayer::load(uint32 id) {
case kVideoDecoderSMK:
filename = Common::String::format("%s.smk", sequenceList[id]);
break;
+ case kVideoDecoderPSX:
+ filename = Common::String::format("%s.str", (_vm->_systemVars.isDemo) ? sequenceList[id] : sequenceListPSX[id]);
+
+ // Need to switch to true color
+ initGraphics(g_system->getWidth(), g_system->getHeight(), true, 0);
+
+ // Need to load here in case it fails in which case we'd need
+ // to go back to paletted mode
+ if (_decoder->loadFile(filename)) {
+ return true;
+ } else {
+ initGraphics(g_system->getWidth(), g_system->getHeight(), true);
+ return false;
+ }
+ break;
}
return _decoder->loadFile(filename.c_str());
@@ -187,6 +232,11 @@ void MoviePlayer::play() {
}
void MoviePlayer::performPostProcessing(byte *screen) {
+ // TODO: We don't support the PSX stream videos yet
+ // nor using the PSX fonts to display subtitles.
+ if (_vm->isPsx())
+ return;
+
if (!_movieTexts.empty()) {
if (_decoder->getCurFrame() == _movieTexts.front()._startFrame) {
_textMan->makeTextSprite(2, (const uint8 *)_movieTexts.front()._text.c_str(), 600, LETTER_COL);
@@ -215,10 +265,10 @@ void MoviePlayer::performPostProcessing(byte *screen) {
for (x = 0; x < _textWidth; x++) {
switch (src[x]) {
case BORDER_COL:
- dst[x] = findBlackPalIndex();
+ dst[x] = getBlackColor();
break;
case LETTER_COL:
- dst[x] = findTextColorPalIndex();
+ dst[x] = findTextColor();
break;
}
}
@@ -238,12 +288,12 @@ void MoviePlayer::performPostProcessing(byte *screen) {
for (y = 0; y < _textHeight; y++) {
if (_textY + y < frameY || _textY + y >= frameY + frameHeight) {
- memset(dst + _textX, findBlackPalIndex(), _textWidth);
+ memset(dst + _textX, getBlackColor(), _textWidth);
} else {
if (frameX > _textX)
- memset(dst + _textX, findBlackPalIndex(), frameX - _textX);
+ memset(dst + _textX, getBlackColor(), frameX - _textX);
if (frameX + frameWidth < _textX + _textWidth)
- memset(dst + frameX + frameWidth, findBlackPalIndex(), _textX + _textWidth - (frameX + frameWidth));
+ memset(dst + frameX + frameWidth, getBlackColor(), _textX + _textWidth - (frameX + frameWidth));
}
dst += _system->getWidth();
@@ -255,14 +305,19 @@ void MoviePlayer::performPostProcessing(byte *screen) {
}
bool MoviePlayer::playVideo() {
+ bool skipped = false;
uint16 x = (g_system->getWidth() - _decoder->getWidth()) / 2;
uint16 y = (g_system->getHeight() - _decoder->getHeight()) / 2;
- while (!_vm->shouldQuit() && !_decoder->endOfVideo()) {
+ while (!_vm->shouldQuit() && !_decoder->endOfVideo() && !skipped) {
if (_decoder->needsUpdate()) {
const Graphics::Surface *frame = _decoder->decodeNextFrame();
- if (frame)
- _vm->_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+ if (frame) {
+ if (_decoderType == kVideoDecoderPSX)
+ drawFramePSX(frame);
+ else
+ _vm->_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+ }
if (_decoder->hasDirtyPalette()) {
_decoder->setSystemPalette();
@@ -362,19 +417,40 @@ bool MoviePlayer::playVideo() {
Common::Event event;
while (_vm->_system->getEventManager()->pollEvent(event))
if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP)
- return false;
+ skipped = true;
_vm->_system->delayMillis(10);
}
- return !_vm->shouldQuit();
+ if (_decoderType == kVideoDecoderPSX) {
+ // Need to jump back to paletted color
+ initGraphics(g_system->getWidth(), g_system->getHeight(), true);
+ }
+
+ return !_vm->shouldQuit() && !skipped;
}
-byte MoviePlayer::findBlackPalIndex() {
- return _black;
+uint32 MoviePlayer::getBlackColor() {
+ return (_decoderType == kVideoDecoderPSX) ? g_system->getScreenFormat().RGBToColor(0x00, 0x00, 0x00) : _black;
}
-
-byte MoviePlayer::findTextColorPalIndex() {
+
+uint32 MoviePlayer::findTextColor() {
+ if (_decoderType == kVideoDecoderPSX) {
+ // We're in true color mode, so return the actual colors
+ switch (_textColor) {
+ case 1:
+ return g_system->getScreenFormat().RGBToColor(248, 252, 248);
+ case 2:
+ return g_system->getScreenFormat().RGBToColor(184, 188, 184);
+ case 3:
+ return g_system->getScreenFormat().RGBToColor(200, 120, 184);
+ case 4:
+ return g_system->getScreenFormat().RGBToColor(80, 152, 184);
+ }
+
+ return g_system->getScreenFormat().RGBToColor(0xFF, 0xFF, 0xFF);
+ }
+
switch (_textColor) {
case 1:
return _c1Color;
@@ -413,6 +489,23 @@ void MoviePlayer::convertColor(byte r, byte g, byte b, float &h, float &s, float
}
}
+void MoviePlayer::drawFramePSX(const Graphics::Surface *frame) {
+ // The PSX videos have half resolution
+
+ Graphics::Surface scaledFrame;
+ scaledFrame.create(frame->w, frame->h * 2, frame->format);
+
+ for (int y = 0; y < scaledFrame.h; y++)
+ memcpy(scaledFrame.getBasePtr(0, y), frame->getBasePtr(0, y / 2), scaledFrame.w * scaledFrame.format.bytesPerPixel);
+
+ uint16 x = (g_system->getWidth() - scaledFrame.w) / 2;
+ uint16 y = (g_system->getHeight() - scaledFrame.h) / 2;
+
+ _vm->_system->copyRectToScreen((byte *)scaledFrame.pixels, scaledFrame.pitch, x, y, scaledFrame.w, scaledFrame.h);
+
+ scaledFrame.free();
+}
+
DXADecoderWithSound::DXADecoderWithSound(Audio::Mixer *mixer, Audio::SoundHandle *bgSoundHandle)
: _mixer(mixer), _bgSoundHandle(bgSoundHandle) {
}
@@ -432,6 +525,24 @@ MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan *
Common::String filename;
Audio::SoundHandle *bgSoundHandle = new Audio::SoundHandle;
+ // For the PSX version, we'll try the PlayStation stream files
+ if (vm->isPsx()) {
+ // The demo uses the normal file names
+ filename = ((vm->_systemVars.isDemo) ? Common::String(sequenceList[id]) : Common::String(sequenceListPSX[id])) + ".str";
+
+ if (Common::File::exists(filename)) {
+#ifdef USE_RGB_COLOR
+ // All BS1 PSX videos run the videos at 2x speed
+ Video::VideoDecoder *psxDecoder = new Video::PSXStreamDecoder(Video::PSXStreamDecoder::kCD2x);
+ return new MoviePlayer(vm, textMan, resMan, snd, system, bgSoundHandle, psxDecoder, kVideoDecoderPSX);
+#else
+ GUI::MessageDialog dialog(Common::String::format(_("PSX stream cutscene '%s' cannot be played in paletted mode"), filename.c_str()), _("OK"));
+ dialog.runModal();
+ return 0;
+#endif
+ }
+ }
+
filename = Common::String::format("%s.smk", sequenceList[id]);
if (Common::File::exists(filename)) {
@@ -461,9 +572,11 @@ MoviePlayer *makeMoviePlayer(uint32 id, SwordEngine *vm, Text *textMan, ResMan *
return NULL;
}
- Common::String buf = Common::String::format(_("Cutscene '%s' not found"), sequenceList[id]);
- GUI::MessageDialog dialog(buf, _("OK"));
- dialog.runModal();
+ if (!vm->isPsx() || scumm_stricmp(sequenceList[id], "enddemo") != 0) {
+ Common::String buf = Common::String::format(_("Cutscene '%s' not found"), sequenceList[id]);
+ GUI::MessageDialog dialog(buf, _("OK"));
+ dialog.runModal();
+ }
return NULL;
}
diff --git a/engines/sword1/animation.h b/engines/sword1/animation.h
index c436607211..f64b03dd1b 100644
--- a/engines/sword1/animation.h
+++ b/engines/sword1/animation.h
@@ -24,7 +24,6 @@
#define SWORD1_ANIMATION_H
#include "video/dxa_decoder.h"
-#include "video/smk_decoder.h"
#include "video/video_decoder.h"
#include "common/list.h"
@@ -38,7 +37,8 @@ namespace Sword1 {
enum DecoderType {
kVideoDecoderDXA = 0,
- kVideoDecoderSMK = 1
+ kVideoDecoderSMK = 1,
+ kVideoDecoderPSX = 2
};
class MovieText {
@@ -83,8 +83,8 @@ protected:
Common::List<MovieText> _movieTexts;
int _textX, _textY, _textWidth, _textHeight;
int _textColor;
- byte _black;
- byte _c1Color, _c2Color, _c3Color, _c4Color;
+ uint32 _black;
+ uint32 _c1Color, _c2Color, _c3Color, _c4Color;
DecoderType _decoderType;
Video::VideoDecoder *_decoder;
@@ -93,9 +93,10 @@ protected:
bool playVideo();
void performPostProcessing(byte *screen);
+ void drawFramePSX(const Graphics::Surface *frame);
- byte findBlackPalIndex();
- byte findTextColorPalIndex();
+ uint32 getBlackColor();
+ uint32 findTextColor();
void convertColor(byte r, byte g, byte b, float &h, float &s, float &v);
};
diff --git a/engines/sword1/sword1.cpp b/engines/sword1/sword1.cpp
index 865e025786..75e8f72d9d 100644
--- a/engines/sword1/sword1.cpp
+++ b/engines/sword1/sword1.cpp
@@ -62,8 +62,9 @@ SwordEngine::SwordEngine(OSystem *syst)
SearchMan.addSubDirectoryMatching(gameDataDir, "speech");
SearchMan.addSubDirectoryMatching(gameDataDir, "video");
SearchMan.addSubDirectoryMatching(gameDataDir, "smackshi");
- SearchMan.addSubDirectoryMatching(gameDataDir, "english");//PSX Demo
- SearchMan.addSubDirectoryMatching(gameDataDir, "italian");//PSX Demo
+ SearchMan.addSubDirectoryMatching(gameDataDir, "streams"); // PSX videos
+ SearchMan.addSubDirectoryMatching(gameDataDir, "english"); // PSX Demo
+ SearchMan.addSubDirectoryMatching(gameDataDir, "italian"); // PSX Demo
_console = new SwordConsole(this);
}
diff --git a/engines/sword2/animation.cpp b/engines/sword2/animation.cpp
index 80b4809722..e77ae98163 100644
--- a/engines/sword2/animation.cpp
+++ b/engines/sword2/animation.cpp
@@ -40,6 +40,11 @@
#include "gui/message.h"
+#include "video/smk_decoder.h"
+#include "video/psx_decoder.h"
+
+#include "engines/util.h"
+
namespace Sword2 {
///////////////////////////////////////////////////////////////////////////////
@@ -66,6 +71,10 @@ MoviePlayer::~MoviePlayer() {
* @param id the id of the file
*/
bool MoviePlayer::load(const char *name) {
+ // This happens when quitting during the "eye" cutscene.
+ if (_vm->shouldQuit())
+ return false;
+
if (_decoderType == kVideoDecoderDXA)
_bgSoundStream = Audio::SeekableAudioStream::openStreamFile(name);
else
@@ -81,16 +90,26 @@ bool MoviePlayer::load(const char *name) {
case kVideoDecoderSMK:
filename = Common::String::format("%s.smk", name);
break;
+ case kVideoDecoderPSX:
+ filename = Common::String::format("%s.str", name);
+
+ // Need to switch to true color
+ initGraphics(640, 480, true, 0);
+
+ // Need to load here in case it fails in which case we'd need
+ // to go back to paletted mode
+ if (_decoder->loadFile(filename)) {
+ return true;
+ } else {
+ initGraphics(640, 480, true);
+ return false;
+ }
}
return _decoder->loadFile(filename.c_str());
}
void MoviePlayer::play(MovieText *movieTexts, uint32 numMovieTexts, uint32 leadIn, uint32 leadOut) {
- // This happens when quitting during the "eye" cutscene.
- if (_vm->shouldQuit())
- return;
-
_leadOutFrame = _decoder->getFrameCount();
if (_leadOutFrame > 60)
_leadOutFrame -= 60;
@@ -120,6 +139,11 @@ void MoviePlayer::play(MovieText *movieTexts, uint32 numMovieTexts, uint32 leadI
while (_snd->isSoundHandleActive(*_bgSoundHandle))
_system->delayMillis(100);
+
+ if (_decoderType == kVideoDecoderPSX) {
+ // Need to jump back to paletted color
+ initGraphics(640, 480, true);
+ }
}
void MoviePlayer::openTextObject(uint32 index) {
@@ -165,7 +189,7 @@ void MoviePlayer::openTextObject(uint32 index) {
}
}
-void MoviePlayer::closeTextObject(uint32 index, byte *screen, uint16 pitch) {
+void MoviePlayer::closeTextObject(uint32 index, Graphics::Surface *screen, uint16 pitch) {
if (index < _numMovieTexts) {
MovieText *text = &_movieTexts[index];
@@ -180,23 +204,23 @@ void MoviePlayer::closeTextObject(uint32 index, byte *screen, uint16 pitch) {
int frameWidth = _decoder->getWidth();
int frameHeight = _decoder->getHeight();
+
+ if (_decoderType == kVideoDecoderPSX)
+ frameHeight *= 2;
+
int frameX = (_system->getWidth() - frameWidth) / 2;
int frameY = (_system->getHeight() - frameHeight) / 2;
- byte black = findBlackPalIndex();
-
- byte *dst = screen + _textY * pitch;
+ uint32 black = getBlackColor();
for (int y = 0; y < text->_textSprite.h; y++) {
if (_textY + y < frameY || _textY + y >= frameY + frameHeight) {
- memset(dst + _textX, black, text->_textSprite.w);
+ screen->hLine(_textX, _textY + y, _textX + text->_textSprite.w, black);
} else {
if (frameX > _textX)
- memset(dst + _textX, black, frameX - _textX);
+ screen->hLine(_textX, _textY + y, frameX, black);
if (frameX + frameWidth < _textX + text->_textSprite.w)
- memset(dst + frameX + frameWidth, black, _textX + text->_textSprite.w - (frameX + frameWidth));
+ screen->hLine(frameX + frameWidth, _textY + y, text->_textSprite.w, black);
}
-
- dst += pitch;
}
}
@@ -206,11 +230,24 @@ void MoviePlayer::closeTextObject(uint32 index, byte *screen, uint16 pitch) {
}
}
-void MoviePlayer::drawTextObject(uint32 index, byte *screen, uint16 pitch) {
+#define PUT_PIXEL(c) \
+ switch (screen->format.bytesPerPixel) { \
+ case 1: \
+ *dst = (c); \
+ break; \
+ case 2: \
+ WRITE_UINT16(dst, (c)); \
+ break; \
+ case 4: \
+ WRITE_UINT32(dst, (c)); \
+ break; \
+ }
+
+void MoviePlayer::drawTextObject(uint32 index, Graphics::Surface *screen, uint16 pitch) {
MovieText *text = &_movieTexts[index];
- byte white = findWhitePalIndex();
- byte black = findBlackPalIndex();
+ uint32 white = getWhiteColor();
+ uint32 black = getBlackColor();
if (text->_textMem && _textSurface) {
byte *src = text->_textSprite.data;
@@ -226,17 +263,20 @@ void MoviePlayer::drawTextObject(uint32 index, byte *screen, uint16 pitch) {
src = psxSpriteBuffer;
}
- byte *dst = screen + _textY * pitch + _textX;
-
for (int y = 0; y < height; y++) {
+ byte *dst = (byte *)screen->getBasePtr(_textX, _textY + y);
+
for (int x = 0; x < width; x++) {
- if (src[x] == 1)
- dst[x] = black;
- else if (src[x] == 255)
- dst[x] = white;
+ if (src[x] == 1) {
+ PUT_PIXEL(black);
+ } else if (src[x] == 255) {
+ PUT_PIXEL(white);
+ }
+
+ dst += screen->format.bytesPerPixel;
}
+
src += width;
- dst += pitch;
}
// Free buffer used to resize psx sprite
@@ -245,7 +285,9 @@ void MoviePlayer::drawTextObject(uint32 index, byte *screen, uint16 pitch) {
}
}
-void MoviePlayer::performPostProcessing(byte *screen, uint16 pitch) {
+#undef PUT_PIXEL
+
+void MoviePlayer::performPostProcessing(Graphics::Surface *screen, uint16 pitch) {
MovieText *text;
int frame = _decoder->getCurFrame();
@@ -286,8 +328,12 @@ bool MoviePlayer::playVideo() {
while (!_vm->shouldQuit() && !_decoder->endOfVideo()) {
if (_decoder->needsUpdate()) {
const Graphics::Surface *frame = _decoder->decodeNextFrame();
- if (frame)
- _vm->_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+ if (frame) {
+ if (_decoderType == kVideoDecoderPSX)
+ drawFramePSX(frame);
+ else
+ _vm->_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
+ }
if (_decoder->hasDirtyPalette()) {
_decoder->setSystemPalette();
@@ -319,7 +365,7 @@ bool MoviePlayer::playVideo() {
}
Graphics::Surface *screen = _vm->_system->lockScreen();
- performPostProcessing((byte *)screen->pixels, screen->pitch);
+ performPostProcessing(screen, screen->pitch);
_vm->_system->unlockScreen();
_vm->_system->updateScreen();
}
@@ -335,12 +381,29 @@ bool MoviePlayer::playVideo() {
return !_vm->shouldQuit();
}
-byte MoviePlayer::findBlackPalIndex() {
- return _black;
+uint32 MoviePlayer::getBlackColor() {
+ return (_decoderType == kVideoDecoderPSX) ? g_system->getScreenFormat().RGBToColor(0x00, 0x00, 0x00) : _black;
}
-byte MoviePlayer::findWhitePalIndex() {
- return _white;
+uint32 MoviePlayer::getWhiteColor() {
+ return (_decoderType == kVideoDecoderPSX) ? g_system->getScreenFormat().RGBToColor(0xFF, 0xFF, 0xFF) : _white;
+}
+
+void MoviePlayer::drawFramePSX(const Graphics::Surface *frame) {
+ // The PSX videos have half resolution
+
+ Graphics::Surface scaledFrame;
+ scaledFrame.create(frame->w, frame->h * 2, frame->format);
+
+ for (int y = 0; y < scaledFrame.h; y++)
+ memcpy(scaledFrame.getBasePtr(0, y), frame->getBasePtr(0, y / 2), scaledFrame.w * scaledFrame.format.bytesPerPixel);
+
+ uint16 x = (g_system->getWidth() - scaledFrame.w) / 2;
+ uint16 y = (g_system->getHeight() - scaledFrame.h) / 2;
+
+ _vm->_system->copyRectToScreen((byte *)scaledFrame.pixels, scaledFrame.pitch, x, y, scaledFrame.w, scaledFrame.h);
+
+ scaledFrame.free();
}
DXADecoderWithSound::DXADecoderWithSound(Audio::Mixer *mixer, Audio::SoundHandle *bgSoundHandle)
@@ -358,10 +421,23 @@ uint32 DXADecoderWithSound::getElapsedTime() const {
// Factory function for creating the appropriate cutscene player
///////////////////////////////////////////////////////////////////////////////
-MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, Audio::Mixer *snd, OSystem *system) {
+MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, Audio::Mixer *snd, OSystem *system, uint32 frameCount) {
Common::String filename;
Audio::SoundHandle *bgSoundHandle = new Audio::SoundHandle;
+ filename = Common::String::format("%s.str", name);
+
+ if (Common::File::exists(filename)) {
+#ifdef USE_RGB_COLOR
+ Video::VideoDecoder *psxDecoder = new Video::PSXStreamDecoder(Video::PSXStreamDecoder::kCD2x, frameCount);
+ return new MoviePlayer(vm, snd, system, bgSoundHandle, psxDecoder, kVideoDecoderPSX);
+#else
+ GUI::MessageDialog dialog(_("PSX cutscenes found but ScummVM has been built without RGB color support"), _("OK"));
+ dialog.runModal();
+ return NULL;
+#endif
+ }
+
filename = Common::String::format("%s.smk", name);
if (Common::File::exists(filename)) {
diff --git a/engines/sword2/animation.h b/engines/sword2/animation.h
index 1f5fced03b..3ef8dac754 100644
--- a/engines/sword2/animation.h
+++ b/engines/sword2/animation.h
@@ -26,7 +26,6 @@
#define SWORD2_ANIMATION_H
#include "video/dxa_decoder.h"
-#include "video/smk_decoder.h"
#include "video/video_decoder.h"
#include "audio/mixer.h"
@@ -36,7 +35,8 @@ namespace Sword2 {
enum DecoderType {
kVideoDecoderDXA = 0,
- kVideoDecoderSMK = 1
+ kVideoDecoderSMK = 1,
+ kVideoDecoderPSX = 2
};
struct MovieText {
@@ -93,18 +93,19 @@ protected:
uint32 _leadOut;
int _leadOutFrame;
- void performPostProcessing(byte *screen, uint16 pitch);
+ void performPostProcessing(Graphics::Surface *screen, uint16 pitch);
bool playVideo();
+ void drawFramePSX(const Graphics::Surface *frame);
void openTextObject(uint32 index);
- void closeTextObject(uint32 index, byte *screen, uint16 pitch);
- void drawTextObject(uint32 index, byte *screen, uint16 pitch);
+ void closeTextObject(uint32 index, Graphics::Surface *screen, uint16 pitch);
+ void drawTextObject(uint32 index, Graphics::Surface *screen, uint16 pitch);
- byte findBlackPalIndex();
- byte findWhitePalIndex();
+ uint32 getBlackColor();
+ uint32 getWhiteColor();
};
-MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, Audio::Mixer *snd, OSystem *system);
+MoviePlayer *makeMoviePlayer(const char *name, Sword2Engine *vm, Audio::Mixer *snd, OSystem *system, uint32 frameCount);
} // End of namespace Sword2
diff --git a/engines/sword2/function.cpp b/engines/sword2/function.cpp
index 60ee6176a4..836b252d6c 100644
--- a/engines/sword2/function.cpp
+++ b/engines/sword2/function.cpp
@@ -2137,7 +2137,9 @@ int32 Logic::fnPlaySequence(int32 *params) {
// pause sfx during sequence
_vm->_sound->pauseFx();
- _moviePlayer = makeMoviePlayer(filename, _vm, _vm->_mixer, _vm->_system);
+ uint32 frameCount = Sword2Engine::isPsx() ? params[1] : 0;
+
+ _moviePlayer = makeMoviePlayer(filename, _vm, _vm->_mixer, _vm->_system, frameCount);
if (_moviePlayer && _moviePlayer->load(filename)) {
_moviePlayer->play(_sequenceTextList, _sequenceTextLines, _smackerLeadIn, _smackerLeadOut);
diff --git a/engines/sword2/sword2.cpp b/engines/sword2/sword2.cpp
index 3b7965259c..bdfc388c5f 100644
--- a/engines/sword2/sword2.cpp
+++ b/engines/sword2/sword2.cpp
@@ -255,6 +255,7 @@ Sword2Engine::Sword2Engine(OSystem *syst) : Engine(syst), _rnd("sword2") {
SearchMan.addSubDirectoryMatching(gameDataDir, "sword2");
SearchMan.addSubDirectoryMatching(gameDataDir, "video");
SearchMan.addSubDirectoryMatching(gameDataDir, "smacks");
+ SearchMan.addSubDirectoryMatching(gameDataDir, "streams"); // PSX video
if (!scumm_stricmp(ConfMan.get("gameid").c_str(), "sword2demo") || !scumm_stricmp(ConfMan.get("gameid").c_str(), "sword2psxdemo"))
_features = GF_DEMO;