ResidualVM logo ResidualVM website - Forums - Contact us BuildBot - Doxygen - Wiki curved edge

transition.cpp

Go to the documentation of this file.
00001 /* ResidualVM - A 3D game interpreter
00002  *
00003  * ResidualVM is the legal property of its developers, whose names
00004  * are too numerous to list here. Please refer to the AUTHORS
00005  * file distributed with this source distribution.
00006  *
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  *
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020  *
00021  */
00022 
00023 #include "common/events.h"
00024 #include "common/config-manager.h"
00025 
00026 #include "engines/myst3/transition.h"
00027 #include "engines/myst3/sound.h"
00028 #include "engines/myst3/state.h"
00029 
00030 #include "graphics/colormasks.h"
00031 #include "graphics/surface.h"
00032 
00033 namespace Myst3 {
00034 
00035 Transition::Transition(Myst3Engine *vm) :
00036         _vm(vm),
00037         _type(kTransitionNone),
00038         _sourceScreenshot(nullptr),
00039         _frameLimiter(new FrameLimiter(g_system, ConfMan.getInt("engine_speed"))) {
00040 
00041     // Capture a screenshot of the source node
00042     int durationTicks = computeDuration();
00043     if (durationTicks) {
00044         _sourceScreenshot = _vm->_gfx->copyScreenshotToTexture();
00045     }
00046 }
00047 
00048 Transition::~Transition() {
00049     _vm->_gfx->freeTexture(_sourceScreenshot);
00050 
00051     delete _frameLimiter;
00052 }
00053 
00054 int Transition::computeDuration() {
00055     int durationTicks = 30 * (100 - ConfMan.getInt("transition_speed")) / 100;
00056     if (_type == kTransitionZip) {
00057         durationTicks >>= 1;
00058     }
00059 
00060     return durationTicks;
00061 }
00062 
00063 void Transition::playSound() {
00064     if (_vm->_state->getTransitionSound()) {
00065         _vm->_sound->playEffect(_vm->_state->getTransitionSound(),
00066                 _vm->_state->getTransitionSoundVolume());
00067     }
00068     _vm->_state->setTransitionSound(0);
00069 }
00070 
00071 void Transition::draw(TransitionType type) {
00072     _type = type;
00073 
00074     // Play the transition sound
00075     playSound();
00076 
00077     int durationTicks = computeDuration();
00078 
00079     // Got any transition to draw?
00080     if (!_sourceScreenshot || type == kTransitionNone || durationTicks == 0) {
00081         return;
00082     }
00083 
00084     // Capture a screenshot of the destination node
00085     _vm->drawFrame(true);
00086     Texture *targetScreenshot = _vm->_gfx->copyScreenshotToTexture();
00087 
00088     // Compute the start and end frames for the animation
00089     int startTick = _vm->_state->getTickCount();
00090     uint endTick = startTick + durationTicks;
00091 
00092     // Draw on the full screen
00093     _vm->_gfx->selectTargetWindow(nullptr, false, false);
00094 
00095     // Draw each step until completion
00096     int completion = 0;
00097     while ((_vm->_state->getTickCount() <= endTick || completion < 100) && !_vm->shouldQuit()) {
00098         _frameLimiter->startFrame();
00099 
00100         completion = CLIP<int>(100 * (_vm->_state->getTickCount() - startTick) / durationTicks, 0, 100);
00101 
00102         _vm->_gfx->clear();
00103 
00104         drawStep(targetScreenshot, _sourceScreenshot, completion);
00105 
00106         _vm->_gfx->flipBuffer();
00107         _frameLimiter->delayBeforeSwap();
00108         g_system->updateScreen();
00109         _vm->_state->updateFrameCounters();
00110 
00111         Common::Event event;
00112         while (_vm->getEventManager()->pollEvent(event)) {
00113             // Ignore all the events happening during transitions, so that the view does not move
00114             // between the initial transition screen shoot and the first frame drawn after the transition.
00115 
00116             // However, keep updating the keyboard state so we don't end up in
00117             // an unbalanced state where the engine believes keys are still
00118             // pressed while they are not.
00119             _vm->processEventForKeyboardState(event);
00120 
00121             if (_vm->_state->hasVarGamePadUpPressed()) {
00122                 _vm->processEventForGamepad(event);
00123             }
00124         }
00125     }
00126 
00127     _vm->_gfx->freeTexture(targetScreenshot);
00128     _vm->_gfx->freeTexture(_sourceScreenshot);
00129     _sourceScreenshot = nullptr;
00130 }
00131 
00132 void Transition::drawStep(Texture *targetTexture, Texture *sourceTexture, uint completion) {
00133     Common::Rect viewport = _vm->_gfx->viewport();
00134 
00135     switch (_type) {
00136     case kTransitionNone:
00137         break;
00138 
00139     case kTransitionFade:
00140     case kTransitionZip: {
00141             Common::Rect textureRect = Common::Rect(sourceTexture->width, sourceTexture->height);
00142             _vm->_gfx->drawTexturedRect2D(viewport, textureRect, sourceTexture);
00143             _vm->_gfx->drawTexturedRect2D(viewport, textureRect, targetTexture, completion / 100.0);
00144         }
00145         break;
00146 
00147     case kTransitionLeftToRight: {
00148             int16 transitionX = (viewport.width() * (100 - completion)) / 100;
00149             Common::Rect sourceTextureRect(0, 0, transitionX, sourceTexture->height);
00150             Common::Rect sourceScreenRect(sourceTextureRect.width(), sourceTextureRect.height());
00151             sourceScreenRect.translate(viewport.left, viewport.top);
00152 
00153             Common::Rect targetTextureRect(transitionX, 0, targetTexture->width, targetTexture->height);
00154             Common::Rect targetScreenRect(targetTextureRect.width(), targetTextureRect.height());
00155             targetScreenRect.translate(viewport.left + transitionX, viewport.top);
00156 
00157             _vm->_gfx->drawTexturedRect2D(sourceScreenRect, sourceTextureRect, sourceTexture);
00158             _vm->_gfx->drawTexturedRect2D(targetScreenRect, targetTextureRect, targetTexture);
00159         }
00160         break;
00161 
00162     case kTransitionRightToLeft: {
00163             int16 transitionX = viewport.width() * completion / 100;
00164             Common::Rect sourceTextureRect(transitionX, 0, sourceTexture->width, sourceTexture->height);
00165             Common::Rect sourceScreenRect(sourceTextureRect.width(), sourceTextureRect.height());
00166             sourceScreenRect.translate(viewport.left + transitionX, viewport.top);
00167 
00168             Common::Rect targetTextureRect(0, 0, transitionX, targetTexture->height);
00169             Common::Rect targetScreenRect(targetTextureRect.width(), targetTextureRect.height());
00170             targetScreenRect.translate(viewport.left, viewport.top);
00171 
00172             _vm->_gfx->drawTexturedRect2D(sourceScreenRect, sourceTextureRect, sourceTexture);
00173             _vm->_gfx->drawTexturedRect2D(targetScreenRect, targetTextureRect, targetTexture);
00174         }
00175         break;
00176     }
00177 }
00178 
00179 } // End of namespace Myst3


Generated on Sat Aug 8 2020 05:01:15 for ResidualVM by doxygen 1.7.1
curved edge   curved edge