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     int transitionSpeed = ConfMan.getInt("transition_speed");
00042 
00043     // Capture a screenshot of the source node
00044     if (transitionSpeed != 100) {
00045         _sourceScreenshot = _vm->_gfx->getScreenshot();
00046     }
00047 }
00048 
00049 Transition::~Transition() {
00050     if (_sourceScreenshot) {
00051         _sourceScreenshot->free();
00052         delete _sourceScreenshot;
00053     }
00054 
00055     delete _frameLimiter;
00056 }
00057 
00058 int Transition::computeDuration() {
00059     int durationTicks = 30 * (100 - ConfMan.getInt("transition_speed")) / 100;
00060     if (_type == kTransitionZip) {
00061         durationTicks >>= 1;
00062     }
00063 
00064     return durationTicks;
00065 }
00066 
00067 void Transition::playSound() {
00068     if (_vm->_state->getTransitionSound()) {
00069         _vm->_sound->playEffect(_vm->_state->getTransitionSound(),
00070                 _vm->_state->getTransitionSoundVolume());
00071     }
00072     _vm->_state->setTransitionSound(0);
00073 }
00074 
00075 void Transition::draw(TransitionType type) {
00076     _type = type;
00077 
00078     // Play the transition sound
00079     playSound();
00080 
00081     int durationTicks = computeDuration();
00082 
00083     // Got any transition to draw?
00084     if (!_sourceScreenshot || type == kTransitionNone || durationTicks == 0) {
00085         return;
00086     }
00087 
00088     // Capture a screenshot of the destination node
00089     _vm->drawFrame(true);
00090     Graphics::Surface *target = _vm->_gfx->getScreenshot();
00091 
00092     Texture *sourceTexture = _vm->_gfx->createTexture(_sourceScreenshot);
00093     Texture *targetTexture = _vm->_gfx->createTexture(target);
00094 
00095     target->free();
00096     delete target;
00097 
00098     // Compute the start and end frames for the animation
00099     int startTick = _vm->_state->getTickCount();
00100     uint endTick = startTick + durationTicks;
00101 
00102     // Draw on the full screen
00103     _vm->_gfx->selectTargetWindow(nullptr, false, false);
00104 
00105     // Draw each step until completion
00106     int completion = 0;
00107     while ((_vm->_state->getTickCount() <= endTick || completion < 100) && !_vm->shouldQuit()) {
00108         _frameLimiter->startFrame();
00109 
00110         completion = CLIP<int>(100 * (_vm->_state->getTickCount() - startTick) / durationTicks, 0, 100);
00111 
00112         drawStep(targetTexture, sourceTexture, completion);
00113 
00114         _vm->_gfx->flipBuffer();
00115         _frameLimiter->delayBeforeSwap();
00116         g_system->updateScreen();
00117         _vm->_state->updateFrameCounters();
00118 
00119         Common::Event event;
00120         while (_vm->getEventManager()->pollEvent(event)) {
00121             // Ignore all the events happening during transitions, so that the view does not move
00122             // between the initial transition screen shoot and the first frame drawn after the transition.
00123 
00124             // However, keep updating the keyboard state so we don't end up in
00125             // an unbalanced state where the engine believes keys are still
00126             // pressed while they are not.
00127             _vm->processEventForKeyboardState(event);
00128 
00129             if (_vm->_state->hasVarGamePadUpPressed()) {
00130                 _vm->processEventForGamepad(event);
00131             }
00132         }
00133     }
00134 
00135     _vm->_gfx->freeTexture(sourceTexture);
00136     _vm->_gfx->freeTexture(targetTexture);
00137 }
00138 
00139 void Transition::drawStep(Texture *targetTexture, Texture *sourceTexture, uint completion) {
00140     Common::Rect viewport = _vm->_gfx->viewport();
00141 
00142     switch (_type) {
00143     case kTransitionNone:
00144         break;
00145 
00146     case kTransitionFade:
00147     case kTransitionZip: {
00148             Common::Rect textureRect = Common::Rect(sourceTexture->width, sourceTexture->height);
00149             _vm->_gfx->drawTexturedRect2D(viewport, textureRect, sourceTexture);
00150             _vm->_gfx->drawTexturedRect2D(viewport, textureRect, targetTexture, completion / 100.0);
00151         }
00152         break;
00153 
00154     case kTransitionLeftToRight: {
00155             int16 transitionX = (viewport.width() * (100 - completion)) / 100;
00156             Common::Rect sourceTextureRect(0, 0, transitionX, sourceTexture->height);
00157             Common::Rect sourceScreenRect(sourceTextureRect.width(), sourceTextureRect.height());
00158             sourceScreenRect.translate(viewport.left, viewport.top);
00159 
00160             Common::Rect targetTextureRect(transitionX, 0, targetTexture->width, targetTexture->height);
00161             Common::Rect targetScreenRect(targetTextureRect.width(), targetTextureRect.height());
00162             targetScreenRect.translate(viewport.left + transitionX, viewport.top);
00163 
00164             _vm->_gfx->drawTexturedRect2D(sourceScreenRect, sourceTextureRect, sourceTexture);
00165             _vm->_gfx->drawTexturedRect2D(targetScreenRect, targetTextureRect, targetTexture);
00166         }
00167         break;
00168 
00169     case kTransitionRightToLeft: {
00170             int16 transitionX = viewport.width() * completion / 100;
00171             Common::Rect sourceTextureRect(transitionX, 0, sourceTexture->width, sourceTexture->height);
00172             Common::Rect sourceScreenRect(sourceTextureRect.width(), sourceTextureRect.height());
00173             sourceScreenRect.translate(viewport.left + transitionX, viewport.top);
00174 
00175             Common::Rect targetTextureRect(0, 0, transitionX, targetTexture->height);
00176             Common::Rect targetScreenRect(targetTextureRect.width(), targetTextureRect.height());
00177             targetScreenRect.translate(viewport.left, viewport.top);
00178 
00179             _vm->_gfx->drawTexturedRect2D(sourceScreenRect, sourceTextureRect, sourceTexture);
00180             _vm->_gfx->drawTexturedRect2D(targetScreenRect, targetTextureRect, targetTexture);
00181         }
00182         break;
00183     }
00184 }
00185 
00186 } // End of namespace Myst3


Generated on Sat Feb 16 2019 05:01:09 for ResidualVM by doxygen 1.7.1
curved edge   curved edge