From 1aa9181466d1916824abb7301ea3e67781d08183 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 14 Feb 2015 15:34:11 -0500 Subject: MADS: Cleanup and bugfixes for panning transition support methods --- engines/mads/palette.cpp | 22 +++++++++++++------- engines/mads/palette.h | 11 ++++------ engines/mads/screen.cpp | 53 ++++++++++++++++++++++++++++++++++-------------- engines/mads/screen.h | 4 ++-- 4 files changed, 59 insertions(+), 31 deletions(-) diff --git a/engines/mads/palette.cpp b/engines/mads/palette.cpp index b41eaedfcc..b5ea136abd 100644 --- a/engines/mads/palette.cpp +++ b/engines/mads/palette.cpp @@ -428,6 +428,14 @@ void Fader::grabPalette(byte *colors, uint start, uint num) { g_system->getPaletteManager()->grabPalette(colors, start, num); } +void Fader::getFullPalette(byte palette[PALETTE_SIZE]) { + grabPalette(&palette[0], 0, PALETTE_COUNT); +} + +void Fader::setFullPalette(byte palette[PALETTE_SIZE]) { + setPalette(&palette[0], 0, PALETTE_COUNT); +} + void Fader::fadeOut(byte palette[PALETTE_SIZE], byte *paletteMap, int baseColor, int numColors, int baseGrey, int numGreys, int tickDelay, int steps) { @@ -886,25 +894,25 @@ void Palette::refreshSceneColors() { } int Palette::closestColor(const byte *matchColor, const byte *refPalette, - int listWrap, int count) { + int paletteInc, int count) { int bestColor = 0; int bestDistance = 0x7fff; for (int idx = 0; idx < count; ++idx) { - // Figure out hash for color + // Figure out figure for 'distance' between two colors int distance = 0; - for (int rgbIdx = 0; rgbIdx < 3; ++rgbIdx, ++refPalette) { - byte diff = *refPalette - matchColor[rgbIdx]; - distance += (int)diff * (int)diff; + for (int rgbIdx = 0; rgbIdx < RGB_SIZE; ++rgbIdx) { + int diff = refPalette[rgbIdx] - matchColor[rgbIdx]; + distance += diff * diff; } // If the given color is a closer match to our color, store the index - if (distance < bestDistance) { + if (distance <= bestDistance) { bestDistance = distance; bestColor = idx; } - refPalette += listWrap - 3; + refPalette += paletteInc; } return bestColor; diff --git a/engines/mads/palette.h b/engines/mads/palette.h index 1c387b4368..5d3bc3a82e 100644 --- a/engines/mads/palette.h +++ b/engines/mads/palette.h @@ -36,6 +36,7 @@ class MADSEngine; #define PALETTE_RESERVED_HIGH_COUNT 10 #define PALETTE_COUNT 256 +#define RGB_SIZE 3 #define PALETTE_SIZE (256 * 3) /** @@ -212,16 +213,12 @@ public: /** * Gets the entire palette at once */ - void getFullPalette(byte palette[PALETTE_SIZE]) { - grabPalette(&palette[0], 0, PALETTE_COUNT); - } + void getFullPalette(byte palette[PALETTE_SIZE]); /** * Sets the entire palette at once */ - void setFullPalette(byte palette[PALETTE_SIZE]) { - setPalette(&palette[0], 0, PALETTE_COUNT); - } + void setFullPalette(byte palette[PALETTE_SIZE]); /** * Calculates a merge/hash for a given palette entry @@ -320,7 +317,7 @@ public: void refreshSceneColors(); static int closestColor(const byte *matchColor, const byte *refPalette, - int listWrap, int count); + int paletteInc, int count); }; } // End of namespace MADS diff --git a/engines/mads/screen.cpp b/engines/mads/screen.cpp index f7179877d5..60f3d8aeaf 100644 --- a/engines/mads/screen.cpp +++ b/engines/mads/screen.cpp @@ -610,7 +610,7 @@ void ScreenSurface::transition(ScreenTransition transitionType, bool surfaceFlag Scene &scene = _vm->_game->_scene; byte palData[PALETTE_SIZE]; - switch (transitionType) { + switch (transitionType) { case kTransitionFadeIn: case kTransitionFadeOutIn: Common::fill(&pal._colorValues[0], &pal._colorValues[3], 0); @@ -738,7 +738,8 @@ void ScreenSurface::panTransition(MSurface &newScreen, byte *palData, int entryS copyRectToScreen(Common::Rect(xAt, destPos.y, xAt + 1, destPos.y + size.y)); // Slight delay - events.delay(1); + events.pollEvents(); + g_system->delayMillis(1); } if ((setPalette && !loop) || throughBlack == THROUGH_BLACK2) @@ -752,28 +753,49 @@ void ScreenSurface::panTransition(MSurface &newScreen, byte *palData, int entryS } } -void ScreenSurface::swapForeground(byte palData[PALETTE_SIZE], byte *paletteMap) { +/** + * Translates the current screen from the old palette to the new palette + */ +void ScreenSurface::swapForeground(byte newPalette[PALETTE_SIZE], byte *paletteMap) { Palette &palette = *_vm->_palette; byte oldPalette[PALETTE_SIZE]; - byte oldMap[256]; - byte newMap[256]; + byte oldMap[PALETTE_COUNT]; palette.getFullPalette(oldPalette); swapPalette(oldPalette, oldMap, true); - swapPalette(palData, newMap, false); - - Common::copy(&palData[3], &palData[PALETTE_SIZE], &oldPalette[3]); + swapPalette(newPalette, paletteMap, false); + + // Transfer translated foreground colors. Since foregrounds are interleaved + // with background, we only copy over each alternate RGB tuplet + const byte *srcP = &newPalette[RGB_SIZE]; + byte *destP = &oldPalette[RGB_SIZE]; + while (destP < &oldPalette[PALETTE_SIZE]) { + Common::copy(srcP, srcP + RGB_SIZE, destP); + srcP += 2 * RGB_SIZE; + destP += 2 * RGB_SIZE; + } + Common::Rect oldClip = _clipBounds; + resetClipBounds(); + copyRectTranslate(*this, oldMap, Common::Point(0, 0), Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT)); palette.setFullPalette(oldPalette); + + setClipBounds(oldClip); } -void ScreenSurface::swapPalette(byte *palData, byte swapTable[PALETTE_COUNT], - int start) { - byte *dynamicList = &palData[start * 3]; +/** + * Translates a given palette into a mapping table. + * Palettes consist of 128 RGB entries for the foreground and background + * respectively, with the two interleaved together. So the start + */ +void ScreenSurface::swapPalette(const byte *palData, byte swapTable[PALETTE_COUNT], + bool foreground) { + int start = foreground ? 1 : 0; + const byte *dynamicList = &palData[start * RGB_SIZE]; int staticStart = 1 - start; - byte *staticList = &palData[staticStart * 3]; + const byte *staticList = &palData[staticStart * RGB_SIZE]; const int PALETTE_START = 1; const int PALETTE_END = 252; @@ -781,13 +803,14 @@ void ScreenSurface::swapPalette(byte *palData, byte swapTable[PALETTE_COUNT], for (int idx = 0; idx < PALETTE_COUNT; ++idx) swapTable[idx] = idx; - for (int idx = 0; idx < 128; ++idx) { + // Handle the 128 palette entries for the foreground or background + for (int idx = 0; idx < (PALETTE_COUNT / 2); ++idx) { if (start >= PALETTE_START && start <= PALETTE_END) { swapTable[start] = Palette::closestColor(dynamicList, staticList, - 6, 128) * 2 + staticStart; + 2 * RGB_SIZE, PALETTE_COUNT / 2) * 2 + staticStart; } - dynamicList += 6; + dynamicList += 2 * RGB_SIZE; start += 2; } } diff --git a/engines/mads/screen.h b/engines/mads/screen.h index 35042e88d2..e2462aff18 100644 --- a/engines/mads/screen.h +++ b/engines/mads/screen.h @@ -217,9 +217,9 @@ private: const Common::Point &srcPos, const Common::Point &destPos, ThroughBlack throughBlack, bool setPalette, int numTicks); - void swapForeground(byte *palData, byte *paletteMap); + void swapForeground(byte newPalette[PALETTE_SIZE], byte *paletteMap); - void swapPalette(byte palData[PALETTE_SIZE], byte swapTable[PALETTE_COUNT], int start); + void swapPalette(const byte palData[PALETTE_SIZE], byte swapTable[PALETTE_COUNT], bool foreground); public: int _shakeCountdown; public: -- cgit v1.2.3