From 00822d5661a81546c45c83b38c1c9a4e999dd89b Mon Sep 17 00:00:00 2001 From: Max Horn Date: Tue, 20 Oct 2009 14:06:17 +0000 Subject: TINSEL: Move BMV player code into a new BMVPlayer class svn-id: r45269 --- engines/tinsel/bmv.cpp | 211 +++++++++++++++---------------------------- engines/tinsel/bmv.h | 125 +++++++++++++++++++++++-- engines/tinsel/detection.cpp | 4 +- engines/tinsel/tinlib.cpp | 12 +-- engines/tinsel/tinsel.cpp | 17 ++-- engines/tinsel/tinsel.h | 2 + 6 files changed, 212 insertions(+), 159 deletions(-) diff --git a/engines/tinsel/bmv.cpp b/engines/tinsel/bmv.cpp index 89feaae20e..8253fc0788 100644 --- a/engines/tinsel/bmv.cpp +++ b/engines/tinsel/bmv.cpp @@ -24,13 +24,10 @@ * The movie player. */ -#include "common/file.h" -#include "sound/mixer.h" -#include "sound/audiostream.h" #include "tinsel/tinsel.h" #include "tinsel/background.h" +#include "tinsel/bmv.h" #include "tinsel/cliprect.h" -#include "tinsel/coroutine.h" #include "tinsel/config.h" #include "tinsel/dw.h" #include "tinsel/events.h" @@ -39,8 +36,6 @@ #include "tinsel/handle.h" #include "tinsel/heapmem.h" #include "tinsel/multiobj.h" -#include "tinsel/object.h" -#include "tinsel/palette.h" #include "tinsel/sched.h" #include "tinsel/strres.h" #include "tinsel/text.h" @@ -50,14 +45,6 @@ namespace Tinsel { -//----------------- GLOBAL GLOBAL DATA ------------------------ - -bool bOldAudio; - -//----------------- LOCAL GLOBAL DATA ------------------------ - -//static READREQ rr; - //----------------- LOCAL DEFINES ---------------------------- #define SZ_C_BLOB 65 @@ -111,8 +98,7 @@ bool bOldAudio; #define sz_AUDIO_pkt 3675 -typedef struct { - +struct TALK_CMD { short x; short y; short stringId; @@ -120,98 +106,20 @@ typedef struct { char r; // may be b! char g; char b; // may be r! +}; -} TALK_CMD, *PTALK_CMD; - -typedef struct { - +struct PRINT_CMD { int16 x; int16 y; int16 stringId; unsigned char duration; unsigned char fontId; - -} PRINT_CMD, *PPRINT_CMD; +}; //----------------- LOCAL GLOBAL DATA ------------------------ -// Set when a movie is on -static bool bMovieOn; - -// Set to kill one off -static bool bAbort; - -// For escaping out of movies -static int bmvEscape; - -// Movie file pointer -static Common::File stream; - -// Movie file name -static char szMovieFile[14]; - -// Pointers to buffers -static byte *bigBuffer; //, *screenBuffer; - -// Next data to use to extract a frame -static int nextUseOffset; - -// Next data to use to extract sound data -static int nextSoundOffset; - -// When above offset gets to what this is set at, rewind -static int wrapUseOffset; - -// The offset of the most future packet -static int mostFutureOffset; - -// The current frame -static int currentFrame; -static int currentSoundFrame; - -// Number of packets currently in RAM -static int numAdvancePackets; - -// Next slot that will be read from disc -static int nextReadSlot; - -// Set when the whole file has been read -static bool bFileEnd; - -// Palette -static COLORREF moviePal[256]; - -static int blobsInBuffer; - -static struct { - - POBJECT pText; - int dieFrame; - -} texts[2]; - -static COLORREF talkColour; - -static int bigProblemCount; - -static bool bIsText; - -static int movieTick; -static int startTick; -static uint32 nextMovieTime = 0; - -static uint16 Au_Prev1 = 0; -static uint16 Au_Prev2 = 0; -static byte *ScreenBeg; -static byte *screenBuffer; - -static bool audioStarted; - -static Audio::AppendableAudioStream *audioStream = 0; -static Audio::SoundHandle audioHandle; - -const uint16 Au_DecTable[16] = {16512, 8256, 4128, 2064, 1032, 516, 258, 192, +static const uint16 Au_DecTable[16] = {16512, 8256, 4128, 2064, 1032, 516, 258, 192, 129, 88, 64, 56, 48, 40, 36, 32}; //---------------- DECOMPRESSOR FUNCTIONS -------------------- @@ -224,7 +132,7 @@ const uint16 Au_DecTable[16] = {16512, 8256, 4128, 2064, 1032, 516, 258, 192, #define ROL(x,v) x = ((x << (v%32)) | (x >> (32 - (v%32)))); #define NEXT_BYTE(v) v = forwardDirection ? v + 1 : v - 1; -static void PrepBMV(const byte *sourceData, int length, short deltaFetchDisp) { +static void PrepBMV(byte *ScreenBeg, const byte *sourceData, int length, short deltaFetchDisp) { uint8 NibbleHi = 0; const byte *saved_esi; uint32 eax = 0; @@ -368,7 +276,7 @@ static void PrepBMV(const byte *sourceData, int length, short deltaFetchDisp) { } } -static void InitBMV(byte *memoryBuffer) { +void BMVPlayer::InitBMV(byte *memoryBuffer) { // Clear the two extra 'off-screen' rows memset(memoryBuffer, 0, SCREEN_WIDE); memset(memoryBuffer + SCREEN_WIDE * (SCREEN_HIGH + 1), 0, SCREEN_WIDE); @@ -385,7 +293,7 @@ static void InitBMV(byte *memoryBuffer) { Au_Prev1 = Au_Prev2 = 0; } -void PrepAudio(const byte *sourceData, int blobCount, byte *destPtr) { +void BMVPlayer::PrepAudio(const byte *sourceData, int blobCount, byte *destPtr) { uint16 dx1 = Au_Prev1; uint16 dx2 = Au_Prev2; @@ -423,14 +331,51 @@ void PrepAudio(const byte *sourceData, int blobCount, byte *destPtr) { //----------------- BMV FUNCTIONS ---------------------------- -static bool MaintainBuffer(void); +BMVPlayer::BMVPlayer() { + bOldAudio = 0; + bMovieOn = 0; + bAbort = 0; + bmvEscape = 0; + + memset(szMovieFile, 0, sizeof(szMovieFile)); + + bigBuffer = 0; + nextUseOffset = 0; + nextSoundOffset = 0; + wrapUseOffset = 0; + mostFutureOffset = 0; + currentFrame = 0; + currentSoundFrame = 0; + numAdvancePackets = 0; + nextReadSlot = 0; + bFileEnd = 0; + + memset(moviePal, 0, sizeof(moviePal)); + + blobsInBuffer = 0; + memset(texts, 0, sizeof(texts)); + + talkColour = 0; + bigProblemCount = 0; + bIsText = 0; + movieTick = 0; + startTick = 0; + nextMovieTime = 0; + Au_Prev1 = 0; + Au_Prev2 = 0; + ScreenBeg = 0; + screenBuffer = 0; + audioStarted = 0; + audioStream = 0; + nextMaintain = 0; +} /** * Called when a packet contains a palette field. * Build a COLORREF array and queue it to the DAC. */ -static void MoviePalette(int paletteOffset) { +void BMVPlayer::MoviePalette(int paletteOffset) { int i; byte *r; @@ -447,17 +392,17 @@ static void MoviePalette(int paletteOffset) { SetTextPal(talkColour); } -static void InitialiseMovieSound() { +void BMVPlayer::InitialiseMovieSound() { audioStream = Audio::makeAppendableAudioStream(22050, Audio::Mixer::FLAG_16BITS | Audio::Mixer::FLAG_STEREO); audioStarted = false; } -static void StartMovieSound() { +void BMVPlayer::StartMovieSound() { } -static void FinishMovieSound() { +void BMVPlayer::FinishMovieSound() { if (audioStream) { _vm->_mixer->stopHandle(audioHandle); @@ -469,7 +414,7 @@ static void FinishMovieSound() { /** * Called when a packet contains an audio field. */ -static void MovieAudio(int audioOffset, int blobs) { +void BMVPlayer::MovieAudio(int audioOffset, int blobs) { if (audioOffset == 0 && blobs == 0) blobs = 57; @@ -495,7 +440,7 @@ static void MovieAudio(int audioOffset, int blobs) { |-------------------------------------------------------| \*-----------------------------------------------------*/ -static void FettleMovieText(void) { +void BMVPlayer::FettleMovieText(void) { int i; bIsText = false; @@ -517,7 +462,7 @@ static void FettleMovieText(void) { |-------------------------------------------------------| \*-----------------------------------------------------*/ -static void BmvDrawText(bool bDraw) { +void BMVPlayer::BmvDrawText(bool bDraw) { int w, h, x, y; for (int i = 0; i < 2; i++) { @@ -553,7 +498,7 @@ static void BmvDrawText(bool bDraw) { |-------------------------------------------------------| \*-----------------------------------------------------*/ -static void MovieText(CORO_PARAM, int stringId, int x, int y, int fontId, COLORREF *pTalkColour, int duration) { +void BMVPlayer::MovieText(CORO_PARAM, int stringId, int x, int y, int fontId, COLORREF *pTalkColour, int duration) { SCNHANDLE hFont; int index; @@ -589,11 +534,9 @@ static void MovieText(CORO_PARAM, int stringId, int x, int y, int fontId, COLORR /** * Called when a packet contains a command field. */ -static int MovieCommand(char cmd, int commandOffset) { +int BMVPlayer::MovieCommand(char cmd, int commandOffset) { if (cmd & CD_PRINT) { - PPRINT_CMD pCmd; - - pCmd = (PPRINT_CMD)(bigBuffer + commandOffset); + PRINT_CMD *pCmd = (PRINT_CMD *)(bigBuffer + commandOffset); MovieText(nullContext, (int16)READ_LE_UINT16(&pCmd->stringId), (int16)READ_LE_UINT16(&pCmd->x), @@ -605,9 +548,7 @@ static int MovieCommand(char cmd, int commandOffset) { return sz_CMD_PRINT_pkt; } else { if (bSubtitles) { - PTALK_CMD pCmd; - - pCmd = (PTALK_CMD)(bigBuffer + commandOffset); + TALK_CMD *pCmd = (TALK_CMD *)(bigBuffer + commandOffset); talkColour = TINSEL_RGB(pCmd->r, pCmd->g, pCmd->b); MovieText(nullContext, (int16)READ_LE_UINT16(&pCmd->stringId), @@ -626,7 +567,7 @@ static int MovieCommand(char cmd, int commandOffset) { * Kicks off the playback of a movie, and waits around * until it's finished. */ -void PlayBMV(CORO_PARAM, SCNHANDLE hFileStem, int myEscape) { +void BMVPlayer::PlayBMV(CORO_PARAM, SCNHANDLE hFileStem, int myEscape) { CORO_BEGIN_CONTEXT; CORO_END_CONTEXT(_ctx); @@ -655,7 +596,7 @@ void PlayBMV(CORO_PARAM, SCNHANDLE hFileStem, int myEscape) { * next packet. The packet may not yet exist, and the *return value may be off the end of bigBuffer. */ -static int FollowingPacket(int thisPacket, bool bReallyImportant) { +int BMVPlayer::FollowingPacket(int thisPacket, bool bReallyImportant) { unsigned char *data; int nextSlot, length; @@ -699,7 +640,7 @@ static int FollowingPacket(int thisPacket, bool bReallyImportant) { /** * Called from the foreground when starting playback of a movie. */ -static void LoadSlots(int number) { +void BMVPlayer::LoadSlots(int number) { int nextOffset; assert(number + nextReadSlot < NUM_SLOTS); @@ -731,7 +672,7 @@ static void LoadSlots(int number) { /** * Called from the foreground when starting playback of a movie. */ -static void InitialiseBMV(void) { +void BMVPlayer::InitialiseBMV(void) { if (!stream.open(szMovieFile)) error(CANNOT_FIND_FILE, szMovieFile); @@ -767,8 +708,6 @@ static void InitialiseBMV(void) { bIsText = false; -// memset(&rr, 0, sizeof(rr)); - // Prefetch data LoadSlots(PREFETCH); @@ -782,7 +721,7 @@ static void InitialiseBMV(void) { /** * Called from the foreground when ending playback of a movie. */ -void FinishBMV(void) { +void BMVPlayer::FinishBMV(void) { int i; // Notify the sound channel @@ -822,7 +761,7 @@ void FinishBMV(void) { /** * MaintainBuffer() */ -static bool MaintainBuffer(void) { +bool BMVPlayer::MaintainBuffer(void) { int nextOffset; // No action if the file is all read @@ -911,7 +850,7 @@ static bool MaintainBuffer(void) { /** * DoBMVFrame */ -static bool DoBMVFrame(void) { +bool BMVPlayer::DoBMVFrame(void) { unsigned char *data; int graphOffset, length; signed short xscr; @@ -1004,7 +943,7 @@ static bool DoBMVFrame(void) { else xscr = 0; - PrepBMV(bigBuffer + graphOffset, length, xscr); + PrepBMV(ScreenBeg, bigBuffer + graphOffset, length, xscr); currentFrame++; numAdvancePackets--; @@ -1021,7 +960,7 @@ static bool DoBMVFrame(void) { /** * DoSoundFrame */ -static bool DoSoundFrame(void) { +bool BMVPlayer::DoSoundFrame(void) { unsigned char *data; int graphOffset; @@ -1095,7 +1034,7 @@ static bool DoSoundFrame(void) { /** * CopyMovieToScreen */ -void CopyMovieToScreen(void) { +void BMVPlayer::CopyMovieToScreen(void) { // Not if not up and running yet! if (!screenBuffer || (currentFrame == 0)) { ForceEntireRedraw(); @@ -1121,7 +1060,8 @@ void CopyMovieToScreen(void) { /** * LookAtBuffers */ -static void LookAtBuffers(void) { +void BMVPlayer::LookAtBuffers(void) { + // FIXME: What's the point of this function??? static int junk; int i; @@ -1134,8 +1074,7 @@ static void LookAtBuffers(void) { /** * Handles playback of any active movie. Called from the foreground 24 times a second. */ -void FettleBMV(void) { - static int nextMaintain = 0; +void BMVPlayer::FettleBMV(void) { int refFrame; // Tick counter needs to be incrementing at a 24Hz rate @@ -1227,14 +1166,14 @@ void FettleBMV(void) { /** * Returns true if a movie is playing. */ -bool MoviePlaying(void) { +bool BMVPlayer::MoviePlaying(void) { return bMovieOn; } /** * Returns the audio lag in ms */ -int32 MovieAudioLag(void) { +int32 BMVPlayer::MovieAudioLag(void) { if (!bMovieOn || !audioStream) return 0; @@ -1243,11 +1182,11 @@ int32 MovieAudioLag(void) { return (playLength - (((int32) _vm->_mixer->getSoundElapsedTime(audioHandle)) << 10)) >> 10; } -uint32 NextMovieTime(void) { +uint32 BMVPlayer::NextMovieTime(void) { return nextMovieTime; } -void AbortMovie(void) { +void BMVPlayer::AbortMovie(void) { bAbort = true; } diff --git a/engines/tinsel/bmv.h b/engines/tinsel/bmv.h index afb2090bb6..7891075315 100644 --- a/engines/tinsel/bmv.h +++ b/engines/tinsel/bmv.h @@ -27,23 +27,132 @@ #ifndef TINSEL_BMV_H #define TINSEL_BMV_H +#include "common/file.h" + +#include "sound/audiostream.h" +#include "sound/mixer.h" + #include "tinsel/coroutine.h" +#include "tinsel/object.h" +#include "tinsel/palette.h" namespace Tinsel { -void PlayBMV(CORO_PARAM, SCNHANDLE hFileStem, int myEscape); -void FinishBMV(); -void CopyMovieToScreen(void); -void FettleBMV(void); +class BMVPlayer { + + bool bOldAudio; + + /// Set when a movie is on + bool bMovieOn; + + /// Set to kill one off + bool bAbort; + + /// For escaping out of movies + int bmvEscape; + + /// Movie file pointer + Common::File stream; + + /// Movie file name + char szMovieFile[14]; + + /// Pointers to buffers + byte *bigBuffer; + + /// Next data to use to extract a frame + int nextUseOffset; + + /// Next data to use to extract sound data + int nextSoundOffset; + + /// When above offset gets to what this is set at, rewind + int wrapUseOffset; + + /// The offset of the most future packet + int mostFutureOffset; + + /// The current frame + int currentFrame; + int currentSoundFrame; + + /// Number of packets currently in RAM + int numAdvancePackets; + + /// Next slot that will be read from disc + int nextReadSlot; + + /// Set when the whole file has been read + bool bFileEnd; + + /// Palette + COLORREF moviePal[256]; + + int blobsInBuffer; + + struct { + POBJECT pText; + int dieFrame; + } texts[2]; + + COLORREF talkColour; + + int bigProblemCount; + + bool bIsText; + + int movieTick; + int startTick; + uint32 nextMovieTime; + + uint16 Au_Prev1; + uint16 Au_Prev2; + byte *ScreenBeg; + byte *screenBuffer; + + bool audioStarted; + + Audio::AppendableAudioStream *audioStream; + Audio::SoundHandle audioHandle; + + int nextMaintain; +public: + BMVPlayer(); + + void PlayBMV(CORO_PARAM, SCNHANDLE hFileStem, int myEscape); + void FinishBMV(); + void CopyMovieToScreen(void); + void FettleBMV(void); + + bool MoviePlaying(void); -bool MoviePlaying(void); + int32 MovieAudioLag(void); -int32 MovieAudioLag(void); + uint32 NextMovieTime(void); -uint32 NextMovieTime(void); + void AbortMovie(void); -void AbortMovie(void); +private: + void InitBMV(byte *memoryBuffer); + void PrepAudio(const byte *sourceData, int blobCount, byte *destPtr); + void MoviePalette(int paletteOffset); + void InitialiseMovieSound(); + void StartMovieSound(); + void FinishMovieSound(); + void MovieAudio(int audioOffset, int blobs); + void FettleMovieText(void); + void BmvDrawText(bool bDraw); + void MovieText(CORO_PARAM, int stringId, int x, int y, int fontId, COLORREF *pTalkColour, int duration); + int MovieCommand(char cmd, int commandOffset); + int FollowingPacket(int thisPacket, bool bReallyImportant); + void LoadSlots(int number); + void InitialiseBMV(void); + bool MaintainBuffer(void); + bool DoBMVFrame(void); + bool DoSoundFrame(void); + void LookAtBuffers(void); +}; } // End of namespace Tinsel diff --git a/engines/tinsel/detection.cpp b/engines/tinsel/detection.cpp index a337f5e63d..038c0c9625 100644 --- a/engines/tinsel/detection.cpp +++ b/engines/tinsel/detection.cpp @@ -30,6 +30,7 @@ #include "common/md5.h" #include "common/savefile.h" +#include "tinsel/bmv.h" #include "tinsel/cursor.h" #include "tinsel/tinsel.h" #include "tinsel/savescn.h" // needed by TinselMetaEngine::listSaves @@ -633,7 +634,6 @@ bool Tinsel::TinselEngine::hasFeature(EngineFeature f) const { namespace Tinsel { extern int getList(Common::SaveFileManager *saveFileMan, const Common::String &target); -extern bool MoviePlaying(); } SaveStateList TinselMetaEngine::listSaves(const char *target) const { @@ -906,7 +906,7 @@ Common::Error TinselEngine::saveGameState(int slot, const char *desc) { } #endif -bool TinselEngine::canLoadGameStateCurrently() { return !MoviePlaying(); } +bool TinselEngine::canLoadGameStateCurrently() { return !_bmv->MoviePlaying(); } #if 0 bool TinselEngine::canSaveGameStateCurrently() { return isCursorShown(); } diff --git a/engines/tinsel/tinlib.cpp b/engines/tinsel/tinlib.cpp index bd8549329f..0bbe65d8c6 100644 --- a/engines/tinsel/tinlib.cpp +++ b/engines/tinsel/tinlib.cpp @@ -1416,8 +1416,8 @@ void NewScene(CORO_PARAM, SCNHANDLE scene, int entrance, int transition) { CORO_BEGIN_CODE(_ctx); if (TinselV2) { - if (MoviePlaying()) { - AbortMovie(); + if (_vm->_bmv->MoviePlaying()) { + _vm->_bmv->AbortMovie(); CORO_SLEEP(2); } } @@ -1646,11 +1646,11 @@ static void PlayMovie(CORO_PARAM, SCNHANDLE hFileStem, int myEscape) { } // They claim to be getting "Can't play two movies at once!" error - while (MoviePlaying()) + while (_vm->_bmv->MoviePlaying()) CORO_SLEEP(1); // Play the movie - CORO_INVOKE_2(PlayBMV, hFileStem, myEscape); + CORO_INVOKE_2(_vm->_bmv->PlayBMV, hFileStem, myEscape); CORO_END_CODE; } @@ -2427,8 +2427,8 @@ static void RestoreScene(CORO_PARAM, TRANSITS transition) { CORO_BEGIN_CODE(_ctx); if (TinselV2) { - if (MoviePlaying()) { - AbortMovie(); + if (_vm->_bmv->MoviePlaying()) { + _vm->_bmv->AbortMovie(); CORO_SLEEP(2); } diff --git a/engines/tinsel/tinsel.cpp b/engines/tinsel/tinsel.cpp index 7fdae39495..6a557f5d3d 100644 --- a/engines/tinsel/tinsel.cpp +++ b/engines/tinsel/tinsel.cpp @@ -871,6 +871,8 @@ TinselEngine::TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc) _sound = new SoundManager(this); + _bmv = new BMVPlayer(); + _mousePos.x = 0; _mousePos.y = 0; _keyHandler = NULL; @@ -878,10 +880,11 @@ TinselEngine::TinselEngine(OSystem *syst, const TinselGameDescription *gameDesc) } TinselEngine::~TinselEngine() { - if (MoviePlaying()) - FinishBMV(); + if (_bmv->MoviePlaying()) + _bmv->FinishBMV(); AudioCD.stop(); + delete _bmv; delete _sound; delete _midiMusic; delete _pcmMusic; @@ -1012,7 +1015,7 @@ Common::Error TinselEngine::run() { ProcessSRQueue(); // Handle any playing movie - FettleBMV(); + _bmv->FettleBMV(); #ifdef DEBUG if (bFast) @@ -1024,8 +1027,8 @@ Common::Error TinselEngine::run() { DoCdChange(); - if (MoviePlaying() && NextMovieTime()) - g_system->delayMillis(MAX(NextMovieTime() - g_system->getMillis() + MovieAudioLag(), 0)); + if (_bmv->MoviePlaying() && _bmv->NextMovieTime()) + g_system->delayMillis(MAX(_bmv->NextMovieTime() - g_system->getMillis() + _bmv->MovieAudioLag(), 0)); else g_system->delayMillis(10); } @@ -1050,8 +1053,8 @@ void TinselEngine::NextGameCycle(void) { // schedule process _scheduler->schedule(); - if (MoviePlaying()) - CopyMovieToScreen(); + if (_bmv->MoviePlaying()) + _bmv->CopyMovieToScreen(); else // redraw background DrawBackgnd(); diff --git a/engines/tinsel/tinsel.h b/engines/tinsel/tinsel.h index b9558764af..e55f7b8f18 100644 --- a/engines/tinsel/tinsel.h +++ b/engines/tinsel/tinsel.h @@ -44,6 +44,7 @@ namespace Tinsel { +class BMVPlayer; class MidiMusicPlayer; class PCMMusicPlayer; class Scheduler; @@ -179,6 +180,7 @@ public: SoundManager *_sound; MidiMusicPlayer *_midiMusic; PCMMusicPlayer *_pcmMusic; + BMVPlayer *_bmv; KEYFPTR _keyHandler; private: -- cgit v1.2.3