From 35d01db1aa02db8554772d88354786e291387499 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Sun, 11 May 2008 15:57:50 +0000 Subject: Implemented page switch animation in kyra3 album. svn-id: r32023 --- engines/kyra/gui_mr.cpp | 31 ++++++----- engines/kyra/kyra_mr.h | 2 +- engines/kyra/screen_hof.cpp | 129 ++------------------------------------------ engines/kyra/screen_hof.h | 5 -- engines/kyra/screen_v2.cpp | 125 ++++++++++++++++++++++++++++++++++++++++++ engines/kyra/screen_v2.h | 8 ++- engines/kyra/text_mr.cpp | 1 + 7 files changed, 156 insertions(+), 145 deletions(-) diff --git a/engines/kyra/gui_mr.cpp b/engines/kyra/gui_mr.cpp index 0408c68317..fda9b089ea 100644 --- a/engines/kyra/gui_mr.cpp +++ b/engines/kyra/gui_mr.cpp @@ -742,11 +742,14 @@ void KyraEngine_MR::showAlbum() { restorePage3(); _screen->copyBlockToPage(0, 0, 0, 320, 200, _screenBuffer); _screen->copyBlockToPage(4, 0, 0, 320, 200, _album.backUpPage); - delete[] _album.backUpPage; - _album.backUpPage = 0; memcpy(_screen->getPalette(0), _screen->getPalette(1), 768); _screen->fadePalette(_screen->getPalette(0), 9); + + delete[] _album.backUpRect; + _album.backUpRect = 0; + delete[] _album.backUpPage; + _album.backUpPage = 0; delete[] _album.file; _album.file = 0; @@ -1045,16 +1048,16 @@ void KyraEngine_MR::albumUpdateRect() { _screen->updateScreen(); } -void KyraEngine_MR::albumSwitchPages(int oldPage, int newPage, int unk) { - debugC(9, kDebugLevelMain, "KyraEngine_MR::albumSwitchPages()"); +void KyraEngine_MR::albumSwitchPages(int oldPage, int newPage, int srcPage) { + debugC(9, kDebugLevelMain, "KyraEngine_MR::albumSwitchPages(%d, %d, %d)", oldPage, newPage, srcPage); if (newPage > oldPage) { - //XXX + _screen->wsaFrameAnimationStep(0xA0, 0x07, 0xA0, 0x07, 0x96, 0xBA, 0x64, 0xBA, srcPage, 0, 2); _screen->copyRegion(260, 7, 260, 7, 50, 186, 2, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); delayWithTicks(1); - //XXX + _screen->wsaFrameAnimationStep(0xA0, 0x07, 0xA0, 0x07, 0x96, 0xBA, 0x32, 0xBA, srcPage, 0, 2); _screen->copyRegion(210, 7, 210, 7, 50, 186, 2, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); @@ -1064,22 +1067,24 @@ void KyraEngine_MR::albumSwitchPages(int oldPage, int newPage, int unk) { _screen->updateScreen(); delayWithTicks(1); - //XXX + _screen->wsaFrameAnimationStep(0x10, 0x07, 0x6E, 0x07, 0x96, 0xBA, 0x32, 0xBA, 2, 0, 2); + _screen->updateScreen(); delayWithTicks(1); - //XXX + _screen->wsaFrameAnimationStep(0x10, 0x07, 0x3C, 0x07, 0x96, 0xBA, 0x64, 0xBA, 2, 0, 2); + _screen->updateScreen(); delayWithTicks(1); _screen->copyRegion(10, 7, 10, 7, 150, 186, 2, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); } else { - //XXX + _screen->wsaFrameAnimationStep(0x0A, 0x07, 0x3C, 0x07, 0x96, 0xBA, 0x64, 0xBA, srcPage, 0, 2); _screen->copyRegion(10, 7, 10, 7, 50, 186, 2, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); delayWithTicks(1); - //XXX + _screen->wsaFrameAnimationStep(0x0A, 0x07, 0x6E, 0x07, 0x96, 0xBA, 0x32, 0xBA, srcPage, 0, 2); _screen->copyRegion(60, 7, 60, 7, 50, 186, 2, 0, Screen::CR_NO_P_CHECK); _screen->updateScreen(); @@ -1089,10 +1094,12 @@ void KyraEngine_MR::albumSwitchPages(int oldPage, int newPage, int unk) { _screen->updateScreen(); delayWithTicks(1); - //XXX + _screen->wsaFrameAnimationStep(0xA0, 0x07, 0xA0, 0x07, 0x96, 0xBA, 0x32, 0xBA, 2, 0, 2); + _screen->updateScreen(); delayWithTicks(1); - //XXX + _screen->wsaFrameAnimationStep(0xA0, 0x07, 0xA0, 0x07, 0x96, 0xBA, 0x64, 0xBA, 2, 0, 2); + _screen->updateScreen(); delayWithTicks(1); _screen->copyRegion(160, 7, 160, 7, 150, 186, 2, 0, Screen::CR_NO_P_CHECK); diff --git a/engines/kyra/kyra_mr.h b/engines/kyra/kyra_mr.h index 2921ab7abc..29a1f6b044 100644 --- a/engines/kyra/kyra_mr.h +++ b/engines/kyra/kyra_mr.h @@ -572,7 +572,7 @@ private: void albumRestoreRect(); void albumUpdateRect(); - void albumSwitchPages(int oldPage, int newPage, int unk); + void albumSwitchPages(int oldPage, int newPage, int srcPage); int albumNextPage(Button *caller); int albumPrevPage(Button *caller); diff --git a/engines/kyra/screen_hof.cpp b/engines/kyra/screen_hof.cpp index 9a4237366b..2378c870a8 100644 --- a/engines/kyra/screen_hof.cpp +++ b/engines/kyra/screen_hof.cpp @@ -31,13 +31,7 @@ namespace Kyra { Screen_HoF::Screen_HoF(KyraEngine_HoF *vm, OSystem *system) - : Screen_v2(vm, system) { - _vm = vm; - _wsaFrameAnimBuffer = new uint8[1024]; -} - -Screen_HoF::~Screen_HoF() { - delete[] _wsaFrameAnimBuffer; + : Screen_v2(vm, system), _vm(vm) { } void Screen_HoF::setScreenDim(int dim) { @@ -74,80 +68,10 @@ void Screen_HoF::generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, in grayOverlay[i] = findLeastDifferentColor(tmpPal + 3 * i, srcPal, lastColor); } -void Screen_HoF::wsaFrameAnimationStep(int x1, int y1, int x2, int y2, - int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim) { - - if (!(w1 || h1 || w2 || h2)) - return; - - ScreenDim cdm = _screenDimTable[dim]; - cdm.sx <<= 3; - cdm.w <<= 3; - - int na = 0, nb = 0, nc = w2; - - if (!calcBounds(cdm.w, cdm.h, x2, y2, w2, h2, na, nb, nc)) - return; - - const uint8 *src = getPagePtr(srcPage) + y1 * 320; - uint8 *dst = getPagePtr(dstPage) + (y2 + cdm.sy) * 320; - - int u = -1; - - do { - int t = (nb * h1) / h2; - if (t != u) { - u = t; - const uint8 *s = src + (x1 + t) * 320; - uint8 *dt = (uint8*) _wsaFrameAnimBuffer; - - t = w2 - w1; - if (!t) { - memcpy(dt, s, w2); - } else if (t > 0) { - if (w1 == 1) { - memset(dt, *s, w2); - } else { - t = ((((((w2 - w1 + 1) & 0xffff) << 8) / w1) + 0x100) & 0xffff) << 8; - int bp = 0; - for (int i = 0; i < w1; i++) { - int cnt = (t >> 16); - bp += (t & 0xffff); - if (bp > 0xffff) { - bp -= 0xffff; - cnt++; - } - memset(dt, *s++, cnt); - dt += cnt; - } - } - } else { - if (w2 == 1) { - *dt = *s; - } else { - t = (((((w1 - w2) & 0xffff) << 8) / w2) & 0xffff) << 8; - int bp = 0; - for (int i = 0; i < w2; i++) { - *dt++ = *s++; - bp += (t & 0xffff); - if (bp > 0xffff) { - bp -= 0xffff; - s++; - } - s += (t >> 16); - } - } - } - } - memcpy(dst + x2 + cdm.sx, _wsaFrameAnimBuffer + na, w2); - dst += 320; - } while (++nb < h2); -} - void Screen_HoF::cmpFadeFrameStep(int srcPage, int srcW, int srcH, int srcX, int srcY, int dstPage, int dstW, int dstH, int dstX, int dstY, int cmpW, int cmpH, int cmpPage) { - if (!(cmpW || cmpH )) + if (!cmpW || !cmpH) return; int r1, r2, r3, r4, r5, r6; @@ -192,8 +116,7 @@ void Screen_HoF::copyPageMemory(int srcPage, int srcPos, int dstPage, int dstPos memcpy(dst, src, numBytes); } - -void Screen_HoF::copyRegionEx(int srcPage, int srcW, int srcH, int dstPage, int dstX,int dstY, int dstW, int dstH, const ScreenDim *dim, bool flag) { +void Screen_HoF::copyRegionEx(int srcPage, int srcW, int srcH, int dstPage, int dstX, int dstY, int dstW, int dstH, const ScreenDim *dim, bool flag) { int x0 = dim->sx << 3; int y0 = dim->sy; int w0 = dim->w << 3; @@ -229,51 +152,5 @@ void Screen_HoF::copyRegionEx(int srcPage, int srcW, int srcH, int dstPage, int } } -bool Screen_HoF::calcBounds(int w0, int h0, int &x1, int &y1, int &w1, int &h1, int &x2, int &y2, int &w2) { - x2 = 0; - y2 = 0; - w2 = w1; - - int t = x1 + w1; - if (t < 1) { - w1 = h1 = -1; - } else { - if (t <= x1) { - x2 = w1 - t; - w1 = t; - x1 = 0; - } - t = w0 - x1; - if (t < 1) { - w1 = h1 = -1; - } else { - if (t <= w1) { - w1 = t; - } - w2 -= w1; - t = h1 + y1; - if (t < 1) { - w1 = h1 = -1; - } else { - if (t <= y1) { - y2 = h1 - t; - h1 = t; - y1 = 0; - } - t = h0 - y1; - if (t < 1) { - w1 = h1 = -1; - } else { - if (t <= h1) { - h1 = t; - } - } - } - } - } - - return (w1 == -1) ? false : true; -} - } // end of namespace Kyra diff --git a/engines/kyra/screen_hof.h b/engines/kyra/screen_hof.h index a6df749538..088e8b7f55 100644 --- a/engines/kyra/screen_hof.h +++ b/engines/kyra/screen_hof.h @@ -36,15 +36,12 @@ class Screen_HoF : public Screen_v2 { friend class Debugger_v2; public: Screen_HoF(KyraEngine_HoF *vm, OSystem *system); - ~Screen_HoF(); void setScreenDim(int dim); const ScreenDim *getScreenDim(int dim); // sequence player void generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool flag); - bool calcBounds(int w0, int h0, int &x1, int &y1, int &w1, int &h1, int &x2, int &y2, int &w2); - void wsaFrameAnimationStep(int x1, int y1, int x2, int y2, int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim); void cmpFadeFrameStep(int srcPage, int srcW, int srcH, int srcX, int srcY, int dstPage, int dstW, int dstH, int dstX, int dstY, int cmpW, int cmpH, int cmpPage); void copyPageMemory(int srcPage, int srcPos, int dstPage, int dstPos, int numBytes); void copyRegionEx(int srcPage, int srcW, int srcH, int dstPage, int dstX,int dstY, int dstW, int dstH, const ScreenDim *d, bool flag = false); @@ -53,8 +50,6 @@ private: static const ScreenDim _screenDimTable[]; static const int _screenDimTableCount; - - uint8 *_wsaFrameAnimBuffer; }; } // End of namespace Kyra diff --git a/engines/kyra/screen_v2.cpp b/engines/kyra/screen_v2.cpp index 564282fb3f..13186b0167 100644 --- a/engines/kyra/screen_v2.cpp +++ b/engines/kyra/screen_v2.cpp @@ -29,6 +29,15 @@ namespace Kyra { +Screen_v2::Screen_v2(KyraEngine *vm, OSystem *system) : Screen(vm, system), _wsaFrameAnimBuffer(0) { + _wsaFrameAnimBuffer = new uint8[1024]; + assert(_wsaFrameAnimBuffer); +} + +Screen_v2::~Screen_v2() { + delete[] _wsaFrameAnimBuffer; +} + uint8 *Screen_v2::generateOverlay(const uint8 *palette, uint8 *buffer, int startColor, uint16 factor) { if (!palette || !buffer) return buffer; @@ -336,5 +345,121 @@ void Screen_v2::setTextColorMap(const uint8 *cmap) { setTextColor(cmap, 0, 15); } +void Screen_v2::wsaFrameAnimationStep(int x1, int y1, int x2, int y2, + int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim) { + + if (!(w1 || h1 || w2 || h2)) + return; + + ScreenDim cdm = *getScreenDim(dim); + cdm.sx <<= 3; + cdm.w <<= 3; + + int na = 0, nb = 0, nc = w2; + + if (!calcBounds(cdm.w, cdm.h, x2, y2, w2, h2, na, nb, nc)) + return; + + const uint8 *src = getPagePtr(srcPage) + y1 * 320; + uint8 *dst = getPagePtr(dstPage) + (y2 + cdm.sy) * 320; + + int u = -1; + + do { + int t = (nb * h1) / h2; + if (t != u) { + u = t; + const uint8 *s = src + (x1 + t) * 320; + uint8 *dt = (uint8 *)_wsaFrameAnimBuffer; + + t = w2 - w1; + if (!t) { + memcpy(dt, s, w2); + } else if (t > 0) { + if (w1 == 1) { + memset(dt, *s, w2); + } else { + t = ((((((w2 - w1 + 1) & 0xffff) << 8) / w1) + 0x100) & 0xffff) << 8; + int bp = 0; + for (int i = 0; i < w1; i++) { + int cnt = (t >> 16); + bp += (t & 0xffff); + if (bp > 0xffff) { + bp -= 0xffff; + cnt++; + } + memset(dt, *s++, cnt); + dt += cnt; + } + } + } else { + if (w2 == 1) { + *dt = *s; + } else { + t = (((((w1 - w2) & 0xffff) << 8) / w2) & 0xffff) << 8; + int bp = 0; + for (int i = 0; i < w2; i++) { + *dt++ = *s++; + bp += (t & 0xffff); + if (bp > 0xffff) { + bp -= 0xffff; + s++; + } + s += (t >> 16); + } + } + } + } + memcpy(dst + x2 + cdm.sx, _wsaFrameAnimBuffer + na, w2); + dst += 320; + } while (++nb < h2); +} + +bool Screen_v2::calcBounds(int w0, int h0, int &x1, int &y1, int &w1, int &h1, int &x2, int &y2, int &w2) { + x2 = 0; + y2 = 0; + w2 = w1; + + int t = x1 + w1; + if (t < 1) { + w1 = h1 = -1; + } else { + if (t <= x1) { + x2 = w1 - t; + w1 = t; + x1 = 0; + } + t = w0 - x1; + if (t < 1) { + w1 = h1 = -1; + } else { + if (t <= w1) { + w1 = t; + } + w2 -= w1; + t = h1 + y1; + if (t < 1) { + w1 = h1 = -1; + } else { + if (t <= y1) { + y2 = h1 - t; + h1 = t; + y1 = 0; + } + t = h0 - y1; + if (t < 1) { + w1 = h1 = -1; + } else { + if (t <= h1) { + h1 = t; + } + } + } + } + } + + return (w1 == -1) ? false : true; +} + } // end of namespace Kyra diff --git a/engines/kyra/screen_v2.h b/engines/kyra/screen_v2.h index 5679dadf39..caec6af992 100644 --- a/engines/kyra/screen_v2.h +++ b/engines/kyra/screen_v2.h @@ -33,7 +33,8 @@ namespace Kyra { class Screen_v2 : public Screen { public: - Screen_v2(KyraEngine *vm, OSystem *system) : Screen(vm, system) {} + Screen_v2(KyraEngine *vm, OSystem *system); + ~Screen_v2(); // screen page handling void copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src, @@ -57,13 +58,18 @@ public: // rect handling int getRectSize(int w, int h); + bool calcBounds(int w0, int h0, int &x1, int &y1, int &w1, int &h1, int &x2, int &y2, int &w2); // text display void setTextColorMap(const uint8 *cmap); // layer handling virtual int getLayer(int x, int y); + + // special WSA handling + void wsaFrameAnimationStep(int x1, int y1, int x2, int y2, int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim); protected: + uint8 *_wsaFrameAnimBuffer; }; } // end of namespace Kyra diff --git a/engines/kyra/text_mr.cpp b/engines/kyra/text_mr.cpp index 70c24106f9..13b37fa77a 100644 --- a/engines/kyra/text_mr.cpp +++ b/engines/kyra/text_mr.cpp @@ -606,6 +606,7 @@ void KyraEngine_MR::albumChatWaitToFinish() { _album.wsa->setY(90); _album.wsa->setDrawPage(2); + albumRestoreRect(); _album.wsa->displayFrame(frame, 0x4000); albumUpdateRect(); -- cgit v1.2.3