[Scummvm-git-logs] scummvm master -> 943f6c756874936bd715220745421e54d1101a96
aquadran
aquadran at gmail.com
Sun Feb 28 12:38:02 UTC 2021
This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
943f6c7568 ICB: Completed movie implementation
Commit: 943f6c756874936bd715220745421e54d1101a96
https://github.com/scummvm/scummvm/commit/943f6c756874936bd715220745421e54d1101a96
Author: PaweÅ KoÅodziejski (aquadran at gmail.com)
Date: 2021-02-28T13:37:55+01:00
Commit Message:
ICB: Completed movie implementation
Changed paths:
engines/icb/fn_movie_pc.cpp
engines/icb/movie_pc.cpp
engines/icb/movie_pc.h
diff --git a/engines/icb/fn_movie_pc.cpp b/engines/icb/fn_movie_pc.cpp
index 7219c33100..451de7cba8 100644
--- a/engines/icb/fn_movie_pc.cpp
+++ b/engines/icb/fn_movie_pc.cpp
@@ -72,7 +72,6 @@ mcodeFunctionReturnCodes _game_session::fn_play_movie(int32 &, int32 *params) {
void Init_play_movie(const char *param0, bool8 param1) {
// Stop all sounds occuring
PauseSounds();
- g_TimerOn = FALSE8;
const char *moviename = (const char *)param0;
diff --git a/engines/icb/movie_pc.cpp b/engines/icb/movie_pc.cpp
index 3d68c43bee..497a2811fa 100644
--- a/engines/icb/movie_pc.cpp
+++ b/engines/icb/movie_pc.cpp
@@ -40,235 +40,194 @@ namespace ICB {
// Instance our global bink handler for movies
MovieManager *g_theSequenceManager;
-SequenceManager::SequenceManager() {
- m_binkObject = NULL;
- m_x = 0;
- m_y = 0;
- m_fadeCounter = 255;
- m_fadeRate = 4;
- m_haveFaded = FALSE8;
- m_rater = TRUE8;
- m_haveClearedScreen = FALSE8;
- m_mission1intro = FALSE8;
- // Zero these, as the global construction handled it earlier:
- m_loop = FALSE8;
- m_endAtFrame = FALSE8;
+MovieManager::MovieManager() {
+ _binkDecoder = nullptr;
+ _x = 0;
+ _y = 0;
+ _fadeCounter = 255;
+ _fadeRate = 4;
+ _haveFaded = false;
+ _rater = true;
+ _haveClearedScreen = false;
+ _loop = FALSE8;
}
-SequenceManager::~SequenceManager() {}
+MovieManager::~MovieManager() {
+ kill();
+}
-bool8 SequenceManager::Register(const char *fileName, bool8 fade, bool8 loop, uint32 flags) {
+bool MovieManager::registerMovie(const char *fileName, bool8 fade, bool8 loop) {
// Release any currently held sequence
- Kill();
+ kill();
+ _x = 0;
+ _y = 0;
if (g_theMusicManager)
g_theMusicManager->StopMusic();
- // Special case hack
- if (strstr(fileName, "m01intro") != NULL)
- m_mission1intro = TRUE8;
- else
- m_mission1intro = FALSE8;
+ _binkDecoder = new Video::BinkDecoder();
+ _binkDecoder->setDefaultHighColorFormat(Graphics::PixelFormat(4, 8, 8, 8, 0, 16, 8, 0, 24));
- // No hack for russian or polish thanks
- if (g_theClusterManager->GetLanguage() == T_RUSSIAN || g_theClusterManager->GetLanguage() == T_POLISH)
- m_mission1intro = FALSE8;
-
- // Let bink make it's own direct sound interface
- BinkSoundUseDirectSound(0);
-
- // Open the Bink file
- m_binkObject = BinkOpen(fileName, flags);
- if (!m_binkObject) {
- Fatal_error("[FILE %s]: BINK error: %s", fileName, BinkGetError());
- return FALSE8;
+ Common::SeekableReadStream *stream = openDiskFileForBinaryStreamRead(fileName);
+ if (!stream) {
+ return false;
}
-
- // Mute the sound if necessary
- if (m_rater)
- SetVolume(GetMusicVolume());
- else
- SetVolume(0);
-
- // Now we need to centre the movie in the screen so calculate the correct coordinates
- uint32 movieWidth = m_binkObject->Width;
- uint32 movieHeight = m_binkObject->Height;
-
- if (movieWidth != SCREEN_WIDTH) {
- m_x = (SCREEN_WIDTH / 2) - (movieWidth / 2);
+ if (!_binkDecoder->loadStream(stream)) {
+ return false;
}
- if (movieHeight != SCREEN_DEPTH) {
- m_y = (SCREEN_DEPTH / 2) - (movieHeight / 2);
+ if (_binkDecoder->getWidth() != SCREEN_WIDTH) {
+ _x = (SCREEN_WIDTH / 2) - (_binkDecoder->getWidth() / 2);
+ }
+ if (_binkDecoder->getHeight() != SCREEN_DEPTH) {
+ _y = (SCREEN_DEPTH / 2) - (_binkDecoder->getHeight() / 2);
}
-
- m_flags = BINKSURFACE32;
// Should we fade the screen out before playing the movie
if (fade) {
- m_fadeCounter = 1; // Yes we should
+ _fadeCounter = 1; // Yes we should
} else {
- m_fadeCounter = 255; // No thanks
+ _fadeCounter = 255; // No thanks
}
- m_haveFaded = FALSE8;
- m_loop = loop;
- m_endAtFrame = 0;
+ _haveFaded = false;
+ _loop = loop;
- return TRUE8;
-}
-
-bool8 SequenceManager::Busy() {
- if (!m_binkObject)
- return FALSE8;
-
- return TRUE8;
+ return true;
}
-uint32 SequenceManager::GetMovieHeight() {
- if (Busy())
- return m_binkObject->Height;
-
- return 0;
+uint32 MovieManager::getMovieHeight() {
+ if (!busy())
+ return 0;
+ return _binkDecoder->getHeight();
}
-uint32 SequenceManager::GetMovieWidth() {
- if (Busy())
- return m_binkObject->Width;
-
- return 0;
-}
+uint32 MovieManager::getMovieWidth() {
+ if (!busy())
+ return 0;
+ return _binkDecoder->getWidth();
+};
-uint32 SequenceManager::GetMovieFrames() {
- if (Busy())
- return m_binkObject->Frames;
+uint32 MovieManager::getMovieFrames() {
+ if (!busy())
+ return 0;
+ return _binkDecoder->getFrameCount();
+};
- return 0;
+bool MovieManager::busy() {
+ return _binkDecoder != nullptr;
}
-int SequenceManager::GetFrameNumber() {
- if (Busy())
- return m_binkObject->FrameNum;
+int MovieManager::getFrameNumber() {
+ if (busy())
+ return _binkDecoder->getCurFrame() + 1;
return 0;
}
-uint32 SequenceManager::DrawFrame(uint32 surface_id) {
- if (!m_binkObject)
- return NOMOVIE;
-
- // Get the current time count
- uint32 timeStart = g_system->getMillis();
+uint32 MovieManager::drawFrame(uint32 surface_id) {
+ if (!_binkDecoder) {
+ return FINISHED;
+ }
// Non-looping movies can be quit using the escape key
- if (Read_DI_once_keys(Common::KEYCODE_ESCAPE) && !m_loop) {
- // Release Bink object and file
- Kill();
+ if (Read_DI_once_keys(Common::KEYCODE_ESCAPE) && !_loop) {
+ kill();
return FINISHED;
}
// Don't do bink, fade the screen
- if (m_fadeCounter < (255 / m_fadeRate)) {
- FadeScreen(surface_id);
- m_haveFaded = TRUE8;
+ if (_fadeCounter < (255 / _fadeRate)) {
+ fadeScreen(surface_id);
+ _haveFaded = true;
return FADING;
}
// Have we performed a fade
- if (m_haveFaded) {
+ if (_haveFaded) {
// Reassign correct surface id
surface_id = working_buffer_id;
- m_haveFaded = FALSE8;
+ _haveFaded = false;
+ if (getFrameNumber() == 0)
+ _binkDecoder->start();
} else {
// Black out the screen before we play the movie
- if ((m_binkObject->FrameNum == 1) && !m_haveClearedScreen) {
+ if ((getFrameNumber() == 0) && !_haveClearedScreen) {
surface_manager->Clear_surface(working_buffer_id);
- m_haveClearedScreen = TRUE8;
+ _haveClearedScreen = true;
+ _binkDecoder->start();
}
}
- if (m_rater) {
- // Don't do anything (skipping frames for audio sync and that I think)
- if (BinkWait(m_binkObject)) {
- BinkService(m_binkObject);
-
- // Mission 1 intro is special case (25fps rather than 12fps)
- if (m_mission1intro) {
- while (g_system->getMillis() - timeStart < 25)
- ;
- } else
- return WAITING;
+ // Decompress a frame
+ const Graphics::Surface *surface = _binkDecoder->decodeNextFrame();
+ if (!surface || _binkDecoder->endOfVideo()) {
+ if (_loop) {
+ _binkDecoder->rewind();
+ surface = _binkDecoder->decodeNextFrame();
+ } else {
+ kill();
+ surface_manager->Clear_surface(working_buffer_id);
+
+ return FINISHED;
}
}
- // Decompress a frame
- BinkDoFrame(m_binkObject);
+ if (_rater) {
+ uint32 waitTime = _binkDecoder->getTimeToNextFrame();
+ g_system->delayMillis(waitTime);
+ }
// For access to buffer
- uint32 pitch;
+ uint16 pitch;
uint8 *surface_address;
- // Lock the directdraw surface
+ // Lock the surface
surface_address = surface_manager->Lock_surface(surface_id);
pitch = surface_manager->Get_pitch(surface_id);
+ uint32 height = surface_manager->Get_height(surface_id);
- // Copy the data onto the screen
- BinkCopyToBuffer(m_binkObject, surface_address, pitch, surface_manager->Get_height(surface_id), m_x, m_y, m_flags);
+ for (int i = 0; i < surface->h; i++) {
+ if (i + _y >= height) {
+ break;
+ }
+ memcpy(surface_address + (i + _y) * pitch, surface->getBasePtr(0, i), MIN(surface->pitch, pitch));
+ }
// Unlock the buffer
surface_manager->Unlock_surface(surface_id);
-
- // Advance to next frame or signal end of sequence
- if (m_binkObject->FrameNum == m_binkObject->Frames || (m_endAtFrame != 0 && m_endAtFrame == m_binkObject->FrameNum)) {
- if (m_loop) {
- BinkGoto(m_binkObject, 1, 0);
- } else {
- // Release Bink object and file
- Kill();
- surface_manager->Clear_surface(working_buffer_id);
-
- return FINISHED;
- }
- } else
- BinkNextFrame(m_binkObject);
-
- // An extra precaution preventing sound break-up
- BinkService(m_binkObject);
-
- // No problemo
return JUSTFINE;
}
-void SequenceManager::SetRate() {
+void MovieManager::setRate() {
// Toggle
- if (m_rater)
- m_rater = FALSE8;
+ if (_rater)
+ _rater = false;
else
- m_rater = TRUE8;
+ _rater = true;
- if (m_binkObject) {
+ if (_binkDecoder) {
// Mute the sound if necessary
- if (m_rater)
- SetVolume(GetMusicVolume());
+ if (_rater)
+ setVolume(GetMusicVolume());
else
- SetVolume(0);
+ setVolume(0);
}
}
-void SequenceManager::FadeScreen(uint32 surface_id) {
+void MovieManager::fadeScreen(uint32 surface_id) {
// Pointer to subtractive table block
uint8 subtractive[8];
// Fade by table
- subtractive[4] = subtractive[0] = (uint8)m_fadeRate;
- subtractive[5] = subtractive[1] = (uint8)m_fadeRate;
- subtractive[6] = subtractive[2] = (uint8)m_fadeRate;
+ subtractive[4] = subtractive[0] = (uint8)_fadeRate;
+ subtractive[5] = subtractive[1] = (uint8)_fadeRate;
+ subtractive[6] = subtractive[2] = (uint8)_fadeRate;
subtractive[7] = subtractive[3] = 0;
// Lock the directdraw surface
uint8 *surface_address = surface_manager->Lock_surface(surface_id);
uint32 pitch = surface_manager->Get_pitch(surface_id);
-#if 1
for (uint32 lines = 0; lines < SCREEN_DEPTH; lines++) {
for (int xPos = 0; xPos < SCREEN_WIDTH; xPos++) {
// 32-bit BGRA pixel
@@ -281,149 +240,35 @@ void SequenceManager::FadeScreen(uint32 surface_id) {
// Next line
surface_address += pitch;
}
-#else
- // Safe surface pointer
- uint32 *safe_ad = (uint32 *)surface_address;
- int pixelPairs = SCREEN_WIDTH / 2;
- for (uint32 lines = 0; lines < SCREEN_DEPTH; lines++) {
- _asm {
- lea edi, subtractive ; // Load the address of the blend colour block
- mov ecx, pixelPairs ; // Pixel Counter (2 pixels at a time mind)
- mov esi, safe_ad ; // Load the address of the pixels
- movq MM0, [edi] ; // Put address of the blend colour block into MMX register
-
- subtractive_fade_loop:
-
- movq MM1, [esi] ; // Load 2 pixels
- psubusb MM1, MM0 ; // Do the subtract
- movq [esi], MM1 ; // Store the result
- add esi, 8 ; // Move pixel pointer on
- dec ecx ; // Reduce counter
- jne subtractive_fade_loop ; // On to the next 2 pixels
-
- EMMS ; // Clear/Set MMX/FPU flag
- }
-
- safe_ad += (pitch / 4);
- }
-#endif
// Unlock the buffer
surface_manager->Unlock_surface(surface_id);
// Increment fade level (pixel shift right)
- m_fadeCounter++;
+ _fadeCounter++;
}
-void SequenceManager::SetVolume(int32 vol) {
- if (!m_binkObject)
- return;
-
- int bink_vol = vol * 256;
-
- if (bink_vol < 0)
- bink_vol = 0;
- if (bink_vol > 32768)
- bink_vol = 32768;
-
- BinkSetVolume(m_binkObject, bink_vol);
+void MovieManager::setVolume(int32 vol) {
+ if (_binkDecoder) {
+ float volumeConversion = Audio::Mixer::kMaxChannelVolume / 128.0f;
+ _binkDecoder->setVolume(volumeConversion * vol);
+ }
}
-void SequenceManager::Kill() {
- if (m_binkObject) {
- BinkClose(m_binkObject);
- m_binkObject = NULL;
+void MovieManager::kill() {
+ if (_binkDecoder) {
+ _binkDecoder->close();
+ delete _binkDecoder;
+ _binkDecoder = nullptr;
}
// Reset blitting coordinates
- m_x = 0;
- m_y = 0;
-
- m_fadeCounter = 255;
-
- m_haveClearedScreen = FALSE8;
-}
-
-bool MovieManager::registerMovie(const char *fileName, bool8 fade, bool8 loop) {
- // Release any currently held sequence
- kill();
_x = 0;
_y = 0;
- if (g_theMusicManager)
- g_theMusicManager->StopMusic();
- /*
- // Special case hack
- if (strstr(fileName, "m01intro") != NULL)
- m_mission1intro = TRUE8;
- else
- m_mission1intro = FALSE8;
-
- // No hack for russian or polish thanks
- if (g_theClusterManager->GetLanguage() == T_RUSSIAN || g_theClusterManager->GetLanguage() == T_POLISH)
- m_mission1intro = FALSE8;
- */
+ _fadeCounter = 255;
- Common::SeekableReadStream *stream = openDiskFileForBinaryStreamRead(fileName);
- if (!stream) {
- return false;
- }
- if (!_binkDecoder->loadStream(stream)) {
- return false;
- }
- if (_binkDecoder->getWidth() != SCREEN_WIDTH) {
- _x = (SCREEN_WIDTH / 2) - (_binkDecoder->getWidth() / 2);
- }
- if (_binkDecoder->getHeight() != SCREEN_DEPTH) {
- _y = (SCREEN_DEPTH / 2) - (_binkDecoder->getHeight() / 2);
- }
- _binkDecoder->start();
- return true;
-}
-
-uint32 MovieManager::drawFrame(uint32 surface_id) {
- if (!_binkDecoder->isPlaying()) {
- return FINISHED;
- }
- // Non-looping movies can be quit using the escape key
- if (Read_DI_once_keys(Common::KEYCODE_ESCAPE) /* && !m_loop*/) {
- kill();
- return FINISHED;
- }
- // TODO: The rest.
- const Graphics::Surface *surface = _binkDecoder->decodeNextFrame();
- if (!surface) {
- kill();
- return FINISHED;
- }
- // For access to buffer
- uint16 pitch;
- uint8 *surface_address;
-
- // Lock the directdraw surface
- surface_address = surface_manager->Lock_surface(surface_id);
- pitch = surface_manager->Get_pitch(surface_id);
- uint32 height = surface_manager->Get_height(surface_id);
-
- for (int i = 0; i < _y; i++) {
- memset(surface_address + i * pitch, 0, MIN(surface->pitch, pitch));
- }
-
- for (int i = 0; i < surface->h; i++) {
- if (i + _y >= height) {
- warning("Movie out of bounds");
- break;
- }
- memcpy(surface_address + (i + _y) * pitch, surface->getBasePtr(0, i), MIN(surface->pitch, pitch));
- }
-
- for (int i = _y + surface->h; i < height; i++) {
- memset(surface_address + i * pitch, 0, MIN(surface->pitch, pitch));
- }
-
- // Unlock the buffer
- surface_manager->Unlock_surface(surface_id);
- return JUSTFINE;
+ _haveClearedScreen = false;
}
} // End of namespace ICB
diff --git a/engines/icb/movie_pc.h b/engines/icb/movie_pc.h
index bdc0772910..a9caa6c6a7 100644
--- a/engines/icb/movie_pc.h
+++ b/engines/icb/movie_pc.h
@@ -49,96 +49,42 @@ class MovieManager;
extern MovieManager *g_theSequenceManager;
-class SequenceManager {
-private:
- HBINK m_binkObject;
-
- uint32 m_x; // X offset in screen
- uint32 m_y; // Y offset in screen
- uint32 m_flags; // Surface type
- uint32 m_fadeCounter;
- uint32 m_fadeRate;
-
- bool8 m_loop;
- bool8 m_haveFaded;
- bool8 m_haveClearedScreen;
- bool8 m_rater;
- bool8 m_mission1intro;
-
- uint32 m_endAtFrame;
-
-public:
- SequenceManager();
- ~SequenceManager();
-
- bool8 Register(const char *fileName, bool8 fade, bool8 loop, uint32 flags = 0);
-
- uint32 GetMovieHeight();
- uint32 GetMovieWidth();
- uint32 GetMovieFrames();
-
- bool8 Busy();
-
- uint32 DrawFrame(uint32 surface_id = working_buffer_id);
- int GetFrameNumber();
-
- void SetRate();
- void SetEndFrame(uint32 f) { m_endAtFrame = f; }
-
- void SetVolume(int32 vol);
-
- void Kill();
-
-private:
- void FadeScreen(uint32 surface_id);
-};
-
class MovieManager {
Video::BinkDecoder *_binkDecoder;
int _x;
int _y;
+ uint32 _fadeCounter;
+ uint32 _fadeRate;
+
+ bool8 _loop;
+ bool _haveFaded;
+ bool _haveClearedScreen;
+ bool _rater;
+
public:
- MovieManager() : _x(0), _y(0) {
- _binkDecoder = new Video::BinkDecoder();
- _binkDecoder->setDefaultHighColorFormat(Graphics::PixelFormat(4, 8, 8, 8, 0, 16, 8, 0, 24));
- };
- ~MovieManager() { delete _binkDecoder; };
+ MovieManager();
+ ~MovieManager();
bool registerMovie(const char *fileName, bool8 fade, bool8 loop);
- uint32 getMovieHeight() {
- if (!busy())
- return 0;
- return _binkDecoder->getHeight();
- };
- uint32 getMovieWidth() {
- if (!busy())
- return 0;
- return _binkDecoder->getWidth();
- };
- uint32 getMovieFrames() {
- if (!busy())
- return 0;
- return _binkDecoder->getFrameCount();
- };
-
- bool busy() { return _binkDecoder->isPlaying(); }
+
+ uint32 getMovieHeight();
+ uint32 getMovieWidth();
+ uint32 getMovieFrames();
+
+ bool busy();
uint32 drawFrame(uint32 surface_id = working_buffer_id);
- int getFrameNumber() {
- if (!busy())
- return 0;
- return _binkDecoder->getCurFrame();
- };
+ int getFrameNumber();
+
+ void setRate();
- void setRate() { warning("TODO: setRate"); }
- void setEndFrame(uint32 f) { warning("TODO: setEndFrame"); }
- void setVolume(int32 vol) { warning("TODO: setVolume"); }
+ void setVolume(int32 vol);
- void kill() { _binkDecoder->close(); }
+ void kill();
private:
- void fadeScreen(uint32 surface_id) {}
+ void fadeScreen(uint32 surface_id);
};
} // End of namespace ICB
More information about the Scummvm-git-logs
mailing list