[Scummvm-cvs-logs] scummvm master -> 5e00b39caec66e1c5626a89f207c26c577fd30d8

dreammaster dreammaster at scummvm.org
Mon Feb 9 04:09:03 CET 2015


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:
5e00b39cae MADS: Implementing code for panning screen transitions


Commit: 5e00b39caec66e1c5626a89f207c26c577fd30d8
    https://github.com/scummvm/scummvm/commit/5e00b39caec66e1c5626a89f207c26c577fd30d8
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2015-02-08T22:07:42-05:00

Commit Message:
MADS: Implementing code for panning screen transitions

Changed paths:
    engines/mads/msurface.cpp
    engines/mads/msurface.h
    engines/mads/palette.cpp
    engines/mads/palette.h
    engines/mads/screen.cpp
    engines/mads/screen.h



diff --git a/engines/mads/msurface.cpp b/engines/mads/msurface.cpp
index 39824ba..d8d01f3 100644
--- a/engines/mads/msurface.cpp
+++ b/engines/mads/msurface.cpp
@@ -485,7 +485,6 @@ void MSurface::scrollY(int yAmount) {
 	delete[] tempData;
 }
 
-
 void MSurface::translate(Common::Array<RGB6> &palette) {
 	for (int y = 0; y < this->h; ++y) {
 		byte *pDest = getBasePtr(0, y);
@@ -521,6 +520,20 @@ MSurface *MSurface::flipHorizontal() const {
 	return dest;
 }
 
+void MSurface::copyRectTranslate(MSurface &srcSurface, const byte *paletteMap,
+		const Common::Point &destPos, const Common::Rect &srcRect) {
+	// Loop through the lines
+	for (int yCtr = 0; yCtr < srcRect.height(); ++yCtr) {
+		const byte *srcP = srcSurface.getBasePtr(srcRect.left, srcRect.top + yCtr);
+		byte *destP = getBasePtr(destPos.x, destPos.y + yCtr);
+
+		// Copy the line over
+		for (int xCtr = 0; xCtr < srcRect.width(); ++xCtr, ++srcP, ++destP) {
+			*destP = paletteMap[*srcP];
+		}
+	}
+}
+
 /*------------------------------------------------------------------------*/
 
 int DepthSurface::getDepth(const Common::Point &pt) {
diff --git a/engines/mads/msurface.h b/engines/mads/msurface.h
index 650d7fd..754e70b 100644
--- a/engines/mads/msurface.h
+++ b/engines/mads/msurface.h
@@ -220,6 +220,13 @@ public:
 	 * Create a new surface which is a flipped horizontal copy of the current one
 	 */
 	MSurface *flipHorizontal() const;
+
+	/**
+	 * Copy an area from one surface to another, translating it using a palette
+	 * map as it's done
+	 */
+	void copyRectTranslate(MSurface &srcSurface, const byte *paletteMap,
+		const Common::Point &destPos, const Common::Rect &srcRect);
 };
 
 class DepthSurface : public MSurface {
diff --git a/engines/mads/palette.cpp b/engines/mads/palette.cpp
index 250eb75..250c98b 100644
--- a/engines/mads/palette.cpp
+++ b/engines/mads/palette.cpp
@@ -885,4 +885,30 @@ void Palette::refreshSceneColors() {
 	setPalette(_mainPalette + (val * 3), val, 256 - val);
 }
 
+int Palette::closestColor(const byte *matchColor, const byte *refPalette,
+		int listWrap, int count) {
+	int bestColor = 0;
+	int bestDifference = 0x7fff;
+
+	for (int idx = 0; idx < count; ++idx) {
+		// Figure out hash for color
+		int hash = 0;
+		for (int rgbIdx = 0; rgbIdx < 3; ++rgbIdx, ++refPalette) {
+			byte diff = *refPalette - matchColor[rgbIdx];
+			hash += (int)diff * (int)diff;
+		}
+
+		// If the given color is a closer match to our color, store the index
+		if (hash < bestDifference) {
+			bestDifference = hash;
+			bestColor = idx;
+		}
+
+		refPalette += listWrap - 3;
+	}
+
+	return bestColor;
+}
+
+
 } // End of namespace MADS
diff --git a/engines/mads/palette.h b/engines/mads/palette.h
index 27d25f2..1c387b4 100644
--- a/engines/mads/palette.h
+++ b/engines/mads/palette.h
@@ -318,6 +318,9 @@ public:
 	void unlock();
 
 	void refreshSceneColors();
+
+	static int closestColor(const byte *matchColor, const byte *refPalette, 
+		int listWrap, int count);
 };
 
 } // End of namespace MADS
diff --git a/engines/mads/screen.cpp b/engines/mads/screen.cpp
index 8552eff..f717987 100644
--- a/engines/mads/screen.cpp
+++ b/engines/mads/screen.cpp
@@ -607,6 +607,7 @@ void ScreenSurface::updateScreen() {
 
 void ScreenSurface::transition(ScreenTransition transitionType, bool surfaceFlag) {
 	Palette &pal = *_vm->_palette;
+	Scene &scene = _vm->_game->_scene;
 	byte palData[PALETTE_SIZE];
 
 	switch (transitionType) {
@@ -639,8 +640,9 @@ void ScreenSurface::transition(ScreenTransition transitionType, bool surfaceFlag
 
 	case kTransitionPanLeftToRight:
 	case kTransitionPanRightToLeft:
-		warning("TODO: pan transition");
-		transition(kTransitionFadeIn, surfaceFlag);
+		panTransition(scene._backgroundSurface, pal._mainPalette,
+			transitionType - kTransitionPanLeftToRight,
+			Common::Point(0, 0), scene._posAdjust, THROUGH_BLACK2, true, 1);
 		break;
 
 	case kTransitionCircleIn1:
@@ -674,5 +676,121 @@ void ScreenSurface::resetClipBounds() {
 	setClipBounds(Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT));
 }
 
+void ScreenSurface::panTransition(MSurface &newScreen, byte *palData, int entrySide,
+		const Common::Point &srcPos, const Common::Point &destPos,
+		ThroughBlack throughBlack, bool setPalette, int numTicks) {
+	EventsManager &events = *_vm->_events;
+	Palette &palette = *_vm->_palette;
+	Common::Point size;
+	int y1, y2;
+	int startX = 0;
+	int deltaX;
+	int sizeY;
+	int xAt;
+	int loopStart;
+//	uint32 baseTicks, currentTicks;
+	byte paletteMap[256];
+
+	size.x = MIN(newScreen.w, (uint16)MADS_SCREEN_WIDTH);
+	size.y = newScreen.h;
+	if (newScreen.h >= MADS_SCREEN_HEIGHT)
+		size.y = MADS_SCENE_HEIGHT;
+
+	// Set starting position and direction delta for the transition
+	if (entrySide == 1)
+		// Right to left
+		startX = size.x - 1;
+	deltaX = startX ? -1 : 1;
+
+	if (setPalette & !throughBlack)
+		palette.setFullPalette(palData);
+
+	// TODO: Original uses a different frequency ticks counter. Need to
+	// confirm frequency and see whether we need to implement it, or
+	// if the current frame ticks can substitute for it
+//	baseTicks = events.getFrameCounter();
+
+	y1 = 0;
+	y2 = size.y - 1;
+	sizeY = y2 - y1 + 1;
+
+	if (throughBlack == THROUGH_BLACK2)
+		swapForeground(palData, &paletteMap[0]);
+
+	loopStart = throughBlack == THROUGH_BLACK1 ? 0 : 1;
+	for (int loop = loopStart; loop < 2; ++loop) {
+		xAt = startX;
+		for (int xCtr = 0; xCtr < size.x; ++xCtr, xAt += deltaX) {
+			if (!loop) {
+				fillRect(Common::Rect(xAt + destPos.x, y1 + destPos.y,
+					xAt + destPos.x + 1, y2 + destPos.y), 0);
+			} else if (throughBlack == THROUGH_BLACK2) {
+				copyRectTranslate(newScreen, paletteMap,
+					Common::Point(xAt, destPos.y),
+					Common::Rect(srcPos.x + xAt, srcPos.y,
+					srcPos.x + xAt + 1, srcPos.y + size.y));
+			} else {
+				newScreen.copyRectToSurface(*this, xAt, destPos.y,
+					Common::Rect(srcPos.x + xAt, srcPos.y, 
+					srcPos.x + xAt + 1, srcPos.y + size.y));
+			}
+
+			copyRectToScreen(Common::Rect(xAt, destPos.y, xAt + 1, destPos.y + size.y));
+
+			// Slight delay
+			events.delay(1);
+		}
+
+		if ((setPalette && !loop) || throughBlack == THROUGH_BLACK2)
+			palette.setFullPalette(palData);
+	}
+
+	if (throughBlack == THROUGH_BLACK2) {
+		Common::Rect r(srcPos.x, srcPos.y, srcPos.x + size.x, srcPos.y + size.y);
+		copyRectToSurface(newScreen, destPos.x, destPos.y, r);
+		copyRectToScreen(r);
+	}
+}
+
+void ScreenSurface::swapForeground(byte palData[PALETTE_SIZE], byte *paletteMap) {
+	Palette &palette = *_vm->_palette;
+	byte oldPalette[PALETTE_SIZE];
+	byte oldMap[256];
+	byte newMap[256];
+
+	palette.getFullPalette(oldPalette);
+	swapPalette(oldPalette, oldMap, true);
+	swapPalette(palData, newMap, false);
+
+	Common::copy(&palData[3], &palData[PALETTE_SIZE], &oldPalette[3]);
+
+	copyRectTranslate(*this, oldMap, Common::Point(0, 0), 
+		Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT));
+	palette.setFullPalette(oldPalette);
+}
+
+void ScreenSurface::swapPalette(byte *palData, byte swapTable[PALETTE_COUNT], 
+		int start) {
+	byte *dynamicList = &palData[start * 3];
+	int staticStart = 1 - start;
+	byte *staticList = &palData[staticStart * 3];
+	const int PALETTE_START = 1;
+	const int PALETTE_END = 252;
+
+	// Set initial index values
+	for (int idx = 0; idx < PALETTE_COUNT; ++idx)
+		swapTable[idx] = idx;
+
+	for (int idx = 0; idx < 128; ++idx) {
+		if (start >= PALETTE_START && start <= PALETTE_END) {
+			swapTable[start] = Palette::closestColor(dynamicList, staticList, 
+				6, 128) * 2 + staticStart;
+		}
+
+		dynamicList += 6;
+		start += 2;
+	}
+}
+
 
 } // End of namespace MADS
diff --git a/engines/mads/screen.h b/engines/mads/screen.h
index 6800523..35042e8 100644
--- a/engines/mads/screen.h
+++ b/engines/mads/screen.h
@@ -56,6 +56,11 @@ enum InputMode {
 	kInputLimitedSentences = 2		// Use only scene hotspots
 };
 
+enum ThroughBlack {
+	THROUGH_BLACK1 = 1,
+	THROUGH_BLACK2 = 2
+};
+
 class SpriteSlot;
 class TextDisplay;
 class UISlot;
@@ -207,6 +212,14 @@ private:
 	uint16 _random;
 	byte *_surfacePixels;
 	Common::Rect _clipBounds;
+
+	void panTransition(MSurface &newScreen, byte *palData, int entrySide,
+		const Common::Point &srcPos, const Common::Point &destPos,
+		ThroughBlack throughBlack, bool setPalette, int numTicks);
+
+	void swapForeground(byte *palData, byte *paletteMap);
+
+	void swapPalette(byte palData[PALETTE_SIZE], byte swapTable[PALETTE_COUNT], int start);
 public:
 	int _shakeCountdown;
 public:






More information about the Scummvm-git-logs mailing list