ASYLUM: Convert Video to new event handling
- Change Text::LoadFont to return the previous font - Fix AsylumEngine::processDelayedEvents not working properly for scenes - Add two params to AsylumEvent (needed by video subtitle handling) git-svn-id: http://asylumengine.googlecode.com/svn/trunk@681 0bfb4aae-4ea4-11de-8d8d-752d95cf3e3c
This commit is contained in:
parent
26eacef2fc
commit
ae4d75e6a0
13 changed files with 245 additions and 256 deletions
|
@ -82,6 +82,10 @@ AsylumEngine::AsylumEngine(OSystem *system, const ADGameDescription *gd) : Engin
|
||||||
_introPlayed = false;
|
_introPlayed = false;
|
||||||
_tickOffset = 0;
|
_tickOffset = 0;
|
||||||
|
|
||||||
|
// Debug
|
||||||
|
_delayedSceneIndex = kResourcePackInvalid;
|
||||||
|
_delayedVideoIndex = -1;
|
||||||
|
|
||||||
// Add default search directories
|
// Add default search directories
|
||||||
const Common::FSNode gameDataDir(ConfMan.get("path"));
|
const Common::FSNode gameDataDir(ConfMan.get("path"));
|
||||||
SearchMan.addSubDirectoryMatching(gameDataDir, "data");
|
SearchMan.addSubDirectoryMatching(gameDataDir, "data");
|
||||||
|
@ -271,7 +275,7 @@ void AsylumEngine::playIntro() {
|
||||||
_sound->playMusic(kResourceNone, 0);
|
_sound->playMusic(kResourceNone, 0);
|
||||||
|
|
||||||
// TODO convert to new event handling
|
// TODO convert to new event handling
|
||||||
_video->playVideo(1);
|
_video->play(1, _mainMenu);
|
||||||
|
|
||||||
if (_scene->worldstats()->musicCurrentResourceIndex != kMusicStopped)
|
if (_scene->worldstats()->musicCurrentResourceIndex != kMusicStopped)
|
||||||
_sound->playMusic(MAKE_RESOURCE(kResourcePackMusic, _scene->worldstats()->musicCurrentResourceIndex));
|
_sound->playMusic(MAKE_RESOURCE(kResourcePackMusic, _scene->worldstats()->musicCurrentResourceIndex));
|
||||||
|
@ -356,7 +360,7 @@ void AsylumEngine::handleEvents() {
|
||||||
if (_handler)
|
if (_handler)
|
||||||
_handler->handleEvent(updateEvt);
|
_handler->handleEvent(updateEvt);
|
||||||
|
|
||||||
// TODO replace by original game code based on switchEventHandler
|
// Handle debug events
|
||||||
processDelayedEvents();
|
processDelayedEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,30 +368,32 @@ void AsylumEngine::processDelayedEvents() {
|
||||||
if (!_video || !_sound || !_mainMenu)
|
if (!_video || !_sound || !_mainMenu)
|
||||||
error("[AsylumEngine::processDelayedEvents] Subsystems not initialized properly!");
|
error("[AsylumEngine::processDelayedEvents] Subsystems not initialized properly!");
|
||||||
|
|
||||||
// check for a delayed video
|
// check for a delayed scene change
|
||||||
int videoIdx = _script->getDelayedVideoIndex();
|
if (_delayedSceneIndex != kResourcePackInvalid && isGameFlagNotSet(kGameFlagScriptProcessing)) {
|
||||||
if (videoIdx >= 0) {
|
ResourcePackId sceneIndex = _delayedSceneIndex;
|
||||||
_sound->stopMusic();
|
|
||||||
_sound->stopAll();
|
|
||||||
_video->playVideo(videoIdx);
|
|
||||||
_script->setDelayedVideoIndex(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for a delayed scene change
|
|
||||||
ResourcePackId packId = _script->getDelayedSceneIndex();
|
|
||||||
if (packId != kResourcePackInvalid && isGameFlagNotSet(kGameFlagScriptProcessing)) {
|
|
||||||
// Reset delayed scene
|
// Reset delayed scene
|
||||||
_script->setDelayedSceneIndex(kResourcePackInvalid);
|
_delayedSceneIndex = kResourcePackInvalid;
|
||||||
|
|
||||||
_sound->stopMusic();
|
_sound->stopMusic();
|
||||||
_sound->stopAll();
|
_sound->stopAll();
|
||||||
|
|
||||||
|
switchEventHandler(NULL);
|
||||||
|
|
||||||
delete _scene;
|
delete _scene;
|
||||||
_scene = new Scene(this);
|
_scene = new Scene(this);
|
||||||
_scene->enter(packId);
|
_scene->enter(sceneIndex);
|
||||||
|
|
||||||
switchEventHandler(_scene);
|
switchEventHandler(_scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check for delayed video
|
||||||
|
if (_delayedVideoIndex != -1 && isGameFlagNotSet(kGameFlagScriptProcessing)) {
|
||||||
|
int32 index = _delayedVideoIndex;
|
||||||
|
_delayedVideoIndex = -1;
|
||||||
|
|
||||||
|
_video->play(index, _handler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -412,11 +418,11 @@ void AsylumEngine::switchEventHandler(EventHandler *handler) {
|
||||||
_handler->handleEvent(init);
|
_handler->handleEvent(init);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AsylumEngine::notify(AsylumEventType type) {
|
void AsylumEngine::notify(AsylumEventType type, int32 param1, int32 param2) {
|
||||||
if (_handler == NULL)
|
if (_handler == NULL)
|
||||||
error("[AsylumEngine::notify] Invalid handler parameter (cannot be NULL)!");
|
error("[AsylumEngine::notify] Invalid handler parameter (cannot be NULL)!");
|
||||||
|
|
||||||
AsylumEvent evt(type);
|
AsylumEvent evt(type, param1, param2);
|
||||||
_handler->handleEvent(evt);
|
_handler->handleEvent(evt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,11 @@ public:
|
||||||
*/
|
*/
|
||||||
void restart();
|
void restart();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run event loop
|
||||||
|
*/
|
||||||
|
void handleEvents();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Switch to a new scene
|
* Switch to a new scene
|
||||||
*
|
*
|
||||||
|
@ -185,7 +190,7 @@ public:
|
||||||
*
|
*
|
||||||
* @param type The event type.
|
* @param type The event type.
|
||||||
*/
|
*/
|
||||||
void notify(AsylumEventType type);
|
void notify(AsylumEventType type, int32 param1 = 0, int32 param2 = 0);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a message handler.
|
* Gets a message handler.
|
||||||
|
@ -248,7 +253,6 @@ private:
|
||||||
bool _introPlayed;
|
bool _introPlayed;
|
||||||
int32 _tickOffset;
|
int32 _tickOffset;
|
||||||
|
|
||||||
void handleEvents();
|
|
||||||
void updateMouseCursor();
|
void updateMouseCursor();
|
||||||
void processDelayedEvents();
|
void processDelayedEvents();
|
||||||
|
|
||||||
|
@ -276,7 +280,11 @@ private:
|
||||||
*/
|
*/
|
||||||
int32 computeSinCosOffset(int32 val);
|
int32 computeSinCosOffset(int32 val);
|
||||||
|
|
||||||
|
|
||||||
|
// Debug
|
||||||
friend class Console;
|
friend class Console;
|
||||||
|
ResourcePackId _delayedSceneIndex;
|
||||||
|
int32 _delayedVideoIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Asylum
|
} // namespace Asylum
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include "asylum/system/screen.h"
|
#include "asylum/system/screen.h"
|
||||||
|
|
||||||
#include "asylum/views/scene.h"
|
#include "asylum/views/scene.h"
|
||||||
|
#include "asylum/views/video.h"
|
||||||
|
|
||||||
#include "asylum/asylum.h"
|
#include "asylum/asylum.h"
|
||||||
#include "asylum/respack.h"
|
#include "asylum/respack.h"
|
||||||
|
@ -328,8 +329,7 @@ bool Console::cmdPlayVideo(int32 argc, const char **argv) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
getScreen()->clear();
|
_vm->_delayedVideoIndex = index;
|
||||||
getScript()->setDelayedVideoIndex(index);
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -374,7 +374,7 @@ bool Console::cmdChangeScene(int32 argc, const char **argv) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
getScript()->setDelayedSceneIndex(index);
|
_vm->_delayedSceneIndex = index;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,13 +45,21 @@ enum AsylumEventType {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct AsylumEvent : public Common::Event {
|
struct AsylumEvent : public Common::Event {
|
||||||
AsylumEvent() : Event() {}
|
AsylumEvent() : Event() {
|
||||||
|
param1 = 0;
|
||||||
|
param2 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Since we don't feed any custom message into the event manager,
|
// Since we don't feed any custom message into the event manager,
|
||||||
// we can safely use our own custom event type.
|
// we can safely use our own custom event type.
|
||||||
AsylumEvent(AsylumEventType msgType) : Event() {
|
AsylumEvent(AsylumEventType msgType, int32 p1 = 0, int32 p2 = 0) : Event() {
|
||||||
type = (Common::EventType)msgType;
|
type = (Common::EventType)msgType;
|
||||||
|
param1 = p1;
|
||||||
|
param2 = p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 param1;
|
||||||
|
int32 param2;
|
||||||
};
|
};
|
||||||
|
|
||||||
class EventHandler {
|
class EventHandler {
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "asylum/system/text.h"
|
#include "asylum/system/text.h"
|
||||||
|
|
||||||
#include "asylum/views/scene.h"
|
#include "asylum/views/scene.h"
|
||||||
|
#include "asylum/views/video.h"
|
||||||
|
|
||||||
#include "asylum/asylum.h"
|
#include "asylum/asylum.h"
|
||||||
#include "asylum/respack.h"
|
#include "asylum/respack.h"
|
||||||
|
@ -1549,7 +1550,7 @@ void Encounter::runScript() {
|
||||||
if (!getSharedData()->getMatteBarHeight()) {
|
if (!getSharedData()->getMatteBarHeight()) {
|
||||||
getScreen()->makeGreyPalette();
|
getScreen()->makeGreyPalette();
|
||||||
getSharedData()->setMatteBarHeight(1);
|
getSharedData()->setMatteBarHeight(1);
|
||||||
getScript()->setDelayedVideoIndex(getVariableInv(entry.param2));
|
getVideo()->play(getVariableInv(entry.param2), this);
|
||||||
getSharedData()->setMatteVar1(1);
|
getSharedData()->setMatteVar1(1);
|
||||||
getSharedData()->setMattePlaySound(true);
|
getSharedData()->setMattePlaySound(true);
|
||||||
getSharedData()->setMatteInitialized(true);
|
getSharedData()->setMatteInitialized(true);
|
||||||
|
|
|
@ -160,12 +160,6 @@ public:
|
||||||
*/
|
*/
|
||||||
void resetQueue();
|
void resetQueue();
|
||||||
|
|
||||||
// Accessors
|
|
||||||
int32 getDelayedVideoIndex() const { return _delayedVideoIndex; }
|
|
||||||
void setDelayedVideoIndex(int32 val) { _delayedVideoIndex = val; }
|
|
||||||
ResourcePackId getDelayedSceneIndex() const { return _delayedSceneIndex; }
|
|
||||||
void setDelayedSceneIndex(ResourcePackId id) { _delayedSceneIndex = id; }
|
|
||||||
|
|
||||||
bool isProcessingSkipped() { return _skipProcessing; }
|
bool isProcessingSkipped() { return _skipProcessing; }
|
||||||
|
|
||||||
// Serializable
|
// Serializable
|
||||||
|
|
|
@ -141,8 +141,7 @@ void Screen::drawWideScreenBars(int16 barSize) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::fillRect(int32 x, int32 y, int32 width, int32 height, int32 color) {
|
void Screen::fillRect(int32 x, int32 y, int32 width, int32 height, int32 color) {
|
||||||
_vm->_system->lockScreen()->fillRect(Common::Rect(x, y, x + width, y + height), color);
|
_backBuffer.fillRect(Common::Rect(x, y, x + width, y + height), color);
|
||||||
_vm->_system->unlockScreen();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::copyBackBufferToScreen() {
|
void Screen::copyBackBufferToScreen() {
|
||||||
|
@ -239,6 +238,10 @@ void Screen::makeGreyPalette() {
|
||||||
warning("[Screen::makeGreyPalette] Not implemented!");
|
warning("[Screen::makeGreyPalette] Not implemented!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Screen::setupPalette(byte *buffer, int start, int count) {
|
||||||
|
warning("[Screen::setupPalette] Not implemented!");
|
||||||
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
// Gamma
|
// Gamma
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -95,6 +95,7 @@ public:
|
||||||
void startPaletteFade(ResourceId resourceId, int32 milliseconds, int32 param);
|
void startPaletteFade(ResourceId resourceId, int32 milliseconds, int32 param);
|
||||||
void updatePalette(int32 param);
|
void updatePalette(int32 param);
|
||||||
void makeGreyPalette();
|
void makeGreyPalette();
|
||||||
|
void setupPalette(byte *buffer, int start, int count);
|
||||||
|
|
||||||
// Gamma
|
// Gamma
|
||||||
void setGammaLevel(ResourceId id, int32 val);
|
void setGammaLevel(ResourceId id, int32 val);
|
||||||
|
@ -114,6 +115,9 @@ public:
|
||||||
void clearGraphicsInQueue();
|
void clearGraphicsInQueue();
|
||||||
void deleteGraphicFromQueue(ResourceId resourceId);
|
void deleteGraphicFromQueue(ResourceId resourceId);
|
||||||
|
|
||||||
|
// Used by Video
|
||||||
|
void copyToBackBuffer(byte *buffer, int32 pitch, int32 x, int32 y, uint32 width, uint32 height);
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
void copyToBackBufferClipped(Graphics::Surface *surface, int x, int y);
|
void copyToBackBufferClipped(Graphics::Surface *surface, int x, int y);
|
||||||
|
|
||||||
|
@ -146,8 +150,6 @@ private:
|
||||||
void blt(Common::Rect *dest, GraphicFrame* frame, Common::Rect *source, int32 flags, bool useColorKey);
|
void blt(Common::Rect *dest, GraphicFrame* frame, Common::Rect *source, int32 flags, bool useColorKey);
|
||||||
void bltFast(int32 dX, int32 dY, GraphicFrame* frame, Common::Rect *source, bool useColorKey);
|
void bltFast(int32 dX, int32 dY, GraphicFrame* frame, Common::Rect *source, bool useColorKey);
|
||||||
|
|
||||||
|
|
||||||
void copyToBackBuffer(byte *buffer, int32 pitch, int32 x, int32 y, uint32 width, uint32 height);
|
|
||||||
void copyToBackBufferWithTransparency(byte *buffer, int32 pitch, int32 x, int32 y, int32 width, int32 height);
|
void copyToBackBufferWithTransparency(byte *buffer, int32 pitch, int32 x, int32 y, int32 width, int32 height);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -51,17 +51,21 @@ Text::~Text() {
|
||||||
_vm = NULL;
|
_vm = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Text::loadFont(ResourceId resourceId) {
|
ResourceId Text::loadFont(ResourceId resourceId) {
|
||||||
if (_fontResource && resourceId == _fontResource->getResourceId())
|
if (_fontResource && resourceId == _fontResource->getResourceId())
|
||||||
return;
|
return resourceId;
|
||||||
|
|
||||||
|
ResourceId previousFont = _fontResource ? _fontResource->getResourceId() : kResourceNone;
|
||||||
|
|
||||||
delete _fontResource;
|
delete _fontResource;
|
||||||
_fontResource = new GraphicResource(_vm, resourceId);
|
_fontResource = NULL;
|
||||||
|
|
||||||
if (resourceId != kResourceNone) {
|
if (resourceId != kResourceNone) {
|
||||||
// load font flag data
|
_fontResource = new GraphicResource(_vm, resourceId);
|
||||||
_curFontFlags = Common::Rational(_fontResource->getData().flags, 16).toInt() & 0x0F;
|
_curFontFlags = Common::Rational(_fontResource->getData().flags, 16).toInt() & 0x0F;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return previousFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Text::setPosition(int32 x, int32 y) {
|
void Text::setPosition(int32 x, int32 y) {
|
||||||
|
|
|
@ -47,7 +47,7 @@ public:
|
||||||
Text(AsylumEngine *engine);
|
Text(AsylumEngine *engine);
|
||||||
~Text();
|
~Text();
|
||||||
|
|
||||||
void loadFont(ResourceId resourceId);
|
ResourceId loadFont(ResourceId resourceId);
|
||||||
|
|
||||||
void setPosition(int32 x, int32 y);
|
void setPosition(int32 x, int32 y);
|
||||||
int32 getWidth(char c);
|
int32 getWidth(char c);
|
||||||
|
|
|
@ -354,7 +354,7 @@ bool MainMenu::init() {
|
||||||
_needEyeCursorInit = true;
|
_needEyeCursorInit = true;
|
||||||
|
|
||||||
// Play start video
|
// Play start video
|
||||||
getVideo()->playVideo(0);
|
getVideo()->play(0, this);
|
||||||
|
|
||||||
// If no savegame is present, start the game directly
|
// If no savegame is present, start the game directly
|
||||||
if (!getSaveLoad()->hasSavegames()) {
|
if (!getSaveLoad()->hasSavegames()) {
|
||||||
|
|
|
@ -26,8 +26,11 @@
|
||||||
#include "asylum/views/video.h"
|
#include "asylum/views/video.h"
|
||||||
|
|
||||||
#include "asylum/system/config.h"
|
#include "asylum/system/config.h"
|
||||||
|
#include "asylum/system/cursor.h"
|
||||||
#include "asylum/system/graphics.h"
|
#include "asylum/system/graphics.h"
|
||||||
#include "asylum/system/savegame.h"
|
#include "asylum/system/savegame.h"
|
||||||
|
#include "asylum/system/screen.h"
|
||||||
|
#include "asylum/system/sound.h"
|
||||||
#include "asylum/system/text.h"
|
#include "asylum/system/text.h"
|
||||||
|
|
||||||
#include "asylum/asylum.h"
|
#include "asylum/asylum.h"
|
||||||
|
@ -36,98 +39,176 @@
|
||||||
|
|
||||||
namespace Asylum {
|
namespace Asylum {
|
||||||
|
|
||||||
Video::Video(AsylumEngine *engine, Audio::Mixer *mixer) : _vm(engine), _skipVideo(false) {
|
Video::Video(AsylumEngine *engine, Audio::Mixer *mixer) : _vm(engine),
|
||||||
Common::Event stopEvent;
|
_currentMovie(0), _subtitleIndex(0), _subtitleCounter(0), _previousFont(kResourceNone), _done(false) {
|
||||||
_stopEvents.clear();
|
|
||||||
stopEvent.type = Common::EVENT_KEYDOWN;
|
|
||||||
stopEvent.kbd.keycode = Common::KEYCODE_ESCAPE;
|
|
||||||
_stopEvents.push_back(stopEvent);
|
|
||||||
|
|
||||||
_smkDecoder = new Graphics::SmackerDecoder(mixer);
|
_smkDecoder = new Graphics::SmackerDecoder(mixer);
|
||||||
|
|
||||||
_text = new VideoText(engine);
|
|
||||||
_text->loadFont(MAKE_RESOURCE(kResourcePackShared, 57)); // video font
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Video::~Video() {
|
Video::~Video() {
|
||||||
delete _smkDecoder;
|
delete _smkDecoder;
|
||||||
delete _text;
|
|
||||||
|
|
||||||
// Zero-out passed pointers
|
// Zero-out passed pointers
|
||||||
_vm = NULL;
|
_vm = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Video::playVideo(int32 videoNumber) {
|
//////////////////////////////////////////////////////////////////////////
|
||||||
char filename[20];
|
// Event Handler
|
||||||
sprintf(filename, "mov%03d.smk", videoNumber);
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
bool Video::handleEvent(const AsylumEvent &evt) {
|
||||||
|
switch ((uint32)evt.type) {
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
getSaveLoad()->setMovieViewed(videoNumber);
|
case EVENT_ASYLUM_INIT:
|
||||||
|
_previousFont = getText()->loadFont(MAKE_RESOURCE(kResourcePackShared, 57));
|
||||||
|
_subtitleCounter = 0;
|
||||||
|
_subtitleIndex = -1;
|
||||||
|
break;
|
||||||
|
|
||||||
if (!_smkDecoder->loadFile(filename)) {
|
case EVENT_ASYLUM_DEINIT:
|
||||||
_smkDecoder->close();
|
getScreen()->clear();
|
||||||
|
getText()->loadFont(_previousFont);
|
||||||
|
break;
|
||||||
|
|
||||||
error("[Video::playVideo] Invalid video index (%d)", videoNumber);
|
case EVENT_ASYLUM_SUBTITLE: {
|
||||||
|
int32 newIndex = (evt.param2 == 1) ? evt.param1 : -1;
|
||||||
|
|
||||||
|
if (_subtitleIndex != newIndex) {
|
||||||
|
_subtitleIndex = newIndex;
|
||||||
|
_subtitleCounter = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_subtitleCounter > 0) {
|
||||||
|
getScreen()->fillRect(0, 400, 640, 80, 0);
|
||||||
|
|
||||||
|
if (_subtitleIndex >= 0) {
|
||||||
|
char *text1 = getText()->get((ResourceId)_currentMovie);
|
||||||
|
|
||||||
|
int32 y = 10 * (44 - getText()->draw(0, 99, kTextCalculate, 10, 400, 20, 620, text1));
|
||||||
|
if (y <= 400)
|
||||||
|
y = 405;
|
||||||
|
|
||||||
|
char *text = getText()->get(_subtitles[_subtitleIndex].resourceId);
|
||||||
|
getText()->draw(0, 99, kTextCenter, 10, y, 20, 620, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
--_subtitleCounter;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
case Common::EVENT_LBUTTONDOWN:
|
||||||
|
case Common::EVENT_KEYDOWN:
|
||||||
|
_done = true;
|
||||||
|
getScreen()->clear();
|
||||||
|
|
||||||
|
// Original set a value that does not seems to be used anywhere
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lastMouseState = g_system->showMouse(false);
|
return false;
|
||||||
_skipVideo = false;
|
}
|
||||||
|
|
||||||
if (Config.showMovieSubtitles)
|
//////////////////////////////////////////////////////////////////////////
|
||||||
loadSubtitles(videoNumber);
|
// Playing
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
void Video::play(int32 videoNumber, EventHandler *handler) {
|
||||||
|
getSaveLoad()->setMovieViewed(videoNumber);
|
||||||
|
_currentMovie = videoNumber;
|
||||||
|
|
||||||
|
// Prepare
|
||||||
|
getCursor()->hide();
|
||||||
|
getSharedData()->setFlag(kFlag1, true);
|
||||||
|
getScreen()->paletteFade(0, 25, 10);
|
||||||
|
getSound()->stopAll();
|
||||||
|
|
||||||
|
// Play movie
|
||||||
|
_vm->switchEventHandler(this);
|
||||||
|
play(Common::String::format("mov%03d.smk", videoNumber), Config.showMovieSubtitles);
|
||||||
|
|
||||||
|
// Cleanup and switch to previous event handler
|
||||||
|
getCursor()->show();
|
||||||
|
getSharedData()->setFlag(kFlag1, false);
|
||||||
|
_vm->switchEventHandler(handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Video::play(Common::String filename, bool showSubtitles) {
|
||||||
|
if (!_smkDecoder->loadFile(filename))
|
||||||
|
error("[Video::playVideo] Invalid video index (%d)", _currentMovie);
|
||||||
|
|
||||||
int32 x = Common::Rational(g_system->getWidth() - _smkDecoder->getWidth(), 2).toInt();
|
int32 x = Common::Rational(g_system->getWidth() - _smkDecoder->getWidth(), 2).toInt();
|
||||||
int32 y = Common::Rational(g_system->getHeight() - _smkDecoder->getHeight(), 2).toInt();
|
int32 y = Common::Rational(g_system->getHeight() - _smkDecoder->getHeight(), 2).toInt();
|
||||||
|
|
||||||
while (!_smkDecoder->endOfVideo() && !_skipVideo) {
|
getScreen()->clear();
|
||||||
processVideoEvents();
|
|
||||||
|
// TODO check flags and setup volume panning
|
||||||
|
|
||||||
|
// Load subtitles
|
||||||
|
if (showSubtitles)
|
||||||
|
loadSubtitles();
|
||||||
|
|
||||||
|
// Setup playing
|
||||||
|
_done = false;
|
||||||
|
uint32 index = 0;
|
||||||
|
int32 frameStart = 0;
|
||||||
|
int32 frameEnd = 0;
|
||||||
|
int32 currentSubtitle = 0;
|
||||||
|
|
||||||
|
while (!_done && !_vm->shouldQuit() && !_smkDecoder->endOfVideo()) {
|
||||||
|
_vm->handleEvents();
|
||||||
|
|
||||||
if (_smkDecoder->needsUpdate()) {
|
if (_smkDecoder->needsUpdate()) {
|
||||||
Graphics::Surface *frame = _smkDecoder->decodeNextFrame();
|
Graphics::Surface *frame = _smkDecoder->decodeNextFrame();
|
||||||
|
|
||||||
|
if (!frame)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (frame) {
|
if (_smkDecoder->hasDirtyPalette())
|
||||||
g_system->copyRectToScreen((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
|
setupPalette();
|
||||||
|
|
||||||
if(Config.showMovieSubtitles) {
|
getScreen()->copyToBackBuffer((byte *)frame->pixels, frame->pitch, x, y, frame->w, frame->h);
|
||||||
Graphics::Surface *screen = g_system->lockScreen();
|
|
||||||
performPostProcessing((byte *)screen->pixels);
|
if (showSubtitles) {
|
||||||
g_system->unlockScreen();
|
int32 currentFrame = _smkDecoder->getCurFrame() + 1;
|
||||||
|
|
||||||
|
// Check for next frame
|
||||||
|
if (currentFrame > frameEnd) {
|
||||||
|
if (index < _subtitles.size()) {
|
||||||
|
frameStart = _subtitles[index].frameStart;
|
||||||
|
frameEnd = _subtitles[index].frameEnd;
|
||||||
|
currentSubtitle = index;
|
||||||
|
++index;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_smkDecoder->hasDirtyPalette())
|
if (currentFrame < frameStart || currentFrame > frameEnd)
|
||||||
_smkDecoder->setSystemPalette();
|
_vm->notify(EVENT_ASYLUM_SUBTITLE, 0, 0);
|
||||||
|
else
|
||||||
g_system->updateScreen();
|
_vm->notify(EVENT_ASYLUM_SUBTITLE, currentSubtitle, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getScreen()->copyBackBufferToScreen();
|
||||||
|
|
||||||
|
g_system->updateScreen();
|
||||||
}
|
}
|
||||||
g_system->delayMillis(10);
|
g_system->delayMillis(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
_smkDecoder->close();
|
_smkDecoder->close();
|
||||||
_subtitles.clear();
|
_subtitles.clear();
|
||||||
g_system->showMouse(lastMouseState);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Video::performPostProcessing(byte *screen) {
|
void Video::setupPalette() {
|
||||||
int32 curFrame = _smkDecoder->getCurFrame();
|
_smkDecoder->setSystemPalette();
|
||||||
|
|
||||||
// Reset subtitle area, by filling it with zeroes
|
warning("[Video::setupPalette] Video palette setup not implemented!");
|
||||||
memset(screen + 640 * 400, 0, 640 * 80);
|
//getScreen()->setupPalette(0, 0, 0);
|
||||||
|
|
||||||
for (uint32 i = 0; i < _subtitles.size(); i++) {
|
|
||||||
VideoSubtitle curSubtitle = _subtitles[i];
|
|
||||||
if (curFrame >= curSubtitle.frameStart &&
|
|
||||||
curFrame <= curSubtitle.frameEnd) {
|
|
||||||
_text->drawMovieSubtitle(screen, curSubtitle.textResourceId);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Video::loadSubtitles(int32 videoNumber) {
|
void Video::loadSubtitles() {
|
||||||
// Read vids.cap
|
|
||||||
|
|
||||||
char movieToken[10];
|
char movieToken[10];
|
||||||
sprintf(movieToken, "[MOV%03d]", videoNumber);
|
sprintf(movieToken, "[MOV%03d]", _currentMovie);
|
||||||
|
|
||||||
Common::File subsFile;
|
Common::File subsFile;
|
||||||
subsFile.open("vids.cap");
|
subsFile.open("vids.cap");
|
||||||
|
@ -163,7 +244,7 @@ void Video::loadSubtitles(int32 videoNumber) {
|
||||||
if (!tok)
|
if (!tok)
|
||||||
error("[Video::loadSubtitles] Invalid subtitle (resource id missing)!");
|
error("[Video::loadSubtitles] Invalid subtitle (resource id missing)!");
|
||||||
|
|
||||||
newSubtitle.textResourceId = (ResourceId)(atoi(tok) + video_subtitle_resourceIds[videoNumber]);
|
newSubtitle.resourceId = (ResourceId)(atoi(tok) + video_subtitle_resourceIds[_currentMovie]);
|
||||||
|
|
||||||
tok = strtok(NULL, " ");
|
tok = strtok(NULL, " ");
|
||||||
|
|
||||||
|
@ -176,131 +257,4 @@ void Video::loadSubtitles(int32 videoNumber) {
|
||||||
delete [] buffer;
|
delete [] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Video::processVideoEvents() {
|
|
||||||
Common::Event curEvent;
|
|
||||||
while (g_system->getEventManager()->pollEvent(curEvent)) {
|
|
||||||
if (curEvent.type == Common::EVENT_RTL || curEvent.type == Common::EVENT_QUIT) {
|
|
||||||
_skipVideo = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Common::List<Common::Event>::const_iterator iter = _stopEvents.begin(); iter != _stopEvents.end(); ++iter) {
|
|
||||||
if (curEvent.type == iter->type) {
|
|
||||||
if (iter->type == Common::EVENT_KEYDOWN || iter->type == Common::EVENT_KEYUP) {
|
|
||||||
if (curEvent.kbd.keycode == iter->kbd.keycode) {
|
|
||||||
_skipVideo = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_skipVideo = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
VideoText::VideoText(AsylumEngine *engine) : _vm(engine) {
|
|
||||||
_curFontFlags = 0;
|
|
||||||
_fontResource = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
VideoText::~VideoText() {
|
|
||||||
delete _fontResource;
|
|
||||||
|
|
||||||
// Zero-out passed pointers
|
|
||||||
_vm = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VideoText::loadFont(ResourceId resourceId) {
|
|
||||||
delete _fontResource;
|
|
||||||
|
|
||||||
_fontResource = new GraphicResource(_vm, resourceId);
|
|
||||||
|
|
||||||
if (resourceId != kResourceNone) {
|
|
||||||
// load font flag data
|
|
||||||
_curFontFlags = Common::Rational(_fontResource->getData().flags, 16).toInt() & 0x0F;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VideoText::drawMovieSubtitle(byte *screenBuffer, ResourceId resourceId) {
|
|
||||||
Common::String textLine[4];
|
|
||||||
Common::String tmpLine;
|
|
||||||
int32 curLine = 0;
|
|
||||||
ResourceEntry *textRes = getResource()->get(resourceId);
|
|
||||||
char *text = strdup((const char *)textRes->data); // for strtok
|
|
||||||
char *tok = strtok(text, " ");
|
|
||||||
int32 startY = 420; // starting y for up to 2 subtitles
|
|
||||||
int32 spacing = 30; // spacing for up to 2 subtitles
|
|
||||||
|
|
||||||
// Videos can have up to 4 lines of text
|
|
||||||
while (tok) {
|
|
||||||
tmpLine += tok;
|
|
||||||
tmpLine += " ";
|
|
||||||
if (getTextWidth(tmpLine.c_str()) > 640) {
|
|
||||||
tmpLine = tok;
|
|
||||||
curLine++;
|
|
||||||
if (curLine >= 2) {
|
|
||||||
startY = 410; // starting Y for 3 subtitles
|
|
||||||
spacing = 20; // spacing for 3-4 subtitles
|
|
||||||
}
|
|
||||||
if (curLine >= 3) {
|
|
||||||
startY = 402; // starting Y for 4 subtitles
|
|
||||||
}
|
|
||||||
}
|
|
||||||
textLine[curLine] += tok;
|
|
||||||
textLine[curLine] += " ";
|
|
||||||
tok = strtok(NULL, " ");
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int32 i = 0; i < curLine + 1; i++) {
|
|
||||||
int32 textWidth = getTextWidth(textLine[i].c_str());
|
|
||||||
drawText(screenBuffer, (int16)Common::Rational(640 - textWidth, 2).toInt(), (int16)(startY + i * spacing), textLine[i].c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
free(text);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32 VideoText::getTextWidth(const char *text) {
|
|
||||||
if (!_fontResource)
|
|
||||||
error("[VideoText::getTextWidth] Video text resources not initialized properly!");
|
|
||||||
|
|
||||||
int32 width = 0;
|
|
||||||
|
|
||||||
while (*text) {
|
|
||||||
GraphicFrame *font = _fontResource->getFrame((uint8)*text);
|
|
||||||
width += font->surface.w + font->x - _curFontFlags;
|
|
||||||
|
|
||||||
text++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VideoText::drawText(byte *screenBuffer, int16 x, int16 y, const char *text) {
|
|
||||||
if (!_fontResource)
|
|
||||||
error("[VideoText::drawText] Video text resources not initialized properly!");
|
|
||||||
|
|
||||||
while (*text) {
|
|
||||||
GraphicFrame *fontLetter = _fontResource->getFrame((uint8)*text);
|
|
||||||
copyToVideoFrame(screenBuffer, fontLetter, x, y + fontLetter->y);
|
|
||||||
x += (int16)(fontLetter->surface.w + fontLetter->x - _curFontFlags);
|
|
||||||
text++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VideoText::copyToVideoFrame(byte *screenBuffer, GraphicFrame *frame, int32 x, int32 y) const {
|
|
||||||
uint16 h = frame->surface.h;
|
|
||||||
uint16 w = frame->surface.w;
|
|
||||||
int32 screenBufferPitch = 640;
|
|
||||||
byte *buffer = (byte *)frame->surface.pixels;
|
|
||||||
byte *dest = screenBuffer + y * screenBufferPitch + x;
|
|
||||||
|
|
||||||
while (h--) {
|
|
||||||
memcpy(dest, buffer, w);
|
|
||||||
dest += screenBufferPitch;
|
|
||||||
buffer += frame->surface.w;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // end of namespace Asylum
|
} // end of namespace Asylum
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#ifndef ASYLUM_VIDEO_H
|
#ifndef ASYLUM_VIDEO_H
|
||||||
#define ASYLUM_VIDEO_H
|
#define ASYLUM_VIDEO_H
|
||||||
|
|
||||||
|
#include "asylum/eventhandler.h"
|
||||||
#include "asylum/shared.h"
|
#include "asylum/shared.h"
|
||||||
|
|
||||||
#include "common/array.h"
|
#include "common/array.h"
|
||||||
|
@ -48,54 +49,62 @@ struct GraphicFrame;
|
||||||
struct VideoSubtitle {
|
struct VideoSubtitle {
|
||||||
int frameStart;
|
int frameStart;
|
||||||
int frameEnd;
|
int frameEnd;
|
||||||
ResourceId textResourceId;
|
ResourceId resourceId;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Video {
|
class Video : public EventHandler {
|
||||||
public:
|
public:
|
||||||
Video(AsylumEngine *engine, Audio::Mixer *mixer);
|
Video(AsylumEngine *engine, Audio::Mixer *mixer);
|
||||||
virtual ~Video();
|
virtual ~Video();
|
||||||
|
|
||||||
void playVideo(int32 videoNumber);
|
/**
|
||||||
|
* Plays a video.
|
||||||
|
*
|
||||||
|
* @param videoNumber The video number.
|
||||||
|
* @param handler The previous event handler.
|
||||||
|
*/
|
||||||
|
void play(int32 videoNumber, EventHandler *handler);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle event.
|
||||||
|
*
|
||||||
|
* @param evt The event.
|
||||||
|
*
|
||||||
|
* @return true if it succeeds, false if it fails.
|
||||||
|
*/
|
||||||
|
bool handleEvent(const AsylumEvent &evt);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AsylumEngine *_vm;
|
AsylumEngine *_vm;
|
||||||
|
|
||||||
void performPostProcessing(byte *screen);
|
|
||||||
void loadSubtitles(int32 videoNumber);
|
|
||||||
void processVideoEvents();
|
|
||||||
|
|
||||||
bool _skipVideo;
|
|
||||||
VideoText *_text;
|
|
||||||
Graphics::SmackerDecoder *_smkDecoder;
|
Graphics::SmackerDecoder *_smkDecoder;
|
||||||
Common::List<Common::Event> _stopEvents;
|
Common::Array<VideoSubtitle> _subtitles;
|
||||||
Common::Array<VideoSubtitle> _subtitles;
|
|
||||||
}; // end of class Video
|
|
||||||
|
|
||||||
// The VideoText class has some methods from the Text class,
|
int32 _currentMovie;
|
||||||
// but it differs from the text class: this class draws text
|
int32 _subtitleIndex;
|
||||||
// to a predefined screen buffer, whereas the Text class draws
|
int32 _subtitleCounter;
|
||||||
// text directly to the screen
|
ResourceId _previousFont;
|
||||||
class VideoText {
|
bool _done;
|
||||||
public:
|
|
||||||
VideoText(AsylumEngine *engine);
|
|
||||||
~VideoText();
|
|
||||||
|
|
||||||
void loadFont(ResourceId resourceId);
|
|
||||||
void drawMovieSubtitle(byte *screenBuffer, ResourceId resourceId);
|
/**
|
||||||
|
* Plays the given file.
|
||||||
|
*
|
||||||
|
* @param filename Filename of the file.
|
||||||
|
* @param showSubtitles true to show, false to hide the subtitles.
|
||||||
|
*/
|
||||||
|
void play(Common::String filename, bool showSubtitles);
|
||||||
|
|
||||||
private:
|
/**
|
||||||
AsylumEngine *_vm;
|
* Sets up the palette.
|
||||||
|
*/
|
||||||
|
void setupPalette();
|
||||||
|
|
||||||
int32 getTextWidth(const char *text);
|
/**
|
||||||
|
* Loads the subtitles (vids.cap)
|
||||||
void drawText(byte *screenBuffer, int16 x, int16 y, const char *text);
|
*/
|
||||||
void copyToVideoFrame(byte *screenBuffer, GraphicFrame *frame, int x, int y) const;
|
void loadSubtitles();
|
||||||
|
};
|
||||||
GraphicResource *_fontResource;
|
|
||||||
uint8 _curFontFlags;
|
|
||||||
|
|
||||||
}; // end of class VideoText
|
|
||||||
|
|
||||||
} // end of namespace Asylum
|
} // end of namespace Asylum
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue