diff options
Diffstat (limited to 'engines/sci/graphics')
-rw-r--r-- | engines/sci/graphics/paint16.cpp | 19 | ||||
-rw-r--r-- | engines/sci/graphics/portrait.cpp | 63 | ||||
-rw-r--r-- | engines/sci/graphics/screen.cpp | 17 | ||||
-rw-r--r-- | engines/sci/graphics/screen.h | 1 | ||||
-rw-r--r-- | engines/sci/graphics/transitions.cpp | 62 | ||||
-rw-r--r-- | engines/sci/graphics/transitions.h | 1 |
6 files changed, 120 insertions, 43 deletions
diff --git a/engines/sci/graphics/paint16.cpp b/engines/sci/graphics/paint16.cpp index f80703e14d..6004e9ce7a 100644 --- a/engines/sci/graphics/paint16.cpp +++ b/engines/sci/graphics/paint16.cpp @@ -471,9 +471,6 @@ void GfxPaint16::kernelGraphRedrawBox(Common::Rect rect) { #define SCI_DISPLAY_WIDTH 106 #define SCI_DISPLAY_SAVEUNDER 107 #define SCI_DISPLAY_RESTOREUNDER 108 -#define SCI_DISPLAY_DUMMY1 114 -#define SCI_DISPLAY_DUMMY2 115 -#define SCI_DISPLAY_DUMMY3 117 #define SCI_DISPLAY_DONTSHOWBITS 121 reg_t GfxPaint16::kernelDisplay(const char *text, uint16 languageSplitter, int argc, reg_t *argv) { @@ -543,22 +540,6 @@ reg_t GfxPaint16::kernelDisplay(const char *text, uint16 languageSplitter, int a bRedraw = 0; break; - // The following three dummy calls are not supported by the Sierra SCI - // interpreter, but are erroneously called in some game scripts. - case SCI_DISPLAY_DUMMY1: // Longbow demo (all rooms) and QFG1 EGA demo (room 11) - case SCI_DISPLAY_DUMMY2: // Longbow demo (all rooms) - case SCI_DISPLAY_DUMMY3: // QFG1 EGA demo (room 11) and PQ2 (room 23) - if (!(g_sci->getGameId() == GID_LONGBOW && g_sci->isDemo()) && - !(g_sci->getGameId() == GID_QFG1 && g_sci->isDemo()) && - !(g_sci->getGameId() == GID_PQ2)) - error("Unknown kDisplay argument %d", displayArg.getOffset()); - - if (displayArg.getOffset() == SCI_DISPLAY_DUMMY2) { - if (!argc) - error("No parameter left for kDisplay(115)"); - argc--; argv++; - } - break; default: SciTrackOriginReply originReply; SciWorkaroundSolution solution = trackOriginAndFindWorkaround(0, kDisplay_workarounds, &originReply); diff --git a/engines/sci/graphics/portrait.cpp b/engines/sci/graphics/portrait.cpp index 668de616fb..cb425f3be9 100644 --- a/engines/sci/graphics/portrait.cpp +++ b/engines/sci/graphics/portrait.cpp @@ -57,13 +57,39 @@ void Portrait::init() { // 4 bytes paletteSize (base 1) // -> 17 bytes // paletteSize bytes paletteData - // 14 bytes bitmap header - // -> 4 bytes unknown - // -> 2 bytes height - // -> 2 bytes width - // -> 6 bytes unknown - // height * width bitmap data - // another animation count times bitmap header and data + // + // bitmap-data follows, total of [animation count] + // 14 bytes bitmap header + // -> 4 bytes unknown + // -> 2 bytes height + // -> 2 bytes width + // -> 6 bytes unknown + // height * width bitmap data + // + // 4 bytes offset table size (may be larger than the actual known entries?!) + // 14 bytes all zeroes (dummy entry?!) + // + // 14 bytes for each entry + // -> 2 bytes displace X + // -> 2 bytes displace Y + // -> 2 bytes height (again) + // -> 2 bytes width (again) + // -> 6 bytes unknown (normally 01 00 00 00 00 00 for delta bitmaps, 00 00 00 00 00 00 for first bitmap) + // random data may be used as filler + // + // 4 bytes lip sync id table size (is [lip sync id count] * 4, should be 0x2E0 for all actors) + // 4 bytes per lip sync id + // -> 1 byte length of ID + // -> 3 bytes actual ID + // + // 4 bytes lip sync id data table size (seems to be the same for all actors, always 0x220 in size) + // 1 byte animation number or 0xFF as terminator + // 1 byte delay, if last byte was not terminator + // one array for every lip sync id + // + // 4 bytes appended, seem to be random + // 9E11120E for alex + // 9E9E9E9E for vizier int32 fileSize = 0; Common::SeekableReadStream *file = SearchMan.createReadStreamForMember("actors/" + _resourceName + ".bin"); @@ -202,8 +228,9 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint if (raveResource->size < 4000) { memcpy(debugPrint, raveResource->data, raveResource->size); debugPrint[raveResource->size] = 0; // set terminating NUL + debug("kPortrait: using actor %s", _resourceName.c_str()); debug("kPortrait (noun %d, verb %d, cond %d, seq %d)", noun, verb, cond, seq); - debug("kPortrait: %s", debugPrint); + debug("kPortrait: rave data is '%s'", debugPrint); } #endif @@ -273,6 +300,14 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint raveLipSyncData = NULL; } +#ifdef DEBUG_PORTRAIT + if (raveID & 0x0ff) { + debug("kPortrait: rave '%c%c' after %d ticks", raveID >> 8, raveID & 0x0ff, raveTicks); + } else if (raveID) { + debug("kPortrait: rave '%c' after %d ticks", raveID >> 8, raveTicks); + } +#endif + timerPosition += raveTicks; // Wait till syncTime passed, then show specific animation bitmap @@ -282,7 +317,8 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint curEvent = _event->getSciEvent(SCI_EVENT_ANY); if (curEvent.type == SCI_EVENT_MOUSE_PRESS || (curEvent.type == SCI_EVENT_KEYBOARD && curEvent.data == SCI_KEY_ESC) || - g_sci->getEngineState()->abortScriptProcessing == kAbortQuitGame) + g_sci->getEngineState()->abortScriptProcessing == kAbortQuitGame || + g_sci->getEngineState()->_delayedRestoreGame) userAbort = true; curPosition = _audio->getAudioPosition(); } while ((curPosition != -1) && (curPosition < timerPosition) && (!userAbort)); @@ -295,6 +331,8 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint timerPositionWithin = timerPosition; raveLipSyncTicks = *raveLipSyncData++; while ( (raveLipSyncData < _lipSyncDataOffsetTableEnd) && (raveLipSyncTicks != 0xFF) ) { + if (raveLipSyncTicks) + raveLipSyncTicks--; // 1 -> wait 0 ticks, 2 -> wait 1 tick, etc. timerPositionWithin += raveLipSyncTicks; do { @@ -308,6 +346,13 @@ void Portrait::doit(Common::Point position, uint16 resourceId, uint16 noun, uint } while ((curPosition != -1) && (curPosition < timerPositionWithin) && (!userAbort)); raveLipSyncBitmapNr = *raveLipSyncData++; +#ifdef DEBUG_PORTRAIT + if (!raveLipSyncTicks) { + debug("kPortrait: showing frame %d", raveLipSyncBitmapNr); + } else { + debug("kPortrait: showing frame %d after %d ticks", raveLipSyncBitmapNr, raveLipSyncTicks); + } +#endif // bitmap nr within sync data is base 1, we need base 0 raveLipSyncBitmapNr--; diff --git a/engines/sci/graphics/screen.cpp b/engines/sci/graphics/screen.cpp index 8b0e76332f..ca5b5b3b8c 100644 --- a/engines/sci/graphics/screen.cpp +++ b/engines/sci/graphics/screen.cpp @@ -81,7 +81,8 @@ GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) { case GID_LSL1: case GID_LSL5: case GID_SQ1: - _width = 190; + _scriptHeight = 190; + break; default: break; } @@ -238,6 +239,8 @@ GfxScreen::GfxScreen(ResourceManager *resMan) : _resMan(resMan) { _vectorPutPixelPtr = &GfxScreen::putPixelDisplayUpscaled; _putPixelPtr = &GfxScreen::putPixelDisplayUpscaled; break; + case GFX_SCREEN_UPSCALED_DISABLED: + break; } } @@ -248,6 +251,18 @@ GfxScreen::~GfxScreen() { free(_displayScreen); } +// should not be used regularly; only meant for restore game +void GfxScreen::clearForRestoreGame() { + // reset all screen data + memset(_visualScreen, 0, _pixels); + memset(_priorityScreen, 0, _pixels); + memset(_controlScreen, 0, _pixels); + memset(_displayScreen, 0, _displayPixels); + memset(&_ditheredPicColors, 0, sizeof(_ditheredPicColors)); + _fontIsUpscaled = false; + copyToScreen(); +} + void GfxScreen::copyToScreen() { g_system->copyRectToScreen(_activeScreen, _displayWidth, 0, 0, _displayWidth, _displayHeight); } diff --git a/engines/sci/graphics/screen.h b/engines/sci/graphics/screen.h index 766e32614a..1c946ef02f 100644 --- a/engines/sci/graphics/screen.h +++ b/engines/sci/graphics/screen.h @@ -76,6 +76,7 @@ public: byte getColorWhite() { return _colorWhite; } byte getColorDefaultVectorData() { return _colorDefaultVectorData; } + void clearForRestoreGame(); void copyToScreen(); void copyFromScreen(byte *buffer); void kernelSyncWithFramebuffer(); diff --git a/engines/sci/graphics/transitions.cpp b/engines/sci/graphics/transitions.cpp index ccc7a4389a..c75580a077 100644 --- a/engines/sci/graphics/transitions.cpp +++ b/engines/sci/graphics/transitions.cpp @@ -124,6 +124,10 @@ void GfxTransitions::setup(int16 number, bool blackoutFlag) { } } +// Checks, if current time is lower than expected time of the current frame +// If current time is higher, then we have to assume that the current system isn't capable +// of either rendering frames that fast or has 60hz V'Sync enabled, which is why we drop frames +// in those cases, so that transitions work as fast as expected. bool GfxTransitions::doCreateFrame(uint32 shouldBeAtMsec) { uint32 msecPos = g_system->getMillis() - _transitionStartTime; @@ -132,12 +136,16 @@ bool GfxTransitions::doCreateFrame(uint32 shouldBeAtMsec) { return false; } -void GfxTransitions::updateScreenAndWait(uint32 shouldBeAtMsec) { +void GfxTransitions::updateScreen() { Common::Event ev; while (g_system->getEventManager()->pollEvent(ev)) {} // discard all events g_system->updateScreen(); +} + +void GfxTransitions::updateScreenAndWait(uint32 shouldBeAtMsec) { + updateScreen(); // if we have still some time left, delay accordingly uint32 msecPos = g_system->getMillis() - _transitionStartTime; if (shouldBeAtMsec > msecPos) @@ -257,6 +265,9 @@ void GfxTransitions::doTransition(int16 number, bool blackoutFlag) { warning("Transitions: ID %d not implemented", number); setNewScreen(blackoutFlag); } + // Just to make sure that the current frame is shown in case we skipped the last update-call b/c of timing + updateScreen(); + debugC(kDebugLevelGraphics, "Transition took %d milliseconds", g_system->getMillis() - _transitionStartTime); } void GfxTransitions::setNewPalette(bool blackoutFlag) { @@ -348,7 +359,9 @@ void GfxTransitions::pixelation(bool blackoutFlag) { copyRectToScreen(pixelRect, blackoutFlag); if ((stepNr & 0x3FF) == 0) { msecCount += 9; - updateScreenAndWait(msecCount); + if (doCreateFrame(msecCount)) { + updateScreenAndWait(msecCount); + } } stepNr++; } while (mask != 0x40); @@ -372,7 +385,9 @@ void GfxTransitions::blocks(bool blackoutFlag) { copyRectToScreen(blockRect, blackoutFlag); if ((stepNr & 7) == 0) { msecCount += 5; - updateScreenAndWait(msecCount); + if (doCreateFrame(msecCount)) { + updateScreenAndWait(msecCount); + } } stepNr++; } while (mask != 0x40); @@ -392,7 +407,9 @@ void GfxTransitions::straight(int16 number, bool blackoutFlag) { copyRectToScreen(newScreenRect, blackoutFlag); if ((stepNr & 1) == 0) { msecCount += 2; - updateScreenAndWait(msecCount); + if (doCreateFrame(msecCount)) { + updateScreenAndWait(msecCount); + } } stepNr++; newScreenRect.translate(-1, 0); @@ -405,7 +422,9 @@ void GfxTransitions::straight(int16 number, bool blackoutFlag) { copyRectToScreen(newScreenRect, blackoutFlag); if ((stepNr & 1) == 0) { msecCount += 2; - updateScreenAndWait(msecCount); + if (doCreateFrame(msecCount)) { + updateScreenAndWait(msecCount); + } } stepNr++; newScreenRect.translate(1, 0); @@ -417,7 +436,9 @@ void GfxTransitions::straight(int16 number, bool blackoutFlag) { while (newScreenRect.top >= _picRect.top) { copyRectToScreen(newScreenRect, blackoutFlag); msecCount += 4; - updateScreenAndWait(msecCount); + if (doCreateFrame(msecCount)) { + updateScreenAndWait(msecCount); + } stepNr++; newScreenRect.translate(0, -1); } @@ -428,7 +449,9 @@ void GfxTransitions::straight(int16 number, bool blackoutFlag) { while (newScreenRect.bottom <= _picRect.bottom) { copyRectToScreen(newScreenRect, blackoutFlag); msecCount += 4; - updateScreenAndWait(msecCount); + if (doCreateFrame(msecCount)) { + updateScreenAndWait(msecCount); + } stepNr++; newScreenRect.translate(0, 1); } @@ -534,7 +557,6 @@ void GfxTransitions::scroll(int16 number) { // Copy over final position just in case _screen->copyRectToScreen(newScreenRect); - g_system->updateScreen(); } // Vertically displays new screen starting from center - works on _picRect area @@ -552,7 +574,9 @@ void GfxTransitions::verticalRollFromCenter(bool blackoutFlag) { copyRectToScreen(leftRect, blackoutFlag); leftRect.translate(-1, 0); copyRectToScreen(rightRect, blackoutFlag); rightRect.translate(1, 0); msecCount += 3; - updateScreenAndWait(msecCount); + if (doCreateFrame(msecCount)) { + updateScreenAndWait(msecCount); + } } } @@ -567,7 +591,9 @@ void GfxTransitions::verticalRollToCenter(bool blackoutFlag) { copyRectToScreen(leftRect, blackoutFlag); leftRect.translate(1, 0); copyRectToScreen(rightRect, blackoutFlag); rightRect.translate(-1, 0); msecCount += 3; - updateScreenAndWait(msecCount); + if (doCreateFrame(msecCount)) { + updateScreenAndWait(msecCount); + } } } @@ -586,7 +612,9 @@ void GfxTransitions::horizontalRollFromCenter(bool blackoutFlag) { copyRectToScreen(upperRect, blackoutFlag); upperRect.translate(0, -1); copyRectToScreen(lowerRect, blackoutFlag); lowerRect.translate(0, 1); msecCount += 4; - updateScreenAndWait(msecCount); + if (doCreateFrame(msecCount)) { + updateScreenAndWait(msecCount); + } } } @@ -601,7 +629,9 @@ void GfxTransitions::horizontalRollToCenter(bool blackoutFlag) { copyRectToScreen(upperRect, blackoutFlag); upperRect.translate(0, 1); copyRectToScreen(lowerRect, blackoutFlag); lowerRect.translate(0, -1); msecCount += 4; - updateScreenAndWait(msecCount); + if (doCreateFrame(msecCount)) { + updateScreenAndWait(msecCount); + } } } @@ -633,7 +663,9 @@ void GfxTransitions::diagonalRollFromCenter(bool blackoutFlag) { copyRectToScreen(leftRect, blackoutFlag); leftRect.translate(-1, 0); leftRect.top--; leftRect.bottom++; copyRectToScreen(rightRect, blackoutFlag); rightRect.translate(1, 0); rightRect.top--; rightRect.bottom++; msecCount += 4; - updateScreenAndWait(msecCount); + if (doCreateFrame(msecCount)) { + updateScreenAndWait(msecCount); + } } } @@ -652,7 +684,9 @@ void GfxTransitions::diagonalRollToCenter(bool blackoutFlag) { copyRectToScreen(leftRect, blackoutFlag); leftRect.translate(1, 0); copyRectToScreen(rightRect, blackoutFlag); rightRect.translate(-1, 0); msecCount += 4; - updateScreenAndWait(msecCount); + if (doCreateFrame(msecCount)) { + updateScreenAndWait(msecCount); + } } } diff --git a/engines/sci/graphics/transitions.h b/engines/sci/graphics/transitions.h index ae9ca4b48a..05842a4d2a 100644 --- a/engines/sci/graphics/transitions.h +++ b/engines/sci/graphics/transitions.h @@ -89,6 +89,7 @@ private: void diagonalRollFromCenter(bool blackoutFlag); void diagonalRollToCenter(bool blackoutFlag); bool doCreateFrame(uint32 shouldBeAtMsec); + void updateScreen(); void updateScreenAndWait(uint32 shouldBeAtMsec); GfxScreen *_screen; |