aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorMartin Kiewitz2009-10-17 14:12:42 +0000
committerMartin Kiewitz2009-10-17 14:12:42 +0000
commitcada56749184ff3984d0772a3371db65c7431324 (patch)
treedeaffa5369979574d4962d15683616d5a57edd64 /engines/sci
parent4bc8d919d8d451f1072fa135bbed745df5aae3ef (diff)
downloadscummvm-rg350-cada56749184ff3984d0772a3371db65c7431324.tar.gz
scummvm-rg350-cada56749184ff3984d0772a3371db65c7431324.tar.bz2
scummvm-rg350-cada56749184ff3984d0772a3371db65c7431324.zip
SCI/newgui: SciGuiTransitions now supports blackout flag as well (used in e.g. sq1 intro)
svn-id: r45187
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/gui/gui_transitions.cpp205
-rw-r--r--engines/sci/gui/gui_transitions.h29
2 files changed, 151 insertions, 83 deletions
diff --git a/engines/sci/gui/gui_transitions.cpp b/engines/sci/gui/gui_transitions.cpp
index 7e2012964c..ae294d02cc 100644
--- a/engines/sci/gui/gui_transitions.cpp
+++ b/engines/sci/gui/gui_transitions.cpp
@@ -25,7 +25,7 @@
#include "common/util.h"
#include "common/stack.h"
-#include "graphics/primitives.h"
+#include "graphics/surface.h"
#include "sci/sci.h"
#include "sci/engine/state.h"
@@ -76,6 +76,29 @@ static const GuiTransitionTranslateEntry oldTransitionIDs[] = {
{ 255, 255, false }
};
+// this table defines the blackout-transition that needs to be done prior doing the actual transition
+static const GuiTransitionTranslateEntry blackoutTransitionIDs[] = {
+ { SCI_TRANSITIONS_VERTICALROLL_FROMCENTER, SCI_TRANSITIONS_VERTICALROLL_TOCENTER },
+ { SCI_TRANSITIONS_HORIZONTALROLL_FROMCENTER, SCI_TRANSITIONS_HORIZONTALROLL_TOCENTER },
+ { SCI_TRANSITIONS_STRAIGHT_FROM_RIGHT, SCI_TRANSITIONS_STRAIGHT_FROM_LEFT },
+ { SCI_TRANSITIONS_STRAIGHT_FROM_LEFT, SCI_TRANSITIONS_STRAIGHT_FROM_RIGHT },
+ { SCI_TRANSITIONS_STRAIGHT_FROM_BOTTOM, SCI_TRANSITIONS_STRAIGHT_FROM_TOP },
+ { SCI_TRANSITIONS_STRAIGHT_FROM_TOP, SCI_TRANSITIONS_STRAIGHT_FROM_BOTTOM },
+ { SCI_TRANSITIONS_DIAGONALROLL_FROMCENTER, SCI_TRANSITIONS_DIAGONALROLL_TOCENTER },
+ { SCI_TRANSITIONS_DIAGONALROLL_TOCENTER, SCI_TRANSITIONS_DIAGONALROLL_FROMCENTER },
+ { SCI_TRANSITIONS_BLOCKS, SCI_TRANSITIONS_BLOCKS },
+ { SCI_TRANSITIONS_PIXELATION, SCI_TRANSITIONS_PIXELATION },
+ { SCI_TRANSITIONS_FADEPALETTE, SCI_TRANSITIONS_NONE },
+ { SCI_TRANSITIONS_SCROLL_RIGHT, SCI_TRANSITIONS_NONE },
+ { SCI_TRANSITIONS_SCROLL_LEFT, SCI_TRANSITIONS_NONE },
+ { SCI_TRANSITIONS_SCROLL_UP, SCI_TRANSITIONS_NONE },
+ { SCI_TRANSITIONS_SCROLL_DOWN, SCI_TRANSITIONS_NONE },
+ { SCI_TRANSITIONS_NONE_LONGBOW, SCI_TRANSITIONS_NONE },
+ { SCI_TRANSITIONS_NONE, SCI_TRANSITIONS_NONE },
+ { SCI_TRANSITIONS_VERTICALROLL_TOCENTER, SCI_TRANSITIONS_NONE },
+ { SCI_TRANSITIONS_HORIZONTALROLL_TOCENTER, SCI_TRANSITIONS_NONE }
+};
+
void SciGuiTransitions::init() {
_oldScreen = new byte[_screen->_displayHeight * _screen->_displayWidth];
@@ -90,95 +113,135 @@ void SciGuiTransitions::setup(int16 number, bool blackoutFlag) {
_blackoutFlag = blackoutFlag;
}
+// will translate a number and return corresponding translationEntry
+const GuiTransitionTranslateEntry *SciGuiTransitions::translateNumber (int16 number, const GuiTransitionTranslateEntry *tablePtr) {
+ while (1) {
+ if (tablePtr->orgId == 255)
+ return NULL;
+ if (tablePtr->orgId == number)
+ return tablePtr;
+ tablePtr++;
+ }
+}
+
void SciGuiTransitions::doit(Common::Rect picRect) {
const GuiTransitionTranslateEntry *translationEntry = _translationTable;
_picRect = picRect;
- if (translationEntry) {
+ if (_translationTable) {
// We need to translate the ID
- while (1) {
- if (translationEntry->oldId == 255) {
- warning("SciGuiTransitions: old ID %d not supported", _number);
- setNewPalette(); setNewScreen();
- _screen->_picNotValid = 0;
- return;
- }
- if (translationEntry->oldId == _number) {
- _number = translationEntry->realId;
- _blackoutFlag = translationEntry->blackoutFlag;
- break;
- }
- translationEntry++;
+ translationEntry = translateNumber(_number, _translationTable);
+ if (translationEntry) {
+ _number = translationEntry->newId;
+ _blackoutFlag = translationEntry->blackoutFlag;
+ } else {
+ warning("SciGuiTransitions: old ID %d not supported", _number);
+ _number = SCI_TRANSITIONS_NONE;
+ _blackoutFlag = false;
}
}
- if (_blackoutFlag)
- warning("SciGuiTransitions: blackout flag currently not supported");
+ if (_blackoutFlag) {
+ // We need to find out what transition we are supposed to use for blackout
+ translationEntry = translateNumber(_number, blackoutTransitionIDs);
+
+ doTransition(translationEntry->newId, true);
+ }
+
+ // Now we do the actual transition to the new screen
+ doTransition(_number, false);
+
+ _screen->_picNotValid = 0;
+}
+
+// This may get called twice, if blackoutFlag is set. It will get once called with blackoutFlag set and another time
+// with no blackoutFlag.
+void SciGuiTransitions::doTransition(int16 number, bool blackoutFlag) {
+ if (number != SCI_TRANSITIONS_FADEPALETTE) {
+ setNewPalette(blackoutFlag);
+ }
- switch (_number) {
+ switch (number) {
case SCI_TRANSITIONS_VERTICALROLL_FROMCENTER:
- setNewPalette(); verticalRollFromCenter();
+ verticalRollFromCenter(blackoutFlag);
break;
case SCI_TRANSITIONS_VERTICALROLL_TOCENTER:
- setNewPalette(); verticalRollFromCenter();
+ verticalRollFromCenter(blackoutFlag);
break;
case SCI_TRANSITIONS_HORIZONTALROLL_FROMCENTER:
- setNewPalette(); horizontalRollFromCenter();
+ horizontalRollFromCenter(blackoutFlag);
break;
case SCI_TRANSITIONS_HORIZONTALROLL_TOCENTER:
- setNewPalette(); horizontalRollToCenter();
+ horizontalRollToCenter(blackoutFlag);
break;
case SCI_TRANSITIONS_DIAGONALROLL_TOCENTER:
- setNewPalette(); diagonalRollToCenter();
+ diagonalRollToCenter(blackoutFlag);
+ break;
case SCI_TRANSITIONS_DIAGONALROLL_FROMCENTER:
- setNewPalette(); diagonalRollFromCenter();
+ diagonalRollFromCenter(blackoutFlag);
+ break;
case SCI_TRANSITIONS_STRAIGHT_FROM_RIGHT:
case SCI_TRANSITIONS_STRAIGHT_FROM_LEFT:
case SCI_TRANSITIONS_STRAIGHT_FROM_BOTTOM:
case SCI_TRANSITIONS_STRAIGHT_FROM_TOP:
- setNewPalette(); straight(_number);
+ straight(number, blackoutFlag);
+ break;
case SCI_TRANSITIONS_PIXELATION:
- setNewPalette(); pixelation();
+ pixelation(blackoutFlag);
break;
case SCI_TRANSITIONS_BLOCKS:
- setNewPalette(); blocks();
+ blocks(blackoutFlag);
break;
case SCI_TRANSITIONS_FADEPALETTE:
- fadeOut(); setNewScreen(); fadeIn();
+ if (!blackoutFlag) {
+ fadeOut(); setNewScreen(blackoutFlag); fadeIn();
+ }
break;
case SCI_TRANSITIONS_SCROLL_RIGHT:
case SCI_TRANSITIONS_SCROLL_LEFT:
case SCI_TRANSITIONS_SCROLL_UP:
case SCI_TRANSITIONS_SCROLL_DOWN:
- setNewPalette(); scroll(_number);
+ scroll(number);
break;
case SCI_TRANSITIONS_NONE_LONGBOW:
case SCI_TRANSITIONS_NONE:
- setNewPalette(); setNewScreen();
+ setNewScreen(blackoutFlag);
break;
+
default:
- warning("SciGuiTransitions: ID %d not implemented", _number);
- setNewPalette(); setNewScreen();
+ warning("SciGuiTransitions: ID %d not implemented", number);
+ setNewScreen(blackoutFlag);
}
+}
- _screen->_picNotValid = 0;
+void SciGuiTransitions::setNewPalette(bool blackoutFlag) {
+ if (!blackoutFlag)
+ if (_isVGA)
+ _palette->setOnScreen();
}
-void SciGuiTransitions::setNewPalette() {
- if (_isVGA)
- _palette->setOnScreen();
+void SciGuiTransitions::setNewScreen(bool blackoutFlag) {
+ if (!blackoutFlag) {
+ _screen->copyRectToScreen(_picRect);
+ g_system->updateScreen();
+ }
}
-void SciGuiTransitions::setNewScreen() {
- _screen->copyRectToScreen(_picRect);
- g_system->updateScreen();
+void SciGuiTransitions::copyRectToScreen(const Common::Rect rect, bool blackoutFlag) {
+ if (!blackoutFlag) {
+ _screen->copyRectToScreen(rect);
+ } else {
+ Graphics::Surface *surface = g_system->lockScreen();
+ surface->fillRect(rect, 0);
+ g_system->unlockScreen();
+ }
}
// Note: dont do too many steps in here, otherwise cpu will crap out because of the load
@@ -210,7 +273,8 @@ void SciGuiTransitions::fadeIn() {
}
// pixelates the new picture over the old one - works against the whole screen
-void SciGuiTransitions::pixelation () {
+// TODO: it seems this needs to get applied on _picRect only if possible
+void SciGuiTransitions::pixelation (bool blackoutFlag) {
uint16 mask = 0x40, stepNr = 0;
Common::Rect pixelRect;
@@ -220,7 +284,7 @@ void SciGuiTransitions::pixelation () {
continue;
pixelRect.left = mask % 320; pixelRect.right = pixelRect.left + 1;
pixelRect.top = mask / 320; pixelRect.bottom = pixelRect.top + 1;
- _screen->copyRectToScreen(pixelRect);
+ copyRectToScreen(pixelRect, blackoutFlag);
if ((stepNr & 0x3FF) == 0) {
g_system->updateScreen();
g_system->delayMillis(5);
@@ -230,7 +294,8 @@ void SciGuiTransitions::pixelation () {
}
// like pixelation but uses 8x8 blocks - works against the whole screen
-void SciGuiTransitions::blocks() {
+// TODO: it seems this needs to get applied on _picRect only if possible
+void SciGuiTransitions::blocks(bool blackoutFlag) {
uint16 mask = 0x40, stepNr = 0;
Common::Rect blockRect;
@@ -240,7 +305,7 @@ void SciGuiTransitions::blocks() {
continue;
blockRect.left = (mask % 40) << 3; blockRect.right = blockRect.left + 8;
blockRect.top = (mask / 40) << 3; blockRect.bottom = blockRect.top + 8;
- _screen->copyRectToScreen(blockRect);
+ copyRectToScreen(blockRect, blackoutFlag);
if ((stepNr & 7) == 0) {
g_system->updateScreen();
g_system->delayMillis(4);
@@ -250,7 +315,7 @@ void SciGuiTransitions::blocks() {
}
// directly shows new screen starting up/down/left/right and going to the opposite direction - works on _picRect area only
-void SciGuiTransitions::straight(int16 number) {
+void SciGuiTransitions::straight(int16 number, bool blackoutFlag) {
int16 stepNr = 0;
Common::Rect newScreenRect = _picRect;
@@ -258,7 +323,7 @@ void SciGuiTransitions::straight(int16 number) {
case SCI_TRANSITIONS_STRAIGHT_FROM_RIGHT:
newScreenRect.left = newScreenRect.right - 1;
while (newScreenRect.left >= _picRect.left) {
- _screen->copyRectToScreen(newScreenRect);
+ copyRectToScreen(newScreenRect, blackoutFlag);
if ((stepNr & 1) == 0) {
g_system->updateScreen();
g_system->delayMillis(1);
@@ -271,7 +336,7 @@ void SciGuiTransitions::straight(int16 number) {
case SCI_TRANSITIONS_STRAIGHT_FROM_LEFT:
newScreenRect.right = newScreenRect.left + 1;
while (newScreenRect.right <= _picRect.right) {
- _screen->copyRectToScreen(newScreenRect);
+ copyRectToScreen(newScreenRect, blackoutFlag);
if ((stepNr & 1) == 0) {
g_system->updateScreen();
g_system->delayMillis(1);
@@ -284,7 +349,7 @@ void SciGuiTransitions::straight(int16 number) {
case SCI_TRANSITIONS_STRAIGHT_FROM_BOTTOM:
newScreenRect.top = newScreenRect.bottom - 1;
while (newScreenRect.top >= _picRect.top) {
- _screen->copyRectToScreen(newScreenRect);
+ copyRectToScreen(newScreenRect, blackoutFlag);
g_system->updateScreen();
g_system->delayMillis(3);
stepNr++;
@@ -295,7 +360,7 @@ void SciGuiTransitions::straight(int16 number) {
case SCI_TRANSITIONS_STRAIGHT_FROM_TOP:
newScreenRect.bottom = newScreenRect.top + 1;
while (newScreenRect.bottom <= _picRect.bottom) {
- _screen->copyRectToScreen(newScreenRect);
+ copyRectToScreen(newScreenRect, blackoutFlag);
g_system->updateScreen();
g_system->delayMillis(3);
stepNr++;
@@ -387,7 +452,7 @@ void SciGuiTransitions::scroll(int16 number) {
}
// vertically displays new screen starting from center - works on _picRect area only
-void SciGuiTransitions::verticalRollFromCenter() {
+void SciGuiTransitions::verticalRollFromCenter(bool blackoutFlag) {
Common::Rect leftRect = Common::Rect(_picRect.left + (_picRect.width() / 2) -1, _picRect.top, _picRect.left + (_picRect.width() / 2), _picRect.bottom);
Common::Rect rightRect = Common::Rect(leftRect.right, _picRect.top, leftRect.right + 1, _picRect.bottom);
@@ -396,28 +461,28 @@ void SciGuiTransitions::verticalRollFromCenter() {
leftRect.translate(1, 0);
if (rightRect.right > _picRect.right)
rightRect.translate(-1, 0);
- _screen->copyRectToScreen(leftRect); leftRect.translate(-1, 0);
- _screen->copyRectToScreen(rightRect); rightRect.translate(1, 0);
+ copyRectToScreen(leftRect, blackoutFlag); leftRect.translate(-1, 0);
+ copyRectToScreen(rightRect, blackoutFlag); rightRect.translate(1, 0);
g_system->updateScreen();
g_system->delayMillis(2);
}
}
// vertically displays new screen starting from edges - works on _picRect area only
-void SciGuiTransitions::verticalRollToCenter() {
+void SciGuiTransitions::verticalRollToCenter(bool blackoutFlag) {
Common::Rect leftRect = Common::Rect(_picRect.left, _picRect.top, _picRect.left + 1, _picRect.bottom);
Common::Rect rightRect = Common::Rect(leftRect.right - 1, _picRect.top, leftRect.right, _picRect.bottom);
while (leftRect.left < rightRect.right) {
- _screen->copyRectToScreen(leftRect); leftRect.translate(1, 0);
- _screen->copyRectToScreen(rightRect); rightRect.translate(-1, 0);
+ copyRectToScreen(leftRect, blackoutFlag); leftRect.translate(1, 0);
+ copyRectToScreen(rightRect, blackoutFlag); rightRect.translate(-1, 0);
g_system->updateScreen();
g_system->delayMillis(2);
}
}
// horizontally displays new screen starting from center - works on _picRect area only
-void SciGuiTransitions::horizontalRollFromCenter() {
+void SciGuiTransitions::horizontalRollFromCenter(bool blackoutFlag) {
Common::Rect upperRect = Common::Rect(_picRect.left, _picRect.top + (_picRect.height() / 2) - 1, _picRect.right, _picRect.top + (_picRect.height() / 2));
Common::Rect lowerRect = Common::Rect(upperRect.left, upperRect.bottom, upperRect.right, upperRect.bottom + 1);
@@ -426,21 +491,21 @@ void SciGuiTransitions::horizontalRollFromCenter() {
upperRect.translate(0, 1);
if (lowerRect.bottom > _picRect.bottom)
lowerRect.translate(0, -1);
- _screen->copyRectToScreen(upperRect); upperRect.translate(0, -1);
- _screen->copyRectToScreen(lowerRect); lowerRect.translate(0, 1);
+ copyRectToScreen(upperRect, blackoutFlag); upperRect.translate(0, -1);
+ copyRectToScreen(lowerRect, blackoutFlag); lowerRect.translate(0, 1);
g_system->updateScreen();
g_system->delayMillis(3);
}
}
// horizontally displays new screen starting from upper and lower edge - works on _picRect area only
-void SciGuiTransitions::horizontalRollToCenter() {
+void SciGuiTransitions::horizontalRollToCenter(bool blackoutFlag) {
Common::Rect upperRect = Common::Rect(_picRect.left, _picRect.top, _picRect.right, _picRect.top + 1);
Common::Rect lowerRect = Common::Rect(upperRect.left, _picRect.bottom - 1, upperRect.right, _picRect.bottom);
while (upperRect.top < lowerRect.bottom) {
- _screen->copyRectToScreen(upperRect); upperRect.translate(0, 1);
- _screen->copyRectToScreen(lowerRect); lowerRect.translate(0, -1);
+ copyRectToScreen(upperRect, blackoutFlag); upperRect.translate(0, 1);
+ copyRectToScreen(lowerRect, blackoutFlag); lowerRect.translate(0, -1);
g_system->updateScreen();
g_system->delayMillis(3);
}
@@ -448,7 +513,7 @@ void SciGuiTransitions::horizontalRollToCenter() {
// diagonally displays new screen starting from center - works on _picRect area only
// assumes that height of rect is larger than width, is also currently not optimized (TODO)
-void SciGuiTransitions::diagonalRollFromCenter() {
+void SciGuiTransitions::diagonalRollFromCenter(bool blackoutFlag) {
int16 halfHeight = _picRect.height() / 2;
Common::Rect upperRect(_picRect.left + halfHeight - 2, _picRect.top + halfHeight, _picRect.right - halfHeight + 1, _picRect.top + halfHeight + 1);
Common::Rect lowerRect(upperRect.left, upperRect.top, upperRect.right, upperRect.bottom);
@@ -468,10 +533,10 @@ void SciGuiTransitions::diagonalRollFromCenter() {
if (rightRect.right > _picRect.right) {
rightRect.translate(-1, 0); upperRect.right--; lowerRect.right--;
}
- _screen->copyRectToScreen(upperRect); upperRect.translate(0, -1); upperRect.left--; upperRect.right++;
- _screen->copyRectToScreen(lowerRect); lowerRect.translate(0, 1); lowerRect.left--; lowerRect.right++;
- _screen->copyRectToScreen(leftRect); leftRect.translate(-1, 0); leftRect.top--; leftRect.bottom++;
- _screen->copyRectToScreen(rightRect); rightRect.translate(1, 0); rightRect.top--; rightRect.bottom++;
+ copyRectToScreen(upperRect, blackoutFlag); upperRect.translate(0, -1); upperRect.left--; upperRect.right++;
+ copyRectToScreen(lowerRect, blackoutFlag); lowerRect.translate(0, 1); lowerRect.left--; lowerRect.right++;
+ copyRectToScreen(leftRect, blackoutFlag); leftRect.translate(-1, 0); leftRect.top--; leftRect.bottom++;
+ copyRectToScreen(rightRect, blackoutFlag); rightRect.translate(1, 0); rightRect.top--; rightRect.bottom++;
g_system->updateScreen();
g_system->delayMillis(3);
}
@@ -479,17 +544,17 @@ void SciGuiTransitions::diagonalRollFromCenter() {
// diagonally displays new screen starting from edges - works on _picRect area only
// assumes that height of rect is larger than width
-void SciGuiTransitions::diagonalRollToCenter() {
+void SciGuiTransitions::diagonalRollToCenter(bool blackoutFlag) {
Common::Rect upperRect(_picRect.left, _picRect.top, _picRect.right, _picRect.top + 1);
Common::Rect lowerRect(_picRect.left, _picRect.bottom - 1, _picRect.right, _picRect.bottom);
Common::Rect leftRect(_picRect.left, _picRect.top, _picRect.left + 1, _picRect.bottom);
Common::Rect rightRect(_picRect.right - 1, _picRect.top, _picRect.right, _picRect.bottom);
while (upperRect.top < lowerRect.bottom) {
- _screen->copyRectToScreen(upperRect); upperRect.translate(0, 1); upperRect.left++; upperRect.right--;
- _screen->copyRectToScreen(lowerRect); lowerRect.translate(0, -1); lowerRect.left++; lowerRect.right--;
- _screen->copyRectToScreen(leftRect); leftRect.translate(1, 0);
- _screen->copyRectToScreen(rightRect); rightRect.translate(-1, 0);
+ copyRectToScreen(upperRect, blackoutFlag); upperRect.translate(0, 1); upperRect.left++; upperRect.right--;
+ copyRectToScreen(lowerRect, blackoutFlag); lowerRect.translate(0, -1); lowerRect.left++; lowerRect.right--;
+ copyRectToScreen(leftRect, blackoutFlag); leftRect.translate(1, 0);
+ copyRectToScreen(rightRect, blackoutFlag); rightRect.translate(-1, 0);
g_system->updateScreen();
g_system->delayMillis(3);
}
diff --git a/engines/sci/gui/gui_transitions.h b/engines/sci/gui/gui_transitions.h
index 2ae2a934e2..b4344543f0 100644
--- a/engines/sci/gui/gui_transitions.h
+++ b/engines/sci/gui/gui_transitions.h
@@ -31,8 +31,8 @@
namespace Sci {
struct GuiTransitionTranslateEntry {
- int16 oldId;
- int16 realId;
+ int16 orgId;
+ int16 newId;
bool blackoutFlag;
};
@@ -70,20 +70,23 @@ public:
private:
void init(void);
- void setNewPalette();
- void setNewScreen();
+ const GuiTransitionTranslateEntry *translateNumber(int16 number, const GuiTransitionTranslateEntry *tablePtr);
+ void doTransition(int16 number, bool blackout);
+ void setNewPalette(bool blackoutFlag);
+ void setNewScreen(bool blackoutFlag);
+ void copyRectToScreen(const Common::Rect rect, bool blackoutFlag);
void fadeOut();
void fadeIn();
- void pixelation();
- void blocks();
- void straight(int16 number);
+ void pixelation(bool blackoutFlag);
+ void blocks(bool blackoutFlag);
+ void straight(int16 number, bool blackoutFlag);
void scroll(int16 number);
- void verticalRollFromCenter();
- void verticalRollToCenter();
- void horizontalRollFromCenter();
- void horizontalRollToCenter();
- void diagonalRollFromCenter();
- void diagonalRollToCenter();
+ void verticalRollFromCenter(bool blackoutFlag);
+ void verticalRollToCenter(bool blackoutFlag);
+ void horizontalRollFromCenter(bool blackoutFlag);
+ void horizontalRollToCenter(bool blackoutFlag);
+ void diagonalRollFromCenter(bool blackoutFlag);
+ void diagonalRollToCenter(bool blackoutFlag);
SciGui *_gui;
SciGuiScreen *_screen;