mirror of
https://github.com/libretro/scummvm.git
synced 2025-04-07 17:22:02 +00:00
MOHAWK: Add initial support for the Riven credits sequence
The credits start too early for a few of the end game sequences, but otherwise works well (minus missing fade support, but that is throughout the game anyway).
This commit is contained in:
parent
cd816b24d7
commit
8743838f47
@ -246,6 +246,13 @@ void GraphicsManager::copyAnimImageSectionToScreen(MohawkSurface *image, Common:
|
|||||||
getVM()->_system->unlockScreen();
|
getVM()->_system->unlockScreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GraphicsManager::addImageToCache(uint16 id, MohawkSurface *surface) {
|
||||||
|
if (_cache.contains(id))
|
||||||
|
error("Image %d already in cache", id);
|
||||||
|
|
||||||
|
_cache[id] = surface;
|
||||||
|
}
|
||||||
|
|
||||||
MystGraphics::MystGraphics(MohawkEngine_Myst* vm) : GraphicsManager(), _vm(vm) {
|
MystGraphics::MystGraphics(MohawkEngine_Myst* vm) : GraphicsManager(), _vm(vm) {
|
||||||
_bmpDecoder = new MystBitmap();
|
_bmpDecoder = new MystBitmap();
|
||||||
|
|
||||||
@ -630,6 +637,9 @@ RivenGraphics::RivenGraphics(MohawkEngine_Riven* vm) : GraphicsManager(), _vm(vm
|
|||||||
_scheduledTransition = -1; // no transition
|
_scheduledTransition = -1; // no transition
|
||||||
_dirtyScreen = false;
|
_dirtyScreen = false;
|
||||||
_inventoryDrawn = false;
|
_inventoryDrawn = false;
|
||||||
|
|
||||||
|
_creditsImage = 302;
|
||||||
|
_creditsPos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
RivenGraphics::~RivenGraphics() {
|
RivenGraphics::~RivenGraphics() {
|
||||||
@ -840,6 +850,17 @@ void RivenGraphics::runScheduledTransition() {
|
|||||||
_scheduledTransition = -1; // Clear scheduled transition
|
_scheduledTransition = -1; // Clear scheduled transition
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RivenGraphics::clearMainScreen() {
|
||||||
|
_mainScreen->fillRect(Common::Rect(0, 0, 608, 392), _pixelFormat.RGBToColor(0, 0, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
void RivenGraphics::fadeToBlack() {
|
||||||
|
// Self-explanatory
|
||||||
|
scheduleTransition(16);
|
||||||
|
clearMainScreen();
|
||||||
|
runScheduledTransition();
|
||||||
|
}
|
||||||
|
|
||||||
void RivenGraphics::showInventory() {
|
void RivenGraphics::showInventory() {
|
||||||
// Don't redraw the inventory
|
// Don't redraw the inventory
|
||||||
if (_inventoryDrawn)
|
if (_inventoryDrawn)
|
||||||
@ -955,6 +976,60 @@ void RivenGraphics::drawExtrasImage(uint16 id, Common::Rect dstRect) {
|
|||||||
_dirtyScreen = true;
|
_dirtyScreen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RivenGraphics::beginCredits() {
|
||||||
|
// Clear the old cache
|
||||||
|
clearCache();
|
||||||
|
|
||||||
|
// Now cache all the credits images
|
||||||
|
for (uint16 i = 302; i <= 320; i++) {
|
||||||
|
MohawkSurface *surface = _bitmapDecoder->decodeImage(_vm->getExtrasResource(ID_TBMP, i));
|
||||||
|
surface->convertToTrueColor();
|
||||||
|
addImageToCache(i, surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
// And clear our screen too
|
||||||
|
clearMainScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RivenGraphics::updateCredits() {
|
||||||
|
if ((_creditsImage == 303 || _creditsImage == 304) && _creditsPos == 0)
|
||||||
|
fadeToBlack();
|
||||||
|
|
||||||
|
if (_creditsImage < 304) {
|
||||||
|
// For the first two credit images, they are faded from black to the image and then out again
|
||||||
|
scheduleTransition(16);
|
||||||
|
|
||||||
|
Graphics::Surface *frame = findImage(_creditsImage++)->getSurface();
|
||||||
|
|
||||||
|
for (int y = 0; y < frame->h; y++)
|
||||||
|
memcpy(_mainScreen->getBasePtr(124, y), frame->getBasePtr(0, y), frame->pitch);
|
||||||
|
|
||||||
|
runScheduledTransition();
|
||||||
|
} else {
|
||||||
|
// Otheriwse, we're scrolling
|
||||||
|
// Move the screen up one row
|
||||||
|
memmove(_mainScreen->pixels, _mainScreen->getBasePtr(0, 1), _mainScreen->pitch * (_mainScreen->h - 1));
|
||||||
|
|
||||||
|
// Only update as long as we're not before the last frame
|
||||||
|
// Otherwise, we're just moving up a row (which we already did)
|
||||||
|
if (_creditsImage <= 320) {
|
||||||
|
// Copy the next row to the bottom of the screen
|
||||||
|
Graphics::Surface *frame = findImage(_creditsImage)->getSurface();
|
||||||
|
memcpy(_mainScreen->getBasePtr(124, _mainScreen->h - 1), frame->getBasePtr(0, _creditsPos), frame->pitch);
|
||||||
|
_creditsPos++;
|
||||||
|
|
||||||
|
if (_creditsPos == _mainScreen->h) {
|
||||||
|
_creditsImage++;
|
||||||
|
_creditsPos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now flush the new screen
|
||||||
|
_vm->_system->copyRectToScreen((byte *)_mainScreen->pixels, _mainScreen->pitch, 0, 0, _mainScreen->w, _mainScreen->h);
|
||||||
|
_vm->_system->updateScreen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
LBGraphics::LBGraphics(MohawkEngine_LivingBooks *vm, uint16 width, uint16 height) : GraphicsManager(), _vm(vm) {
|
LBGraphics::LBGraphics(MohawkEngine_LivingBooks *vm, uint16 width, uint16 height) : GraphicsManager(), _vm(vm) {
|
||||||
_bmpDecoder = _vm->isPreMohawk() ? new OldMohawkBitmap() : new MohawkBitmap();
|
_bmpDecoder = _vm->isPreMohawk() ? new OldMohawkBitmap() : new MohawkBitmap();
|
||||||
|
|
||||||
|
@ -110,6 +110,7 @@ protected:
|
|||||||
virtual Common::Array<MohawkSurface *> decodeImages(uint16 id);
|
virtual Common::Array<MohawkSurface *> decodeImages(uint16 id);
|
||||||
|
|
||||||
virtual MohawkEngine *getVM() = 0;
|
virtual MohawkEngine *getVM() = 0;
|
||||||
|
void addImageToCache(uint16 id, MohawkSurface *surface);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// An image cache that stores images until clearCache() is called
|
// An image cache that stores images until clearCache() is called
|
||||||
@ -195,11 +196,17 @@ public:
|
|||||||
// Transitions
|
// Transitions
|
||||||
void scheduleTransition(uint16 id, Common::Rect rect = Common::Rect(0, 0, 608, 392));
|
void scheduleTransition(uint16 id, Common::Rect rect = Common::Rect(0, 0, 608, 392));
|
||||||
void runScheduledTransition();
|
void runScheduledTransition();
|
||||||
|
void fadeToBlack();
|
||||||
|
|
||||||
// Inventory
|
// Inventory
|
||||||
void showInventory();
|
void showInventory();
|
||||||
void hideInventory();
|
void hideInventory();
|
||||||
|
|
||||||
|
// Credits
|
||||||
|
void beginCredits();
|
||||||
|
void updateCredits();
|
||||||
|
uint getCurCreditsImage() { return _creditsImage; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MohawkSurface *decodeImage(uint16 id);
|
MohawkSurface *decodeImage(uint16 id);
|
||||||
MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
|
MohawkEngine *getVM() { return (MohawkEngine *)_vm; }
|
||||||
@ -224,6 +231,10 @@ private:
|
|||||||
Graphics::Surface *_mainScreen;
|
Graphics::Surface *_mainScreen;
|
||||||
bool _dirtyScreen;
|
bool _dirtyScreen;
|
||||||
Graphics::PixelFormat _pixelFormat;
|
Graphics::PixelFormat _pixelFormat;
|
||||||
|
void clearMainScreen();
|
||||||
|
|
||||||
|
// Credits
|
||||||
|
uint _creditsImage, _creditsPos;
|
||||||
};
|
};
|
||||||
|
|
||||||
class LBGraphics : public GraphicsManager {
|
class LBGraphics : public GraphicsManager {
|
||||||
|
@ -223,13 +223,27 @@ void RivenExternal::runEndGame(uint16 video) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RivenExternal::runCredits(uint16 video) {
|
void RivenExternal::runCredits(uint16 video) {
|
||||||
// TODO: Play until the last frame and then run the credits
|
// Initialize our credits state
|
||||||
|
_vm->_cursor->hideCursor();
|
||||||
|
_vm->_gfx->beginCredits();
|
||||||
|
uint nextCreditsFrameStart = 0;
|
||||||
|
|
||||||
VideoHandle videoHandle = _vm->_video->findVideoHandleRiven(video);
|
VideoHandle videoHandle = _vm->_video->findVideoHandleRiven(video);
|
||||||
|
|
||||||
while (!_vm->_video->endOfVideo(videoHandle) && !_vm->shouldQuit()) {
|
while (!_vm->shouldQuit() && _vm->_gfx->getCurCreditsImage() <= 320) {
|
||||||
if (_vm->_video->updateMovies())
|
if (_vm->_video->getCurFrame(videoHandle) >= (int32)_vm->_video->getFrameCount(videoHandle) - 1) {
|
||||||
_vm->_system->updateScreen();
|
if (_vm->_system->getMillis() >= nextCreditsFrameStart) {
|
||||||
|
// the first two frames stay on for 5 seconds
|
||||||
|
// the rest of the scroll updates happen at 30Hz
|
||||||
|
if (_vm->_gfx->getCurCreditsImage() < 304)
|
||||||
|
nextCreditsFrameStart = _vm->_system->getMillis() + 5000;
|
||||||
|
else
|
||||||
|
nextCreditsFrameStart = _vm->_system->getMillis() + 1000 / 30;
|
||||||
|
|
||||||
|
_vm->_gfx->updateCredits();
|
||||||
|
}
|
||||||
|
} else if (_vm->_video->updateMovies())
|
||||||
|
_vm->_system->updateScreen();
|
||||||
|
|
||||||
Common::Event event;
|
Common::Event event;
|
||||||
while (_vm->_system->getEventManager()->pollEvent(event))
|
while (_vm->_system->getEventManager()->pollEvent(event))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user