[Scummvm-cvs-logs] SF.net SVN: scummvm:[45455] scummvm/trunk/engines/draci

spalek at users.sourceforge.net spalek at users.sourceforge.net
Wed Oct 28 08:34:17 CET 2009


Revision: 45455
          http://scummvm.svn.sourceforge.net/scummvm/?rev=45455&view=rev
Author:   spalek
Date:     2009-10-28 07:34:17 +0000 (Wed, 28 Oct 2009)

Log Message:
-----------
Implement palette fading

Modified Paths:
--------------
    scummvm/trunk/engines/draci/draci.cpp
    scummvm/trunk/engines/draci/game.cpp
    scummvm/trunk/engines/draci/game.h
    scummvm/trunk/engines/draci/screen.cpp
    scummvm/trunk/engines/draci/screen.h
    scummvm/trunk/engines/draci/script.cpp
    scummvm/trunk/engines/draci/script.h

Modified: scummvm/trunk/engines/draci/draci.cpp
===================================================================
--- scummvm/trunk/engines/draci/draci.cpp	2009-10-28 04:57:54 UTC (rev 45454)
+++ scummvm/trunk/engines/draci/draci.cpp	2009-10-28 07:34:17 UTC (rev 45455)
@@ -365,7 +365,7 @@
 		// Adjust engine start time
 		const int delta = _system->getMillis() - _pauseStartTime;
 		_engineStartTime += delta / 1000;
-		_game->shiftSpeechTick(delta);
+		_game->shiftSpeechAndFadeTick(delta);
 		_pauseStartTime = 0;
 	}
 }

Modified: scummvm/trunk/engines/draci/game.cpp
===================================================================
--- scummvm/trunk/engines/draci/game.cpp	2009-10-28 04:57:54 UTC (rev 45454)
+++ scummvm/trunk/engines/draci/game.cpp	2009-10-28 07:34:17 UTC (rev 45455)
@@ -165,6 +165,7 @@
 	setQuit(false);
 	setExitLoop(false);
 	_scheduledPalette = 0;
+	_fadePhases = _fadePhase = 0;
 	setLoopStatus(kStatusGate);
 	setLoopSubstatus(kSubstatusOrdinary);
 
@@ -239,6 +240,22 @@
 		if (shouldExitLoop() > 1)	// after loading
 			break;
 
+		if (_fadePhase > 0 && (_vm->_system->getMillis() - _fadeTick) >= kFadingTimeUnit) {
+			_fadeTick = _vm->_system->getMillis();
+			--_fadePhase;
+			const BAFile *startPal = _vm->_paletteArchive->getFile(_currentRoom._palette);
+			const BAFile *endPal = getScheduledPalette() >= 0 ? _vm->_paletteArchive->getFile(getScheduledPalette()) : NULL;
+			_vm->_screen->interpolatePalettes(startPal->_data, endPal->_data, 0, kNumColours, _fadePhases - _fadePhase, _fadePhases);
+			if (_loopSubstatus == kSubstatusFade && _fadePhase == 0) {
+				setExitLoop(true);
+				// Rewrite the palette index of the current
+				// room.  This is necessary when two fadings
+				// are called after each other, such as in the
+				// intro.  We rely on that getScheduledPalette() >= 0.
+				_currentRoom._palette = getScheduledPalette();
+			}
+		}
+
 		// Fetch mouse coordinates
 		int x = _vm->_mouse->getPosX();
 		int y = _vm->_mouse->getPosY();
@@ -1530,8 +1547,9 @@
 	_speechDuration = duration;
 }
 
-void Game::shiftSpeechTick(int delta) {
+void Game::shiftSpeechAndFadeTick(int delta) {
 	_speechTick += delta;
+	_fadeTick += delta;
 }
 
 int Game::getEscRoom() const {
@@ -1550,6 +1568,11 @@
 	return _scheduledPalette;
 }
 
+void Game::initializeFading(int phases) {
+	_fadePhases = _fadePhase = phases;
+	_fadeTick = _vm->_system->getMillis();
+}
+
 /**
  * The GPL command Mark sets the animation index (which specifies the order in which
  * animations were loaded in) which is then used by the Release command to delete

Modified: scummvm/trunk/engines/draci/game.h
===================================================================
--- scummvm/trunk/engines/draci/game.h	2009-10-28 04:57:54 UTC (rev 45454)
+++ scummvm/trunk/engines/draci/game.h	2009-10-28 07:34:17 UTC (rev 45455)
@@ -87,6 +87,11 @@
 	kSpeechTimeUnit = 2640
 };
 
+// One fading phase is 50ms.
+enum FadeConstants {
+	kFadingTimeUnit = 50
+};
+
 /** Inventory related magical constants */
 enum InventoryConstants {
   kInventoryItemWidth = 25,
@@ -330,7 +335,7 @@
 	void setExitLoop(int exit) { _shouldExitLoop = exit; }
 
 	void setSpeechTiming(uint tick, uint duration);
-	void shiftSpeechTick(int delta);
+	void shiftSpeechAndFadeTick(int delta);
 
 	void updateTitle();
 	void updateCursor();
@@ -360,6 +365,7 @@
 
 	void schedulePalette(int paletteID);
 	int getScheduledPalette() const;
+	void initializeFading(int phases);
 
 	void DoSync(Common::Serializer &s);
 
@@ -423,6 +429,9 @@
 	int _markedAnimationIndex; ///< Used by the Mark GPL command
 
 	int _scheduledPalette;
+	int _fadePhases;
+	int _fadePhase;
+	uint _fadeTick;
 };
 
 } // End of namespace Draci

Modified: scummvm/trunk/engines/draci/screen.cpp
===================================================================
--- scummvm/trunk/engines/draci/screen.cpp	2009-10-28 04:57:54 UTC (rev 45454)
+++ scummvm/trunk/engines/draci/screen.cpp	2009-10-28 07:34:17 UTC (rev 45455)
@@ -33,35 +33,28 @@
 Screen::Screen(DraciEngine *vm) : _vm(vm) {
 	_surface = new Surface(kScreenWidth, kScreenHeight);
 	_palette = new byte[4 * kNumColours];
-	setPaletteEmpty();
+	_blackPalette = new byte[3 * kNumColours];
+	for (int i = 0; i < 3 * kNumColours; ++i) {
+		_blackPalette[i] = 0;
+	}
+	setPalette(NULL, 0, kNumColours);
 	this->clearScreen();
 }
 
 Screen::~Screen() {
 	delete _surface;
 	delete[] _palette;
+	delete[] _blackPalette;
 }
 
 /**
- * @brief Sets the first numEntries of palette to zero
- * @param numEntries The number of entries to set to zero (from start)
- */
-void Screen::setPaletteEmpty(uint numEntries) {
-	for (uint i = 0; i < 4 * numEntries; ++i) {
-		_palette[i] = 0;
-	}
-
-	_vm->_system->setPalette(_palette, 0, numEntries);
-}
-
-/**
  * @brief Sets a part of the palette
  * @param data Pointer to a buffer containing new palette data
  *        start Index of the colour where replacement should start
  *        num Number of colours to replace
  */
 void Screen::setPalette(const byte *data, uint16 start, uint16 num) {
-	Common::MemoryReadStream pal(data, 3 * kNumColours);
+	Common::MemoryReadStream pal(data ? data : _blackPalette, 3 * kNumColours);
 	pal.seek(start * 4);
 
 	// Copy the palette
@@ -74,13 +67,40 @@
 
 	// TODO: Investigate why this is needed
 	// Shift the palette two bits to the left to make it brighter
-	for (uint i = 0; i < 4 * kNumColours; ++i) {
+	for (int i = start * 4; i < (start + num) * 4; ++i) {
 		_palette[i] <<= 2;
 	}
 
 	_vm->_system->setPalette(_palette, start, num);
 }
 
+void Screen::interpolatePalettes(const byte *first, const byte *second, uint16 start, uint16 num, int index, int number) {
+	Common::MemoryReadStream firstPal(first ? first : _blackPalette, 3 * kNumColours);
+	Common::MemoryReadStream secondPal(second ? second : _blackPalette, 3 * kNumColours);
+	firstPal.seek(start * 4);
+	secondPal.seek(start * 4);
+
+	// Interpolate the palettes
+	for (uint16 i = start; i < start + num; ++i) {
+		_palette[i * 4] = interpolate(firstPal.readByte(), secondPal.readByte(), index, number);
+		_palette[i * 4 + 1] = interpolate(firstPal.readByte(), secondPal.readByte(), index, number);
+		_palette[i * 4 + 2] = interpolate(firstPal.readByte(), secondPal.readByte(), index, number);
+		_palette[i * 4 + 3] = 0;
+	}
+
+	// TODO: Investigate why this is needed
+	// Shift the palette two bits to the left to make it brighter
+	for (int i = start * 4; i < (start + num) * 4; ++i) {
+		_palette[i] <<= 2;
+	}
+
+	_vm->_system->setPalette(_palette, start, num);
+}
+
+int Screen::interpolate(int first, int second, int index, int number) {
+	return (second * index + first * (number - index)) / number;
+}
+
 /**
  * @brief Copies the current memory screen buffer to the real screen
  */

Modified: scummvm/trunk/engines/draci/screen.h
===================================================================
--- scummvm/trunk/engines/draci/screen.h	2009-10-28 04:57:54 UTC (rev 45454)
+++ scummvm/trunk/engines/draci/screen.h	2009-10-28 07:34:17 UTC (rev 45455)
@@ -46,8 +46,8 @@
 	Screen(DraciEngine *vm);
 	~Screen();
 
-	void setPaletteEmpty(uint numEntries = kNumColours);
 	void setPalette(const byte *data, uint16 start, uint16 num);
+	void interpolatePalettes(const byte *first, const byte *second, uint16 start, uint16 num, int index, int number);
 	const byte *getPalette() const;
 	void copyToScreen();
 	void clearScreen();
@@ -56,8 +56,11 @@
 	void drawRect(Common::Rect r, uint8 colour);
 
 private:
+	int interpolate(int first, int second, int index, int number);
+
 	Surface *_surface;
 	byte *_palette;
+	byte *_blackPalette;
 	DraciEngine *_vm;
 };
 

Modified: scummvm/trunk/engines/draci/script.cpp
===================================================================
--- scummvm/trunk/engines/draci/script.cpp	2009-10-28 04:57:54 UTC (rev 45454)
+++ scummvm/trunk/engines/draci/script.cpp	2009-10-28 07:34:17 UTC (rev 45455)
@@ -64,8 +64,8 @@
 		{ 11, 1, "LoadPalette", 		1, { 2 }, &Script::loadPalette },
 		{ 12, 1, "SetPalette", 			0, { 0 }, &Script::setPalette },
 		{ 12, 2, "BlackPalette", 		0, { 0 }, &Script::blackPalette },
-		{ 13, 1, "FadePalette", 		3, { 1, 1, 1 }, NULL },
-		{ 13, 2, "FadePalettePlay", 	3, { 1, 1, 1 }, NULL },
+		{ 13, 1, "FadePalette", 		3, { 1, 1, 1 }, &Script::fadePalette },
+		{ 13, 2, "FadePalettePlay", 	3, { 1, 1, 1 }, &Script::fadePalettePlay },
 		{ 14, 1, "NewRoom", 			2, { 3, 1 }, &Script::newRoom },
 		{ 15, 1, "ExecInit", 			1, { 3 }, &Script::execInit },
 		{ 15, 2, "ExecLook", 			1, { 3 }, &Script::execLook },
@@ -840,14 +840,36 @@
 	_vm->_game->schedulePalette(kBlackPalette);
 }
 
+void Script::fadePalette(Common::Queue<int> &params) {
+	params.pop();	// unused first and last
+	params.pop();
+	int phases = params.pop();
+	_vm->_game->initializeFading(phases);
+}
+
+void Script::fadePalettePlay(Common::Queue<int> &params) {
+	params.pop();	// unused first and last
+	params.pop();
+	int phases = params.pop();
+	_vm->_game->initializeFading(phases);
+
+	_vm->_game->setLoopSubstatus(kSubstatusFade);
+	_vm->_game->loop();
+	_vm->_game->setExitLoop(false);
+	_vm->_game->setLoopSubstatus(kSubstatusOrdinary);
+}
+
 void Script::setPalette(Common::Queue<int> &params) {
 	if (_vm->_game->getScheduledPalette() == -1) {
-		_vm->_screen->setPaletteEmpty();
+		_vm->_screen->setPalette(NULL, 0, kNumColours);
 	} else {
 		const BAFile *f;
 		f = _vm->_paletteArchive->getFile(_vm->_game->getScheduledPalette());
 		_vm->_screen->setPalette(f->_data, 0, kNumColours);
 	}
+	// Immediately update the palette
+	_vm->_screen->copyToScreen();
+	_vm->_system->delayMillis(100);
 }
 
 void Script::quitGame(Common::Queue<int> &params) {

Modified: scummvm/trunk/engines/draci/script.h
===================================================================
--- scummvm/trunk/engines/draci/script.h	2009-10-28 04:57:54 UTC (rev 45454)
+++ scummvm/trunk/engines/draci/script.h	2009-10-28 07:34:17 UTC (rev 45455)
@@ -138,6 +138,8 @@
 	void resetBlock(Common::Queue<int> &params);
 	void setPalette(Common::Queue<int> &params);
 	void blackPalette(Common::Queue<int> &params);
+	void fadePalette(Common::Queue<int> &params);
+	void fadePalettePlay(Common::Queue<int> &params);
 	void loadPalette(Common::Queue<int> &params);
 	void quitGame(Common::Queue<int> &params);
 	void pushNewRoom(Common::Queue<int> &params);


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list