[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